예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
 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;
                    }
                }
            }
        }