/** * 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 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 } }