/**
   * 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;
  }
Example #2
0
 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());
 }
Example #3
0
  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();
  }