Skip to content

Commit

Permalink
MosaicOpImage won't produce suitable outputs without alpha, ROI or No…
Browse files Browse the repository at this point in the history
  • Loading branch information
aaime committed Dec 7, 2018
1 parent 150df98 commit d49d8dd
Showing 1 changed file with 155 additions and 19 deletions.
174 changes: 155 additions & 19 deletions jt-mosaic/src/main/java/it/geosolutions/jaiext/mosaic/MosaicOpImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ public class MosaicOpImage extends OpImage {
public static final double[] DEFAULT_DESTINATION_NO_DATA_VALUE = { 0 };

/** mosaic type selected */
private MosaicType mosaicTypeSelected;
private final MosaicType mosaicTypeSelected;

/** Number of bands for every image */
private int numBands;
private final int numBands;

/** Bean used for storing image data, ROI, alpha channel, Nodata Range */
private final ImageMosaicBean[] imageBeans;
Expand All @@ -99,10 +99,10 @@ public class MosaicOpImage extends OpImage {
private boolean alphaPresent;

/** Border extender for the source data */
private BorderExtender sourceBorderExtender;
private final BorderExtender sourceBorderExtender;

/** Border extender for the ROI or alpha channel data */
private BorderExtender zeroBorderExtender;
private final BorderExtender zeroBorderExtender;

/**
* No data values for the destination image if the pixel of the same location are no Data (Byte)
Expand Down Expand Up @@ -143,13 +143,13 @@ public class MosaicOpImage extends OpImage {
* Table used for checking no data values. The first index indicates the source, the second the
* band, the third the value
*/
protected byte[][][] byteLookupTable;
private final byte[][][] byteLookupTable;

/** Boolean array indicating which source images has No Data and not */
private final boolean[] hasNoData;

/** The format tag for the destination image */
private RasterFormatTag rasterFormatTag;
private final RasterFormatTag rasterFormatTag;

/** Enumerator for the type of mosaic weigher */
public enum WeightType {
Expand Down Expand Up @@ -633,7 +633,7 @@ public MosaicOpImage(List sources, ImageLayout layout, Map renderingHints,
RasterFormatTag[] tags = getRasterFormatTags();
for (int i = 0; i < numSources; i++) {
// Selection of the i-th source.
RenderedImage img = getSourceImage(i);
PlanarImage img = getSourceImage(i);
// Calculation of the padding
int[] padding = calculatePadding(img, totalBounds);
// Extend the Source image if padding is defined
Expand Down Expand Up @@ -674,9 +674,9 @@ public MosaicOpImage(List sources, ImageLayout layout, Map renderingHints,
RenderedOp create = JAI.create("border", pb);
imageBeans[i].setAlphaChannel(create);
} else {
imageBeans[i].setAlphaChannel(alpha);
imageBeans[i].setAlphaChannel(alpha);
}

if (alphaSampleModel.getNumBands() != 1) {
throw new IllegalArgumentException("Alpha bands number must be 1");
} else if (alphaSampleModel.getDataType() != sampleModel.getDataType()) {
Expand Down Expand Up @@ -709,7 +709,7 @@ public MosaicOpImage(List sources, ImageLayout layout, Map renderingHints,
RenderedOp create = JAI.create("border", pb);
imageBeans[i].setRoiImage(create);
} else {
imageBeans[i].setRoiImage(roiIMG);
imageBeans[i].setRoiImage(roiIMG);
}
imageBeans[i].setRoi(roi);
}
Expand Down Expand Up @@ -781,8 +781,7 @@ public MosaicOpImage(List sources, ImageLayout layout, Map renderingHints,
Range noDataByte = expandedNoDataRage;

// The lookup table is filled with the related no data or valid data for
// every
// value
// every value
for (int b = 0; b < numBands; b++) {
for (int z = 0; z < byteLookupTable[i][0].length; z++) {
if (noDataByte != null && noDataByte.contains(z)) {
Expand Down Expand Up @@ -893,6 +892,7 @@ public Raster computeTile(int tileX, int tileY) {
// Initialization of a new RasterBean for passing all the raster information
// to the compute rect method
Raster[] sourceRasters = new Raster[numSources];
Rectangle[] sourceRectangles = new Rectangle[numSources];
RasterFormatTag[] sourceTags = new RasterFormatTag[numSources];
ColorModel[] sourceColorModels = new ColorModel[numSources];
Raster[] alphaRasters = new Raster[numSources];
Expand All @@ -918,21 +918,22 @@ public Raster computeTile(int tileX, int tileY) {
// If the data are present then we can check if Alpha and ROI are present
if (data != null) {
sourceRasters[intersectingSourceCount] = data;
sourceRectangles[intersectingSourceCount] = srcRect != null && !srcRect.contains(destRectangle) ? srcRect : null;
sourceTags[intersectingSourceCount] = imageBeans[i].getRasterFormatTag();
sourceColorModels[intersectingSourceCount] = imageBeans[i].getColorModel();
noDataRanges[intersectingSourceCount] = imageBeans[i].getSourceNoData();

// Get the Alpha data from the padded alpha image if present
PlanarImage alpha = imageBeans[i].getAlphaChannel();
if (alphaPresent && alpha != null) {
alphaRasters[intersectingSourceCount] = alpha.getData(destRectangle);
alphaRasters[intersectingSourceCount] = alpha.getExtendedData(destRectangle, zeroBorderExtender);
alphaChannelColorModels[intersectingSourceCount] = imageBeans[i].getAlphaChannel().getColorModel();
}

// Get the ROI data from the padded ROI image if present
RenderedImage roi = imageBeans[i].getRoiImage();
if (roiPresent && roi != null) {
roiRasters[intersectingSourceCount] = roi.getData(destRectangle);
roiRasters[intersectingSourceCount] = PlanarImage.wrapRenderedImage(roi).getExtendedData(destRectangle, zeroBorderExtender);// roi.getData(destRectangle);
}

intersectingSourceCount++;
Expand All @@ -941,7 +942,7 @@ public Raster computeTile(int tileX, int tileY) {
}

// For the given source destination rasters, the mosaic is calculated
computeRect(sourceRasters, sourceTags, sourceColorModels, destRaster, destRectangle,
computeRect(sourceRasters, sourceRectangles, sourceTags, sourceColorModels, destRaster, destRectangle,
alphaRasters, roiRasters, noDataRanges, alphaChannelColorModels, intersectingSourceCount);

// Tile recycling if the Recycle is present
Expand All @@ -960,7 +961,7 @@ public Raster computeTile(int tileX, int tileY) {

}

private void computeRect(Raster[] sourceRasters, RasterFormatTag[] rasterFormatTags,
private void computeRect(Raster[] sourceRasters, Rectangle[] sourceRectangles, RasterFormatTag[] rasterFormatTags,
ColorModel[] sourceColorModels, WritableRaster destRaster, Rectangle destRectangle,
Raster[] alphaRasters, Raster[] roiRasters, Range[] noDataRanges, ColorModel[] alphaChannelColorModels, int sourcesNumber) {

Expand All @@ -976,6 +977,7 @@ private void computeRect(Raster[] sourceRasters, RasterFormatTag[] rasterFormatT
for (int i = 0; i < sourcesNumber; i++) {
// RasterAccessorBean temporary file
RasterBeanAccessor helpAccessor = new RasterBeanAccessor();
helpAccessor.setBounds(sourceRectangles[i]);
if (sourceRasters[i] != null) {
helpAccessor.setDataRasterAccessor(new RasterAccessorExt(sourceRasters[i],
destRectangle, rasterFormatTags[i], sourceColorModels[i], getNumBands(),
Expand Down Expand Up @@ -1166,10 +1168,10 @@ private void byteLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
}

// The destination data band are selected
byte[][] dBandDataByteS = dstDataByte;
final byte[][] dBandDataByteS = dstDataByte;
// the destination lineOffset is initialized
int[] dLineOffsetS = new int[dstBands];
int[] dPixelOffsetS = new int[dstBands];
final int[] dLineOffsetS = new int[dstBands];
final int[] dPixelOffsetS = new int[dstBands];
for (int b = 0; b < dstBands; b++) {
dLineOffsetS[b] = dstBandOffsets[b];
}
Expand Down Expand Up @@ -1211,6 +1213,17 @@ private void byteLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
if (dataRA == null) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source valuse are initialized only for the switch
// method
for (int b = 0; b < dstBands; b++) {
Expand Down Expand Up @@ -1318,6 +1331,16 @@ private void byteLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueByteS[b] = sBandDataByteS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -1574,6 +1597,17 @@ private void ushortLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
if (dataRA == null) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
valueS[b] = sBandDataUshortS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -1682,6 +1716,16 @@ private void ushortLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueUshortS[b] = (short) (sBandDataUshortS[s][b][sPixelOffsetsS[s][b]]
Expand Down Expand Up @@ -1943,6 +1987,17 @@ private void shortLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
if (dataRA == null) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueShortS[b] = sBandDataShortS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -2050,6 +2105,16 @@ private void shortLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueShortS[b] = sBandDataShortS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -2309,6 +2374,17 @@ private void intLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
if (dataRA == null) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueIntS[b] = sBandDataIntS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -2415,6 +2491,16 @@ private void intLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueIntS[b] = sBandDataIntS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -2674,6 +2760,17 @@ private void floatLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
if (dataRA == null) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueFloatS[b] = sBandDataFloatS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -2780,6 +2877,16 @@ private void floatLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueFloatS[b] = sBandDataFloatS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -3039,6 +3146,17 @@ private void doubleLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
if (dataRA == null) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueDoubleS[b] = sBandDataDoubleS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -3145,6 +3263,16 @@ private void doubleLoop(RasterBeanAccessor[] srcBean, RasterAccessor dst) {
continue;
}

final Rectangle rect = srcBean[s].getBounds();
if (rect != null && !rect.contains(dstX, dstY)) {
// just move forward the offsets
for (int b = 0; b < dstBands; b++) {
// Offset update
sPixelOffsetsS[s][b] += srcPixelStride[s];
}
continue;
}

// The source values are initialized only for the switch method
for (int b = 0; b < dstBands; b++) {
sourceValueDoubleS[b] = sBandDataDoubleS[s][b][sPixelOffsetsS[s][b]];
Expand Down Expand Up @@ -3290,6 +3418,7 @@ private static class RasterBeanAccessor {

// No data range
private Range sourceNoDataRangeRasterAccessor;
private Rectangle bounds;

// No-argument constructor as requested for the java beans
RasterBeanAccessor() {
Expand Down Expand Up @@ -3329,6 +3458,13 @@ public void setSourceNoDataRangeRasterAccessor(Range sourceNoDataRangeRasterAcce
this.sourceNoDataRangeRasterAccessor = sourceNoDataRangeRasterAccessor;
}

public void setBounds(Rectangle bounds) {
this.bounds = bounds;
}

public Rectangle getBounds() {
return bounds;
}
}

}

0 comments on commit d49d8dd

Please sign in to comment.