package org.libtiff.jai.codecimpl;
import org.libtiff.jai.codec.XTIFFTileCodecImpl;
import org.libtiff.jai.codec.XTIFFTileCodec;
import org.libtiff.jai.codec.XTIFFEncodeParam;
import org.libtiff.jai.codec.XTIFF;
import org.libtiff.jai.util.JaiI18N;
import java.awt.Rectangle;
/**
* 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;
}
}