private static void Encode(Options options) { var compressionLevel = CalcCompressionLevel(options); var compressedFileName = options.PathToBmp + ".compressed." + options.DCTSize + "." + compressionLevel; var bmp = (Bitmap)Image.FromFile(options.PathToBmp); CheckCorrectSize(options, bmp); var grayscaleMatrix = bmp.ToGrayscaleMatrix(); var compressedImage = grayscaleMatrix.ParallelCompressWithDCT(options); var bytesForHuffman = compressedImage.ToBytesArray(); var decodeTable = null as Dictionary <BitsWithLength, byte>; var encodedWithHuffman = HuffmanCodec.Encode(bytesForHuffman, out decodeTable, options); using (FileStream fs = File.OpenWrite(compressedFileName)) { var encodedDataLength = BitConverter.GetBytes(encodedWithHuffman.Length); fs.Write(encodedDataLength, 0, 4); fs.Write(encodedWithHuffman, 0, encodedWithHuffman.Length); var serializedTable = SerializeDecodeTable(decodeTable); fs.Write(serializedTable, 0, serializedTable.Length); } }
public static CompressedImage Compress(Matrix matrix, int quality = 50) { var allQuantizedBytes = new byte[matrix.Height * matrix.Width * 6]; var comps = new[] { Component.y, Component.cb, Component.cr }; var qm = GetQuantizationMatrix(quality); Parallel.For(0, matrix.Height / 8, i => { var y = i * 8; for (var x = 0; x < matrix.Width; x += DCTSize) { for (var index = 0; index < 3; index++) { var subMatrix = GetSubMatrix(matrix, y, DCTSize, x, DCTSize, comps[index]); ShiftMatrixValues(subMatrix, -128); var channelFreqs = DCT.DCT2D(subMatrix); var quantizedFreqs = Quantize(channelFreqs, qm); var quantizedBytes = ZigZagScan(quantizedFreqs); quantizedBytes.CopyTo(allQuantizedBytes, ((3 * x / 8 + (y / 8) * 3 * (matrix.Width / 8)) + index) * quantizedBytes.Length); } } }); long bitsCount; Dictionary <BitsWithLength, byte> decodeTable; var compressedBytes = HuffmanCodec.Encode(allQuantizedBytes, out decodeTable, out bitsCount); return(new CompressedImage { Quality = quality, CompressedBytes = compressedBytes, BitsCount = bitsCount, DecodeTable = decodeTable, Height = matrix.Height, Width = matrix.Width }); }
private static CompressedImage Compress(Matrix matrix, int quality = 50) { var allQuantizedBytes = new List <byte>(); for (var y = 0; y < matrix.Height; y += DCTSize) { for (var x = 0; x < matrix.Width; x += DCTSize) { foreach (var selector in new Func <Pixel, double>[] { p => p.Y, p => p.Cb, p => p.Cr }) { var subMatrix = GetSubMatrix(matrix, y, DCTSize, x, DCTSize, selector); ShiftMatrixValues(subMatrix, -128); var channelFreqs = DCT.DCT2D(subMatrix); var quantizedFreqs = Quantize(channelFreqs, quality); var quantizedBytes = ZigZagScan(quantizedFreqs); allQuantizedBytes.AddRange(quantizedBytes); } } } long bitsCount; Dictionary <BitsWithLength, byte> decodeTable; var compressedBytes = HuffmanCodec.Encode(allQuantizedBytes, out decodeTable, out bitsCount); return(new CompressedImage { Quality = quality, CompressedBytes = compressedBytes, BitsCount = bitsCount, DecodeTable = decodeTable, Height = matrix.Height, Width = matrix.Width }); }
private static CompressedImage Compress(Matrix matrix, int quality = 50) { var allQuantizedBytes = new byte[matrix.Height * matrix.Width * 3]; Parallel.ForEach(Enumerable.Range(0, matrix.Height / DCTSize).Select(y => y * DCTSize), y => { for (var x = 0; x < matrix.Width; x += DCTSize) { var i = 0; foreach (var selector in new Func <Pixel, double>[] { p => p.Y, p => p.Cb, p => p.Cr }) { var subMatrix = GetSubMatrix(matrix, y, DCTSize, x, DCTSize, selector); ShiftMatrixValues(subMatrix, -128); DCT.DCT2D(subMatrix); var quantizedFreqs = Quantize(subMatrix, quality); var quantizedBytes = ZigZagScan(quantizedFreqs); for (var j = 0; j < quantizedBytes.Length; j++) { allQuantizedBytes[(x * 8 + y * matrix.Width) * 3 + 64 * i + j] = quantizedBytes[j]; } i++; i %= 3; } } }); var compressedBytes = HuffmanCodec.Encode(allQuantizedBytes, out var decodeTable, out var bitsCount); return(new CompressedImage { Quality = quality, CompressedBytes = compressedBytes, BitsCount = bitsCount, DecodeTable = decodeTable, Height = matrix.Height, Width = matrix.Width, RealHeight = matrix.RealHeight, RealWidth = matrix.RealWidth }); }
private static CompressedImage Compress(CbCrImage cbCrImage, int quality = 50) { var allQuantizedBytes = new byte[(cbCrImage.Height - cbCrImage.Height % 8) * (cbCrImage.Width - cbCrImage.Width % 8) * 3]; var shiftFunc = new Func <double, double>(x => x - 128); var DCTcoefficients = DCT.GetCoefficientsMatrix(DCTSize, DCTSize); var transponseDCTcoefficients = DCT.Transpose(DCTcoefficients); var quantizationMatrix = GetQuantizationMatrix(quality); var channels = new List <double[, ]> { cbCrImage.y, cbCrImage.Cb, cbCrImage.Cr }; Parallel.For(0, cbCrImage.Height / DCTSize, y => { var y1 = y; Parallel.For(0, cbCrImage.Width / DCTSize, _x => { var x = _x; Parallel.For(0, channels.Count, _k => { var k = _k; var subMatrix = GetSubMatrix(channels[k], y1 * DCTSize, DCTSize, x * DCTSize, DCTSize, shiftFunc); var channelFreqs = DCT.DCT2D(subMatrix, DCTcoefficients, transponseDCTcoefficients); var quantizedFreqs = Quantize(channelFreqs, quantizationMatrix); var quantizedBytes = ZigZagScan(quantizedFreqs); var index = (y1 * (cbCrImage.Width / DCTSize) + x) * DCTSize * DCTSize * 3 + DCTSize * DCTSize * k; for (var i = 0; i < quantizedBytes.Count; i++) { allQuantizedBytes[index + i] = quantizedBytes[i]; } }); }); }); long bitsCount; Dictionary <BitsWithLength, byte> decodeTable; var compressedBytes = HuffmanCodec.Encode(allQuantizedBytes, out decodeTable, out bitsCount); return(new CompressedImage { Quality = quality, CompressedBytes = compressedBytes, BitsCount = bitsCount, DecodeTable = decodeTable, Height = cbCrImage.Height, Width = cbCrImage.Width }); }
private static CompressedImage Compress(Matrix matrix) { var allQuantizedBytes = new byte[matrix.Height * matrix.Width * 3]; Parallel.For(0, matrix.Height / DctSize, h => { Parallel.For(0, matrix.Width / DctSize, w => { var counter = 0; foreach (var selector in new Func <Pixel, double>[] { p => 16.0 + (65.738 * p.C1 + 129.057 * p.C2 + 24.064 * p.C3) / 256.0, p => 128.0 + (-37.945 * p.C1 - 74.494 * p.C2 + 112.439 * p.C3) / 256.0, p => 128.0 + (112.439 * p.C1 - 94.154 * p.C2 - 18.285 * p.C3) / 256.0 }) { var subMatrix = GetSubMatrix(matrix, h * DctSize, DctSize, w * DctSize, DctSize, selector); ShiftMatrixValues(subMatrix, -128); var channelFreqs = FastDct.Dct(subMatrix); var quantizedFreqs = Quantize(channelFreqs); var quantizedBytes = ZigZagScan(quantizedFreqs); Array.Copy(quantizedBytes, 0, allQuantizedBytes, h * 8 * matrix.Width * 3 + w * 64 * 3 + 64 * counter++, 64); } }); }); var compressedBytes = HuffmanCodec.Encode(allQuantizedBytes, out var decodeTable, out var bitsCount); return(new CompressedImage { Quality = CompressionQuality, CompressedBytes = compressedBytes, BitsCount = bitsCount, DecodeTable = decodeTable, Height = matrix.Height, Width = matrix.Width }); }
private static CompressedImage Compress(Matrix matrix, int quality = 50) { var tuples = new List <(int, int)>(); for (var y = 0; y < matrix.Height; y += DCTSize) { for (var x = 0; x < matrix.Width; x += DCTSize) { tuples.Add((x, y)); } } var allQuantizedBytes = new List <byte> [tuples.Count]; // MathEx.LoopByTwoVariablesStepped(0, matrix.Height, 0, matrix.Width, DCTSize, (y, x) => Parallel.For(0, tuples.Count, i => { var(x, y) = tuples[i]; allQuantizedBytes[i] = new List <byte>(); foreach (var selector in new Func <Pixel, double>[] { p => p.Y, p => p.Cb, p => p.Cr }) { var subMatrix = GetSubMatrix(matrix, y, DCTSize, x, DCTSize, selector); ShiftMatrixValues(subMatrix, -128); var channelFreqs = DCT.DCT2D(subMatrix); var quantizedFreqs = Quantize(channelFreqs, quality); var quantizedBytes = ZigZagScan(quantizedFreqs); // allQuantizedBytes.Add(quantizedBytes); allQuantizedBytes[i].AddRange(quantizedBytes); } }); var compressedBytes = HuffmanCodec.Encode(allQuantizedBytes.SelectMany(i => i), out var decodeTable, out var bitsCount); return(new CompressedImage { Quality = quality, CompressedBytes = compressedBytes, BitsCount = bitsCount, DecodeTable = decodeTable, Height = matrix.Height, Width = matrix.Width }); }
private CompressedImage Compress(Matrix matrix, int quality = 50) { var heigth = matrix.Height / DCTSize; var width = matrix.Width / DCTSize; var quantinizedMatrix = new List <byte> [heigth, width]; var channelSelectors = new Func <Pixel, double>[] { p => p.Y, p => p.Cb, p => p.Cr }; var dct = new DCT(DCTSize); Parallel.For(0, heigth, h => { Parallel.For(0, width, w => { quantinizedMatrix[h, w] = new List <byte>(); foreach (var selector in channelSelectors) { var subMatrix = matrix.GetSubMatrix(h * DCTSize, DCTSize, w * DCTSize, DCTSize, selector); subMatrix.ShiftValues(-128); var channelFreqs = dct.DCT2D(subMatrix); var quantizedFreqs = Quantize(channelFreqs); var quantizedBytes = ZigZagScan(quantizedFreqs); quantinizedMatrix[h, w].AddRange(quantizedBytes); } }); }); var bytes = quantinizedMatrix.Join(); var compressedBytes = HuffmanCodec.Encode(bytes, out var decodeTable, out var bitsCount); return(new CompressedImage { Quality = quality, CompressedBytes = compressedBytes, BitsCount = bitsCount, DecodeTable = decodeTable, Height = matrix.Height, Width = matrix.Width }); }