public void Colors() { using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var directory = rawImage.Directories.Last(); var address = directory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = directory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); var lossless = startOfImage.StartOfFrame; Assert.AreEqual(4, lossless.Components.Length); // clrs foreach (var component in lossless.Components) { Assert.AreEqual(1, component.HFactor); // sraw Assert.AreEqual(1, component.VFactor); // sraw } Assert.AreEqual(4, lossless.Components.Sum(comp => comp.HFactor * comp.VFactor)); } }
public void Test2() { using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); // The first IFD contains a small RGB version of the picture (one fourth the size) compressed in Jpeg, the EXIF part, and the Makernotes part. // The second IFD contains a small RGB version (160x120 pixels) of the picture, compressed in Jpeg. // The third IFD contains a small RGB version of the picture, NOT compressed (even with compression==6), and one which no white balance, correction has been applied. // The fourth IFD contains the RAW data compressed in lossless Jpeg. var directory = rawImage.Directories.First(); // stripOffset 6) 0x0111 ULong 32-bit: 96332 // orientation 7) 0x0112 UShort 16-bit: 1 // stripByteCounts 8) 0x0117 ULong 32-bit: 2390306 var address = directory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var orientation = directory.Entries.Single(e => e.TagId == 0x0112).ValuePointer; var length = directory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS Assert.AreEqual(0x00010268u, address); Assert.AreEqual(0x001AC95Du, length); Assert.AreEqual(8u, orientation); binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); // Assert.AreEqual(0, startOfImage.); } }
private static void canon_sraw_load_raw(StartOfImage startOfImage, ushort[] slices) { var startOfFrame = startOfImage.StartOfFrame; var sraw = startOfFrame.Components[0].HFactor * startOfFrame.Components[0].VFactor - 1; // 1 Assert.AreEqual(1, sraw); var clrs = startOfFrame.Components.Length + sraw; // 4 Assert.AreEqual(4, clrs); var height = startOfFrame.ScanLines; Assert.AreEqual(1728, height); var jrow = 0; var width = slices[1]; // image width Assert.AreEqual(864, width); var rawWidth = startOfFrame.SamplesPerLine; // 0x1031 var jhwide = startOfFrame.SamplesPerLine; // 0xffc0, data[3] << 8 | data[4] Assert.AreEqual(2592u, startOfFrame.SamplesPerLine); var jwide = (jhwide >>= 1) * clrs; var ecol = 0; var jcol = 0; var rp = new int[0]; for (var slice = 0; slice <= slices[0]; slice++) { var scol = ecol; ecol += slices[1] * 2 / clrs; if (slices[0] == 0 || ecol > rawWidth - 1) { ecol = rawWidth & -2; } for (var row = 0; row < height; row += (clrs >> 1) - 1) { var ip = new short[width, 4]; // image + row * width for (var col = scol; col < ecol; col += 2, jcol += clrs) { if ((jcol %= jwide) == 0) { rp = new_ljpeg_row(jrow++, startOfImage); // rp.length = 10368 } if (col >= width) { continue; } for (var c = 0; c < clrs - 2; c++) { ip[col + (c >> 1) * width + (c & 1), 0] = (short)rp[jcol + c]; } ip[col, 1] = (short)(rp[jcol + clrs - 2] - 0x4000); ip[col, 2] = (short)(rp[jcol + clrs - 1] - 0x4000); } } } }
public void RawImageSize() { // 1 Sensor Width : 5920 = 1 * 2960 + 2960 // 2 Sensor Height : 3950 using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var directory = rawImage.Directories.Last(); var address = directory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = directory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS var strips = directory.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3).ValuePointer; // TIF_CR2_SLICE binaryReader.BaseStream.Seek(strips, SeekOrigin.Begin); var x = binaryReader.ReadUInt16(); var y = binaryReader.ReadUInt16(); var z = binaryReader.ReadUInt16(); Assert.AreEqual(1, x); Assert.AreEqual(3440, y); Assert.AreEqual(3440, z); binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); var lossless = startOfImage.StartOfFrame; Assert.AreEqual(14, lossless.Precision); Assert.AreEqual(4, lossless.Components.Length); Assert.AreEqual(3440, lossless.SamplesPerLine); Assert.AreEqual(2272, lossless.ScanLines); } }
private static void ParseRow( StartOfFrame lossless, int x, ushort y, StartOfImage startOfImage, HuffmanTable table0, short[,] rowBuf, short[] predictor, Bitmap image1) { var i1 = 4 / lossless.Components.Length; for (var j = 0; j < lossless.ScanLines / i1; j++) { for (var g = 0; g < i1; g++) { for (var i = 0; i < y / lossless.Components.Length; i++) { for (var h = 0; h < lossless.Components.Length; h++) { var hufCode = UnitTests.GetValue(startOfImage.ImageData, table0); var difCode = startOfImage.ImageData.GetSetOfBits(hufCode); var dif = UnitTests.DecodeDifBits(hufCode, difCode); if (i == 0) { rowBuf[g * i1 + h, i] = predictor[h] += dif; } else { rowBuf[g * i1 + h, i] = (short)(rowBuf[g * i1 + h, i - 1] + dif); } } } } UnitTests.DumpPixel(x * y, j, rowBuf, image1); } }
public void App1Test() { var data = new byte[] { 0xFF, 0xD8, 0xFF, 0xE1, 0x00, 0x04, 0x00, 0x00 }; using (var memory = new MemoryStream(data)) using (var reader = new BinaryReader(memory)) { var startOfImage = new StartOfImage(reader, 0x0000, (uint)data.Length); } }
public void TagTest() { var data = new byte[] { 0xFF, 0xD8 }; using (var memory = new MemoryStream(data)) using (var reader = new BinaryReader(memory)) { var startOfImage = new StartOfImage(reader, 0x0000, (uint)data.Length); Assert.AreEqual(0xD8, startOfImage.Tag); } }
private static void DumpBitmap(string fileName2, string bitmap) { using (var fileStream = File.Open(fileName2, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var imageFileDirectory = rawImage.Directories.Last(); var strips = imageFileDirectory.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3).ValuePointer; // TIF_CR2_SLICE binaryReader.BaseStream.Seek(strips, SeekOrigin.Begin); var x = binaryReader.ReadUInt16(); var y = binaryReader.ReadUInt16(); var z = binaryReader.ReadUInt16(); Console.WriteLine("x {0}, y {1}, z {2}", x, y, z); Assert.AreEqual(1, x); Assert.AreEqual(2960, y); Assert.AreEqual(2960, z); var address = imageFileDirectory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = imageFileDirectory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length) { ImageData = new ImageData(binaryReader, length) }; var lossless = startOfImage.StartOfFrame; Console.WriteLine("lines {0}, samples per line {1} * {2} = {3}", lossless.ScanLines, lossless.SamplesPerLine, lossless.Components.Length, lossless.Width); Assert.AreEqual(x * y + z, lossless.Width); // Sensor width (bits) Assert.AreEqual(x * y + z, lossless.SamplesPerLine * lossless.Components.Length); var rowBuf = new short[4, lossless.SamplesPerLine]; var predictor = new[] { (short)(1 << (lossless.Precision - 1)), (short)(1 << (lossless.Precision - 1)) }; var table0 = startOfImage.HuffmanTable.Tables[0x00]; // var table1 = startOfImage.HuffmanTable.Tables[0x01]; using (var image1 = new Bitmap(500, 500)) { for (var k = 0; k < x; k++) { ParseRow(lossless, k, y, startOfImage, table0, rowBuf, predictor, image1); } ParseRow(lossless, x, z, startOfImage, table0, rowBuf, predictor, image1); image1.Save(bitmap); Console.WriteLine("EOF {0}", startOfImage.ImageData.RawData.Length - startOfImage.ImageData.Index); } } }
public void HuffmanTable1() { // Huffman - Luminance (Y) - DC using (var memory = new MemoryStream(SimpleData)) using (var binaryReader = new BinaryReader(memory)) { var length = (uint)SimpleData.Length; var startOfImage = new StartOfImage(binaryReader, 0x0000u, length); var table = startOfImage.HuffmanTable.Tables[0x00]; Console.WriteLine(table); } }
private static void ProcessSlice(StartOfImage startOfImage, int slice, int samples, BitmapData data, DataBuf pp) { var startOfFrame = startOfImage.StartOfFrame; var scanLines = startOfFrame.ScanLines; var memory = new DataBuf[2]; // 0x4000 for (var line = 0; line < scanLines; line++) // 0..1728 { // 6 bytes * 8 bits == 48 bits per pixel // 3 = 6 bytes * samplesPerLine / (slices[0] * slices[1] + slices[2]); var scan0 = data.Scan0 + data.Stride * line + slice * samples * 3; // read four shorts, for two pixels for (var col = 0; col < samples / 4; col++) // 0..216 ==> 0/6 .. 2592/6 --> 0 .. 432 { cc += 4; var diff = new DiffBuf { Y1 = startOfImage.ProcessColor(0x00), Y2 = startOfImage.ProcessColor(0x00), Cb = startOfImage.ProcessColor(0x01), Cr = startOfImage.ProcessColor(0x01) }; if (line % 6 == 0 && col == 0) { pp.Y = (ushort)(pp.Y + diff.Y1); pp.Cb += diff.Cb; pp.Cr += diff.Cr; memory[0].Y = pp.Y; memory[0].Cb = pp.Cb; memory[0].Cr = pp.Cr; pp.Y = (ushort)(pp.Y + diff.Y2); memory[1].Y = pp.Y; memory[1].Cb = pp.Cb; memory[1].Cr = pp.Cr; } else { memory[0].Y = (ushort)(memory[0].Y + diff.Y1); memory[0].Cb = (short)(memory[0].Cb + diff.Cb); memory[0].Cr = (short)(memory[0].Cr + diff.Cr); memory[1].Y = (ushort)(memory[1].Y + diff.Y2); memory[1].Cb = memory[0].Cb; memory[1].Cr = memory[0].Cr; } PokePixels(scan0, col, memory[0], memory[1]); } } }
private static void ProcessSlice(StartOfImage startOfImage, int slice, int width, DataBuf[,] memory) { var startOfFrame = startOfImage.StartOfFrame; const int step = 6; for (var line = 0; line < startOfFrame.ScanLines; line += step) // 0..1728 { var vpred = new DataBuf { Y = 0x4000 }; var diff = ReadDiffBufs(step * width, startOfImage); ProcessSixLines(slice, line, memory, vpred, diff); // 864 } }
private static void DumpImage3SRaw(string folder, string file) { var fileName2 = folder + file; using (var fileStream = File.Open(fileName2, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); // Image #3 is a raw image compressed in ITU-T81 lossless JPEG var image = rawImage.Directories.Skip(3).First(); var offset = image.Entries.Single(e => e.TagId == 0x0111 && e.TagType == 4).ValuePointer; var count = image.Entries.Single(e => e.TagId == 0x0117 && e.TagType == 4).ValuePointer; var imageFileEntry = image.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3); var slices = RawImage.ReadUInts16(binaryReader, imageFileEntry); CollectionAssert.AreEqual(new[] { (ushort)5, (ushort)864, (ushort)864 }, slices); binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, offset, count); var startOfFrame = startOfImage.StartOfFrame; Assert.AreEqual(15, startOfFrame.Precision); // sraw/sraw2 Assert.AreEqual(1728u, startOfFrame.ScanLines); // height Assert.AreEqual(2592u, startOfFrame.SamplesPerLine); // width Assert.AreEqual(7776, startOfFrame.Width); Assert.AreEqual(startOfFrame.SamplesPerLine * 3, startOfFrame.Width); Assert.AreEqual(startOfFrame.SamplesPerLine * 2, slices[0] * slices[1] + slices[2]); startOfImage.ImageData.Reset(); // read one line of diff 2592 * 3 == samples per line // write it to six lines of one slice var memory = new DataBuf[startOfFrame.ScanLines, startOfFrame.SamplesPerLine]; // 1728 x 2592 for (var slice = 0; slice < slices[0]; slice++) // 0..5 { ProcessSlice(startOfImage, slice, slices[1], memory); } ProcessSlice(startOfImage, slices[0], slices[2], memory); Assert.AreEqual(8957952, cc); Assert.AreEqual(3, startOfImage.ImageData.DistFromEnd); MakeBitmap(memory, folder); } }
public void PredictorSelectionValue() { using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var directory = rawImage.Directories.Last(); var address = directory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = directory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); Assert.AreEqual(1, startOfImage.StartOfScan.Bb1); // Do nothing } }
private static short[] ReadDiffRow(StartOfImage startOfImage) { var startOfFrame = startOfImage.StartOfFrame; var width = startOfFrame.Width; var diff = new short[width]; for (var x = 0; x < width / 2; x++) { diff[2 * x + 0] = startOfImage.ProcessColor(0x00); diff[2 * x + 1] = startOfImage.ProcessColor(0x01); _cc += 2; } return(diff); }
private static int[] new_ljpeg_row(int jrow, StartOfImage startOfImage) { var startOfFrame = startOfImage.StartOfFrame; var bits = startOfFrame.Precision; // 15 var vpred = new int[6]; for (var c = 0; c < 6; c++) { vpred[c] = 1 << (bits - 1); } var memory = new int[4 * startOfFrame.SamplesPerLine]; var spred = 0; for (var col = 0; col < startOfFrame.SamplesPerLine; col++) { for (var c = 0; c < 4; c++) { var diff = startOfImage.ProcessColor((byte)(c / 2)); int pred; if (c <= 1 && (col > 0 || c > 0)) { pred = spred; } else if (col > 0) { pred = memory[4 * col + c - 4]; } else { pred = (vpred[c] += diff) - diff; } memory[4 * col + c] = pred + diff; if (c <= 1) { spred = memory[4 * col + c]; } } } return(memory); }
private static void CreateBitmap(BinaryReader binaryReader, StartOfImage startOfImage, string outFile, uint offset, ushort[] slices) { binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin); var startOfFrame = startOfImage.StartOfFrame; var height = startOfFrame.ScanLines; Assert.AreEqual(1728, height); // image height var samplesPerLine = startOfFrame.SamplesPerLine; Assert.AreEqual(2592, samplesPerLine); // image width var width = startOfFrame.Width; Assert.AreEqual(7776, startOfFrame.Width); Assert.AreEqual(samplesPerLine * 2, slices[0] * slices[1] + slices[2]); Assert.AreEqual(width, samplesPerLine * 3); Assert.AreEqual(3, 6 * samplesPerLine / (slices[0] * slices[1] + slices[2])); using (var bitmap = new Bitmap(samplesPerLine, height, PixelFormat.Format48bppRgb)) { var size = new Rectangle(0, 0, bitmap.Width, bitmap.Height); var data = bitmap.LockBits(size, ImageLockMode.ReadWrite, bitmap.PixelFormat); try { Assert.AreEqual(6 * samplesPerLine, data.Stride); // 6 bytes * 8 bits == 48 bits per pixel var pp = new DataBuf { Y = 0x4000 }; for (var slice = 0; slice < slices[0]; slice++) // 0..5 { ProcessSlice(startOfImage, slice, slices[1], data, pp); } ProcessSlice(startOfImage, slices[0], slices[2], data, pp); } finally { bitmap.UnlockBits(data); } bitmap.Save(outFile); } }
public void TestMethod8() { const string directory = @"..\..\..\Samples\"; const string fileName2 = directory + "IMAG0086.jpg"; using (var fileStream = File.Open(fileName2, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var startOfImage = new StartOfImage(binaryReader, 0x00u, (uint)fileStream.Length); Assert.AreEqual(0xFF, startOfImage.Mark); Assert.AreEqual(0xD8, startOfImage.Tag); // JPG_MARK_SOI var huffmanTable = startOfImage.HuffmanTable; Assert.AreEqual(0xFF, huffmanTable.Mark); Assert.AreEqual(0xC4, huffmanTable.Tag); Console.WriteLine(huffmanTable); } }
private static DiffBuf[] ReadDiffBufs(int samplesPerLine, StartOfImage startOfImage) { var table0 = startOfImage.HuffmanTable.Tables[0x00]; var table1 = startOfImage.HuffmanTable.Tables[0x01]; var diff = new DiffBuf[samplesPerLine / 4]; // 864 / 4 == 216 for (var x = 0; x < diff.Length; x++) { diff[x].Y1 = startOfImage.ProcessColor(0x00); diff[x].Y2 = startOfImage.ProcessColor(0x00); diff[x].Cb = startOfImage.ProcessColor(0x01); diff[x].Cr = startOfImage.ProcessColor(0x01); cc += 4; } return(diff); }
private static void DumpImage3SRaw(string folder, string file) { var fileName2 = folder + file; using (var fileStream = File.Open(fileName2, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); // Image #3 is a raw image compressed in ITU-T81 lossless JPEG { var image = rawImage.Directories.Skip(3).First(); var offset = image.Entries.Single(e => e.TagId == 0x0111 && e.TagType == 4).ValuePointer; // Assert.AreEqual(0x2D42DCu, offset); var count = image.Entries.Single(e => e.TagId == 0x0117 && e.TagType == 4).ValuePointer; // Assert.AreEqual(0x1501476u, count); var imageFileEntry = image.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3); var slices = RawImage.ReadUInts16(binaryReader, imageFileEntry); CollectionAssert.AreEqual(new[] { (ushort)5, (ushort)864, (ushort)864 }, slices); binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, offset, count); var startOfFrame = startOfImage.StartOfFrame; Assert.AreEqual(1728u, startOfFrame.ScanLines); Assert.AreEqual(2592u, startOfFrame.SamplesPerLine); Assert.AreEqual(7776, startOfFrame.Width); Assert.AreEqual(15, startOfFrame.Precision); // sraw/sraw2 startOfImage.ImageData.Reset(); canon_sraw_load_raw(startOfImage, slices); //Assert.AreEqual(3, startOfImage.ImageData.DistFromEnd); // MakeBitmap(memory, folder); } } }
private static DiffBuf[] ReadDiffRow(StartOfImage startOfImage) { var startOfFrame = startOfImage.StartOfFrame; int samplesPerLine = startOfFrame.SamplesPerLine; var diff = new DiffBuf[samplesPerLine / 4]; // 648 for (var x = 0; x < samplesPerLine / 4; x++) // 0..648 { diff[x].Y1 = startOfImage.ProcessColor(0x00); diff[x].Y2 = startOfImage.ProcessColor(0x00); diff[x].Y3 = startOfImage.ProcessColor(0x00); diff[x].Y4 = startOfImage.ProcessColor(0x00); diff[x].Cb = startOfImage.ProcessColor(0x01); diff[x].Cr = startOfImage.ProcessColor(0x01); cc += 4; } return(diff); }
public void ReadFile() { const string Folder = @"D:\Users\Greg\Pictures\2013_10_14\"; const string FileName2 = Folder + "IMG_4195.CR2"; using (var fileStream = File.Open(FileName2, FileMode.Open, FileAccess.Read)) { var binaryReader = new BinaryReader(fileStream); var rawImage = new RawImage(binaryReader); var imageFileDirectory = rawImage.Directories.Last(); var address = imageFileDirectory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = imageFileDirectory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); Assert.IsTrue(startOfImage.ImageData.EndOfFile); Assert.AreEqual(startOfImage.ImageData.RawData.Length, startOfImage.ImageData.Index + 1); Assert.AreEqual(7, startOfImage.ImageData.BitsLeft); } }
private static DiffBuf[] ReadDiffRow(StartOfImage startOfImage) { var startOfFrame = startOfImage.StartOfFrame; int samplesPerLine = startOfFrame.SamplesPerLine; var table0 = startOfImage.HuffmanTable.Tables[0x00]; var table1 = startOfImage.HuffmanTable.Tables[0x01]; var diff = new DiffBuf[samplesPerLine / 2]; // 1296 for (var x = 0; x < samplesPerLine / 2; x++) // 1296 { diff[x].Y1 = startOfImage.ProcessColor(0x00); diff[x].Y2 = startOfImage.ProcessColor(0x00); diff[x].Cb = startOfImage.ProcessColor(0x01); diff[x].Cr = startOfImage.ProcessColor(0x01); cc += 4; } return(diff); }
public void Bits() { using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var directory = rawImage.Directories.Last(); var address = directory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = directory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); var lossless = startOfImage.StartOfFrame; Assert.AreEqual(14, lossless.Precision); var startOfScan = startOfImage.StartOfScan; Assert.AreEqual(0, startOfScan.Bb3 & 0x0F); Assert.AreEqual(14, lossless.Precision - (startOfScan.Bb3 & 0x0f)); } }
public void SimpleImage() { using (var memory = new MemoryStream(SimpleData)) using (var binaryReader = new BinaryReader(memory)) { var length = (uint)SimpleData.Length; var startOfImage = new StartOfImage(binaryReader, 0x0000u, length); Assert.AreEqual(0xFF, startOfImage.Mark); Assert.AreEqual(0xD8, startOfImage.Tag); var huffmanTable = startOfImage.HuffmanTable; Assert.AreEqual(0xFF, huffmanTable.Mark); Assert.AreEqual(0xC4, huffmanTable.Tag); var startOfScan = startOfImage.StartOfScan; Assert.AreEqual(0xFF, startOfScan.Mark); Assert.AreEqual(0xDA, startOfScan.Tag); var imageData = startOfImage.ImageData; CollectionAssert.AreEqual( new byte[] { 0xFC, 0xFF, 0x00, 0xE2, 0xAF, 0xEF, 0xF3, 0x15, 0x7F, 0xFF, 0xD9 }, imageData.RawData); } }
private static void ProcessFile(string fileName, string bitmap) { using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var imageFileDirectory = rawImage.Directories.Last(); var strips = imageFileDirectory.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3).ValuePointer; // TIF_CR2_SLICE binaryReader.BaseStream.Seek(strips, SeekOrigin.Begin); var x = binaryReader.ReadUInt16(); var y = binaryReader.ReadUInt16(); var z = binaryReader.ReadUInt16(); var address = imageFileDirectory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = imageFileDirectory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); var lossless = startOfImage.StartOfFrame; var rawSize = address + length - binaryReader.BaseStream.Position - 2; // Assert.AreEqual(23852858, rawSize); // RawSize (Raw = new byte[RawSize] startOfImage.ImageData = new ImageData(binaryReader, (uint)rawSize); var colors = lossless.Components.Sum(comp => comp.HFactor * comp.VFactor); var table0 = startOfImage.HuffmanTable.Tables[0x00]; // var buffer = new byte[rawSize]; using (var image1 = new Bitmap(500, 500)) { for (var jrow = 0; jrow < lossless.ScanLines; jrow++) { var rowBuf = new ushort[lossless.SamplesPerLine * colors]; for (var jcol = 0; jcol < lossless.SamplesPerLine; jcol++) { for (var jcolor = 0; jcolor < colors; jcolor++) { //var pred = (ushort)0; //var len = gethuff(); //var diff = getbits(len); //var row = pred + diff; var val = GetValue(startOfImage.ImageData, table0); var bits = startOfImage.ImageData.GetSetOfBits(val); rowBuf[jcol * colors + jcolor] = bits; } DumpPixel(jcol, jrow, rowBuf, colors, image1); } // var pp = startOfImage.ImageData.Index; } image1.Save(bitmap); } // Assert.AreEqual(23852855, startOfImage.ImageData.Index); //Console.WriteLine("{0}: ", startOfImage.ImageData.BitsLeft); //for (var i = startOfImage.ImageData.Index; i < rawSize - 2; i++) //{ // Console.WriteLine("{0} ", startOfImage.ImageData.RawData[i].ToString("X2")); //} } }
public void TestMethod6() { using (var fileStream = File.Open(FileName, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var imageFileDirectory = rawImage.Directories.Last(); var strips = imageFileDirectory.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3).ValuePointer; // TIF_CR2_SLICE binaryReader.BaseStream.Seek(strips, SeekOrigin.Begin); var x = binaryReader.ReadUInt16(); var y = binaryReader.ReadUInt16(); var z = binaryReader.ReadUInt16(); var address = imageFileDirectory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = imageFileDirectory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); Assert.AreEqual(0xFF, startOfImage.Mark); Assert.AreEqual(0xD8, startOfImage.Tag); // JPG_MARK_SOI var huffmanTable = startOfImage.HuffmanTable; Assert.AreEqual(0xFF, huffmanTable.Mark); Assert.AreEqual(0xC4, huffmanTable.Tag); // This file has two huffman tables: 0x00 and 0x01 Assert.AreEqual(2, huffmanTable.Tables.Count); Assert.IsTrue(huffmanTable.Tables.ContainsKey(0x00)); Assert.IsTrue(huffmanTable.Tables.ContainsKey(0x01)); var lossless = startOfImage.StartOfFrame; Assert.AreEqual(0xFF, lossless.Mark); Assert.AreEqual(0xC3, lossless.Tag); Assert.AreEqual(14, lossless.Precision); Assert.AreEqual(4, lossless.Components.Length); Assert.AreEqual(3440, lossless.SamplesPerLine); Assert.AreEqual(2272, lossless.ScanLines); Assert.AreEqual(13760, lossless.Width); // Sensor width (bits) Assert.AreEqual(13760, lossless.SamplesPerLine * lossless.Components.Length); Assert.AreEqual(6880, x * y + z); foreach (var component in lossless.Components) { // Console.WriteLine("== {0}: {1} {2} {3}", component.ComponentId, component.HFactor, component.VFactor, component.TableId); Assert.AreEqual(0x01, component.HFactor); Assert.AreEqual(0x01, component.VFactor); Assert.AreEqual(0x00, component.TableId); } var startOfScan = startOfImage.StartOfScan; Assert.AreEqual(0xFF, startOfScan.Mark); Assert.AreEqual(0xDA, startOfScan.Tag); //foreach (var scanComponent in startOfScan.Components) //{ // Console.WriteLine("{0}: {1} {2}", scanComponent.Id, scanComponent.Dc, scanComponent.Ac); //} var imageData = startOfImage.ImageData; } }
public void TestMethodB() { // const string Directory = @"C:\Users\Greg\Documents\Visual Studio 2012\Projects\PhotoDebug\Samples\"; // const string FileName2 = Directory + "IMG_0503.CR2"; const string directory = @"D:\Users\Greg\Pictures\2013-10-06 001\"; const string fileName2 = directory + "0L2A8892.CR2"; using (var fileStream = File.Open(fileName2, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var imageFileDirectory = rawImage.Directories.Last(); var strips = imageFileDirectory.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3).ValuePointer; // TIF_CR2_SLICE binaryReader.BaseStream.Seek(strips, SeekOrigin.Begin); var x = binaryReader.ReadUInt16(); var y = binaryReader.ReadUInt16(); var z = binaryReader.ReadUInt16(); var address = imageFileDirectory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = imageFileDirectory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length); var lossless = startOfImage.StartOfFrame; // Assert.AreEqual(4711440, lossless.SamplesPerLine * lossless.ScanLines); // IbSize (IB = new ushort[IbSize]) var rawSize = address + length - binaryReader.BaseStream.Position - 2; // Assert.AreEqual(23852856, rawSize); // RawSize (Raw = new byte[RawSize] startOfImage.ImageData = new ImageData(binaryReader, (uint)rawSize); // var table0 = startOfImage.HuffmanTable.Tables[0x00]; var buffer = new byte[rawSize]; var rp = 0; for (var jrow = 0; jrow < lossless.ScanLines; jrow++) { for (var jcol = 0; jcol < lossless.SamplesPerLine; jcol++) { var val = startOfImage.ImageData.RawData[rp++]; if (val == 0xFF) { var code = startOfImage.ImageData.RawData[rp]; if (code != 0) { Assert.Fail($"Invalid code found {rp}, {startOfImage.ImageData.RawData[rp]}"); } rp++; } var jidx = jrow * lossless.SamplesPerLine + jcol; var i = jidx / (y * lossless.ScanLines); var j = i >= x; if (j) { i = x; } jidx -= i * (y * lossless.ScanLines); var row = jidx / (j ? y : z); var col = jidx % (j ? y : z) + i * y; buffer[row * lossless.SamplesPerLine + col] = val; } } } }
private static void DumpImage3SRaw(string fileName) { using (var fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); // Image #3 is a raw image compressed in ITU-T81 lossless JPEG var image = rawImage.Directories.Skip(3).First(); Assert.AreEqual(7, image.Entries.Length); var compression = image.Entries.Single(e => e.TagId == 0x0103 && e.TagType == 3).ValuePointer; Assert.AreEqual(6u, compression); var offset = image.Entries.Single(e => e.TagId == 0x0111 && e.TagType == 4).ValuePointer; // Assert.AreEqual(0x2D42DCu, offset); var count = image.Entries.Single(e => e.TagId == 0x0117 && e.TagType == 4).ValuePointer; // Assert.AreEqual(0x1501476u, count); var item3 = image.Entries.Single(e => e.TagId == 0xC5D8 && e.TagType == 4).ValuePointer; Assert.AreEqual(0x1u, item3); var item4 = image.Entries.Single(e => e.TagId == 0xC5E0 && e.TagType == 4).ValuePointer; Assert.AreEqual(0x3u, item4); // 0xC640 UShort 16-bit: [0x000119BE] (3): 8, 1296, 1296, var imageFileEntry = image.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3); // Assert.AreEqual(0x000119BEu, imageFileEntry.ValuePointer); // Assert.AreEqual(3u, imageFileEntry.NumberOfValue); var slices = RawImage.ReadUInts16(binaryReader, imageFileEntry); CollectionAssert.AreEqual(new ushort[] { 8, 1296, 1296 }, slices); var item6 = image.Entries.Single(e => e.TagId == 0xC6C5 && e.TagType == 4).ValuePointer; Assert.AreEqual(0x4u, item6); binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, offset, count); var startOfFrame = startOfImage.StartOfFrame; Assert.AreEqual(2592u, startOfFrame.ScanLines); Assert.AreEqual(3888u, startOfFrame.SamplesPerLine); Assert.AreEqual(11664, startOfFrame.Width); // var rowBuf0 = new short[startOfFrame.SamplesPerLine * startOfFrame.Components.Length]; // var rowBuf1 = new short[startOfFrame.SamplesPerLine * startOfFrame.Components.Length]; // var predictor = new[] { (short)(1 << (startOfFrame.Precision - 1)), (short)(1 << (startOfFrame.Precision - 1)) }; Assert.AreEqual(2, startOfImage.HuffmanTable.Tables.Count); // var table0 = startOfImage.HuffmanTable.Tables[0x00]; // var table1 = startOfImage.HuffmanTable.Tables[0x01]; Assert.AreEqual(15, startOfFrame.Precision); // mraw/sraw1 // chrominance subsampling factors Assert.AreEqual(3, startOfFrame.Components.Length); // mraw/sraw1 // Assert.AreEqual(1, startOfFrame.Components[0].ComponentId); Assert.AreEqual(2, startOfFrame.Components[0].HFactor); Assert.AreEqual(2, startOfFrame.Components[0].VFactor); // MRAW Assert.AreEqual(0, startOfFrame.Components[0].TableId); Assert.AreEqual(2, startOfFrame.Components[1].ComponentId); Assert.AreEqual(1, startOfFrame.Components[1].HFactor); Assert.AreEqual(1, startOfFrame.Components[1].VFactor); Assert.AreEqual(0, startOfFrame.Components[1].TableId); Assert.AreEqual(3, startOfFrame.Components[2].ComponentId); Assert.AreEqual(1, startOfFrame.Components[2].HFactor); Assert.AreEqual(1, startOfFrame.Components[2].VFactor); Assert.AreEqual(0, startOfFrame.Components[2].TableId); // mraw/sraw1 // Y1 Y2 Y3 Y4 Cb Cr // Y1 Cb Cr Y2 x x // Y3 x x Y4 x x var startOfScan = startOfImage.StartOfScan; // DumpStartOfScan(startOfScan); Assert.AreEqual(1, startOfScan.Bb1); // Start of spectral or predictor selection Assert.AreEqual(0, startOfScan.Bb2); // end of spectral selection Assert.AreEqual(0, startOfScan.Bb3); // successive approximation bit positions Assert.AreEqual(3, startOfScan.Components.Length); // sraw/sraw2 Assert.AreEqual(1, startOfScan.Components[0].Id); Assert.AreEqual(0, startOfScan.Components[0].Dc); Assert.AreEqual(0, startOfScan.Components[0].Ac); Assert.AreEqual(2, startOfScan.Components[1].Id); Assert.AreEqual(1, startOfScan.Components[1].Dc); Assert.AreEqual(0, startOfScan.Components[1].Ac); Assert.AreEqual(3, startOfScan.Components[2].Id); Assert.AreEqual(1, startOfScan.Components[2].Dc); Assert.AreEqual(0, startOfScan.Components[2].Ac); // DumpCompressedData(startOfImage); // horizontal sampling == 1 startOfImage.ImageData.Reset(); var memory = new DataBuf[startOfFrame.ScanLines][]; // [2592][] for (var line = 0; line < startOfFrame.ScanLines; line++) // 0 .. 2592 { var diff = ReadDiffRow(startOfImage); // VerifyDiff(diff, line); var memory1 = ProcessDiff(diff, startOfFrame.SamplesPerLine); // memory[line] = memory1; } Assert.AreEqual(10077696, cc); Assert.AreEqual(1, startOfImage.ImageData.DistFromEnd); var outFile = Path.ChangeExtension(fileName, ".bmp"); MakeBitmap(memory, outFile, slices); } }
private static void DumpBitmap(string fileName2, string bitmap) { using (var fileStream = File.Open(fileName2, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(fileStream)) { var rawImage = new RawImage(binaryReader); var imageFileDirectory = rawImage.Directories.Last(); // compression for 7D RAW should be 4 - // compression for 7D mRAW and sRAW should be 3 - // compression for 5DIII RAW should be 2 - // compression for 5DIII mRAW and sRAW should be 3 - //var compressoin = imageFileDirectory.Entries.Single(e => e.TagId == 0x0103 && e.TagType == 3).ValuePointer; // TIF_COMPRESSION //Assert.AreEqual(6u, compressoin); // JpegCompression var strips = imageFileDirectory.Entries.Single(e => e.TagId == 0xC640 && e.TagType == 3).ValuePointer; // TIF_CR2_SLICE binaryReader.BaseStream.Seek(strips, SeekOrigin.Begin); var x = binaryReader.ReadUInt16(); var y = binaryReader.ReadUInt16(); var z = binaryReader.ReadUInt16(); Console.WriteLine("x {0}, y {1}, z {2}", x, y, z); //Assert.AreEqual(2, x); //Assert.AreEqual(1728, y); //Assert.AreEqual(1904, z); var address = imageFileDirectory.Entries.Single(e => e.TagId == 0x0111).ValuePointer; // TIF_STRIP_OFFSETS var length = imageFileDirectory.Entries.Single(e => e.TagId == 0x0117).ValuePointer; // TIF_STRIP_BYTE_COUNTS binaryReader.BaseStream.Seek(address, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, address, length) { ImageData = new ImageData(binaryReader, length) }; // Step 1: Huffman Table var huffmanTable = startOfImage.HuffmanTable; var table0 = huffmanTable.Tables[0x00]; var table1 = huffmanTable.Tables[0x01]; DumpHuffmanTable(huffmanTable); // Step 2: Start of Frame var startOfFrame = startOfImage.StartOfFrame; DumpStartOfFrame(startOfFrame); //Assert.AreEqual(x * y + z, startOfFrame.Width); // Sensor width (bits) //Assert.AreEqual(x * y + z, startOfFrame.SamplesPerLine * startOfFrame.Components.Length); // Step 3: Start of Scan var startOfScan = startOfImage.StartOfScan; DumpStartOfScan(startOfScan); var predictor = new[] { (short)(1 << (startOfFrame.Precision - 1)), (short)(1 << (startOfFrame.Precision - 1)), (short)(1 << (startOfFrame.Precision - 1)), (short)(1 << (startOfFrame.Precision - 1)) }; using (var image1 = new Bitmap(startOfFrame.SamplesPerLine, startOfFrame.ScanLines)) { for (var k = 0; k < x; k++) { ParseRow(startOfFrame.ScanLines, k, y, y, startOfImage.ImageData, predictor, table0, table1, image1); } ParseRow(startOfFrame.ScanLines, x, y, z, startOfImage.ImageData, predictor, table0, table1, image1); image1.Save(bitmap); } Console.WriteLine("EOF {0}", startOfImage.ImageData.RawData.Length - startOfImage.ImageData.Index); } }
// 4:2:2 chrominance subsampling pattern // 2x1 chroma subsampling private static void ProcessLine15321Old(int slice, int line, int samplesPerLine, StartOfImage startOfImage, DataBuf[,] memory, DataBuf prev) { var diff = ReadDiffBufs(samplesPerLine, startOfImage); for (var x = 0; x < diff.Length; x++) // 216 { var pp = prev; var y1 = (ushort)(pp.Y + diff[x].Y1); var y2 = (ushort)(pp.Y + diff[x].Y1 + diff[x].Y2); var cb = (short)(pp.Cb + diff[x].Cb); var cr = (short)(pp.Cr + diff[x].Cr); pp.Y = y2; pp.Cb = cb; pp.Cr = cr; var col = 2 * slice * diff.Length + 2 * x; memory[line, col].Y = y1; memory[line, col].Cb = cb; memory[line, col].Cr = cr; memory[line, col + 1].Y = y2; memory[line, col + 1].Cb = 0; memory[line, col + 1].Cr = 0; } }