protected int[] unpackFloatingPointSamples(final int width, final int height, final int scanSize, final byte[] bytes, final int bitsPerPixel,
            final ByteOrder byteOrder) throws ImagingException {
        final int bitsPerSample = bitsPerPixel / samplesPerPixel;
        final int bytesPerSample = bitsPerSample / 8;
        final int bytesPerScan = scanSize * samplesPerPixel * bytesPerSample;
        final int nBytes = bytesPerScan * height;
        final int length = bytes.length < nBytes ? nBytes / bytesPerScan : height;
        final int[] samples = Allocator.intArray(scanSize * samplesPerPixel * height);
        // floating-point differencing is indicated by a predictor value of 3.
        if (predictor == TiffTagConstants.PREDICTOR_VALUE_FLOATING_POINT_DIFFERENCING) {
            // at this time, this class supports the 32-bit format. The
            // main reason for this is that we have not located sample data
            // that can be used for testing and analysis.
            if (bitsPerPixel / samplesPerPixel != 32) {
                throw new ImagingException(
                        "Imaging does not yet support floating-point data" + " with predictor type 3 for " + bitsPerPixel + " bits per sample");
            }

            if (planarConfiguration == TiffPlanarConfiguration.CHUNKY) {
                final int bytesInRow = scanSize * 4 * samplesPerPixel;
                for (int i = 0; i < length; i++) {
                    final int aOffset = i * bytesInRow;
                    final int bOffset = aOffset + scanSize * samplesPerPixel;
                    final int cOffset = bOffset + scanSize * samplesPerPixel;
                    final int dOffset = cOffset + scanSize * samplesPerPixel;
                    // in this loop, the source bytes give delta values.
                    // we adjust them to give true values. This operation is
                    // done on a row-by-row basis.
                    for (int j = 1; j < bytesInRow; j++) {
                        bytes[aOffset + j] += bytes[aOffset + j - 1];
                    }
                    // pack the bytes into the integer bit-equivalent of
                    // floating point values
                    int index = i * scanSize;
                    for (int j = 0; j < width * samplesPerPixel; j++) {
                        final int a = bytes[aOffset + j];
                        final int b = bytes[bOffset + j];
                        final int c = bytes[cOffset + j];
                        final int d = bytes[dOffset + j];
                        // Pack the 4 byte components into a single integer
                        // in the byte order used by the TIFF standard
                        samples[index++] = (a & 0xff) << 24 | (b & 0xff) << 16 | (c & 0xff) << 8 | d & 0xff;
                    }
                }
            } else {
                final int bytesInRow = scanSize * 4;
                for (int iPlane = 0; iPlane < samplesPerPixel; iPlane++) {
                    final int planarIntOffset = iPlane * length * scanSize;
                    final int planarByteOffset = planarIntOffset * 4;

                    for (int i = 0; i < length; i++) {
                        final int aOffset = i * bytesInRow + planarByteOffset;
                        final int bOffset = aOffset + scanSize;
                        final int cOffset = bOffset + scanSize;
                        final int dOffset = cOffset + scanSize;
                        // in this loop, the source bytes give delta values.
                        // we adjust them to give true values. This operation is
                        // done on a row-by-row basis.
                        for (int j = 1; j < bytesInRow; j++) {
                            bytes[aOffset + j] += bytes[aOffset + j - 1];
                        }
                        // pack the bytes into the integer bit-equivalent of
                        // floating point values
                        int index = planarIntOffset + i * scanSize;
                        for (int j = 0; j < width; j++) {
                            final int a = bytes[aOffset + j];
                            final int b = bytes[bOffset + j];
                            final int c = bytes[cOffset + j];
                            final int d = bytes[dOffset + j];
                            // Pack the 4 byte components into a single integer
                            // in the byte order used by the TIFF standard
                            samples[index++] = (a & 0xff) << 24 | (b & 0xff) << 16 | (c & 0xff) << 8 | d & 0xff;
                        }
                    }
                }

            }
            return samples;
        } // end of predictor==3 case.

        // simple packing case, 64 or 32 bits --------------------------
        if (bitsPerSample == 64) {
            int k = 0;
            int index = 0;
            for (int i = 0; i < length; i++) {
                for (int j = 0; j < scanSize; j++) {
                    final long b0 = bytes[k++] & 0xffL;
                    final long b1 = bytes[k++] & 0xffL;
                    final long b2 = bytes[k++] & 0xffL;
                    final long b3 = bytes[k++] & 0xffL;
                    final long b4 = bytes[k++] & 0xffL;
                    final long b5 = bytes[k++] & 0xffL;
                    final long b6 = bytes[k++] & 0xffL;
                    final long b7 = bytes[k++] & 0xffL;
                    final long sbits;
                    if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
                        sbits = b7 << 56 | b6 << 48 | b5 << 40 | b4 << 32 | b3 << 24 | b2 << 16 | b1 << 8 | b0;

                    } else {
                        sbits = b0 << 56 | b1 << 48 | b2 << 40 | b3 << 32 | b4 << 24 | b5 << 16 | b6 << 8 | b7;
                    }
                    // since the photometric interpreter does not
                    // currently support doubles, we need to replace this
                    // element with a float. This action is inefficient and
                    // should be improved.
                    final float f = (float) Double.longBitsToDouble(sbits);
                    samples[index++] = Float.floatToRawIntBits(f);
                }
            }
        } else if (bitsPerSample == 32) {
            int k = 0;
            int index = 0;
            for (int i = 0; i < length; i++) {
                for (int j = 0; j < scanSize * samplesPerPixel; j++) {
                    final int b0 = bytes[k++] & 0xff;
                    final int b1 = bytes[k++] & 0xff;
                    final int b2 = bytes[k++] & 0xff;
                    final int b3 = bytes[k++] & 0xff;
                    final int sbits;
                    if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
                        sbits = b3 << 24 | b2 << 16 | b1 << 8 | b0;

                    } else {
                        sbits = b0 << 24 | b1 << 16 | b2 << 8 | b3;
                    }
                    // since the photometric interpreter does not
                    // currently support doubles, we need to replace this
                    // element with a float. This action is inefficient and
                    // should be improved.
                    samples[index++] = sbits;
                }
            }
        } else {
            throw new ImagingException("Imaging does not support floating-point samples with " + bitsPerPixel + " bits per sample");
        }

        return samples;
    }
Given a source file that specifies the floating-point data format, unpack the raw bytes obtained from the source file and organize them into an array of
integers containing the bit-equivalent of IEEE-754 32-bit floats. Source files containing 64 bit doubles are downcast to floats.
<p>
This method supports either the tile format or the strip format of TIFF source files. The scan size indicates the number of columns to be extracted. For
strips, the width and the scan size are always the full width of the image. For tiles, the scan size is the full width of the tile, but the width may be
smaller in the cases where the tiles do not evenly divide the width (for example, a 256 pixel wide tile in a 257 pixel wide image would result in two
columns of tiles, the second column having only one column of pixels that were worth extracting.

@param width        the width of the data block to be extracted
@param height       the height of the data block to be extracted
@param scanSize     the number of pixels in a single row of the block
@param bytes        the raw bytes
@param bitsPerPixel the number of bits per sample, 32 or 64.
@param byteOrder    the byte order for the source data
@return a valid array of integers in row major order, dimensions scan-size wide and height.
@throws ImagingException in the event of an invalid format.
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/AbstractImageDataReader.java