public static Bitmap Decompress(int height, int width, byte[] compressedData) { YCbCrSubSample yCbCrSubSamples = DecodeCompressedBytes(height, width, compressedData); // up sample YCbCr[,] yCbCrs = UpSample(yCbCrSubSamples); // change to RGB and write to bitmap int h = yCbCrs.GetLength(0), w = yCbCrs.GetLength(1); Bitmap img = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb); for (int row = 0; row < h; ++row) { for (int col = 0; col < w; ++col) { img.SetPixel(col, row, ColorChannel.YcbcrToRgb(yCbCrs[row, col])); } } return(img); }
public static byte[] Compress(Bitmap image) { // 1. get YCbCr channels of the image YCbCr[,] yCbCrs = ColorChannel.ReadYCbCrs(image); // 2. sub sample YCbCrSubSample yCbCrSubSamples = SubSample(yCbCrs); // for each channel, run a sperate thread for DCT, quantized, zigzag sampling var tasks = new Task[3]; sbyte[] yStream = null, cbStream = null, crStream = null; tasks[0] = Task.Factory.StartNew(() => { //3,4. DCT sub quantized sbyte[,] s = DCTSubQuantized(yCbCrSubSamples.Y, LuminanceQuantizationTable); yStream = ZigZagTransform(s); }); tasks[1] = Task.Factory.StartNew(() => { sbyte[,] s = DCTSubQuantized(yCbCrSubSamples.Cb, ChrominanceQuantizationTable); cbStream = ZigZagTransform(s); }); tasks[2] = Task.Factory.StartNew(() => { sbyte[,] s = DCTSubQuantized(yCbCrSubSamples.Cr, ChrominanceQuantizationTable); crStream = ZigZagTransform(s); }); Task.WaitAll(tasks); // concatennate byte stream var data = new sbyte[yStream.Length + cbStream.Length + crStream.Length]; yStream.CopyTo(data, 0); cbStream.CopyTo(data, yStream.Length); crStream.CopyTo(data, yStream.Length + cbStream.Length); return(RunLengthEncode(data)); }
private Bitmap DecompressIFrame(byte[] bs) { frameMemory = DecodeCompressedBytes(FrameHeight, FrameWidth, bs); YCbCr[,] yCbCrs = UpSample(frameMemory); return(ColorChannel.CreateBitmapFromYCbCr(yCbCrs)); }
private byte[] CompressPframe(Bitmap bitmap) { YCbCr[,] yCbCrs = ColorChannel.ReadYCbCrs(bitmap); YCbCrSubSample yCbCrSubSamples = JPEG.SubSample(yCbCrs); // motion vecotr estimate var mv = new MotionVector(15); EstimateResult vecotrDiffs = mv.Estimate(frameMemory, yCbCrSubSamples); // dct subquantized differences var tasks = new Task[3]; sbyte[,] yQuantized = null, cbQuantized = null, crQuantized = null; tasks[0] = Task.Factory.StartNew(() => { yQuantized = DCTSubQuantized(vecotrDiffs.YDiffs, LuminanceQuantizationTable); }); tasks[1] = Task.Factory.StartNew(() => { cbQuantized = DCTSubQuantized(vecotrDiffs.CbDiffs, ChrominanceQuantizationTable); }); tasks[2] = Task.Factory.StartNew(() => { crQuantized = DCTSubQuantized(vecotrDiffs.CrDiffs, ChrominanceQuantizationTable); }); Task.WaitAll(tasks); //upquantized IDCT, add to frame memory int yHeight = yCbCrSubSamples.Y.GetLength(0), yWidth = yCbCrSubSamples.Y.GetLength(1), cHeight = yCbCrSubSamples.Cb.GetLength(0), cWidth = yCbCrSubSamples.Cb.GetLength(1); tasks[0] = Task.Factory.StartNew(() => { yCbCrSubSamples.Y = UpQuantizedIDCT(yHeight, yWidth, yQuantized, LuminanceQuantizationTable); }); tasks[1] = Task.Factory.StartNew(() => { yCbCrSubSamples.Cb = UpQuantizedIDCT(cHeight, cWidth, cbQuantized, ChrominanceQuantizationTable); }); tasks[2] = Task.Factory.StartNew(() => { yCbCrSubSamples.Cr = UpQuantizedIDCT(cHeight, cWidth, crQuantized, ChrominanceQuantizationTable); }); // zigzag RLE differences sbyte[] yStream = ZigZagTransform(yQuantized); sbyte[] cbStream = ZigZagTransform(cbQuantized); sbyte[] crStream = ZigZagTransform(crQuantized); // concatennate byte stream var data = new sbyte[vecotrDiffs.Vectors.Length * 2 + yStream.Length + cbStream.Length + crStream.Length]; for (int i = 0, j = 0; i < vecotrDiffs.Vectors.Length; ++i) { data[j++] = (sbyte)(vecotrDiffs.Vectors[i].x); data[j++] = (sbyte)(vecotrDiffs.Vectors[i].y); } yStream.CopyTo(data, vecotrDiffs.Vectors.Length * 2); cbStream.CopyTo(data, yStream.Length + vecotrDiffs.Vectors.Length * 2); crStream.CopyTo(data, yStream.Length + cbStream.Length + vecotrDiffs.Vectors.Length * 2); Task.WaitAll(tasks); AddDifferencesToMemoryFrame(yCbCrSubSamples, vecotrDiffs.Vectors); // update frame memory return(RunLengthEncode(data)); }