Sketcher2 source code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.7 KiB

package com.jotuntech.sketcher.common;
import java.util.zip.Deflater;
public class PixelPacker {
private Deflater deflater;
private byte[] encodedPixels = null;
public PixelPacker() {
deflater = new Deflater(Deflater.BEST_COMPRESSION, true);
}
public int pack(int[] pixels, byte[] output) {
return pack(pixels, output, 0, output.length);
}
public int pack(int[] pixels, byte[] output, int ofs, int len) {
/* Create buffers, or enlarge them if they are too small */
if(encodedPixels == null || encodedPixels.length < pixels.length * 6) {
encodedPixels = new byte[pixels.length * 6];
}
int lastAlpha = 0, lastY = 0, lastCb = 256, lastCr = 256;
for(int pixelOffset = 0, YOffset = pixels.length, CbOffset = pixels.length * 2, CrOffset = pixels.length * 4; pixelOffset < pixels.length; pixelOffset++, YOffset++, CbOffset++, CrOffset++) {
int pixel = pixels[pixelOffset];
/* Extract alpha channel */
int alpha = (pixel >> 24) & 0xFF;
/* Differential transform */
int deltaAlpha = alpha - lastAlpha;
lastAlpha = alpha;
/* Convert negative deltas to equivalent positive deltas */
if(deltaAlpha < 0) {
deltaAlpha = 256 + deltaAlpha;
}
/* Luma and chroma deltas */
int deltaY, deltaCb, deltaCr;
/* Color deltas are zero if alpha is zero, for better compression */
if(alpha == 0) {
deltaY = 0;
deltaCb = 0;
deltaCr = 0;
} else {
/* Extract color channels */
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = pixel & 0xFF;
/* Forward color transform */
int Y = (red + (green << 1) + blue) >> 2;
int Cb = 256 + blue - green;
int Cr = 256 + red - green;
/* Differential transform */
deltaY = Y - lastY;
deltaCb = Cb - lastCb;
deltaCr = Cr - lastCr;
lastY = Y;
lastCb = Cb;
lastCr = Cr;
/* Convert negative deltas to equivalent positive deltas */
if(deltaY < 0) {
deltaY = 256 + deltaY;
}
if(deltaCb < 0) {
deltaCb = 512 + deltaCb;
}
if(deltaCr < 0) {
deltaCr = 512 + deltaCr;
}
}
/* Store image channels */
encodedPixels[pixelOffset] = (byte) deltaAlpha;
encodedPixels[YOffset] = (byte) deltaY;
encodedPixels[CbOffset++] = (byte) (deltaCb >>> 8);
encodedPixels[CbOffset] = (byte) deltaCb;
encodedPixels[CrOffset++] = (byte) (deltaCr >>> 8);
encodedPixels[CrOffset] = (byte) deltaCr;
}
/* Deflate encoded pixels */
deflater.reset();
deflater.setInput(encodedPixels, 0, pixels.length * 6);
deflater.finish();
int compressedLength = 0;
while(!deflater.finished() && compressedLength < len) {
compressedLength += deflater.deflate(output, ofs + compressedLength, len - compressedLength);
}
return compressedLength;
}
}