Ejemplo n.º 1
0
        /// <summary>
        /// Apply predictor decode
        /// </summary>
        /// <param name="InputBuffer">Input buffer</param>
        /// <returns>Output buffer</returns>
        internal byte[] PredictorDecode
        (
            byte[]          InputBuffer
        )
        {
            // test for /DecodeParams
            PdfDictionary DecodeParms = Dictionary.FindValue("/DecodeParms").ToDictionary;

            // none found
            if (DecodeParms == null)
            {
                return(InputBuffer);
            }

            // look for predictor code. if default (none or 1) do nothing
            if (!DecodeParms.FindValue("/Predictor").GetInteger(out int Predictor) || Predictor == 1)
            {
                return(InputBuffer);
            }

            // we only support predictor code 12
            if (Predictor != 12)
            {
                return(null);
            }

            // get width
            DecodeParms.FindValue("/Columns").GetInteger(out int Width);
            if (Width < 0)
            {
                throw new ApplicationException("/DecodeParms /Columns is negative");
            }
            if (Width == 0)
            {
                Width = 1;
            }

            // calculate rows
            int Rows = InputBuffer.Length / (Width + 1);

            if (Rows < 1)
            {
                throw new ApplicationException("/DecodeParms /Columns is greater than stream length");
            }

            // create output buffer
            byte[] OutputBuffer = new byte[Rows * Width];

            // reset pointers
            int InPtr      = 1;
            int OutPtr     = 0;
            int OutPrevPtr = 0;

            // first row (ignore filter)
            while (OutPtr < Width)
            {
                OutputBuffer[OutPtr++] = InputBuffer[InPtr++];
            }

            // decode loop
            for (int Row = 1; Row < Rows; Row++)
            {
                // first byte is filter
                int Filter = InputBuffer[InPtr++];

                // we support PNG filter up only
                if (Filter != 2)
                {
                    throw new ApplicationException("/DecodeParms Only supported filter is 2");
                }

                // convert input to output
                for (int Index = 0; Index < Width; Index++)
                {
                    OutputBuffer[OutPtr++] = (byte)(OutputBuffer[OutPrevPtr++] + InputBuffer[InPtr++]);
                }
            }

            return(OutputBuffer);
        }