/* JAI-Ext - OpenSource Java Advanced Image Extensions Library * http://www.geo-solutions.it/ * Copyright 2014 GeoSolutions * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package it.geosolutions.jaiext.scale; import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.util.Arrays; import java.util.Map; import javax.media.jai.BorderExtender; import javax.media.jai.ImageLayout; import javax.media.jai.Interpolation; import javax.media.jai.RasterAccessor; import javax.media.jai.RasterFormatTag; import javax.media.jai.iterator.RandomIter; import it.geosolutions.jaiext.interpolators.InterpolationNearest; import it.geosolutions.jaiext.iterators.RandomIterFactory; import it.geosolutions.jaiext.range.Range; public class ScaleNearestOpImage extends ScaleOpImage { /** Nearest-Neighbor interpolator */ protected InterpolationNearest interpN = null; /** Byte lookuptable used if no data are present */ protected byte[][] byteLookupTable; public ScaleNearestOpImage(RenderedImage source, ImageLayout layout, Map configuration, BorderExtender extender, Interpolation interp, float scaleX, float scaleY, float transX, float transY, boolean useRoiAccessor, Range nodata, double[] backgroundValues) { super(source, layout, configuration, true, extender, interp, scaleX, scaleY, transX, transY, useRoiAccessor, backgroundValues); scaleOpInitialization(source, interp, nodata, backgroundValues, useRoiAccessor); } private void scaleOpInitialization(RenderedImage source, Interpolation interp, Range nodata, double[] backgroundValues, boolean useRoiAccessor) { // If the source has an IndexColorModel, override the default setting // in OpImage. The dest shall have exactly the same SampleModel and // ColorModel as the source. // Note, in this case, the source should have an integral data type. ColorModel srcColorModel = source.getColorModel(); if (srcColorModel instanceof IndexColorModel) { sampleModel = source.getSampleModel() .createCompatibleSampleModel(tileWidth, tileHeight); colorModel = srcColorModel; } SampleModel sm = source.getSampleModel(); // Source image data Type int srcDataType = sm.getDataType(); // NumBands int numBands = getSampleModel().getNumBands(); // selection of the inverse scale parameters both for the x and y axis if (invScaleXRational.num > invScaleXRational.denom) { invScaleXInt = invScaleXRational.num / invScaleXRational.denom; invScaleXFrac = invScaleXRational.num % invScaleXRational.denom; } else { invScaleXInt = 0; invScaleXFrac = invScaleXRational.num; } if (invScaleYRational.num > invScaleYRational.denom) { invScaleYInt = invScaleYRational.num / invScaleYRational.denom; invScaleYFrac = invScaleYRational.num % invScaleYRational.denom; } else { invScaleYInt = 0; invScaleYFrac = invScaleYRational.num; } // Interpolator settings interpolator = interp; // If both roiBounds and roiIter are not null, they are used in calculation Range nod = nodata; double[] destNod = null; if (backgroundValues != null && backgroundValues.length > 0){ destNod = backgroundValues; } if (interp instanceof InterpolationNearest) { interpN = (InterpolationNearest) interp; this.interp = interpN; interpN.setROIBounds(roiBounds); if(nod == null){ nod = interpN.getNoDataRange(); } if(destNod == null){ destNod = new double[]{interpN.getDestinationNoData()}; } } // Nodata definition if (nod != null) { hasNoData = true; noData = nod; } if (destNod != null) { destinationNoDataDouble = destNod; } else if (this.backgroundValues != null && this.backgroundValues.length > 0) { destinationNoDataDouble = this.backgroundValues; } // Expand the destination nodata values if not defined if(destinationNoDataDouble != null && destinationNoDataDouble.length < numBands){ double[] tmp = new double[numBands]; Arrays.fill(tmp, destinationNoDataDouble[0]); destinationNoDataDouble = tmp; } // ROIAccessor definition if (hasROI) { this.useRoiAccessor = useRoiAccessor; } // subsample bits used for the bilinear and bicubic interpolation subsampleBits = interp.getSubsampleBitsH(); // Internal precision required for position calculations one = 1 << subsampleBits; // Subsampling related variables shift2 = 2 * subsampleBits; round2 = 1 << (shift2 - 1); // Number of subsample positions one = 1 << subsampleBits; // Get the width and height and padding of the Interpolation kernel. interp_width = interp.getWidth(); interp_height = interp.getHeight(); interp_left = interp.getLeftPadding(); interp_top = interp.getTopPadding(); // Create the destination No data arrays destinationNoDataByte = new byte[numBands]; destinationNoDataShort = new short[numBands]; destinationNoDataUShort = new short[numBands]; destinationNoDataInt = new int[numBands]; destinationNoDataFloat = new float[numBands]; // Populate the arrays for (int i = 0; i < numBands; i++) { destinationNoDataByte[i] = (byte) ((int) destinationNoDataDouble[i] & 0xFF); destinationNoDataUShort[i] = (short) (((short) destinationNoDataDouble[i]) & 0xffff); destinationNoDataShort[i] = (short) destinationNoDataDouble[i]; destinationNoDataInt[i] = (int) destinationNoDataDouble[i]; destinationNoDataFloat[i] = (float) destinationNoDataDouble[i]; } // Creation of a lookuptable containing the values to use for no data if (hasNoData) { // Creation of a lookuptable containing the values to use for no data byteLookupTable = new byte[numBands][256]; for (int i = 0; i < byteLookupTable[0].length; i++) { byte value = (byte) i; for (int b = 0; b < numBands; b++) { if (noData.contains(value)) { byteLookupTable[b][i] = destinationNoDataByte[b]; } else { byteLookupTable[b][i] = value; } } } } //Definition of the possible cases that can be found // caseA = no ROI nor No Data // caseB = ROI present but No Data not present // caseC = No Data present but ROI not present // Last case not defined = both ROI and No Data are present caseA = !hasROI && !hasNoData; caseB = hasROI && !hasNoData; caseC = !hasROI && hasNoData; } @Override protected void computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect) { // Retrieve format tags. RasterFormatTag[] formatTags = getFormatTags(); // Only one source raster is used Raster source = sources[0]; // Get the source rectangle Rectangle srcRect = source.getBounds(); // SRC and destination accessors are used for simplifying calculations RasterAccessor srcAccessor = new RasterAccessor(source, srcRect, formatTags[0], getSourceImage(0).getColorModel()); RasterAccessor dstAccessor = new RasterAccessor(dest, destRect, formatTags[1], getColorModel()); // Destination rectangle dimensions int dwidth = destRect.width; int dheight = destRect.height; // From the rasterAccessor are calculated the pixelStride and the scanLineStride int srcPixelStride = srcAccessor.getPixelStride(); int srcScanlineStride = srcAccessor.getScanlineStride(); // Initialization of the x and y position array int[] xpos = new int[dwidth]; int[] ypos = new int[dheight]; // ROI support int[] yposRoi = null; // Scanline stride. It is used as integer because it can return null values int roiScanlineStride = 0; // Roi rasterAccessor initialization RasterAccessor roiAccessor = null; // Roi raster initialization Raster roi = null; RandomIter roiIter = null; // ROI calculation only if the roi raster is present if (hasROI) { if (useRoiAccessor) { if(srcROIImage.getBounds().contains(srcRect)){ roi = srcROIImage.getData(srcRect); } else { roi = srcROIImgExt.getData(srcRect); } // creation of the rasterAccessor roiAccessor = new RasterAccessor(roi, srcRect, RasterAccessor.findCompatibleTags( new RenderedImage[] { srcROIImage }, srcROIImage)[0], srcROIImage.getColorModel()); // ROI scanlinestride roiScanlineStride = roiAccessor.getScanlineStride(); // Initialization of the roi y position array yposRoi = new int[dheight]; } else { roiIter = RandomIterFactory.create(srcROIImgExt, roiRect, true, true); } } // Initialization of the x and y fractional array int[] xfracValues = new int[dwidth]; int[] yfracValues = new int[dheight]; preComputePositionsInt(destRect, srcRect.x, srcRect.y, srcPixelStride, srcScanlineStride, xpos, ypos, xfracValues, yfracValues, roiScanlineStride, yposRoi); // destination data type dataType = dest.getSampleModel().getDataType(); // This methods differs only for the presence of the roi or if the image is a binary one // if is binary // computeLoopBynary(srcAccessor, source, dest, destRect, xpos, ypos,yposRoi, xfracvalues, // yfracvalues,roi,yposRoi,srcRect.x, srcRect.y); switch (dstAccessor.getDataType()) { case DataBuffer.TYPE_BYTE: byteLoop(srcAccessor, srcRect, destRect, dstAccessor, xpos, ypos, roiAccessor, yposRoi, roiIter); break; case DataBuffer.TYPE_USHORT: ushortLoop(srcAccessor, destRect, dstAccessor, xpos, ypos, roiAccessor, yposRoi, roiIter); break; case DataBuffer.TYPE_SHORT: shortLoop(srcAccessor, destRect, dstAccessor, xpos, ypos, roiAccessor, yposRoi, roiIter); break; case DataBuffer.TYPE_INT: intLoop(srcAccessor, destRect, dstAccessor, xpos, ypos, roiAccessor, yposRoi, roiIter); break; case DataBuffer.TYPE_FLOAT: floatLoop(srcAccessor, destRect, dstAccessor, xpos, ypos, roiAccessor, yposRoi, roiIter); break; case DataBuffer.TYPE_DOUBLE: doubleLoop(srcAccessor, destRect, dstAccessor, xpos, ypos, roiAccessor, yposRoi, roiIter); break; } } private void byteLoop(RasterAccessor src, Rectangle srcRect, Rectangle dstRect, RasterAccessor dst, int[] xpos, int[] ypos, RasterAccessor roi, int[] yposRoi, RandomIter roiIter) { // BandOffsets final int srcScanlineStride = src.getScanlineStride(); final int srcPixelStride = src.getPixelStride(); final int bandOffsets[] = src.getBandOffsets(); // Destination rectangle dimensions final int dwidth = dstRect.width; final int dheight = dstRect.height; // Destination image band numbers final int dnumBands = dst.getNumBands(); // Destination bandOffsets, PixelStride and ScanLineStride final int dstBandOffsets[] = dst.getBandOffsets(); final int dstPixelStride = dst.getPixelStride(); final int dstScanlineStride = dst.getScanlineStride(); // Destination and source data arrays (for all bands) final byte[][] srcDataArrays = src.getByteDataArrays(); final byte[][] dstDataArrays = dst.getByteDataArrays(); final byte[] roiDataArray; final int roiDataLength; if (useRoiAccessor) { roiDataArray = roi.getByteDataArray(0); roiDataLength = roiDataArray.length; } else { roiDataArray = null; roiDataLength = 0; } if (caseA) { // for all bands for (int k = 0; k < dnumBands; k++) { final byte[] srcData = srcDataArrays[k]; final byte[] dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection int posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection int posx = xpos[i]; int pos = posx + posy; // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (caseB) { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { final byte[] srcData = srcDataArrays[k]; final byte[] dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection int posy = ypos[j] + bandOffset; // roi y position initialization int posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection int posx = xpos[i]; int pos = posx + posy; int windex = (posx / dnumBands) + posyROI; int w = windex < roiDataLength ? roiDataArray[windex] & 0xff : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataByte[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { final byte[] srcData = srcDataArrays[k]; final byte[] dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection int posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection int posx = xpos[i]; int pos = posx + posy; // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { int w = roiIter.getSample(x0, y0, 0) & 0xff; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataByte[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataByte[k]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } else { if (caseC) { // for all bands for (int k = 0; k < dnumBands; k++) { final byte[] srcData = srcDataArrays[k]; final byte[] dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection int posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection int posx = xpos[i]; int pos = posx + posy; int value = srcData[pos]; dstData[dstPixelOffset] = byteLookupTable[k][value&0xFF]; // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { final byte[] srcData = srcDataArrays[k]; final byte[] dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection int posy = ypos[j] + bandOffset; // roi y position initialization int posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection int posx = xpos[i]; int pos = posx + posy; int value = srcData[pos]; if (byteLookupTable[k][value&0xFF] == destinationNoDataByte[k]) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataByte[k]; } else { int windex = (posx / dnumBands) + posyROI; int w = windex < roiDataLength ? roiDataArray[windex] & 0xff : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataByte[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = byteLookupTable[k][value&0xFF]; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { final byte[] srcData = srcDataArrays[k]; final byte[] dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection int posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection int posx = xpos[i]; int pos = posx + posy; int value = srcData[pos]; if (byteLookupTable[k][value&0xFF] == destinationNoDataByte[k]) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataByte[k]; } else { // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { int w = roiIter.getSample(x0, y0, 0) & 0xff; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataByte[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = byteLookupTable[k][value&0xFF]; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataByte[k]; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } } } } private void ushortLoop(RasterAccessor src, Rectangle dstRect, RasterAccessor dst, int[] xpos, int[] ypos, RasterAccessor roi, int[] yposRoi, RandomIter roiIter) { // BandOffsets int srcScanlineStride = src.getScanlineStride(); int srcPixelStride = src.getPixelStride(); int bandOffsets[] = src.getBandOffsets(); // Destination rectangle dimensions int dwidth = dstRect.width; int dheight = dstRect.height; // Destination image band numbers int dnumBands = dst.getNumBands(); // Destination bandOffsets, PixelStride and ScanLineStride int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); // Destination and source data arrays (for all bands) short[][] srcDataArrays = src.getShortDataArrays(); short[][] dstDataArrays = dst.getShortDataArrays(); // Destination and source data arrays (for a single band) short[] dstData = null; short[] srcData = null; byte[] roiDataArray = null; int roiDataLength = 0; int w, posx, posy, pos, posyROI, windex; if (useRoiAccessor) { roiDataArray = roi.getByteDataArray(0); roiDataLength = roiDataArray.length; } if (caseA) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (caseB) { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] & 0xffff : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0) & 0xffff; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } else if (caseC) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; short value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; short value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } else { windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] & 0xffff : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; short value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } else { // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0) & 0xffff; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataUShort[k]; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } } } private void shortLoop(RasterAccessor src, Rectangle dstRect, RasterAccessor dst, int[] xpos, int[] ypos, RasterAccessor roi, int[] yposRoi, RandomIter roiIter) { // BandOffsets int srcScanlineStride = src.getScanlineStride(); int srcPixelStride = src.getPixelStride(); int bandOffsets[] = src.getBandOffsets(); // Destination rectangle dimensions int dwidth = dstRect.width; int dheight = dstRect.height; // Destination image band numbers int dnumBands = dst.getNumBands(); // Destination bandOffsets, PixelStride and ScanLineStride int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); // Destination and source data arrays (for all bands) short[][] srcDataArrays = src.getShortDataArrays(); short[][] dstDataArrays = dst.getShortDataArrays(); // Destination and source data arrays (for a single band) short[] dstData = null; short[] srcData = null; byte[] roiDataArray = null; int roiDataLength = 0; int w, posx, posy, pos, posyROI, windex; if (useRoiAccessor) { roiDataArray = roi.getByteDataArray(0); roiDataLength = roiDataArray.length; } if (caseA) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (caseB) { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0); if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } else if (caseC) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; short value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; short value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } else { windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; short value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } else { // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0); if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataShort[k]; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } } } private void intLoop(RasterAccessor src, Rectangle dstRect, RasterAccessor dst, int[] xpos, int[] ypos, RasterAccessor roi, int[] yposRoi, RandomIter roiIter) { // BandOffsets int srcScanlineStride = src.getScanlineStride(); int srcPixelStride = src.getPixelStride(); int bandOffsets[] = src.getBandOffsets(); // Destination rectangle dimensions int dwidth = dstRect.width; int dheight = dstRect.height; // Destination image band numbers int dnumBands = dst.getNumBands(); // Destination bandOffsets, PixelStride and ScanLineStride int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); // Destination and source data arrays (for all bands) int[][] srcDataArrays = src.getIntDataArrays(); int[][] dstDataArrays = dst.getIntDataArrays(); // Destination and source data arrays (for a single band) int[] dstData = null; int[] srcData = null; byte[] roiDataArray = null; int roiDataLength = 0; int w, posx, posy, pos, posyROI, windex; if (useRoiAccessor) { roiDataArray = roi.getByteDataArray(0); roiDataLength = roiDataArray.length; } if (caseA) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (caseB) { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0); if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } else if (caseC) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; int value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; int value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } else { windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; int value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } else { // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0); if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataInt[k]; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } } } private void floatLoop(RasterAccessor src, Rectangle dstRect, RasterAccessor dst, int[] xpos, int[] ypos, RasterAccessor roi, int[] yposRoi, RandomIter roiIter) { // BandOffsets int srcScanlineStride = src.getScanlineStride(); int srcPixelStride = src.getPixelStride(); int bandOffsets[] = src.getBandOffsets(); // Destination rectangle dimensions int dwidth = dstRect.width; int dheight = dstRect.height; // Destination image band numbers int dnumBands = dst.getNumBands(); // Destination bandOffsets, PixelStride and ScanLineStride int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); // Destination and source data arrays (for all bands) float[][] srcDataArrays = src.getFloatDataArrays(); float[][] dstDataArrays = dst.getFloatDataArrays(); // Destination and source data arrays (for a single band) float[] dstData = null; float[] srcData = null; byte[] roiDataArray = null; int roiDataLength = 0; int w, posx, posy, pos, posyROI, windex; if (useRoiAccessor) { roiDataArray = roi.getByteDataArray(0); roiDataLength = roiDataArray.length; } if (caseA) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (caseB) { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0); if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } else if (caseC) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; float value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; float value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } else { windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; float value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } else { // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0); if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataFloat[k]; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } } } private void doubleLoop(RasterAccessor src, Rectangle dstRect, RasterAccessor dst, int[] xpos, int[] ypos, RasterAccessor roi, int[] yposRoi, RandomIter roiIter) { // BandOffsets int srcScanlineStride = src.getScanlineStride(); int srcPixelStride = src.getPixelStride(); int bandOffsets[] = src.getBandOffsets(); // Destination rectangle dimensions int dwidth = dstRect.width; int dheight = dstRect.height; // Destination image band numbers int dnumBands = dst.getNumBands(); // Destination bandOffsets, PixelStride and ScanLineStride int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); // Destination and source data arrays (for all bands) double[][] srcDataArrays = src.getDoubleDataArrays(); double[][] dstDataArrays = dst.getDoubleDataArrays(); // Destination and source data arrays (for a single band) double[] dstData = null; double[] srcData = null; byte[] roiDataArray = null; int roiDataLength = 0; int w, posx, posy, pos, posyROI, windex; if (useRoiAccessor) { roiDataArray = roi.getByteDataArray(0); roiDataLength = roiDataArray.length; } if (caseA) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (caseB) { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0); if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = srcData[pos]; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } else if (caseC) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; double value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { if (useRoiAccessor) { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // roi y position initialization posyROI = yposRoi[j]; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; double value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } else { windex = (posx / dnumBands) + posyROI; w = windex < roiDataLength ? roiDataArray[windex] : 0; if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } else { // for all bands for (int k = 0; k < dnumBands; k++) { srcData = srcDataArrays[k]; dstData = dstDataArrays[k]; // Line and band Offset initialization int dstlineOffset = dstBandOffsets[k]; int bandOffset = bandOffsets[k]; // cycle on the y values for (int j = 0; j < dheight; j++) { // pixel offset initialization int dstPixelOffset = dstlineOffset; // y position selection posy = ypos[j] + bandOffset; // cycle on the x values for (int i = 0; i < dwidth; i++) { // x position selection posx = xpos[i]; pos = posx + posy; double value = srcData[pos]; if (noData.contains(value)) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } else { // PixelPositions int x0 = src.getX() + posx / srcPixelStride; int y0 = src.getY() + (posy - bandOffset) / srcScanlineStride; if (roiBounds.contains(x0, y0)) { w = roiIter.getSample(x0, y0, 0); if (w == 0) { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } else { // The interpolated value is saved in the destination array dstData[dstPixelOffset] = value; } } else { // The destination no data value is saved in the destination array dstData[dstPixelOffset] = destinationNoDataDouble[k]; } } // destination pixel offset update dstPixelOffset += dstPixelStride; } // destination line offset update dstlineOffset += dstScanlineStride; } } } } } } }