/// <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); }