private static Matrix Uncompress(CompressedImage image) { var result = new Matrix(image.Height, image.Width); using (var allQuantizedBytes = new MemoryStream(HuffmanCodec.Decode(image.CompressedBytes, image.DecodeTable, image.BitsCount))) { for (var y = 0; y < image.Height; y += DctSize) { for (var x = 0; x < image.Width; x += DctSize) { var _y = new double[DctSize, DctSize]; var cb = new double[DctSize, DctSize]; var cr = new double[DctSize, DctSize]; foreach (var channel in new [] { _y, cb, cr }) { var quantizedBytes = new byte[DctSize * DctSize]; allQuantizedBytes.ReadAsync(quantizedBytes, 0, quantizedBytes.Length).Wait(); var quantizedFreqs = ZigZagUnScan(quantizedBytes); var channelFreqs = DeQuantize(quantizedFreqs); FastDct.InverseDct(channelFreqs, channel); ShiftMatrixValues(channel, 128); } SetPixels(result, _y, cb, cr, y, x); } } } return(result); }
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 }); }