Beispiel #1
0
 private static void SetPixels(CbCrImage cbCrImage, double[,] a, double[,] b, double[,] c, int yOffset, int xOffset, int shiftValue)
 {
     for (var y = 0; y < a.GetLength(0); y++)
     {
         for (var x = 0; x < a.GetLength(1); x++)
         {
             cbCrImage.y[yOffset + y, xOffset + x]  = a[y, x] + shiftValue;
             cbCrImage.Cb[yOffset + y, xOffset + x] = b[y, x] + shiftValue;
             cbCrImage.Cr[yOffset + y, xOffset + x] = c[y, x] + shiftValue;
         }
     }
 }
Beispiel #2
0
        private static CbCrImage Uncompress(CompressedImage image)
        {
            var result                    = new CbCrImage(image.Height, image.Width);
            var DCTcoefficients           = DCT.GetCoefficientsMatrix(DCTSize, DCTSize);
            var transponseDCTcoefficients = DCT.Transpose(DCTcoefficients);
            var quantizationMatrix        = GetQuantizationMatrix(image.Quality);

            using (var allQuantizedBytes =
                       new MemoryStream(HuffmanCodec.Decode(image.CompressedBytes, image.DecodeTable, image.BitsCount)))
            {
                Parallel.For(0, image.Height / DCTSize, ky =>
                {
                    var y = ky;
                    Parallel.For(0, image.Width / DCTSize, _x =>
                    {
                        var x  = _x;
                        var _y = new double[DCTSize, DCTSize];
                        var cb = new double[DCTSize, DCTSize];
                        var cr = new double[DCTSize, DCTSize];
                        var c  = 0;
                        foreach (var channel in new[] { _y, cb, cr })
                        {
                            var quantizedBytes = new byte[DCTSize * DCTSize];
                            lock (allQuantizedBytes)
                            {
                                allQuantizedBytes.Seek((y * (image.Width / 8) + x) * 8 * 8 * 3 + 8 * 8 * c, SeekOrigin.Begin);
                                allQuantizedBytes.ReadAsync(quantizedBytes, 0, quantizedBytes.Length).Wait();
                            }
                            c++;
                            var quantizedFreqs = ZigZagUnScan(quantizedBytes);
                            var channelFreqs   = DeQuantize(quantizedFreqs, quantizationMatrix);
                            DCT.IDCT2D(channelFreqs, channel, DCTcoefficients, transponseDCTcoefficients);
                        }
                        SetPixels(result, _y, cb, cr, y * DCTSize, x * DCTSize, 128);
                    });
                });
            }

            return(result);
        }
Beispiel #3
0
        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
            });
        }