public void DCT_Insertion_Test() { var bmap = new Bitmap(inputImagePath); double[] pixelArray = getPixelArray(bmap); IDCT dct = DCT.CreateParallelDCT(); double[] forward = dct.Forward(pixelArray); double[] signal = Enumerable.Repeat(0d, 5000).ToArray(); signal[3000] = 750; var insert_point = 30000; var fSignal = dct.Forward(signal); for (int i = insert_point; i < insert_point + fSignal.Length; i++) { forward[i] += fSignal[i - insert_point]; } var output = setPixelMatrix(bmap, dct.Backward(forward)); output.Save(outputImagePath); }
public void DCT_Back_Fort_Test() { var bmap = new Bitmap(inputImagePath); double[] pixelArray = getPixelArray(bmap); IDCT dct = DCT.CreateParallelDCT(); var output = setPixelMatrix(bmap, dct.Backward(dct.Forward(pixelArray))); output.Save(outputImagePath); }
public void DCT_detection_Test() { var bmap = new Bitmap(inputImagePath); double[] pixelArray = getPixelArray(bmap); IDCT dct = DCT.CreateParallelDCT(); double[] forward = dct.Forward(pixelArray); const int signalSize = 5000; double[] signal = Enumerable.Repeat(0d, signalSize).ToArray(); signal[3000] = 750; var insert_point = 30000; var fSignal = dct.Forward(signal); for (int i = insert_point; i < insert_point + fSignal.Length; i++) { forward[i] += fSignal[i - insert_point]; } var output = setPixelMatrix(bmap, dct.Backward(forward)); output.Save(outputImagePath); var bmapMarked = new Bitmap(outputImagePath); var forwardedMarked = dct.Forward(getPixelArray(bmapMarked)); double[] extractedSignal = Enumerable.Repeat(0d, signalSize).ToArray(); for (int i = insert_point; i < insert_point + fSignal.Length; i++) { extractedSignal[i - insert_point] = Math.Abs(forward[i] - forwardedMarked[i]); } var bacwardextractedSignal = dct.Backward(extractedSignal); var mean = bacwardextractedSignal.Sum() / bacwardextractedSignal.Length; Console.WriteLine(mean); }
public JpegEncoder(IPixelMapper pixelMapper, IDCT dct) { this.pixelMapper = pixelMapper; this.dct = dct; }
/// <summary> /// Setups the specified segments. /// </summary> /// <param name="segments">The segments.</param> /// <exception cref="System.Exception"> /// missing SOF marker or SOS has wrong length or SOS length inconsistent with number of /// components or Unknown component selector or Repeated component selector or bad Td value /// or bad Ta value or Total sampling factors too large. or bad spectral selection bounds or /// progressive AC coefficients for more than one component or bad successive approximation /// values or Excessive DC component or Too many components or Too many components or Bad RST marker /// </exception> public override void Setup(IEnumerable <SegmentBase> segments) { Length = GetLength(Bytes); var n = Length; var StartOfFrameSegment = segments.OfType <StartOfFrame>().FirstOrDefault(); var DefineHuffmanTableSegment = segments.OfType <DefineHuffmanTable>().FirstOrDefault(); var DefineRestartIntervalSegment = segments.OfType <DefineRestartInterval>().FirstOrDefault() ?? new DefineRestartInterval(null); var DefineQuantizationTableSegment = segments.OfType <DefineQuantizationTable>().FirstOrDefault(); if (StartOfFrameSegment == null) { throw new Exception("missing SOF marker"); } if (n < 6 || 4 + (2 * (int)StartOfFrameSegment.TypeOfImage) < n || n % 2 != 0) { throw new Exception("SOS has wrong length"); } Bytes.ReadFull(TempData, 0, n); byte lnComp = TempData[0]; if (n != 4 + 2 * lnComp) { throw new Exception("SOS length inconsistent with number of components"); } Scan[] scan = new Scan[MAXIMUM_NUMBER_COMPONENTS]; int totalHV = 0; for (int i = 0; i < lnComp; i++) { int cs = TempData[1 + (2 * i)]; int compIndex = -1; for (int j = 0; j < (int)StartOfFrameSegment.TypeOfImage; j++) { Component compv = StartOfFrameSegment.Components[j]; if (cs == compv.ComponentIdentifier) { compIndex = j; } } if (compIndex < 0) { throw new Exception("Unknown component selector"); } scan[i].ComponentIndex = (byte)compIndex; for (int j = 0; j < i; j++) { if (scan[i].ComponentIndex == scan[j].ComponentIndex) { throw new Exception("Repeated component selector"); } } totalHV += StartOfFrameSegment.Components[compIndex].HorizontalSamplingFactor * StartOfFrameSegment.Components[compIndex].VerticalSamplingFactor; scan[i].Td = (byte)(TempData[2 + (2 * i)] >> 4); if (scan[i].Td > MAXIMUM_TH) { throw new Exception("bad Td value"); } scan[i].Ta = (byte)(TempData[2 + (2 * i)] & 0x0f); if (scan[i].Ta > MAXIMUM_TH) { throw new Exception("bad Ta value"); } } if (StartOfFrameSegment.TypeOfImage != ImageType.GreyScale && totalHV > 10) { throw new Exception("Total sampling factors too large."); } int zigStart = 0; int zigEnd = Block.BlockSize - 1; int ah = 0; int al = 0; if (StartOfFrameSegment.Progressive) { zigStart = (int)TempData[1 + (2 * lnComp)]; zigEnd = (int)TempData[2 + (2 * lnComp)]; ah = (int)(TempData[3 + (2 * lnComp)] >> 4); al = (int)(TempData[3 + (2 * lnComp)] & 0x0f); if ((zigStart == 0 && zigEnd != 0) || zigStart > zigEnd || zigEnd >= Block.BlockSize) { throw new Exception("bad spectral selection bounds"); } if (zigStart != 0 && lnComp != 1) { throw new Exception("progressive AC coefficients for more than one component"); } if (ah != 0 && ah != al + 1) { throw new Exception("bad successive approximation values"); } } int h0 = StartOfFrameSegment.Components[0].HorizontalSamplingFactor; int v0 = StartOfFrameSegment.Components[0].VerticalSamplingFactor; int mxx = (StartOfFrameSegment.Width + (8 * h0) - 1) / (8 * h0); int myy = (StartOfFrameSegment.Height + (8 * v0) - 1) / (8 * v0); if (img1 == null && img3 == null) { makeImg(mxx, myy, StartOfFrameSegment); } if (StartOfFrameSegment.Progressive) { for (int i = 0; i < lnComp; i++) { int compIndex = scan[i].ComponentIndex; if (ProgressiveCoefficients[compIndex] == null) { ProgressiveCoefficients[compIndex] = new Block[mxx * myy * StartOfFrameSegment.Components[compIndex].HorizontalSamplingFactor * StartOfFrameSegment.Components[compIndex].VerticalSamplingFactor]; for (int j = 0; j < ProgressiveCoefficients[compIndex].Length; j++) { ProgressiveCoefficients[compIndex][j] = new Block(); } } } } Bytes.Bits = new BitsBuffer(); int mcu = 0; byte expectedRST = SegmentTypes.Restart0; var b = new Block(); int[] dc = new int[MAXIMUM_NUMBER_COMPONENTS]; int bx, by, blockCount = 0; for (int my = 0; my < myy; my++) { for (int mx = 0; mx < mxx; mx++) { for (int i = 0; i < lnComp; i++) { int compIndex = scan[i].ComponentIndex; int hi = StartOfFrameSegment.Components[compIndex].HorizontalSamplingFactor; int vi = StartOfFrameSegment.Components[compIndex].VerticalSamplingFactor; Block qt = DefineQuantizationTableSegment.quant[StartOfFrameSegment.Components[compIndex].QuatizationTableDestSelector]; for (int j = 0; j < hi * vi; j++) { if (lnComp != 1) { bx = hi * mx + j % hi; by = vi * my + j / hi; } else { int q = mxx * hi; bx = blockCount % q; by = blockCount / q; blockCount++; if (bx * 8 >= StartOfFrameSegment.Width || by * 8 >= StartOfFrameSegment.Height) { continue; } } if (StartOfFrameSegment.Progressive) { b = ProgressiveCoefficients[compIndex][by * mxx * hi + bx]; } else { b = new Block(); } if (ah != 0) { refine(b, DefineHuffmanTableSegment.HuffmanCodes[acTable, scan[i].Ta], zigStart, zigEnd, 1 << al); } else { int zig = zigStart; if (zig == 0) { zig++; var value = DefineHuffmanTableSegment.HuffmanCodes[dcTable, scan[i].Td].DecodeHuffman(Bytes); if (value > 16) { throw new Exception("Excessive DC component"); } var dcDelta = Bytes.receiveExtend(value); dc[compIndex] += dcDelta; b[0] = dc[compIndex] << al; } if (zig <= zigEnd && EndOfBlockRun > 0) { EndOfBlockRun--; } else { var huffv = DefineHuffmanTableSegment.HuffmanCodes[acTable, scan[i].Ta]; for (; zig <= zigEnd; zig++) { var value = huffv.DecodeHuffman(Bytes); var val0 = (byte)(value >> 4); var val1 = (byte)(value & 0x0f); if (val1 != 0) { zig += val0; if (zig > zigEnd) { break; } var ac = Bytes.receiveExtend(val1); b[unzig[zig]] = ac << al; } else { if (val0 != 0x0f) { EndOfBlockRun = (ushort)(1 << val0); if (val0 != 0) { EndOfBlockRun |= (ushort)Bytes.DecodeBits(val0); } EndOfBlockRun--; break; } zig += 0x0f; } } } } if (StartOfFrameSegment.Progressive) { if (zigEnd != Block.BlockSize - 1 || al != 0) { ProgressiveCoefficients[compIndex][by * mxx * hi + bx] = b; continue; } } for (int zig = 0; zig < Block.BlockSize; zig++) { b[unzig[zig]] *= qt[zig]; } IDCT.Transform(b); byte[] dst = null; int offset = 0; int stride = 0; if (StartOfFrameSegment.TypeOfImage == ImageType.GreyScale) { dst = img1.Pixels; stride = img1.Stride; offset = img1.Offset + 8 * (by * img1.Stride + bx); } else { switch (compIndex) { case 0: dst = img3.YPixels; stride = img3.YStride; offset = img3.YOffset + 8 * (by * img3.YStride + bx); break; case 1: dst = img3.CBPixels; stride = img3.CStride; offset = img3.COffset + 8 * (by * img3.CStride + bx); break; case 2: dst = img3.CRPixels; stride = img3.CStride; offset = img3.COffset + 8 * (by * img3.CStride + bx); break; case 3: throw new Exception("Too many components"); default: throw new Exception("Too many components"); } } for (int y = 0; y < 8; y++) { int y8 = y * 8; int yStride = y * stride; for (int x = 0; x < 8; x++) { int c = b[y8 + x]; if (c < -128) { c = 0; } else if (c > 127) { c = 255; } else { c += 128; } dst[yStride + x + offset] = (byte)c; } } } } mcu++; if (DefineRestartIntervalSegment.RestartInterval > 0 && mcu % DefineRestartIntervalSegment.RestartInterval == 0 && mcu < mxx * myy) { Bytes.ReadFull(TempData, 0, 2); if (TempData[0] != 0xff || TempData[1] != expectedRST) { throw new Exception("Bad RST marker"); } expectedRST++; if (expectedRST == SegmentTypes.Restart7 + 1) { expectedRST = SegmentTypes.Restart0; } Bytes.Bits = new BitsBuffer(); dc = new int[MAXIMUM_NUMBER_COMPONENTS]; EndOfBlockRun = 0; } } } }