Esempio n. 1
0
        public void DumpMakerNotes3()
        {
            const string fileName = @"C:..\..\Photos\7Dhigh.CR2";

            using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);
                    var image    = rawImage.Directories.First();

                    var exifEntry = image[0x8769];
                    binaryReader.BaseStream.Seek(exifEntry.ValuePointer, SeekOrigin.Begin);
                    var exif = new ImageFileDirectory(binaryReader);

                    var notesEntry = exif[0x927c];
                    binaryReader.BaseStream.Seek(notesEntry.ValuePointer, SeekOrigin.Begin);
                    var notes = new ImageFileDirectory(binaryReader);
                    Assert.AreEqual(41, notes.Entries.Length);

                    var model = RawImage.ReadChars(binaryReader, notes[0x0006]);
                    Assert.AreEqual("Canon EOS 7D", model);

                    var firmware = RawImage.ReadChars(binaryReader, notes[0x0007]);
                    Assert.AreEqual("Firmware Version 2.0.3\0", firmware);

                    // 0x0010 ULong 32 - bit: 2147484240
                    var id = notes[0x0010];
                    Assert.AreEqual(0x80000250, id.ValuePointer);

                    // notes.DumpDirectory(binaryReader);
                }
        }
Esempio n. 2
0
        public void DumpCameraInfo()
        {
            const string fileName = @"C:..\..\Photos\5DIIIhigh.CR2";

            using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);
                    var image    = rawImage.Directories.First();

                    var exifEntry = image.Entries.Single(e => e.TagId == 0x8769 && e.TagType == 4);
                    binaryReader.BaseStream.Seek(exifEntry.ValuePointer, SeekOrigin.Begin);
                    var exif = new ImageFileDirectory(binaryReader);

                    var notesEntry = exif.Entries.Single(e => e.TagId == 0x927C && e.TagType == 7);
                    binaryReader.BaseStream.Seek(notesEntry.ValuePointer, SeekOrigin.Begin);
                    var notes = new ImageFileDirectory(binaryReader);

                    // 7)  0x000D UByte[]: [0x000006F0] (1536):                     // camera info
                    var entry = notes.Entries.Single(e => e.TagId == 0x000D && e.TagType == 7);
                    binaryReader.BaseStream.Seek(entry.ValuePointer, SeekOrigin.Begin);
                    var data = RawImage.ReadChars(binaryReader, entry);

                    //var xxx = new ImageFileDirectory(binaryReader);
                    // "ªª\u0010#\u0010#H\0\0\u0087\0i\0\u0003\0\0\0\0\0\0\u0001\0\0\u0006\0\0\0\u0094\u0002\0Z\0H\0Z\0 \0\0\0\0\0\0\0\0\u0003\0\0\0\0\0\0\0 \0\0\u0001»»HP\0\u001a\u0001\0ñ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0002\0\0\0ÿ\0H\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0001\u0001\0\0\0\0\u0003\u0001\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0004§\u0003\r\0\0\0\0\0\0\0\0\0ÿÿÿÿ\fÌÌ\u0002\0\0\0\u0001\0\0\0\0\0\0\0H\0\0\0\0\0\0\0\0H\0\0\0\0j\0\0\0\0\0P\u0014\0\0\0\0\0\0\0\0\0\0\u0006\0\0\0\u0006\0\0\0\u0006\0\0\0\u0004\0\0\0\u0004\0\0\0\u0004\0\0\0\u0001\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0085\0\0\0\u0001\0\0\0\u0001\0\0\0\u0001\0\0\0\a\0\u0001\0\0\0\0\u0003\u0005\u0003ÿÿ\u0003\a\u0001\0\0\0\0\0\a\0\0\0\0\0\0\u0016\u0001\0\0\0\u0001\0\u0001\u0003\0\0\0\0\0\0\0\0\0\0\0\0\0\t\u0001\0\0\0\0\0\0\0\u0006\u0001\0\0\a\u0003\u0003\u0003\u0002ÿ\0\0\0\0\0\0\0\0\u0001 P\0æ\0\u0018\0F\u0091g\u0002\0\0ÿ\0\0\0\0\0\0\0\0\0\0\0\0\0\0!\0\0\u0001\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0001\0\0\0\u0080\u0016\0\0\0\u000f\0\0à\u0010\0\0\u0080\n\0\0\u0080\u0004\0\0\0\u0003\0\0Ð\u0002\0\0à\u0001\0\0\0\0\0\0\0\0\0\0Ð\u0002\0\0à\u0001\0\0Ð\u0002\0\0à\u0001\0\0\0\0\0\0\0\0\0\0Ð\u0002\0\0à\u0001\0\0\0\0\0\0\0\0\0\0\u0001\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\0\u0002\0\0\0\0\0\0\0\0\0\0\n\u0002\0\u0001\0\0\u0001\0\0\u0002\u0001\0\0\0\0\0\0\0\u0001\u0001\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01.2.3\0A6(34)\0VQ\0\u0018\u0002\u0098\u0019Xþ\u0013\0dî\0\0dî\0\0\0\0\0\0Greg Eakin\0\0\0a3a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0e\0\0\0d\0\0\0d\0\0\0\u0082\0\0\0Ñ \0\0\0\0\0\0f\0\0\0e\0\0\0d\0\0\0\b\0\0\0\b\0\0\0\b\0\0\0\b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0î\u0001\0\u0004\0\u0004Ú\u0002\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ë\u0001\0\u0004\0\u0004~\u0002\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ë\u0001\0\u0004\0\u0004~\u0002\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ë\u0001\0\u0004\0\u0004~\u0002\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ë\u0001\0\u0004\0\u0004~\u0002\0\0\0\0\0\0\0\0\u0001\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0001\0\0\0\0\0\0\0\u0003\0\0\0\0\0\0\0\0\0\0\0ï¾­Þï¾­Þ\0\0\0\0\u0002\0\0\0\0\0\0\0\0\0\0\0ï¾­Þï¾­Þ\0\0\0\0\u0004\0\0\0\0\0\0\0\0\0\0\0ï¾­Þï¾­Þ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ï¾­Þï¾­Þ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ï¾­Þï¾­Þ\0\0\0\0\u0003\0\0\0ï¾­Þï¾­Þ\0\0\0\0\0\0\0\0\0\0\0\0\u0003\0\0\0\0\0\0\0\0\0\0\0ï¾­Þï¾­Þ\0\0\0\0\u0003\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0003\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0003\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0081\0\u0081\0\u0081\0\0\0ÿÿÿÿÿÿÿÿ\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0004\0\u0004\0\u0004\0\u0004\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0004\0\u0004\0\u0004\0\u0004\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0004\0\u0004\0\u0004\0\u0004\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0004\0\u0004\0\u0004\0\u0004\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\u0004\0\u0004\0\u0004\0\u0004\0\0\0\0\0\0\0\0q\b9S\t\0\0\0\0\0\u0001\0\0\0\u0001\0\0\0\0\0\0\0\0\0\0\0\u0001\0\0\0\0\0\0\0\0#\0\0\0\0\0\0\0\0\0\0\0\0À6\0\0Ä9\u0001\0\0\0\0\0\0\0\0\0\0\0\0\0\u0003\0\0\0S\0\0\0X\0\u0003\u0080\0\0\0\0\u0003\0\0\0M\0\0\0N\0\0\0\0\0\0\0\u0003\0\0\03\0\0\0;\0\u0003\u0080\0\0\0\0\u0003\0\0\0T"
                }
        }
Esempio n. 3
0
        public void Model()
        {
            using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);

                    // 0x0110 Ascii 8-bit: [0x000000FA] (13): Canon EOS 7D
                    var imageFileDirectory = rawImage[0x00000010];
                    var imageFileEntry     = imageFileDirectory[0x0110];
                    Assert.AreEqual(2, imageFileEntry.TagType);
                    Assert.AreEqual(0x000000FAu, imageFileEntry.ValuePointer);
                    Assert.AreEqual(21u, imageFileEntry.NumberOfValue);

                    Assert.AreEqual("Canon EOS 7D Mark II", RawImage.ReadChars(binaryReader, imageFileEntry));
                }
        }
Esempio n. 4
0
        public void Maker()
        {
            using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);

                    // 0x010F Ascii 8-bit: [0x000000F4] (6): Canon
                    var imageFileDirectory = rawImage[0x00000010];
                    var imageFileEntry     = imageFileDirectory[0x010F];
                    Assert.AreEqual(2, imageFileEntry.TagType);
                    Assert.AreEqual(0x000000F4u, imageFileEntry.ValuePointer);
                    Assert.AreEqual(6u, imageFileEntry.NumberOfValue);

                    var readChars = RawImage.ReadChars(binaryReader, imageFileEntry);
                    Assert.AreEqual("Canon", readChars);
                }
        }
Esempio n. 5
0
        public void TestMethodTags()
        {
            const string directory = @"..\..\Photos\";
            const string fileName2 = directory + "5DIIIhigh.CR2";

            using (var fileStream = File.Open(fileName2, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);

                    var ifd0 = rawImage.Directories.First();
                    var make = ifd0[0x010f];
                    Assert.AreEqual("Canon", RawImage.ReadChars(binaryReader, make));
                    var model = ifd0[0x0110];
                    // Assert.AreEqual("Canon EOS 7D", RawImage.ReadChars(binaryReader, model));
                    Assert.AreEqual("Canon EOS 5D Mark III", RawImage.ReadChars(binaryReader, model));

                    var exif = ifd0[0x8769];
                    binaryReader.BaseStream.Seek(exif.ValuePointer, SeekOrigin.Begin);
                    var tags = new ImageFileDirectory(binaryReader);

                    var makerNotes = tags[0x927C];
                    binaryReader.BaseStream.Seek(makerNotes.ValuePointer, SeekOrigin.Begin);
                    var notes = new ImageFileDirectory(binaryReader);

                    var white = notes[0x4001];
                    Console.WriteLine("0x{0:X4}, {1}, {2}, {3}", white.TagId, white.TagType, white.NumberOfValue, white.ValuePointer);
                    // var wb = new WhiteBalance(binaryReader, white);
                    ReadSomeData(binaryReader, white.ValuePointer);

                    var size2 = notes[0x4002];
                    Console.WriteLine("0x{0:X4}, {1}, {2}, {3}", size2.TagId, size2.TagType, size2.NumberOfValue, size2.ValuePointer);
                    ReadSomeData(binaryReader, size2.ValuePointer);

                    var size5 = notes[0x4005];
                    Console.WriteLine("0x{0:X4}, {1}, {2}, {3}", size5.TagId, size5.TagType, size5.NumberOfValue, size5.ValuePointer);
                    ReadSomeData(binaryReader, size5.ValuePointer);
                }
        }
Esempio n. 6
0
        public void XmpMetadata()
        {
            using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);

                    // 0x02BC Byte 8-bit: [0x000119C4] (8192): // XML packet containing XMP metadata
                    var imageFileDirectory = rawImage[0x00000010];
                    var imageFileEntry     = imageFileDirectory[0x02BC];
                    Assert.AreEqual(1, imageFileEntry.TagType);
                    Assert.AreEqual(0x0000B608u, imageFileEntry.ValuePointer);
                    Assert.AreEqual(8192u, imageFileEntry.NumberOfValue);

                    var readChars = RawImage.ReadChars(binaryReader, imageFileEntry);

                    const string Expected1 =
                        "<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?><x:xmpmeta xmlns:x=\"adobe:ns:meta/\"><rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"><rdf:Description rdf:about=\"\" xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"><xmp:Rating>0</xmp:Rating></rdf:Description></rdf:RDF></x:xmpmeta>";
                    Assert.AreEqual(Expected1, readChars.Substring(0, 291));
                    // lots of white space between these two substrings.
                    const string Expected2 = "<?xpacket end='w'?>";
                    Assert.AreEqual(Expected2, readChars.Substring(8173));
                }
        }
Esempio n. 7
0
        private static void DumpImage0(string fileName)
        {
            using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);

                    // Images #0 and #1 are compressed in lossy (classic) JPEG
                    var image = rawImage.Directories.First();

                    Assert.AreEqual(18, image.Entries.Length);
                    CollectionAssert.AreEqual(
                        new ushort[]
                    {
                        0x0100, 0x0101, 0x0102, 0x0103, 0x010F, 0x0110, 0x0111, 0x0112, 0x0117, 0x011A, 0x011B,
                        0x128, 0x0132, 0x013B, 0x02BC, 0x8298, 0x8769, 0x8825
                    },
                        image.Entries.Select(e => e.TagId).ToArray());

                    var imageWidth = image.Entries.Single(e => e.TagId == 0x0100 && e.TagType == 3).ValuePointer;
                    Assert.AreEqual(5760u, imageWidth);

                    var imageLength = image.Entries.Single(e => e.TagId == 0x0101 && e.TagType == 3).ValuePointer;
                    Assert.AreEqual(3840u, imageLength);

                    var imageFileEntry0102 = image.Entries.Single(e => e.TagId == 0x0102 && e.TagType == 3);
                    // Assert.AreEqual(3u, imageFileEntry0102.NumberOfValue);
                    // Assert.AreEqual(238u, imageFileEntry0102.ValuePointer);
                    var bitsPerSample = RawImage.ReadUInts16(binaryReader, imageFileEntry0102);
                    CollectionAssert.AreEqual(new[] { (ushort)8, (ushort)8, (ushort)8 }, bitsPerSample);

                    var compression = image.Entries.Single(e => e.TagId == 0x0103 && e.TagType == 3).ValuePointer;
                    Assert.AreEqual(6u, compression);

                    var imageFileEntry010F = image.Entries.Single(e => e.TagId == 0x010F && e.TagType == 2);
                    // Assert.AreEqual(6u, imageFileEntry010F.NumberOfValue);
                    // Assert.AreEqual(244u, imageFileEntry010F.ValuePointer);
                    var make = RawImage.ReadChars(binaryReader, imageFileEntry010F);
                    Assert.AreEqual("Canon", make);

                    var imageFileEntry0110 = image.Entries.Single(e => e.TagId == 0x0110 && e.TagType == 2);
                    // Assert.AreEqual(22u, imageFileEntry0110.NumberOfValue);
                    // Assert.AreEqual(250u, imageFileEntry0110.ValuePointer);
                    var model = RawImage.ReadChars(binaryReader, imageFileEntry0110);
                    Assert.AreEqual("Canon EOS 5D Mark III", model);

                    var stripOffset = image.Entries.Single(e => e.TagId == 0x0111 && e.TagType == 4).ValuePointer;
                    // Assert.AreEqual(99812u, stripOffset);

                    var orientation = image.Entries.Single(e => e.TagId == 0x0112 && e.TagType == 3).ValuePointer;
                    // Assert.AreEqual(1u, orientation);    // 1 = 0,0 is top left

                    var stripByteCounts = image.Entries.Single(e => e.TagId == 0x0117 && e.TagType == 4).ValuePointer;
                    // Assert.AreEqual(2823352u, stripByteCounts);

                    var imageFileEntry011A = image.Entries.Single(e => e.TagId == 0x011A && e.TagType == 5);
                    // Assert.AreEqual(1u, imageFileEntry011A.NumberOfValue);
                    // Assert.AreEqual(282u, imageFileEntry011A.ValuePointer);
                    var xResolution = RawImage.ReadRational(binaryReader, imageFileEntry011A);
                    CollectionAssert.AreEqual(new[] { 72u, 1u }, xResolution);

                    var imageFileEntry011B = image.Entries.Single(e => e.TagId == 0x011B && e.TagType == 5);
                    // Assert.AreEqual(1u, imageFileEntry011B.NumberOfValue);
                    // Assert.AreEqual(290u, imageFileEntry011B.ValuePointer);
                    var yResolution = RawImage.ReadRational(binaryReader, imageFileEntry011B);
                    CollectionAssert.AreEqual(new[] { 72u, 1u }, yResolution);

                    var resolutionUnit = image.Entries.Single(e => e.TagId == 0x0128 && e.TagType == 3).ValuePointer;
                    Assert.AreEqual(2u, resolutionUnit); // 1 == none, 2 == pixels per inch, 3 == pixels per centimeter

                    var imageFileEntry0132 = image.Entries.Single(e => e.TagId == 0x0132 && e.TagType == 2);
                    // Assert.AreEqual(20u, imageFileEntry0132.NumberOfValue);
                    // Assert.AreEqual(298u, imageFileEntry0132.ValuePointer);
                    var dateTime = RawImage.ReadChars(binaryReader, imageFileEntry0132);
                    // Assert.AreEqual("2016:02:21 14:04:17", dateTime);

                    var imageFileEntry013B = image.Entries.Single(e => e.TagId == 0x013B && e.TagType == 2);
                    // Assert.AreEqual(11u, imageFileEntry013B.NumberOfValue);
                    // Assert.AreEqual(318u, imageFileEntry013B.ValuePointer);
                    var item13 = RawImage.ReadChars(binaryReader, imageFileEntry013B);
                    Assert.AreEqual("Greg Eakin", item13);

                    var imageFileEntry02BC = image.Entries.Single(e => e.TagId == 0x02BC && e.TagType == 1);
                    // Assert.AreEqual(8192u, imageFileEntry02BC.NumberOfValue);
                    // Assert.AreEqual(72132u, imageFileEntry02BC.ValuePointer);
                    var xmpData = RawImage.ReadBytes(binaryReader, imageFileEntry02BC);
                    var xmp     = System.Text.Encoding.UTF8.GetString(xmpData);

                    var imageFileEntry8298 = image.Entries.Single(e => e.TagId == 0x8298 && e.TagType == 2);
                    // Assert.AreEqual(53u, imageFileEntry8298.NumberOfValue);
                    // Assert.AreEqual(382u, imageFileEntry8298.ValuePointer);
                    var item15 = RawImage.ReadChars(binaryReader, imageFileEntry8298);
                    // Assert.AreEqual("Copyright (c) 2015, Greg Eakin. All rights reserved.", item15);

                    var exif = image.Entries.Single(e => e.TagId == 0x8769 && e.TagType == 4).ValuePointer;
                    // Assert.AreEqual(446u, exif);

                    var gps = image.Entries.Single(e => e.TagId == 0x8825 && e.TagType == 4).ValuePointer;
                    // Assert.AreEqual(70028u, gps);
                }
        }
Esempio n. 8
0
        public void SearchWhiteBalance()
        {
            const string fileName = @"..\..\Photos\5DIIIhigh.CR2";

            using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);

                    var ifid0 = rawImage.Directories.First();
                    var make  = ifid0[0x010f]; // Make
                    Assert.AreEqual("Canon", RawImage.ReadChars(binaryReader, make));

                    var model = ifid0[0x0110]; // Model
                    // Assert.AreEqual("Canon EOS 7D", RawImage.ReadChars(binaryReader, model));
                    Assert.AreEqual("Canon EOS 5D Mark III", RawImage.ReadChars(binaryReader, model));

                    var exif = ifid0[0x8769]; // Exif Offset
                    binaryReader.BaseStream.Seek(exif.ValuePointer, SeekOrigin.Begin);
                    var tags = new ImageFileDirectory(binaryReader);
                    // tags.DumpDirectory(binaryReader);

                    var makerNotes = tags[0x927C]; // Maker Notes
                    binaryReader.BaseStream.Seek(makerNotes.ValuePointer, SeekOrigin.Begin);
                    var notes = new ImageFileDirectory(binaryReader);
                    // notes.DumpDirectory(binaryReader);

                    // Camera settings
                    var settings = notes.Entries.Single(e => e.TagId == 0x0001 && e.TagType == 3);
                    //Console.WriteLine("Camera Settings id: {0}, type: {1}, count {2}, value {3}", settings.TagId, settings.TagType, settings.NumberOfValue, settings.ValuePointer);
                    binaryReader.BaseStream.Seek(settings.ValuePointer, SeekOrigin.Begin);
                    var settingsData = new ushort[settings.NumberOfValue];
                    for (var i = 0; i < settings.NumberOfValue; i++)
                    {
                        settingsData[i] = binaryReader.ReadUInt16();
                    }
                    Assert.AreEqual(2, settingsData[1]); // MacroMode == Normal
                    Assert.AreEqual(4, settingsData[3]); // Qualtiy == RAW
                    Assert.AreEqual(0, settingsData[4]); // Flash == Off
                    Assert.AreEqual(6, settingsData[9]); // RecordMode == CR2

                    // focus info
                    //var focalLength = notes.Entries.Single(e => e.TagId == 0x0002 && e.TagType == 3);
                    //Console.WriteLine("Focal Length: {0}, type: {1}, count {2}, value {3}", focalLength.TagId, focalLength.TagType, focalLength.NumberOfValue, focalLength.ValuePointer);
                    //binaryReader.BaseStream.Seek(focalLength.ValuePointer, SeekOrigin.Begin);
                    //for (var i = 0; i < focalLength.NumberOfValue; i++)
                    //    var x = binaryReader.ReadUInt16();

                    // shot info
                    var shot = notes.Entries.Single(e => e.TagId == 0x0004 && e.TagType == 3);
                    binaryReader.BaseStream.Seek(shot.ValuePointer, SeekOrigin.Begin);
                    var shotData = new ushort[shot.NumberOfValue];
                    for (var i = 0; i < shot.NumberOfValue; i++)
                    {
                        shotData[i] = binaryReader.ReadUInt16();
                    }
                    Assert.AreEqual(0x0000, shotData[7]); //! Auto - White balance

                    // ProcessingInfo
                    var process = notes.Entries.Single(e => e.TagId == 0x00A0 && e.TagType == 3);
                    binaryReader.BaseStream.Seek(process.ValuePointer, SeekOrigin.Begin);
                    var processData = new ushort[process.NumberOfValue];
                    for (var i = 0; i < process.NumberOfValue; i++)
                    {
                        processData[i] = binaryReader.ReadUInt16();
                    }
                    Assert.AreEqual(0x0000, processData[6]); // White balance - Red
                    Assert.AreEqual(0x0000, processData[7]); // White balance - Blue
                    Assert.AreEqual(0xFFFF, processData[8]); // White balance
                    Assert.AreEqual(5200, processData[9]);   // Color Temp

                    // Mesaured Color Tags
                    //var colorTags = notes.Entries.Single(e => e.TagId == 0x00aa && e.TagType == 3);
                    //binaryReader.BaseStream.Seek(colorTags.ValuePointer, SeekOrigin.Begin);
                    //var colorTagsData = new ushort[colorTags.NumberOfValue];
                    //for (var i = 0; i < colorTags.NumberOfValue; i++)
                    //    colorTagsData[i] = binaryReader.ReadUInt16();

                    // Color Data
                    var colorBalance = notes.Entries.Single(e => e.TagId == 0x4001 && e.TagType == 3);
                    binaryReader.BaseStream.Seek(colorBalance.ValuePointer, SeekOrigin.Begin);
                    var colorBalanceTags = new ushort[colorBalance.NumberOfValue];
                    for (var i = 0; i < colorBalance.NumberOfValue; i++)
                    {
                        colorBalanceTags[i] = binaryReader.ReadUInt16();
                    }

                    // color data version
                    Assert.AreEqual(10, colorBalanceTags[0]);

                    // WB_RGGBLevelsAsShot
                    Assert.AreEqual(0x07F0, colorBalanceTags[63]);
                    Assert.AreEqual(0x0400, colorBalanceTags[64]);
                    Assert.AreEqual(0x0400, colorBalanceTags[65]);
                    Assert.AreEqual(0x06A6, colorBalanceTags[66]);

                    // ColorTempAsShot
                    Assert.AreEqual(4997, colorBalanceTags[67]);

                    // WB_RGGBLevelsAuto
                    Assert.AreEqual(0x07F0, colorBalanceTags[68]);
                    Assert.AreEqual(0x0400, colorBalanceTags[69]);
                    Assert.AreEqual(0x0400, colorBalanceTags[70]);
                    Assert.AreEqual(0x06A6, colorBalanceTags[71]);

                    // ColorTempAuto
                    Assert.AreEqual(4997, colorBalanceTags[72]);

                    // WB_RGGBLevelsMeasured
                    Assert.AreEqual(0x07F0, colorBalanceTags[73]);
                    Assert.AreEqual(0x0400, colorBalanceTags[74]);
                    Assert.AreEqual(0x0400, colorBalanceTags[75]);
                    Assert.AreEqual(0x06A6, colorBalanceTags[76]);

                    // ColorTempMeasured
                    Assert.AreEqual(4997, colorBalanceTags[77]);

                    // 213-275 color clib tags

                    // Average Black level
                    Assert.AreEqual(0x0800, colorBalanceTags[276]);
                    Assert.AreEqual(0x0800, colorBalanceTags[277]);
                    Assert.AreEqual(0x0800, colorBalanceTags[278]);
                    Assert.AreEqual(0x0800, colorBalanceTags[279]);

                    // Raw masured RGGB
                    Assert.AreEqual(0x000191A3, colorBalanceTags[429] << 16 | colorBalanceTags[430]);
                    Assert.AreEqual(0x00018143, colorBalanceTags[431] << 16 | colorBalanceTags[432]);
                    Assert.AreEqual(0x00017B99, colorBalanceTags[433] << 16 | colorBalanceTags[434]);
                    Assert.AreEqual(0x000090B6, colorBalanceTags[435] << 16 | colorBalanceTags[436]);

                    // var wb = new WhiteBalance(binaryReader, colorBalance);
                }
        }
Esempio n. 9
0
        private static void DumpGpsInfo(BinaryReader binaryReader, uint offset)
        {
            binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin);

            var tags = new ImageFileDirectory(binaryReader);

            Assert.AreEqual(0x00000302u, tags.Entries.Single(e => e.TagId == 0x0000 && e.TagType == 1).ValuePointer);    // version number
            // tags.DumpDirectory(binaryReader);

            if (tags.Entries.Length == 1)
            {
                Console.WriteLine("GPS info not found....");
                return;
            }

            Assert.AreEqual(31, tags.Entries.Length);
            var expected = new List <ushort>();

            for (ushort i = 0; i < 0x001F; i++)
            {
                expected.Add(i);
            }
            CollectionAssert.AreEqual(expected.ToArray(), tags.Entries.Select(e => e.TagId).ToArray());

            // "A" active, "V" void
            Console.WriteLine("Satellite signal status {0}", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0009 && e.TagType == 2)));

            var date     = RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x001D && e.TagType == 2));
            var timeData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0007 && e.TagType == 5));

            Assert.AreEqual(6, timeData.Length);
            var time1    = (double)timeData[0] / timeData[1];
            var time2    = (double)timeData[2] / timeData[3];
            var time3    = (double)timeData[4] / timeData[5];
            var dateTime = GpsData2.ConvertDateTime(date, time1, time2, time3);

            Console.WriteLine("Timestamp {0:M\'/\'d\'/\'yyyy\' \'h\':\'mm\':\'ss\' \'tt}", dateTime.ToLocalTime());

            var latitudeData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0002 && e.TagType == 5));

            Assert.AreEqual(6, latitudeData.Length);
            var latitude1         = (double)latitudeData[0] / latitudeData[1];
            var latitude2         = (double)latitudeData[2] / latitudeData[3];
            var latitude3         = (double)latitudeData[4] / latitudeData[5];
            var latitudeDirection = RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0001 && e.TagType == 2));

            Console.WriteLine("Latitude {0}° {1}\' {2}\" {3}", latitude1, latitude2, latitude3, latitudeDirection);

            var longitudeData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0004 && e.TagType == 5));

            Assert.AreEqual(6, longitudeData.Length);
            var longitude1         = (double)longitudeData[0] / longitudeData[1];
            var longitude2         = (double)longitudeData[2] / longitudeData[3];
            var longitude3         = (double)longitudeData[4] / longitudeData[5];
            var longitudeDirection = RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0003 && e.TagType == 2));

            Console.WriteLine("Longitude {0}° {1}\' {2}\" {3}", longitude1, longitude2, longitude3, longitudeDirection);

            var altitudeData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0006 && e.TagType == 5));

            Assert.AreEqual(2, altitudeData.Length);
            var altitude = (double)altitudeData[0] / altitudeData[1];

            Console.WriteLine("Altitude {0:0.00} m", altitude);
            Assert.AreEqual(0x00000000u, tags.Entries.Single(e => e.TagId == 0x0005 && e.TagType == 1).ValuePointer);

            Console.WriteLine("Geographic coordinate system {0}", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0012 && e.TagType == 2)));

            Assert.AreEqual("M", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0010 && e.TagType == 2)));     // Magnetic Direction
            var directionData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0011 && e.TagType == 5));

            Assert.AreEqual(2, directionData.Length);
            var direction = (double)directionData[0] / directionData[1];

            Console.WriteLine("Direction {0}°", direction);

            var dopData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x000B && e.TagType == 5));

            Assert.AreEqual(2, dopData.Length);
            var dop = (double)dopData[0] / dopData[1];

            Console.WriteLine("Dilution of Position {0}", dop);

            var quality = RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x000A && e.TagType == 2));

            Console.WriteLine("Fix quality = {0}", GpsData2.DumpFixQuality(quality));
            Console.WriteLine("Number of satellites = {0}", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0008 && e.TagType == 2)));

            // Speed
            Assert.AreEqual("", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x000C && e.TagType == 2)));
            var data0D = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x000D && e.TagType == 5));

            CollectionAssert.AreEqual(new uint[] { 0, 1 }, data0D);

            // Track
            Assert.AreEqual("", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x000E && e.TagType == 2)));
            var data0F = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x000F && e.TagType == 5));

            CollectionAssert.AreEqual(new uint[] { 0, 1 }, data0F);

            // Destination
            Assert.AreEqual("", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0013 && e.TagType == 2)));
            var data14 = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0014 && e.TagType == 5));

            CollectionAssert.AreEqual(new uint[] { 0, 1, 0, 1, 0, 1 }, data14);
            Assert.AreEqual("", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0015 && e.TagType == 2)));
            var data16 = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0016 && e.TagType == 5));

            CollectionAssert.AreEqual(new uint[] { 0, 1, 0, 1, 0, 1 }, data16);
            Assert.AreEqual("", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0017 && e.TagType == 2)));
            var data18 = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0018 && e.TagType == 5));

            CollectionAssert.AreEqual(new uint[] { 0, 1 }, data18);
            Assert.AreEqual("", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0019 && e.TagType == 2)));
            var data1A = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x001A && e.TagType == 5));

            CollectionAssert.AreEqual(new uint[] { 0, 1 }, data1A);

            // Processing Method
            var data1B = RawImage.ReadBytes(binaryReader, tags.Entries.Single(e => e.TagId == 0x001B && e.TagType == 7));

            Assert.AreEqual(256, data1B.Length);
            foreach (var b in data1B)
            {
                Assert.AreEqual(0x00, b);
            }

            // Area Information
            var data1C = RawImage.ReadBytes(binaryReader, tags.Entries.Single(e => e.TagId == 0x001C && e.TagType == 7));

            Assert.AreEqual(256, data1C.Length);
            foreach (var b in data1C)
            {
                Assert.AreEqual(0x00, b);
            }

            // Differential
            Assert.AreEqual(0x0000u, tags.Entries.Single(e => e.TagId == 0x001E && e.TagType == 3).ValuePointer);

            // Model GP-E2
            // firmware 2.0.0
            // serial number 3410400095
        }
Esempio n. 10
0
        public void DumpExifData1()
        {
            const string fileName = @"C:..\..\Photos\5DIIIhigh.CR2";

            using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);
                    var image    = rawImage.Directories.First();

                    var imageFileEntry = image.Entries.Single(e => e.TagId == 0x8769 && e.TagType == 4);
                    binaryReader.BaseStream.Seek(imageFileEntry.ValuePointer, SeekOrigin.Begin);
                    var exif = new ImageFileDirectory(binaryReader);
                    exif.DumpDirectory(binaryReader);

                    Assert.AreEqual(38, exif.Entries.Length);

                    var exposure = exif.Entries.Single(e => e.TagId == 0x829A && e.TagType == 5);
                    var fStop    = exif.Entries.Single(e => e.TagId == 0x829D && e.TagType == 5);
                    var iso      = exif.Entries.Single(e => e.TagId == 0x8827 && e.TagType == 3);

                    // 0)  0x829A URational 2x32-bit: [0x0000038C] (1): 30/1 = 30   // exposure time
                    // 1)  0x829D URational 2x32-bit: [0x00000394] (1): 32/10 = 3.2 // f number
                    // 2)  0x8822 UShort 16-bit: 3                                  // Exposure program
                    // 3)  0x8827 UShort 16-bit: 100                                // ISO speed 100
                    // 4)  0x8830 UShort 16-bit: 2
                    // 5)  0x8832 ULong 32-bit: 100
                    // 6)  0x9000 UByte[]: 48, 50, 51, 48                           // Exif version 2.30
                    // 7)  0x9003 Ascii 8-bit, null terminated: [0x0000039C] (20): "2014:03:31 06:17:21"    // date time, original
                    // 8)  0x9004 Ascii 8-bit, null terminated: [0x000003B0] (20): "2014:03:31 06:17:21"    // date time, digitized
                    // 9)  0x9101 UByte[]: 1, 2, 3, 0                                           // Componets configuration YCbCr
                    //10)  0x9201 SRational 2x32-bit: [0x000003C4] (1): -327680/65536 = -5      // Shutter speed (32.00s)
                    //11)  0x9202 URational 2x32-bit: [0x000003CC] (1): 221184/65536 = 3.375    // Aperture value (F3.2)
                    //12)  0x9204 SRational 2x32-bit: [0x000003D4] (1): 0/1 = 0                 // exposure bios
                    //13)  0x9207 UShort 16-bit: 3                                              // metering mode (spot)
                    //14)  0x9209 UShort 16-bit: 16                                             // flash (not fired)
                    //15)  0x920A URational 2x32-bit: [0x000003DC] (1): 32/1 = 32               // focal length
                    //16)  0x927C Maker note: [0x000003E4] (68540):
                    //17)  0x9286 UByte[]: [0x00010FA0] (264):                                  // user comment
                    //18)  0x9290 Ascii 8-bit, null terminated: [0x00003030] (3): "00"          // subsecond time
                    //19)  0x9291 Ascii 8-bit, null terminated: [0x00003030] (3): "00"          // subsecond time original
                    //20)  0x9292 Ascii 8-bit, null terminated: [0x00003030] (3): "00"          // subsecond time digitized
                    //21)  0xA000 UByte[]: 48, 49, 48, 48                                       // Flash Pix Version 0100
                    //22)  0xA001 UShort 16-bit: 1                                              // colorspace sRGB
                    //23)  0xA002 UShort 16-bit: 5760                                           // width
                    //24)  0xA003 UShort 16-bit: 3840                                           // height
                    //25)  0xA005 ULong 32-bit: 69800                                           // interoperability offset
                    //26)  0xA20E URational 2x32-bit: [0x000110C6] (1): 5760000/1461 = 3942.50513347023     // focal plane X resolution
                    //27)  0xA20F URational 2x32-bit: [0x000110CE] (1): 3840000/972 = 3950.61728395062      // focal plane Y resolution
                    //28)  0xA210 UShort 16-bit: 2                                                          // resolution units inches
                    //29)  0xA401 UShort 16-bit: 0
                    //30)  0xA402 UShort 16-bit: 0
                    //31)  0xA403 UShort 16 - bit: 0
                    //32)  0xA406 UShort 16 - bit: 0
                    //33)  0xA430 Ascii 8 - bit, null terminated: [0x000110D6](11): "Greg Eakin"            // author
                    //34)  0xA431 Ascii 8 - bit, null terminated: [0x000110F6](13): "032033000212"          // Camera serial number
                    //35)  0xA432 URational 2x32 - bit: [0x00011116] (4): 24/1 = 24                         // focal length
                    //36)  0xA434 Ascii 8-bit, null terminated: [0x00011136] (21): "EF24-70mm f/2.8L USM"   // lens
                    //37)  0xA435 Ascii 8-bit, null terminated: [0x00011180] (11): "0000000000"

                    var notesEntry = exif[0x927c];
                    // Assert.AreEqual(68540u, notesEntry.NumberOfValue);
                    // Assert.AreEqual(0x000001BEu, imageFileEntry.ValuePointer);

                    var interopEntry = exif.Entries.Single(e => e.TagId == 0xA005 && e.TagType == 4);
                    binaryReader.BaseStream.Seek(interopEntry.ValuePointer, SeekOrigin.Begin);
                    var interop = new ImageFileDirectory(binaryReader);
                    CollectionAssert.AreEqual(new ushort[] { 0x0001, 0x0002, }, interop.Entries.Select(e => e.TagId).ToArray());
                    // interop.DumpDirectory(binaryReader);

                    var tag01 = interop.Entries.Single(e => e.TagId == 0x0001 && e.TagType == 2);
                    var index = RawImage.ReadChars(binaryReader, tag01);
                    Assert.AreEqual("R98", index);

                    var tag02   = interop.Entries.Single(e => e.TagId == 0x0002 && e.TagType == 7);
                    var version = RawImage.ReadChars(binaryReader, tag02);
                    Assert.AreEqual("0100", version);
                }
        }
Esempio n. 11
0
        public void DumpKeyInformation()
        {
            const string fileName = @"C:..\..\Photos\5DIIIhigh.CR2";

            using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);

                    //From IFD#0:
                    var image = rawImage.Directories.First();

                    //Camera make is taken from tag #271 (0x10f)
                    var make = RawImage.ReadChars(binaryReader, image[0x010F]);
                    Assert.AreEqual("Canon", make);

                    //Camera model is from tag #272 (0x110)
                    var model = RawImage.ReadChars(binaryReader, image[0x0110]);
                    Assert.AreEqual("Canon EOS 5D Mark III", model);

                    var exifEntry = image[0x8769];
                    binaryReader.BaseStream.Seek(exifEntry.ValuePointer, SeekOrigin.Begin);
                    var exif = new ImageFileDirectory(binaryReader);

                    var notesEntry = exif[0x927c];
                    binaryReader.BaseStream.Seek(notesEntry.ValuePointer, SeekOrigin.Begin);
                    var notes = new ImageFileDirectory(binaryReader);

                    //model ID from Makernotes, Tag #0x10
                    var modelId = notes[0x0010];
                    Assert.AreEqual(0x80000285, modelId.ValuePointer);

                    //white balance information is taken from tag #0x4001
                    var white = notes[0x4001];

                    //From IFD#3:
                    image = rawImage.Directories.Skip(3).First();

                    //StripOffset, offset to RAW data : tag #0x111
                    var offset = image[0x0111].ValuePointer;

                    //StripByteCount, length of RAW data: tag #0x117
                    var count = image[0x0117].ValuePointer;

                    //image slice layout (cr2_slice[]) : tag #0xc640
                    var imageFileEntry = image[0xC640];
                    Assert.AreEqual(3u, imageFileEntry.NumberOfValue);
                    var slices = RawImage.ReadUInts16(binaryReader, imageFileEntry);
                    CollectionAssert.AreEqual(new ushort[] { 1, 2960, 2960 }, slices);

                    //the RAW image dimensions is taken from lossless jpeg (0xffc3 section)
                    binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin);
                    var startOfImage = new StartOfImage(binaryReader, offset, count);

                    var startOfFrame = startOfImage.StartOfFrame;
                    Assert.AreEqual(3950u, startOfFrame.ScanLines);      // = 3840 + 110
                    Assert.AreEqual(2960u, startOfFrame.SamplesPerLine); // = 5920 / 2
                    Assert.AreEqual(2, startOfFrame.Components.Length);
                    Assert.AreEqual(5920, startOfFrame.Width);           // = 5760 + 160
                }
        }
Esempio n. 12
0
        public void DumpMakerNotes1()
        {
            const string fileName = @"C:..\..\Photos\5DIIIhigh.CR2";

            using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    var rawImage = new RawImage(binaryReader);
                    var image    = rawImage.Directories.First();

                    var exifEntry = image.Entries.Single(e => e.TagId == 0x8769 && e.TagType == 4);
                    binaryReader.BaseStream.Seek(exifEntry.ValuePointer, SeekOrigin.Begin);
                    var exif = new ImageFileDirectory(binaryReader);

                    var notesEntry = exif.Entries.Single(e => e.TagId == 0x927C && e.TagType == 7);
                    binaryReader.BaseStream.Seek(notesEntry.ValuePointer, SeekOrigin.Begin);
                    var notes = new ImageFileDirectory(binaryReader);
                    Assert.AreEqual(42, notes.Entries.Length);

                    notes.DumpDirectory(binaryReader);

                    // camera settings notes[0x0001]
                    // focus info notes[0x0002]
                    // image type notes[0x0006]
                    // dust delete notes[0x0097]
                    // color balance notes[0x4001]
                    // AF Micro adjust notes[0x4013]
                    // Vignetting correction notes[0x40015]

                    var model = RawImage.ReadChars(binaryReader, notes[0x0006]);
                    Assert.AreEqual("Canon EOS 5D Mark III", model);

                    var firmware = RawImage.ReadChars(binaryReader, notes[0x0007]);
                    Assert.AreEqual("Firmware Version 1.2.3\0", firmware);

                    // 0x0010 ULong 32 - bit: 2147484293
                    var id = notes.Entries.Single(e => e.TagId == 0x0010 && e.TagType == 4);
                    Assert.AreEqual(0x80000285, id.ValuePointer);

                    // 0)  0x0001 UShort 16-bit: [0x000005E2] (49): 98, 2, 0, 4, 0, 0, 0, 3, 0, 6, 65535, 1, 0, 0, 0, 32767, 32767, 1, 2, 0, 3, 65535, 230, 70, 24, 1, 96, 288, 0, 0, 0, 0, 65535, 65535, 65535, 0, 0, 0, 0, 65535, 65535, 0, 0, 32767, 65535, 65535, 0, 0, 65535,
                    //              00: length, bytes
                    //              01: Macro mode, 2 == Normal
                    //              03: RAW
                    //              05: drive single
                    //              07: Focus one shot
                    //              09: Record mode, 6 == CR2
                    //              0a: image size, -1 == N/A
                    //              0b: Program manual
                    //              10: ISO 16383
                    //              17: Lens 24-70
                    // 1)  0x0002 UShort 16-bit: [0x00000644] (4): 0, 32, 53893, 12236,
                    // 2)  0x0003 UShort 16-bit: [0x0000064C] (4): 0, 0, 0, 0,
                    // 3)  0x0004 UShort 16-bit: [0x00000654] (34): 68, 0, 160, 65324, 108, 65376, 0, 0, 3, 0, 8, 8, 148, 0, 0, 0, 0, 0, 1, 0, 0, 108, 65376, 45, 0, 0, 248, 65535, 65535, 65535, 65535, 0, 0, 0,
                    //              07: white balance auto
                    //              09: Sequence number
                    //              0f: flash bias
                    // 4)  0x0006 Ascii 8-bit, null terminated: [0x00000698] (22): "Canon EOS 5D Mark III"
                    // 5)  0x0007 Ascii 8-bit, null terminated: [0x000006B8] (24): "Firmware Version 1.2.3"
                    // 6)  0x0009 Ascii 8-bit, null terminated: [0x000006D0] (32): "Greg Eakin"
                    // 7)  0x000D UByte[]: [0x000006F0] (1536):                     // camera info
                    // 8)  0x0010 ULong 32-bit: 2147484293                          // camera id
                    // 9)  0x0013 UShort 16-bit: [0x00000CF0] (4): 0, 159, 7, 112,  // thumbnail image valid area
                    //10)  0x0019 UShort 16-bit: 1
                    //11)  0x0026 UShort 16-bit: [0x00000CF8] (265): 530, 0, 61, 61, 5760, 3840, 5760, 3840, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 288, 0, 65248, 1520, 1232, 944, 639, 288, 0, 64016, 64304, 64592, 64897, 65248, 1520, 1232, 944, 639, 288, 0, 64016, 64304, 64592, 64897, 65248, 1520, 1232, 944, 639, 288, 0, 64016, 64304, 64592, 64897, 65248, 1520, 1232, 944, 639, 288, 0, 64016, 64304, 64592, 64897, 65248, 1520, 1232, 944, 639, 288, 0, 64016, 64304, 64592, 64897, 65248, 288, 0, 65248, 64888, 64888, 64888, 65103, 65103, 65103, 65103, 65103, 65103, 65103, 65103, 65103, 65103, 65103, 65321, 65321, 65321, 65321, 65321, 65321, 65321, 65321, 65321, 65321, 65321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, 648, 648, 648, 0, 0, 0, 0, 0, 0, 16384, 0, 0, 0, 0, 0, 65535,
                    //12)  0x0035 ULong 32-bit: [0x00000F0A] (4): 0010 FFFFFE5C 001E 003C    // time info
                    //13)  0x0093 UShort 16-bit: [0x00000F1A] (30): 60, 0, 0, 0, 0, 0, 0, 0, 65535, 0, 0, 0, 0, 0, 65535, 65535, 90, 65535, 0, 0, 1191, 781, 0, 0, 0, 0, 65535, 0, 0, 0,
                    //14)  0x0095 Ascii 8-bit, null terminated: [0x00000F56] (74): "EF24-70mm f/2.8L USM"
                    //15)  0x0096 Ascii 8-bit, null terminated: [0x00000FA0] (16): "AD0144782"
                    //16)  0x0097 UByte[]: [0x00000FB0] (1024):                     // dust removal info
                    //17)  0x0098 UShort 16-bit: [0x000013B0] (4): 0, 0, 0, 0,      // crop info
                    //18)  0x0099 ULong 32-bit: [0x000013B8] (83): 014C 0003 0001 0054 0006 0101 0001 0000 0102 0001 0001 0104 0001 0000 0105 0001 0000 0106 0002 0003 0000 0108 0001 0000 0002 0020 0002 040A 0001 0007 040B 0001 0001 0004 00C4 0005 070C 0020 0000 0000 0000 0000 0001 0000 0001 0003 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0007 0003 0706 0001 0000 070F 0002 0000 0002 080E 0001 0000 0813 0001 0000
                    //19)  0x009A ULong 32-bit: [0x00001504] (5): 0000 1680 0F00 0000 0000  // aspect info
                    //20)  0x00A0 UShort 16-bit: [0x00001518] (14): 28, 0, 0, 0, 0, 0, 0, 0, 65535, 5200, 133, 0, 0, 0,     //processing info
                    //21)  0x00AA UShort 16-bit: [0x00001534] (6): 12, 1057, 1024, 1024, 386, 0,            // measured color
                    //22)  0x00B4 UShort 16-bit: 1                                  // color space, 1 == sRGB
                    //23)  0x00D0 ULong 32-bit: 0                                   // VRD recipe
                    //24)  0x00E0 UShort 16-bit: [0x00001540] (17): 34, 5920, 3950, 1, 1, 140, 96, 5899, 3935, 0, 0, 0, 0, 0, 0, 0, 0,      // sensor info
                    //25)  0x4001 UShort 16-bit: [0x00001562] (1312): 10, 819, 1024, 1024, 350, 570, 1024, 1024, 479, 398, 1024, 1024, 671, 1459, 1787, 1787, 609, 1557, 2724, 2725, 1263, 739, 1838, 1837, 1192, 3, 0, 263, 262, 265, 0, 1439, 3054, 3051, 1706, 665, 208, 207, 30, 75, 588, 589, 1011, 1365, 2358, 2358, 441, 1255, 2540, 2539, 1379, 577, 185, 185, 26, 67, 478, 478, 803, 1191, 1965, 1966, 367, 2032, 1024, 1024, 1702, 4997, 2032, 1024, 1024, 1702, 4997, 2032, 1024, 1024, 1702, 4997, 2032, 1024, 1024, 1702, 4997, 1024, 1024, 1024, 1024, 4378, 1024, 1024, 1024, 1024, 4378, 2032, 1024, 1024, 1702, 4997, 2032, 1024, 1024, 1702, 4997, 2032, 1024, 1024, 1702, 4997, 2032, 1024, 1024, 1702, 4997, 2032, 1024, 1024, 1702, 4997, 1370, 1028, 1018, 1952, 3415, 777, 1170, 1170, 529, 3415, 2076, 1024, 1024, 1657, 5200, 2383, 1024, 1024, 1411, 7000, 2231, 1024, 1024, 1524, 6000, 1494, 1024, 1024, 2473, 3200, 1824, 1024, 1024, 2378, 3714, 2076, 1024, 1024, 1657, 5189, 2315, 1024, 1024, 1500, 6320, 2068, 1024, 1024, 1446, 5940, 2076, 1024, 1024, 1657, 5189, 2076, 1024, 1024, 1657, 5189, 2076, 1024, 1024, 1657, 5189, 2076, 1024, 1024, 1657, 5189, 1010, 1024, 1024, 1022, 4325, 1010, 1024, 1024, 1022, 4325, 1010, 1024, 1024, 1022, 4325, 1010, 1024, 1024, 1022, 4325, 1010, 1024, 1024, 1022, 4325, 65228, 383, 881, 10900, 65246, 391, 858, 10000, 65292, 413, 800, 8300, 65343, 440, 743, 7000, 65396, 470, 688, 6000, 65423, 486, 662, 5600, 65453, 505, 633, 5200, 65500, 531, 586, 4700, 20, 570, 539, 4200, 74, 612, 498, 3800, 123, 652, 463, 3500, 180, 702, 424, 3200, 226, 741, 390, 3000, 267, 790, 371, 2800, 372, 920, 322, 2400, 500, 2065, 2081, 2048, 2048, 2048, 2048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 409, 494, 708, 3748, 1676, 1764, 1587, 932, 5697, 4163, 4172, 2546, 1182, 935, 2342, 200, 64, 17, 18, 669, 49, 20, 37, 10, 399, 469, 1094, 1564, 593, 474, 2860, 597, 0, 1, 2, 8, 1, 2, 4, 0, 8, 6, 8, 4, 6, 1, 40, 31, 5, 7, 11, 46, 8, 7, 11, 3, 14, 8, 15, 16, 9, 5, 114, 47, 0, 0, 0, 32768, 0, 1024, 1024, 1024, 2639, 3807, 6471, 4116, 65511, 51, 4099, 4076, 24, 65485, 4093, 0, 256, 1, 37283, 1, 33091, 1, 31641, 0, 37046, 1024, 1024, 1024, 0, 0, 0, 65533, 0, 8191, 256, 0, 0, 1024, 686, 427, 491, 638, 406, 792, 0, 0, 0, 0, 0, 15, 240, 256, 256, 256, 256, 256, 256, 0, 15, 240, 256, 256, 256, 256, 256, 256, 0, 0, 131, 0, 16, 32, 64, 96, 128, 192, 0, 0, 0, 0, 0, 0, 0, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1160, 0, 2048, 2048, 2048, 2048, 14708, 15220, 10087, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 240, 256, 256, 256, 256, 256, 256, 0, 15, 240, 256, 256, 256, 256, 256, 256, 125, 125, 126, 1, 1, 244, 244, 8, 24, 60, 92, 111, 130, 166, 218, 235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 81, 98, 118, 133, 216, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1391, 1024, 859, 0, 0, 0, 0, 75, 80, 32344, 525, 0, 0, 0, 0, 782, 225, 0, 575, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 1024, 1024, 617, 100, 0, 79, 79, 32331, 598, 0, 0, 0, 0, 100, 44, 72, 16, 33, 230, 255, 21305, 2068, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 63, 95, 127, 159, 191, 223, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 1, 244, 0, 0, 0, 0, 0, 0, 0, 31, 63, 95, 127, 159, 191, 223, 255, 48, 51, 55, 56, 54, 49, 46, 48, 54, 60, 68, 74, 82, 87, 90, 92, 94, 94, 91, 89, 86, 85, 88, 92, 94, 93, 94, 99, 104, 112, 113, 112, 111, 113, 118, 121, 124, 129, 132, 144, 154, 164, 189, 217, 240, 238, 235, 226, 212, 197, 168, 138, 97, 73, 64, 53, 47, 45, 46, 48, 47, 90, 85, 0, 255, 4, 44, 72, 21305, 2068, 0, 0, 0, 0, 0, 230, 255, 33, 823, 191, 0, 510, 136, 0, 352, 0, 0, 16, 0, 0, 0, 0, 0, 0, 65535, 0, 65535, 65535, 65535, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100, 0, 100, 100, 0, 40, 0, 0, 0, 0, 0, 44, 72, 21305, 2068, 0, 0, 0, 0, 0, 230, 255, 33, 32331, 598, 0, 0, 0, 0, 21305, 2068, 4, 44, 0, 0, 0, 0, 0, 0, 0, 0, 31, 63, 95, 127, 159, 191, 223, 255, 0, 0, 516, 1024, 1024, 617,
                    //26)  0x4002 UByte[]: [0x00001FA2] (43572):
                    //27)  0x4005 UByte[]: [0x0000C9D6] (16792):
                    //28)  0x4008 UShort 16-bit: [0x00010B6E] (3): 129, 129, 129,       // black level
                    //29)  0x4009 UShort 16-bit: [0x00010B74] (3): 0, 0, 0,
                    //30)  0x4010 Ascii 8-bit, null terminated: [0x00010B7A] (32): ""
                    //31)  0x4011 UByte[]: [0x00010B9A] (252):
                    //32)  0x4012 Ascii 8-bit, null terminated: [0x00010C96] (32): ""
                    //33)  0x4013 ULong 32-bit: [0x00010CB6] (11): 002C 0000 0000 000A FFFFFFFF 0000 000A 0000 000A 0000 000A       // AF micro adjust
                    //34)  0x4015 UByte[]: [0x00010CE2] (456):                          // Vignetting Correction
                    //35)  0x4016 ULong 32-bit: [0x00010EAA] (7): 001C 0000 0001 0000 0000 0001 0001    // Vignetting Correction 2
                    //36)  0x4018 ULong 32-bit: [0x00010EC6] (7): 001C 0000 0003 0000 0000 0003 0001    // Lighting Option
                    //37)  0x4019 UByte[]: [0x00010EE2] (30):                                           // Lens info
                    //38)  0x4021 ULong 32-bit: [0x00010F00] (5): 0014 0000 0000 0000 0001              // multi exposure
                    //39)  0x4025 ULong 32-bit: [0x00010F14] (9): 0024 0000 0000 0000 0000 0000 0000 0000 0000      // HDR info
                    //40)  0x4027 ULong 32-bit: [0x00010F38] (5): 0014 90001 A6A30034 73C0600 D0D0D0
                    //41)  0x4028 ULong 32-bit: [0x00010F4C] (19): 004C 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 003F 0000 0001 0001 0002 0000 0000   // AF Coding

                    // Color Balance
                    //var data1B = RawImage.ReadBytes(binaryReader, notes.Entries.Single(e => e.TagId == 0x4001 && e.TagType == 3));

                    // Vignetting Correction
                    //var data1B = RawImage.ReadBytes(binaryReader, notes.Entries.Single(e => e.TagId == 0x4015 && e.TagType == 7));

                    // CRW Parm
                    var data01 = RawImage.ReadBytes(binaryReader, notes.Entries.Single(e => e.TagId == 0x4002 && e.TagType == 7));

                    // Flavor
                    var data02 = RawImage.ReadBytes(binaryReader, notes.Entries.Single(e => e.TagId == 0x4005 && e.TagType == 7));

                    var data03 = RawImage.ReadBytes(binaryReader, notes.Entries.Single(e => e.TagId == 0x4011 && e.TagType == 7));

                    // Vignetting Correction
                    var data04 = RawImage.ReadBytes(binaryReader, notes.Entries.Single(e => e.TagId == 0x4015 && e.TagType == 7));

                    // Lens info
                    var data05 = RawImage.ReadBytes(binaryReader, notes.Entries.Single(e => e.TagId == 0x4019 && e.TagType == 7));
                }
        }
Esempio n. 13
0
        private static void DumpGpsInfo(BinaryReader binaryReader, uint offset)
        {
            binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin);

            var tags = new ImageFileDirectory(binaryReader);

            Assert.AreEqual(0x00000302u, tags.Entries.Single(e => e.TagId == 0x0000 && e.TagType == 1).ValuePointer);    // version number
            // tags.DumpDirectory(binaryReader);

            if (tags.Entries.Length == 1)
            {
                Console.WriteLine("GPS info not found....");
                return;
            }

            Assert.AreEqual(16, tags.Entries.Length);
            var expected = new[]
            {
                (ushort)0x00, (ushort)0x01, (ushort)0x02, (ushort)0x03,
                (ushort)0x04, (ushort)0x05, (ushort)0x06, (ushort)0x07,
                (ushort)0x08, (ushort)0x09, (ushort)0x0A, (ushort)0x0B,
                (ushort)0x10, (ushort)0x11, (ushort)0x12, (ushort)0x1D
            };

            CollectionAssert.AreEqual(expected.ToArray(), tags.Entries.Select(e => e.TagId).ToArray());

            // "A" active, "V" void
            Console.WriteLine("Satellite signal status {0}", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0009 && e.TagType == 2)));

            var date     = RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x001D && e.TagType == 2));
            var timeData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0007 && e.TagType == 5));

            Assert.AreEqual(6, timeData.Length);
            var time1    = (double)timeData[0] / timeData[1];
            var time2    = (double)timeData[2] / timeData[3];
            var time3    = (double)timeData[4] / timeData[5];
            var dateTime = ConvertDateTime(date, time1, time2, time3);

            Console.WriteLine("Timestamp {0:M\'/\'d\'/\'yyyy\' \'h\':\'mm\':\'ss\' \'tt}", dateTime.ToLocalTime());

            var latitudeData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0002 && e.TagType == 5));

            Assert.AreEqual(6, latitudeData.Length);
            var latitude1         = (double)latitudeData[0] / latitudeData[1];
            var latitude2         = (double)latitudeData[2] / latitudeData[3];
            var latitude3         = (double)latitudeData[4] / latitudeData[5];
            var latitudeDirection = RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0001 && e.TagType == 2));

            Console.WriteLine("Latitude {0}° {1}\' {2}\" {3}", latitude1, latitude2, latitude3, latitudeDirection);

            var longitudeData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0004 && e.TagType == 5));

            Assert.AreEqual(6, longitudeData.Length);
            var longitude1         = (double)longitudeData[0] / longitudeData[1];
            var longitude2         = (double)longitudeData[2] / longitudeData[3];
            var longitude3         = (double)longitudeData[4] / longitudeData[5];
            var longitudeDirection = RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0003 && e.TagType == 2));

            Console.WriteLine("Longitude {0}° {1}\' {2}\" {3}", longitude1, longitude2, longitude3, longitudeDirection);

            var altitudeData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0006 && e.TagType == 5));

            Assert.AreEqual(2, altitudeData.Length);
            var altitude = (double)altitudeData[0] / altitudeData[1];

            Console.WriteLine("Altitude {0:0.00} m", altitude);
            Assert.AreEqual(0x00000000u, tags.Entries.Single(e => e.TagId == 0x0005 && e.TagType == 1).ValuePointer);

            Console.WriteLine("Geographic coordinate system {0}", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0012 && e.TagType == 2)));

            Assert.AreEqual("M", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0010 && e.TagType == 2)));     // Magnetic Direction
            var directionData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x0011 && e.TagType == 5));

            Assert.AreEqual(2, directionData.Length);
            var direction = (double)directionData[0] / directionData[1];

            Console.WriteLine("Direction {0}°", direction);

            var dopData = RawImage.ReadRational(binaryReader, tags.Entries.Single(e => e.TagId == 0x000B && e.TagType == 5));

            Assert.AreEqual(2, dopData.Length);
            var dop = (double)dopData[0] / dopData[1];

            Console.WriteLine("Dilution of Position {0}", dop);

            var quality = RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x000A && e.TagType == 2));

            Console.WriteLine("Fix quality = {0}", DumpFixQuality(quality));
            Console.WriteLine("Number of satellites = {0}", RawImage.ReadChars(binaryReader, tags.Entries.Single(e => e.TagId == 0x0008 && e.TagType == 2)));
        }