/// <summary> /// Initializes a new instance of the <see cref="JPEGFile"/> class from the /// specified data stream. /// </summary> /// <param name="stream">A <see cref="Sytem.IO.Stream"/> that contains image data.</param> /// <param name="encoding">The encoding to be used for text metadata when the source encoding is unknown.</param> protected internal TIFFFile(Stream stream, System.Text.Encoding encoding) { Format = ImageFileFormat.TIFF; IFDs = new List <ImageFileDirectory>(); Encoding = encoding; // Read the entire stream byte[] data = Utility.GetStreamBytes(stream); // Read the TIFF header TIFFHeader = TIFFHeader.FromBytes(data, 0); uint nextIFDOffset = TIFFHeader.IFDOffset; if (nextIFDOffset == 0) { throw new NotValidTIFFileException("The first IFD offset is zero."); } // Read IFDs in order while (nextIFDOffset != 0) { ImageFileDirectory ifd = ImageFileDirectory.FromBytes(data, nextIFDOffset, TIFFHeader.ByteOrder); nextIFDOffset = ifd.NextIFDOffset; IFDs.Add(ifd); } // Process IFDs // TODO: Add support for multiple frames foreach (ImageFileDirectoryEntry field in IFDs[0].Fields) { Properties.Add(ExifPropertyFactory.Get(field.Tag, field.Type, field.Count, field.Data, BitConverterEx.SystemByteOrder, IFD.Zeroth, Encoding)); } }
/// <summary> /// Returns a <see cref="TIFFHeader"/> initialized from the given byte data. /// </summary> /// <param name="data">The data.</param> /// <param name="offset">The offset into <paramref name="data"/>.</param> /// <returns>A <see cref="TIFFHeader"/> initialized from the given byte data.</returns> public static TIFFHeader FromBytes(byte[] data, int offset) { TIFFHeader header = new TIFFHeader(); // TIFF header if (data[offset] == 0x49 && data[offset + 1] == 0x49) { header.ByteOrder = BitConverterEx.ByteOrder.LittleEndian; } else if (data[offset] == 0x4D && data[offset + 1] == 0x4D) { header.ByteOrder = BitConverterEx.ByteOrder.BigEndian; } else { throw new NotValidTIFFHeader(); } // TIFF header may have a different byte order if (BitConverterEx.LittleEndian.ToUInt16(data, offset + 2) == 42) { header.TIFFHeaderByteOrder = BitConverterEx.ByteOrder.LittleEndian; } else if (BitConverterEx.BigEndian.ToUInt16(data, offset + 2) == 42) { header.TIFFHeaderByteOrder = BitConverterEx.ByteOrder.BigEndian; } else { throw new NotValidTIFFHeader(); } header.ID = 42; // IFD offset header.IFDOffset = BitConverterEx.ToUInt32(data, offset + 4, header.TIFFHeaderByteOrder, BitConverterEx.SystemByteOrder); return(header); }