public void write(final ImageOutputStream ios, final long ifdOffset, final long nextIfdOffset)
     throws IOException {
   Guardian.assertGreaterThan("ifdOffset", ifdOffset, -1);
   computeOffsets(ifdOffset);
   ios.seek(ifdOffset);
   final TiffDirectoryEntry[] entries = entrySet.getEntries();
   new TiffShort(entries.length).write(ios);
   long entryPosition = ios.getStreamPosition();
   for (TiffDirectoryEntry entry : entries) {
     ios.seek(entryPosition);
     entry.write(ios);
     entryPosition += TiffDirectoryEntry.BYTES_PER_ENTRY;
   }
   writeNextIfdOffset(ios, ifdOffset, nextIfdOffset);
 }
  /**
   * Gets pixel data of an <code>IIOImage</code> object.
   *
   * @param image an <code>IIOImage</code> object
   * @return a byte buffer of pixel data
   * @throws Exception
   */
  public static ByteBuffer getImageByteBuffer(IIOImage image) throws IOException {
    // Set up the writeParam
    TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.US);
    tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);

    // Get tif writer and set output to file
    Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(TIFF_FORMAT);
    ImageWriter writer = writers.next();

    if (writer == null) {
      throw new RuntimeException(
          "Need to install JAI Image I/O package.\nhttps://jai-imageio.dev.java.net");
    }

    // Get the stream metadata
    IIOMetadata streamMetadata = writer.getDefaultStreamMetadata(tiffWriteParam);

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
    writer.setOutput(ios);
    writer.write(
        streamMetadata, new IIOImage(image.getRenderedImage(), null, null), tiffWriteParam);
    //        writer.write(image.getRenderedImage());
    writer.dispose();
    //        ImageIO.write(image.getRenderedImage(), "tiff", ios); // this can be used in lieu of
    // writer
    ios.seek(0);
    BufferedImage bi = ImageIO.read(ios);
    return convertImageData(bi);
  }
Exemple #3
0
  /**
   * Gets pixel data of an <code>IIOImage</code> object.
   *
   * @param oimage an <code>IIOImage</code> object
   * @return a byte buffer of pixel data
   * @throws Exception
   */
  public static ByteBuffer getImageByteBuffer(BufferedImage oimage) throws IOException {
    // Get tif writer and set output to file
    ImageWriter writer = new TIFFImageWriterSpi().createWriterInstance();

    // Set up the writeParam
    // We are using the old JAI ImageIO plugin, because for some reason, OCR don't work with
    // TwelveMonkeys' plugin
    ImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.US);
    tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);

    // Get the stream metadata
    IIOMetadata streamMetadata = writer.getDefaultStreamMetadata(tiffWriteParam);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
    writer.setOutput(ios);
    writer.write(streamMetadata, new IIOImage(oimage, null, null), tiffWriteParam);
    writer.dispose();

    // Read the writed image
    ios.seek(0);
    ImageReader reader = new TIFFImageReaderSpi().createReaderInstance();
    ImageReadParam param = reader.getDefaultReadParam();
    reader.setInput(ios, true, true);
    BufferedImage bi;
    try {
      bi = reader.read(0, param);
    } finally {
      reader.dispose();
      ios.close();
    }

    return convertImageData(bi);
  }
 private long available() throws IOException {
   checkClosed();
   long pos = out.getStreamPosition();
   if (pos < offset) {
     out.seek(offset);
     pos = offset;
   }
   return offset + out.length() - pos;
 }
 public SubImageOutputStream(
     ImageOutputStream out, long offset, ByteOrder bo, boolean forwardFlushAndClose)
     throws IOException {
   this.out = out;
   this.offset = offset;
   this.forwardFlushAndClose = forwardFlushAndClose;
   setByteOrder(bo);
   out.seek(offset);
 }
  /**
   * 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();
    }
  }
 private void writeNextIfdOffset(
     final ImageOutputStream ios, final long ifdOffset, final long nextIfdOffset)
     throws IOException {
   ios.seek(getPosForNextIfdOffset(ifdOffset));
   new TiffLong(nextIfdOffset).write(ios);
 }
 @Override
 public void seek(long pos) throws IOException {
   out.seek(pos + offset);
   length = Math.max(pos - offset + 1, length);
 }
Exemple #9
0
  public void writeToStream(ImageOutputStream stream, final boolean isBTIFF) throws IOException {

    long nextSpace;

    if (!isBTIFF) {
      int numFields = getNumTIFFFields();
      stream.writeShort(numFields);

      nextSpace = stream.getStreamPosition() + 12 * numFields + 4;

    } else {
      long numFields = getNumTIFFFields();
      stream.writeLong(numFields);

      nextSpace = stream.getStreamPosition() + 20 * numFields + 8;
    }

    Iterator iter = iterator();

    while (iter.hasNext()) {
      TIFFField f = (TIFFField) iter.next();

      TIFFTag tag = f.getTag();

      int type = f.getType();
      int count = f.getCount();

      // Hack to deal with unknown tags
      if (type == 0) {
        type = TIFFTag.TIFF_UNDEFINED;
      }
      int size = count * TIFFTag.getSizeOfType(type);

      if (type == TIFFTag.TIFF_ASCII) {
        int chars = 0;
        for (int i = 0; i < count; i++) {
          chars += f.getAsString(i).length() + 1;
        }
        count = chars;
        size = count;
      }

      int tagNumber = f.getTagNumber();
      stream.writeShort(tagNumber);
      stream.writeShort(type);

      if (isBTIFF) {
        stream.writeLong(count);
        stream.writeLong(0);
        stream.mark(); // Mark beginning of next field
        stream.skipBytes(-8);
      } else {
        stream.writeInt(count);
        stream.writeInt(0);
        stream.mark(); // Mark beginning of next field
        stream.skipBytes(-4);
      }

      long pos;

      if (!isBTIFF) {
        if (size > 4 || tag.isIFDPointer()) {
          // Ensure IFD or value is written on a word boundary
          nextSpace = (nextSpace + 3) & ~0x3;

          stream.writeInt((int) nextSpace);
          stream.seek(nextSpace);
          pos = nextSpace;

          if (tag.isIFDPointer()) {
            TIFFIFD subIFD = (TIFFIFD) f.getData();
            subIFD.writeToStream(stream, isBTIFF);
            nextSpace = subIFD.lastPosition;
          } else {
            writeTIFFFieldToStream(f, stream);
            nextSpace = stream.getStreamPosition();
          }
        } else {
          pos = stream.getStreamPosition();
          writeTIFFFieldToStream(f, stream);
        }
      } else {
        if (size > 8 || tag.isIFDPointer()) {
          // Ensure IFD or value is written on a Long boundary
          nextSpace = (nextSpace + 7) & ~0x7;

          stream.writeLong(nextSpace);
          stream.seek(nextSpace);
          pos = nextSpace;

          if (tag.isIFDPointer()) {
            TIFFIFD subIFD = (TIFFIFD) f.getData();
            subIFD.writeToStream(stream, isBTIFF);
            nextSpace = subIFD.lastPosition;
          } else {
            writeTIFFFieldToStream(f, stream);
            nextSpace = stream.getStreamPosition();
          }
        } else {
          pos = stream.getStreamPosition();
          writeTIFFFieldToStream(f, stream);
        }
      }
      // If we are writing the data for the
      // StripByteCounts, TileByteCounts, StripOffsets,
      // TileOffsets, JPEGInterchangeFormat, or
      // JPEGInterchangeFormatLength fields, record the current stream
      // position for backpatching
      if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS
          || tagNumber == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS
          || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) {
        this.stripOrTileByteCountsPosition = pos;
      } else if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_OFFSETS
          || tagNumber == BaselineTIFFTagSet.TAG_TILE_OFFSETS
          || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) {
        this.stripOrTileOffsetsPosition = pos;
      }

      stream.reset(); // Go to marked position of next field
    }

    this.lastPosition = nextSpace;
  }