Ejemplo n.º 1
0
 /// <summary>
 /// Skip white space
 /// </summary>
 public void SkipWhiteSpace()
 {
     // skip white space
     if (PdfBase.IsWhiteSpace(NextChar))
     {
         while ((NextChar = ReadChar()) != EOF && PdfBase.IsWhiteSpace(NextChar))
         {
             ;
         }
     }
     return;
 }
Ejemplo n.º 2
0
        ////////////////////////////////////////////////////////////////////
        // Parse inline image
        ////////////////////////////////////////////////////////////////////

        internal PdfOp ParseInlineImage()
        {
            // create empty dictionary
            PdfDictionary ImageDict = ParseDictionary(true);

            // get image width
            if (!ImageDict.FindValue("/W").GetInteger(out int Width) || Width <= 0)
            {
                throw new ApplicationException("Parse inline image: Width error");
            }

            // get image height
            if (!ImageDict.FindValue("/H").GetInteger(out int Height) || Height <= 0)
            {
                throw new ApplicationException("Parse inline image: Height error");
            }

            // get image bits per component
            if (!ImageDict.FindValue("/BPC").GetInteger(out int BitPerComp) ||
                BitPerComp != 1 && BitPerComp != 2 && BitPerComp != 4 && BitPerComp != 8)
            {
                throw new ApplicationException("Parse inline image: BPC error");
            }

            int Components = 0;

            // get color space
            string ColorSpace = ImageDict.FindValue("/CS").ToName;

            if (ColorSpace != null)
            {
                // number of components
                if (ColorSpace == "/G")
                {
                    Components = 1;
                }
                else if (ColorSpace == "/RGB")
                {
                    Components = 3;
                }
                else if (ColorSpace == "/CMYK")
                {
                    Components = 4;
                }
                else
                {
                    throw new ApplicationException("Parse inline image: ColorSpace error");
                }
            }

            ImageDict.FindValue("/IM").GetBoolean(out bool IM);
            if (IM)
            {
                Components = 1;
            }

            PdfBase Filter = ImageDict.FindValue("/F");

            if (!Filter.IsEmpty)
            {
                throw new ApplicationException("Parse inline image: No filter support");
            }

            // no ASCIIHexDecode AHx or ASCII85Decode A85
            if (!PdfBase.IsWhiteSpace(NextChar))
            {
                throw new ApplicationException("Parse inline image: ID must be followed by white space");
            }

            // image width in bytes
            int WidthBytes = 0;

            switch (BitPerComp)
            {
            case 1:
                WidthBytes = (Width + 7) / 8;
                break;

            case 2:
                WidthBytes = (Width + 3) / 4;
                break;

            case 4:
                WidthBytes = (Width + 1) / 2;
                break;

            case 8:
                WidthBytes = Width;
                break;
            }

            // image size
            int Size = WidthBytes * Height * Components;

            // image stream
            byte[] ImageStream = new byte[Size];

            for (int Index = 0; Index < Size; Index++)
            {
                // read next character
                NextChar = ReadChar();

                // end of file error
                if (NextChar == EOF)
                {
                    throw new ApplicationException("Invalid inline image (end of contents)");
                }

                // save it in bitmap
                ImageStream[Index] = (byte)NextChar;
            }

            // get termination
            NextChar = ReadChar();
            SkipWhiteSpace();
            if (NextChar != 'E' || ReadChar() != 'I')
            {
                throw new ApplicationException("Parse inline image: EI is missing");
            }
            NextChar = ReadChar();

            PdfOp InlineImage = new PdfOp(Operator.BeginInlineImage);

            InlineImage.ArgumentArray = new PdfBase[] { ImageDict, new PdfString(ImageStream) };

            // exit
            return(InlineImage);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Parse object reference number n 0 R obj
        /// </summary>
        /// <returns>Object number</returns>
        public int ParseObjectRefNo()
        {
            // loop in case of one or more comments
            SkipComments();

            // must be a digit
            if (NextChar < '0' || NextChar > '9')
            {
                return(0);
            }

            // next content element
            StringBuilder NextItem = new StringBuilder();

            NextItem.Append((char)NextChar);

            // add more characters until next delimiter
            while ((NextChar = ReadChar()) != EOF && !PdfBase.IsDelimiter(NextChar))
            {
                NextItem.Append((char)NextChar);
            }

            // integer
            if (!int.TryParse(NextItem.ToString(), out int ObjNo) || ObjNo <= 0)
            {
                return(0);
            }

            // next character must be space
            if (!PdfBase.IsWhiteSpace(NextChar))
            {
                return(0);
            }

            // skip additional white space
            while ((NextChar = ReadChar()) != EOF && PdfBase.IsWhiteSpace(NextChar))
            {
                ;
            }

            // next character must be zero
            if (NextChar != '0')
            {
                return(0);
            }

            // next character must be white space
            NextChar = ReadChar();
            if (!PdfBase.IsWhiteSpace(NextChar))
            {
                return(0);
            }

            // skip additional white space
            while ((NextChar = ReadChar()) != EOF && PdfBase.IsWhiteSpace(NextChar))
            {
                ;
            }

            // next 3 characters must be obj
            if (NextChar != 'o' || ReadChar() != 'b' || ReadChar() != 'j')
            {
                return(0);
            }

            // next character must be a delimiter
            NextChar = ReadChar();
            if (!PdfBase.IsDelimiter(NextChar))
            {
                return(0);
            }

            // return object number
            return(ObjNo);
        }
Ejemplo n.º 4
0
        ////////////////////////////////////////////////////////////////////
        // Parse hex string item and return PdfString
        ////////////////////////////////////////////////////////////////////

        internal PdfBase ParseHexString()
        {
            // create value string
            List <byte> StrArr = new List <byte>();

            // add more hexadecimal numbers until next closing >
            bool First = true;
            int  OneChar;
            int  OneByte = 0;

            for (;;)
            {
                // read next character
                NextChar = ReadChar();
                if (NextChar == EOF)
                {
                    throw new ApplicationException("Invalid hex string (End of contents)");
                }

                // end of string
                if (NextChar == '>')
                {
                    break;
                }

                // ignore white space within the string
                if (PdfBase.IsWhiteSpace(NextChar))
                {
                    continue;
                }

                // test for hex digits
                if (NextChar >= '0' && NextChar <= '9')
                {
                    OneChar = NextChar - '0';
                }
                else if (NextChar >= 'A' && NextChar <= 'F')
                {
                    OneChar = NextChar - ('A' - 10);
                }
                else if (NextChar >= 'a' && NextChar <= 'f')
                {
                    OneChar = NextChar - ('a' - 10);
                }
                else
                {
                    throw new ApplicationException("Invalid hex string");
                }

                if (First)
                {
                    OneByte = OneChar;
                    First   = false;
                }
                else
                {
                    StrArr.Add((byte)((OneByte << 4) | OneChar));
                    First = true;
                }
            }

            if (!First)
            {
                StrArr.Add((byte)(OneByte << 4));
            }

            // read next character after closing >
            NextChar = ReadChar();

            // exit
            return(new PdfString(StrArr.ToArray()));
        }
Ejemplo n.º 5
0
        ////////////////////////////////////////////////////////////////////
        // Test for reference
        // We have positive integer already. Test for zero and R
        ////////////////////////////////////////////////////////////////////

        internal bool TestReference()
        {
            // save current file position
            int Pos = GetPos();

            // save next character
            int TempChar = NextChar;

            for (;;)
            {
                // next character must be space
                if (!PdfBase.IsWhiteSpace(TempChar))
                {
                    break;
                }

                // skip additional white space
                while ((TempChar = ReadChar()) != EOF && PdfBase.IsWhiteSpace(TempChar))
                {
                    ;
                }

                // generation is not supported
                // next character must be zero
                if (TempChar != '0')
                {
                    break;
                }

                // next character must be white space
                TempChar = ReadChar();
                if (!PdfBase.IsWhiteSpace(TempChar))
                {
                    break;
                }

                // skip additional white space
                while ((TempChar = ReadChar()) != EOF && PdfBase.IsWhiteSpace(TempChar))
                {
                    ;
                }

                // next character must be R
                if (TempChar != 'R')
                {
                    break;
                }

                // next character must be a delimiter
                TempChar = ReadChar();
                if (!PdfBase.IsDelimiter(TempChar))
                {
                    break;
                }

                // found
                NextChar = TempChar;
                return(true);
            }

            // restore position
            SetPos(Pos);
            return(false);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Apply ASCII 85 decode
        /// </summary>
        /// <param name="InputBuffer">Input buffer</param>
        /// <returns>Output buffer</returns>
        internal byte[] Ascii85Decode
        (
            byte[] InputBuffer
        )
        {
            // array of power of 85: 85**4, 85**3, 85**2, 85**1, 85**0
            uint[] Power85 = new uint[] { 85 * 85 * 85 * 85, 85 * 85 * 85, 85 * 85, 85, 1 };

            // output buffer
            List <byte> OutputBuffer = new List <byte>();

            // convert input to output buffer
            int  State     = 0;
            uint FourBytes = 0;

            for (int Index = 0; Index < InputBuffer.Length; Index++)
            {
                // next character
                char NextChar = (char)InputBuffer[Index];

                // end of stream "~>"
                if (NextChar == '~')
                {
                    break;
                }

                // ignore white space
                if (PdfBase.IsWhiteSpace(NextChar))
                {
                    continue;
                }

                // special case of four zero bytes
                if (NextChar == 'z' && State == 0)
                {
                    OutputBuffer.Add(0);
                    OutputBuffer.Add(0);
                    OutputBuffer.Add(0);
                    OutputBuffer.Add(0);
                    continue;
                }

                // test for valid characters
                if (NextChar < '!' || NextChar > 'u')
                {
                    throw new ApplicationException("Illegal character in ASCII85Decode");
                }

                // accumulate 4 output bytes from 5 input bytes
                FourBytes += Power85[State++] * (uint)(NextChar - '!');

                // we have 4 output bytes
                if (State == 5)
                {
                    OutputBuffer.Add((byte)(FourBytes >> 24));
                    OutputBuffer.Add((byte)(FourBytes >> 16));
                    OutputBuffer.Add((byte)(FourBytes >> 8));
                    OutputBuffer.Add((byte)FourBytes);

                    // reset state
                    State     = 0;
                    FourBytes = 0;
                }
            }

            // if state is not zero add one, two or three terminating bytes
            if (State != 0)
            {
                if (State == 1)
                {
                    throw new ApplicationException("Illegal length in ASCII85Decode");
                }

                // add padding of 84
                for (int PadState = State; PadState < 5; PadState++)
                {
                    FourBytes += Power85[PadState] * (uint)('u' - '!');
                }

                // add one, two or three terminating bytes
                OutputBuffer.Add((byte)(FourBytes >> 24));
                if (State >= 3)
                {
                    OutputBuffer.Add((byte)(FourBytes >> 16));
                    if (State >= 4)
                    {
                        OutputBuffer.Add((byte)(FourBytes >> 8));
                    }
                }
            }

            // exit
            return(OutputBuffer.ToArray());
        }