mirror of
https://github.com/a2geek/apple2-image-encoder.git
synced 2024-06-29 01:29:40 +00:00
Compare commits
7 Commits
4.4.0-FINA
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
61315596a1 | ||
|
720dc56406 | ||
|
6c0aa23a75 | ||
|
30eef62cb8 | ||
|
5ff79e05a8 | ||
|
75d5d8d4cd | ||
|
e25ae7ff38 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
/.settings/
|
/.settings/
|
||||||
/.classpath
|
/.classpath
|
||||||
/.project
|
/.project
|
||||||
|
/bin
|
||||||
|
|
|
@ -11,7 +11,7 @@ Currently supported Apple II graphic formats:
|
||||||
Format | Width | Height | Colors
|
Format | Width | Height | Colors
|
||||||
------ | ----- | ------ | ------
|
------ | ----- | ------ | ------
|
||||||
Lores | 40 | 40 | Standard Apple 16 colors
|
Lores | 40 | 40 | Standard Apple 16 colors
|
||||||
Double | Lores | 80 | 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).
|
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).
|
Currently supported "compression" formats: RLE, Variable RLE, PackBits, 'deflate' method of Zip, GZip, BitPack #1 - #3 (my attempts and they're worthless).
|
||||||
|
@ -35,8 +35,3 @@ If you want some ideas about compressability, click the compression tab. You can
|
||||||
# Installation
|
# 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.
|
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.
|
|
||||||
|
|
26
pom.xml
26
pom.xml
|
@ -4,15 +4,15 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>a2geek.apple2</groupId>
|
<groupId>a2geek.apple2</groupId>
|
||||||
<artifactId>apple2-image-encoder</artifactId>
|
<artifactId>apple2-image-encoder</artifactId>
|
||||||
<version>4.4.0-FINAL</version>
|
<version>4.4.1-FINAL</version>
|
||||||
<name>Apple II Image Encoder</name>
|
<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>
|
<description>A utility that got out of hand and became an application to move modern images to the Apple II platform.</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<maven.shade.version>2.4.3</maven.shade.version>
|
<maven.shade.version>3.0.0</maven.shade.version>
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.13.1</junit.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -22,6 +22,23 @@
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -52,4 +69,5 @@
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build></project>
|
</build>
|
||||||
|
</project>
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,14 +7,7 @@ import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
import a2geek.apple2.image.encoder.A2Image;
|
import a2geek.apple2.image.encoder.A2Image;
|
||||||
import a2geek.apple2.image.encoder.encode.A2Encoder;
|
import a2geek.apple2.image.encoder.encode.A2Encoder;
|
||||||
import a2geek.apple2.image.encoder.encode.BitPack1;
|
import a2geek.apple2.image.encoder.encode.A2EncoderFactory;
|
||||||
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.util.ProgressListener;
|
import a2geek.apple2.image.encoder.util.ProgressListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +18,7 @@ import a2geek.apple2.image.encoder.util.ProgressListener;
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class EncoderTableModel extends AbstractTableModel {
|
public class EncoderTableModel extends AbstractTableModel {
|
||||||
private List<A2Encoder> encoders = new ArrayList<A2Encoder>();
|
private final List<A2Encoder> results = new ArrayList<>();
|
||||||
private byte[] data = null;
|
private byte[] data = null;
|
||||||
private String[] headers = new String[] { "Type", "Original", "Compressed", "%" };
|
private String[] headers = new String[] { "Type", "Original", "Compressed", "%" };
|
||||||
/**
|
/**
|
||||||
|
@ -34,29 +27,17 @@ public class EncoderTableModel extends AbstractTableModel {
|
||||||
public EncoderTableModel(A2Image image, int maxSize, ProgressListener listener) {
|
public EncoderTableModel(A2Image image, int maxSize, ProgressListener listener) {
|
||||||
this.data = image.getBytes();
|
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;
|
int count = 0;
|
||||||
for (Class encoderClass : encoderClasses) {
|
int size = A2EncoderFactory.getEncoders().size();
|
||||||
if (listener != null && listener.isCancelled()) return;
|
for (A2Encoder encoder : A2EncoderFactory.getEncoders()) {
|
||||||
A2Encoder a2encoder = null;
|
|
||||||
try {
|
try {
|
||||||
a2encoder = (A2Encoder)encoderClass.newInstance();
|
if (listener != null && listener.isCancelled()) return;
|
||||||
count++;
|
count++;
|
||||||
if (listener != null) listener.update(count, encoderClasses.length, a2encoder.getTitle());
|
if (listener != null) listener.update(count, size, encoder.getTitle());
|
||||||
a2encoder.encode(image, maxSize);
|
encoder.encode(image, maxSize);
|
||||||
encoders.add(a2encoder);
|
results.add(encoder);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
// FIXME ignore errors...
|
// Ignoring these as some are expected to throw errors if boundaries are missed
|
||||||
//ImageEncoderApp.showErrorDialog(a2encoder.getTitle(), t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +51,7 @@ public class EncoderTableModel extends AbstractTableModel {
|
||||||
* Answer with the number of rows.
|
* Answer with the number of rows.
|
||||||
*/
|
*/
|
||||||
public int getRowCount() {
|
public int getRowCount() {
|
||||||
return encoders.size();
|
return results.size();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Answer with the number of columns.
|
* Answer with the number of columns.
|
||||||
|
@ -84,13 +65,13 @@ public class EncoderTableModel extends AbstractTableModel {
|
||||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||||
switch (columnIndex) {
|
switch (columnIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
return encoders.get(rowIndex).getTitle();
|
return results.get(rowIndex).getTitle();
|
||||||
case 1:
|
case 1:
|
||||||
return data.length;
|
return data.length;
|
||||||
case 2:
|
case 2:
|
||||||
return encoders.get(rowIndex).getSize();
|
return results.get(rowIndex).getSize();
|
||||||
case 3:
|
case 3:
|
||||||
return (encoders.get(rowIndex).getSize() * 100) / data.length;
|
return (results.get(rowIndex).getSize() * 100) / data.length;
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
@ -116,6 +97,6 @@ public class EncoderTableModel extends AbstractTableModel {
|
||||||
* Answer with the specific A2Encoder.
|
* Answer with the specific A2Encoder.
|
||||||
*/
|
*/
|
||||||
public A2Encoder getSelectedEncoder(int rowIndex) {
|
public A2Encoder getSelectedEncoder(int rowIndex) {
|
||||||
return encoders.get(rowIndex);
|
return results.get(rowIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user