Example usage for java.awt.image WritableRaster getSampleModel

List of usage examples for java.awt.image WritableRaster getSampleModel

Introduction

In this page you can find the example usage for java.awt.image WritableRaster getSampleModel.

Prototype

public SampleModel getSampleModel() 

Source Link

Document

Returns the SampleModel that describes the layout of the image data.

Usage

From source file:GraphicsUtil.java

/**
 * Copies data from one raster to another. Only the region of
 * overlap between src and dst is copied.  <tt>Src</tt> and
 * <tt>Dst</tt> must have compatible SampleModels.
 *
 * @param src The source of the data//from   www  .j  a  va 2 s  . co  m
 * @param dst The destination for the data.
 */
public static void copyData(Raster src, WritableRaster dst) {
    if (is_INT_PACK_Data(src.getSampleModel(), false) && is_INT_PACK_Data(dst.getSampleModel(), false)) {
        copyData_INT_PACK(src, dst);
        return;
    }

    copyData_FALLBACK(src, dst);
}

From source file:main.MapKit.java

@Override
public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel,
        RenderingHints hints) {//from w w w . j a v  a  2 s.com
    return new CompositeContext() {
        @Override
        public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
            if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT
                    || dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT
                    || dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
                throw new IllegalStateException("Source and destination must store pixels as INT.");
            }

            int width = Math.min(src.getWidth(), dstIn.getWidth());
            int height = Math.min(src.getHeight(), dstIn.getHeight());

            int[] srcPixel = new int[4];
            int[] dstPixel = new int[4];
            int[] srcPixels = new int[width];
            int[] dstPixels = new int[width];

            for (int y = 0; y < height; y++) {
                src.getDataElements(0, y, width, 1, srcPixels);
                dstIn.getDataElements(0, y, width, 1, dstPixels);

                for (int x = 0; x < width; x++) {
                    // pixels are stored as INT_ARGB
                    // our arrays are [R, G, B, A]
                    int pixel = srcPixels[x];
                    srcPixel[0] = (pixel >> 16) & 0xFF;
                    srcPixel[1] = (pixel >> 8) & 0xFF;
                    srcPixel[2] = (pixel >> 0) & 0xFF;
                    srcPixel[3] = (pixel >> 24) & 0xFF;

                    pixel = dstPixels[x];
                    dstPixel[0] = (pixel >> 16) & 0xFF;
                    dstPixel[1] = (pixel >> 8) & 0xFF;
                    dstPixel[2] = (pixel >> 0) & 0xFF;
                    dstPixel[3] = (pixel >> 24) & 0xFF;

                    int[] result = new int[] { (srcPixel[0] * dstPixel[0]) >> 8,
                            (srcPixel[1] * dstPixel[1]) >> 8, (srcPixel[2] * dstPixel[2]) >> 8,
                            (srcPixel[3] * dstPixel[3]) >> 8 };

                    // mixes the result with the opacity
                    dstPixels[x] = (result[3]) << 24 | (result[0]) << 16 | (result[1]) << 8 | (result[2]);
                }
                dstOut.setDataElements(0, y, width, 1, dstPixels);
            }
        }

        @Override
        public void dispose() {
            // empty
        }
    };
}

From source file:com.bc.ceres.jai.opimage.ReinterpretOpImage.java

private void reformat(Raster sourceRaster, WritableRaster targetRaster, Rectangle targetRectangle) {
    final int sourceDataType = sourceRaster.getSampleModel().getDataType();
    final int targetDataType = targetRaster.getSampleModel().getDataType();
    final PixelAccessor sourceAcc = new PixelAccessor(getSourceImage(0));
    final PixelAccessor targetAcc = new PixelAccessor(this);
    final UnpackedImageData sourcePixels;
    final UnpackedImageData targetPixels;

    sourcePixels = sourceAcc.getPixels(sourceRaster, targetRectangle, sourceDataType, false);

    switch (sourceDataType) {
    case DataBuffer.TYPE_BYTE:
        if (interpretationType == ReinterpretDescriptor.INTERPRET_BYTE_SIGNED) {
            targetPixels = targetAcc.getPixels(targetRaster, targetRectangle, targetDataType, true);
            reformatSByte(sourcePixels, targetPixels, targetRectangle);
            break;
        }//w  w w  .j  a va 2  s  . com
    case DataBuffer.TYPE_INT:
        if (interpretationType == ReinterpretDescriptor.INTERPRET_INT_UNSIGNED) {
            targetPixels = targetAcc.getPixels(targetRaster, targetRectangle, targetDataType, true);
            reformatUInt(sourcePixels, targetPixels, targetRectangle);
            break;
        }
    default:
        targetPixels = sourcePixels;
    }

    targetAcc.setPixels(targetPixels);
}

From source file:com.bc.ceres.jai.opimage.ReinterpretOpImage.java

private void rescale(Raster sourceRaster, WritableRaster targetRaster, Rectangle targetRectangle) {
    final int sourceDataType = sourceRaster.getSampleModel().getDataType();
    final int targetDataType = targetRaster.getSampleModel().getDataType();
    final PixelAccessor sourceAcc = new PixelAccessor(getSourceImage(0));
    final PixelAccessor targetAcc = new PixelAccessor(this);
    final UnpackedImageData sourcePixels;
    final UnpackedImageData targetPixels;

    sourcePixels = sourceAcc.getPixels(sourceRaster, targetRectangle, sourceDataType, false);
    targetPixels = targetAcc.getPixels(targetRaster, targetRectangle, targetDataType, true);

    switch (sourceDataType) {
    case DataBuffer.TYPE_BYTE:
        if (interpretationType == ReinterpretDescriptor.INTERPRET_BYTE_SIGNED) {
            rescaleSByte(sourcePixels, targetPixels, targetRectangle);
        } else {//  ww  w .ja v  a 2s .c o m
            rescaleByte(sourcePixels, targetPixels, targetRectangle);
        }
        break;
    case DataBuffer.TYPE_USHORT:
        rescaleUShort(sourcePixels, targetPixels, targetRectangle);
        break;
    case DataBuffer.TYPE_SHORT:
        rescaleShort(sourcePixels, targetPixels, targetRectangle);
        break;
    case DataBuffer.TYPE_INT:
        if (interpretationType == ReinterpretDescriptor.INTERPRET_INT_UNSIGNED) {
            rescaleUInt(sourcePixels, targetPixels, targetRectangle);
        } else {
            rescaleInt(sourcePixels, targetPixels, targetRectangle);
        }
        break;
    case DataBuffer.TYPE_FLOAT:
        rescaleFloat(sourcePixels, targetPixels, targetRectangle);
        break;
    case DataBuffer.TYPE_DOUBLE:
        rescaleDouble(sourcePixels, targetPixels, targetRectangle);
        break;
    }

    targetAcc.setPixels(targetPixels);
}

From source file:GraphicsUtil.java

/**
 * An internal optimized version of copyData designed to work on
 * Integer packed data with a SinglePixelPackedSampleModel.  Only
 * the region of overlap between src and dst is copied.
 *
 * Calls to this should be preflighted with is_INT_PACK_Data
 * on both src and dest (requireAlpha can be false).
 *
 * @param src The source of the data//from   www . j  a  v a2  s .c om
 * @param dst The destination for the data.
 */
public static void copyData_INT_PACK(Raster src, WritableRaster dst) {
    // System.out.println("Fast copyData");
    int x0 = dst.getMinX();
    if (x0 < src.getMinX())
        x0 = src.getMinX();

    int y0 = dst.getMinY();
    if (y0 < src.getMinY())
        y0 = src.getMinY();

    int x1 = dst.getMinX() + dst.getWidth() - 1;
    if (x1 > src.getMinX() + src.getWidth() - 1)
        x1 = src.getMinX() + src.getWidth() - 1;

    int y1 = dst.getMinY() + dst.getHeight() - 1;
    if (y1 > src.getMinY() + src.getHeight() - 1)
        y1 = src.getMinY() + src.getHeight() - 1;

    int width = x1 - x0 + 1;
    int height = y1 - y0 + 1;

    SinglePixelPackedSampleModel srcSPPSM;
    srcSPPSM = (SinglePixelPackedSampleModel) src.getSampleModel();

    final int srcScanStride = srcSPPSM.getScanlineStride();
    DataBufferInt srcDB = (DataBufferInt) src.getDataBuffer();
    final int[] srcPixels = srcDB.getBankData()[0];
    final int srcBase = (srcDB.getOffset()
            + srcSPPSM.getOffset(x0 - src.getSampleModelTranslateX(), y0 - src.getSampleModelTranslateY()));

    SinglePixelPackedSampleModel dstSPPSM;
    dstSPPSM = (SinglePixelPackedSampleModel) dst.getSampleModel();

    final int dstScanStride = dstSPPSM.getScanlineStride();
    DataBufferInt dstDB = (DataBufferInt) dst.getDataBuffer();
    final int[] dstPixels = dstDB.getBankData()[0];
    final int dstBase = (dstDB.getOffset()
            + dstSPPSM.getOffset(x0 - dst.getSampleModelTranslateX(), y0 - dst.getSampleModelTranslateY()));

    if ((srcScanStride == dstScanStride) && (srcScanStride == width)) {
        // System.out.println("VERY Fast copyData");

        System.arraycopy(srcPixels, srcBase, dstPixels, dstBase, width * height);
    } else if (width > 128) {
        int srcSP = srcBase;
        int dstSP = dstBase;
        for (int y = 0; y < height; y++) {
            System.arraycopy(srcPixels, srcSP, dstPixels, dstSP, width);
            srcSP += srcScanStride;
            dstSP += dstScanStride;
        }
    } else {
        for (int y = 0; y < height; y++) {
            int srcSP = srcBase + y * srcScanStride;
            int dstSP = dstBase + y * dstScanStride;
            for (int x = 0; x < width; x++)
                dstPixels[dstSP++] = srcPixels[srcSP++];
        }
    }
}

From source file:nitf.imageio.NITFReader.java

@Override
public Raster readRaster(int imageIndex, ImageReadParam param) throws IOException {
    checkIndex(imageIndex);/*from  w  ww.j a  va  2s  .com*/

    Rectangle sourceRegion = new Rectangle();
    Rectangle destRegion = new Rectangle();
    computeRegions(param, getWidth(imageIndex), getHeight(imageIndex), null, sourceRegion, destRegion);

    // Set everything to default values
    int sourceXSubsampling = param != null ? param.getSourceXSubsampling() : 1;
    int sourceYSubsampling = param != null ? param.getSourceYSubsampling() : 1;
    Point destinationOffset = param != null ? param.getDestinationOffset() : new Point(0, 0);

    ImageSubheader subheader;
    try {
        subheader = record.getImages()[imageIndex].getSubheader();
    } catch (NITFException e) {
        throw new IOException(ExceptionUtils.getStackTrace(e));
    }
    String irep = subheader.getImageRepresentation().getStringData().trim();
    String pvType = subheader.getPixelValueType().getStringData().trim();
    int nbpp = subheader.getNumBitsPerPixel().getIntData();
    int bandCount = subheader.getBandCount();

    // make the band offsets array, for the output
    int[] bandOffsets = null;
    int[] sourceBands = param != null ? param.getSourceBands() : null;
    if (param != null && param.getDestinationBands() != null)
        bandOffsets = param.getDestinationBands();
    else if (param != null && sourceBands != null) {
        bandOffsets = new int[sourceBands.length];
        for (int i = 0; i < bandOffsets.length; i++)
            bandOffsets[i] = sourceBands[i];
    } else {
        // Setup band offsets -- TODO should we really read ALL bands by
        // default?
        bandOffsets = new int[bandCount];
        for (int i = 0; i < bandOffsets.length; i++)
            bandOffsets[i] = i;
    }

    int nBytes = ((nbpp - 1) / 8) + 1;

    int bufType = -1;

    // byte
    if (nBytes == 1) {
        bufType = DataBuffer.TYPE_BYTE;
    }
    // short
    else if (nBytes == 2) {
        bufType = DataBuffer.TYPE_USHORT;
    }
    // float
    else if (nBytes == 4 && pvType.equals("R")) {
        bufType = DataBuffer.TYPE_FLOAT;
    }
    // double
    else if (nBytes == 8 && pvType.equals("R")) {
        bufType = DataBuffer.TYPE_DOUBLE;
    } else {
        throw new NotImplementedException("not yet implemented");
    }

    WritableRaster ras = ImageIOUtils.makeGenericPixelInterleavedWritableRaster(destRegion.width,
            destRegion.height, bandOffsets.length, bufType);
    checkReadParamBandSettings(param, bandCount, ras.getSampleModel().getNumBands());
    readRaster(imageIndex, sourceRegion, destRegion, sourceXSubsampling, sourceYSubsampling, bandOffsets,
            nBytes, destinationOffset, ras);
    return ras;
}

From source file:org.geotools.imageio.netcdf.NetCDFImageReader.java

/**
 * @see javax.imageio.ImageReader#read(int, javax.imageio.ImageReadParam)
 *///from  w ww  . j a v a 2  s  . co m
@Override
public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
    clearAbortRequest();

    final Slice2DIndex slice2DIndex = getSlice2DIndex(imageIndex);
    final String variableName = slice2DIndex.getVariableName();
    final VariableAdapter wrapper = getCoverageDescriptor(new NameImpl(variableName));

    /*
     * Fetches the parameters that are not already processed by utility
     * methods like 'getDestination' or 'computeRegions' (invoked below).
     */
    final int strideX, strideY;
    // final int[] srcBands;
    final int[] dstBands;
    if (param != null) {
        strideX = param.getSourceXSubsampling();
        strideY = param.getSourceYSubsampling();
        // srcBands = param.getSourceBands();
        dstBands = param.getDestinationBands();
    } else {
        strideX = 1;
        strideY = 1;
        // srcBands = null;
        dstBands = null;
    }

    /*
     * Gets the destination image of appropriate size. We create it now
     * since it is a convenient way to get the number of destination bands.
     */
    final int width = wrapper.getWidth();
    final int height = wrapper.getHeight();
    /*
     * Computes the source region (in the NetCDF file) and the destination
     * region (in the buffered image). Copies those informations into UCAR
     * Range structure.
     */
    final Rectangle srcRegion = new Rectangle();
    final Rectangle destRegion = new Rectangle();
    computeRegions(param, width, height, null, srcRegion, destRegion);

    // Flipping is needed only when the input latitude coordinate is ordered
    // from min to max
    if (needsFlipping) {
        flipVertically(param, height, srcRegion);
    }
    int destWidth = destRegion.x + destRegion.width;
    int destHeight = destRegion.y + destRegion.height;

    /*
     * build the ranges that need to be read from each 
     * dimension based on the source region
     */
    final List<Range> ranges = new LinkedList<Range>();
    try {
        // add the ranges the COARDS way: T, Z, Y, X
        // T
        int first = slice2DIndex.getTIndex();
        int length = 1;
        int stride = 1;
        if (first != -1) {
            ranges.add(new Range(first, first + length - 1, stride));
        }
        // Z
        first = slice2DIndex.getZIndex();
        if (first != -1) {
            ranges.add(new Range(first, first + length - 1, stride));
        }
        // Y
        first = srcRegion.y;
        length = srcRegion.height;
        stride = strideY;
        ranges.add(new Range(first, first + length - 1, stride));
        // X
        first = srcRegion.x;
        length = srcRegion.width;
        stride = strideX;
        ranges.add(new Range(first, first + length - 1, stride));
    } catch (InvalidRangeException e) {
        throw netcdfFailure(e);
    }

    /*
     * create the section of multidimensional array indices
     * that defines the exact data that need to be read 
     * for this image index and parameters 
     */
    final Section section = new Section(ranges);

    /*
     * Setting SampleModel and ColorModel.
     */
    final SampleModel sampleModel = wrapper.getSampleModel().createCompatibleSampleModel(destWidth, destHeight);
    final ColorModel colorModel = ImageIOUtilities.createColorModel(sampleModel);

    final WritableRaster raster = Raster.createWritableRaster(sampleModel, new Point(0, 0));
    final BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);

    CoordinateAxis axis = wrapper.variableDS.getCoordinateSystems().get(0).getLatAxis();
    boolean flipYAxis = false;
    try {
        Array yAxisStart = axis.read(new Section().appendRange(2));
        float y1 = yAxisStart.getFloat(0);
        float y2 = yAxisStart.getFloat(1);
        if (y2 > y1) {
            flipYAxis = true;
        }
    } catch (InvalidRangeException e) {
        throw new RuntimeException(e);
    }
    /*
     * Reads the requested sub-region only.
     */
    processImageStarted(imageIndex);
    final int numDstBands = 1;
    final float toPercent = 100f / numDstBands;
    final int type = raster.getSampleModel().getDataType();
    final int xmin = destRegion.x;
    final int ymin = destRegion.y;
    final int xmax = destRegion.width + xmin;
    final int ymax = destRegion.height + ymin;
    for (int zi = 0; zi < numDstBands; zi++) {
        // final int srcBand = (srcBands == null) ? zi : srcBands[zi];
        final int dstBand = (dstBands == null) ? zi : dstBands[zi];
        final Array array;
        try {
            // TODO leak through
            array = wrapper.variableDS.read(section);
        } catch (InvalidRangeException e) {
            throw netcdfFailure(e);
        }
        if (flipYAxis) {
            final IndexIterator it = array.getIndexIterator();
            for (int y = ymax; --y >= ymin;) {
                for (int x = xmin; x < xmax; x++) {
                    switch (type) {
                    case DataBuffer.TYPE_DOUBLE: {
                        raster.setSample(x, y, dstBand, it.getDoubleNext());
                        break;
                    }
                    case DataBuffer.TYPE_FLOAT: {
                        raster.setSample(x, y, dstBand, it.getFloatNext());
                        break;
                    }
                    case DataBuffer.TYPE_BYTE: {
                        byte b = it.getByteNext();
                        // int myByte = (0x000000FF & ((int) b));
                        // short anUnsignedByte = (short) myByte;
                        // raster.setSample(x, y, dstBand, anUnsignedByte);
                        raster.setSample(x, y, dstBand, b);
                        break;
                    }
                    default: {
                        raster.setSample(x, y, dstBand, it.getIntNext());
                        break;
                    }
                    }
                }
            }
        } else {
            switch (type) {
            case DataBuffer.TYPE_DOUBLE: {
                DoubleBuffer doubleBuffer = array.getDataAsByteBuffer().asDoubleBuffer();
                double[] samples = new double[destRegion.width * destRegion.height];
                doubleBuffer.get(samples);
                raster.setSamples(xmin, ymin, destRegion.width, destRegion.height, dstBand, samples);
                break;
            }
            case DataBuffer.TYPE_FLOAT:
                float[] samples = new float[destRegion.width * destRegion.height];
                FloatBuffer floatBuffer = array.getDataAsByteBuffer().asFloatBuffer();
                floatBuffer.get(samples);
                raster.setSamples(xmin, ymin, destRegion.width, destRegion.height, dstBand, samples);
                break;
            case DataBuffer.TYPE_BYTE:
                //THIS ONLY WORKS FOR ONE BAND!!
                raster.setDataElements(xmin, ymin, destRegion.width, destRegion.height,
                        array.getDataAsByteBuffer().array());
                break;
            case DataBuffer.TYPE_INT:
                IntBuffer intBuffer = array.getDataAsByteBuffer().asIntBuffer();
                int[] intSamples = new int[destRegion.width * destRegion.height];
                intBuffer.get(intSamples);
                raster.setSamples(xmin, ymin, destRegion.width, destRegion.height, dstBand, intSamples);
                break;
            default: {
                final IndexIterator it = array.getIndexIterator();
                for (int y = ymin; y < ymax; y++) {
                    for (int x = xmin; x < xmax; x++) {
                        raster.setSample(x, y, dstBand, it.getIntNext());
                    }
                }
                break;
            }

            }

        }
        /*
         * Checks for abort requests after reading. It would be a waste of a
         * potentially good image (maybe the abort request occurred after we
         * just finished the reading) if we didn't implemented the
         * 'isCancel()' method. But because of the later, which is checked
         * by the NetCDF library, we can't assume that the image is
         * complete.
         */
        if (abortRequested()) {
            processReadAborted();
            return image;
        }
        /*
         * Reports progress here, not in the deeper loop, because the costly
         * part is the call to 'variable.read(...)' which can't report
         * progress. The loop that copy pixel values is fast, so reporting
         * progress there would be pointless.
         */
        processImageProgress(zi * toPercent);
    }
    processImageComplete();
    return image;
}

From source file:org.geotools.imageio.unidata.UnidataImageReader.java

/**
 * @see javax.imageio.ImageReader#read(int, javax.imageio.ImageReadParam)
 *///  ww  w .j a va2  s.  com
@Override
public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
    clearAbortRequest();

    final UnidataSlice2DIndex slice2DIndex = getSlice2DIndex(imageIndex);
    final String variableName = slice2DIndex.getVariableName();
    final UnidataVariableAdapter wrapper = getCoverageDescriptor(new NameImpl(variableName));

    /*
     * Fetches the parameters that are not already processed by utility
     * methods like 'getDestination' or 'computeRegions' (invoked below).
     */
    final int strideX, strideY;
    // final int[] srcBands;
    final int[] dstBands;
    if (param != null) {
        strideX = param.getSourceXSubsampling();
        strideY = param.getSourceYSubsampling();
        // srcBands = param.getSourceBands();
        dstBands = param.getDestinationBands();
    } else {
        strideX = 1;
        strideY = 1;
        // srcBands = null;
        dstBands = null;
    }

    /*
     * Gets the destination image of appropriate size. We create it now
     * since it is a convenient way to get the number of destination bands.
     */
    final int width = wrapper.getWidth();
    final int height = wrapper.getHeight();
    /*
     * Computes the source region (in the NetCDF file) and the destination
     * region (in the buffered image). Copies those informations into UCAR
     * Range structure.
     */
    final Rectangle srcRegion = new Rectangle();
    final Rectangle destRegion = new Rectangle();
    computeRegions(param, width, height, null, srcRegion, destRegion);
    flipVertically(param, height, srcRegion);
    int destWidth = destRegion.x + destRegion.width;
    int destHeight = destRegion.y + destRegion.height;

    /*
     * build the ranges that need to be read from each 
     * dimension based on the source region
     */
    final List<Range> ranges = new LinkedList<Range>();
    try {
        // add the ranges the COARDS way: T, Z, Y, X
        // T
        int first = slice2DIndex.getTIndex();
        int length = 1;
        int stride = 1;
        if (first != -1) {
            ranges.add(new Range(first, first + length - 1, stride));
        }
        // Z
        first = slice2DIndex.getZIndex();
        if (first != -1) {
            ranges.add(new Range(first, first + length - 1, stride));
        }
        // Y
        first = srcRegion.y;
        length = srcRegion.height;
        stride = strideY;
        ranges.add(new Range(first, first + length - 1, stride));
        // X
        first = srcRegion.x;
        length = srcRegion.width;
        stride = strideX;
        ranges.add(new Range(first, first + length - 1, stride));
    } catch (InvalidRangeException e) {
        throw netcdfFailure(e);
    }

    /*
     * create the section of multidimensional array indices
     * that defines the exact data that need to be read 
     * for this image index and parameters 
     */
    final Section section = new Section(ranges);

    /*
     * Setting SampleModel and ColorModel.
     */
    final SampleModel sampleModel = wrapper.getSampleModel().createCompatibleSampleModel(destWidth, destHeight);
    final ColorModel colorModel = ImageIOUtilities.createColorModel(sampleModel);

    final WritableRaster raster = Raster.createWritableRaster(sampleModel, new Point(0, 0));
    final BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);

    CoordinateAxis axis = wrapper.variableDS.getCoordinateSystems().get(0).getLatAxis();
    boolean flipYAxis = false;
    try {
        Array yAxisStart = axis.read(new Section().appendRange(2));
        float y1 = yAxisStart.getFloat(0);
        float y2 = yAxisStart.getFloat(1);
        if (y2 > y1) {
            flipYAxis = true;
        }
    } catch (InvalidRangeException e) {
        throw new RuntimeException(e);
    }
    /*
     * Reads the requested sub-region only.
     */
    processImageStarted(imageIndex);
    final int numDstBands = 1;
    final float toPercent = 100f / numDstBands;
    final int type = raster.getSampleModel().getDataType();
    final int xmin = destRegion.x;
    final int ymin = destRegion.y;
    final int xmax = destRegion.width + xmin;
    final int ymax = destRegion.height + ymin;
    for (int zi = 0; zi < numDstBands; zi++) {
        // final int srcBand = (srcBands == null) ? zi : srcBands[zi];
        final int dstBand = (dstBands == null) ? zi : dstBands[zi];
        final Array array;
        try {
            // TODO leak through
            array = wrapper.variableDS.read(section);
        } catch (InvalidRangeException e) {
            throw netcdfFailure(e);
        }
        if (flipYAxis) {
            final IndexIterator it = array.getIndexIterator();
            for (int y = ymax; --y >= ymin;) {
                for (int x = xmin; x < xmax; x++) {
                    switch (type) {
                    case DataBuffer.TYPE_DOUBLE: {
                        raster.setSample(x, y, dstBand, it.getDoubleNext());
                        break;
                    }
                    case DataBuffer.TYPE_FLOAT: {
                        raster.setSample(x, y, dstBand, it.getFloatNext());
                        break;
                    }
                    case DataBuffer.TYPE_BYTE: {
                        byte b = it.getByteNext();
                        // int myByte = (0x000000FF & ((int) b));
                        // short anUnsignedByte = (short) myByte;
                        // raster.setSample(x, y, dstBand, anUnsignedByte);
                        raster.setSample(x, y, dstBand, b);
                        break;
                    }
                    default: {
                        raster.setSample(x, y, dstBand, it.getIntNext());
                        break;
                    }
                    }
                }
            }
        } else {
            switch (type) {
            case DataBuffer.TYPE_DOUBLE: {
                DoubleBuffer doubleBuffer = array.getDataAsByteBuffer().asDoubleBuffer();
                double[] samples = new double[destRegion.width * destRegion.height];
                doubleBuffer.get(samples);
                raster.setSamples(xmin, ymin, destRegion.width, destRegion.height, dstBand, samples);
                break;
            }
            case DataBuffer.TYPE_FLOAT:
                float[] samples = new float[destRegion.width * destRegion.height];
                FloatBuffer floatBuffer = array.getDataAsByteBuffer().asFloatBuffer();
                floatBuffer.get(samples);
                raster.setSamples(xmin, ymin, destRegion.width, destRegion.height, dstBand, samples);
                break;
            case DataBuffer.TYPE_BYTE:
                //THIS ONLY WORKS FOR ONE BAND!!
                raster.setDataElements(xmin, ymin, destRegion.width, destRegion.height,
                        array.getDataAsByteBuffer().array());
                break;
            case DataBuffer.TYPE_INT:
                IntBuffer intBuffer = array.getDataAsByteBuffer().asIntBuffer();
                int[] intSamples = new int[destRegion.width * destRegion.height];
                intBuffer.get(intSamples);
                raster.setSamples(xmin, ymin, destRegion.width, destRegion.height, dstBand, intSamples);
                break;
            default: {
                final IndexIterator it = array.getIndexIterator();
                for (int y = ymin; y < ymax; y++) {
                    for (int x = xmin; x < xmax; x++) {
                        raster.setSample(x, y, dstBand, it.getIntNext());
                    }
                }
                break;
            }

            }

        }
        /*
         * Checks for abort requests after reading. It would be a waste of a
         * potentially good image (maybe the abort request occurred after we
         * just finished the reading) if we didn't implemented the
         * 'isCancel()' method. But because of the later, which is checked
         * by the NetCDF library, we can't assume that the image is
         * complete.
         */
        if (abortRequested()) {
            processReadAborted();
            return image;
        }
        /*
         * Reports progress here, not in the deeper loop, because the costly
         * part is the call to 'variable.read(...)' which can't report
         * progress. The loop that copy pixel values is fast, so reporting
         * progress there would be pointless.
         */
        processImageProgress(zi * toPercent);
    }
    processImageComplete();
    return image;
}