protected int[] unpackIntSamples(final int width, final int height, final int scanSize, final byte[] bytes, final int predictor, final int bitsPerSample,
            final ByteOrder byteOrder) {
        final int bytesPerSample = bitsPerSample / 8;
        final int nBytes = bytesPerSample * scanSize * height;
        final int length = bytes.length < nBytes ? nBytes / scanSize : height;

        final int[] samples = Allocator.intArray(scanSize * height);
        // At this time, Commons Imaging only supports two-byte
        // two's complement short integers. It is assumed that
        // the calling module already checked the arguments for
        // compliance, so this method simply assumes that they are correct.

        // The logic that follows is simplified by the fact that
        // the existing API only supports two-byte signed integers.
        final boolean useDifferencing = predictor == TiffTagConstants.PREDICTOR_VALUE_HORIZONTAL_DIFFERENCING;

        for (int i = 0; i < length; i++) {
            final int index = i * scanSize;
            int offset = index * bytesPerSample;
            if (bitsPerSample == 16) {
                if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
                    for (int j = 0; j < width; j++, offset += 2) {
                        samples[index + j] = bytes[offset + 1] << 8 | bytes[offset] & 0xff;
                    }
                } else {
                    for (int j = 0; j < width; j++, offset += 2) {
                        samples[index + j] = bytes[offset] << 8 | bytes[offset + 1] & 0xff;
                    }
                }
            } else if (bitsPerSample == 32) {
                if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
                    for (int j = 0; j < width; j++, offset += 4) {
                        samples[index + j] = bytes[offset + 3] << 24 | (bytes[offset + 2] & 0xff) << 16 | (bytes[offset + 1] & 0xff) << 8
                                | bytes[offset] & 0xff;
                    }
                } else {
                    for (int j = 0; j < width; j++, offset += 4) {
                        samples[index + j] = bytes[offset] << 24 | (bytes[offset + 1] & 0xff) << 16 | (bytes[offset + 2] & 0xff) << 8
                                | bytes[offset + 3] & 0xff;
                    }
                }
            }
            if (useDifferencing) {
                for (int j = 1; j < width; j++) {
                    samples[index + j] += samples[index + j - 1];
                }
            }
        }

        return samples;
    }
Given a source file that specifies numerical data as short integers, unpack the raw bytes obtained from the source file and organize them into an array
of integers.
<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"
parameter 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 predictor     the predictor specified by the source, only predictor 3 is supported.
@param bitsPerSample 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.
src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/AbstractImageDataReader.java