/* 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.convolve; import it.geosolutions.jaiext.range.Range; import java.awt.RenderingHints; import java.awt.image.RenderedImage; import javax.media.jai.BorderExtender; import javax.media.jai.ImageLayout; import javax.media.jai.KernelJAI; import javax.media.jai.ROI; import javax.media.jai.RasterAccessor; import javax.media.jai.iterator.RandomIter; import com.sun.media.jai.util.ImageUtil; public class ConvolveGeneralOpImage extends ConvolveOpImage { public ConvolveGeneralOpImage(RenderedImage source, BorderExtender extender, RenderingHints hints, ImageLayout l, KernelJAI kernel, ROI roi, Range noData, double destinationNoData, boolean skipNoData) { super(source, extender, hints, l, kernel, roi, noData, destinationNoData, skipNoData); } @Override protected void byteLoop(RasterAccessor src, RasterAccessor dst, RandomIter roiIter, boolean roiContainsTile) { // Parameter definition int dwidth = dst.getWidth(); int dheight = dst.getHeight(); int dnumBands = dst.getNumBands(); float[] kdata = kernel.getKernelData(); int kw = kernel.getWidth(); int kh = kernel.getHeight(); byte dstDataArrays[][] = dst.getByteDataArrays(); int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); byte srcDataArrays[][] = src.getByteDataArrays(); int srcBandOffsets[] = src.getBandOffsets(); int srcPixelStride = src.getPixelStride(); int srcScanlineStride = src.getScanlineStride(); // Definition of the positions parameters int x0 = 0; int y0 = 0; int srcX = src.getX(); int srcY = src.getY(); int srcScanlineOffset = 0; int dstScanlineOffset = 0; // Only valid data if (caseA || (caseB && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { byte dstData[] = dstDataArrays[k]; byte srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw; v++) { f += ((int) srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v]; imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil.clampRoundByte(f); } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI check } else if (caseB) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { byte dstData[] = dstDataArrays[k]; byte srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { f += ((int) srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (!inRoi) { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataByte; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundByte(f); } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // NoData Check } else if (caseC || (hasROI && hasNoData && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { byte dstData[] = dstDataArrays[k]; byte srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw && valid; v++) { // Check on the nodata int value = (int) srcData[imageOffset] & 0xff; if (valid && lut[value]) { f += value * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundByte(f); } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataByte; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI and NoData Check } else { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { byte dstData[] = dstDataArrays[k]; byte srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw && valid; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { int value = (int) srcData[imageOffset] & 0xff; if (valid && lut[value]) { f += value * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } f += ((int) srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (inRoi && valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundByte(f); } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataByte; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } } } @Override protected void ushortLoop(RasterAccessor src, RasterAccessor dst, RandomIter roiIter, boolean roiContainsTile) { // Parameter definition int dwidth = dst.getWidth(); int dheight = dst.getHeight(); int dnumBands = dst.getNumBands(); float[] kdata = kernel.getKernelData(); int kw = kernel.getWidth(); int kh = kernel.getHeight(); short dstDataArrays[][] = dst.getShortDataArrays(); int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); short srcDataArrays[][] = src.getShortDataArrays(); int srcBandOffsets[] = src.getBandOffsets(); int srcPixelStride = src.getPixelStride(); int srcScanlineStride = src.getScanlineStride(); // Definition of the positions parameters int x0 = 0; int y0 = 0; int srcX = src.getX(); int srcY = src.getY(); int srcScanlineOffset = 0; int dstScanlineOffset = 0; // Only valid data if (caseA || (caseB && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { short dstData[] = dstDataArrays[k]; short srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw; v++) { f += (srcData[imageOffset] & 0xffff) * kdata[kernelVerticalOffset + v]; imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil.clampRoundUShort(f); } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI check } else if (caseB) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { short dstData[] = dstDataArrays[k]; short srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { f += (srcData[imageOffset] & 0xffff) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (!inRoi) { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataShort; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundUShort(f); } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // NoData Check } else if (caseC || (hasROI && hasNoData && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { short dstData[] = dstDataArrays[k]; short srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw && valid; v++) { // Check on the nodata short value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value & 0xffff) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundUShort(f); } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataShort; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI and NoData Check } else { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { short dstData[] = dstDataArrays[k]; short srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw && valid; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { short value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value & 0xFFFF) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } f += ((int) srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (inRoi && valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundUShort(f); } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataShort; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } } } @Override protected void shortLoop(RasterAccessor src, RasterAccessor dst, RandomIter roiIter, boolean roiContainsTile) { // Parameter definition int dwidth = dst.getWidth(); int dheight = dst.getHeight(); int dnumBands = dst.getNumBands(); float[] kdata = kernel.getKernelData(); int kw = kernel.getWidth(); int kh = kernel.getHeight(); short dstDataArrays[][] = dst.getShortDataArrays(); int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); short srcDataArrays[][] = src.getShortDataArrays(); int srcBandOffsets[] = src.getBandOffsets(); int srcPixelStride = src.getPixelStride(); int srcScanlineStride = src.getScanlineStride(); // Definition of the positions parameters int x0 = 0; int y0 = 0; int srcX = src.getX(); int srcY = src.getY(); int srcScanlineOffset = 0; int dstScanlineOffset = 0; // Only valid data if (caseA || (caseB && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { short dstData[] = dstDataArrays[k]; short srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw; v++) { f += (srcData[imageOffset]) * kdata[kernelVerticalOffset + v]; imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil.clampRoundShort(f); } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI check } else if (caseB) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { short dstData[] = dstDataArrays[k]; short srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { f += (srcData[imageOffset]) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (!inRoi) { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataShort; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundShort(f); } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // NoData Check } else if (caseC || (hasROI && hasNoData && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { short dstData[] = dstDataArrays[k]; short srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw && valid; v++) { // Check on the nodata short value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundShort(f); } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataShort; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI and NoData Check } else { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { short dstData[] = dstDataArrays[k]; short srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw && valid; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { short value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } f += ((int) srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (inRoi && valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundShort(f); } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataShort; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } } } @Override protected void intLoop(RasterAccessor src, RasterAccessor dst, RandomIter roiIter, boolean roiContainsTile) { // Parameter definition int dwidth = dst.getWidth(); int dheight = dst.getHeight(); int dnumBands = dst.getNumBands(); float[] kdata = kernel.getKernelData(); int kw = kernel.getWidth(); int kh = kernel.getHeight(); int dstDataArrays[][] = dst.getIntDataArrays(); int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); int srcDataArrays[][] = src.getIntDataArrays(); int srcBandOffsets[] = src.getBandOffsets(); int srcPixelStride = src.getPixelStride(); int srcScanlineStride = src.getScanlineStride(); // Definition of the positions parameters int x0 = 0; int y0 = 0; int srcX = src.getX(); int srcY = src.getY(); int srcScanlineOffset = 0; int dstScanlineOffset = 0; // Only valid data if (caseA || (caseB && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { int dstData[] = dstDataArrays[k]; int srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw; v++) { f += (srcData[imageOffset]) * kdata[kernelVerticalOffset + v]; imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil.clampRoundInt(f); } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI check } else if (caseB) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { int dstData[] = dstDataArrays[k]; int srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { f += (srcData[imageOffset]) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (!inRoi) { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataInt; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundInt(f); } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // NoData Check } else if (caseC || (hasROI && hasNoData && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { int dstData[] = dstDataArrays[k]; int srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw && valid; v++) { // Check on the nodata int value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundInt(f); } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataInt; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI and NoData Check } else { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { int dstData[] = dstDataArrays[k]; int srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw && valid; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { int value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } f += ((int) srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (inRoi && valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = ImageUtil .clampRoundInt(f); } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataInt; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } } } @Override protected void floatLoop(RasterAccessor src, RasterAccessor dst, RandomIter roiIter, boolean roiContainsTile) { // Parameter definition int dwidth = dst.getWidth(); int dheight = dst.getHeight(); int dnumBands = dst.getNumBands(); float[] kdata = kernel.getKernelData(); int kw = kernel.getWidth(); int kh = kernel.getHeight(); float dstDataArrays[][] = dst.getFloatDataArrays(); int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); float srcDataArrays[][] = src.getFloatDataArrays(); int srcBandOffsets[] = src.getBandOffsets(); int srcPixelStride = src.getPixelStride(); int srcScanlineStride = src.getScanlineStride(); // Definition of the positions parameters int x0 = 0; int y0 = 0; int srcX = src.getX(); int srcY = src.getY(); int srcScanlineOffset = 0; int dstScanlineOffset = 0; // Only valid data if (caseA || (caseB && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { float dstData[] = dstDataArrays[k]; float srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw; v++) { f += (srcData[imageOffset]) * kdata[kernelVerticalOffset + v]; imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } dstData[dstPixelOffset + dstBandOffsets[k]] = f; } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI check } else if (caseB) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { float dstData[] = dstDataArrays[k]; float srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { f += (srcData[imageOffset]) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (!inRoi) { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataFloat; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = f; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // NoData Check } else if (caseC || (hasROI && hasNoData && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { float dstData[] = dstDataArrays[k]; float srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw && valid; v++) { // Check on the nodata float value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = f; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataFloat; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI and NoData Check } else { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { float dstData[] = dstDataArrays[k]; float srcData[] = srcDataArrays[k]; float f = 0.5F; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw && valid; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { float value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } f += ((int) srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (inRoi && valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = f; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataFloat; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } } } @Override protected void doubleLoop(RasterAccessor src, RasterAccessor dst, RandomIter roiIter, boolean roiContainsTile) { // Parameter definition int dwidth = dst.getWidth(); int dheight = dst.getHeight(); int dnumBands = dst.getNumBands(); float[] kdata = kernel.getKernelData(); int kw = kernel.getWidth(); int kh = kernel.getHeight(); double dstDataArrays[][] = dst.getDoubleDataArrays(); int dstBandOffsets[] = dst.getBandOffsets(); int dstPixelStride = dst.getPixelStride(); int dstScanlineStride = dst.getScanlineStride(); double srcDataArrays[][] = src.getDoubleDataArrays(); int srcBandOffsets[] = src.getBandOffsets(); int srcPixelStride = src.getPixelStride(); int srcScanlineStride = src.getScanlineStride(); // Definition of the positions parameters int x0 = 0; int y0 = 0; int srcX = src.getX(); int srcY = src.getY(); int srcScanlineOffset = 0; int dstScanlineOffset = 0; // Only valid data if (caseA || (caseB && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { double dstData[] = dstDataArrays[k]; double srcData[] = srcDataArrays[k]; double f = 0.5D; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw; v++) { f += (srcData[imageOffset]) * kdata[kernelVerticalOffset + v]; imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } dstData[dstPixelOffset + dstBandOffsets[k]] = f; } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI check } else if (caseB) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { double dstData[] = dstDataArrays[k]; double srcData[] = srcDataArrays[k]; double f = 0.5D; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; for (int u = 0; u < kh; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { f += (srcData[imageOffset]) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (!inRoi) { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataDouble; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = f; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // NoData Check } else if (caseC || (hasROI && hasNoData && roiContainsTile)) { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; for (int i = 0; i < dwidth; i++) { // Cycle on the bands for (int k = 0; k < dnumBands; k++) { double dstData[] = dstDataArrays[k]; double srcData[] = srcDataArrays[k]; double f = 0.5D; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; for (int v = 0; v < kw && valid; v++) { // Check on the nodata double value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = f; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataDouble; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } // ROI and NoData Check } else { for (int j = 0; j < dheight; j++) { int srcPixelOffset = srcScanlineOffset; int dstPixelOffset = dstScanlineOffset; y0 = srcY + j; for (int i = 0; i < dwidth; i++) { x0 = srcX + i; // Cycle on the bands for (int k = 0; k < dnumBands; k++) { double dstData[] = dstDataArrays[k]; double srcData[] = srcDataArrays[k]; double f = 0.5D; int kernelVerticalOffset = 0; int imageVerticalOffset = srcPixelOffset + srcBandOffsets[k]; // ROI check on the other kernel values boolean inRoi = false; boolean valid = true; for (int u = 0; u < kh && valid; u++) { int imageOffset = imageVerticalOffset; int yI = y0 + u; for (int v = 0; v < kw && valid; v++) { int xI = x0 + v; // Check if all the pixel kernel belongs to the // ROI if ((roiBounds.contains(xI, yI) && roiIter.getSample(xI, yI, 0) > 0)) { double value = srcData[imageOffset]; if (valid && noData.contains(value)) { f += (value) * kdata[kernelVerticalOffset + v]; } else if (skipNoData) { // if skipNoData is set to true // other computations are skipped valid = false; } f += ((int) srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v]; inRoi = true; } imageOffset += srcPixelStride; } kernelVerticalOffset += kw; imageVerticalOffset += srcScanlineStride; } if (inRoi && valid) { dstData[dstPixelOffset + dstBandOffsets[k]] = f; } else { dstData[dstPixelOffset + dstBandOffsets[k]] = destNoDataDouble; } } srcPixelOffset += srcPixelStride; dstPixelOffset += dstPixelStride; } srcScanlineOffset += srcScanlineStride; dstScanlineOffset += dstScanlineStride; } } } }