private void readTrueColor(ImageReadParam pParam, final ImageInputStream pInput) throws IOException {
        final int width = header.width;
        final int height = header.height;

        final Rectangle aoi = getSourceRegion(pParam, width, height);
        final Point offset = pParam == null ? new Point(0, 0) : pParam.getDestinationOffset();

        // Set everything to default values
        int sourceXSubsampling = 1;
        int sourceYSubsampling = 1;
        int[] sourceBands = null;
        int[] destinationBands = null;

        // Get values from the ImageReadParam, if any
        if (pParam != null) {
            sourceXSubsampling = pParam.getSourceXSubsampling();
            sourceYSubsampling = pParam.getSourceYSubsampling();

            sourceBands = pParam.getSourceBands();
            destinationBands = pParam.getDestinationBands();
        }

        // Ensure band settings from param are compatible with images
        checkReadParamBandSettings(pParam, header.bitplanes / 8, image.getSampleModel().getNumBands());

        // NOTE:  Each row of the image is stored in an integral number of 16 bit words.
        // The number of words per row is words=((w+15)/16)
        int planeWidth = 2 * ((width + 15) / 16);
        final byte[] planeData = new byte[8 * planeWidth];

        WritableRaster destination = image.getRaster();
        if (destinationBands != null || offset.x != 0 || offset.y != 0) {
            destination = destination.createWritableChild(0, 0, destination.getWidth(), destination.getHeight(), offset.x, offset.y, destinationBands);
        }
//        WritableRaster raster = image.getRaster().createCompatibleWritableRaster(width, 1);
        WritableRaster raster = image.getRaster().createCompatibleWritableRaster(8 * planeWidth, 1);
        Raster sourceRow = raster.createChild(aoi.x, 0, aoi.width, 1, 0, 0, sourceBands);

        final byte[] data = ((DataBufferByte) raster.getDataBuffer()).getData();
        final int channels = (header.bitplanes + 7) / 8;
        final int planesPerChannel = 8;
        Object dataElements = null;

        for (int srcY = 0; srcY < height; srcY++) {
            for (int c = 0; c < channels; c++) {
                for (int p = 0; p < planesPerChannel; p++) {
                    readPlaneData(pInput, planeData, p * planeWidth, planeWidth);
                }

                // Skip rows outside AOI
                if (srcY >= (aoi.y + aoi.height)) {
                    return;
                }
                else if (srcY < aoi.y || (srcY - aoi.y) % sourceYSubsampling != 0) {
                    continue;
                }

                if (formType == IFF.TYPE_ILBM) {
                    // NOTE: Using (channels - c - 1) instead of just c,
                    // effectively reverses the channel order from RGBA to ABGR
                    int off = (channels - c - 1);

                    int pixelPos = 0;
                    for (int planePos = 0; planePos < planeWidth; planePos++) {
                        IFFUtil.bitRotateCW(planeData, planePos, planeWidth, data, off + pixelPos * channels, channels);
                        pixelPos += 8;
                    }
                }
                else if (formType == IFF.TYPE_PBM) {
                    System.arraycopy(planeData, 0, data, srcY * 8 * planeWidth, planeWidth);
                }
                else {
                    throw new AssertionError(String.format("Unsupported FORM type: %s", formType));
                }
            }

            if (srcY >= aoi.y && (srcY - aoi.y) % sourceYSubsampling == 0) {
                int dstY = (srcY - aoi.y) / sourceYSubsampling;
                // TODO: Support conversion to INT (A)RGB rasters (maybe using ColorConvertOp?)
                // TODO: Avoid createChild if no region?
                if (sourceXSubsampling == 1) {
                    destination.setRect(0, dstY, sourceRow);
//                dataElements = raster.getDataElements(aoi.x, 0, aoi.width, 1, dataElements);
//                destination.setDataElements(offset.x, offset.y + (srcY - aoi.y) / sourceYSubsampling, aoi.width, 1, dataElements);
                }
                else {
                    for (int srcX = 0; srcX < sourceRow.getWidth(); srcX += sourceXSubsampling) {
                        dataElements = sourceRow.getDataElements(srcX, 0, dataElements);
                        int dstX = srcX / sourceXSubsampling;
                        destination.setDataElements(dstX, dstY, dataElements);
                    }
                }
            }

            processImageProgress(srcY * 100f / header.width);
            if (abortRequested()) {
                processReadAborted();
                break;
            }
        }
    }
private void readTrueColor ( ImageReadParam pParam , final ImageInputStream pInput ) throws IOException { final int width = header . width ; final int height = header . height ; final Rectangle aoi = getSourceRegion ( pParam , width , height ) ; final Point offset = pParam == null ? new Point ( 0 , 0 ) : pParam . getDestinationOffset ( ) ; int sourceXSubsampling = 1 ; int sourceYSubsampling = 1 ; int [ ] sourceBands = null ; int [ ] destinationBands = null ; if ( pParam != null ) { sourceXSubsampling = pParam . getSourceXSubsampling ( ) ; sourceYSubsampling = pParam . getSourceYSubsampling ( ) ; sourceBands = pParam . getSourceBands ( ) ; destinationBands = pParam . getDestinationBands ( ) ; } checkReadParamBandSettings ( pParam , header . bitplanes / 8 , image . getSampleModel ( ) . getNumBands ( ) ) ; int planeWidth = 2 * ( ( width + 15 ) / 16 ) ; final byte [ ] planeData = new byte [ 8 * planeWidth ] ; WritableRaster destination = image . getRaster ( ) ; if ( destinationBands != null || offset . x != 0 || offset . y != 0 ) { destination = destination . createWritableChild ( 0 , 0 , destination . getWidth ( ) , destination . getHeight ( ) , offset . x , offset . y , destinationBands ) ; } WritableRaster raster = image . getRaster ( ) . createCompatibleWritableRaster ( 8 * planeWidth , 1 ) ; Raster sourceRow = raster . createChild ( aoi . x , 0 , aoi . width , 1 , 0 , 0 , sourceBands ) ; final byte [ ] data = ( ( DataBufferByte ) raster . getDataBuffer ( ) ) . getData ( ) ; final int channels = ( header . bitplanes + 7 ) / 8 ; final int planesPerChannel = 8 ; Object dataElements = null ; for ( int srcY = 0 ; srcY < height ; srcY ++ ) { for ( int c = 0 ; c < channels ; c ++ ) { for ( int p = 0 ; p < planesPerChannel ; p ++ ) { readPlaneData ( pInput , planeData , p * planeWidth , planeWidth ) ; } if ( srcY >= ( aoi . y + aoi . height ) ) { return ; } else if ( srcY < aoi . y || ( srcY - aoi . y ) % sourceYSubsampling != 0 ) { continue ; } if ( formType == IFF . TYPE_ILBM ) { int off = ( channels - c - 1 ) ; int pixelPos = 0 ; for ( int planePos = 0 ; planePos < planeWidth ; planePos ++ ) { IFFUtil . bitRotateCW ( planeData , planePos , planeWidth , data , off + pixelPos * channels , channels ) ; pixelPos += 8 ; } } else if ( formType == IFF . TYPE_PBM ) { System . arraycopy ( planeData , 0 , data , srcY * 8 * planeWidth , planeWidth ) ; } else { throw new AssertionError ( String . format ( "Unsupported FORM type: %s" , formType ) ) ; } } if ( srcY >= aoi . y && ( srcY - aoi . y ) % sourceYSubsampling == 0 ) { int dstY = ( srcY - aoi . y ) / sourceYSubsampling ; if ( sourceXSubsampling == 1 ) { destination . setRect ( 0 , dstY , sourceRow ) ; } else { for ( int srcX = 0 ; srcX < sourceRow . getWidth ( ) ; srcX += sourceXSubsampling ) { dataElements = sourceRow . getDataElements ( srcX , 0 , dataElements ) ; int dstX = srcX / sourceXSubsampling ; destination . setDataElements ( dstX , dstY , dataElements ) ; } } } processImageProgress ( srcY * 100f / header . width ) ; if ( abortRequested ( ) ) { processReadAborted ( ) ; break ; } } }
significant bit of the blue value.