// Utilities /** * Returns the number of image directories (subimages) stored in a * given TIFF file, represented by a <code>SeekableStream</code>. */ public static int GetNumDirectories(RandomAccessFileOrArray stream) { long pointer = stream.FilePointer; // Save stream pointer stream.Seek(0L); int endian = stream.ReadUnsignedShort(); if (!IsValidEndianTag(endian)) { throw new ArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d)."); } bool isBigEndian = (endian == 0x4d4d); int magic = ReadUnsignedShort(stream, isBigEndian); if (magic != 42) { throw new ArgumentException("Bad magic number, should be 42."); } stream.Seek(4L); long offset = ReadUnsignedInt(stream, isBigEndian); int numDirectories = 0; while (offset != 0L) { ++numDirectories; // EOFException means IFD was probably not properly terminated. try { stream.Seek(offset); int entries = ReadUnsignedShort(stream, isBigEndian); stream.Skip(12*entries); offset = ReadUnsignedInt(stream, isBigEndian); } catch (EndOfStreamException) { //numDirectories--; break; } } stream.Seek(pointer); // Reset stream pointer return numDirectories; }
/** * Constructs a TIFFDirectory from a SeekableStream. * The directory parameter specifies which directory to read from * the linked list present in the stream; directory 0 is normally * read but it is possible to store multiple images in a single * TIFF file by maintaing multiple directories. * * @param stream a SeekableStream to read from. * @param directory the index of the directory to read. */ public TIFFDirectory(RandomAccessFileOrArray stream, int directory) { long global_save_offset = stream.FilePointer; long ifd_offset; // Read the TIFF header stream.Seek(0L); int endian = stream.ReadUnsignedShort(); if (!IsValidEndianTag(endian)) { throw new ArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d)."); } isBigEndian = (endian == 0x4d4d); int magic = ReadUnsignedShort(stream); if (magic != 42) { throw new ArgumentException("Bad magic number, should be 42."); } // Get the initial ifd offset as an unsigned int (using a long) ifd_offset = ReadUnsignedInt(stream); for (int i = 0; i < directory; i++) { if (ifd_offset == 0L) { throw new ArgumentException("Directory number too large."); } stream.Seek(ifd_offset); int entries = ReadUnsignedShort(stream); stream.Skip(12*entries); ifd_offset = ReadUnsignedInt(stream); } stream.Seek(ifd_offset); Initialize(stream); stream.Seek(global_save_offset); }