protected override void Execute() { int samplesPerView = GlobalInfo.SamplesInChart; double dt = 1.0 / GlobalInfo.SampleRate; double fundmentalFrequency = 0, thd = 0; int index; _configForm.GetChannelIndex(out index); if (index < 0) { return; } int harmonicLevel = _configForm.GetHarmonicLevel(); if (_harmonicLevel?.Length != harmonicLevel) { _harmonicLevel = new double[harmonicLevel]; } double[] waveform = DataBuf.GetRange(samplesPerView * index, samplesPerView).ToArray(); HarmonicAnalyzer.ToneAnalysis(waveform, dt, out fundmentalFrequency, out thd, ref _harmonicLevel, harmonicLevel); DetailValues[0] = thd.ToString(); DetailValues[1] = fundmentalFrequency.ToString(); }
private static DataBuf[] ProcessDiff(DiffBuf[] diff, DataBuf prev) { var memory = new DataBuf[2 * diff.Length]; // 2592 for (var x = 0; x < diff.Length; x++) // 2592 { var y1 = (ushort)(prev.Y + diff[x].Y1); var y2 = (ushort)(prev.Y + diff[x].Y1 + diff[x].Y2); var cb = (short)(prev.Cb + diff[x].Cb); var cr = (short)(prev.Cr + diff[x].Cr); prev.Y = y2; prev.Cb = cb; prev.Cr = cr; memory[2 * x].Y = y1; memory[2 * x].Cb = cb; memory[2 * x].Cr = cr; memory[2 * x + 1].Y = y2; memory[2 * x + 1].Cb = cb; memory[2 * x + 1].Cr = cr; } return(memory); }
private static DataBuf[] ProcessDiff(DiffBuf[] diff, int samplesPerLine) { Assert.AreEqual(samplesPerLine / 4, diff.Length); var prev = new DataBuf { Y = 0x4000, Cb = 0, Cr = 0 }; var memory = new DataBuf[samplesPerLine]; // 2592 for (var x = 0; x < samplesPerLine / 4; x++) // 2592 { var y1 = (ushort)(prev.Y + diff[x].Y1); var y2 = (ushort)(prev.Y + diff[x].Y1 + diff[x].Y2); var y3 = (ushort)(prev.Y + diff[x].Y1 + diff[x].Y2 + diff[x].Y3); var y4 = (ushort)(prev.Y + diff[x].Y1 + diff[x].Y2 + diff[x].Y3 + diff[x].Y4); var cb = (short)(prev.Cb + diff[x].Cb); var cr = (short)(prev.Cr + diff[x].Cr); prev.Y = y2; prev.Cb = cb; prev.Cr = cr; memory[4 * x].Y = y1; memory[4 * x].Cb = cb; memory[4 * x].Cr = cr; memory[4 * x + 1].Y = y2; memory[4 * x + 1].Cb = cb; memory[4 * x + 1].Cr = cr; } return(memory); }
private static DataBuf[] ProcessDiff(DiffBuf[] diff, DataBuf prev) { var samplesPerLine = diff.Length * 4; var memory = new DataBuf[samplesPerLine]; // 2592 for (var x = 0; x < samplesPerLine / 4; x++) // 2592 { var y1 = (ushort)(prev.Y + diff[x].Y1); var y2 = (ushort)(prev.Y + diff[x].Y1 + diff[x].Y2); var y3 = (ushort)(prev.Y + diff[x].Y1 + diff[x].Y2 + diff[x].Y3); var y4 = (ushort)(prev.Y + diff[x].Y1 + diff[x].Y2 + diff[x].Y3 + diff[x].Y4); var cb = (short)(prev.Cb + diff[x].Cb); var cr = (short)(prev.Cr + diff[x].Cr); prev.Y = y2; prev.Cb = cb; prev.Cr = cr; memory[4 * x].Y = y1; memory[4 * x].Cb = cb; memory[4 * x].Cr = cr; memory[4 * x + 1].Y = y2; memory[4 * x + 1].Cb = cb; memory[4 * x + 1].Cr = cr; } return(memory); }
private static void PixelSet(Bitmap bitmap, int row, int col, DataBuf val) { var r = val.Y + 1.40200 * val.Cr; var g = val.Y - 0.34414 * val.Cb - 0.71414 * val.Cr; var b = val.Y + 1.77200 * val.Cb; var color = Color.FromArgb((byte)((int)r >> 7), (byte)((int)g >> 7), (byte)((int)b >> 7)); bitmap.SetPixel(col, row, color); }
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]); } } }
// 4:2:2 chrominance subsampling pattern // 2x1 chroma subsampling private static void ProcessSixLines(int slice, int line, DataBuf[,] memory, DataBuf prev, DiffBuf[] diff) { var last = memory.GetLength(1); var spred = (ushort)0; for (var y = 0; y < 6; y++) { var row = line + y; if (slice == 0) { prev.Y = (ushort)(prev.Y + diff[0].Y1); spred = prev.Y; memory[row, 0].Y = prev.Y; memory[row, 0].Cb = prev.Cb += diff[0].Cb; memory[row, 0].Cr = prev.Cr += diff[0].Cr; spred = (ushort)(spred + diff[0].Y2); memory[row, 1].Y = spred; memory[row, 1].Cb = 0; //(short)(memory[row, 0].Cb + diff[0].Cb); memory[row, 1].Cr = 0; //(short)(memory[row, 0].Cr + diff[0].Cr); } else { spred = (ushort)(spred + diff[0].Y1); memory[row, 0].Y = spred; memory[row, 0].Cb = (short)(memory[row, last - 1].Cb + diff[0].Cb); memory[row, 0].Cr = (short)(memory[row, last - 1].Cr + diff[0].Cr); spred = (ushort)(spred + diff[0].Y2); memory[row, 1].Y = spred; memory[row, 1].Cb = 0; //(short)(memory[row, 0].Cb + diff[0].Cb); memory[row, 1].Cr = 0; //(short)(memory[row, 0].Cr + diff[0].Cr); } for (var x = 1; x < diff.Length / 6; x++) // 216 { var col = 2 * (slice * diff.Length / 6 + x); spred = (ushort)(spred + diff[x].Y1); memory[row, col].Y = spred; memory[row, col].Cb = (short)(memory[row, col - 1].Cb + diff[x].Cb); memory[row, col].Cr = (short)(memory[row, col - 1].Cr + diff[x].Cr); spred = (ushort)(spred + diff[x].Y2); memory[row, col + 1].Y = spred; memory[row, col + 1].Cb = (short)(memory[row, col].Cb + diff[x].Cb); memory[row, col + 1].Cr = (short)(memory[row, col].Cr + diff[x].Cr); } } }
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 } }
protected override void Execute() { _spectrumDatas.Clear(); int dataStartIndex = 0; int samplesPerView = DataBuf.Count / GlobalInfo.EnableChannelCount; for (int i = 0; i < GlobalInfo.EnableChannelCount; i++) { double[] showData = DataBuf.GetRange(dataStartIndex, samplesPerView).ToArray(); Spectrum.PowerSpectrum(showData, GlobalInfo.SampleRate, ref _spectrum, out _df, SpectrumUnits.dBV, _configForm.Window, _configForm.WindowPara); _spectrumDatas.AddRange(_spectrum); dataStartIndex += samplesPerView; } }
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); } }
protected override void Execute() { _filteredDatas.Clear(); int samplesPerView = GlobalInfo.SamplesInChart; // if (null == _filteredWave || _filteredWave.Length != samplesPerView) // { // _filteredWave = new double[samplesPerView]; // } OnlineFirFilter filter = _configForm.Filter; for (int i = 0; i < GlobalInfo.EnableChannelCount; i++) { double[] showData = DataBuf.GetRange(i * samplesPerView, samplesPerView).ToArray(); _filteredDatas.AddRange(filter.ProcessSamples(showData)); } }
public DataBuf[][] ReadImage() { var memory = new DataBuf[StartOfFrame.ScanLines][]; // [1728][] var prev = new DataBuf { Y = 0x4000, Cb = 0, Cr = 0 }; for (var line = 0; line < StartOfFrame.ScanLines; line++) // 0 .. 3950 { var diff = ReadDiffRow(); var memory1 = ProcessDiff(diff, prev); memory[line] = memory1; } 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); } }
protected override void Execute() { int signalIndex; _configForm.GetChannelIndex(out signalIndex); if (signalIndex < 0) { DetailValues[0] = Constants.NotAvailable; } else { int samplesInChart = GlobalInfo.SamplesInChart; _squareMeasurement.SetWaveform(DataBuf.GetRange(samplesInChart * signalIndex, samplesInChart).ToArray()); DetailValues[0] = _squareMeasurement.GetHighStateLevel().ToString(); DetailValues[1] = _squareMeasurement.GetLowStateLevel().ToString(); DetailValues[2] = (GlobalInfo.SampleRate / _squareMeasurement.GetPeriod()).ToString(); } }
protected override void Execute() { int signal1Index, signal2Index; _configForm.GetChannelIndex(out signal1Index, out signal2Index); int samplesPerView = GlobalInfo.SamplesInChart; if (signal2Index >= 0 && signal1Index >= 0 && signal1Index != signal2Index) { double[] signal1 = DataBuf.GetRange(signal1Index * samplesPerView, samplesPerView).ToArray(); double[] signal2 = DataBuf.GetRange(signal2Index * samplesPerView, samplesPerView).ToArray(); DetailValues[0] = Phase.CalPhaseShift(signal1, signal2).ToString(); } else { DetailValues[0] = Constants.NotAvailable; } }
private static void PokePixels(IntPtr scan0, IntPtr scan1, int col, DataBuf pixel0, DataBuf pixel1, DataBuf pixel2, DataBuf pixel3) { { var red = pixel0.Y + 1.40200 * pixel0.Cr; var green = pixel0.Y - 0.34414 * pixel0.Cb - 0.71414 * pixel0.Cr; var blue = pixel0.Y + 1.77200 * pixel0.Cb; Marshal.WriteInt16(scan0, 12 * col + 4, (short)red); Marshal.WriteInt16(scan0, 12 * col + 2, (short)green); Marshal.WriteInt16(scan0, 12 * col + 0, (short)blue); } { var red = pixel1.Y + 1.40200 * pixel1.Cr; var green = pixel1.Y - 0.34414 * pixel1.Cb - 0.71414 * pixel1.Cr; var blue = pixel1.Y + 1.77200 * pixel1.Cb; Marshal.WriteInt16(scan0, 12 * col + 10, (short)red); Marshal.WriteInt16(scan0, 12 * col + 8, (short)green); Marshal.WriteInt16(scan0, 12 * col + 6, (short)blue); } { var red = pixel2.Y + 1.40200 * pixel2.Cr; var green = pixel2.Y - 0.34414 * pixel2.Cb - 0.71414 * pixel2.Cr; var blue = pixel2.Y + 1.77200 * pixel2.Cb; Marshal.WriteInt16(scan1, 12 * col + 4, (short)red); Marshal.WriteInt16(scan1, 12 * col + 2, (short)green); Marshal.WriteInt16(scan1, 12 * col + 0, (short)blue); } { var red = pixel3.Y + 1.40200 * pixel3.Cr; var green = pixel3.Y - 0.34414 * pixel3.Cb - 0.71414 * pixel3.Cr; var blue = pixel3.Y + 1.77200 * pixel3.Cb; Marshal.WriteInt16(scan1, 12 * col + 10, (short)red); Marshal.WriteInt16(scan1, 12 * col + 8, (short)green); Marshal.WriteInt16(scan1, 12 * col + 6, (short)blue); } }
protected override void Execute() { int channelCount = GlobalInfo.Channels.Count(item => item.Enabled); int sampleCount = GlobalInfo.SamplesInChart; for (int i = 0; i < DetailValues.Length; i++) { DetailValues[i] = ""; } for (int i = 0; i < channelCount; i++) { ToneAnalysisResult result = HarmonicAnalysis.ToneAnalysis(DataBuf.GetRange(i * sampleCount, sampleCount).ToArray(), 1.0 / GlobalInfo.SampleRate); DetailValues[0] += $"{result.THD:f6} "; DetailValues[1] += $"{result.THDplusN:f6} "; DetailValues[2] += $"{result.SINAD:f6} "; DetailValues[3] += $"{result.SNR:f6} "; DetailValues[4] += $"{result.NoiseFloor:f6} "; DetailValues[5] += $"{result.ENOB:f6} "; } }
private static void PokePixels(IntPtr scan0, int col, DataBuf pixel0, DataBuf pixel1) { { var red = pixel0.R; var green = pixel0.G; var blue = pixel0.B; Marshal.WriteInt16(scan0, 12 * col + 4, (short)red); Marshal.WriteInt16(scan0, 12 * col + 2, (short)green); Marshal.WriteInt16(scan0, 12 * col + 0, (short)blue); } { var red = pixel1.R; var green = pixel1.G; var blue = pixel1.B; Marshal.WriteInt16(scan0, 12 * col + 10, (short)red); Marshal.WriteInt16(scan0, 12 * col + 8, (short)green); Marshal.WriteInt16(scan0, 12 * col + 6, (short)blue); } }
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 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(); 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); // 0xC640 UShort 16-bit: [0x000119BE] (3): 5, 864, 864, 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[] { 5, 864, 864 }, slices); binaryReader.BaseStream.Seek(offset, SeekOrigin.Begin); var startOfImage = new StartOfImage(binaryReader, offset, count); // { ImageData = new ImageData(binaryReader, count) }; var startOfFrame = startOfImage.StartOfFrame; Assert.AreEqual(1728u, startOfFrame.ScanLines); Assert.AreEqual(2592u, startOfFrame.SamplesPerLine); Assert.AreEqual(7776, startOfFrame.Width); Assert.AreEqual(2, startOfImage.HuffmanTable.Tables.Count); //var table0 = startOfImage.HuffmanTable.Tables[0x00]; //var table1 = startOfImage.HuffmanTable.Tables[0x01]; Assert.AreEqual(15, startOfFrame.Precision); // sraw/sraw2 // chrominance subsampling factors Assert.AreEqual(3, startOfFrame.Components.Length); // sraw/sraw2 // J:a:b = 4:2:2, h/v = 2/1 Assert.AreEqual(1, startOfFrame.Components[0].ComponentId); Assert.AreEqual(2, startOfFrame.Components[0].HFactor); // SRAW Assert.AreEqual(1, startOfFrame.Components[0].VFactor); 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); // sraw/sraw2 // Y1 Y2 Cb Cr ... // Y1 Cb Cr Y2 x x // Y1 Cb Cr Y2 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 prev = new DataBuf { Y = 0x4000, Cb = 0, Cr = 0 }; var memory = new DataBuf[startOfFrame.ScanLines][]; // [1728][] for (var line = 0; line < startOfFrame.ScanLines; line++) // 0 .. 1728 { var diff = ReadDiffRow(startOfImage); // VerifyDiff(diff, line); var memory1 = ProcessDiff(diff, prev); // 2592 memory[line] = memory1; } Assert.AreEqual(8957952, cc); Assert.AreEqual(3, startOfImage.ImageData.DistFromEnd); var outFile = Path.ChangeExtension(fileName, ".bmp"); MakeBitmap(memory, outFile, slices); } } }
private static void ProcessSlice(StartOfImage startOfImage, int slice, int width, BitmapData data, ushort[] pp) { var startOfFrame = startOfImage.StartOfFrame; var scanLines = startOfFrame.ScanLines; var memory = new ushort[2]; for (var line = 0; line < scanLines; line++) { // 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 * width * 6; // read two shorts, for two pixels for (var col = 0; col < width / 2; col++) { var diff = new DiffBuf { Y1 = startOfImage.ProcessColor(0x00), Y2 = startOfImage.ProcessColor(0x01), }; cc += 2; if (line % 2 == 0 && col == 0) { pp[0] = (ushort)(pp[0] + diff.Y1); memory[0] = pp[0]; pp[1] = (ushort)(pp[1] + diff.Y2); memory[1] = pp[1]; } else { memory[0] = (ushort)(memory[0] + diff.Y1); memory[1] = (ushort)(memory[1] + diff.Y2); } if (line % 2 == 0) { var pixel0 = new DataBuf { R = memory[0] }; var pixel1 = new DataBuf { G = memory[1] }; PokePixels(scan0, col, pixel0, pixel1); } else { var pixel0 = new DataBuf { G = memory[0] }; var pixel1 = new DataBuf { B = memory[1] }; PokePixels(scan0, col, pixel0, pixel1); } } } }
// 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; } }
private void button1_Click(object sender, EventArgs e) { this.button1.Enabled = false; DllInvoke dllInvoke = new DllInvoke("Rad.dll"); colorDataSrc = new ColorDataSrc() { pd000_R = new double[MAX_WIDTH * MAX_HEIGHT], pd000_G = new double[MAX_WIDTH * MAX_HEIGHT], pd000_B = new double[MAX_WIDTH * MAX_HEIGHT], pd016_R = new double[MAX_WIDTH * MAX_HEIGHT], pd016_G = new double[MAX_WIDTH * MAX_HEIGHT], pd016_B = new double[MAX_WIDTH * MAX_HEIGHT], pd032_R = new double[MAX_WIDTH * MAX_HEIGHT], pd032_G = new double[MAX_WIDTH * MAX_HEIGHT], pd032_B = new double[MAX_WIDTH * MAX_HEIGHT], pd064_R = new double[MAX_WIDTH * MAX_HEIGHT], pd064_G = new double[MAX_WIDTH * MAX_HEIGHT], pd064_B = new double[MAX_WIDTH * MAX_HEIGHT], pd096_R = new double[MAX_WIDTH * MAX_HEIGHT], pd096_G = new double[MAX_WIDTH * MAX_HEIGHT], pd096_B = new double[MAX_WIDTH * MAX_HEIGHT], pd128_R = new double[MAX_WIDTH * MAX_HEIGHT], pd128_G = new double[MAX_WIDTH * MAX_HEIGHT], pd128_B = new double[MAX_WIDTH * MAX_HEIGHT], pd160_R = new double[MAX_WIDTH * MAX_HEIGHT], pd160_G = new double[MAX_WIDTH * MAX_HEIGHT], pd160_B = new double[MAX_WIDTH * MAX_HEIGHT], pd192_R = new double[MAX_WIDTH * MAX_HEIGHT], pd192_G = new double[MAX_WIDTH * MAX_HEIGHT], pd192_B = new double[MAX_WIDTH * MAX_HEIGHT], pd224_R = new double[MAX_WIDTH * MAX_HEIGHT], pd224_G = new double[MAX_WIDTH * MAX_HEIGHT], pd224_B = new double[MAX_WIDTH * MAX_HEIGHT], pucBmpSrc = new byte[MAX_WIDTH * MAX_HEIGHT * 3], pucDllCtrl = new byte[DEMURA_CFG_SIZE], }; dataBuf = new DataBuf() { pdBuf0_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf1_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf2_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf3_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf4_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf5_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf6_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf7_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf8_R = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf0_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf1_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf2_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf3_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf4_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf5_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf6_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf7_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf8_G = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf0_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf1_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf2_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf3_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf4_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf5_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf6_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf7_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf8_B = new double[MAX_WIDTH * MAX_HEIGHT], pdBuf9 = new double[MAX_WIDTH * MAX_HEIGHT], }; compDataResult = new CompDataResult() { pucCompData = new byte[MAX_WIDTH * MAX_HEIGHT * 3], pucFlhCompData = new byte[MAX_FLASH_SIZE_QHD], }; #region path string str_exe_directory_path = Environment.CurrentDirectory + "\\"; string str_cfg_file_full_path = str_exe_directory_path + "DMR_CFG_GVO_720_2160.rad"; string str_capras_032_R_file_full_path = str_exe_directory_path + "Red32.csv"; string str_capras_032_G_file_full_path = str_exe_directory_path + "Green32.csv"; string str_capras_032_B_file_full_path = str_exe_directory_path + "Blue32.csv"; string str_capras_064_R_file_full_path = str_exe_directory_path + "Red64.csv"; string str_capras_064_G_file_full_path = str_exe_directory_path + "Green64.csv"; string str_capras_064_B_file_full_path = str_exe_directory_path + "Blue64.csv"; string str_capras_096_R_file_full_path = str_exe_directory_path + "Red96.csv"; string str_capras_096_G_file_full_path = str_exe_directory_path + "Green96.csv"; string str_capras_096_B_file_full_path = str_exe_directory_path + "Blue96.csv"; string str_capras_160_R_file_full_path = str_exe_directory_path + "Red160.csv"; string str_capras_160_G_file_full_path = str_exe_directory_path + "Green160.csv"; string str_capras_160_B_file_full_path = str_exe_directory_path + "Blue160.csv"; string str_capras_192_R_file_full_path = str_exe_directory_path + "Red192.csv"; string str_capras_192_G_file_full_path = str_exe_directory_path + "Green192.csv"; string str_capras_192_B_file_full_path = str_exe_directory_path + "Blue192.csv"; string str_capras_224_R_file_full_path = str_exe_directory_path + "Red224.csv"; string str_capras_224_G_file_full_path = str_exe_directory_path + "Green224.csv"; string str_capras_224_B_file_full_path = str_exe_directory_path + "Blue224.csv"; string str_flash_file_full_path = str_exe_directory_path + "DemuraFlash.txt"; using (var file = new FileStream(str_cfg_file_full_path, FileMode.Open, FileAccess.Read)) { file.Read(colorDataSrc.pucDllCtrl, 0, DEMURA_CFG_SIZE); } funcFileProc(colorDataSrc.pd032_R, str_capras_032_R_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd032_G, str_capras_032_G_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd032_B, str_capras_032_B_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd064_R, str_capras_064_R_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd064_G, str_capras_064_G_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd064_B, str_capras_064_B_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd096_R, str_capras_096_R_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd096_G, str_capras_096_G_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd096_B, str_capras_096_B_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd160_R, str_capras_160_R_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd160_G, str_capras_160_G_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd160_B, str_capras_160_B_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd192_R, str_capras_192_R_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd192_G, str_capras_192_G_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd192_B, str_capras_192_B_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd224_R, str_capras_224_R_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd224_G, str_capras_224_G_file_full_path, 2160, 720, -1, 0); funcFileProc(colorDataSrc.pd224_B, str_capras_224_B_file_full_path, 2160, 720, -1, 0); #endregion IntPtr dataSrcPtr = Marshal.AllocHGlobal(Marshal.SizeOf(colorDataSrc)); Marshal.StructureToPtr(colorDataSrc, dataSrcPtr, false); IntPtr dataBufPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataBuf)); Marshal.StructureToPtr(dataBuf, dataBufPtr, false); IntPtr dataResultPtr = Marshal.AllocHGlobal(Marshal.SizeOf(compDataResult)); Marshal.StructureToPtr(compDataResult, dataResultPtr, false); RadFunc radFunc = (RadFunc)dllInvoke.Invoke("RadFunc", typeof(RadFunc)); var ret = radFunc(dataSrcPtr, dataBufPtr, dataResultPtr); if (ret == 0) { compDataResult = (CompDataResult)Marshal.PtrToStructure(dataResultPtr, typeof(CompDataResult)); using (var fileStream = File.Open(str_flash_file_full_path, FileMode.OpenOrCreate, FileAccess.Write)) { int DMRpatter_start = 256; int compensate_crc = 2; int flash_full_chksum = 2; int write_size = 720 * 2160 * 3 * 3 / 8 + DMRpatter_start + compensate_crc + flash_full_chksum; fileStream.Write(compDataResult.pucFlhCompData, 0, write_size); } } this.button1.Enabled = true; }
private static void ProcessSlice(StartOfImage startOfImage, int slice, int samples, BitmapData data) { var startOfFrame = startOfImage.StartOfFrame; var table0 = startOfImage.HuffmanTable.Tables[0x00]; var table1 = startOfImage.HuffmanTable.Tables[0x01]; var lastRow = new DataBuf { Y = 0x0000 }; // 0x4000 for (var line = 0; line < startOfFrame.ScanLines; line += 2) // 0..2592 { // 6 bytes * 8 bits == 48 bits per pixel // 2 = 6 bytes * samplesPerLine / (slices[0] * slices[1] + slices[2]); var scan0 = data.Scan0 + data.Stride * line + slice * samples * 2; var scan1 = data.Scan0 + data.Stride * (line + 1) + slice * samples * 2; // read six shorts, for four pixels for (var col = 0; col < samples / 6; col++) // 0..1296 { cc += 6; var diff = new DiffBuf { Y1 = startOfImage.ProcessColor(0x00), Y2 = startOfImage.ProcessColor(0x00), Y3 = startOfImage.ProcessColor(0x00), Y4 = startOfImage.ProcessColor(0x00), Cb = startOfImage.ProcessColor(0x01), Cr = startOfImage.ProcessColor(0x01), }; var pixel0 = new DataBuf { Y = (ushort)(lastRow.Y + diff.Y1), Cb = (short)(lastRow.Cb + diff.Cb), Cr = (short)(lastRow.Cr + diff.Cr) }; var pixel1 = new DataBuf { Y = (ushort)(lastRow.Y + diff.Y1 + diff.Y2), Cb = (short)(lastRow.Cb + diff.Cb), Cr = (short)(lastRow.Cr + diff.Cr) }; var pixel2 = new DataBuf { Y = (ushort)(lastRow.Y + diff.Y1 + diff.Y2 + diff.Y3), Cb = (short)(lastRow.Cb + diff.Cb), Cr = (short)(lastRow.Cr + diff.Cr) }; var pixel3 = new DataBuf { Y = (ushort)(lastRow.Y + diff.Y1 + diff.Y2 + diff.Y3 + diff.Y4), Cb = (short)(lastRow.Cb + diff.Cb), Cr = (short)(lastRow.Cr + diff.Cr) }; PokePixels(scan0, scan1, col, pixel0, pixel1, pixel2, pixel3); } } }