    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.imaging.formats.tiff.datareaders;
    018
    019import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_1D;
    020import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_GROUP_3;
    021import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_GROUP_4;
    022import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_DEFLATE_PKZIP;
    023import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_DEFLATE_ADOBE;
    024import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_LZW;
    025import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_PACKBITS;
    026import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_UNCOMPRESSED;
    027import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_FLAG_T4_OPTIONS_2D;
    028import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_FLAG_T4_OPTIONS_FILL;
    029import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE;
    030import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE;
    031
    032import java.awt.Rectangle;
    033import java.io.ByteArrayInputStream;
    034import java.io.IOException;
    035import java.io.InputStream;
    036import java.nio.ByteOrder;
    037import java.util.Arrays;
    038
    039import org.apache.commons.imaging.ImageReadException;
    040import org.apache.commons.imaging.common.ImageBuilder;
    041import org.apache.commons.imaging.common.PackBits;
    042import org.apache.commons.imaging.common.itu_t4.T4AndT6Compression;
    043import org.apache.commons.imaging.common.mylzw.MyLzwDecompressor;
    044import org.apache.commons.imaging.common.ZlibDeflate;
    045import org.apache.commons.imaging.formats.tiff.TiffRasterData;
    046import org.apache.commons.imaging.formats.tiff.TiffDirectory;
    047import org.apache.commons.imaging.formats.tiff.TiffField;
    048import org.apache.commons.imaging.formats.tiff.constants.TiffPlanarConfiguration;
    049import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants;
    050import org.apache.commons.imaging.formats.tiff.photometricinterpreters.PhotometricInterpreter;
    051
    052/**
    053 * Defines the base class for the TIFF file reader classes. The TIFF format
    054 * defines two broad organizations for image pixel storage: strips and tiles.
    055 * This class defines common elements for both representations.
    056 * <p>
    057 * <strong>The TIFF Floating-Point Formats </strong>
    058 * <p>
    059 * In addition to providing images, TIFF files can supply data in the form of
    060 * numerical values. As of March 2020 the Commons Imaging library was extended
    061 * to support some floating-point data formats.
    062 * <p>
    063 * Unfortunately, the TIFF floating-point format allows for a lot of different
    064 * variations. At this time, only the most widely used of these are supported.
    065 * When this code was written, only a small set of test data products were
    066 * available. Thus it is likely that developers will wish to extend the range of
    067 * floating-point data that can be processed as additional test data become
    068 * available. When implementing extensions to this logic, developers are
    069 * reminded that image processing requires the handling of literally millions of
    070 * pixels, so attention to performance is essential to a successful
    071 * implementation (please see the notes in {@link DataReaderStrips} for more
    072 * information).
    073 * <p>
    074 * The TIFF floating-point specification is poorly documented. So these
    075 * notes are included to provide clarification on at least some aspects of the
    076 * format. Some documentation and C-code examples are available in "TIFF
    077 * Technical Note 3, April 8, 2005)".
    078 * <p>
    079 * <strong>The Predictor==3 Case</strong>
    080 * <p>
    081 * TIFF specifies an extension for a predictor that is intended to improve data
    082 * compression ratios for floating-point values. This predictor is specified
    083 * using the TIFF predictor TAG with a value of 3 (see TIFF Technical Note 3).
    084 * Consider a 4-byte floating point value given in IEEE-754 format. Let f3 be
    085 * the high-order byte, with f2 the next highest, followed by f1, and f0 for the
    086 * low-order byte. This designation should not be confused with the in-memory
    087 * layout of the bytes (little-endian versus big-endian), but rather their
    088 * numerical values. The sign bit and upper 7 bits of the exponent are given in
    089 * the high-order byte, followed by the one remaining exponent bit and the
    090 * mantissa in the lower-order bytes.
    091 * <p>
    092 * In many real-valued raster data sets, the sign and magnitude (exponent) of
    093 * the values change slowly. But the bits in the mantissa vary rapidly in a
    094 * semi-random manner. The information entropy in the mantissa tends to increase
    095 * in the lowest ordered bytes. Thus, the high-order bytes have more redundancy
    096 * than the low-order bytes and can compress more efficiently. To exploit this,
    097 * the TIFF format splits the bytes into groups based on their
    098 * order-of-magnitude. This splitting process takes place on a ROW-BY-ROW basis
    099 * (note the emphasis, this point is not clearly documented in the spec). For
    100 * example, for a row of length 3 pixels -- A, B, and C -- the data for two rows
    101 * would be given as shown below (again, ignoring endian issues):
    102 * <pre>
    103 *   Original:
    104 *      A3 A2 A1 A0   B3 B2 B1 B0   C3 C2 C1 C0
    105 *      D3 D3 D1 D0   E3 E2 E2 E0   F3 F2 F1 F0
    106 *
    107 *   Bytes split into groups by order-of-magnitude:
    108 *      A3 B3 C3   A2 B2 C2   A1 B1 C1   A0 B0 C0
    109 *      D3 E3 F3   D2 E2 F2   D1 E1 F1   D0 E0 F0
    110 * </pre> To further improve the compression, the predictor takes the difference
    111 * of each subsequent bytes. Again, the differences (deltas) are computed on a
    112 * row-byte-row basis. For the most part, the differences combine bytes
    113 * associated with the same order-of-magnitude, though there is a special
    114 * transition at the end of each order-of-magnitude set (shown in parentheses):
    115 * <pre>
    116 *      A3, B3-A3, C3-B3, (A2-C3), B2-A2, C2-B2, (A1-C2), etc.
    117 *      D3, E3-D3, F3-D3, (D2-F3), E3-D2, etc.
    118 * </pre> Once the predictor transform is complete, the data is stored using
    119 * conventional data compression techniques such as Deflate or LZW. In practice,
    120 * floating point data does not compress especially well, but using the above
    121 * technique, the TIFF process typically reduces the overall storage size by 20
    122 * to 30 percent (depending on the data). The TIFF Technical Note 3 specifies 3
    123 * data size formats for storing floating point values:
    124 * <pre>
    125 *     32 bits    IEEE-754 single-precision standard
    126 *     16 bits    IEEE-754 half-precision standard
    127 *     24 bits    A non-standard representation
    128 * </pre> At this time, we have not obtained data samples for the smaller
    129 * representations used in combination with a predictor.
    130 * <p>
    131 * <strong>Interleaved formats</strong>
    132 * <p>
    133 * TIFF Technical Note 3 also provides example code for cases where each pixel
    134 * (or raster cell) in the image is associated with more than one floating-point
    135 * samples. Data in this format might be used for real-valued vector data,
    136 * complex-valued pairs, or other numerical applications).
    137 * <p>At this time, we have encountered only a limited selection of the possible
    138 * configurations for multi-variable data. The code below only supports those
    139 * configurations for which we had actual images that could be used to verify
    140 * our implementation.  The implementation supports the following formats:
    141 * <ul>
    142 * <li>32-bit floating-point data</li>
    143 * <li>Uncompressed, Deflate, or LZW compression</li>
    144 * <li>Optional horizontal predictors used with compression</li>
    145 * <li>PlanarConfiguration interleaved (CHUNKY) or non-interleaved (PLANAR)</li>
    146 * </ul>
    147 * <p>
    148 * Note that integer formats are not supported at this time.
    149 * <p>
    150 * Often, the TIFF files store multi-variable data in so that samples are
    151 * interleaved. For example, a configuration that gave two samples per pixel (or
    152 * cell) would give the two values for the first pixel in order followed by the
    153 * two values for the second pixel, etc. If a differencing approach were used
    154 * for data compression, the byte-stream would begin with the high-order byte
    155 * for each of the two samples for the first pixel, followed by the high-order
    156 * byte for each of the next two samples, and so forth for the remainder of the
    157 * row of pixels. It would then follow with the second-highest-order bytes for
    158 * the first two samples, etc.
    159 * <p>
    160 * This implementation also supports the non-interleaved (PLANAR) configuration.
    161 * One consideration in implementing this feature was that TIFF Technical Note 3
    162 * does not address the case where a TIFF image uses the alternate planar
    163 * configuration.  For conventional images, the TIFF specification (Revision 6.0)
    164 * recommends that the planar configuration should be avoided (see pg. 38).
    165 * But for numerical data products, the planar configuration may yield better
    166 * data compression in the case where different sample sets have different
    167 * statistical properties. Because separated groups often have more
    168 * uniformity and predictability than interleaved data sets, they sometimes lead
    169 * to a small improvement in storage-size reduction when data compression is
    170 * used.
    171 */
    172public abstract class ImageDataReader {
    173
    174    protected final TiffDirectory directory;
    175    protected final PhotometricInterpreter photometricInterpreter;
    176    private final int[] bitsPerSample;
    177    protected final int bitsPerSampleLength;
    178    private final int[] last;
    179
    180    protected final int predictor;
    181    protected final int samplesPerPixel;
    182    protected final int width;
    183    protected final int height;
    184    protected final int sampleFormat;
    185
    186    protected final TiffPlanarConfiguration planarConfiguration;
    187
    188    public ImageDataReader(final TiffDirectory directory,
    189        final PhotometricInterpreter photometricInterpreter, final int[] bitsPerSample,
    190        final int predictor, final int samplesPerPixel, final int sampleFormat,
    191        final int width, final int height, final TiffPlanarConfiguration planarConfiguration) {
    192        this.directory = directory;
    193        this.photometricInterpreter = photometricInterpreter;
    194        this.bitsPerSample = bitsPerSample;
    195        this.bitsPerSampleLength = bitsPerSample.length;
    196        this.samplesPerPixel = samplesPerPixel;
    197        this.sampleFormat = sampleFormat;
    198        this.predictor = predictor;
    199        this.width = width;
    200        this.height = height;
    201        this.planarConfiguration = planarConfiguration;
    202        last = new int[samplesPerPixel];
    203
    204    }
    205
    206    /**
    207     * Read the image data from the IFD associated with this instance of
    208     * ImageDataReader using the optional sub-image specification if desired.
    209     *
    210     * @param subImageSpecification a rectangle describing a sub-region of the
    211     * image for reading, or a null if the whole image is to be read.
    212     * @param hasAlpha indicates that the image has an alpha (transparency)
    213     * channel (RGB color model only).
    214     * @param isAlphaPremultiplied indicates that the image uses the associated
    215     * alpha channel format (pre-multiplied alpha).
    216     * @return a valid instance containing the pixel data from the image.
    217     * @throws ImageReadException in the event of a data format error or other
    218     * TIFF-specific failure.
    219     * @throws IOException in the event of an unrecoverable I/O error.
    220     */
    221    public abstract ImageBuilder readImageData(
    222            Rectangle subImageSpecification,
    223            boolean hasAlpha,
    224            boolean isAlphaPremultiplied)
    225            throws ImageReadException, IOException;
    226
    227    /**
    228     * Checks if all the bits per sample entries are the same size
    229     *
    230     * @param size the size to check
    231     * @return true if all the bits per sample entries are the same
    232     */
    233    protected boolean isHomogenous(final int size) {
    234        for (final int element : bitsPerSample) {
    235            if (element != size) {
    236                return false;
    237            }
    238        }
    239        return true;
    240    }
    241
    242    /**
    243     * Reads samples and returns them in an int array.
    244     *
    245     * @param bis the stream to read from
    246     * @param result the samples array to populate, must be the same length as
    247     * bitsPerSample.length
    248     * @throws IOException
    249     */
    250    void getSamplesAsBytes(final BitInputStream bis, final int[] result) throws IOException {
    251        for (int i = 0; i < bitsPerSample.length; i++) {
    252            final int bits = bitsPerSample[i];
    253            int sample = bis.readBits(bits);
    254            if (bits < 8) {
    255                final int sign = sample & 1;
    256                sample = sample << (8 - bits); // scale to byte.
    257                if (sign > 0) {
    258                    sample = sample | ((1 << (8 - bits)) - 1); // extend to byte
    259                }
    260            } else if (bits > 8) {
    261                sample = sample >> (bits - 8); // extend to byte.
    262            }
    263            result[i] = sample;
    264        }
    265    }
    266
    267    protected void resetPredictor() {
    268        Arrays.fill(last, 0);
    269    }
    270
    271    protected int[] applyPredictor(final int[] samples) {
    272        if (predictor == 2) {
    273            // Horizontal differencing.
    274            for (int i = 0; i < samples.length; i++) {
    275                samples[i] = 0xff & (samples[i] + last[i]);
    276                last[i] = samples[i];
    277            }
    278        }
    279
    280        return samples;
    281    }
    282
    283    protected void applyPredictorToBlock(final int width, final int height, final int nSamplesPerPixel, final byte []p ){
    284        final int k = width*nSamplesPerPixel;
    285        for(int i=0; i<height; i++){
    286            final int j0  = i*k+nSamplesPerPixel;
    287            final int j1 = (i+1)*k;
    288            for(int j=j0; j<j1; j++){
    289                p[j]+=p[j-nSamplesPerPixel];
    290            }
    291        }
    292    }
    293
    294    protected byte[] decompress(final byte[] compressedInput, final int compression,
    295            final int expectedSize, final int tileWidth, final int tileHeight)
    296            throws ImageReadException, IOException {
    297        final TiffField fillOrderField = directory.findField(TiffTagConstants.TIFF_TAG_FILL_ORDER);
    298        int fillOrder = TiffTagConstants.FILL_ORDER_VALUE_NORMAL;
    299        if (fillOrderField != null) {
    300            fillOrder = fillOrderField.getIntValue();
    301        }
    302        final byte[] compressedOrdered; // re-ordered bytes (if necessary)
    303        if (fillOrder == TiffTagConstants.FILL_ORDER_VALUE_NORMAL) {
    304            compressedOrdered = compressedInput;
    305            // good
    306        } else if (fillOrder == TiffTagConstants.FILL_ORDER_VALUE_REVERSED) {
    307            compressedOrdered = new byte[compressedInput.length];
    308            for (int i = 0; i < compressedInput.length; i++) {
    309                compressedOrdered[i] = (byte) (Integer.reverse(0xff & compressedInput[i]) >>> 24);
    310            }
    311        } else {
    312            throw new ImageReadException("TIFF FillOrder=" + fillOrder
    313                    + " is invalid");
    314        }
    315
    316        switch (compression) {
    317        case TIFF_COMPRESSION_UNCOMPRESSED: // None;
    318            return compressedOrdered;
    319        case TIFF_COMPRESSION_CCITT_1D: // CCITT Group 3 1-Dimensional Modified
    320                                        // Huffman run-length encoding.
    321            return T4AndT6Compression.decompressModifiedHuffman(compressedOrdered,
    322                    tileWidth, tileHeight);
    323        case TIFF_COMPRESSION_CCITT_GROUP_3: {
    324            int t4Options = 0;
    325            final TiffField field = directory.findField(TiffTagConstants.TIFF_TAG_T4_OPTIONS);
    326            if (field != null) {
    327                t4Options = field.getIntValue();
    328            }
    329            final boolean is2D = (t4Options & TIFF_FLAG_T4_OPTIONS_2D) != 0;
    330            final boolean usesUncompressedMode = (t4Options & TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE) != 0;
    331            if (usesUncompressedMode) {
    332                throw new ImageReadException(
    333                        "T.4 compression with the uncompressed mode extension is not yet supported");
    334            }
    335            final boolean hasFillBitsBeforeEOL = (t4Options & TIFF_FLAG_T4_OPTIONS_FILL) != 0;
    336            if (is2D) {
    337                return T4AndT6Compression.decompressT4_2D(compressedOrdered,
    338                        tileWidth, tileHeight, hasFillBitsBeforeEOL);
    339            }
    340            return T4AndT6Compression.decompressT4_1D(compressedOrdered,
    341                    tileWidth, tileHeight, hasFillBitsBeforeEOL);
    342        }
    343        case TIFF_COMPRESSION_CCITT_GROUP_4: {
    344            int t6Options = 0;
    345            final TiffField field = directory.findField(TiffTagConstants.TIFF_TAG_T6_OPTIONS);
    346            if (field != null) {
    347                t6Options = field.getIntValue();
    348            }
    349            final boolean usesUncompressedMode = (t6Options & TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE) != 0;
    350            if (usesUncompressedMode) {
    351                throw new ImageReadException(
    352                        "T.6 compression with the uncompressed mode extension is not yet supported");
    353            }
    354            return T4AndT6Compression.decompressT6(compressedOrdered, tileWidth,
    355                    tileHeight);
    356        }
    357        case TIFF_COMPRESSION_LZW: {
    358            final InputStream is = new ByteArrayInputStream(compressedOrdered);
    359
    360            final int lzwMinimumCodeSize = 8;
    361
    362            final MyLzwDecompressor myLzwDecompressor = new MyLzwDecompressor(
    363                    lzwMinimumCodeSize, ByteOrder.BIG_ENDIAN);
    364
    365            myLzwDecompressor.setTiffLZWMode();
    366
    367            return myLzwDecompressor.decompress(is, expectedSize);
    368        }
    369
    370        // Packbits
    371        case TIFF_COMPRESSION_PACKBITS: {
    372            return new PackBits().decompress(compressedOrdered, expectedSize);
    373        }
    374
    375        // deflate
    376        case TIFF_COMPRESSION_DEFLATE_ADOBE:
    377        case TIFF_COMPRESSION_DEFLATE_PKZIP: {
    378            return ZlibDeflate.decompress(compressedInput, expectedSize);
    379        }
    380
    381        default:
    382            throw new ImageReadException("Tiff: unknown/unsupported compression: " + compression);
    383        }
    384    }
    385
    386    /**
    387     * Given a source file that specifies the floating-point data format, unpack
    388     * the raw bytes obtained from the source file and organize them into an
    389     * array of integers containing the bit-equivalent of IEEE-754 32-bit
    390     * floats. Source files containing 64 bit doubles are downcast to floats.
    391     * <p>
    392     * This method supports either the tile format or the strip format of TIFF
    393     * source files. The scan size indicates the number of columns to be
    394     * extracted. For strips, the width and the scan size are always the full
    395     * width of the image. For tiles, the scan size is the full width of the
    396     * tile, but the width may be smaller in the cases where the tiles do not
    397     * evenly divide the width (for example, a 256 pixel wide tile in a 257
    398     * pixel wide image would result in two columns of tiles, the second column
    399     * having only one column of pixels that were worth extracting.
    400     *
    401     * @param width the width of the data block to be extracted
    402     * @param height the height of the data block to be extracted
    403     * @param scanSize the number of pixels in a single row of the block
    404     * @param bytes the raw bytes
    405     * @param bitsPerPixel the number of bits per sample, 32 or 64.
    406     * @param byteOrder the byte order for the source data
    407     * @return a valid array of integers in row major order, dimensions
    408     * scan-size wide and height height.
    409     * @throws ImageReadException in the event of an invalid format.
    410     */
    411    protected int[] unpackFloatingPointSamples(
    412        final int width,
    413        final int height,
    414        final int scanSize,
    415        final byte[] bytes,
    416        final int bitsPerPixel,
    417        final ByteOrder byteOrder)
    418        throws ImageReadException {
    419        final int bitsPerSample = bitsPerPixel / samplesPerPixel;
    420        final int bytesPerSample = bitsPerSample / 8;
    421        final int bytesPerScan = scanSize * samplesPerPixel * bytesPerSample;
    422        final int nBytes = bytesPerScan * height;
    423        final int length = bytes.length < nBytes ? nBytes / bytesPerScan : height;
    424        final int[] samples = new int[scanSize * samplesPerPixel * height];
    425        // floating-point differencing is indicated by a predictor value of 3.
    426        if (predictor == TiffTagConstants.PREDICTOR_VALUE_FLOATING_POINT_DIFFERENCING) {
    427            // at this time, this class supports the 32-bit format.  The
    428            // main reason for this is that we have not located sample data
    429            // that can be used for testing and analysis.
    430            if (bitsPerPixel / samplesPerPixel != 32) {
    431                throw new ImageReadException(
    432                    "Imaging does not yet support floating-point data"
    433                    + " with predictor type 3 for "
    434                    + bitsPerPixel + " bits per sample");
    435            }
    436
    437            if (planarConfiguration == TiffPlanarConfiguration.CHUNKY) {
    438                final int bytesInRow = scanSize * 4 * samplesPerPixel;
    439                for (int i = 0; i < length; i++) {
    440                    final int aOffset = i * bytesInRow;
    441                    final int bOffset = aOffset + scanSize * samplesPerPixel;
    442                    final int cOffset = bOffset + scanSize * samplesPerPixel;
    443                    final int dOffset = cOffset + scanSize * samplesPerPixel;
    444                    // in this loop, the source bytes give delta values.
    445                    // we adjust them to give true values.  This operation is
    446                    // done on a row-by-row basis.
    447                    for (int j = 1; j < bytesInRow; j++) {
    448                        bytes[aOffset + j] += bytes[aOffset + j - 1];
    449                    }
    450                    // pack the bytes into the integer bit-equivalent of
    451                    // floating point values
    452                    int index = i * scanSize;
    453                    for (int j = 0; j < width * samplesPerPixel; j++) {
    454                        final int a = bytes[aOffset + j];
    455                        final int b = bytes[bOffset + j];
    456                        final int c = bytes[cOffset + j];
    457                        final int d = bytes[dOffset + j];
    458                        // Pack the 4 byte components into a single integer
    459                        // in the byte order used by the TIFF standard
    460                        samples[index++] = ((a & 0xff) << 24)
    461                            | ((b & 0xff) << 16)
    462                            | ((c & 0xff) << 8)
    463                            | (d & 0xff);
    464                    }
    465                }
    466            } else {
    467                final int bytesInRow = scanSize * 4;
    468                for (int iPlane = 0; iPlane < samplesPerPixel; iPlane++) {
    469                    int planarIntOffset = iPlane * length * scanSize;
    470                    int planarByteOffset = planarIntOffset * 4;
    471
    472                    for (int i = 0; i < length; i++) {
    473                        final int aOffset = i * bytesInRow + planarByteOffset;
    474                        final int bOffset = aOffset + scanSize;
    475                        final int cOffset = bOffset + scanSize;
    476                        final int dOffset = cOffset + scanSize;
    477                        // in this loop, the source bytes give delta values.
    478                        // we adjust them to give true values.  This operation is
    479                        // done on a row-by-row basis.
    480                        for (int j = 1; j < bytesInRow; j++) {
    481                            bytes[aOffset + j] += bytes[aOffset + j - 1];
    482                        }
    483                        // pack the bytes into the integer bit-equivalent of
    484                        // floating point values
    485                        int index = planarIntOffset + i * scanSize;
    486                        for (int j = 0; j < width; j++) {
    487                            final int a = bytes[aOffset + j];
    488                            final int b = bytes[bOffset + j];
    489                            final int c = bytes[cOffset + j];
    490                            final int d = bytes[dOffset + j];
    491                            // Pack the 4 byte components into a single integer
    492                            // in the byte order used by the TIFF standard
    493                            samples[index++] = ((a & 0xff) << 24)
    494                                | ((b & 0xff) << 16)
    495                                | ((c & 0xff) << 8)
    496                                | (d & 0xff);
    497                        }
    498                    }
    499                }
    500
    501            }
    502            return samples;
    503        }  // end of predictor==3 case.
    504
    505        // simple packing case, 64 or 32 bits --------------------------
    506        if (bitsPerSample == 64) {
    507            int k = 0;
    508            int index = 0;
    509            for (int i = 0; i < length; i++) {
    510                for (int j = 0; j < scanSize; j++) {
    511                    final long b0 = bytes[k++] & 0xffL;
    512                    final long b1 = bytes[k++] & 0xffL;
    513                    final long b2 = bytes[k++] & 0xffL;
    514                    final long b3 = bytes[k++] & 0xffL;
    515                    final long b4 = bytes[k++] & 0xffL;
    516                    final long b5 = bytes[k++] & 0xffL;
    517                    final long b6 = bytes[k++] & 0xffL;
    518                    final long b7 = bytes[k++] & 0xffL;
    519                    long sbits;
    520                    if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
    521                        sbits = (b7 << 56)
    522                            | (b6 << 48)
    523                            | (b5 << 40)
    524                            | (b4 << 32)
    525                            | (b3 << 24)
    526                            | (b2 << 16)
    527                            | (b1 << 8)
    528                            | b0;
    529
    530                    } else {
    531                        sbits = (b0 << 56)
    532                            | (b1 << 48)
    533                            | (b2 << 40)
    534                            | (b3 << 32)
    535                            | (b4 << 24)
    536                            | (b5 << 16)
    537                            | (b6 << 8)
    538                            | b7;
    539                    }
    540                    // since the photometric interpreter does not
    541                    // currently support doubles, we need to replace this
    542                    // element with a float.  This action is inefficient and
    543                    // should be improved.
    544                    final float f = (float) Double.longBitsToDouble(sbits);
    545                    samples[index++] = Float.floatToRawIntBits(f);
    546                }
    547            }
    548        } else if (bitsPerSample == 32) {
    549            int k = 0;
    550            int index = 0;
    551            for (int i = 0; i < length; i++) {
    552                for (int j = 0; j < scanSize * samplesPerPixel; j++) {
    553                    final int b0 = bytes[k++] & 0xff;
    554                    final int b1 = bytes[k++] & 0xff;
    555                    final int b2 = bytes[k++] & 0xff;
    556                    final int b3 = bytes[k++] & 0xff;
    557                    int sbits;
    558                    if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
    559                        sbits
    560                            = (b3 << 24)
    561                            | (b2 << 16)
    562                            | (b1 << 8)
    563                            | b0;
    564
    565                    } else {
    566                        sbits
    567                            = (b0 << 24)
    568                            | (b1 << 16)
    569                            | (b2 << 8)
    570                            | b3;
    571                    }
    572                    // since the photometric interpreter does not
    573                    // currently support doubles, we need to replace this
    574                    // element with a float.  This action is inefficient and
    575                    // should be improved.
    576                    samples[index++] = sbits;
    577                }
    578            }
    579        } else {
    580            throw new ImageReadException(
    581                "Imaging does not support floating-point samples with "
    582                + bitsPerPixel + " bits per sample");
    583        }
    584
    585        return samples;
    586    }
    587
    588    /**
    589     * Given a source file that specifies numerical data as short integers,
    590     * unpack the raw bytes obtained from the source file and organize them into
    591     * an array of integers.
    592     * <p>
    593     * This method supports either the tile format or the strip format of TIFF
    594     * source files. The scan size indicates the number of columns to be
    595     * extracted. For strips, the width and the scan size are always the full
    596     * width of the image. For tiles, the scan size is the full width of the
    597     * tile, but the "width" parameter may be smaller in the cases where the
    598     * tiles do not evenly divide the width (for example, a 256 pixel wide tile
    599     * in a 257 pixel wide image would result in two columns of tiles, the
    600     * second column having only one column of pixels that were worth
    601     * extracting.
    602     *
    603     * @param width the width of the data block to be extracted
    604     * @param height the height of the data block to be extracted
    605     * @param scanSize the number of pixels in a single row of the block
    606     * @param bytes the raw bytes
    607     * @param predictor the predictor specified by the source, only predictor 3
    608     * is supported.
    609     * @param bitsPerSample the number of bits per sample, 32 or 64.
    610     * @param byteOrder the byte order for the source data
    611     * @return a valid array of integers in row major order, dimensions
    612     * scan-size wide and height height.
    613     */
    614    protected int[] unpackIntSamples(
    615        final int width,
    616        final int height,
    617        final int scanSize,
    618        final byte[] bytes,
    619        final int predictor,
    620        final int bitsPerSample,
    621        final ByteOrder byteOrder) {
    622        final int bytesPerSample = bitsPerSample / 8;
    623        final int nBytes = bytesPerSample * scanSize * height;
    624        final int length = bytes.length < nBytes ? nBytes / scanSize : height;
    625
    626        final int[] samples = new int[scanSize * height];
    627        // At this time, Commons Imaging only supports two-byte
    628        // two's complement short integers.  It is assumed that
    629        // the calling module already checked the arguments for
    630        // compliance, so this method simply assumes that they are correct.
    631
    632        // The logic that follows is simplified by the fact that
    633        // the existing API only supports two-byte signed integers.
    634        boolean useDifferencing
    635                = predictor == TiffTagConstants.PREDICTOR_VALUE_HORIZONTAL_DIFFERENCING;
    636
    637        for (int i = 0; i < length; i++) {
    638            int index = i * scanSize;
    639            int offset = index * bytesPerSample;
    640            if (bitsPerSample == 16) {
    641                if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
    642                    for (int j = 0; j < width; j++, offset += 2) {
    643                        samples[index + j]
    644                          = (bytes[offset + 1] << 8) | (bytes[offset] & 0xff);
    645                    }
    646                } else {
    647                    for (int j = 0; j < width; j++, offset += 2) {
    648                        samples[index + j]
    649                          = (bytes[offset] << 8) | (bytes[offset + 1] & 0xff);
    650                    }
    651                }
    652            } else if (bitsPerSample == 32) {
    653                if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
    654                    for (int j = 0; j < width; j++, offset += 4) {
    655                        samples[index + j]
    656                          = (bytes[offset + 3] << 24)
    657                          | ((bytes[offset + 2] & 0xff) << 16)
    658                          | ((bytes[offset + 1] & 0xff) << 8)
    659                          | (bytes[offset] & 0xff);
    660                    }
    661                } else {
    662                    for (int j = 0; j < width; j++, offset += 4) {
    663                        samples[index + j]
    664                          = (bytes[offset] << 24)
    665                          | ((bytes[offset + 1] & 0xff) << 16)
    666                          | ((bytes[offset + 2] & 0xff) << 8)
    667                          | (bytes[offset + 3] & 0xff);
    668                    }
    669                }
    670            }
    671            if (useDifferencing) {
    672                for (int j = 1; j < width; j++) {
    673                    samples[index + j] += samples[index + j - 1];
    674                }
    675            }
    676        }
    677
    678        return samples;
    679    }
    680
    681    /**
    682     * Transfer samples obtained from the TIFF file to a floating-point raster.
    683     *
    684     * @param xBlock coordinate of block relative to source data
    685     * @param yBlock coordinate of block relative to source data
    686     * @param blockWidth width of block, in pixels
    687     * @param blockHeight height of block in pixels
    688     * @param blockData the data for the block
    689     * @param xRaster coordinate of raster relative to source data
    690     * @param yRaster coordinate of raster relative to source data
    691     * @param rasterWidth width of the raster (always smaller than source data)
    692     * @param rasterHeight height of the raster (always smaller than source
    693     * data)
    694     * @param rasterData the raster data.
    695     */
    696    void transferBlockToRaster(final int xBlock, final int yBlock,
    697            final int blockWidth, final int blockHeight, final int[] blockData,
    698            final int xRaster, final int yRaster,
    699            final int rasterWidth, final int rasterHeight, int samplesPerPixel,
    700            final float[] rasterData) {
    701
    702        // xR0, yR0 are the coordinates within the raster (upper-left corner)
    703        // xR1, yR1 are ONE PAST the coordinates of the lower-right corner
    704        int xR0 = xBlock - xRaster;  // xR0, yR0 coordinates relative to
    705        int yR0 = yBlock - yRaster; // the raster
    706        int xR1 = xR0 + blockWidth;
    707        int yR1 = yR0 + blockHeight;
    708        if (xR0 < 0) {
    709            xR0 = 0;
    710        }
    711        if (yR0 < 0) {
    712            yR0 = 0;
    713        }
    714        if (xR1 > rasterWidth) {
    715            xR1 = rasterWidth;
    716        }
    717        if (yR1 > rasterHeight) {
    718            yR1 = rasterHeight;
    719        }
    720
    721        // Recall that the above logic may have adjusted xR0, xY0 so that
    722        // they are not necessarily point to the source pixel at xRaster, yRaster
    723        // we compute xSource = xR0+xRaster.
    724        //            xOffset = xSource-xBlock
    725        // since the block cannot be accessed with a negative offset,
    726        // we check for negatives and adjust xR0, yR0 upward as necessary
    727        int xB0 = xR0 + xRaster - xBlock;
    728        int yB0 = yR0 + yRaster - yBlock;
    729        if (xB0 < 0) {
    730            xR0 -= xB0;
    731            xB0 = 0;
    732        }
    733        if (yB0 < 0) {
    734            yR0 -= yB0;
    735            yB0 = 0;
    736        }
    737
    738        int w = xR1 - xR0;
    739        int h = yR1 - yR0;
    740        if (w <= 0 || h <= 0) {
    741            // The call to this method put the block outside the
    742            // bounds of the raster.  There is nothing to do.  Ideally,
    743            // this situation never arises, because it would mean that
    744            // the data was read from the file unnecessarily.
    745            return;
    746        }
    747        // see if the xR1, yR1 would extend past the limits of the block
    748        if (w > blockWidth) {
    749            w = blockWidth;
    750        }
    751        if (h > blockHeight) {
    752            h = blockHeight;
    753        }
    754
    755        // The TiffRasterData class expects data to be in the order
    756        // corresponding to TiffPlanarConfiguration.PLANAR.  So for the
    757        // multivariable case, we must convert CHUNKY data to PLANAR.
    758        if (samplesPerPixel == 1) {
    759            for (int i = 0; i < h; i++) {
    760                final int yR = yR0 + i;
    761                final int yB = yB0 + i;
    762                final int rOffset = yR * rasterWidth + xR0;
    763                final int bOffset = yB * blockWidth + xB0;
    764                for (int j = 0; j < w; j++) {
    765                    rasterData[rOffset + j] = Float.intBitsToFloat(blockData[bOffset + j]);
    766                }
    767            }
    768        } else if (this.planarConfiguration == TiffPlanarConfiguration.CHUNKY) {
    769            // The source data is in the interleaved (Chunky) order,
    770            // but the TiffRasterData class expects non-interleaved order.
    771            // So we transcribe the elements as appropriate.
    772            int pixelsPerPlane = rasterWidth * rasterHeight;
    773            for (int i = 0; i < h; i++) {
    774                final int yR = yR0 + i;
    775                final int yB = yB0 + i;
    776                final int rOffset = yR * rasterWidth + xR0;
    777                final int bOffset = yB * blockWidth + xB0;
    778                for (int j = 0; j < w; j++) {
    779                    for (int k = 0; k < samplesPerPixel; k++) {
    780                        rasterData[k * pixelsPerPlane + rOffset + j]
    781                                = Float.intBitsToFloat(blockData[(bOffset + j) * samplesPerPixel + k]);
    782                    }
    783                }
    784            }
    785        } else {
    786            for (int iPlane = 0; iPlane < samplesPerPixel; iPlane++) {
    787                int rPlanarOffset = iPlane * rasterWidth * rasterHeight;
    788                int bPlanarOffset = iPlane * blockWidth * blockHeight;
    789                for (int i = 0; i < h; i++) {
    790                    final int yR = yR0 + i;
    791                    final int yB = yB0 + i;
    792                    final int rOffset = rPlanarOffset + yR * rasterWidth + xR0;
    793                    final int bOffset = bPlanarOffset + yB * blockWidth + xB0;
    794                    for (int j = 0; j < w; j++) {
    795                        rasterData[rOffset + j] = Float.intBitsToFloat(blockData[bOffset + j]);
    796                    }
    797                }
    798            }
    799        }
    800
    801    }
    802
    803    /**
    804     * Transfer samples obtained from the TIFF file to an integer raster.
    805     *
    806     * @param xBlock coordinate of block relative to source data
    807     * @param yBlock coordinate of block relative to source data
    808     * @param blockWidth width of block, in pixels
    809     * @param blockHeight height of block in pixels
    810     * @param blockData the data for the block
    811     * @param xRaster coordinate of raster relative to source data
    812     * @param yRaster coordinate of raster relative to source data
    813     * @param rasterWidth width of the raster (always smaller than source data)
    814     * @param rasterHeight height of the raster (always smaller than source
    815     * data)
    816     * @param rasterData the raster data.
    817     */
    818    void transferBlockToRaster(final int xBlock, final int yBlock,
    819        final int blockWidth, final int blockHeight, final int[] blockData,
    820        final int xRaster, final int yRaster,
    821        final int rasterWidth, final int rasterHeight, final int[] rasterData) {
    822
    823        // xR0, yR0 are the coordinates within the raster (upper-left corner)
    824        // xR1, yR1 are ONE PAST the coordinates of the lower-right corner
    825        int xR0 = xBlock - xRaster;  // xR0, yR0 coordinates relative to
    826        int yR0 = yBlock - yRaster; // the raster
    827        int xR1 = xR0 + blockWidth;
    828        int yR1 = yR0 + blockHeight;
    829        if (xR0 < 0) {
    830            xR0 = 0;
    831        }
    832        if (yR0 < 0) {
    833            yR0 = 0;
    834        }
    835        if (xR1 > rasterWidth) {
    836            xR1 = rasterWidth;
    837        }
    838        if (yR1 > rasterHeight) {
    839            yR1 = rasterHeight;
    840        }
    841
    842        // Recall that the above logic may have adjusted xR0, xY0 so that
    843        // they are not necessarily point to the source pixel at xRaster, yRaster
    844        // we compute xSource = xR0+xRaster.
    845        //            xOffset = xSource-xBlock
    846        // since the block cannot be accessed with a negative offset,
    847        // we check for negatives and adjust xR0, yR0 upward as necessary
    848        int xB0 = xR0 + xRaster - xBlock;
    849        int yB0 = yR0 + yRaster - yBlock;
    850        if (xB0 < 0) {
    851            xR0 -= xB0;
    852            xB0 = 0;
    853        }
    854        if (yB0 < 0) {
    855            yR0 -= yB0;
    856            yB0 = 0;
    857        }
    858
    859        int w = xR1 - xR0;
    860        int h = yR1 - yR0;
    861        if (w <= 0 || h <= 0) {
    862            // The call to this method puts the block outside the
    863            // bounds of the raster.  There is nothing to do.  Ideally,
    864            // this situation never arises, because it would mean that
    865            // the data was read from the file unnecessarily.
    866            return;
    867        }
    868        // see if the xR1, yR1 would extend past the limits of the block
    869        if (w > blockWidth) {
    870            w = blockWidth;
    871        }
    872        if (h > blockHeight) {
    873            h = blockHeight;
    874        }
    875
    876        for (int i = 0; i < h; i++) {
    877            final int yR = yR0 + i;
    878            final int yB = yB0 + i;
    879            final int rOffset = yR * rasterWidth + xR0;
    880            final int bOffset = yB * blockWidth + xB0;
    881            System.arraycopy(blockData, bOffset, rasterData, rOffset, w);
    882        }
    883    }
    884
    885    /**
    886     * Defines a method for accessing the floating-point raster data in a TIFF
    887     * image. These implementations of this method in DataReaderStrips and
    888     * DataReaderTiled assume that this instance is of a compatible data type
    889     * (floating-point) and that all access checks have already been performed.
    890     *
    891     * @param subImage if non-null, instructs the access method to retrieve only
    892     * a sub-section of the image data.
    893     * @return a valid instance
    894     * @throws ImageReadException in the event of an incompatible data form.
    895     * @throws IOException in the event of I/O error.
    896     */
    897    public abstract TiffRasterData readRasterData(Rectangle subImage)
    898        throws ImageReadException, IOException;
    899}