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); } }
public void DumpSensorInfo3() { 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.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); // Sensor Info var data = RawImage.ReadUInts16(binaryReader, notes.Entries.Single(e => e.TagId == 0x00E0 && e.TagType == 3)); Assert.AreEqual(2 * data.Length, data[0]); var imageWidth = (int)image.Entries.Single(e => e.TagId == 0x0100 && e.TagType == 3).ValuePointer; Assert.AreEqual(imageWidth, data[7] - data[5] + data[3]); var imageLength = (int)image.Entries.Single(e => e.TagId == 0x0101 && e.TagType == 3).ValuePointer; Assert.AreEqual(imageLength, data[8] - data[6] + data[4]); } }
/// <summary> /// Initializes a new instance of the <see cref="JPEGFile" /> class from the /// specified data stream. /// </summary> /// <param name="stream">A <see cref="Sytem.IO.Stream" /> that contains image data.</param> /// <param name="encoding">The encoding to be used for text metadata when the source encoding is unknown.</param> protected internal TIFFFile(Stream stream, Encoding encoding) { Format = ImageFileFormat.TIFF; IFDs = new List <ImageFileDirectory>(); Encoding = encoding; // Read the entire stream var data = Utility.GetStreamBytes(stream); // Read the TIFF header TIFFHeader = TIFFHeader.FromBytes(data, 0); var nextIFDOffset = TIFFHeader.IFDOffset; if (nextIFDOffset == 0) { throw new NotValidTIFFileException("The first IFD offset is zero."); } // Read IFDs in order while (nextIFDOffset != 0) { var ifd = ImageFileDirectory.FromBytes(data, nextIFDOffset, TIFFHeader.ByteOrder); nextIFDOffset = ifd.NextIFDOffset; IFDs.Add(ifd); } // Process IFDs // TODO: Add support for multiple frames foreach (ImageFileDirectoryEntry field in IFDs[0].Fields) { Properties.Add(ExifPropertyFactory.Get(field.Tag, field.Type, field.Count, field.Data, BitConverterEx.SystemByteOrder, IFD.Zeroth, Encoding)); } }
private float[] ConvertRowToFloat(ImageFileDirectory ifd, byte[] row) { int width = (int)ifd.ImageWidth; if (ifd.SamplesPerPixel == 1) { if (ifd.BitsPerSample == 32) { if (ifd.SampleFormat == 3) { var output = new float[width]; if (_reader.StreamIsLittleEndian != BitConverter.IsLittleEndian) { int w4 = 4 * width; for (int i = 0; i < w4; i += 4) { byte b = row[i]; row[i] = row[i + 3]; row[i + 3] = b; b = row[i + 1]; row[i + 1] = row[i + 2]; row[i + 2] = b; } } Buffer.BlockCopy(row, 0, output, 0, width + width); return(output); } } } return(null); }
public void CanonDustDeleteData() { 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 exif = ifid0[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); // notes.DumpDirectory(binaryReader); var data = notes[0x0097]; binaryReader.BaseStream.Seek(data.ValuePointer, SeekOrigin.Begin); for (var i = 0; i < data.NumberOfValue; i++) { var x = binaryReader.ReadUInt16(); Console.WriteLine("{0} : {1}", i, x); } } }
public ImageFileDirectory WriteImageFile <T>(IBitmap <T> bitmap) { var ifd = new ImageFileDirectory(); WriteImageFile <T>(ifd, bitmap); return(ifd); }
public void DumpCameraSettings() { 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); // 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, var data = RawImage.ReadUInts16(binaryReader, notes.Entries.Single(e => e.TagId == 0x0001 && e.TagType == 3)); Assert.AreEqual(2 * data.Length, data[0]); Assert.AreEqual(2, data[1]); // 01: Macro mode, 2 == Normal Assert.AreEqual(4, data[3]); // 03: quality, 4 == RAW Assert.AreEqual(0, data[5]); // 05: drive single Assert.AreEqual(3, data[7]); // 07: Focus one shot Assert.AreEqual(6, data[9]); // 09: Record mode, 6 == CR2 Assert.AreEqual(65535, data[10]); // 0a: image size, -1 == N/A Assert.AreEqual(1, data[11]); // 0b: Program manual Assert.AreEqual(32767, data[16]); // 10: ISO 16383 Assert.AreEqual(70, data[23]); // 17: Lens 24-70 } }
private short[] ConvertRowToInt16(ImageFileDirectory ifd, byte[] row) { int width = (int)ifd.ImageWidth; if (ifd.SamplesPerPixel == 1) { if (ifd.BitsPerSample == 16) { if (ifd.SampleFormat == 1 || ifd.SampleFormat == 2) { var output = new short[width]; if (_reader.StreamIsLittleEndian != BitConverter.IsLittleEndian) { int w2 = width + width; for (int i = 0; i < w2; i += 2) { byte b = row[i]; row[i] = row[i + 1]; row[i + 1] = b; } } Buffer.BlockCopy(row, 0, output, 0, width + width); return(output); } } } return(null); }
private void ReadIfds(IIoStream stream, uint ifdOffset) { var ptr = ifdOffset; while (ptr > 0 && ptr < stream.Length) { try { var ifd = new ImageFileDirectory(ptr); var buffer = new byte[12]; stream.Read(buffer, 2, ptr); var offset = ptr + 2; var size = _bit.ToInt16(buffer, 0); for (var i = 0; i < size; i++) { var currOffset = offset + i * 12; stream.Read(buffer, 12, currOffset); ifd.AddTag(buffer, _bit, stream); } stream.Read(buffer, 4, offset + size * 12); ptr = _bit.ToUInt32(buffer, 0); if (ifd.Tags.Any()) { _ifds.Add(ifd); } } catch (Exception) { break; } } }
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" } }
/// <summary> /// Loads TIFF header from stream. /// </summary> /// <param name="stream">Fully formatted TIFF image.</param> /// <returns>Length of header.</returns> protected override long Load(Stream stream) { base.Load(stream); byte[] temp = stream.ReadBytes(8); if (!CheckIdentifier(temp)) { throw new FormatException("Stream is not a recognised TIFF image."); } // Change byte order if required. if (temp[0] == 'M') { endianness = MyBitConverter.Endianness.BigEndian; } // Header FirstImageOffset = MyBitConverter.ToUInt32(temp, 4, endianness); stream.Seek(FirstImageOffset, SeekOrigin.Begin); var IFD = new ImageFileDirectory(stream, endianness); Pages = new List <ImageFileDirectory>() { IFD }; // Add mipmaps if they exist while (IFD.NextIFDOffset != 0) { IFD = new ImageFileDirectory(stream, endianness); Pages.Add(IFD); } return(0); // No sensible return value since header is not contiguous (right?) }
private Array ConvertRow(ImageFileDirectory ifd, byte[] row) { if (ifd.SamplesPerPixel == 1) { if (ifd.BitsPerSample == 8) { if (ifd.SampleFormat == SampleFormat.Unsigned || ifd.SampleFormat == SampleFormat.Signed) { // var output = new byte[width]; // Buffer.BlockCopy(row, 0, output, 0, width + width); // return output; return(row); } } else if (ifd.BitsPerSample == 16) { if (ifd.SampleFormat == SampleFormat.Unsigned || ifd.SampleFormat == SampleFormat.Signed) { var output = new short[row.Length / 2]; if (_reader.StreamIsLittleEndian != BitConverter.IsLittleEndian) { int w2 = row.Length; for (int i = 0; i < w2; i += 2) { byte b = row[i]; row[i] = row[i + 1]; row[i + 1] = b; } } Buffer.BlockCopy(row, 0, output, 0, row.Length); return(output); } } else if (ifd.BitsPerSample == 32) { if (ifd.SampleFormat == SampleFormat.FloatingPoint) { var output = new float[row.Length / 4]; if (_reader.StreamIsLittleEndian != BitConverter.IsLittleEndian) { int w4 = row.Length; for (int i = 0; i < w4; i += 4) { byte b = row[i]; row[i] = row[i + 3]; row[i + 3] = b; b = row[i + 1]; row[i + 1] = row[i + 2]; row[i + 2] = b; } } Buffer.BlockCopy(row, 0, output, 0, row.Length); return(output); } } } return(null); }
public void EntriesCount() { using (var memory = new MemoryStream(Data)) using (var reader = new BinaryReader(memory)) { var imageFileDirectory = new ImageFileDirectory(reader); Assert.AreEqual(1, imageFileDirectory.Entries.Length); } }
public IEnumerable <float[]> ReadImageFileAsFloat(ImageFileDirectory ifd) { var rows = ReadImageFile(ifd); foreach (var row in rows) { yield return(ConvertRowToFloat(ifd, row)); } }
public IEnumerable <short[]> ReadImageFileAsInt16(ImageFileDirectory ifd) { var rows = ReadImageFile(ifd); foreach (var row in rows) { yield return(ConvertRowToInt16(ifd, row)); } }
public void NextEntry() { using (var memory = new MemoryStream(Data)) using (var reader = new BinaryReader(memory)) { var imageFileDirectory = new ImageFileDirectory(reader); Assert.AreEqual(0x00000000u, imageFileDirectory.NextEntry); } }
public void DumpExifData3() { 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 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(37, exif.Entries.Length); // 0) 0x829A URational 2x32-bit: [0x00000380] (1): 1/15 = 0.0666666666666667 // 1) 0x829D URational 2x32-bit: [0x00000388] (1): 18/10 = 1.8 // 2) 0x8822 UShort 16-bit: 2 // 3) 0x8827 UShort 16-bit: 400 // 4) 0x8830 UShort 16-bit: 2 // 5) 0x8832 ULong 32-bit: 400 // 6) 0x9000 UByte[]: 48, 50, 51, 48 // 7) 0x9003 Ascii 8-bit, null terminated: [0x00000390] (20): "2012:11:18 19:04:22" // 8) 0x9004 Ascii 8-bit, null terminated: [0x000003A4] (20): "2012:11:18 19:04:22" // 9) 0x9101 UByte[]: 1, 2, 3, 0 //10) 0x9201 SRational 2x32-bit: [0x000003B8] (1): 262144/65536 = 4 //11) 0x9202 URational 2x32-bit: [0x000003C0] (1): 106496/65536 = 1.625 //12) 0x9204 SRational 2x32-bit: [0x000003C8] (1): 0/1 = 0 //13) 0x9207 UShort 16-bit: 5 //14) 0x9209 UShort 16-bit: 16 //15) 0x920A URational 2x32-bit: [0x000003D0] (1): 50/1 = 50 //16) 0x927C Maker note: [0x000003D8] (45494): //17) 0x9286 UByte[]: [0x0000B58E] (264): //18) 0x9290 Ascii 8-bit, null terminated: [0x00003030] (3): "00" //19) 0x9291 Ascii 8-bit, null terminated: [0x00003030] (3): "00" //20) 0x9292 Ascii 8-bit, null terminated: [0x00003030] (3): "00" //21) 0xA000 UByte[]: 48, 49, 48, 48 //22) 0xA001 UShort 16-bit: 1 //23) 0xA002 UShort 16-bit: 5184 //24) 0xA003 UShort 16-bit: 3456 //25) 0xA005 ULong 32-bit: 46742 //26) 0xA20E URational 2x32-bit: [0x0000B6B4] (1): 5184000/907 = 5715.54575523705 //27) 0xA20F URational 2x32-bit: [0x0000B6BC] (1): 3456000/595 = 5808.40336134454 //28) 0xA210 UShort 16-bit: 2 //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: [0x0000B6C4] (11): "Greg Eakin" //34) 0xA431 Ascii 8-bit, null terminated: [0x0000B6E4] (11): "3071201378" //35) 0xA432 URational 2x32-bit: [0x0000B704] (4): 50/1 = 50 //36) 0xA434 Ascii 8-bit, null terminated: [0x0000B724] (16): "EF50mm f/1.8 II" } }
public void Entry() { using (var memory = new MemoryStream(Data)) using (var reader = new BinaryReader(memory)) { var imageFileDirectory = new ImageFileDirectory(reader); var entry = imageFileDirectory.Entries.First(); Assert.AreEqual(0x0012, entry.TagId); } }
private void WriteImageFileDirectory(ImageFileDirectory ifd) { if (ifd.Entries.TryGetValue(IfdTag.StripOffsets, out var stripOffsetsEntry)) { WriteArrayField(stripOffsetsEntry, ifd.StripOffsets); } if (ifd.Entries.TryGetValue(IfdTag.StripByteCounts, out var stripByteCountsEntry)) { WriteArrayField(stripByteCountsEntry, ifd.StripByteCounts); } UpdateLastReference(); var entries = ifd.Entries.Values.OrderBy(v => v.Tag).ToArray(); if (BigTiff) { _writer.Write((long)entries.Length); } else { _writer.Write((ushort)entries.Length); } foreach (var entry in entries) { _writer.Write((ushort)entry.Tag); _writer.Write((ushort)entry.FieldType); if (BigTiff) { _writer.Write((long)entry.NumValues); } else { _writer.Write((uint)entry.NumValues); } if (entry.Value != null) { WriteFieldValue(entry.FieldType, entry.Value); } else { WriteFieldValue(entry.FieldType, entry.Offset); } } _lastReferencePosition = _writer.BaseStream.Position; WriteReference(0); }
public IEnumerable <byte[]> ReadImageFile(ImageFileDirectory ifd) { if (ifd.PhotometricInterpretation != 1) { throw new NotSupportedException($"PhotometricInterpretation must be BlackIsZero: {ifd.PhotometricInterpretation}"); } if (ifd.Compression != 1) { throw new NotSupportedException($"Compression not supported: {ifd.Compression}"); } if (ifd.SamplesPerPixel != 1) { throw new NotSupportedException($"SamplesPerPixel must be 1: {ifd.SamplesPerPixel}"); } if (ifd.SamplesPerPixel > 1 && ifd.PlanarConfiguration != 1) { throw new NotSupportedException($"PlanarConfiguration must be ChunkyFormat: {ifd.PlanarConfiguration}"); } _reader.Stream.Position = ifd.StripOffsets; var stripOffsets = new uint[ifd.NumStripOffsets]; for (int i = 0; i < ifd.NumStripOffsets; i++) { stripOffsets[i] = _reader.ReadUInt32(); } _reader.Stream.Position = ifd.StripByteCounts; var stripByteCounts = new uint[ifd.NumStripByteCounts]; for (int i = 0; i < ifd.NumStripByteCounts; i++) { stripByteCounts[i] = _reader.ReadUInt32(); } for (uint i = 0; i < ifd.NumStripOffsets; i++) { _stream.Position = stripOffsets[i]; uint bytesPerRow = stripByteCounts[i] / ifd.RowsPerStrip; for (uint j = 0; j < ifd.RowsPerStrip; j++) { var buffer = new byte[bytesPerRow]; _stream.Read(buffer, 0, (int)bytesPerRow); yield return(buffer); } } }
private IEnumerable <byte[]> ReadImageFileInternal(ImageFileDirectory ifd, int offsetX, int offsetY, int outputWidth, int outputHeight) { if (ifd.PhotometricInterpretation != PhotometricInterpretation.BlackIsZero && ifd.PhotometricInterpretation != PhotometricInterpretation.RGB) { throw new NotSupportedException($"PhotometricInterpretation not supported: {ifd.PhotometricInterpretation}"); } if (ifd.Compression != Compression.NoCompression) { throw new NotSupportedException($"Compression not supported: {ifd.Compression}"); } // if (ifd.SamplesPerPixel != 1) // throw new NotSupportedException($"SamplesPerPixel must be 1: {ifd.SamplesPerPixel}"); if (ifd.SamplesPerPixel > 1 && ifd.PlanarConfiguration != PlanarConfiguration.Chunky) { throw new NotSupportedException($"PlanarConfiguration must be ChunkyFormat: {ifd.PlanarConfiguration}"); } if (ifd.FillOrder != 1) { throw new NotSupportedException($"FillOrder = {ifd.FillOrder} is not supported"); } int bytesPerPixel = ifd.SamplesPerPixel * (ifd.BitsPerSample >> 3); int outputBufferSize = bytesPerPixel * outputWidth; int y = 0; for (uint i = 0; i < ifd.StripOffsets.Length; i++) { long position = ifd.StripOffsets[i] + offsetX * bytesPerPixel; for (uint j = 0; j < ifd.RowsPerStrip; j++) { if (y >= offsetY && y < offsetY + outputHeight) { _stream.Position = position; var buffer = new byte[outputBufferSize]; _stream.Read(buffer, 0, outputBufferSize); yield return(buffer); } position += outputBufferSize; y++; } } }
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); } }
private void ReadIfds(IIoStream stream, uint ifdOffset) { var ptr = ifdOffset; while (ptr > 0) { var ifd = new ImageFileDirectory(ptr); _ifds.Add(ifd); var buffer = new byte[12]; stream.Read(buffer, 2, ptr); var offset = ptr + 2; var size = _bit.ToInt16(buffer, 0); for (var i = 0; i < size; i++) { var currOffset = offset + i * 12; stream.Read(buffer, 12, currOffset); ifd.AddTag(buffer, _bit, stream); } stream.Read(buffer, 4, offset + size * 12); ptr = _bit.ToUInt32(buffer, 0); } }
private void WriteBitmap <T>(ImageFileDirectory ifd, IBitmap <T> bitmap, int offsetX, int offsetY, int imageWidth, int imageHeight) { int bytesPerPixel = ifd.SamplesPerPixel * (ifd.BitsPerSample >> 3); var buffer = new byte[bytesPerPixel * imageWidth]; var stripOffsets = new List <long>(); var stripByteCounts = new List <long>(); foreach (var row in bitmap.GetRows()) { stripOffsets.Add(_writer.BaseStream.Position); stripByteCounts.Add(buffer.Length); Buffer.BlockCopy(row, offsetX * bytesPerPixel, buffer, 0, buffer.Length); _writer.BaseStream.Write(buffer, 0, buffer.Length); } ifd.RowsPerStrip = 1; ifd.StripOffsets = stripOffsets.ToArray(); ifd.StripByteCounts = stripByteCounts.ToArray(); }
public void DumpSensorInfo1() { 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); // Sensor Info // 24) 0x00E0 UShort 16-bit: [0x00001540] (17): 34, 5920, 3950, 1, 1, 140, 96, 5899, 3935, 0, 0, 0, 0, 0, 0, 0, 0, var data = RawImage.ReadUInts16(binaryReader, notes.Entries.Single(e => e.TagId == 0x00E0 && e.TagType == 3)); Assert.AreEqual(2 * data.Length, data[0]); //Assert.AreEqual(5920, data[1]); // sensor width //Assert.AreEqual(3950, data[2]); // sensor height //Assert.AreEqual(1, data[3]); // left //Assert.AreEqual(1, data[4]); // top //Assert.AreEqual(140, data[5]); // mask left //Assert.AreEqual(96, data[6]); // mask top //Assert.AreEqual(5899, data[7]); // mask right //Assert.AreEqual(3935, data[8]); // mask bottom var imageWidth = (int)image.Entries.Single(e => e.TagId == 0x0100 && e.TagType == 3).ValuePointer; Assert.AreEqual(imageWidth, data[7] - data[5] + data[3]); var imageLength = (int)image.Entries.Single(e => e.TagId == 0x0101 && e.TagType == 3).ValuePointer; Assert.AreEqual(imageLength, data[8] - data[6] + data[4]); } }
public EnumerableBitmap <T> ReadImageFile <T>(ImageFileDirectory ifd, int offsetX, int offsetY, int outputWidth, int outputHeight) { if (offsetX < 0 || offsetX >= ifd.ImageWidth) { throw new ArgumentOutOfRangeException("offsetX"); } if (offsetY < 0 || offsetY >= ifd.ImageHeight) { throw new ArgumentOutOfRangeException("offsetY"); } if (outputWidth <= 0) { throw new ArgumentOutOfRangeException("outputWidth"); } if (outputHeight <= 0) { throw new ArgumentOutOfRangeException("outputHeight"); } outputWidth = Math.Min(outputWidth, ifd.ImageWidth - offsetX); outputHeight = Math.Min(outputHeight, ifd.ImageHeight - offsetY); var rows = ReadImageFileInternal(ifd, offsetX, offsetY, outputWidth, outputHeight); return(new EnumerableBitmap <T>(outputWidth, outputHeight, ifd.SamplesPerPixel, rows.Select(row => (T[])ConvertRow(ifd, row)))); // var blockingQueue = new BlockingCollection<byte[]>(8); // Task.Run(() => // { // var rows = ReadImageFileInternal(ifd, offsetX, offsetY, outputWidth, outputHeight); // foreach(var row in rows) // blockingQueue.Add(row); // blockingQueue.CompleteAdding(); // }); // return new EnumerableBitmap<T>(outputWidth, outputHeight, blockingQueue.GetConsumingEnumerable().Select(row => (T[])ConvertRow(ifd, row))); }
private void PrepareImageFileDirectory(ImageFileDirectory ifd) { ifd.Entries[IfdTag.ImageWidth] = new IfdEntry { Tag = IfdTag.ImageWidth, FieldType = FieldType.UInt32, NumValues = 1, Value = ifd.ImageWidth }; ifd.Entries[IfdTag.ImageHeight] = new IfdEntry { Tag = IfdTag.ImageHeight, FieldType = FieldType.UInt32, NumValues = 1, Value = ifd.ImageHeight }; ifd.Entries[IfdTag.BitsPerSample] = new IfdEntry { Tag = IfdTag.BitsPerSample, FieldType = FieldType.UInt16, NumValues = 1, Value = ifd.BitsPerSample }; ifd.Entries[IfdTag.PhotometricInterpretation] = new IfdEntry { Tag = IfdTag.PhotometricInterpretation, FieldType = FieldType.UInt16, NumValues = 1, Value = (ushort)ifd.PhotometricInterpretation }; ifd.Entries[IfdTag.Compression] = new IfdEntry { Tag = IfdTag.Compression, FieldType = FieldType.UInt16, NumValues = 1, Value = (ushort)ifd.Compression }; ifd.Entries[IfdTag.SamplesPerPixel] = new IfdEntry { Tag = IfdTag.SamplesPerPixel, FieldType = FieldType.UInt16, NumValues = 1, Value = (ushort)ifd.SamplesPerPixel }; ifd.Entries[IfdTag.RowsPerStrip] = new IfdEntry { Tag = IfdTag.RowsPerStrip, FieldType = FieldType.UInt32, NumValues = 1, Value = (uint)ifd.RowsPerStrip }; ifd.Entries[IfdTag.PlanarConfiguration] = new IfdEntry { Tag = IfdTag.PlanarConfiguration, FieldType = FieldType.UInt16, NumValues = 1, Value = (uint)ifd.PlanarConfiguration }; ifd.Entries[IfdTag.SampleFormat] = new IfdEntry { Tag = IfdTag.SampleFormat, FieldType = FieldType.UInt16, NumValues = 1, Value = (uint)ifd.SampleFormat }; ifd.Entries[IfdTag.StripOffsets] = new IfdEntry { Tag = IfdTag.StripOffsets, FieldType = BigTiff ? FieldType.UInt64 : FieldType.UInt32 }; ifd.Entries[IfdTag.StripByteCounts] = new IfdEntry { Tag = IfdTag.StripByteCounts, FieldType = BigTiff ? FieldType.UInt64 : FieldType.UInt32 }; }
public void DumpSensorInfo3() { 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); var sensorInfo = notes[0x00E0]; var stuff = RawImage.ReadUInts16(binaryReader, sensorInfo); CollectionAssert.AreEqual(new[] { (ushort)34u, // length (ushort)5360u, // sensor width (ushort)3516u, // sensor height (ushort)1u, // sensor left (ushort)1u, // sensor top (ushort)168u, // sensor right (ushort)56u, // sensor bottom (ushort)5351u, (ushort)3511u, (ushort)0u, (ushort)0u, (ushort)0u, (ushort)0u, (ushort)0u, (ushort)0u, (ushort)0u, (ushort)0u }, stuff); } }
/// <summary> /// Saves the <see cref="ImageFile" /> to the given stream. /// </summary> /// <param name="stream">The data stream used to save the image.</param> public override void Save(Stream stream) { BitConverterEx conv = BitConverterEx.SystemEndian; // Write TIFF header uint ifdoffset = 8; // Byte order stream.Write( BitConverterEx.SystemByteOrder == BitConverterEx.ByteOrder.LittleEndian ? new byte[] { 0x49, 0x49 } : new byte[] { 0x4D, 0x4D }, 0, 2); // TIFF ID stream.Write(conv.GetBytes((ushort)42), 0, 2); // Offset to 0th IFD, will be corrected below stream.Write(conv.GetBytes(ifdoffset), 0, 4); // Write IFD sections for (var i = 0; i < IFDs.Count; i++) { ImageFileDirectory ifd = IFDs[i]; // Save the location of IFD offset var ifdLocation = stream.Position - 4; // Write strips first var stripOffsets = new byte[4 * ifd.Strips.Count]; var stripLengths = new byte[4 * ifd.Strips.Count]; var stripOffset = ifdoffset; for (var j = 0; j < ifd.Strips.Count; j++) { var stripData = ifd.Strips[j].Data; var oBytes = BitConverter.GetBytes(stripOffset); var lBytes = BitConverter.GetBytes((uint)stripData.Length); Array.Copy(oBytes, 0, stripOffsets, 4 * j, 4); Array.Copy(lBytes, 0, stripLengths, 4 * j, 4); stream.Write(stripData, 0, stripData.Length); stripOffset += (uint)stripData.Length; } // Remove old strip tags for (var j = ifd.Fields.Count - 1; j > 0; j--) { var tag = ifd.Fields[j].Tag; if (tag == 273 || tag == 279) { ifd.Fields.RemoveAt(j); } } // Write new strip tags ifd.Fields.Add(new ImageFileDirectoryEntry(273, 4, (uint)ifd.Strips.Count, stripOffsets)); ifd.Fields.Add(new ImageFileDirectoryEntry(279, 4, (uint)ifd.Strips.Count, stripLengths)); // Write fields after strips ifdoffset = stripOffset; // Correct IFD offset var currentLocation = stream.Position; stream.Seek(ifdLocation, SeekOrigin.Begin); stream.Write(conv.GetBytes(ifdoffset), 0, 4); stream.Seek(currentLocation, SeekOrigin.Begin); // Offset to field data var dataOffset = ifdoffset + 2 + ((uint)ifd.Fields.Count * 12) + 4; // Field count stream.Write(conv.GetBytes((ushort)ifd.Fields.Count), 0, 2); // Fields foreach (ImageFileDirectoryEntry field in ifd.Fields) { // Tag stream.Write(conv.GetBytes(field.Tag), 0, 2); // Type stream.Write(conv.GetBytes(field.Type), 0, 2); // Count stream.Write(conv.GetBytes(field.Count), 0, 4); // Field data var data = field.Data; if (data.Length <= 4) { stream.Write(data, 0, data.Length); for (var j = data.Length; j < 4; j++) { stream.WriteByte(0); } } else { stream.Write(conv.GetBytes(dataOffset), 0, 4); var currentOffset = stream.Position; stream.Seek(dataOffset, SeekOrigin.Begin); stream.Write(data, 0, data.Length); dataOffset += (uint)data.Length; stream.Seek(currentOffset, SeekOrigin.Begin); } } // Offset to next IFD ifdoffset = dataOffset; stream.Write(conv.GetBytes(i == IFDs.Count - 1 ? 0 : ifdoffset), 0, 4); } }
/// <summary> /// Loads TIFF header from stream. /// </summary> /// <param name="stream">Fully formatted TIFF image.</param> /// <returns>Length of header.</returns> protected override long Load(Stream stream) { base.Load(stream); byte[] temp = stream.ReadBytes(8); if (!CheckIdentifier(temp)) throw new FormatException("Stream is not a recognised TIFF image."); // Change byte order if required. if (temp[0] == 'M') endianness = MyBitConverter.Endianness.BigEndian; // Header FirstImageOffset = MyBitConverter.ToUInt32(temp, 4, endianness); stream.Seek(FirstImageOffset, SeekOrigin.Begin); var IFD = new ImageFileDirectory(stream, endianness); Pages = new List<ImageFileDirectory>() { IFD }; // Add mipmaps if they exist while (IFD.NextIFDOffset != 0) { IFD = new ImageFileDirectory(stream, endianness); Pages.Add(IFD); } return 0; // No sensible return value since header is not contiguous (right?) }
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); } }