/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */
package org.apache.batik.ext.awt.image.codec.tiff;

import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferShort;
import java.awt.image.DataBufferUShort;
import java.awt.image.IndexColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;

import org.apache.batik.ext.awt.image.codec.util.SeekableStream;
import org.apache.batik.ext.awt.image.rendered.AbstractRed;
import org.apache.batik.ext.awt.image.rendered.CachableRed;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGDecodeParam;
import com.sun.image.codec.jpeg.JPEGImageDecoder;

/**
 *
 * @version $Id$
 */
public class TIFFImage extends AbstractRed {

    // Compression types
    public static final int COMP_NONE      = 1;
    public static final int COMP_FAX_G3_1D = 2;
    public static final int COMP_FAX_G3_2D = 3;
    public static final int COMP_FAX_G4_2D = 4;
    public static final int COMP_LZW       = 5;
    public static final int COMP_JPEG_OLD  = 6;
    public static final int COMP_JPEG_TTN2 = 7;
    public static final int COMP_PACKBITS  = 32773;
    public static final int COMP_DEFLATE   = 32946;

    // Image types
    private static final int TYPE_UNSUPPORTED = -1;
    private static final int TYPE_BILEVEL      = 0;
    private static final int TYPE_GRAY_4BIT    = 1;
    private static final int TYPE_GRAY         = 2;
    private static final int TYPE_GRAY_ALPHA   = 3;
    private static final int TYPE_PALETTE      = 4;
    private static final int TYPE_RGB          = 5;
    private static final int TYPE_RGB_ALPHA    = 6;
    private static final int TYPE_YCBCR_SUB    = 7;
    private static final int TYPE_GENERIC      = 8;

    // Incidental tags
    private static final int TIFF_JPEG_TABLES       = 347;
    private static final int TIFF_YCBCR_SUBSAMPLING = 530;

    SeekableStream stream;
    int tileSize;
    int tilesX, tilesY;
    long[] tileOffsets;
    long[] tileByteCounts;
    char[] colormap;
    int sampleSize;
    int compression;
    byte[] palette;
    int numBands;

    int chromaSubH;
    int chromaSubV;

    // Fax compression related variables
    long tiffT4Options;
    long tiffT6Options;
    int fillOrder;

    // LZW compression related variable
    int predictor;

    // TTN2 JPEG related variables
    JPEGDecodeParam decodeParam = null;
    boolean colorConvertJPEG = false;

    // DEFLATE variables
    Inflater inflater = null;

    // Endian-ness indicator
    boolean isBigEndian;

    int imageType;
    boolean isWhiteZero = false;
    int dataType;

    boolean decodePaletteAsShorts;
    boolean tiled;

    // Decoders
    private TIFFFaxDecoder decoder = null;
    private TIFFLZWDecoder lzwDecoder = null;

    /**
     * Decode a buffer of data into a Raster with the specified location.
     *
     * @param data buffer contain an interchange or abbreviated datastream.
     * @param decodeParam decoding parameters; may be null unless the
     *        data buffer contains an abbreviated datastream in which case
     *        it may not be null or an error will occur.
     * @param colorConvert whether to perform color conversion; in this
     *        case that would be limited to YCbCr-to-RGB.
     * @param minX the X position of the returned Raster.
     * @param minY the Y position of the returned Raster.
     */
    private static final Raster decodeJPEG(byte[] data,
                                           JPEGDecodeParam decodeParam,
                                           boolean colorConvert,
                                           int minX,
                                           int minY) {
        // Create an InputStream from the compressed data array.
        ByteArrayInputStream jpegStream = new ByteArrayInputStream(data);

        // Create a decoder.
        JPEGImageDecoder decoder = decodeParam == null ?
            JPEGCodec.createJPEGDecoder(jpegStream) :
            JPEGCodec.createJPEGDecoder(jpegStream,
                                        decodeParam);

        // Decode the compressed data into a Raster.
        Raster jpegRaster;
        try {
            jpegRaster = colorConvert ?
                decoder.decodeAsBufferedImage().getWritableTile(0, 0) :
                decoder.decodeAsRaster();
        } catch (IOException ioe) {
            throw new RuntimeException("TIFFImage13");
        }

        // Translate the decoded Raster to the specified location and return.
        return jpegRaster.createTranslatedChild(minX, minY);
    }

    /**
     * Inflates <code>deflated</code> into <code>inflated</code> using the
     * <code>Inflater</code> constructed during class instantiation.
     */
    private final void inflate(byte[] deflated, byte[] inflated) {
        inflater.setInput(deflated);
        try {
            inflater.inflate(inflated);
        } catch(DataFormatException dfe) {
            throw new RuntimeException("TIFFImage17"+": "+
                                       dfe.getMessage());
        }
        inflater.reset();
    }

    private static SampleModel createPixelInterleavedSampleModel
        (int dataType, int tileWidth, int tileHeight, int bands) {
        int [] bandOffsets = new int[bands];
        for (int i=0; i<bands; i++)
            bandOffsets[i] = i;
        return new PixelInterleavedSampleModel
            (dataType, tileWidth, tileHeight, bands,
             tileWidth*bands, bandOffsets);
    }

    /**
     * Return as a long[] the value of a TIFF_LONG or TIFF_SHORT field.
     */
    private long[] getFieldAsLongs(TIFFField field) {
        long[] value = null;

        if(field.getType() == TIFFField.TIFF_SHORT) {
            char[] charValue = field.getAsChars();
            value = new long[charValue.length];
            for(int i = 0; i < charValue.length; i++) {
                value[i] = charValue[i]  & 0xffff;
            }
        } else if(field.getType() == TIFFField.TIFF_LONG) {
            value = field.getAsLongs();
        } else {
            throw new RuntimeException();
        }

        return value;
    }

    /**
     * Constructs a TIFFImage that acquires its data from a given
     * SeekableStream and reads from a particular IFD of the stream.
     * The index of the first IFD is 0.
     *
     * @param stream the SeekableStream to read from.
     * @param param an instance of TIFFDecodeParam, or null.
     * @param directory the index of the IFD to read from.
     */
    public TIFFImage(SeekableStream stream,
                     TIFFDecodeParam param,
                     int directory)
        throws IOException {

        this.stream = stream;
        if (param == null) {
            param = new TIFFDecodeParam();
        }

        decodePaletteAsShorts = param.getDecodePaletteAsShorts();

        // Read the specified directory.
        TIFFDirectory dir = param.getIFDOffset() == null ?
            new TIFFDirectory(stream, directory) :
            new TIFFDirectory(stream, param.getIFDOffset().longValue(),
                              directory);

        // Get the number of samples per pixel
        TIFFField sfield = dir.getField(TIFFImageDecoder.TIFF_SAMPLES_PER_PIXEL);
        int samplesPerPixel = sfield == null ? 1 : (int)sfield.getAsLong(0);

        // Read the TIFF_PLANAR_CONFIGURATION field
        TIFFField planarConfigurationField =
            dir.getField(TIFFImageDecoder.TIFF_PLANAR_CONFIGURATION);
        char[] planarConfiguration = planarConfigurationField == null ?
            new char[] {1} :
            planarConfigurationField.getAsChars();

            // Support planar format (band sequential) only for 1 sample/pixel.
            if (planarConfiguration[0] != 1 && samplesPerPixel != 1) {
                throw new RuntimeException("TIFFImage0");
            }

            // Read the TIFF_BITS_PER_SAMPLE field
            TIFFField bitsField =
                dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE);
            char[] bitsPerSample = null;
            if(bitsField != null) {
                bitsPerSample = bitsField.getAsChars();
            } else {
                bitsPerSample = new char[] {1};

                // Ensure that all samples have the same bit depth.
                for (int i = 1; i < bitsPerSample.length; i++) {
                    if (bitsPerSample[i] != bitsPerSample[0]) {
                        throw new RuntimeException("TIFFImage1");
                    }
                }
            }
            sampleSize = bitsPerSample[0];

            // Read the TIFF_SAMPLE_FORMAT tag to see whether the data might be
            // signed or floating point
            TIFFField sampleFormatField =
                dir.getField(TIFFImageDecoder.TIFF_SAMPLE_FORMAT);

            char[] sampleFormat = null;
            if (sampleFormatField != null) {
                sampleFormat = sampleFormatField.getAsChars();

                // Check that all the samples have the same format
                for (int l=1; l<sampleFormat.length; l++) {
                    if (sampleFormat[l] != sampleFormat[0]) {
                        throw new RuntimeException("TIFFImage2");
                    }
                }

            } else {
                sampleFormat = new char[] {1};
            }

            // Set the data type based on the sample size and format.
            boolean isValidDataFormat = false;
            switch(sampleSize) {
            case 1:
            case 4:
            case 8:
                if(sampleFormat[0] != 3) {
                    // Ignore whether signed or unsigned: treat all as unsigned.
                    dataType = DataBuffer.TYPE_BYTE;
                    isValidDataFormat = true;
                }
                break;
            case 16:
                if(sampleFormat[0] != 3) {
                    dataType = sampleFormat[0] == 2 ?
                        DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
                    isValidDataFormat = true;
                }
                break;
            case 32:
              if (sampleFormat[0] == 3)
                isValidDataFormat = false;
              else {
                dataType = DataBuffer.TYPE_INT;
                isValidDataFormat = true;
              }
              break;
            }

            if(!isValidDataFormat) {
                throw new RuntimeException("TIFFImage3");
            }

            // Figure out what compression if any, is being used.
            TIFFField compField = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION);
            compression = compField == null ? COMP_NONE : compField.getAsInt(0);

            // Get the photometric interpretation.
            int photometricType = (int)dir.getFieldAsLong(
                                                          TIFFImageDecoder.TIFF_PHOTOMETRIC_INTERPRETATION);

            // Determine which kind of image we are dealing with.
            imageType = TYPE_UNSUPPORTED;
            switch(photometricType) {
            case 0: // WhiteIsZero
                isWhiteZero = true;
            case 1: // BlackIsZero
                if(sampleSize == 1 && samplesPerPixel == 1) {
                    imageType = TYPE_BILEVEL;
                } else if(sampleSize == 4 && samplesPerPixel == 1) {
                    imageType = TYPE_GRAY_4BIT;
                } else if(sampleSize % 8 == 0) {
                    if(samplesPerPixel == 1) {
                        imageType = TYPE_GRAY;
                    } else if(samplesPerPixel == 2) {
                        imageType = TYPE_GRAY_ALPHA;
                    } else {
                        imageType = TYPE_GENERIC;
                    }
                }
                break;
            case 2: // RGB
                if(sampleSize % 8 == 0) {
                    if(samplesPerPixel == 3) {
                        imageType = TYPE_RGB;
                    } else if(samplesPerPixel == 4) {
                        imageType = TYPE_RGB_ALPHA;
                    } else {
                        imageType = TYPE_GENERIC;
                    }
                }
                break;
            case 3: // RGB Palette
                if(samplesPerPixel == 1 &&
                   (sampleSize == 4 || sampleSize == 8 || sampleSize == 16)) {
                    imageType = TYPE_PALETTE;
                }
                break;
            case 4: // Transparency mask
                if(sampleSize == 1 && samplesPerPixel == 1) {
                    imageType = TYPE_BILEVEL;
                }
                break;
            case 6: // YCbCr
                if(compression == COMP_JPEG_TTN2 &&
                   sampleSize == 8 && samplesPerPixel == 3) {
                    // Set color conversion flag.
                    colorConvertJPEG = param.getJPEGDecompressYCbCrToRGB();

                    // Set type to RGB if color converting.
                    imageType = colorConvertJPEG ? TYPE_RGB : TYPE_GENERIC;
                } else {
                    TIFFField chromaField = dir.getField(TIFF_YCBCR_SUBSAMPLING);
                    if(chromaField != null) {
                        chromaSubH = chromaField.getAsInt(0);
                        chromaSubV = chromaField.getAsInt(1);
                    } else {
                        chromaSubH = chromaSubV = 2;
                    }

                    if(chromaSubH*chromaSubV == 1) {
                        imageType = TYPE_GENERIC;
                    } else if(sampleSize == 8 && samplesPerPixel == 3) {
                        imageType = TYPE_YCBCR_SUB;
                    }
                }
                break;
            default: // Other including CMYK, CIE L*a*b*, unknown.
                if(sampleSize % 8 == 0) {
                    imageType = TYPE_GENERIC;
                }
            }

            // Bail out if not one of the supported types.
            if(imageType == TYPE_UNSUPPORTED) {
                throw new RuntimeException("TIFFImage4");
            }

            // Set basic image layout
            Rectangle bounds = new Rectangle
                (0, 0,
                 (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_WIDTH),
                 (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH));

            // Set a preliminary band count. This may be changed later as needed.
            numBands = samplesPerPixel;

            // Figure out if any extra samples are present.
            TIFFField efield = dir.getField(TIFFImageDecoder.TIFF_EXTRA_SAMPLES);
            int extraSamples = efield == null ? 0 : (int)efield.getAsLong(0);

            int tileWidth, tileHeight;
            if (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS) != null) {
                tiled = true;
                // Image is in tiled format
                tileWidth =
                    (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH);
                tileHeight =
                    (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH);
                tileOffsets =
                    (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS)).getAsLongs();
                tileByteCounts =
                    getFieldAsLongs(dir.getField(TIFFImageDecoder.TIFF_TILE_BYTE_COUNTS));

            } else {
                tiled = false;

                // Image is in stripped format, looks like tiles to us
                // Note: Some legacy files may have tile width and height
                // written but use the strip offsets and byte counts fields
                // instead of the tile offsets and byte counts. Therefore
                // we default here to the tile dimensions if they are written.
                tileWidth =
                    dir.getField(TIFFImageDecoder.TIFF_TILE_WIDTH) != null ?
                    (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH) :
                    bounds.width;
                TIFFField field =
                    dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP);
                if (field == null) {
                    // Default is infinity (2^32 -1), basically the entire image

                    tileHeight =
                        dir.getField(TIFFImageDecoder.TIFF_TILE_LENGTH) != null ?
                        (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH):
                        bounds.height;
                } else {
                    long l = field.getAsLong(0);
                    long infinity = 1;
                    infinity = (infinity << 32) - 1;
                    if (l == infinity) {
                        // 2^32 - 1 (effectively infinity, entire image is 1 strip)
                        tileHeight = bounds.height;
                    } else {
                        tileHeight = (int)l;
                    }
                }

                TIFFField tileOffsetsField =
                    dir.getField(TIFFImageDecoder.TIFF_STRIP_OFFSETS);
                if (tileOffsetsField == null) {
                    throw new RuntimeException("TIFFImage5");
                } else {
                    tileOffsets = getFieldAsLongs(tileOffsetsField);
                }

                TIFFField tileByteCountsField =
                    dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS);
                if (tileByteCountsField == null) {
                    throw new RuntimeException("TIFFImage6");
                } else {
                    tileByteCounts = getFieldAsLongs(tileByteCountsField);
                }
            }

            // Calculate number of tiles and the tileSize in bytes
            tilesX = (bounds.width + tileWidth - 1)/tileWidth;
            tilesY = (bounds.height + tileHeight - 1)/tileHeight;
            tileSize = tileWidth * tileHeight * numBands;

            // Check whether big endian or little endian format is used.
            isBigEndian = dir.isBigEndian();

            TIFFField fillOrderField =
                dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER);
            if (fillOrderField != null) {
                fillOrder = fillOrderField.getAsInt(0);
            } else {
                // Default Fill Order
                fillOrder = 1;
            }

            switch(compression) {
            case COMP_NONE:
            case COMP_PACKBITS:
                // Do nothing.
                break;
            case COMP_DEFLATE:
                inflater = new Inflater();
                break;
            case COMP_FAX_G3_1D:
            case COMP_FAX_G3_2D:
            case COMP_FAX_G4_2D:
                if(sampleSize != 1) {
                    throw new RuntimeException("TIFFImage7");
                }

                // Fax T.4 compression options
                if (compression == 3) {
                    TIFFField t4OptionsField =
                        dir.getField(TIFFImageDecoder.TIFF_T4_OPTIONS);
                    if (t4OptionsField != null) {
                        tiffT4Options = t4OptionsField.getAsLong(0);
                    } else {
                        // Use default value
                        tiffT4Options = 0;
                    }
                }

                // Fax T.6 compression options
                if (compression == 4) {
                    TIFFField t6OptionsField =
                        dir.getField(TIFFImageDecoder.TIFF_T6_OPTIONS);
                    if (t6OptionsField != null) {
                        tiffT6Options = t6OptionsField.getAsLong(0);
                    } else {
                        // Use default value
                        tiffT6Options = 0;
                    }
                }

                // Fax encoding, need to create the Fax decoder.
                decoder = new TIFFFaxDecoder(fillOrder,
                                             tileWidth, tileHeight);
                break;

            case COMP_LZW:
                // LZW compression used, need to create the LZW decoder.
                TIFFField predictorField =
                    dir.getField(TIFFImageDecoder.TIFF_PREDICTOR);

                if (predictorField == null) {
                    predictor = 1;
                } else {
                    predictor = predictorField.getAsInt(0);

                    if (predictor != 1 && predictor != 2) {
                        throw new RuntimeException("TIFFImage8");
                    }

                    if (predictor == 2 && sampleSize != 8) {
                        throw new RuntimeException(sampleSize +
                                                   "TIFFImage9");
                    }
                }

                lzwDecoder = new TIFFLZWDecoder(tileWidth, predictor,
                                                samplesPerPixel);
                break;

            case COMP_JPEG_OLD:
                throw new RuntimeException("TIFFImage15");

            case COMP_JPEG_TTN2:
                if(!(sampleSize == 8 &&
                     ((imageType == TYPE_GRAY && samplesPerPixel == 1) ||
                      (imageType == TYPE_PALETTE && samplesPerPixel == 1) ||
                      (imageType == TYPE_RGB && samplesPerPixel == 3)))) {
                    throw new RuntimeException("TIFFImage16");
                }

                // Create decodeParam from JPEGTables field if present.
                if(dir.isTagPresent(TIFF_JPEG_TABLES)) {
                    TIFFField jpegTableField = dir.getField(TIFF_JPEG_TABLES);
                    byte[] jpegTable = jpegTableField.getAsBytes();
                    ByteArrayInputStream tableStream =
                        new ByteArrayInputStream(jpegTable);
                    JPEGImageDecoder decoder =
                        JPEGCodec.createJPEGDecoder(tableStream);
                    decoder.decodeAsRaster();
                    decodeParam = decoder.getJPEGDecodeParam();
                }

                break;
            default:
                throw new RuntimeException("TIFFImage10");
            }

            ColorModel  colorModel  = null;
            SampleModel sampleModel = null;
            switch(imageType) {
            case TYPE_BILEVEL:
            case TYPE_GRAY_4BIT:
                sampleModel =
                    new MultiPixelPackedSampleModel(dataType,
                                                    tileWidth,
                                                    tileHeight,
                                                    sampleSize);
                if(imageType == TYPE_BILEVEL) {
                    byte[] map = new byte[] {(byte)(isWhiteZero ? 255 : 0),
                                             (byte)(isWhiteZero ? 0 : 255)};
                    colorModel = new IndexColorModel(1, 2, map, map, map);
                } else {
                    byte [] map = new byte[16];
                    if (isWhiteZero) {
                        for (int i=0; i<map.length; i++)
                            map[i] = (byte)(255-(16*i));
                    } else {
                        for (int i=0; i<map.length; i++)
                            map[i] = (byte)(16*i);
                    }
                    colorModel = new IndexColorModel(4, 16, map, map, map);
                }
                break;

            case TYPE_GRAY:
            case TYPE_GRAY_ALPHA:
            case TYPE_RGB:
            case TYPE_RGB_ALPHA:
                // Create a pixel interleaved SampleModel with decreasing
                // band offsets.
                int[] reverseOffsets = new int[numBands];
                for (int i=0; i<numBands; i++) {
                    reverseOffsets[i] = numBands - 1 - i;
                }
                sampleModel = new PixelInterleavedSampleModel
                    (dataType, tileWidth, tileHeight,
                     numBands, numBands*tileWidth, reverseOffsets);

                if(imageType == TYPE_GRAY) {
                  colorModel = new ComponentColorModel
                    (ColorSpace.getInstance(ColorSpace.CS_GRAY),
                     new int[] { sampleSize }, false, false,
                     Transparency.OPAQUE, dataType);
                } else if (imageType == TYPE_RGB) {
                  colorModel = new ComponentColorModel
                    (ColorSpace.getInstance(ColorSpace.CS_sRGB),
                     new int[] { sampleSize, sampleSize, sampleSize },
                     false, false, Transparency.OPAQUE, dataType);
                } else { // hasAlpha
                    // Transparency.OPAQUE signifies image data that is
                    // completely opaque, meaning that all pixels have an alpha
                    // value of 1.0. So the extra band gets ignored, which is
                    // what we want.
                    int transparency = Transparency.OPAQUE;
                    if(extraSamples == 1) { // associated (premultiplied) alpha
                        transparency = Transparency.TRANSLUCENT;
                    } else if(extraSamples == 2) { // unassociated alpha
                        transparency = Transparency.BITMASK;
                    }

                    colorModel =
                        createAlphaComponentColorModel(dataType,
                                                       numBands,
                                                       extraSamples == 1,
                                                       transparency);
                }
                break;

            case TYPE_GENERIC:
            case TYPE_YCBCR_SUB:
                // For this case we can't display the image, so we create a
                // SampleModel with increasing bandOffsets, and keep the
                // ColorModel as null, as there is no appropriate ColorModel.

                int[] bandOffsets = new int[numBands];
                for (int i=0; i<numBands; i++) {
                    bandOffsets[i] = i;
                }

                sampleModel = new PixelInterleavedSampleModel
                    (dataType, tileWidth, tileHeight,
                     numBands, numBands * tileWidth, bandOffsets);
                colorModel = null;
                break;

            case TYPE_PALETTE:
                // Get the colormap
                TIFFField cfield = dir.getField(TIFFImageDecoder.TIFF_COLORMAP);
                if (cfield == null) {
                    throw new RuntimeException("TIFFImage11");
                } else {
                    colormap = cfield.getAsChars();
                }

                // Could be either 1 or 3 bands depending on whether we use
                // IndexColorModel or not.
                if (decodePaletteAsShorts) {
                    numBands = 3;

                    // If no SampleFormat tag was specified and if the
                    // sampleSize is less than or equal to 8, then the
                    // dataType was initially set to byte, but now we want to
                    // expand the palette as shorts, so the dataType should
                    // be ushort.
                    if (dataType == DataBuffer.TYPE_BYTE) {
                        dataType = DataBuffer.TYPE_USHORT;
                    }

                    // Data will have to be unpacked into a 3 band short image
                    // as we do not have a IndexColorModel that can deal with
                    // a colormodel whose entries are of short data type.
                    sampleModel = createPixelInterleavedSampleModel
                        (dataType, tileWidth, tileHeight, numBands);

                  colorModel = new ComponentColorModel
                    (ColorSpace.getInstance(ColorSpace.CS_sRGB),
                     new int[] { 16, 16, 16 }, false, false,
                     Transparency.OPAQUE, dataType);

                } else {

                    numBands = 1;

                    if (sampleSize == 4) {
                        // Pixel data will not be unpacked, will use
                        // MPPSM to store packed data and
                        // IndexColorModel to do the unpacking.
                        sampleModel = new MultiPixelPackedSampleModel
                            (DataBuffer.TYPE_BYTE, tileWidth, tileHeight,
                             sampleSize);
                    } else if (sampleSize == 8) {

                        sampleModel = createPixelInterleavedSampleModel
                            (DataBuffer.TYPE_BYTE, tileWidth, tileHeight,
                             numBands);
                    } else if (sampleSize == 16) {

                        // Here datatype has to be unsigned since we
                        // are storing indices into the
                        // IndexColorModel palette. Ofcourse the
                        // actual palette entries are allowed to be
                        // negative.
                        dataType = DataBuffer.TYPE_USHORT;
                        sampleModel = createPixelInterleavedSampleModel
                            (DataBuffer.TYPE_USHORT, tileWidth, tileHeight,
                             numBands);
                    }

                    int bandLength = colormap.length/3;
                    byte[] r = new byte[bandLength];
                    byte[] g = new byte[bandLength];
                    byte[] b = new byte[bandLength];

                    int gIndex = bandLength;
                    int bIndex = bandLength * 2;

                    if (dataType == DataBuffer.TYPE_SHORT) {

                        for (int i=0; i<bandLength; i++) {
                            r[i] = param.decodeSigned16BitsTo8Bits
                                ((short)colormap[i]);
                            g[i] = param.decodeSigned16BitsTo8Bits
                                ((short)colormap[gIndex+i]);
                            b[i] = param.decodeSigned16BitsTo8Bits
                                ((short)colormap[bIndex+i]);
                        }

                    } else {

                        for (int i=0; i<bandLength; i++) {
                            r[i] = param.decode16BitsTo8Bits
                                (colormap[i] & 0xffff);
                            g[i] = param.decode16BitsTo8Bits
                                (colormap[gIndex+i] & 0xffff);
                            b[i] = param.decode16BitsTo8Bits
                                (colormap[bIndex+i] & 0xffff);
                        }

                    }

                    colorModel = new IndexColorModel(sampleSize,
                                                     bandLength, r, g, b);
                }
                break;

            default:
                throw new RuntimeException("TIFFImage4");
            }

        Map properties = new HashMap();
        // Set a property "tiff_directory".
        properties.put("tiff_directory", dir);

        // System.out.println("Constructed TIFF");

        init((CachableRed)null, bounds, colorModel, sampleModel,
             0, 0, properties);
    }

    /**
     * Reads a private IFD from a given offset in the stream.  This
     * method may be used to obtain IFDs that are referenced
     * only by private tag values.
     */
    public TIFFDirectory getPrivateIFD(long offset) throws IOException {
        return new TIFFDirectory(stream, offset, 0);
    }


    public WritableRaster copyData(WritableRaster wr) {
        copyToRaster(wr);
        return wr;
    }


    /**
     * Returns tile (tileX, tileY) as a Raster.
     */
    public synchronized Raster getTile(int tileX, int tileY) {
        if ((tileX < 0) || (tileX >= tilesX) ||
            (tileY < 0) || (tileY >= tilesY)) {
            throw new IllegalArgumentException("TIFFImage12");
        }

        // System.out.println("Called TIFF getTile:" + tileX + "," + tileY);


        // Get the data array out of the DataBuffer
        byte[] bdata = null;
        short[] sdata = null;
        int[] idata = null;

        SampleModel sampleModel = getSampleModel();
        WritableRaster tile = makeTile(tileX,tileY);

        DataBuffer buffer = tile.getDataBuffer();

        int dataType = sampleModel.getDataType();
        if (dataType == DataBuffer.TYPE_BYTE) {
            bdata = ((DataBufferByte)buffer).getData();
        } else if (dataType == DataBuffer.TYPE_USHORT) {
            sdata = ((DataBufferUShort)buffer).getData();
        } else if (dataType == DataBuffer.TYPE_SHORT) {
            sdata = ((DataBufferShort)buffer).getData();
        } else if (dataType == DataBuffer.TYPE_INT) {
            idata = ((DataBufferInt)buffer).getData();
        }

        // Variables used for swapping when converting from RGB to BGR
        byte bswap;
        short sswap;
        int iswap;

        // Save original file pointer position and seek to tile data location.
        long save_offset = 0;
        try {
            save_offset = stream.getFilePointer();
            stream.seek(tileOffsets[tileY*tilesX + tileX]);
        } catch (IOException ioe) {
            throw new RuntimeException("TIFFImage13");
        }

        // Number of bytes in this tile (strip) after compression.
        int byteCount = (int)tileByteCounts[tileY*tilesX + tileX];

        // Find out the number of bytes in the current tile
        Rectangle newRect;
        if (!tiled)
            newRect = tile.getBounds();
        else
            newRect = new Rectangle(tile.getMinX(), tile.getMinY(),
                                    tileWidth, tileHeight);

        int unitsInThisTile = newRect.width * newRect.height * numBands;

        // Allocate read buffer if needed.
        byte[] data = compression != COMP_NONE || imageType == TYPE_PALETTE ?
            new byte[byteCount] : null;

        // Read the data, uncompressing as needed. There are four cases:
        // bilevel, palette-RGB, 4-bit grayscale, and everything else.
        if(imageType == TYPE_BILEVEL) { // bilevel
            try {
                if (compression == COMP_PACKBITS) {
                    stream.readFully(data, 0, byteCount);

                    // Since the decompressed data will still be packed
                    // 8 pixels into 1 byte, calculate bytesInThisTile
                    int bytesInThisTile;
                    if ((newRect.width % 8) == 0) {
                        bytesInThisTile = (newRect.width/8) * newRect.height;
                    } else {
                        bytesInThisTile =
                            (newRect.width/8 + 1) * newRect.height;
                    }
                    decodePackbits(data, bytesInThisTile, bdata);
                } else if (compression == COMP_LZW) {
                    stream.readFully(data, 0, byteCount);
                    lzwDecoder.decode(data, bdata, newRect.height);
                } else if (compression == COMP_FAX_G3_1D) {
                    stream.readFully(data, 0, byteCount);
                    decoder.decode1D(bdata, data, 0, newRect.height);
                } else if (compression == COMP_FAX_G3_2D) {
                    stream.readFully(data, 0, byteCount);
                    decoder.decode2D(bdata, data, 0, newRect.height,
                                     tiffT4Options);
                } else if (compression == COMP_FAX_G4_2D) {
                    stream.readFully(data, 0, byteCount);
                    decoder.decodeT6(bdata, data, 0, newRect.height,
                                     tiffT6Options);
                } else if (compression == COMP_DEFLATE) {
                    stream.readFully(data, 0, byteCount);
                    inflate(data, bdata);
                } else if (compression == COMP_NONE) {
                    stream.readFully(bdata, 0, byteCount);
                }

                stream.seek(save_offset);
            } catch (IOException ioe) {
                throw new RuntimeException("TIFFImage13");
            }
        } else if(imageType == TYPE_PALETTE) { // palette-RGB
            if (sampleSize == 16) {

                if (decodePaletteAsShorts) {

                    short[] tempData= null;

                    // At this point the data is 1 banded and will
                    // become 3 banded only after we've done the palette
                    // lookup, since unitsInThisTile was calculated with
                    // 3 bands, we need to divide this by 3.
                    int unitsBeforeLookup = unitsInThisTile / 3;

                    // Since unitsBeforeLookup is the number of shorts,
                    // but we do our decompression in terms of bytes, we
                    // need to multiply it by 2 in order to figure out
                    // how many bytes we'll get after decompression.
                    int entries = unitsBeforeLookup * 2;

                    // Read the data, if compressed, decode it, reset the pointer
                    try {

                        if (compression == COMP_PACKBITS) {

                            stream.readFully(data, 0, byteCount);

                            byte[] byteArray = new byte[entries];
                            decodePackbits(data, entries, byteArray);
                            tempData = new short[unitsBeforeLookup];
                            interpretBytesAsShorts(byteArray, tempData,
                                                   unitsBeforeLookup);

                        }  else if (compression == COMP_LZW) {

                            // Read in all the compressed data for this tile
                            stream.readFully(data, 0, byteCount);

                            byte[] byteArray = new byte[entries];
                            lzwDecoder.decode(data, byteArray, newRect.height);
                            tempData = new short[unitsBeforeLookup];
                            interpretBytesAsShorts(byteArray, tempData,
                                                   unitsBeforeLookup);

                        }  else if (compression == COMP_DEFLATE) {

                            stream.readFully(data, 0, byteCount);
                            byte[] byteArray = new byte[entries];
                            inflate(data, byteArray);
                            tempData = new short[unitsBeforeLookup];
                            interpretBytesAsShorts(byteArray, tempData,
                                                   unitsBeforeLookup);

                        } else if (compression == COMP_NONE) {

                            // byteCount tells us how many bytes are there
                            // in this tile, but we need to read in shorts,
                            // which will take half the space, so while
                            // allocating we divide byteCount by 2.
                            tempData = new short[byteCount/2];
                            readShorts(byteCount/2, tempData);
                        }

                        stream.seek(save_offset);

                    } catch (IOException ioe) {
                        throw new RuntimeException("TIFFImage13");
                    }

                    if (dataType == DataBuffer.TYPE_USHORT) {

                        // Expand the palette image into an rgb image with ushort
                        // data type.
                        int cmapValue;
                        int count = 0, lookup, len = colormap.length/3;
                        int len2 = len * 2;
                        for (int i=0; i<unitsBeforeLookup; i++) {
                            // Get the index into the colormap
                            lookup = tempData[i] & 0xffff;
                            // Get the blue value
                            cmapValue = colormap[lookup+len2];
                            sdata[count++] = (short)(cmapValue & 0xffff);
                            // Get the green value
                            cmapValue = colormap[lookup+len];
                            sdata[count++] = (short)(cmapValue & 0xffff);
                            // Get the red value
                            cmapValue = colormap[lookup];
                            sdata[count++] = (short)(cmapValue & 0xffff);
                        }

                    } else if (dataType == DataBuffer.TYPE_SHORT) {

                        // Expand the palette image into an rgb image with
                        // short data type.
                        int cmapValue;
                        int count = 0, lookup, len = colormap.length/3;
                        int len2 = len * 2;
                        for (int i=0; i<unitsBeforeLookup; i++) {
                            // Get the index into the colormap
                            lookup = tempData[i] & 0xffff;
                            // Get the blue value
                            cmapValue = colormap[lookup+len2];
                            sdata[count++] = (short)cmapValue;
                            // Get the green value
                            cmapValue = colormap[lookup+len];
                            sdata[count++] = (short)cmapValue;
                            // Get the red value
                            cmapValue = colormap[lookup];
                            sdata[count++] = (short)cmapValue;
                        }
                    }

                } else {

                    // No lookup being done here, when RGB values are needed,
                    // the associated IndexColorModel can be used to get them.

                    try {

                        if (compression == COMP_PACKBITS) {

                            stream.readFully(data, 0, byteCount);

                            // Since unitsInThisTile is the number of shorts,
                            // but we do our decompression in terms of bytes, we
                            // need to multiply unitsInThisTile by 2 in order to
                            // figure out how many bytes we'll get after
                            // decompression.
                            int bytesInThisTile = unitsInThisTile * 2;

                            byte[] byteArray = new byte[bytesInThisTile];
                            decodePackbits(data, bytesInThisTile, byteArray);
                            interpretBytesAsShorts(byteArray, sdata,
                                                   unitsInThisTile);

                        } else if (compression == COMP_LZW) {

                            stream.readFully(data, 0, byteCount);

                            // Since unitsInThisTile is the number of shorts,
                            // but we do our decompression in terms of bytes, we
                            // need to multiply unitsInThisTile by 2 in order to
                            // figure out how many bytes we'll get after
                            // decompression.
                            byte[] byteArray = new byte[unitsInThisTile * 2];
                            lzwDecoder.decode(data, byteArray, newRect.height);
                            interpretBytesAsShorts(byteArray, sdata,
                                                   unitsInThisTile);

                        }  else if (compression == COMP_DEFLATE) {

                            stream.readFully(data, 0, byteCount);
                            byte[] byteArray = new byte[unitsInThisTile * 2];
                            inflate(data, byteArray);
                            interpretBytesAsShorts(byteArray, sdata,
                                                   unitsInThisTile);

                        } else if (compression == COMP_NONE) {

                            readShorts(byteCount/2, sdata);
                        }

                        stream.seek(save_offset);

                    } catch (IOException ioe) {
                        throw new RuntimeException("TIFFImage13");
                    }
                }

            } else if (sampleSize == 8) {

                if (decodePaletteAsShorts) {

                    byte[] tempData= null;

                    // At this point the data is 1 banded and will
                    // become 3 banded only after we've done the palette
                    // lookup, since unitsInThisTile was calculated with
                    // 3 bands, we need to divide this by 3.
                    int unitsBeforeLookup = unitsInThisTile / 3;

                    // Read the data, if compressed, decode it, reset the pointer
                    try {

                        if (compression == COMP_PACKBITS) {

                            stream.readFully(data, 0, byteCount);
                            tempData = new byte[unitsBeforeLookup];
                            decodePackbits(data, unitsBeforeLookup, tempData);

                        }  else if (compression == COMP_LZW) {

                            stream.readFully(data, 0, byteCount);
                            tempData = new byte[unitsBeforeLookup];
                            lzwDecoder.decode(data, tempData, newRect.height);

                        } else if (compression == COMP_JPEG_TTN2) {

                            stream.readFully(data, 0, byteCount);
                            Raster tempTile = decodeJPEG(data,
                                                         decodeParam,
                                                         colorConvertJPEG,
                                                         tile.getMinX(),
                                                         tile.getMinY());
                            int[] tempPixels = new int[unitsBeforeLookup];
                            tempTile.getPixels(tile.getMinX(),
                                               tile.getMinY(),
                                               tile.getWidth(),
                                               tile.getHeight(),
                                               tempPixels);
                            tempData = new byte[unitsBeforeLookup];
                            for(int i = 0; i < unitsBeforeLookup; i++) {
                                tempData[i] = (byte)tempPixels[i];
                            }

                        }  else if (compression == COMP_DEFLATE) {

                            stream.readFully(data, 0, byteCount);
                            tempData = new byte[unitsBeforeLookup];
                            inflate(data, tempData);

                        } else if (compression == COMP_NONE) {

                            tempData = new byte[byteCount];
                            stream.readFully(tempData, 0, byteCount);
                        }

                        stream.seek(save_offset);

                    } catch (IOException ioe) {
                        throw new RuntimeException("TIFFImage13");
                    }

                    // Expand the palette image into an rgb image with ushort
                    // data type.
                    int cmapValue;
                    int count = 0, lookup, len = colormap.length/3;
                    int len2 = len * 2;
                    for (int i=0; i<unitsBeforeLookup; i++) {
                        // Get the index into the colormap
                        lookup = tempData[i] & 0xff;
                        // Get the blue value
                        cmapValue = colormap[lookup+len2];
                        sdata[count++] = (short)(cmapValue & 0xffff);
                        // Get the green value
                        cmapValue = colormap[lookup+len];
                        sdata[count++] = (short)(cmapValue & 0xffff);
                        // Get the red value
                        cmapValue = colormap[lookup];
                        sdata[count++] = (short)(cmapValue & 0xffff);
                    }
                } else {

                    // No lookup being done here, when RGB values are needed,
                    // the associated IndexColorModel can be used to get them.

                    try {

                        if (compression == COMP_PACKBITS) {

                            stream.readFully(data, 0, byteCount);
                            decodePackbits(data, unitsInThisTile, bdata);

                        } else if (compression == COMP_LZW) {

                            stream.readFully(data, 0, byteCount);
                            lzwDecoder.decode(data, bdata, newRect.height);

                        } else if (compression == COMP_JPEG_TTN2) {

                            stream.readFully(data, 0, byteCount);
                            tile.setRect(decodeJPEG(data,
                                                    decodeParam,
                                                    colorConvertJPEG,
                                                    tile.getMinX(),
                                                    tile.getMinY()));

                        }  else if (compression == COMP_DEFLATE) {

                            stream.readFully(data, 0, byteCount);
                            inflate(data, bdata);

                        } else if (compression == COMP_NONE) {

                            stream.readFully(bdata, 0, byteCount);
                        }

                        stream.seek(save_offset);

                    } catch (IOException ioe) {
                        throw new RuntimeException("TIFFImage13");
                    }
                }

            } else if (sampleSize == 4) {

                int padding = (newRect.width % 2 == 0) ? 0 : 1;
                int bytesPostDecoding = ((newRect.width/2 + padding) *
                                         newRect.height);

                // Output short images
                if (decodePaletteAsShorts) {

                    byte[] tempData = null;

                    try {
                        stream.readFully(data, 0, byteCount);
                        stream.seek(save_offset);
                    } catch (IOException ioe) {
                        throw new RuntimeException("TIFFImage13");
                    }

                    // If compressed, decode the data.
                    if (compression == COMP_PACKBITS) {

                        tempData = new byte[bytesPostDecoding];
                        decodePackbits(data, bytesPostDecoding, tempData);

                    }  else if (compression == COMP_LZW) {

                        tempData = new byte[bytesPostDecoding];
                        lzwDecoder.decode(data, tempData, newRect.height);

                    }  else if (compression == COMP_DEFLATE) {

                        tempData = new byte[bytesPostDecoding];
                        inflate(data, tempData);

                    } else if (compression == COMP_NONE) {

                        tempData = data;
                    }

                    int bytes = unitsInThisTile / 3;

                    // Unpack the 2 pixels packed into each byte.
                    data = new byte[bytes];

                    int srcCount = 0, dstCount = 0;
                    for (int j=0; j<newRect.height; j++) {
                        for (int i=0; i<newRect.width/2; i++) {
                            data[dstCount++] =
                                (byte)((tempData[srcCount] & 0xf0) >> 4);
                            data[dstCount++] =
                                (byte)(tempData[srcCount++] & 0x0f);
                        }

                        if (padding == 1) {
                            data[dstCount++] =
                                (byte)((tempData[srcCount++] & 0xf0) >> 4);
                        }
                    }

                    int len = colormap.length/3;
                    int len2 = len*2;
                    int cmapValue, lookup;
                    int count = 0;
                    for (int i=0; i<bytes; i++) {
                        lookup = data[i] & 0xff;
                        cmapValue = colormap[lookup+len2];
                        sdata[count++] = (short)(cmapValue & 0xffff);
                        cmapValue = colormap[lookup+len];
                        sdata[count++] = (short)(cmapValue & 0xffff);
                        cmapValue = colormap[lookup];
                        sdata[count++] = (short)(cmapValue & 0xffff);
                    }
                } else {

                    // Output byte values, use IndexColorModel for unpacking
                    try {

                        // If compressed, decode the data.
                        if (compression == COMP_PACKBITS) {

                            stream.readFully(data, 0, byteCount);
                            decodePackbits(data, bytesPostDecoding, bdata);

                        }  else if (compression == COMP_LZW) {

                            stream.readFully(data, 0, byteCount);
                            lzwDecoder.decode(data, bdata, newRect.height);

                        }  else if (compression == COMP_DEFLATE) {

                            stream.readFully(data, 0, byteCount);
                            inflate(data, bdata);

                        } else if (compression == COMP_NONE) {

                            stream.readFully(bdata, 0, byteCount);
                        }

                        stream.seek(save_offset);

                    } catch (IOException ioe) {
                        throw new RuntimeException("TIFFImage13");
                    }
                }
            }
        } else if(imageType == TYPE_GRAY_4BIT) { // 4-bit gray
            try {
                if (compression == COMP_PACKBITS) {

                    stream.readFully(data, 0, byteCount);

                    // 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(data, bytesInThisTile, bdata);

                } else if (compression == COMP_LZW) {

                    stream.readFully(data, 0, byteCount);
                    lzwDecoder.decode(data, bdata, newRect.height);

                }  else if (compression == COMP_DEFLATE) {

                    stream.readFully(data, 0, byteCount);
                    inflate(data, bdata);

                } else {

                    stream.readFully(bdata, 0, byteCount);
                }

                stream.seek(save_offset);
            } catch (IOException ioe) {
                throw new RuntimeException("TIFFImage13");
            }
        } else { // everything else
            try {

                if (sampleSize == 8) {

                    if (compression == COMP_NONE) {
                        stream.readFully(bdata, 0, byteCount);

                    } else if (compression == COMP_LZW) {

                        stream.readFully(data, 0, byteCount);
                        lzwDecoder.decode(data, bdata, newRect.height);

                    } else if (compression == COMP_PACKBITS) {

                        stream.readFully(data, 0, byteCount);
                        decodePackbits(data, unitsInThisTile, bdata);

                    } else if (compression == COMP_JPEG_TTN2) {

                        stream.readFully(data, 0, byteCount);
                        tile.setRect(decodeJPEG(data,
                                                decodeParam,
                                                colorConvertJPEG,
                                                tile.getMinX(),
                                                tile.getMinY()));
                    } else if (compression == COMP_DEFLATE) {

                        stream.readFully(data, 0, byteCount);
                        inflate(data, bdata);
                    }

                } else if (sampleSize == 16) {

                    if (compression == COMP_NONE) {

                        readShorts(byteCount/2, sdata);

                    } else if (compression == COMP_LZW) {

                        stream.readFully(data, 0, byteCount);

                        // Since unitsInThisTile is the number of shorts,
                        // but we do our decompression in terms of bytes, we
                        // need to multiply unitsInThisTile by 2 in order to
                        // figure out how many bytes we'll get after
                        // decompression.
                        byte[] byteArray = new byte[unitsInThisTile * 2];
                        lzwDecoder.decode(data, byteArray, newRect.height);
                        interpretBytesAsShorts(byteArray, sdata,
                                               unitsInThisTile);

                    } else if (compression == COMP_PACKBITS) {

                        stream.readFully(data, 0, byteCount);

                        // Since unitsInThisTile is the number of shorts,
                        // but we do our decompression in terms of bytes, we
                        // need to multiply unitsInThisTile by 2 in order to
                        // figure out how many bytes we'll get after
                        // decompression.
                        int bytesInThisTile = unitsInThisTile * 2;

                        byte[] byteArray = new byte[bytesInThisTile];
                        decodePackbits(data, bytesInThisTile, byteArray);
                        interpretBytesAsShorts(byteArray, sdata,
                                               unitsInThisTile);
                    } else if (compression == COMP_DEFLATE) {

                        stream.readFully(data, 0, byteCount);
                        byte[] byteArray = new byte[unitsInThisTile * 2];
                        inflate(data, byteArray);
                        interpretBytesAsShorts(byteArray, sdata,
                                               unitsInThisTile);

                    }
                } else if (sampleSize == 32 &&
                           dataType == DataBuffer.TYPE_INT) { // redundant
                    if (compression == COMP_NONE) {

                        readInts(byteCount/4, idata);

                    } else if (compression == COMP_LZW) {

                        stream.readFully(data, 0, byteCount);

                        // Since unitsInThisTile is the number of ints,
                        // but we do our decompression in terms of bytes, we
                        // need to multiply unitsInThisTile by 4 in order to
                        // figure out how many bytes we'll get after
                        // decompression.
                        byte[] byteArray = new byte[unitsInThisTile * 4];
                        lzwDecoder.decode(data, byteArray, newRect.height);
                        interpretBytesAsInts(byteArray, idata,
                                             unitsInThisTile);

                    } else if (compression == COMP_PACKBITS) {

                        stream.readFully(data, 0, byteCount);

                        // Since unitsInThisTile is the number of ints,
                        // but we do our decompression in terms of bytes, we
                        // need to multiply unitsInThisTile by 4 in order to
                        // figure out how many bytes we'll get after
                        // decompression.
                        int bytesInThisTile = unitsInThisTile * 4;

                        byte[] byteArray = new byte[bytesInThisTile];
                        decodePackbits(data, bytesInThisTile, byteArray);
                        interpretBytesAsInts(byteArray, idata,
                                             unitsInThisTile);
                    } else if (compression == COMP_DEFLATE) {

                        stream.readFully(data, 0, byteCount);
                        byte[] byteArray = new byte[unitsInThisTile * 4];
                        inflate(data, byteArray);
                        interpretBytesAsInts(byteArray, idata,
                                             unitsInThisTile);

                    }
                }

                stream.seek(save_offset);

            } catch (IOException ioe) {
                throw new RuntimeException("TIFFImage13");
            }

            // Modify the data for certain special cases.
            switch(imageType) {
            case TYPE_GRAY:
            case TYPE_GRAY_ALPHA:
                if(isWhiteZero) {
                    // Since we are using a ComponentColorModel with this
                    // image, we need to change the WhiteIsZero data to
                    // BlackIsZero data so it will display properly.
                    if (dataType == DataBuffer.TYPE_BYTE &&
                        !(getColorModel() instanceof IndexColorModel)) {

                        for (int l = 0; l < bdata.length; l += numBands) {
                            bdata[l] = (byte)(255 - bdata[l]);
                        }
                    } else if (dataType == DataBuffer.TYPE_USHORT) {

                        int ushortMax = Short.MAX_VALUE - Short.MIN_VALUE;
                        for (int l = 0; l < sdata.length; l += numBands) {
                            sdata[l] = (short)(ushortMax - sdata[l]);
                        }

                    } else if (dataType == DataBuffer.TYPE_SHORT) {

                        for (int l = 0; l < sdata.length; l += numBands) {
                            sdata[l] = (short)(~sdata[l]);
                        }
                    } else if (dataType == DataBuffer.TYPE_INT) {

                        long uintMax = ((long)Integer.MAX_VALUE -
                                        (long)Integer.MIN_VALUE);
                        for (int l = 0; l < idata.length; l += numBands) {
                            idata[l] = (int)(uintMax - idata[l]);
                        }
                    }
                }
                break;
            case TYPE_RGB:
                // Change RGB to BGR order, as Java2D displays that faster.
                // Unnecessary for JPEG-in-TIFF as the decoder handles it.
                if (sampleSize == 8 && compression != COMP_JPEG_TTN2) {
                    for (int i=0; i<unitsInThisTile; i+=3) {
                        bswap = bdata[i];
                        bdata[i] = bdata[i+2];
                        bdata[i+2] = bswap;
                    }
                } else if (sampleSize == 16) {
                    for (int i=0; i<unitsInThisTile; i+=3) {
                        sswap = sdata[i];
                        sdata[i] = sdata[i+2];
                        sdata[i+2] = sswap;
                    }
                } else if (sampleSize == 32) {
                    if(dataType == DataBuffer.TYPE_INT) {
                        for (int i=0; i<unitsInThisTile; i+=3) {
                            iswap = idata[i];
                            idata[i] = idata[i+2];
                            idata[i+2] = iswap;
                        }
                    }
                }
                break;
            case TYPE_RGB_ALPHA:
                // Convert from RGBA to ABGR for Java2D
                if (sampleSize == 8) {
                    for (int i=0; i<unitsInThisTile; i+=4) {
                        // Swap R and A
                        bswap = bdata[i];
                        bdata[i] = bdata[i+3];
                        bdata[i+3] = bswap;

                        // Swap G and B
                        bswap = bdata[i+1];
                        bdata[i+1] = bdata[i+2];
                        bdata[i+2] = bswap;
                    }
                } else if (sampleSize == 16) {
                    for (int i=0; i<unitsInThisTile; i+=4) {
                        // Swap R and A
                        sswap = sdata[i];
                        sdata[i] = sdata[i+3];
                        sdata[i+3] = sswap;

                        // Swap G and B
                        sswap = sdata[i+1];
                        sdata[i+1] = sdata[i+2];
                        sdata[i+2] = sswap;
                    }
                } else if (sampleSize == 32) {
                    if(dataType == DataBuffer.TYPE_INT) {
                        for (int i=0; i<unitsInThisTile; i+=4) {
                            // Swap R and A
                            iswap = idata[i];
                            idata[i] = idata[i+3];
                            idata[i+3] = iswap;

                            // Swap G and B
                            iswap = idata[i+1];
                            idata[i+1] = idata[i+2];
                            idata[i+2] = iswap;
                        }
                    }
                }
                break;
            case TYPE_YCBCR_SUB:
                // Post-processing for YCbCr with subsampled chrominance:
                // simply replicate the chroma channels for displayability.
                int pixelsPerDataUnit = chromaSubH*chromaSubV;

                int numH = newRect.width/chromaSubH;
                int numV = newRect.height/chromaSubV;

                byte[] tempData = new byte[numH*numV*(pixelsPerDataUnit + 2)];
                System.arraycopy(bdata, 0, tempData, 0, tempData.length);

                int samplesPerDataUnit = pixelsPerDataUnit*3;
                int[] pixels = new int[samplesPerDataUnit];

                int bOffset = 0;
                int offsetCb = pixelsPerDataUnit;
                int offsetCr = offsetCb + 1;

                int y = newRect.y;
                for(int j = 0; j < numV; j++) {
                    int x = newRect.x;
                    for(int i = 0; i < numH; i++) {
                        int Cb = tempData[bOffset + offsetCb];
                        int Cr = tempData[bOffset + offsetCr];
                        int k = 0;
                        while(k < samplesPerDataUnit) {
                            pixels[k++] = tempData[bOffset++];
                            pixels[k++] = Cb;
                            pixels[k++] = Cr;
                        }
                        bOffset += 2;
                        tile.setPixels(x, y, chromaSubH, chromaSubV, pixels);
                        x += chromaSubH;
                    }
                    y += chromaSubV;
                }

                break;
            }
        }

        return tile;
    }

    private void readShorts(int shortCount, short[] shortArray) {

        // Since each short consists of 2 bytes, we need a
        // byte array of double size
        int byteCount = 2 * shortCount;
        byte[] byteArray = new byte[byteCount];

        try {
            stream.readFully(byteArray, 0, byteCount);
        } catch (IOException ioe) {
            throw new RuntimeException("TIFFImage13");
        }

        interpretBytesAsShorts(byteArray, shortArray, shortCount);
    }

    private void readInts(int intCount, int[] intArray) {

        // Since each int consists of 4 bytes, we need a
        // byte array of quadruple size
        int byteCount = 4 * intCount;
        byte[] byteArray = new byte[byteCount];

        try {
            stream.readFully(byteArray, 0, byteCount);
        } catch (IOException ioe) {
            throw new RuntimeException("TIFFImage13");
        }

        interpretBytesAsInts(byteArray, intArray, intCount);
    }

    // Method to interpret a byte array to a short array, depending on
    // whether the bytes are stored in a big endian or little endian format.
    private void interpretBytesAsShorts(byte[] byteArray,
                                        short[] shortArray,
                                        int shortCount) {

        int j = 0;
        int firstByte, secondByte;

        if (isBigEndian) {

            for (int i=0; i<shortCount; i++) {
                firstByte = byteArray[j++] & 0xff;
                secondByte = byteArray[j++] & 0xff;
                shortArray[i] = (short)((firstByte << 8) + secondByte);
            }

        } else {

            for (int i=0; i<shortCount; i++) {
                firstByte = byteArray[j++] & 0xff;
                secondByte = byteArray[j++] & 0xff;
                shortArray[i] = (short)((secondByte << 8) + firstByte);
            }
        }
    }

    // Method to interpret a byte array to a int array, depending on
    // whether the bytes are stored in a big endian or little endian format.
    private void interpretBytesAsInts(byte[] byteArray,
                                      int[] intArray,
                                      int intCount) {

        int j = 0;

        if (isBigEndian) {

            for (int i=0; i<intCount; i++) {
                intArray[i] = (((byteArray[j++] & 0xff) << 24) |
                               ((byteArray[j++] & 0xff) << 16) |
                               ((byteArray[j++] & 0xff) << 8) |
                               ( byteArray[j++] & 0xff));
            }

        } else {

            for (int i=0; i<intCount; i++) {
                intArray[i] = ((byteArray[j++] & 0xff) |
                              ((byteArray[j++] & 0xff) << 8) |
                              ((byteArray[j++] & 0xff) << 16) |
                              ((byteArray[j++] & 0xff) << 24));
            }
        }
    }

    // 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("TIFFImage14");
        }

        return dst;
    }

    // Need a createColorModel().
    // Create ComponentColorModel for TYPE_RGB images
    private ComponentColorModel createAlphaComponentColorModel
    (int dataType, int numBands,
     boolean isAlphaPremultiplied, int transparency) {

        ComponentColorModel ccm = null;
        int[] RGBBits = null;
        ColorSpace cs = null;
        switch(numBands) {
            case 2: // gray+alpha
                cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
                break;
            case 4: // RGB+alpha
                cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
                break;
            default:
                throw new IllegalArgumentException();
        }

        int componentSize = 0;
        switch(dataType) {
            case DataBuffer.TYPE_BYTE:
                componentSize = 8;
                break;
            case DataBuffer.TYPE_USHORT:
            case DataBuffer.TYPE_SHORT:
                componentSize = 16;
                break;
            case DataBuffer.TYPE_INT:
                componentSize = 32;
                break;
            default:
                throw new IllegalArgumentException();
        }

        RGBBits = new int[numBands];
        for(int i = 0; i < numBands; i++) {
            RGBBits[i] = componentSize;
        }

        ccm = new ComponentColorModel(cs,
                                      RGBBits,
                                      true,
                                      isAlphaPremultiplied,
                                      transparency,
                                      dataType);


        return ccm;
    }

}
