/** * Returns a contiguous <code>Raster</code> of data over the specified <code>Rectangle</code>. If * the region is a sub-region of a single tile, then a child of that tile will be returned. If the * region overlaps more than one tile and has 8 bits per sample, then a pixel interleaved Raster * having band offsets 0,1,... will be returned. Otherwise the Raster returned by <code> * im.copyData(null)</code> will be returned. */ private static final Raster getContiguousData(RenderedImage im, Rectangle region) { if (im == null) { throw new IllegalArgumentException("im == null"); } else if (region == null) { throw new IllegalArgumentException("region == null"); } Raster raster; if (im.getNumXTiles() == 1 && im.getNumYTiles() == 1) { // Image is not tiled so just get a reference to the tile. raster = im.getTile(im.getMinTileX(), im.getMinTileY()); // Ensure result has requested coverage. Rectangle bounds = raster.getBounds(); if (!bounds.equals(region)) { raster = raster.createChild( region.x, region.y, region.width, region.height, region.x, region.y, null); } } else { // Image is tiled. // Create an interleaved raster for copying for 8-bit case. // This ensures that for RGB data the band offsets are {0,1,2}. SampleModel sampleModel = im.getSampleModel(); WritableRaster target = sampleModel.getSampleSize(0) == 8 ? Raster.createInterleavedRaster( DataBuffer.TYPE_BYTE, im.getWidth(), im.getHeight(), sampleModel.getNumBands(), new Point(im.getMinX(), im.getMinY())) : null; // Copy the data. raster = im.copyData(target); } return raster; }
public static void dumpImageInfo(RenderedImage image) { final SampleModel sampleModel = image.getSampleModel(); final ColorModel colorModel = image.getColorModel(); System.out.println("image: " + image); System.out.println(" minX = " + image.getMinX()); System.out.println(" minY = " + image.getMinY()); System.out.println(" width = " + image.getWidth()); System.out.println(" height = " + image.getHeight()); System.out.println( " colorModel = " + (colorModel != null ? colorModel.getClass() : "null")); System.out.println( " colorSpace = " + (colorModel != null ? colorModel.getColorSpace() : "null")); System.out.println(" sampleModel = " + sampleModel.getClass()); System.out.println(" numBands = " + sampleModel.getNumBands()); System.out.println(" dataType = " + sampleModel.getDataType()); System.out.println(" transferType = " + sampleModel.getTransferType()); System.out.println(" tileGridXOffset = " + image.getTileGridXOffset()); System.out.println(" tileGridYOffset = " + image.getTileGridYOffset()); System.out.println(" minTileX = " + image.getMinTileX()); System.out.println(" minTileY = " + image.getMinTileY()); System.out.println(" tileWidth = " + image.getTileWidth()); System.out.println(" tileHeight = " + image.getTileHeight()); }
public void encode(RenderedImage im) throws IOException { // Get the SampleModel. SampleModel sm = im.getSampleModel(); // Check the data type, band count, and sample size. int dataType = sm.getTransferType(); if (dataType == DataBuffer.TYPE_FLOAT || dataType == DataBuffer.TYPE_DOUBLE) { throw new IllegalArgumentException(JaiI18N.getString("WBMPImageEncoder0")); } else if (sm.getNumBands() != 1) { throw new IllegalArgumentException(JaiI18N.getString("WBMPImageEncoder1")); } else if (sm.getSampleSize(0) != 1) { throw new IllegalArgumentException(JaiI18N.getString("WBMPImageEncoder2")); } // Save image dimensions. int width = im.getWidth(); int height = im.getHeight(); // Write WBMP header. output.write(0); // TypeField output.write(0); // FixHeaderField output.write(intToMultiByte(width)); // width output.write(intToMultiByte(height)); // height Raster tile = null; // If the data are not formatted nominally then reformat. if (sm.getDataType() != DataBuffer.TYPE_BYTE || !(sm instanceof MultiPixelPackedSampleModel) || ((MultiPixelPackedSampleModel) sm).getDataBitOffset() != 0) { MultiPixelPackedSampleModel mppsm = new MultiPixelPackedSampleModel( DataBuffer.TYPE_BYTE, width, height, 1, (width + 7) / 8, 0); WritableRaster raster = Raster.createWritableRaster(mppsm, new Point(im.getMinX(), im.getMinY())); raster.setRect(im.getData()); tile = raster; } else if (im.getNumXTiles() == 1 && im.getNumYTiles() == 1) { tile = im.getTile(im.getMinTileX(), im.getMinTileY()); } else { tile = im.getData(); } // Check whether the image is white-is-zero. boolean isWhiteZero = false; if (im.getColorModel() instanceof IndexColorModel) { IndexColorModel icm = (IndexColorModel) im.getColorModel(); isWhiteZero = (icm.getRed(0) + icm.getGreen(0) + icm.getBlue(0)) > (icm.getRed(1) + icm.getGreen(1) + icm.getBlue(1)); } // Get the line stride, bytes per row, and data array. int lineStride = ((MultiPixelPackedSampleModel) sm).getScanlineStride(); int bytesPerRow = (width + 7) / 8; byte[] bdata = ((DataBufferByte) tile.getDataBuffer()).getData(); // Write the data. if (!isWhiteZero && lineStride == bytesPerRow) { // Write the entire image. output.write(bdata, 0, height * bytesPerRow); } else { // Write the image row-by-row. int offset = 0; if (!isWhiteZero) { // Black-is-zero for (int row = 0; row < height; row++) { output.write(bdata, offset, bytesPerRow); offset += lineStride; } } else { // White-is-zero: need to invert data. byte[] inverted = new byte[bytesPerRow]; for (int row = 0; row < height; row++) { for (int col = 0; col < bytesPerRow; col++) { inverted[col] = (byte) (~(bdata[col + offset])); } output.write(inverted, 0, bytesPerRow); offset += lineStride; } } } }
private void testType(RenderedImage src, boolean nodataUsed, boolean roiUsed) { // Optional No Data Range used Range noData; // Source image data type int dataType = src.getSampleModel().getDataType(); // If no Data are present, the No Data Range associated is used if (nodataUsed) { switch (dataType) { case DataBuffer.TYPE_BYTE: noData = noDataByte; break; case DataBuffer.TYPE_USHORT: noData = noDataUShort; break; case DataBuffer.TYPE_SHORT: noData = noDataShort; break; case DataBuffer.TYPE_INT: noData = noDataInt; break; case DataBuffer.TYPE_FLOAT: noData = noDataFloat; break; case DataBuffer.TYPE_DOUBLE: noData = noDataDouble; break; default: throw new IllegalArgumentException("Wrong data type"); } } else { noData = null; } ROI roi; if (roiUsed) { roi = roiObject; } else { roi = null; } // BandCombined result RenderedOp combined = BandCombineDescriptor.create(src, matrix, roi, noData, destinationNoData, null); int tileWidth = combined.getTileWidth(); int tileHeight = combined.getTileHeight(); int minTileX = combined.getMinTileX(); int minTileY = combined.getMinTileY(); int numXTiles = combined.getNumXTiles(); int numYTiles = combined.getNumYTiles(); int maxTileX = minTileX + numXTiles; int maxTileY = minTileY + numYTiles; // Ensure same size assertEquals(combined.getWidth(), src.getWidth()); assertEquals(combined.getHeight(), src.getHeight()); assertEquals(combined.getMinX(), src.getMinX()); assertEquals(combined.getMinY(), src.getMinY()); assertEquals(minTileX, src.getMinTileX()); assertEquals(minTileY, src.getMinTileY()); assertEquals(numXTiles, src.getNumXTiles()); assertEquals(numYTiles, src.getNumYTiles()); assertEquals(tileWidth, src.getTileWidth()); assertEquals(tileHeight, src.getTileHeight()); int srcBands = src.getSampleModel().getNumBands(); int dstBands = combined.getNumBands(); // Ensure a correct band size assertEquals(dstBands, matrix.length); // Check on all the pixels if they have been calculate correctly for (int tileX = minTileX; tileX < maxTileX; tileX++) { for (int tileY = minTileY; tileY < maxTileY; tileY++) { Raster tile = combined.getTile(tileX, tileY); Raster srcTile = src.getTile(tileX, tileY); int minX = tile.getMinX(); int minY = tile.getMinY(); int maxX = minX + tileWidth - 1; int maxY = minY + tileHeight - 1; for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { boolean isValidRoi = !roiUsed || (roiUsed && roiObject.contains(x, y)); if (isValidRoi) { for (int b = 0; b < dstBands; b++) { // Getting the result double result = tile.getSampleDouble(x, y, b); // Calculating the expected result from sources boolean valid = false; double calculated = 0; for (int i = 0; i < srcBands; i++) { double sample = srcTile.getSampleDouble(x, y, i); boolean isValidData = !nodataUsed || (nodataUsed && !noDataDouble.contains(sample)); valid |= isValidData; if (isValidData) { switch (dataType) { case DataBuffer.TYPE_BYTE: calculated += ((int) sample & 0xFF) * matrix[b][i]; break; case DataBuffer.TYPE_USHORT: calculated += ((int) sample & 0xFFFF) * matrix[b][i]; break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_INT: case DataBuffer.TYPE_FLOAT: case DataBuffer.TYPE_DOUBLE: calculated += sample * matrix[b][i]; break; default: break; } } } if (valid) { calculated += matrix[b][srcBands]; switch (dataType) { case DataBuffer.TYPE_BYTE: calculated = ImageUtil.clampRoundByte(calculated); result = ImageUtil.clampRoundByte(result); break; case DataBuffer.TYPE_USHORT: calculated = ImageUtil.clampRoundUShort(calculated); result = ImageUtil.clampRoundUShort(result); break; case DataBuffer.TYPE_SHORT: calculated = ImageUtil.clampRoundShort(calculated); result = ImageUtil.clampRoundShort(result); break; case DataBuffer.TYPE_INT: calculated = ImageUtil.clampRoundInt(calculated); result = ImageUtil.clampRoundInt(result); break; case DataBuffer.TYPE_FLOAT: calculated = (float) calculated; calculated = (float) result; break; case DataBuffer.TYPE_DOUBLE: break; default: break; } assertEquals(result, calculated, TOLERANCE); } else { assertEquals(result, destNoData, TOLERANCE); } } } else { for (int b = 0; b < dstBands; b++) { assertEquals(tile.getSampleDouble(x, y, b), destNoData, TOLERANCE); } } } } } } // Disposal of the output image combined.dispose(); }