    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.awt.image.BufferedImage;
    034import java.io.ByteArrayInputStream;
    035import java.io.IOException;
    036import java.io.InputStream;
    037import java.nio.ByteOrder;
    038import java.util.Arrays;
    039
    040import org.apache.commons.imaging.ImageReadException;
    041import org.apache.commons.imaging.common.ImageBuilder;
    042import org.apache.commons.imaging.common.PackBits;
    043import org.apache.commons.imaging.common.itu_t4.T4AndT6Compression;
    044import org.apache.commons.imaging.common.mylzw.MyLzwDecompressor;
    045import org.apache.commons.imaging.common.ZlibDeflate;
    046import org.apache.commons.imaging.formats.tiff.TiffRasterData;
    047import org.apache.commons.imaging.formats.tiff.TiffDirectory;
    048import org.apache.commons.imaging.formats.tiff.TiffField;
    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
    067 * range of floating-point data that can be processed as
    068 * additional test data become available. When implementing extensions to this
    069 * logic, developers are reminded that image processing requires
    070 * the handling of literally millions of pixels, so attention to performance
    071 * is essential to a successful implementation (please see the notes in
    072 * DataReaderStrips.java for more information).
    073 * <p>
    074 * The TIFF floating-point specification is very 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
    086 * f1, and f0 for the low-order byte. This designation should not be confused
    087 * with the in-memory layout of the bytes (little-endian versus big-endian), but
    088 * rather their numerical values. The sign bit and upper 7 bits of the exponent
    089 * are given in the high-order byte, followed by the remaining sign bit and the
    090 * mantissa in the lower.
    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 order-of-magnitude.
    098 * This splitting process takes place on a ROW-BY-ROW basis (note the emphasis,
    099 * this point is not clearly documented in the spec). For example, for a row of
    100 * length 3 pixels -- A, B, and C -- the data for two rows would be given as
    101 * 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>
    111 * To further improve the compression, the predictor takes the difference
    112 * of each subsequent bytes. Again, the differences (deltas) are computed on a
    113 * row-byte-row basis. For the most part, the differences combine bytes
    114 * associated with the same order-of-magnitude, though there is a special
    115 * transition at the end of each order-of-magnitude set (shown in parentheses):
    116 * <pre>
    117 *      A3, B3-A3, C3-B3, (A2-C3), B2-A2, C2-B2, (A1-C2), etc.
    118 *      D3, E3-D3, F3-D3, (D2-F3), E3-D2, etc.
    119 * </pre>
    120 * Once the predictor transform is complete, the data is stored using
    121 * conventional data compression techniques such as Deflate or LZW. In practice,
    122 * floating point data does not compress especially well, but using the above
    123 * technique, the TIFF process typically reduces the overall storage size by 20
    124 * to 30 percent (depending on the data). The TIFF Technical Note 3 specifies 3
    125 * data size formats for storing floating point values:
    126 * <pre>
    127 *     32 bits    IEEE-754 single-precision standard
    128 *     16 bits    IEEE-754 half-precision standard
    129 *     24 bits    A non-standard representation
    130 * </pre>
    131 * At this time, we have not obtained data samples for the smaller
    132 * representations used in combination with a predictor.
    133 * <p>
    134 * <strong>Interleaved formats</strong>
    135 * <p>
    136 * TIFF Technical Note 3 also provides sample code for interleaved data, such as
    137 * a real-valued vector or a complex pair. At this time no samples of
    138 * interleaved data were available. As a caveat, the specification that the
    139 * document provides has disadvantages in terms of code complexity and
    140 * performance. Because the interleaved evaluation is embedded inside the pixel
    141 * row and column loops, it puts a lot of redundant conditional evaluations
    142 * inside the double nested loops. It is recommended that when interleaved data
    143 * is implemented, it should get their own block of code so as not to interfere
    144 * with the processing of the more common non-interleaved variations.
    145 */
    146@SuppressWarnings("PMD.TooManyStaticImports")
    147public abstract class ImageDataReader {
    148    protected final TiffDirectory directory;
    149    protected final PhotometricInterpreter photometricInterpreter;
    150    private final int[] bitsPerSample;
    151    protected final int bitsPerSampleLength;
    152    private final int[] last;
    153
    154    protected final int predictor;
    155    protected final int samplesPerPixel;
    156    protected final int width;
    157    protected final int height;
    158    protected final int sampleFormat;
    159
    160    public ImageDataReader(final TiffDirectory directory,
    161            final PhotometricInterpreter photometricInterpreter, final int[] bitsPerSample,
    162        final int predictor, final int samplesPerPixel, final int sampleFormat,
    163        final int width, final int height) {
    164        this.directory = directory;
    165        this.photometricInterpreter = photometricInterpreter;
    166        this.bitsPerSample = bitsPerSample;
    167        this.bitsPerSampleLength = bitsPerSample.length;
    168        this.samplesPerPixel = samplesPerPixel;
    169        this.sampleFormat = sampleFormat;
    170        this.predictor = predictor;
    171        this.width = width;
    172        this.height = height;
    173        last = new int[samplesPerPixel];
    174    }
    175
    176    // public abstract void readImageData(BufferedImage bi, ByteSource
    177    // byteSource)
    178    public abstract void readImageData(ImageBuilder imageBuilder)
    179            throws ImageReadException, IOException;
    180
    181
    182    public abstract BufferedImage readImageData(Rectangle subImage)
    183            throws ImageReadException, IOException;
    184
    185    /**
    186     * Checks if all the bits per sample entries are the same size
    187     * @param size the size to check
    188     * @return true if all the bits per sample entries are the same
    189     */
    190    protected boolean isHomogenous(final int size) {
    191        for (final int element : bitsPerSample) {
    192            if (element != size) {
    193                return false;
    194            }
    195        }
    196        return true;
    197    }
    198
    199    /**
    200     * Reads samples and returns them in an int array.
    201     *
    202     * @param bis
    203     *            the stream to read from
    204     * @param result
    205     *            the samples array to populate, must be the same length as
    206     *            bitsPerSample.length
    207     * @throws IOException
    208     */
    209    void getSamplesAsBytes(final BitInputStream bis, final int[] result) throws IOException {
    210        for (int i = 0; i < bitsPerSample.length; i++) {
    211            final int bits = bitsPerSample[i];
    212            int sample = bis.readBits(bits);
    213            if (bits < 8) {
    214                final int sign = sample & 1;
    215                sample = sample << (8 - bits); // scale to byte.
    216                if (sign > 0) {
    217                    sample = sample | ((1 << (8 - bits)) - 1); // extend to byte
    218                }
    219            } else if (bits > 8) {
    220                sample = sample >> (bits - 8); // extend to byte.
    221            }
    222            result[i] = sample;
    223        }
    224    }
    225
    226    protected void resetPredictor() {
    227        Arrays.fill(last, 0);
    228    }
    229
    230    protected int[] applyPredictor(final int[] samples) {
    231        if (predictor == 2) {
    232            // Horizontal differencing.
    233            for (int i = 0; i < samples.length; i++) {
    234                samples[i] = 0xff & (samples[i] + last[i]);
    235                last[i] = samples[i];
    236            }
    237        }
    238
    239        return samples;
    240    }
    241
    242    protected byte[] decompress(final byte[] compressedInput, final int compression,
    243            final int expectedSize, final int tileWidth, final int tileHeight)
    244            throws ImageReadException, IOException {
    245        final TiffField fillOrderField = directory.findField(TiffTagConstants.TIFF_TAG_FILL_ORDER);
    246        int fillOrder = TiffTagConstants.FILL_ORDER_VALUE_NORMAL;
    247        if (fillOrderField != null) {
    248            fillOrder = fillOrderField.getIntValue();
    249        }
    250        final byte[] compressedOrdered; // re-ordered bytes (if necessary)
    251        if (fillOrder == TiffTagConstants.FILL_ORDER_VALUE_NORMAL) {
    252            compressedOrdered = compressedInput;
    253            // good
    254        } else if (fillOrder == TiffTagConstants.FILL_ORDER_VALUE_REVERSED) {
    255            compressedOrdered = new byte[compressedInput.length];
    256            for (int i = 0; i < compressedInput.length; i++) {
    257                compressedOrdered[i] = (byte) (Integer.reverse(0xff & compressedInput[i]) >>> 24);
    258            }
    259        } else {
    260            throw new ImageReadException("TIFF FillOrder=" + fillOrder
    261                    + " is invalid");
    262        }
    263
    264        switch (compression) {
    265        case TIFF_COMPRESSION_UNCOMPRESSED: // None;
    266            return compressedOrdered;
    267        case TIFF_COMPRESSION_CCITT_1D: // CCITT Group 3 1-Dimensional Modified
    268                                        // Huffman run-length encoding.
    269            return T4AndT6Compression.decompressModifiedHuffman(compressedOrdered,
    270                    tileWidth, tileHeight);
    271        case TIFF_COMPRESSION_CCITT_GROUP_3: {
    272            int t4Options = 0;
    273            final TiffField field = directory.findField(TiffTagConstants.TIFF_TAG_T4_OPTIONS);
    274            if (field != null) {
    275                t4Options = field.getIntValue();
    276            }
    277            final boolean is2D = (t4Options & TIFF_FLAG_T4_OPTIONS_2D) != 0;
    278            final boolean usesUncompressedMode = (t4Options & TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE) != 0;
    279            if (usesUncompressedMode) {
    280                throw new ImageReadException(
    281                        "T.4 compression with the uncompressed mode extension is not yet supported");
    282            }
    283            final boolean hasFillBitsBeforeEOL = (t4Options & TIFF_FLAG_T4_OPTIONS_FILL) != 0;
    284            if (is2D) {
    285                return T4AndT6Compression.decompressT4_2D(compressedOrdered,
    286                        tileWidth, tileHeight, hasFillBitsBeforeEOL);
    287            }
    288            return T4AndT6Compression.decompressT4_1D(compressedOrdered,
    289                    tileWidth, tileHeight, hasFillBitsBeforeEOL);
    290        }
    291        case TIFF_COMPRESSION_CCITT_GROUP_4: {
    292            int t6Options = 0;
    293            final TiffField field = directory.findField(TiffTagConstants.TIFF_TAG_T6_OPTIONS);
    294            if (field != null) {
    295                t6Options = field.getIntValue();
    296            }
    297            final boolean usesUncompressedMode = (t6Options & TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE) != 0;
    298            if (usesUncompressedMode) {
    299                throw new ImageReadException(
    300                        "T.6 compression with the uncompressed mode extension is not yet supported");
    301            }
    302            return T4AndT6Compression.decompressT6(compressedOrdered, tileWidth,
    303                    tileHeight);
    304        }
    305        case TIFF_COMPRESSION_LZW: {
    306            final InputStream is = new ByteArrayInputStream(compressedOrdered);
    307
    308            final int lzwMinimumCodeSize = 8;
    309
    310            final MyLzwDecompressor myLzwDecompressor = new MyLzwDecompressor(
    311                    lzwMinimumCodeSize, ByteOrder.BIG_ENDIAN);
    312
    313            myLzwDecompressor.setTiffLZWMode();
    314
    315            return myLzwDecompressor.decompress(is, expectedSize);
    316        }
    317
    318        // Packbits
    319        case TIFF_COMPRESSION_PACKBITS: {
    320            return new PackBits().decompress(compressedOrdered, expectedSize);
    321        }
    322
    323        // deflate
    324        case TIFF_COMPRESSION_DEFLATE_ADOBE:
    325        case TIFF_COMPRESSION_DEFLATE_PKZIP: {
    326            return ZlibDeflate.decompress(compressedInput, expectedSize);
    327        }
    328
    329        default:
    330            throw new ImageReadException("Tiff: unknown/unsupported compression: " + compression);
    331        }
    332    }
    333
    334    /**
    335     * Given a source file that specifies the floating-point data format, unpack
    336     * the raw bytes obtained from the source file and organize them into an
    337     * array of integers containing the bit-equivalent of IEEE-754 32-bit
    338     * floats. Source files containing 64 bit doubles are downcast to floats.
    339     * <p>
    340     * This method supports either the tile format or the strip format of TIFF
    341     * source files. The scan size indicates the number of columns to be
    342     * extracted. For strips, the width and the scan size are always the full
    343     * width of the image. For tiles, the scan size is the full width of the
    344     * tile, but the width may be smaller in the cases where the tiles do not
    345     * evenly divide the width (for example, a 256 pixel wide tile in a 257
    346     * pixel wide image would result in two columns of tiles, the second column
    347     * having only one column of pixels that were worth extracting.
    348     *
    349     * @param width the width of the data block to be extracted
    350     * @param height the height of the data block to be extracted
    351     * @param scansize the number of pixels in a single row of the block
    352     * @param bytes the raw bytes
    353     * @param predictor the predictor specified by the source, only predictor 3
    354     * is supported.
    355     * @param bitsPerSample the number of bits per sample, 32 or 64.
    356     * @param byteOrder the byte order for the source data
    357     * @return a valid array of integers in row major order, dimensions
    358     * scan-size wide and height height.
    359     * @throws ImageReadException in the event of an invalid format.
    360     */
    361    protected int[] unpackFloatingPointSamples(
    362        int width,
    363        int height,
    364        int scansize,
    365        byte[] bytes,
    366        int predictor,
    367        int bitsPerSample, ByteOrder byteOrder)
    368        throws ImageReadException {
    369        int bytesPerSample = bitsPerSample / 8;
    370        int nBytes = bytesPerSample * scansize * height;
    371        int length = bytes.length < nBytes ? nBytes / scansize : height;
    372
    373        int[] samples = new int[scansize * height];
    374        // floating-point differencing is indicated by a predictor value of 3.
    375        if (predictor == TiffTagConstants.PREDICTOR_VALUE_FLOATING_POINT_DIFFERENCING) {
    376            // at this time, this class supports the 32-bit format.  The
    377            // main reason for this is that we have not located sample data
    378            // that can be used for testing and analysis.
    379            if (bitsPerSample != 32) {
    380                throw new ImageReadException(
    381                    "Imaging does not yet support floating-point data"
    382                    + " with predictor type 3 for "
    383                    + bitsPerSample + " bits per sample");
    384            }
    385            int bytesInRow = scansize * 4;
    386            for (int i = 0; i < length; i++) {
    387                int aOffset = i * bytesInRow;
    388                int bOffset = aOffset + scansize;
    389                int cOffset = bOffset + scansize;
    390                int dOffset = cOffset + scansize;
    391                // in this loop, the source bytes give delta values.
    392                // we adjust them to give true values.  This operation is
    393                // done on a row-by-row basis.
    394                for (int j = 1; j < bytesInRow; j++) {
    395                    bytes[aOffset + j] += bytes[aOffset + j - 1];
    396                }
    397                // pack the bytes into the integer bit-equivalent of
    398                // floating point values
    399                int index = i * scansize;
    400                for (int j = 0; j < width; j++) {
    401                    int a = bytes[aOffset + j];
    402                    int b = bytes[bOffset + j];
    403                    int c = bytes[cOffset + j];
    404                    int d = bytes[dOffset + j];
    405                    // Pack the 4 byte components into a single integer
    406                    // in the byte order used by the TIFF standard
    407                    samples[index++] = ((a & 0xff) << 24)
    408                        | ((b & 0xff) << 16)
    409                        | ((c & 0xff) << 8)
    410                        | (d & 0xff);
    411                }
    412            }
    413            return samples;
    414        }  // end of predictor==3 case.
    415
    416        // simple packing case, 64 or 32 bits --------------------------
    417        if (bitsPerSample == 64) {
    418            int k = 0;
    419            int index = 0;
    420            for (int i = 0; i < length; i++) {
    421                for (int j = 0; j < scansize; j++) {
    422                    long b0 = bytes[k++] & 0xffL;
    423                    long b1 = bytes[k++] & 0xffL;
    424                    long b2 = bytes[k++] & 0xffL;
    425                    long b3 = bytes[k++] & 0xffL;
    426                    long b4 = bytes[k++] & 0xffL;
    427                    long b5 = bytes[k++] & 0xffL;
    428                    long b6 = bytes[k++] & 0xffL;
    429                    long b7 = bytes[k++] & 0xffL;
    430                    long sbits;
    431                    if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
    432                        sbits = (b7 << 56)
    433                            | (b6 << 48)
    434                            | (b5 << 40)
    435                            | (b4 << 32)
    436                            | (b3 << 24)
    437                            | (b2 << 16)
    438                            | (b1 << 8)
    439                            | b0;
    440
    441                    } else {
    442                        sbits = (b0 << 56)
    443                            | (b1 << 48)
    444                            | (b2 << 40)
    445                            | (b3 << 32)
    446                            | (b4 << 24)
    447                            | (b5 << 16)
    448                            | (b6 << 8)
    449                            | b7;
    450                    }
    451                    // since the photometric interpreter does not
    452                    // currently support doubles, we need to replace this
    453                    // element with a float.  This action is inefficient and
    454                    // should be improved.
    455                    float f = (float) Double.longBitsToDouble(sbits);
    456                    samples[index++] = Float.floatToRawIntBits(f);
    457                }
    458            }
    459        } else if (bitsPerSample == 32) {
    460            int k = 0;
    461            int index = 0;
    462            for (int i = 0; i < length; i++) {
    463                for (int j = 0; j < scansize; j++) {
    464                    int b0 = bytes[k++] & 0xff;
    465                    int b1 = bytes[k++] & 0xff;
    466                    int b2 = bytes[k++] & 0xff;
    467                    int b3 = bytes[k++] & 0xff;
    468                    int sbits;
    469                    if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
    470                        sbits
    471                            = (b3 << 24)
    472                            | (b2 << 16)
    473                            | (b1 << 8)
    474                            | b0;
    475
    476                    } else {
    477                        sbits
    478                            = (b0 << 24)
    479                            | (b1 << 16)
    480                            | (b2 << 8)
    481                            | b3;
    482                    }
    483                    // since the photometric interpreter does not
    484                    // currently support doubles, we need to replace this
    485                    // element with a float.  This action is inefficient and
    486                    // should be improved.
    487                    samples[index++] = sbits;
    488                }
    489            }
    490        } else {
    491            throw new ImageReadException(
    492                "Imaging does not support floating-point samples with "
    493                + bitsPerSample + " bits per sample");
    494        }
    495
    496        return samples;
    497    }
    498
    499    /**
    500     *
    501     * @param xBlock coordinate of block relative to source data
    502     * @param yBlock coordinate of block relative to source data
    503     * @param blockWidth width of block, in pixels
    504     * @param blockHeight height of block in pixels
    505     * @param blockData the data for the block
    506     * @param xRaster coordinate of raster relative to source data
    507     * @param yRaster coordinate of raster relative to source data
    508     * @param rasterWidth width of the raster (always smaller than source data)
    509     * @param rasterHeight height of the raster (always smaller than source
    510     * data)
    511     * @param rasterData the raster data.
    512     */
    513    void transferBlockToRaster(int xBlock, int yBlock,
    514        int blockWidth, int blockHeight, int blockData[],
    515        int xRaster, int yRaster,
    516        int rasterWidth, int rasterHeight, float[] rasterData) {
    517
    518        // xR0, yR0 are the coordinates within the raster (upper-left corner)
    519        // xR1, yR1 are ONE PAST the coordinates of the lower-right corner
    520        int xR0 = xBlock - xRaster;  // xR0, yR0 coordinates relative to
    521        int yR0 = yBlock - yRaster; // the raster
    522        int xR1 = xR0 + blockWidth;
    523        int yR1 = yR0 + blockHeight;
    524        if (xR0 < 0) {
    525            xR0 = 0;
    526        }
    527        if (yR0 < 0) {
    528            yR0 = 0;
    529        }
    530        if (xR1 > rasterWidth) {
    531            xR1 = rasterWidth;
    532        }
    533        if (yR1 > rasterHeight) {
    534            yR1 = rasterHeight;
    535        }
    536
    537        // Recall that the above logic may have adjusted xR0, xY0 so that
    538        // they are not necessarily point to the source pixel at xRaster, yRaster
    539        // we compute xSource = xR0+xRaster.
    540        //            xOffset = xSource-xBlock
    541        // since the block cannot be accessed with a negative offset,
    542        // we check for negatives and adjust xR0, yR0 upward as necessary
    543        int xB0 = xR0 + xRaster - xBlock;
    544        int yB0 = yR0 + yRaster - yBlock;
    545        if (xB0 < 0) {
    546            xR0 -= xB0;
    547            xB0 = 0;
    548        }
    549        if (yB0 < 0) {
    550            yR0 -= yB0;
    551            yB0 = 0;
    552        }
    553
    554        int w = xR1 - xR0;
    555        int h = yR1 - yR0;
    556        if (w <= 0 || h <= 0) {
    557            // The call to this method put the block outside the
    558            // bounds of the raster.  There is nothing to do.  Ideally,
    559            // this situation never arises, because it would mean that
    560            // the data was read from the file unnecessarily.
    561            return;
    562        }
    563        // see if the xR1, yR1 would extend past the limits of the block
    564        if (w > blockWidth) {
    565            w = blockWidth;
    566        }
    567        if (h > blockHeight) {
    568            h = blockHeight;
    569        }
    570
    571        for (int i = 0; i < h; i++) {
    572            int yR = yR0 + i;
    573            int yB = yB0 + i;
    574            int rOffset = yR * rasterWidth + xR0;
    575            int bOffset = yB * blockWidth + xB0;
    576            for (int j = 0; j < w; j++) {
    577                rasterData[rOffset + j] = Float.intBitsToFloat(blockData[bOffset + j]);
    578            }
    579        }
    580    }
    581
    582    /**
    583     * Defines a method for accessing the floating-point raster data in a TIFF
    584     * image. These implementations of this method in DataReaderStrips and
    585     * DataReaderTiled assume that this instance is of a compatible data type
    586     * (floating-point) and that all access checks have already been performed.
    587     *
    588     * @param subImage if non-null, instructs the access method to retrieve only
    589     * a sub-section of the image data.
    590     * @return a valid instance
    591     * @throws ImageReadException in the event of an incompatible data form.
    592     * @throws IOException in the event of I/O error.
    593     */
    594    public abstract TiffRasterData readRasterData(Rectangle subImage)
    595        throws ImageReadException, IOException;
    596}