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}