Esempio n. 1
0
        /// <summary>
        /// Applies all PNG filters to the given scanline and returns the filtered scanline that is deemed
        /// to be most compressible, using lowest total variation as proxy for compressibility.
        /// </summary>
        /// <param name="rawScanline">The raw scanline</param>
        /// <param name="previousScanline">The previous scanline</param>
        /// <param name="result">The filtered scanline result.</param>
        /// <returns>The <see cref="T:byte[]"/></returns>
        private byte[] GetOptimalFilteredScanline(byte[] rawScanline, byte[] previousScanline, byte[] result)
        {
            // Palette images don't compress well with adaptive filtering.
            if (this.PngColorType == PngColorType.Palette)
            {
                NoneFilter.Encode(rawScanline, result);
                return(result);
            }

            SubFilter.Encode(rawScanline, this.sub, this.bytesPerPixel);
            int currentTotalVariation = this.CalculateTotalVariation(this.sub);
            int lowestTotalVariation  = currentTotalVariation;

            result = this.sub;

            UpFilter.Encode(rawScanline, previousScanline, this.up);
            currentTotalVariation = this.CalculateTotalVariation(this.up);

            if (currentTotalVariation < lowestTotalVariation)
            {
                lowestTotalVariation = currentTotalVariation;
                result = this.up;
            }

            AverageFilter.Encode(rawScanline, previousScanline, this.average, this.bytesPerPixel);
            currentTotalVariation = this.CalculateTotalVariation(this.average);

            if (currentTotalVariation < lowestTotalVariation)
            {
                lowestTotalVariation = currentTotalVariation;
                result = this.average;
            }

            PaethFilter.Encode(rawScanline, previousScanline, this.paeth, this.bytesPerPixel);
            currentTotalVariation = this.CalculateTotalVariation(this.paeth);

            if (currentTotalVariation < lowestTotalVariation)
            {
                result = this.paeth;
            }

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Applies all PNG filters to the given scanline and returns the filtered scanline that is deemed
        /// to be most compressible, using lowest total variation as proxy for compressibility.
        /// </summary>
        /// <param name="rawScanline">The raw scanline</param>
        /// <param name="previousScanline">The previous scanline</param>
        /// <param name="result">The filtered scanline result</param>
        /// <param name="bytesPerScanline">The number of bytes per scanline</param>
        private void GetOptimalFilteredScanline(byte[] rawScanline, byte[] previousScanline, byte[] result, int bytesPerScanline)
        {
            // Palette images don't compress well with adaptive filtering.
            if (this.PngColorType == PngColorType.Palette)
            {
                NoneFilter.Encode(rawScanline, result, bytesPerScanline);
                return;
            }

            Tuple <byte[], int>[] candidates = new Tuple <byte[], int> [4];

            byte[] sub = SubFilter.Encode(rawScanline, this.bytesPerPixel, bytesPerScanline);
            candidates[0] = new Tuple <byte[], int>(sub, this.CalculateTotalVariation(sub));

            byte[] up = UpFilter.Encode(rawScanline, previousScanline, result, bytesPerScanline);
            candidates[1] = new Tuple <byte[], int>(up, this.CalculateTotalVariation(up));

            byte[] average = AverageFilter.Encode(rawScanline, previousScanline, result, this.bytesPerPixel, bytesPerScanline);
            candidates[2] = new Tuple <byte[], int>(average, this.CalculateTotalVariation(average));

            byte[] paeth = PaethFilter.Encode(rawScanline, previousScanline, result, this.bytesPerPixel, bytesPerScanline);
            candidates[3] = new Tuple <byte[], int>(paeth, this.CalculateTotalVariation(paeth));

            int lowestTotalVariation      = int.MaxValue;
            int lowestTotalVariationIndex = 0;

            for (int i = 0; i < candidates.Length; i++)
            {
                if (candidates[i].Item2 < lowestTotalVariation)
                {
                    lowestTotalVariationIndex = i;
                    lowestTotalVariation      = candidates[i].Item2;
                }
            }

            // ReSharper disable once RedundantAssignment
            result = candidates[lowestTotalVariationIndex].Item1;
        }
Esempio n. 3
0
        /// <summary>
        /// Applies all PNG filters to the given scanline and returns the filtered scanline that is deemed
        /// to be most compressible, using lowest total variation as proxy for compressibility.
        /// </summary>
        /// <param name="rawScanline">The raw scanline</param>
        /// <param name="previousScanline">The previous scanline</param>
        /// <param name="byteCount">The number of bytes per pixel</param>
        /// <returns>The <see cref="T:byte[]"/></returns>
        private byte[] GetOptimalFilteredScanline(byte[] rawScanline, byte[] previousScanline, int byteCount)
        {
            List <Tuple <byte[], int> > candidates = new List <Tuple <byte[], int> >();

            if (this.PngColorType == PngColorType.Palette)
            {
                byte[] none = NoneFilter.Encode(rawScanline);
                candidates.Add(new Tuple <byte[], int>(none, this.CalculateTotalVariation(none)));
            }
            else
            {
                byte[] sub = SubFilter.Encode(rawScanline, byteCount);
                candidates.Add(new Tuple <byte[], int>(sub, this.CalculateTotalVariation(sub)));

                byte[] up = UpFilter.Encode(rawScanline, previousScanline);
                candidates.Add(new Tuple <byte[], int>(up, this.CalculateTotalVariation(up)));

                byte[] average = AverageFilter.Encode(rawScanline, previousScanline, byteCount);
                candidates.Add(new Tuple <byte[], int>(average, this.CalculateTotalVariation(average)));

                byte[] paeth = PaethFilter.Encode(rawScanline, previousScanline, byteCount);
                candidates.Add(new Tuple <byte[], int>(paeth, this.CalculateTotalVariation(paeth)));
            }

            int lowestTotalVariation      = int.MaxValue;
            int lowestTotalVariationIndex = 0;

            for (int i = 0; i < candidates.Count; i++)
            {
                if (candidates[i].Item2 < lowestTotalVariation)
                {
                    lowestTotalVariationIndex = i;
                    lowestTotalVariation      = candidates[i].Item2;
                }
            }

            return(candidates[lowestTotalVariationIndex].Item1);
        }