Compare commits

...

7 Commits

Author SHA1 Message Date
A2 Geek 61315596a1
Merge pull request #1 from a2geek/dependabot/maven/junit-junit-4.13.1
Bump junit from 4.12 to 4.13.1
2020-11-17 23:00:17 -06:00
dependabot[bot] 720dc56406
Bump junit from 4.12 to 4.13.1
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-17 13:34:23 +00:00
Rob Greene 6c0aa23a75 Removing version history as that is now in the Github releases tab. 2019-03-05 22:23:58 -06:00
Rob Greene 30eef62cb8 Bumping commons compress for CVE-2018-11771. 2019-03-05 22:23:29 -06:00
Rob 5ff79e05a8 Tweak to pull in Apache Commons Codec. 2017-07-09 16:07:08 -05:00
Rob 75d5d8d4cd Adding bin. 2017-07-03 18:42:55 -05:00
Rob e25ae7ff38 Fixing glitch in table. 2017-07-03 18:42:41 -05:00
6 changed files with 126 additions and 56 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
/.settings/
/.classpath
/.project
/bin

View File

@ -1,18 +1,18 @@
# Overview
This application will convert a modern image into a format usable by an Apple II - lores, double lores, and super hires are currently supported. It also includes basic compression capabilities. The color palettes go through an optimization phase to the standard 16 color palette, or, of the existing palette in the case of a super hires.
This application will convert a modern image into a format usable by an Apple II - lores, double lores, and super hires are currently supported. It also includes basic compression capabilities. The color palettes go through an optimization phase to the standard 16 color palette, or, of the existing palette in the case of a super hires.
**Requires:** Java 1.8 (originally implemented for Java 1.4, but being rebuilt with modern tools, hence Java 1.8 requirement).
**Requires:** Java 1.8 (originally implemented for Java 1.4, but being rebuilt with modern tools, hence Java 1.8 requirement).
**Tip:** You can drag an image into the original tab instead of digging around for it.
**Tip:** You can drag an image into the original tab instead of digging around for it.
Currently supported Apple II graphic formats:
Currently supported Apple II graphic formats:
Format | Width | Height | Colors
------ | ----- | ------ | ------
Lores | 40 | 40 | Standard Apple 16 colors
Double | Lores | 80 | 40 | Standard Apple 16 colors
Super Hires | 320 | 200 | 16 palettes of 16 colors; each palette entry is 12 bit color (4 bits per red, green, blue).
------ | ----- | ------ | ------
Lores | 40 | 40 | Standard Apple 16 colors
Double Lores | 80 | 40 | Standard Apple 16 colors
Super Hires | 320 | 200 | 16 palettes of 16 colors; each palette entry is 12 bit color (4 bits per red, green, blue).
Currently supported "compression" formats: RLE, Variable RLE, PackBits, 'deflate' method of Zip, GZip, BitPack #1 - #3 (my attempts and they're worthless).
@ -20,23 +20,18 @@ The [original TODO list](TODO.md) has been preserved for any future efforts.
# Screen Shots
This is the original tab with a 2048x1536 image taken on my digital camera. If you're not sure what you are looking at, it is the upper-left corner of the image in the next picture.
This is the original tab with a 2048x1536 image taken on my digital camera. If you're not sure what you are looking at, it is the upper-left corner of the image in the next picture.
![Original](doc/images/a2ie-original.png)
Choose the image type to convert to and click the convert button. If you wish, you can save the raw Apple II data. Note that for lores and double lores, no screen holes are saved.
Choose the image type to convert to and click the convert button. If you wish, you can save the raw Apple II data. Note that for lores and double lores, no screen holes are saved.
![Converted](doc/images/a2ie-convert.png)
If you want some ideas about compressability, click the compression tab. You can enter the "max size allowed" which I use to figure out if the image can fit into the memory I've allocated for it on the Apple II. Click the Compress button to run through all the possibilities. Those that fit in the size given are colored green, the rest are red. If the compression method fails for some reason, it does not show up (note that Bit Pack #1 is missing - it only works on images less than 64 pixels wide or high or something like that). Note that each compression method's results can be saved to disk.
If you want some ideas about compressability, click the compression tab. You can enter the "max size allowed" which I use to figure out if the image can fit into the memory I've allocated for it on the Apple II. Click the Compress button to run through all the possibilities. Those that fit in the size given are colored green, the rest are red. If the compression method fails for some reason, it does not show up (note that Bit Pack #1 is missing - it only works on images less than 64 pixels wide or high or something like that). Note that each compression method's results can be saved to disk.
![Compression Tab](doc/images/a2ie-compression.png)
# Installation
Apple Image Encoder is distributed in a self-executing Java JAR file. What this means is that once Java has been installed on your system, you just need to (a) click the link and open the program to run it or (b) save the file to your hard disk and then double-click on that file. Use whichever works best for you.
# Version History
* 09/12/2016 - 4.4.0 - Migrated to GitHub, Maven, rebuilt application.
* 08/06/2005 - 4.3.1 - Initial public release. Prior (internal) releases include command-line only, proof-of-concept work, etc. *This is the only version that will still work with Java 1.5 or later. This is the original package from 2005.

30
pom.xml
View File

@ -1,18 +1,18 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>a2geek.apple2</groupId>
<artifactId>apple2-image-encoder</artifactId>
<version>4.4.0-FINAL</version>
<version>4.4.1-FINAL</version>
<name>Apple II Image Encoder</name>
<description>A utility that got out of hand and became an application to move modern images to the Apple II platform.</description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.shade.version>2.4.3</maven.shade.version>
<junit.version>4.12</junit.version>
<maven.shade.version>3.0.0</maven.shade.version>
<junit.version>4.13.1</junit.version>
</properties>
<dependencies>
@ -22,6 +22,23 @@
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>[1.18,)</version>
</dependency>
<dependency>
<groupId>org.brotli</groupId>
<artifactId>dec</artifactId>
<version>0.1.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.6</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
@ -52,4 +69,5 @@
</executions>
</plugin>
</plugins>
</build></project>
</build>
</project>

View File

@ -0,0 +1,27 @@
package a2geek.apple2.image.encoder.encode;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
public abstract class A2EncoderFactory {
public static List<A2Encoder> getEncoders() {
List<A2Encoder> list = new ArrayList<>();
list.add(new RleEncoder());
list.add(new VariableRleEncoder());
list.add(new PackBitsEncoder());
list.add(new BitPack1());
list.add(new BitPack2());
list.add(new BitPack3());
list.add(new GZipEncoder());
list.add(new ZipEncoder());
// From Apache Commons
for (String outputProvider : CompressorStreamFactory.findAvailableCompressorOutputStreamProviders().keySet()) {
// PACK200 does nothing for some reason, so just ignoring it
if (CompressorStreamFactory.PACK200.equals(outputProvider)) continue;
list.add(new CommonsCodecEncoder(outputProvider));
}
return list;
}
}

View File

@ -0,0 +1,48 @@
package a2geek.apple2.image.encoder.encode;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorOutputStream;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.commons.compress.compressors.CompressorStreamProvider;
import a2geek.apple2.image.encoder.A2Image;
import a2geek.apple2.image.encoder.ui.ImageEncoderApp;
public class CommonsCodecEncoder extends A2Encoder {
private CompressorStreamProvider provider = new CompressorStreamFactory();
private String name;
private String title;
public CommonsCodecEncoder(String name) {
this(name, name.toUpperCase());
}
public CommonsCodecEncoder(String name, String title) {
this.name = name;
this.title = title;
}
@Override
public void encode(A2Image a2image, int maxSize) {
try {
reset(maxSize);
ByteArrayOutputStream ba = new ByteArrayOutputStream();
CompressorOutputStream out = provider.createCompressorOutputStream(name, ba);
out.write(a2image.getBytes());
out.close();
for (byte b : ba.toByteArray()) {
addByte(b);
}
} catch (CompressorException | IOException ex) {
ImageEncoderApp.showErrorDialog("Apache Commons '" + name + "' compress", ex);
}
}
@Override
public String getTitle() {
return title;
}
}

View File

@ -7,14 +7,7 @@ import javax.swing.table.AbstractTableModel;
import a2geek.apple2.image.encoder.A2Image;
import a2geek.apple2.image.encoder.encode.A2Encoder;
import a2geek.apple2.image.encoder.encode.BitPack1;
import a2geek.apple2.image.encoder.encode.BitPack2;
import a2geek.apple2.image.encoder.encode.BitPack3;
import a2geek.apple2.image.encoder.encode.GZipEncoder;
import a2geek.apple2.image.encoder.encode.PackBitsEncoder;
import a2geek.apple2.image.encoder.encode.RleEncoder;
import a2geek.apple2.image.encoder.encode.VariableRleEncoder;
import a2geek.apple2.image.encoder.encode.ZipEncoder;
import a2geek.apple2.image.encoder.encode.A2EncoderFactory;
import a2geek.apple2.image.encoder.util.ProgressListener;
/**
@ -25,7 +18,7 @@ import a2geek.apple2.image.encoder.util.ProgressListener;
*/
@SuppressWarnings("serial")
public class EncoderTableModel extends AbstractTableModel {
private List<A2Encoder> encoders = new ArrayList<A2Encoder>();
private final List<A2Encoder> results = new ArrayList<>();
private byte[] data = null;
private String[] headers = new String[] { "Type", "Original", "Compressed", "%" };
/**
@ -33,30 +26,18 @@ public class EncoderTableModel extends AbstractTableModel {
*/
public EncoderTableModel(A2Image image, int maxSize, ProgressListener listener) {
this.data = image.getBytes();
Class[] encoderClasses = new Class[] {
RleEncoder.class,
VariableRleEncoder.class,
PackBitsEncoder.class,
BitPack1.class,
BitPack2.class,
BitPack3.class,
GZipEncoder.class,
ZipEncoder.class
};
int count = 0;
for (Class encoderClass : encoderClasses) {
if (listener != null && listener.isCancelled()) return;
A2Encoder a2encoder = null;
int size = A2EncoderFactory.getEncoders().size();
for (A2Encoder encoder : A2EncoderFactory.getEncoders()) {
try {
a2encoder = (A2Encoder)encoderClass.newInstance();
if (listener != null && listener.isCancelled()) return;
count++;
if (listener != null) listener.update(count, encoderClasses.length, a2encoder.getTitle());
a2encoder.encode(image, maxSize);
encoders.add(a2encoder);
if (listener != null) listener.update(count, size, encoder.getTitle());
encoder.encode(image, maxSize);
results.add(encoder);
} catch (Throwable t) {
// FIXME ignore errors...
//ImageEncoderApp.showErrorDialog(a2encoder.getTitle(), t);
// Ignoring these as some are expected to throw errors if boundaries are missed
}
}
}
@ -70,7 +51,7 @@ public class EncoderTableModel extends AbstractTableModel {
* Answer with the number of rows.
*/
public int getRowCount() {
return encoders.size();
return results.size();
}
/**
* Answer with the number of columns.
@ -84,13 +65,13 @@ public class EncoderTableModel extends AbstractTableModel {
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return encoders.get(rowIndex).getTitle();
return results.get(rowIndex).getTitle();
case 1:
return data.length;
case 2:
return encoders.get(rowIndex).getSize();
return results.get(rowIndex).getSize();
case 3:
return (encoders.get(rowIndex).getSize() * 100) / data.length;
return (results.get(rowIndex).getSize() * 100) / data.length;
default:
return "Unknown";
}
@ -116,6 +97,6 @@ public class EncoderTableModel extends AbstractTableModel {
* Answer with the specific A2Encoder.
*/
public A2Encoder getSelectedEncoder(int rowIndex) {
return encoders.get(rowIndex);
return results.get(rowIndex);
}
}