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.

77 lines
2.4 KiB

package com.jotuntech.sketcher.common;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
public class PixelUnpacker {
Inflater inflater;
private byte[] encodedPixels;
public PixelUnpacker() {
inflater = new Inflater(true);
}
public void unpack(byte[] input, int ofs, int len, int[] output) {
if(encodedPixels == null || encodedPixels.length < input.length * 6) {
encodedPixels = new byte[output.length * 6];
}
inflater.reset();
inflater.setInput(input, ofs, len);
//Log.debug("Inflating from offset " + ofs + " length " + len);
int encodedLength = 0;
try {
while(!inflater.finished() && encodedLength < encodedPixels.length) {
encodedLength += inflater.inflate(encodedPixels, encodedLength, encodedPixels.length - encodedLength);
}
} catch(DataFormatException e) {
throw new RuntimeException(e);
}
if(encodedLength < output.length * 6) {
Log.error("needsInput = " + inflater.needsInput());
throw new RuntimeException("Encoded length " + encodedLength + " is shorter than output length " + output.length * 6 + ".");
}
int lastAlpha = 0, lastY = 0, lastCb = 256, lastCr = 256;
for(int outputOffset = 0, YOffset = output.length, CbOffset = output.length * 2, CrOffset = output.length * 4; outputOffset < output.length; outputOffset++, YOffset++, CbOffset++, CrOffset++) {
/* Extract alpha channel delta */
int deltaAlpha = encodedPixels[outputOffset] & 0xFF;
/* Differential transform with overflow wrapping */
int alpha = (lastAlpha + deltaAlpha) & 0xFF;
lastAlpha = alpha;
/* Color channel deltas are always zero when alpha is zero */
if(alpha == 0) {
output[outputOffset] = 0;
++CbOffset;
++CrOffset;
} else {
/* Extract color channel deltas */
int deltaY = encodedPixels[YOffset] & 0xFF;
int deltaCb = ((encodedPixels[CbOffset++] & 0xFF) << 8) | (encodedPixels[CbOffset] & 0xFF);
int deltaCr = ((encodedPixels[CrOffset++] & 0xFF) << 8) | (encodedPixels[CrOffset] & 0xFF);
/* Differental transform with overflow wrapping */
int Y = (lastY + deltaY) & 0xFF;
int Cb = (lastCb + deltaCb) & 0x1FF;
int Cr = (lastCr + deltaCr) & 0x1FF;
lastY = Y;
lastCb = Cb;
lastCr = Cr;
/* Inverse color transform */
Cb -= 256;
Cr -= 256;
int green = Y - ((Cb + Cr) >> 2);
int red = Cr + green;
int blue = Cb + green;
output[outputOffset] = Pixels.pack(alpha, red, green, blue);
}
}
}
}