示例#1
0
        /// <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);
        }
示例#3
0
        /// <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));
        }
示例#4
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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();
        }
示例#8
0
 private bool readHeaderOkWithoutExceptions(ref TiffHeader header)
 {
     try
     {
         return(readHeaderOk(ref header));
     }
     catch
     {
         WarningExt(this, m_clientdata, m_name, "Failed to read header");
         return(false);
     }
 }
示例#9
0
        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();
        }
示例#10
0
        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);
            }
        }
示例#11
0
 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);
     }
 }
示例#12
0
        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);
        }
示例#13
0
        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();
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
        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();
        }
示例#19
0
        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);
        }
示例#20
0
        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);
        }