public static void Decompress([NotNull] InterleavedFile file, [NotNull] byte[] Red, [NotNull] byte[] Green, [NotNull] byte[] Blue, byte scale) { var planeWidth = WaveletRestorePlanar2(file, scale, out var Y, out var U, out var V); YuvPlanes_To_RgbPlanes(file.Version, Y, U, V, planeWidth, planeWidth, planeWidth, Red, Green, Blue); }
private static InterleavedFile WaveletDecomposePlanar2([NotNull] float[] Y, [NotNull] float[] U, [NotNull] float[] V, int planeWidth, int planeHeight, int imgWidth, int imgHeight) { int rounds = (int)Math.Log(planeWidth, 2); var p2Height = (int)NextPow2((uint)planeHeight); var p2Width = (int)NextPow2((uint)planeWidth); var hx = new float[p2Height]; var wx = new float[p2Width]; var msY = new MemoryStream(); var msU = new MemoryStream(); var msV = new MemoryStream(); for (int ch = 0; ch < 3; ch++) { var buffer = Pick(ch, Y, U, V); var ms = Pick(ch, msY, msU, msV); // DC to AC for (int i = 0; i < buffer.Length; i++) { buffer[i] -= 127.5f; } // Transform for (int i = 0; i < rounds; i++) { var height = p2Height >> i; var width = p2Width >> i; // Wavelet decompose vertical for (int x = 0; x < width; x++) // each column { CdfWavelet.Fwt97(buffer, hx, height, x, planeWidth); } // Wavelet decompose HALF horizontal for (int y = 0; y < height / 2; y++) // each row { CdfWavelet.Fwt97(buffer, wx, width, y * planeWidth, 1); } } // Reorder, Quantise and reduce co-efficients var packedLength = ToStorageOrder2D(buffer, planeWidth, planeHeight, rounds, imgWidth, imgHeight); QuantisePlanar2(buffer, ch, packedLength, QuantiseType.Reduce, StandardYQuants, StandardCQuants); // Write output using (var tmp = new MemoryStream(buffer.Length)) { // byte-by-byte writing to DeflateStream is *very* slow, so we buffer DataEncoding.FibonacciEncode(buffer, 0, tmp); using (var gs = new DeflateStream(ms, CompressionLevel.Optimal, true)) { tmp.WriteTo(gs); gs.Flush(); } } } // interleave the files: msY.Seek(0, SeekOrigin.Begin); msU.Seek(0, SeekOrigin.Begin); msV.Seek(0, SeekOrigin.Begin); var container = new InterleavedFile((ushort)imgWidth, (ushort)imgHeight, 1, StandardYQuants, StandardCQuants, msY.ToArray(), msU.ToArray(), msV.ToArray()); msY.Dispose(); msU.Dispose(); msV.Dispose(); return(container); }
public static int WaveletRestorePlanar2([NotNull] InterleavedFile container, byte scale, out float[] Y, out float[] U, out float[] V) { // ReSharper disable IdentifierTypo var Ybytes = container.Planes?[0]; var Ubytes = container.Planes?[1]; var Vbytes = container.Planes?[2]; // ReSharper restore IdentifierTypo var yQuants = container.QuantiserSettings_Y ?? StandardYQuants; var cQuants = container.QuantiserSettings_C ?? StandardCQuants; if (Ybytes == null || Ubytes == null || Vbytes == null) { Y = new float[0]; U = new float[0]; V = new float[0]; return(0);//throw new NullReferenceException("Planes were not read from image correctly"); } int imgWidth = container.Width; int imgHeight = container.Height; // the original image source's internal buffer size var packedLength = NextPow2(imgWidth) * NextPow2(imgHeight); // scale by a power of 2 if (scale < 1) { scale = 1; } var scaleShift = scale - 1; if (scale > 1) { imgWidth >>= scaleShift; imgHeight >>= scaleShift; } var planeWidth = NextPow2(imgWidth); var planeHeight = NextPow2(imgHeight); var sampleCount = planeHeight * planeWidth; Y = new float[sampleCount]; U = new float[sampleCount]; V = new float[sampleCount]; var hx = new float[planeHeight]; var wx = new float[planeWidth]; int rounds = (int)Math.Log(planeWidth, 2); for (int ch = 0; ch < 3; ch++) { var buffer = Pick(ch, Y, U, V); var storedData = new MemoryStream(Pick(ch, Ybytes, Ubytes, Vbytes)); using (var gs = new DeflateStream(storedData, CompressionMode.Decompress)) { var ms = new MemoryStream(sampleCount); gs.CopyTo(ms); ms.Seek(0, SeekOrigin.Begin); DataEncoding.FibonacciDecode(ms, buffer); } // Re-expand co-efficients QuantisePlanar2(buffer, ch, packedLength, QuantiseType.Expand, yQuants, cQuants); FromStorageOrder2D(buffer, planeWidth, planeHeight, rounds, imgWidth, imgHeight, scaleShift); // Restore for (int i = rounds - 1; i >= 0; i--) { var height = planeHeight >> i; var width = planeWidth >> i; // Wavelet restore HALF horizontal for (int y = 0; y < height / 2; y++) // each row { CdfWavelet.Iwt97(buffer, wx, width, y * planeWidth, 1); } // Wavelet restore vertical for (int x = 0; x < width; x++) // each column { CdfWavelet.Iwt97(buffer, hx, height, x, planeWidth); } } // AC to DC for (int i = 0; i < buffer.Length; i++) { buffer[i] += 127.5f; } } return(planeWidth); }