예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }