/// <summary> /// Reads the TIFF header to the provided structure. /// </summary> /// <param name="inputStream">The input stream of TIFF data.</param> /// <param name="length">Length of the TIFF data.</param> /// <param name="tiffHeader">TIFF header.</param> /// <returns> /// Remaining length of the data on success, 0 on failure. /// </returns> private static int ReadTiffHeader(Stream inputStream, int length, TiffHeader tiffHeader) { if (length <= 8) { return(0); } // Read the byte order tiffHeader.ByteOrder = StreamProcessor.ReadPackedInt(inputStream, 4, false); length -= 4; if (tiffHeader.ByteOrder != TIFF_BYTE_ORDER_LITTLE_END && tiffHeader.ByteOrder != TIFF_BYTE_ORDER_BIG_END) { Debug.WriteLine("Invalid TIFF header"); return(0); } tiffHeader.LittleEndian = (tiffHeader.ByteOrder == TIFF_BYTE_ORDER_LITTLE_END); // Read the offset of the first IFD and check if it is reasonable tiffHeader.FirstIfdOffset = StreamProcessor.ReadPackedInt(inputStream, 4, tiffHeader.LittleEndian); length -= 4; if (tiffHeader.FirstIfdOffset < 8 || tiffHeader.FirstIfdOffset - 8 > length) { Debug.WriteLine("Invalid offset"); return(0); } return(length); }
public async Task ReadFirstIfdAsync_ReadsCorrectly(ByteOrder byteOrder) { var stream = new StreamBuilder(byteOrder) .WritePadding(20) .WriteInt16(3) .WriteTiffIfdEntry(2, TiffType.Ascii, 20, new byte[] { 1, 2, 3, 4 }) .WriteTiffIfdEntry(4, TiffType.Short, 40, new byte[] { 2, 3, 4, 5 }) .WriteTiffIfdEntry(6, TiffType.Double, 60, new byte[] { 3, 4, 5, 6 }) .WriteUInt32(123456) .ToStream(); var header = new TiffHeader { FirstIfdReference = new TiffIfdReference(20) }; var ifd = await TiffReader.ReadFirstIfdAsync(header, stream, byteOrder); Assert.Equal(3, ifd.Entries.Length); AssertTiff.Equal(new TiffIfdEntry { Tag = 2, Type = TiffType.Ascii, Count = 20, Value = new byte[] { 1, 2, 3, 4 } }, ifd.Entries[0]); AssertTiff.Equal(new TiffIfdEntry { Tag = 4, Type = TiffType.Short, Count = 40, Value = new byte[] { 2, 3, 4, 5 } }, ifd.Entries[1]); AssertTiff.Equal(new TiffIfdEntry { Tag = 6, Type = TiffType.Double, Count = 60, Value = new byte[] { 3, 4, 5, 6 } }, ifd.Entries[2]); Assert.Equal(new TiffIfdReference(123456), ifd.NextIfdReference); }
/// <summary> /// Reads orientation information from TIFF data. /// </summary> /// <param name="inputStream">The input stream of TIFF data.</param> /// <param name="length">Length of the TIFF data.</param> /// <returns> /// Orientation information (1/3/6/8 on success, 0 if not found). /// </returns> public static int ReadOrientationFromTIFF(Stream inputStream, int length) { // Read tiff header TiffHeader tiffHeader = new TiffHeader(); length = ReadTiffHeader(inputStream, length, tiffHeader); // Move to the first IFD // offset is relative to the beginning of the TIFF data // and we already consumed the first 8 bytes of header int toSkip = tiffHeader.FirstIfdOffset - 8; if (length == 0 || toSkip > length) { return(0); } inputStream.Seek(toSkip, SeekOrigin.Current); length -= toSkip; // Move to the entry with orientation tag length = MoveToTiffEntryWithTag( inputStream, length, tiffHeader.LittleEndian, TIFF_TAG_ORIENTATION); // Read orientation return(GetOrientationFromTiffEntry(inputStream, length, tiffHeader.LittleEndian)); }
private bool readHeaderOk(ref TiffHeader header) { bool res = readShortOK(out header.tiff_magic); if (res) { res = readShortOK(out header.tiff_version); } if (res) { if (header.tiff_version == TIFF_BIGTIFF_VERSION) { res = readShortOK(out header.tiff_offsize); if (res) { res = readShortOK(out header.tiff_fill); } if (res) { res = readUlongOK(out header.tiff_diroff); } } else { uint intout; res = readUIntOK(out intout); header.tiff_diroff = intout; } } return(res); }
public void SizeOfHeader_AlwaysReturnsEightBytes() { var header = new TiffHeader(); var size = TiffReader.SizeOfHeader(header); Assert.Equal(8, size); }
internal override IFDHeader ParseBytes(List <byte> bytes, Endianness e, int offsetCorrectionIndex) { IFDHeader result = new IFDHeader(typeof(NikonType3MakerNotesTagCode)); TiffHeader tiffHeader = exifProcessor.GetTiffHeader(bytes, 10); result = exifProcessor.GetIFDHeader <NikonType3MakerNotesTagCode>(IFDHeaderType.MakerNotesHeader, bytes, 10 + 8, 10 + 8, tiffHeader.ByteOrder); return(result); }
public void TryParse_ValidStreamButInvalidStartIndex_ReturnFalseAndOutputNull() { var correctTiffStream = new FileStream(Constants.TiffSamplePath, FileMode.Open, FileAccess.Read); var invalidStartIndexStreamResult = TiffHeader.TryParse(correctTiffStream, 1, out var headerInvalidStartIndexResult); Assert.IsFalse(invalidStartIndexStreamResult); Assert.IsNull(headerInvalidStartIndexResult); correctTiffStream.Dispose(); }
private bool readHeaderOkWithoutExceptions(ref TiffHeader header) { try { return(readHeaderOk(ref header)); } catch { WarningExt(this, m_clientdata, m_name, "Failed to read header"); return(false); } }
public void TryParse_ValidStream_ReturnTrueAndCorrectNull() { var validStream = new FileStream(Constants.TiffSamplePath, FileMode.Open, FileAccess.Read, FileShare.Read); var validStreamResult = TiffHeader.TryParse(validStream, 0, out var tiffHeader); Assert.IsTrue(validStreamResult); Assert.IsNotNull(tiffHeader); Assert.AreEqual(0x002A, tiffHeader.VersionNumber); Assert.IsTrue(tiffHeader.ByteOrder == ByteOrder.BigEndian || tiffHeader.ByteOrder == ByteOrder.LittleEndian); Assert.IsTrue(tiffHeader.OffsetOfIfd0 > 0); validStream.Dispose(); }
private bool readHeaderOkWithoutExceptions(ref TiffHeader header) { try { return(readHeaderOk(ref header)); } #pragma warning disable CA1031 // Do not catch general exception types catch #pragma warning restore CA1031 // Do not catch general exception types { WarningExt(this, m_clientdata, m_name, "Failed to read header"); return(false); } }
public RawBase(ref byte[] Content) { if (IsCR3(Content)) { _rawType = RawType.CR3; this._content = Content; crxheader = new CRXHeader(ref Content); } else { _rawType = RawType.Tiff; this._content = Content; _header = new TiffHeader(ref Content); } }
private bool writeHeaderOK(TiffHeader header) { bool res = writeShortOK(header.tiff_magic); if (res) { res = writeShortOK(header.tiff_version); } if (res) { res = writeIntOK((int)header.tiff_diroff); } return(res); }
public static ImageInfo GetImageInfo(Stream imageStream) { if (Utility.StreamContainsJpegSoiEoiMarker(imageStream)) { //TODO parse jpeg return(null); } if (TiffHeader.TryParse(imageStream, 0, out TiffHeader header)) { //TODO Parse TIFF files. return(null); } throw new InvalidImageFormatException(); }
private bool readHeaderOk(ref TiffHeader header) { bool res = readShortOK(out header.tiff_magic); if (res) { res = readShortOK(out header.tiff_version); } if (res) { res = readUIntOK(out header.tiff_diroff); } return(res); }
private TiffHeader FindTiffCR3(CRXIFD[] ifd) { TiffHeader tiffHeader = null; foreach (var i in ifd) { if (i.SubIFD.Length > 0) { tiffHeader = FindTiffCR3(i.SubIFD); } if (i.TiffData != null) { tiffHeader = i.TiffData; } if (tiffHeader != null) { return(tiffHeader); } } return(tiffHeader); }
private bool writeHeaderOK(TiffHeader header) { // if we are here the cached image directory shortcut jump is invalid resetPenultimateDirectoryOffset(); bool res = writeShortOK(header.tiff_magic); if (res) { res = writeShortOK(header.tiff_version); } if (header.tiff_version == TIFF_BIGTIFF_VERSION) { if (res) { res = writeShortOK(header.tiff_offsize); } if (res) { res = writeShortOK(header.tiff_fill); } if (res) { res = writelongOK((long)header.tiff_diroff); } } else { if (res) { res = writeIntOK((int)header.tiff_diroff); } if (res) { res = writelongOK(0); } } return(res); }
private bool writeHeaderOK(TiffHeader header)//ALEX { //If we are here the cached directory jump is invalid AlexNextDirHighWaterMarkClear(); bool res = writeShortOK(header.tiff_magic); if (res) { res = writeShortOK(header.tiff_version); } if (header.tiff_version == TIFF_BIGTIFF_VERSION) { if (res) { res = writeShortOK(header.tiff_offsize); } if (res) { res = writeShortOK(header.tiff_fill); } if (res) { res = writelongOK((long)header.tiff_diroff);//ALEX2 } } else { if (res) { res = writeIntOK((int)header.tiff_diroff); } if (res) { res = writelongOK(0);//ALEX2 } } return(res); }
public void TryParse_InvalidStream_ReturnFalseAndOutputNull() { var invalidStream = new FileStream(Constants.InvalidImagePath, FileMode.Open, FileAccess.Read, FileShare.Read); var veryShortStream = new MemoryStream(Encoding.UTF8.GetBytes("er")); var closedStream = new MemoryStream(); closedStream.Dispose(); var noReadPermissionStream = new FileStream(Constants.TiffSamplePath, FileMode.Open, FileAccess.Write); var nullStreamResult = TiffHeader.TryParse(null, 0, out var headerNullResult); var invalidStreamResult = TiffHeader.TryParse(invalidStream, 0, out var headerInvalidResult); var veryShortStreamResult = TiffHeader.TryParse(veryShortStream, 0, out var headerVeryShortResult); var closeStreamResult = TiffHeader.TryParse(closedStream, 0, out var headerClosedResult); var noReadPermissionStreamResult = TiffHeader.TryParse(noReadPermissionStream, 0, out var headerNoReadPermissionResult); Assert.IsFalse(nullStreamResult); Assert.IsNull(headerNullResult); Assert.IsFalse(invalidStreamResult); Assert.IsNull(headerInvalidResult); Assert.IsFalse(veryShortStreamResult); Assert.IsNull(headerVeryShortResult); Assert.IsFalse(closeStreamResult); Assert.IsNull(headerClosedResult); Assert.IsFalse(noReadPermissionStreamResult); Assert.IsNull(headerNoReadPermissionResult); invalidStream.Dispose(); veryShortStream.Dispose(); noReadPermissionStream.Dispose(); }
private bool writeHeaderOK(TiffHeader header) { bool res = writeShortOK(header.tiff_magic); if (res) { res = writeShortOK(header.tiff_version); } if (header.tiff_version == TIFF_BIGTIFF_VERSION) { if (res) { res = writeShortOK(header.tiff_offsize); } if (res) { res = writeShortOK(header.tiff_fill); } if (res) { res = writelongOK((long)header.tiff_diroff); } } else { if (res) { res = writeIntOK((int)header.tiff_diroff); } if (res) { res = writelongOK(0); } } return(res); }
public CRXIFD(byte[] content, uint offset) { size = TiffType.getInt(offset, content, true); Name = Encoding.ASCII.GetString(content, (int)offset + SizeLen, NameLen).ToString(); if (Name == "PRVW") { PRVW = CRXParser.ParsePRVW(content, offset); } no = SizeLen + NameLen; if (size == 1) { size = TiffType.getInt((uint)(offset + no), content, true); no = SizeLen + NameLen + 8; } if (dicCount.Keys.Contains(Name)) { dicCount[Name]++; } else { dicCount.Add(Name, 1); } if (tags.Contains(Name)) { FillTags(Name, content, offset + no, size - no); } if (cmt.Contains(Name) || Name == "CMT") { TiffData = FillTiff(content, offset + no, size - no); } if (innerParsing.Contains(Name)) { var adressOffsetParent = (uint)(offset + no); if (Name == "uuid") { adressOffsetParent = adressOffsetParent + UUIDLen; } uint adressOffset = adressOffsetParent; do { var crx = new CRXIFD(content, adressOffset); adressOffset = crx.NextIFDOffset; lstCRXIFD.Add(crx); if (crx.Name == "\0\0\0\u0001") { break; } } while (adressOffset < (adressOffsetParent + size)); } if (innerOffsets.Keys.Contains(Name)) { size = (int)(size - no - innerOffsets[Name]); } if (Name == "trak") { Name = "trak" + dicCount["trak"]; } NextIFDOffset = (uint)(offset + size); }