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); } }
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); } }