Пример #1
0
        private static void WriteToFile(int width, int height, IEnumerable <int[][]> yBlocks, IEnumerable <int[][]> cbBlocks, IEnumerable <int[][]> crBlocks,
                                        string subsamplingType, QuantizingType quantizingType, int alphaY, int gammaY, int alphaC, int gammaC, int nY, int nC)
        {
            //*** saving to file
            // format: height, width, number of yblocks, yblocks, number of cbBlocks, cbBlocks, number of crBlocks, crBlocks,
            //         subsampling type,
            //         quantizing type
            //         Ny Nc
            //         alpha gamma
            var filename = "test.myjpg";

            using (var writer = new BinaryWriter(File.Open(string.Format(filename), FileMode.Create)))
            {
                writer.Write(height);
                writer.Write(width);
                writer.Write(yBlocks.Count());
                foreach (var block in yBlocks.Select(x => x.ToZigZagArray(8)))
                {
                    block.ForEach(x => writer.Write(x));
                }
                writer.Write(cbBlocks.Count());
                foreach (var block in cbBlocks.Select(x => x.ToZigZagArray(8)))
                {
                    block.ForEach(x => writer.Write(x));
                }
                writer.Write(crBlocks.Count());
                foreach (var block in crBlocks.Select(x => x.ToZigZagArray(8)))
                {
                    block.ForEach(x => writer.Write(x));
                }
                writer.Write(getSubsamplingCodeByType[subsamplingType]);
                writer.Write(getQuantizingCodeByType[quantizingType]);
                writer.Write(nY);
                writer.Write(nC);
                writer.Write(alphaY);
                writer.Write(gammaY);
                writer.Write(alphaC);
                writer.Write(gammaC);
            }
            Zip7(filename);
        }
Пример #2
0
        public static BitmapSource JpegSteps(Image image, int size, string downsamplingType, QuantizingType quantizingType,
                                             int alphaY, int gammaY, int alphaC, int gammaC, int remainingCountY, int remainingCountC)
        {
            var source = ((BitmapSource)image.Source);
            var ycbcr  = MainWindow.ToYCbCr(source);

            var compY  = new byte[size * size];
            var compCb = new byte[size * size];
            var compCr = new byte[size * size];

            for (var i = 0; i < size * size * 4; i += 4)
            {
                compY[i / 4]  = ycbcr[i];
                compCb[i / 4] = ycbcr[i + 1];
                compCr[i / 4] = ycbcr[i + 2];
            }

            //*** Downsampling
            var matrixY  = ToMatrix(compY, size);
            var matrixCb = Downsampling(ToMatrix(compCb, size), size, downsamplingType);
            var matrixCr = Downsampling(ToMatrix(compCr, size), size, downsamplingType);

            //*** Splitting to blocks 8x8 and DCT
            var dct      = new DiscreteCosineTransformator();
            var hSize    = size / getHorSizeLossByType[downsamplingType];
            var vSize    = size / getVertSizeLossByType[downsamplingType];
            var yBlocks  = SplitTo8x8Matrices(matrixY, size, size).Select(dct.DCT).ToList();
            var cbBlocks = SplitTo8x8Matrices(matrixCb, hSize, vSize).Select(dct.DCT).ToList();
            var crBlocks = SplitTo8x8Matrices(matrixCr, hSize, vSize).Select(dct.DCT).ToList();

            //*** Quantizing
            var quantizorY = new JpegQuantisor(alphaY, gammaY);
            var quantizorC = new JpegQuantisor(alphaC, gammaC);

            switch (quantizingType)
            {
            case QuantizingType.Nullify:
                yBlocks  = yBlocks.Select(x => quantizorY.SimpleQuantizing(x, remainingCountY)).ToList();
                cbBlocks = cbBlocks.Select(x => quantizorC.SimpleQuantizing(x, remainingCountC)).ToList();
                crBlocks = crBlocks.Select(x => quantizorC.SimpleQuantizing(x, remainingCountC)).ToList();
                break;

            case QuantizingType.AlphaGamma:
                yBlocks  = yBlocks.Select(quantizorY.QQuantizing).ToList();
                cbBlocks = cbBlocks.Select(quantizorC.QQuantizing).ToList();
                crBlocks = crBlocks.Select(quantizorC.QQuantizing).ToList();
                break;

            default:
                yBlocks  = yBlocks.Select(x => quantizorY.QuantizingRecommended(x, "Y")).ToList();
                cbBlocks = cbBlocks.Select(x => quantizorC.QuantizingRecommended(x, "Cb")).ToList();
                crBlocks = crBlocks.Select(x => quantizorC.QuantizingRecommended(x, "Cr")).ToList();
                break;
            }

            //*** saving to file

            WriteToFile(size, size, yBlocks, cbBlocks, crBlocks, downsamplingType, quantizingType, alphaY, gammaY, alphaC, gammaC, remainingCountY, remainingCountC);

            //*** back steps:

            //*** back quantizing
            switch (quantizingType)
            {
            case QuantizingType.Nullify:
                break;

            case QuantizingType.AlphaGamma:
                yBlocks  = yBlocks.Select(quantizorY.BackQQuantizing).ToList();
                cbBlocks = cbBlocks.Select(quantizorC.BackQQuantizing).ToList();
                crBlocks = crBlocks.Select(quantizorC.BackQQuantizing).ToList();
                break;

            default:
                yBlocks  = yBlocks.Select(x => quantizorY.BackQuantizingRecommended(x, "Y")).ToList();
                cbBlocks = cbBlocks.Select(x => quantizorC.BackQuantizingRecommended(x, "Cb")).ToList();
                crBlocks = crBlocks.Select(x => quantizorC.BackQuantizingRecommended(x, "Cr")).ToList();
                break;
            }

            //*** back DCT
            yBlocks  = yBlocks.Select(dct.InverseDCT).ToList();
            cbBlocks = cbBlocks.Select(dct.InverseDCT).ToList();
            crBlocks = crBlocks.Select(dct.InverseDCT).ToList();

            //*** back to whole matrix

            var backY  = Matrices8x8ToOne(yBlocks.ToList(), size, size);
            var backCb = Matrices8x8ToOne(cbBlocks.ToList(), hSize, vSize);
            var backCr = Matrices8x8ToOne(crBlocks.ToList(), hSize, vSize);

            //*** back downsampling
            backCb = BackDownsampling(backCb, size, downsamplingType);
            backCr = BackDownsampling(backCr, size, downsamplingType);

            compY  = MatrixToPixels(backY, size);
            compCb = MatrixToPixels(backCb, size);
            compCr = MatrixToPixels(backCr, size);

            var pixels = new byte[size * size * 4];

            for (var i = 0; i < size * size * 4; i += 4)
            {
                pixels[i]     = compY[i / 4];
                pixels[i + 1] = compCb[i / 4];
                pixels[i + 2] = compCr[i / 4];
            }

            return(MainWindow.ToRGB(pixels, source));
        }