Пример #1
0
        IFDEntry ParseMakernote(ushort tag, ushort type, uint count, long baseOffset, uint offset)
        {
            long makernote_offset = baseOffset + offset;
            var  ifd_structure    = new IFDStructure();

            // This is the minimum size a makernote should have
            // The shortest header is PENTAX_HEADER (4)
            // + IFD entry count (2)
            // + at least one IFD etry (12)
            // + next IFD pointer (4)
            // = 22 ....
            // we use this number to read a header which is big used
            // to identify the makernote types
            int header_size = 18;

            long length = 0;

            try {
                length = file.Length;
            } catch (Exception) {
                // Use a safety-value of 4 gigabyte.
                length = 1073741824L * 4;
            }

            if (makernote_offset > length)
            {
                file.MarkAsCorrupt("offset to makernote is beyond file size");
                return(null);
            }

            if (makernote_offset + header_size > length)
            {
                file.MarkAsCorrupt("data is to short to contain a maker note ifd");
                return(null);
            }

            // read header
            file.Seek(makernote_offset, SeekOrigin.Begin);
            ByteVector header = file.ReadBlock(header_size);

            if (header.StartsWith(PANASONIC_HEADER))
            {
                var reader = new IFDReader(file, is_bigendian, ifd_structure, baseOffset, offset + 12, max_offset);

                reader.ReadIFD(baseOffset, offset + 12, max_offset);
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Panasonic, PANASONIC_HEADER, 12, true, null));
            }

            if (header.StartsWith(PENTAX_HEADER))
            {
                var reader = new IFDReader(file, is_bigendian, ifd_structure, baseOffset, offset + 6, max_offset);

                reader.ReadIFD(baseOffset, offset + 6, max_offset);
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Pentax, header.Mid(0, 6), 6, true, null));
            }

            if (header.StartsWith(OLYMPUS1_HEADER))
            {
                var reader = new IFDReader(file, is_bigendian, ifd_structure, baseOffset, offset + 8, max_offset);

                reader.Read();
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Olympus1, header.Mid(0, 8), 8, true, null));
            }

            if (header.StartsWith(OLYMPUS2_HEADER))
            {
                var reader = new IFDReader(file, is_bigendian, ifd_structure, makernote_offset, 12, count);

                reader.Read();
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Olympus2, header.Mid(0, 12), 12, false, null));
            }

            if (header.StartsWith(SONY_HEADER))
            {
                var reader = new IFDReader(file, is_bigendian, ifd_structure, baseOffset, offset + 12, max_offset);

                reader.ReadIFD(baseOffset, offset + 12, max_offset);
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Sony, SONY_HEADER, 12, true, null));
            }

            if (header.StartsWith(NIKON_HEADER))
            {
                ByteVector endian_bytes = header.Mid(10, 2);

                if (endian_bytes.ToString() == "II" || endian_bytes.ToString() == "MM")
                {
                    bool   makernote_endian = endian_bytes.ToString().Equals("MM");
                    ushort magic            = header.Mid(12, 2).ToUShort(is_bigendian);

                    if (magic == 42)
                    {
                        var reader = new Nikon3MakernoteReader(file, makernote_endian, ifd_structure, makernote_offset + 10, 8, max_offset - offset - 10);

                        reader.Read();
                        return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Nikon3, header.Mid(0, 18), 8, false, makernote_endian));
                    }
                }
            }

            if (header.StartsWith(LEICA_HEADER))
            {
                var reader = new IFDReader(file, is_bigendian, ifd_structure, makernote_offset, 8, count);

                reader.Read();
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Leica, header.Mid(0, 8), 10, false, null));
            }

            try {
                var reader = new IFDReader(file, is_bigendian, ifd_structure, baseOffset, offset, max_offset);

                reader.Read();
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Canon));
            } catch {
                return(null);
            }
        }
Пример #2
0
        private IFDEntry ParseMakernote(ushort tag, ushort type, uint count, long base_offset, uint offset)
        {
            long         makernote_offset = base_offset + offset;
            IFDStructure ifd_structure    = new IFDStructure();
            int          header_size      = 18;
            long         length           = 0;

            try
            {
                length = file.Length;
            }
            catch (Exception)
            {
                length = 1073741824L * 4;
            }
            if (makernote_offset > length)
            {
                file.MarkAsCorrupt("offset to makernote is beyond file size");
                return(null);
            }
            if (makernote_offset + header_size > length)
            {
                file.MarkAsCorrupt("data is to short to contain a maker note ifd");
                return(null);
            }
            file.Seek(makernote_offset, SeekOrigin.Begin);
            ByteVector header = file.ReadBlock(header_size);

            if (header.StartsWith(PANASONIC_HEADER))
            {
                IFDReader reader = new IFDReader(file, is_bigendian, ifd_structure, base_offset, offset + 12, max_offset);
                reader.ReadIFD(base_offset, offset + 12, max_offset);
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Panasonic, PANASONIC_HEADER, 12, true, null));
            }
            if (header.StartsWith(PENTAX_HEADER))
            {
                IFDReader reader = new IFDReader(file, is_bigendian, ifd_structure, base_offset, offset + 6, max_offset);
                reader.ReadIFD(base_offset, offset + 6, max_offset);
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Pentax, header.Mid(0, 6), 6, true, null));
            }
            if (header.StartsWith(OLYMPUS1_HEADER))
            {
                IFDReader reader = new IFDReader(file, is_bigendian, ifd_structure, base_offset, offset + 8, max_offset);
                reader.Read();
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Olympus1, header.Mid(0, 8), 8, true, null));
            }
            if (header.StartsWith(OLYMPUS2_HEADER))
            {
                IFDReader reader = new IFDReader(file, is_bigendian, ifd_structure, makernote_offset, 12, count);
                reader.Read();
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Olympus2, header.Mid(0, 12), 12, false, null));
            }
            if (header.StartsWith(SONY_HEADER))
            {
                IFDReader reader = new IFDReader(file, is_bigendian, ifd_structure, base_offset, offset + 12, max_offset);
                reader.ReadIFD(base_offset, offset + 12, max_offset);
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Sony, SONY_HEADER, 12, true, null));
            }
            if (header.StartsWith(NIKON_HEADER))
            {
                ByteVector endian_bytes = header.Mid(10, 2);
                if (endian_bytes.ToString() == "II" || endian_bytes.ToString() == "MM")
                {
                    bool   makernote_endian = endian_bytes.ToString().Equals("MM");
                    ushort magic            = header.Mid(12, 2).ToUShort(is_bigendian);
                    if (magic == 42)
                    {
                        var reader = new Nikon3MakernoteReader(file, makernote_endian, ifd_structure, makernote_offset + 10, 8, max_offset - offset - 10);
                        reader.Read();
                        return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Nikon3, header.Mid(0, 18), 8, false, makernote_endian));
                    }
                }
            }
            if (header.StartsWith(LEICA_HEADER))
            {
                IFDReader reader = new IFDReader(file, is_bigendian, ifd_structure, makernote_offset, 8, count);
                reader.Read();
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Leica, header.Mid(0, 8), 10, false, null));
            }
            try
            {
                IFDReader reader = new IFDReader(file, is_bigendian, ifd_structure, base_offset, offset, max_offset);
                reader.Read();
                return(new MakernoteIFDEntry(tag, ifd_structure, MakernoteType.Canon));
            }
            catch
            {
                return(null);
            }
        }