Exemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PdfTrailer"/> class from a <see cref="PdfCrossReferenceStream"/>.
        /// </summary>
        public PdfTrailer(PdfCrossReferenceStream trailer)
            : base(trailer._document)
        {
            _document = trailer._document;

            // /ID [<09F877EBF282E9408ED1882A9A21D9F2><2A4938E896006F499AC1C2EA7BFB08E4>]
            // /Info 7 0 R
            // /Root 1 0 R
            // /Size 10

            PdfReference iref = trailer.Elements.GetReference(Keys.Info);

            if (iref != null)
            {
                Elements.SetReference(Keys.Info, iref);
            }

            Elements.SetReference(Keys.Root, trailer.Elements.GetReference(Keys.Root));

            Elements.SetInteger(Keys.Size, trailer.Elements.GetInteger(Keys.Size));

            PdfArray id = trailer.Elements.GetArray(Keys.ID);

            if (id != null)
            {
                Elements.SetValue(Keys.ID, id);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PdfTrailer"/> class from a <see cref="PdfCrossReferenceStream"/>.
        /// </summary>
        public PdfTrailer(PdfCrossReferenceStream trailer)
            : base(trailer._document)
        {
            _document = trailer._document;

            // /ID [<09F877EBF282E9408ED1882A9A21D9F2><2A4938E896006F499AC1C2EA7BFB08E4>]
            // /Info 7 0 R
            // /Root 1 0 R
            // /Size 10

            PdfReference iref = trailer.Elements.GetReference(Keys.Info);
            if (iref != null)
                Elements.SetReference(Keys.Info, iref);

            Elements.SetReference(Keys.Root, trailer.Elements.GetReference(Keys.Root));

            Elements.SetInteger(Keys.Size, trailer.Elements.GetInteger(Keys.Size));

            PdfArray id = trailer.Elements.GetArray(Keys.ID);
            if (id != null)
                Elements.SetValue(Keys.ID, id);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Reads cross reference stream(s).
        /// </summary>
        private PdfTrailer ReadXRefStream(PdfCrossReferenceTable xrefTable)
        {
            // Read cross reference stream.
            //Debug.Assert(_lexer.Symbol == Symbol.Integer);

            int number = _lexer.TokenToInteger;
            int generation = ReadInteger();
            Debug.Assert(generation == 0);

            ReadSymbol(Symbol.Obj);
            ReadSymbol(Symbol.BeginDictionary);
            PdfObjectID objectID = new PdfObjectID(number, generation);

            PdfCrossReferenceStream xrefStream = new PdfCrossReferenceStream(_document);

            ReadDictionary(xrefStream, false);
            ReadSymbol(Symbol.BeginStream);
            ReadStream(xrefStream);

            //xrefTable.Add(new PdfReference(objectID, position));
            PdfReference iref = new PdfReference(xrefStream);
            iref.ObjectID = objectID;
            iref.Value = xrefStream;
            xrefTable.Add(iref);

            Debug.Assert(xrefStream.Stream != null);
            //string sValue = new RawEncoding().GetString(xrefStream.Stream.UnfilteredValue,);
            //sValue.GetType();
            byte[] bytesRaw = xrefStream.Stream.UnfilteredValue;
            byte[] bytes = bytesRaw;

            // HACK: Should be done in UnfilteredValue.
            if (xrefStream.Stream.HasDecodeParams)
            {
                int predictor = xrefStream.Stream.DecodePredictor;
                int columns = xrefStream.Stream.DecodeColumns;
                bytes = DecodeCrossReferenceStream(bytesRaw, columns, predictor);
            }

#if DEBUG_
            for (int idx = 0; idx < bytes.Length; idx++)
            {
                if (idx % 4 == 0)
                    Console.WriteLine();
                Console.Write("{0:000} ", (int)bytes[idx]);
            }
            Console.WriteLine();
#endif

            //     bytes.GetType();
            // Add to table.
            //    xrefTable.Add(new PdfReference(objectID, -1));

            int size = xrefStream.Elements.GetInteger(PdfCrossReferenceStream.Keys.Size);
            PdfArray index = xrefStream.Elements.GetValue(PdfCrossReferenceStream.Keys.Index) as PdfArray;
            int prev = xrefStream.Elements.GetInteger(PdfCrossReferenceStream.Keys.Prev);
            PdfArray w = (PdfArray)xrefStream.Elements.GetValue(PdfCrossReferenceStream.Keys.W);

            // E.g.: W[1 2 1] ¤ Index[7 12] ¤ Size 19

            // Setup subsections.
            int subsectionCount;
            int[][] subsections = null;
            int subsectionEntryCount = 0;
            if (index == null)
            {
                // Setup with default values.
                subsectionCount = 1;
                subsections = new int[subsectionCount][];
                subsections[0] = new int[] { 0, size }; // HACK: What is size? Contratiction in PDF reference.
                subsectionEntryCount = size;
            }
            else
            {
                // Read subsections from array.
                Debug.Assert(index.Elements.Count % 2 == 0);
                subsectionCount = index.Elements.Count / 2;
                subsections = new int[subsectionCount][];
                for (int idx = 0; idx < subsectionCount; idx++)
                {
                    subsections[idx] = new int[] { index.Elements.GetInteger(2 * idx), index.Elements.GetInteger(2 * idx + 1) };
                    subsectionEntryCount += subsections[idx][1];
                }
            }

            // W key.
            Debug.Assert(w.Elements.Count == 3);
            int[] wsize = { w.Elements.GetInteger(0), w.Elements.GetInteger(1), w.Elements.GetInteger(2) };
            int wsum = StreamHelper.WSize(wsize);
            if (wsum * subsectionEntryCount != bytes.Length)
                GetType();
            Debug.Assert(wsum * subsectionEntryCount == bytes.Length, "Check implementation here.");
            int testcount = subsections[0][1];
            int[] currentSubsection = subsections[0];
#if DEBUG && CORE
            if (PdfDiagnostics.TraceXrefStreams)
            {
                for (int idx = 0; idx < testcount; idx++)
                {
                    uint field1 = StreamHelper.ReadBytes(bytes, idx * wsum, wsize[0]);
                    uint field2 = StreamHelper.ReadBytes(bytes, idx * wsum + wsize[0], wsize[1]);
                    uint field3 = StreamHelper.ReadBytes(bytes, idx * wsum + wsize[0] + wsize[1], wsize[2]);
                    string res = String.Format("{0,2:00}: {1} {2,5} {3}  // ", idx, field1, field2, field3);
                    switch (field1)
                    {
                        case 0:
                            res += "Fee list: object number, generation number";
                            break;

                        case 1:
                            res += "Not compresed: offset, generation number";
                            break;

                        case 2:
                            res += "Compressed: object stream object number, index in stream";
                            break;

                        default:
                            res += "??? Type undefined";
                            break;
                    }
                    Debug.WriteLine(res);
                }
            }
#endif

            int index2 = -1;
            for (int ssc = 0; ssc < subsectionCount; ssc++)
            {
                int abc = subsections[ssc][1];
                for (int idx = 0; idx < abc; idx++)
                {
                    index2++;

                    PdfCrossReferenceStream.CrossReferenceStreamEntry item =
                        new PdfCrossReferenceStream.CrossReferenceStreamEntry();

                    item.Type = StreamHelper.ReadBytes(bytes, index2 * wsum, wsize[0]);
                    item.Field2 = StreamHelper.ReadBytes(bytes, index2 * wsum + wsize[0], wsize[1]);
                    item.Field3 = StreamHelper.ReadBytes(bytes, index2 * wsum + wsize[0] + wsize[1], wsize[2]);

                    xrefStream.Entries.Add(item);

                    switch (item.Type)
                    {
                        case 0:
                            // Nothing to do, not needed.
                            break;

                        case 1: // offset / generation number
                            //// Even it is restricted, an object can exists in more than one subsection.
                            //// (PDF Reference Implementation Notes 15).

                            int position = (int)item.Field2;
                            objectID = ReadObjectNumber(position);
#if DEBUG
                            if (objectID.ObjectNumber == 1074)
                                GetType();
#endif
                            Debug.Assert(objectID.GenerationNumber == item.Field3);

                            //// Ignore the latter one.
                            if (!xrefTable.Contains(objectID))
                            {
#if DEBUG
                                GetType();
#endif
                                // Add iref for all uncrompressed objects.
                                xrefTable.Add(new PdfReference(objectID, position));

                            }
                            break;

                        case 2:
                            // Nothing to do yet.
                            break;
                    }
                }
            }
            return xrefStream;
        }