コード例 #1
0
  /**
   * Writes raster data from the given in-memory source buffer into the data sink specified by the
   * given source band and region.
   *
   * <p>
   *
   * <h3>Source band</h3>
   *
   * The source band is used to identify the data sink in which this method transfers the sample
   * values given in the source buffer. The method does not modify the pixel data of the given
   * source band at all.
   *
   * <p>
   *
   * <h3>Source buffer</h3>
   *
   * The first element of the source buffer corresponds to the given <code>sourceOffsetX</code> and
   * <code>sourceOffsetY</code> of the source region. These parameters are an offset within the
   * band's raster data and <b>not</b> an offset within the source buffer.<br>
   * The number of elements in the buffer must be exactly be <code>sourceWidth * sourceHeight</code>
   * . The pixel values to be writte are considered to be stored in line-by-line order, so the
   * raster X co-ordinate varies faster than the Y.
   *
   * <p>
   *
   * <h3>Source region</h3>
   *
   * The given destination region specified by the <code>sourceOffsetX</code>, <code>sourceOffsetY
   * </code>, <code>sourceWidth</code> and <code>sourceHeight</code> parameters is given in the
   * source band's raster co-ordinates. These co-ordinates are identical with the destination raster
   * co-ordinates since product writers do not support spectral or spatial subsets.
   *
   * @param sourceBand the source band which identifies the data sink to which to write the sample
   *     values
   * @param regionData the data buffer which provides the sample values to be written
   * @param regionX the X-offset in the band's raster co-ordinates
   * @param regionY the Y-offset in the band's raster co-ordinates
   * @param regionWidth the width of region to be written given in the band's raster co-ordinates
   * @param regionHeight the height of region to be written given in the band's raster co-ordinates
   * @throws java.io.IOException if an I/O error occurs
   * @throws IllegalArgumentException if the number of elements source buffer not equals <code>
   *     sourceWidth *
   *                                  sourceHeight</code> or the source region is out of the band's
   *     raster
   * @see Band#getRasterWidth()
   * @see Band#getRasterHeight()
   */
  public void writeBandRasterData(
      final Band sourceBand,
      final int regionX,
      final int regionY,
      final int regionWidth,
      final int regionHeight,
      final ProductData regionData,
      ProgressMonitor pm)
      throws IOException {
    if (!tempProduct.containsBand(sourceBand.getName())) {
      throw new IllegalArgumentException(
          "'" + sourceBand.getName() + "' is not a band of the product");
    }
    final int bandDataType = ifd.getBandDataType();
    final int stripIndex = getStripIndex(sourceBand);
    final TiffValue[] offsetValues = ifd.getEntry(TiffTag.STRIP_OFFSETS).getValues();
    final long stripOffset = ((TiffLong) offsetValues[stripIndex]).getValue();
    final TiffValue[] bitsPerSampleValues = ifd.getEntry(TiffTag.BITS_PER_SAMPLE).getValues();
    final long elemSize = ((TiffShort) bitsPerSampleValues[stripIndex]).getValue() / 8;
    final long sourceWidthBytes = sourceBand.getSceneRasterWidth() * elemSize;
    final long regionOffsetXInBytes = regionX * elemSize;
    final long pixelOffset = sourceWidthBytes * regionY + regionOffsetXInBytes;
    final long startOffset = stripOffset + pixelOffset;

    pm.beginTask("Writing band '" + sourceBand.getName() + "'...", regionHeight);
    try {
      for (int y = 0; y < regionHeight; y++) {
        ios.seek(startOffset + y * sourceWidthBytes);
        final int stride = y * regionWidth;
        if (bandDataType == ProductData.TYPE_UINT8) {
          final byte[] data = new byte[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (byte) regionData.getElemUIntAt(stride + x);
          }
          ios.write(data);
        } else if (bandDataType == ProductData.TYPE_INT8) {
          final byte[] data = new byte[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (byte) regionData.getElemIntAt(stride + x);
          }
          ios.write(data);
        } else if (bandDataType == ProductData.TYPE_UINT16) {
          final short[] data = new short[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (short) regionData.getElemUIntAt(stride + x);
          }
          ios.writeShorts(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_INT16) {
          final short[] data = new short[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (short) regionData.getElemIntAt(stride + x);
          }
          ios.writeShorts(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_UINT32) {
          final int[] data = new int[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (int) regionData.getElemUIntAt(stride + x);
          }
          ios.writeInts(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_INT32) {
          final int[] data = new int[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = regionData.getElemIntAt(stride + x);
          }
          ios.writeInts(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_FLOAT32) {
          final float[] data = new float[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = regionData.getElemFloatAt(stride + x);
          }
          ios.writeFloats(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_FLOAT64) {
          final double[] data = new double[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = regionData.getElemDoubleAt(stride + x);
          }
          ios.writeDoubles(data, 0, regionWidth);
        }
        pm.worked(1);
      }
    } finally {
      pm.done();
    }
  }
コード例 #2
0
  /**
   * Called by the framework in order to compute a tile for the given target band.
   *
   * <p>The default implementation throws a runtime exception with the message "not implemented".
   *
   * @param targetBand The target band.
   * @param targetTile The current tile associated with the target band to be computed.
   * @param pm A progress monitor which should be used to determine computation cancelation
   *     requests.
   * @throws OperatorException If an error occurs during computation of the target raster.
   */
  @Override
  public void computeTile(Band targetBand, Tile targetTile, ProgressMonitor pm)
      throws OperatorException {

    try {
      final Band sourceBand = sourceProduct.getBand(targetBand.getName());
      final Tile srcTile = getSourceTile(sourceBand, targetTile.getRectangle());

      final Stx stx = sourceBand.getStx();
      double origMin = stx.getMinimum();
      double origMax = stx.getMaximum();
      ScalingType scaling = verifyScaling(targetScaling, dataType);

      final double newMin = getMin(dataType);
      final double newMax = getMax(dataType);
      final double newRange = newMax - newMin;

      if (origMax <= newMax
          && origMin >= newMin
          && sourceBand.getDataType() < ProductData.TYPE_FLOAT32) scaling = ScalingType.NONE;

      final ProductData srcData = srcTile.getRawSamples();
      final ProductData dstData = targetTile.getRawSamples();

      final double srcNoDataValue = sourceBand.getNoDataValue();
      final double destNoDataValue = targetBand.getNoDataValue();

      if (scaling == ScalingType.LINEAR_PEAK_CLIPPED) {
        final Histogram histogram = new Histogram(stx.getHistogramBins(), origMin, origMax);
        final int[] bitCounts = histogram.getBinCounts();
        double rightPct = 0.025;
        for (int i = bitCounts.length - 1; i > 0; --i) {
          if (bitCounts[i] > 10) {
            rightPct = i / (double) bitCounts.length;
            break;
          }
        }
        final Range autoStretchRange = histogram.findRange(0.025, rightPct);
        origMin = autoStretchRange.getMin();
        origMax = autoStretchRange.getMax();
      } else if (scaling == ScalingType.LINEAR_CLIPPED) {
        final Histogram histogram = new Histogram(stx.getHistogramBins(), origMin, origMax);
        final Range autoStretchRange = histogram.findRangeFor95Percent();
        origMin = autoStretchRange.getMin();
        origMax = autoStretchRange.getMax();
      }
      final double origRange = origMax - origMin;

      final int numElem = dstData.getNumElems();
      double srcValue;
      for (int i = 0; i < numElem; ++i) {
        srcValue = srcData.getElemDoubleAt(i);
        if (srcValue == srcNoDataValue) {
          dstData.setElemDoubleAt(i, destNoDataValue);
        } else {
          if (scaling == ScalingType.NONE) dstData.setElemDoubleAt(i, srcValue);
          else if (scaling == ScalingType.TRUNC)
            dstData.setElemDoubleAt(i, truncate(srcValue, newMin, newMax));
          else if (scaling == ScalingType.LOGARITHMIC)
            dstData.setElemDoubleAt(i, logScale(srcValue, origMin, newMin, origRange, newRange));
          else {
            if (srcValue > origMax) srcValue = origMax;
            if (srcValue < origMin) srcValue = origMin;
            dstData.setElemDoubleAt(i, scale(srcValue, origMin, newMin, origRange, newRange));
          }
        }
      }

      targetTile.setRawSamples(dstData);
    } catch (Exception e) {
      throw new OperatorException(e.getMessage());
    }
  }