コード例 #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="byteCount">The number of bytes per pixel</param>
        /// <returns></returns>
        private byte[] GetOptimalFilteredScanline(byte[] rawScanline, byte[] previousScanline, int byteCount)
        {
            List <Tuple <byte[], int> > candidates = new List <Tuple <byte[], int> >();

            byte[] sub = SubFilter.Encode(rawScanline, byteCount);
            candidates.Add(new Tuple <byte[], int>(sub, CalculateTotalVariation(sub)));

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

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

            byte[] paeth = PaethFilter.Encode(rawScanline, previousScanline, byteCount);
            candidates.Add(new Tuple <byte[], int>(paeth, 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);
        }
コード例 #2
0
ファイル: PngDecoderCore.cs プロジェクト: ITTalk/2016_Krakow
        /// <summary>
        /// Decodes the raw pixel data row by row
        /// </summary>
        /// <typeparam name="T">The pixel format.</typeparam>
        /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
        /// <param name="pixelData">The pixel data.</param>
        /// <param name="pixels">The image pixels.</param>
        private void DecodePixelData <T, TP>(byte[] pixelData, T[] pixels)
            where T : IPackedVector <TP>
            where TP : struct
        {
            byte[] previousScanline = new byte[this.bytesPerScanline];

            for (int y = 0; y < this.header.Height; y++)
            {
                byte[] scanline = new byte[this.bytesPerScanline];
                Array.Copy(pixelData, y * this.bytesPerScanline, scanline, 0, this.bytesPerScanline);
                FilterType filterType = (FilterType)scanline[0];
                byte[]     defilteredScanline;

                switch (filterType)
                {
                case FilterType.None:

                    defilteredScanline = NoneFilter.Decode(scanline);

                    break;

                case FilterType.Sub:

                    defilteredScanline = SubFilter.Decode(scanline, bytesPerPixel);

                    break;

                case FilterType.Up:

                    defilteredScanline = UpFilter.Decode(scanline, previousScanline);

                    break;

                case FilterType.Average:

                    defilteredScanline = AverageFilter.Decode(scanline, previousScanline, bytesPerPixel);

                    break;

                case FilterType.Paeth:

                    defilteredScanline = PaethFilter.Decode(scanline, previousScanline, bytesPerPixel);

                    break;

                default:
                    throw new ImageFormatException("Unknown filter type.");
                }

                previousScanline = defilteredScanline;
                ProcessDefilteredScanline <T, TP>(defilteredScanline, y, pixels);
            }
        }