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; }