![JAR search and dependency download from the Maven repository](/logo.png)
org.monte.media.ilbm.ILBMEncoder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.monte.media.amigaatari Show documentation
Show all versions of org.monte.media.amigaatari Show documentation
A library for processing Amiga and Atari still images, video, audio and meta-data.
The newest version!
/*
* @(#)Main.java
* Copyright © 2023 Werner Randelshofer, Switzerland. MIT License.
*/
package org.monte.media.ilbm;
import org.monte.media.amigabitmap.AmigaBitmapImage;
import org.monte.media.iff.IFFOutputStream;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.image.IndexColorModel;
import java.io.File;
import java.io.IOException;
/**
* {@code ILBMEncoder}.
*
* @author Werner Randelshofer
*/
public class ILBMEncoder {
public ILBMEncoder() {
}
public void write(File f, AmigaBitmapImage img, int camg) throws IOException {
IFFOutputStream out = null;
try {
out = new IFFOutputStream(new FileImageOutputStream(f));
out.pushCompositeChunk("FORM", "ILBM");
writeBMHD(out, img);
writeCMAP(out, img);
writeCAMG(out, camg);
writeBODY(out, img);
out.popChunk();
} finally {
if (out != null) {
out.close();
}
}
}
/**
* Writes the bitmap header (ILBM BMHD).
*
*
* typedef UBYTE Masking; // Choice of masking technique
*
* #define mskNone 0
* #define mskHasMask 1
* #define mskHasTransparentColor 2
* #define mskLasso 3
*
* typedef UBYTE Compression; // Choice of compression algorithm
* // applied to the rows of all source and mask planes.
* // "cmpByteRun1" is the byte run encoding. Do not compress
* // accross rows!
* #define cmpNone 0
* #define cmpByteRun1 1
*
* typedef struct {
* UWORD w, h; // raster width & height in pixels
* WORD x, y; // pixel position for this image
* UBYTE nbPlanes; // # source bitplanes
* Masking masking;
* Compression compression;
* UBYTE pad1; // unused; ignore on read, write as 0
* UWORD transparentColor; // transparent "color number" (sort of)
* UBYTE xAspect, yAspect; // pixel aspect, a ratio width : height
* UWORD pageWidth, pageHeight; // source "page" size in pixels
* } BitmapHeader;
*
*/
private void writeBMHD(IFFOutputStream out, AmigaBitmapImage img) throws IOException {
out.pushDataChunk("BMHD");
out.writeUWORD(img.getWidth());
out.writeUWORD(img.getHeight());
out.writeWORD(0);
out.writeWORD(0);
out.writeUBYTE(img.getDepth());
out.writeUBYTE(0); // mskNone
out.writeUBYTE(1); // cmpByteRun1
out.writeUBYTE(0);
out.writeUWORD(0);
out.writeUBYTE(44);
out.writeUBYTE(52);
out.writeUWORD(img.getWidth());
out.writeUWORD(img.getHeight());
out.popChunk();
}
/**
* Writes the color map (ILBM CMAP).
*/
private void writeCMAP(IFFOutputStream out, AmigaBitmapImage img) throws IOException {
out.pushDataChunk("CMAP");
IndexColorModel cm = (IndexColorModel) img.getPlanarColorModel();
for (int i = 0, n = cm.getMapSize(); i < n; ++i) {
out.writeUBYTE(cm.getRed(i));
out.writeUBYTE(cm.getGreen(i));
out.writeUBYTE(cm.getBlue(i));
}
out.popChunk();
}
/**
* Writes the color amiga viewport mode display id (ILBM CAMG).
*/
private void writeCAMG(IFFOutputStream out, int camg) throws IOException {
out.pushDataChunk("CAMG");
out.writeLONG(camg);
out.popChunk();
}
/**
* Writes the body (ILBM BODY).
*/
private void writeBODY(IFFOutputStream out, AmigaBitmapImage img) throws IOException {
out.pushDataChunk("BODY");
int w = img.getWidth() / 8;
int ss = img.getScanlineStride();
int bs = img.getBitplaneStride();
int offset = 0;
byte[] data = img.getBitmap();
for (int y = 0, h = img.getHeight(); y < h; y++) {
for (int p = 0, d = img.getDepth(); p < d; p++) {
out.writeByteRun1(data, offset + bs * p, w);
}
offset += ss;
}
out.popChunk();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy