/**
   * 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
  private static void writeTIFFFieldToStream(TIFFField field, ImageOutputStream stream)
      throws IOException {
    int count = field.getCount();
    Object data = field.getData();

    switch (field.getType()) {
      case TIFFTag.TIFF_ASCII:
        for (int i = 0; i < count; i++) {
          String s = ((String[]) data)[i];
          int length = s.length();
          for (int j = 0; j < length; j++) {
            stream.writeByte(s.charAt(j) & 0xff);
          }
          stream.writeByte(0);
        }
        break;
      case TIFFTag.TIFF_UNDEFINED:
      case TIFFTag.TIFF_BYTE:
      case TIFFTag.TIFF_SBYTE:
        stream.write((byte[]) data);
        break;
      case TIFFTag.TIFF_SHORT:
        stream.writeChars((char[]) data, 0, ((char[]) data).length);
        break;
      case TIFFTag.TIFF_SSHORT:
        stream.writeShorts((short[]) data, 0, ((short[]) data).length);
        break;
      case TIFFTag.TIFF_SLONG:
        stream.writeInts((int[]) data, 0, ((int[]) data).length);
        break;
      case TIFFTag.TIFF_LONG:
        for (int i = 0; i < count; i++) {
          stream.writeInt((int) (((long[]) data)[i]));
        }
        break;
      case TIFFTag.TIFF_LONG8:
        stream.writeLongs((long[]) data, 0, ((long[]) data).length);
        break;
      case TIFFTag.TIFF_IFD_POINTER:
        stream.writeInt(0); // will need to be backpatched
        break;
      case TIFFTag.TIFF_FLOAT:
        stream.writeFloats((float[]) data, 0, ((float[]) data).length);
        break;
      case TIFFTag.TIFF_DOUBLE:
        stream.writeDoubles((double[]) data, 0, ((double[]) data).length);
        break;
      case TIFFTag.TIFF_SRATIONAL:
        for (int i = 0; i < count; i++) {
          stream.writeInt(((int[][]) data)[i][0]);
          stream.writeInt(((int[][]) data)[i][1]);
        }
        break;
      case TIFFTag.TIFF_RATIONAL:
        for (int i = 0; i < count; i++) {
          long num = ((long[][]) data)[i][0];
          long den = ((long[][]) data)[i][1];
          stream.writeInt((int) num);
          stream.writeInt((int) den);
        }
        break;
      default:
        // error
    }
  }