001: package org.libtiff.jai.codecimpl;
002:
003: import org.libtiff.jai.codec.XTIFFTileCodecImpl;
004: import org.libtiff.jai.codec.XTIFFTileCodec;
005: import org.libtiff.jai.codec.XTIFFEncodeParam;
006: import org.libtiff.jai.codec.XTIFF;
007: import org.libtiff.jai.util.JaiI18N;
008: import java.awt.Rectangle;
009:
010: /**
011: * This codec encapsulates all the logic for the default TIFF
012: * "packbits" bit-packing codec algorithm.
013: */
014: public class XTIFFPackTileCodec extends XTIFFTileCodecImpl {
015:
016: public XTIFFPackTileCodec() {
017: }
018:
019: public XTIFFTileCodec create() {
020: return new XTIFFPackTileCodec();
021: }
022:
023: public boolean canEncode() {
024: return false;
025: }
026:
027: public void register() {
028: register(XTIFF.COMPRESSION_PACKBITS);
029: }
030:
031: /**
032: * encode the tile into bpixels and return the byte size
033: * (uncompressed packing algorithm). The padding has already
034: * been done, so we may safely assume that pixels is exactly
035: * rows by cols by numBands ints.
036: */
037:
038: public int encodeTilePixels(int[] pixels, Rectangle newRect,
039: byte[] bpixels) {
040: return 0;
041: }
042:
043: /**
044: * Decode a rectangle of pixels
045: */
046: public void decodeTilePixels(byte[] input, Rectangle newRect,
047: byte[] bdata) {
048:
049: if (bitsPerSample[0] == 8) {
050: decodePackbits(input, unitsInThisTile, bdata);
051: } else if (bitsPerSample[0] == 4) {
052: // Since the decompressed data will still be packed
053: // 2 pixels into 1 byte, calculate bytesInThisTile
054: int bytesInThisTile;
055: if ((newRect.width % 8) == 0) {
056: bytesInThisTile = (newRect.width / 2) * newRect.height;
057: } else {
058: bytesInThisTile = (newRect.width / 2 + 1)
059: * newRect.height;
060: }
061:
062: decodePackbits(input, bytesInThisTile, bdata);
063: }
064: }
065:
066: /**
067: * Decode a rectangle of pixels
068: */
069: public void decodeTilePixels(byte[] input, Rectangle newRect,
070: short[] sdata) {
071: int bytesInThisTile = unitsInThisTile * 2;
072: byte byteArray[] = new byte[bytesInThisTile];
073: decodePackbits(input, bytesInThisTile, byteArray);
074: unpackShorts(byteArray, sdata, unitsInThisTile);
075: }
076:
077: // Uncompress packbits compressed image data.
078: private byte[] decodePackbits(byte data[], int arraySize, byte[] dst) {
079:
080: if (dst == null) {
081: dst = new byte[arraySize];
082: }
083:
084: int srcCount = 0, dstCount = 0;
085: byte repeat, b;
086:
087: try {
088:
089: while (dstCount < arraySize) {
090:
091: b = data[srcCount++];
092:
093: if (b >= 0 && b <= 127) {
094:
095: // literal run packet
096: for (int i = 0; i < (b + 1); i++) {
097: dst[dstCount++] = data[srcCount++];
098: }
099:
100: } else if (b <= -1 && b >= -127) {
101:
102: // 2 byte encoded run packet
103: repeat = data[srcCount++];
104: for (int i = 0; i < (-b + 1); i++) {
105: dst[dstCount++] = repeat;
106: }
107:
108: } else {
109: // no-op packet. Do nothing
110: srcCount++;
111: }
112: }
113: } catch (java.lang.ArrayIndexOutOfBoundsException ae) {
114: throw new RuntimeException(JaiI18N
115: .getString("XTIFFImageDecoder10"));
116: }
117:
118: return dst;
119: }
120: }
|