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); }
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)); }