package org.libtiff.jai.codecimpl;
import java.awt.Rectangle;
import org.libtiff.jai.codec.XTIFF;
import org.libtiff.jai.codec.XTIFFTileCodec;
import org.libtiff.jai.codec.XTIFFTileCodecImpl;
import org.libtiff.jai.util.JaiI18N;
/**
* This codec encapsulates all the logic for the default TIFF "packbits"
* bit-packing codec algorithm.
*/
public class XTIFFPackTileCodec extends XTIFFTileCodecImpl {
public XTIFFPackTileCodec() {}
public XTIFFTileCodec create() {
return new XTIFFPackTileCodec();
}
public boolean canEncode() {
return false;
}
public void register() {
register(XTIFF.COMPRESSION_PACKBITS);
}
/**
* encode the tile into bpixels and return the byte size (uncompressed
* packing algorithm). The padding has already been done, so we may safely
* assume that pixels is exactly rows by cols by numBands ints.
*/
public int encodeTilePixels(int[] pixels, Rectangle newRect, byte[] bpixels) {
return 0;
}
/**
* Decode a rectangle of pixels
*/
public void decodeTilePixels(byte[] input, Rectangle newRect, byte[] bdata) {
if (bitsPerSample[0] == 8) {
decodePackbits(input, unitsInThisTile, bdata);
} else if (bitsPerSample[0] == 4) {
// Since the decompressed data will still be packed
// 2 pixels into 1 byte, calculate bytesInThisTile
int bytesInThisTile;
if ((newRect.width % 8) == 0) {
bytesInThisTile = (newRect.width / 2) * newRect.height;
} else {
bytesInThisTile = (newRect.width / 2 + 1) * newRect.height;
}
decodePackbits(input, bytesInThisTile, bdata);
}
}
/**
* Decode a rectangle of pixels
*/
public void decodeTilePixels(byte[] input, Rectangle newRect, short[] sdata) {
int bytesInThisTile = unitsInThisTile * 2;
byte byteArray[] = new byte[bytesInThisTile];
decodePackbits(input, bytesInThisTile, byteArray);
unpackShorts(byteArray, sdata, unitsInThisTile);
}
// Uncompress packbits compressed image data.
private byte[] decodePackbits(byte data[], int arraySize, byte[] dst) {
if (dst == null) {
dst = new byte[arraySize];
}
int srcCount = 0, dstCount = 0;
byte repeat, b;
try {
while (dstCount < arraySize) {
b = data[srcCount++];
if (b >= 0 && b <= 127) {
// literal run packet
for (int i = 0; i < (b + 1); i++) {
dst[dstCount++] = data[srcCount++];
}
} else if (b <= -1 && b >= -127) {
// 2 byte encoded run packet
repeat = data[srcCount++];
for (int i = 0; i < (-b + 1); i++) {
dst[dstCount++] = repeat;
}
} else {
// no-op packet. Do nothing
srcCount++;
}
}
} catch (java.lang.ArrayIndexOutOfBoundsException ae) {
throw new RuntimeException(JaiI18N.getString("XTIFFImageDecoder10"));
}
return dst;
}
}