예제 #1
0
    /// <summary>
    /// Adds a cross reference entry to the table. Used when parsing the trailer.
    /// </summary>
    public void Add(PdfReference iref)
    {
      if (iref.ObjectID.IsEmpty)
        iref.ObjectID = new PdfObjectID(GetNewObjectNumber());

      if (this.objectTable.ContainsKey(iref.ObjectID))
        throw new InvalidOperationException("Object already in table.");

      this.objectTable.Add(iref.ObjectID, iref);
    }
예제 #2
0
        /// <summary>
        /// Adds a cross reference entry to the table. Used when parsing the trailer.
        /// </summary>
        public void Add(PdfReference iref)
        {
#if DEBUG
            if (iref.ObjectID.ObjectNumber == 948)
                GetType();
#endif
            if (iref.ObjectID.IsEmpty)
                iref.ObjectID = new PdfObjectID(GetNewObjectNumber());

            if (ObjectTable.ContainsKey(iref.ObjectID))
                throw new InvalidOperationException("Object already in table.");

            ObjectTable.Add(iref.ObjectID, iref);
        }
예제 #3
0
    /// <summary>
    /// Calculates the transitive closure of the specified PdfObject with the specified depth, i.e. all indirect objects
    /// recursively reachable from the specified object in up to maximally depth steps.
    /// </summary>
    public PdfReference[] TransitiveClosure(PdfObject pdfObject, int depth)
    {
      CheckConsistence();
      Dictionary<PdfItem, object> objects = new Dictionary<PdfItem, object>();
      this.overflow = new Dictionary<PdfItem, object>();
      TransitiveClosureImplementation(objects, pdfObject, ref depth);
    TryAgain:
      if (this.overflow.Count > 0)
      {
        PdfObject[] array = new PdfObject[this.overflow.Count];
        this.overflow.Keys.CopyTo(array, 0);
        this.overflow = new Dictionary<PdfItem, object>();
        for (int idx = 0; idx < array.Length; idx++)
        {
          //PdfObject o = array[idx];
          //o.GetType();
          PdfObject obj = array[idx];
          //if (!objects.Contains(obj))
          //  objects.Add(obj, null);
          TransitiveClosureImplementation(objects, obj, ref depth);
        }
        goto TryAgain;
      }

      CheckConsistence();

      ICollection collection = objects.Keys;
      int count = collection.Count;
      PdfReference[] irefs = new PdfReference[count];
      collection.CopyTo(irefs, 0);

#if true_
      for (int i = 0; i < count; i++)
        for (int j = 0; j < count; j++)
          if (i != j)
          {
            Debug.Assert(Object.ReferenceEquals(irefs[i].Document, this.document));
            Debug.Assert(irefs[i] != irefs[j]);
            Debug.Assert(!Object.ReferenceEquals(irefs[i], irefs[j]));
            Debug.Assert(!Object.ReferenceEquals(irefs[i].Value, irefs[j].Value));
            Debug.Assert(!Object.ReferenceEquals(irefs[i].ObjectID, irefs[j].Value.ObjectID));
            Debug.Assert(irefs[i].ObjectNumber != irefs[j].Value.ObjectNumber);
            Debug.Assert(Object.ReferenceEquals(irefs[i].Document, irefs[j].Document));
            GetType();
          }
#endif
      return irefs;
    }
예제 #4
0
    /// <summary>
    /// Recursively converts the page tree into a flat array.
    /// </summary>
    PdfDictionary[] GetKids(PdfReference iref, PdfPage.InheritedValues values, PdfDictionary parent)
    {
      // TODO: inherit inheritable keys...
      PdfDictionary kid = (PdfDictionary)iref.Value;

      if (kid.Elements.GetName(Keys.Type) == "/Page")
      {
        PdfPage.InheritValues(kid, values);
        return new PdfDictionary[] { kid };
      }
      else
      {
        Debug.Assert(kid.Elements.GetName(Keys.Type) == "/Pages");
        PdfPage.InheritValues(kid, ref values);
        ArrayList list = new ArrayList();
        PdfArray kids = kid.Elements["/Kids"] as PdfArray;
        foreach (PdfReference xref2 in kids)
          list.AddRange(GetKids(xref2, values, kid));
        int count = list.Count;
        Debug.Assert(count == kid.Elements.GetInteger("/Count"));
        return (PdfDictionary[])list.ToArray(typeof(PdfDictionary));
      }
    }
      /// <summary>
      /// Retrieves the raw data for the colorspace.
      /// </summary>
      /// <returns>The raw data from the PdfArray of PdfReference.</returns>
      protected virtual IEnumerable<byte> GetRawPalette(PdfReference reference)
      {
        if (reference == null) throw new ArgumentNullException("reference", "The reference index was null.");

        var value = (reference.Value as PdfDictionary);
        if (value == null) return(new byte[0]);
        return (value.Stream.UnfilteredValue);
      }
예제 #6
0
    public void CheckConsistence()
    {
      Dictionary<PdfReference, object> ht1 = new Dictionary<PdfReference, object>();
      foreach (PdfReference iref in this.objectTable.Values)
      {
        Debug.Assert(!ht1.ContainsKey(iref), "Duplicate iref.");
        Debug.Assert(iref.Value != null);
        ht1.Add(iref, null);
      }

      Dictionary<PdfObjectID, object> ht2 = new Dictionary<PdfObjectID, object>();
      foreach (PdfReference iref in this.objectTable.Values)
      {
        Debug.Assert(!ht2.ContainsKey(iref.ObjectID), "Duplicate iref.");
        ht2.Add(iref.ObjectID, null);
      }

      ICollection collection = this.objectTable.Values;
      int count = collection.Count;
      PdfReference[] irefs = new PdfReference[count];
      collection.CopyTo(irefs, 0);
#if true_
      for (int i = 0; i < count; i++)
        for (int j = 0; j < count; j++)
          if (i != j)
          {
            Debug.Assert(Object.ReferenceEquals(irefs[i].Document, this.document));
            Debug.Assert(irefs[i] != irefs[j]);
            Debug.Assert(!Object.ReferenceEquals(irefs[i], irefs[j]));
            Debug.Assert(!Object.ReferenceEquals(irefs[i].Value, irefs[j].Value));
            Debug.Assert(!Object.ReferenceEquals(irefs[i].ObjectID, irefs[j].Value.ObjectID));
            Debug.Assert(irefs[i].ObjectNumber != irefs[j].Value.ObjectNumber);
            Debug.Assert(Object.ReferenceEquals(irefs[i].Document, irefs[j].Document));
            GetType();
          }
#endif
    }
예제 #7
0
    /// <summary>
    /// Parses whatever comes until the specified stop symbol is reached.
    /// </summary>
    void ParseObject(Symbol stop)
    {
#if DEBUG_
      ParseObjectCounter++;
      Debug.WriteLine(ParseObjectCounter.ToString());
      if (ParseObjectCounter == 178)
        GetType();
#endif
      Symbol symbol;
      while ((symbol = ScanNextToken()) != Symbol.Eof)
      {
        if (symbol == stop)
          return;

        switch (symbol)
        {
          case Symbol.Comment:
            // ignore comments
            break;

          case Symbol.Null:
            this.stack.Shift(PdfNull.Value);
            break;

          case Symbol.Boolean:
            this.stack.Shift(new PdfBoolean(this.lexer.TokenToBoolean));
            break;

          case Symbol.Integer:
            this.stack.Shift(new PdfInteger(this.lexer.TokenToInteger));
            break;

          case Symbol.UInteger:
            this.stack.Shift(new PdfUInteger(this.lexer.TokenToUInteger));
            break;

          case Symbol.Real:
            this.stack.Shift(new PdfReal(this.lexer.TokenToReal));
            break;

          case Symbol.String:
            //this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.PDFDocEncoding));
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.RawEncoding));
            break;

          case Symbol.UnicodeString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.Unicode));
            break;

          case Symbol.HexString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.HexLiteral));
            break;

          case Symbol.UnicodeHexString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.Unicode | PdfStringFlags.HexLiteral));
            break;

          case Symbol.Name:
            this.stack.Shift(new PdfName(this.lexer.Token));
            break;

          case Symbol.R:
            {
              Debug.Assert(this.stack.GetItem(-1) is PdfInteger && this.stack.GetItem(-2) is PdfInteger);
              PdfObjectID objectID = new PdfObjectID(this.stack.GetInteger(-2), this.stack.GetInteger(-1));

              PdfReference iref = this.document.irefTable[objectID];
              if (iref == null)
              {
                // If a document has more than one PdfXRefTable it is possible that the first trailer has
                // indirect references to objects whos iref entry is not yet read in.
                if (this.document.irefTable.IsUnderConstruction)
                {
                  // XRefTable not complete when trailer is read. Create temporary irefs that are
                  // removed later in PdfTrailer.FixXRefs.
                  iref = new PdfReference(objectID, 0);
                  this.stack.Reduce(iref, 2);
                  break;
                }
                // PDF Reference section 3.2.9:
                // An indirect reference to an undefined object is not an error;
                // it is simply treated as a reference to the null object.
                this.stack.Reduce(PdfNull.Value, 2);
                // Let's see what null objects are good for...
                //Debug.Assert(false, "Null object detected!");
                //this.stack.Reduce(PdfNull.Value, 2);
              }
              else
                this.stack.Reduce(iref, 2);
              break;
            }

          case Symbol.BeginArray:
            PdfArray array = new PdfArray(this.document);
            ReadArray(array, false);
            this.stack.Shift(array);
            break;

          case Symbol.BeginDictionary:
            PdfDictionary dict = new PdfDictionary(this.document);
            ReadDictionary(dict, false);
            this.stack.Shift(dict);
            break;

          case Symbol.BeginStream:
            throw new NotImplementedException();

          default:
            string error = this.lexer.Token;
            Debug.Assert(false, "Unexpected: " + error);
            break;
        }
      }
      throw new PdfReaderException("Unexpected end of file.");
    }
예제 #8
0
 PdfItem ReadReference(PdfReference iref, bool includeReferences)
 {
   throw new NotImplementedException("ReadReference");
 }
 public void Remove(PdfReference iref)
 {
     ObjectTable.Remove(iref.ObjectID);
 }
예제 #10
0
    /// <summary>
    /// Recursively converts the page tree into a flat array.
    /// </summary>
    PdfDictionary[] GetKids(PdfReference iref, PdfPage.InheritedValues values, PdfDictionary parent)
    {
      // TODO: inherit inheritable keys...
      PdfDictionary kid = (PdfDictionary)iref.Value;

      if (kid.Elements.GetName(Keys.Type) == "/Page")
      {
        PdfPage.InheritValues(kid, values);
        return new PdfDictionary[] { kid };
      }
      else
      {
        Debug.Assert(kid.Elements.GetName(Keys.Type) == "/Pages");
        PdfPage.InheritValues(kid, ref values);
        List<PdfDictionary> list = new List<PdfDictionary>();
        PdfArray kids = kid.Elements["/Kids"] as PdfArray;
        //newTHHO 15.10.2007 begin
        if (kids == null)
        {
          PdfReference xref3 = kid.Elements["/Kids"] as PdfReference;
          kids = xref3.Value as PdfArray;
        }
        //newTHHO 15.10.2007 end
        foreach (PdfReference xref2 in kids)
          list.AddRange(GetKids(xref2, values, kid));
        int count = list.Count;
        Debug.Assert(count == kid.Elements.GetInteger("/Count"));
        //return (PdfDictionary[])list.ToArray(typeof(PdfDictionary));
        return list.ToArray();
      }
    }
 /// <summary>
 /// Adds a cloned object to this table.
 /// </summary>
 /// <param name="externalID">The object identifier in the forein object.</param>
 /// <param name="iref">The cross reference to the clone of the forein object, which belongs to
 /// this document. In general the clone has a different object identifier.</param>
 public void Add(PdfObjectID externalID, PdfReference iref)
 {
   this.externalIDs[externalID.ToString()] = iref;
 }
예제 #12
0
 public void Remove(PdfReference iref)
 {
   this.objectTable.Remove(iref.ObjectID);
 }
예제 #13
0
파일: Parser.cs 프로젝트: Sl0vi/PDFsharp
        /// <summary>
        /// Reads the compressed object with the specified index in the object stream
        /// of the object with the specified object id.
        /// </summary>
        internal PdfReference ReadCompressedObject(PdfObjectID objectID, int index)
        {
            PdfReference iref;
#if true
            Debug.Assert(_document._irefTable.ObjectTable.ContainsKey(objectID));
            if (!_document._irefTable.ObjectTable.TryGetValue(objectID, out iref))
            {
                throw new NotImplementedException("This case is not coded or something else went wrong");
            }
#else
            // We should never come here because the object stream must be a type 1 entry in the xref stream
            // and iref was created before.

            // Has the specified object already an iref in the object table?
            if (!_document._irefTable.ObjectTable.TryGetValue(objectID, out iref))
            {
                try
                {
#if true_
                    iref = new PdfReference(objectID,);
                    iref.ObjectID = objectID;
                    _document._irefTable.Add(os);
#else
                    PdfDictionary dict = (PdfDictionary)ReadObject(null, objectID, false, false);
                    PdfObjectStream os = new PdfObjectStream(dict);
                    iref = new PdfReference(os);
                    iref.ObjectID = objectID;
                    _document._irefTable.Add(os);
#endif
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    throw;
                }
            }
#endif

            // Read in object stream object when we come here for the very first time.
            if (iref.Value == null)
            {
                try
                {
                    Debug.Assert(_document._irefTable.Contains(iref.ObjectID));
                    PdfDictionary pdfObject = (PdfDictionary)ReadObject(null, iref.ObjectID, false, false);
                    PdfObjectStream objectStream = new PdfObjectStream(pdfObject);
                    Debug.Assert(objectStream.Reference == iref);
                    // objectStream.Reference = iref; Superfluous, see Assert in line before.
                    Debug.Assert(objectStream.Reference.Value != null, "Something went wrong.");
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    throw;
                }
            }
            Debug.Assert(iref.Value != null);

            PdfObjectStream objectStreamStream = iref.Value as PdfObjectStream;
            if (objectStreamStream == null)
            {
                Debug.Assert(((PdfDictionary)iref.Value).Elements.GetName("/Type") == "/ObjStm");

                objectStreamStream = new PdfObjectStream((PdfDictionary)iref.Value);
                Debug.Assert(objectStreamStream.Reference == iref);
                // objectStream.Reference = iref; Superfluous, see Assert in line before.
                Debug.Assert(objectStreamStream.Reference.Value != null, "Something went wrong.");
            }
            Debug.Assert(objectStreamStream != null);


            //PdfObjectStream objectStreamStream = (PdfObjectStream)iref.Value;
            if (objectStreamStream == null)
                throw new Exception("Something went wrong here.");
            return objectStreamStream.ReadCompressedObject(index);
        }
예제 #14
0
파일: Parser.cs 프로젝트: Sl0vi/PDFsharp
        /// <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;
        }
예제 #15
0
        internal PdfFormXObject(PdfDocument thisDocument, PdfImportedObjectTable importedObjectTable, XPdfForm form)
            : base(thisDocument)
        {
            Debug.Assert(importedObjectTable != null);
            Debug.Assert(ReferenceEquals(thisDocument, importedObjectTable.Owner));
            Elements.SetName(Keys.Type, "/XObject");
            Elements.SetName(Keys.Subtype, "/Form");

            if (form.IsTemplate)
            {
                Debug.Assert(importedObjectTable == null);
                // TODO more initialization here???
                return;
            }

            XPdfForm pdfForm = form;
            // Get import page
            PdfPages importPages = importedObjectTable.ExternalDocument.Pages;

            if (pdfForm.PageNumber < 1 || pdfForm.PageNumber > importPages.Count)
            {
                PSSR.ImportPageNumberOutOfRange(pdfForm.PageNumber, importPages.Count, form._path);
            }
            PdfPage importPage = importPages[pdfForm.PageNumber - 1];

            // Import resources
            PdfItem res = importPage.Elements["/Resources"];

            if (res != null) // unlikely but possible
            {
#if true
                // Get root object
                PdfObject root;
                if (res is PdfReference)
                {
                    root = ((PdfReference)res).Value;
                }
                else
                {
                    root = (PdfDictionary)res;
                }

                root = ImportClosure(importedObjectTable, thisDocument, root);
                // If the root was a direct object, make it indirect.
                if (root.Reference == null)
                {
                    thisDocument._irefTable.Add(root);
                }

                Debug.Assert(root.Reference != null);
                Elements["/Resources"] = root.Reference;
#else
                // Get transitive closure
                PdfObject[] resources = importPage.Owner.Internals.GetClosure(resourcesRoot);
                int         count     = resources.Length;
#if DEBUG_
                for (int idx = 0; idx < count; idx++)
                {
                    Debug.Assert(resources[idx].XRef != null);
                    Debug.Assert(resources[idx].XRef.Document != null);
                    Debug.Assert(resources[idx].Document != null);
                    if (resources[idx].ObjectID.ObjectNumber == 12)
                    {
                        GetType();
                    }
                }
#endif
                // 1st step. Already imported objects are reused and new ones are cloned.
                for (int idx = 0; idx < count; idx++)
                {
                    PdfObject obj = resources[idx];
                    if (importedObjectTable.Contains(obj.ObjectID))
                    {
                        // external object was already imported
                        PdfReference iref = importedObjectTable[obj.ObjectID];
                        Debug.Assert(iref != null);
                        Debug.Assert(iref.Value != null);
                        Debug.Assert(iref.Document == Owner);
                        // replace external object by the already clone counterpart
                        resources[idx] = iref.Value;
                    }
                    else
                    {
                        // External object was not imported earlier and must be cloned
                        PdfObject clone = obj.Clone();
                        Debug.Assert(clone.Reference == null);
                        clone.Document = Owner;
                        if (obj.Reference != null)
                        {
                            // add it to this (the importer) document
                            Owner.irefTable.Add(clone);
                            Debug.Assert(clone.Reference != null);
                            // save old object identifier
                            importedObjectTable.Add(obj.ObjectID, clone.Reference);
                            //Debug.WriteLine("Cloned: " + obj.ObjectID.ToString());
                        }
                        else
                        {
                            // The root object (the /Resources value) is not an indirect object
                            Debug.Assert(idx == 0);
                            // add it to this (the importer) document
                            Owner.irefTable.Add(clone);
                            Debug.Assert(clone.Reference != null);
                        }
                        // replace external object by its clone
                        resources[idx] = clone;
                    }
                }
#if DEBUG_
                for (int idx = 0; idx < count; idx++)
                {
                    Debug.Assert(resources[idx].XRef != null);
                    Debug.Assert(resources[idx].XRef.Document != null);
                    Debug.Assert(resources[idx].Document != null);
                    if (resources[idx].ObjectID.ObjectNumber == 12)
                    {
                        GetType();
                    }
                }
#endif

                // 2nd step. Fix up indirect references that still refers to the import document.
                for (int idx = 0; idx < count; idx++)
                {
                    PdfObject obj = resources[idx];
                    Debug.Assert(obj.Owner != null);
                    FixUpObject(importedObjectTable, importedObjectTable.Owner, obj);
                }

                // Set resources key to the root of the clones
                Elements["/Resources"] = resources[0].Reference;
#endif
            }

            // Take /Rotate into account.
            PdfRectangle rect = importPage.Elements.GetRectangle(PdfPage.Keys.MediaBox);
            // Reduce rotation to 0, 90, 180, or 270.
            int rotate = (importPage.Elements.GetInteger(PdfPage.Keys.Rotate) % 360 + 360) % 360;
            //rotate = 0;
            if (rotate == 0)
            {
                // Set bounding box to media box.
                Elements["/BBox"] = rect;
            }
            else
            {
                // TODO: Have to adjust bounding box? (I think not, but I'm not sure -> wait for problem)
                Elements["/BBox"] = rect;

                // Rotate the image such that it is upright.
                XMatrix matrix = new XMatrix();
                double  width  = rect.Width;
                double  height = rect.Height;
                matrix.RotateAtPrepend(-rotate, new XPoint(width / 2, height / 2));

                // Translate the image such that its center lies on the center of the rotated bounding box.
                double offset = (height - width) / 2;
                if (rotate == 90)
                {
                    // TODO It seems we can simplify this as the sign of offset changes too.
                    if (height > width)
                    {
                        matrix.TranslatePrepend(offset, offset); // Tested.
                    }
                    else
                    {
                        matrix.TranslatePrepend(offset, offset); // TODO Test case.
                    }
                }
                else if (rotate == 270)
                {
                    // TODO It seems we can simplify this as the sign of offset changes too.
                    if (height > width)
                    {
                        matrix.TranslatePrepend(-offset, -offset); // Tested.
                    }
                    else
                    {
                        matrix.TranslatePrepend(-offset, -offset); // Tested.
                    }
                }

                //string item = "[" + PdfEncoders.ToString(matrix) + "]";
                //Elements[Keys.Matrix] = new PdfLiteral(item);
                Elements.SetMatrix(Keys.Matrix, matrix);
            }

            // Preserve filter because the content keeps unmodified.
            PdfContent content = importPage.Contents.CreateSingleContent();
#if !DEBUG
            content.Compressed = true;
#endif
            PdfItem filter = content.Elements["/Filter"];
            if (filter != null)
            {
                Elements["/Filter"] = filter.Clone();
            }

            // (no cloning needed because the bytes keep untouched)
            Stream = content.Stream; // new PdfStream(bytes, this);
            Elements.SetInteger("/Length", content.Stream.Value.Length);
        }
예제 #16
0
        /// <summary>
        /// Replace all indirect references to external objects by their cloned counterparts
        /// owned by the importer document.
        /// </summary>
        void FixUpObject_old(PdfImportedObjectTable iot, PdfObject value)
        {
            // TODO: merge with PdfXObject.FixUpObject
            PdfDictionary dict;
            PdfArray      array;

            if ((dict = value as PdfDictionary) != null)
            {
                // Set document for cloned direct objects
                if (dict.Owner == null)
                {
                    dict.Document = Owner;
                }
                else
                {
                    Debug.Assert(dict.Owner == Owner);
                }

                // Search for indirect references in all keys
                PdfName[] names = dict.Elements.KeyNames;
                foreach (PdfName name in names)
                {
                    PdfItem item = dict.Elements[name];
                    // Is item an iref?
                    PdfReference iref = item as PdfReference;
                    if (iref != null)
                    {
                        // Does the iref already belong to this document?
                        if (iref.Document == Owner)
                        {
                            // Yes: fine
                            continue;
                        }
                        else
                        {
                            Debug.Assert(iref.Document == iot.ExternalDocument);
                            // No: replace with iref of cloned object
                            PdfReference newXRef = iot[iref.ObjectID];
                            Debug.Assert(newXRef != null);
                            Debug.Assert(newXRef.Document == Owner);
                            dict.Elements[name] = newXRef;
                        }
                    }
                    else if (item is PdfObject)
                    {
                        // Fix up inner objects
                        FixUpObject_old(iot, (PdfObject)item);
                    }
                }
            }
            else if ((array = value as PdfArray) != null)
            {
                // Set document for cloned direct objects
                if (array.Owner == null)
                {
                    array.Document = Owner;
                }
                else
                {
                    Debug.Assert(array.Owner == Owner);
                }

                // Search for indirect references in all array elements
                int count = array.Elements.Count;
                for (int idx = 0; idx < count; idx++)
                {
                    PdfItem item = array.Elements[idx];
                    // Is item an iref?
                    PdfReference iref = item as PdfReference;
                    if (iref != null)
                    {
                        // Does the iref belongs to this document?
                        if (iref.Document == Owner)
                        {
                            // Yes: fine
                            continue;
                        }
                        else
                        {
                            Debug.Assert(iref.Document == iot.ExternalDocument);
                            // No: replace with iref of cloned object
                            PdfReference newXRef = iot[iref.ObjectID];
                            Debug.Assert(newXRef != null);
                            Debug.Assert(newXRef.Document == Owner);
                            array.Elements[idx] = newXRef;
                        }
                    }
                    else if (item is PdfObject)
                    {
                        // Fix up inner objects
                        FixUpObject_old(iot, (PdfObject)item);
                    }
                }
            }
        }
        void TransitiveClosureImplementation(Dictionary <PdfItem, object> objects, PdfObject pdfObject /*, ref int depth*/)
        {
            try
            {
                _nestingLevel++;
                if (_nestingLevel >= 1000)
                {
                    if (!_overflow.ContainsKey(pdfObject))
                    {
                        _overflow.Add(pdfObject, null);
                    }
                    return;
                }
#if DEBUG_
                //enterCount++;
                if (enterCount == 5400)
                {
                    GetType();
                }
                //if (!Object.ReferenceEquals(pdfObject.Owner, _document))
                //  GetType();
                //////Debug.Assert(Object.ReferenceEquals(pdfObject27.Document, _document));
                //      if (item is PdfObject && ((PdfObject)item).ObjectID.ObjectNumber == 5)
                //        Debug.WriteLine("items: " + ((PdfObject)item).ObjectID.ToString());
                //if (pdfObject.ObjectNumber == 5)
                //  GetType();
#endif

                IEnumerable   enumerable = null; //(IEnumerator)pdfObject;
                PdfDictionary dict;
                PdfArray      array;
                if ((dict = pdfObject as PdfDictionary) != null)
                {
                    enumerable = dict.Elements.Values;
                }
                else if ((array = pdfObject as PdfArray) != null)
                {
                    enumerable = array.Elements;
                }
                else
                {
                    Debug.Assert(false, "Should not come here.");
                }

                if (enumerable != null)
                {
                    foreach (PdfItem item in enumerable)
                    {
                        PdfReference iref = item as PdfReference;
                        if (iref != null)
                        {
                            // Is this an indirect reference to an object that does not exist?
                            //if (iref.Document == null)
                            //{
                            //    Debug.WriteLine("Dead object detected: " + iref.ObjectID.ToString());
                            //    PdfReference dead = DeadObject;
                            //    iref.ObjectID = dead.ObjectID;
                            //    iref.Document = _document;
                            //    iref.SetObject(dead.Value);
                            //    PdfDictionary dict = (PdfDictionary)dead.Value;

                            //    dict.Elements["/DeadObjectCount"] =
                            //      new PdfInteger(dict.Elements.GetInteger("/DeadObjectCount") + 1);

                            //    iref = dead;
                            //}

                            if (!ReferenceEquals(iref.Document, _document))
                            {
                                GetType();
                                Debug.WriteLine(String.Format("Bad iref: {0}", iref.ObjectID.ToString()));
                            }
                            Debug.Assert(ReferenceEquals(iref.Document, _document) || iref.Document == null, "External object detected!");
#if DEBUG_
                            if (iref.ObjectID.ObjectNumber == 23)
                            {
                                GetType();
                            }
#endif
                            if (!objects.ContainsKey(iref))
                            {
                                PdfObject value = iref.Value;

                                // Ignore unreachable objets.
                                if (iref.Document != null)
                                {
                                    // ... from trailer hack
                                    if (value == null)
                                    {
                                        iref = ObjectTable[iref.ObjectID];
                                        Debug.Assert(iref.Value != null);
                                        value = iref.Value;
                                    }
                                    Debug.Assert(ReferenceEquals(iref.Document, _document));
                                    objects.Add(iref, null);
                                    //Debug.WriteLine(String.Format("objects.Add('{0}', null);", iref.ObjectID.ToString()));
                                    if (value is PdfArray || value is PdfDictionary)
                                    {
                                        TransitiveClosureImplementation(objects, value /*, ref depth*/);
                                    }
                                }
                                //else
                                //{
                                //  objects2.Add(this[iref.ObjectID], null);
                                //}
                            }
                        }
                        else
                        {
                            PdfObject pdfObject28 = item as PdfObject;
                            //if (pdfObject28 != null)
                            //  Debug.Assert(Object.ReferenceEquals(pdfObject28.Document, _document));
                            if (pdfObject28 != null && (pdfObject28 is PdfDictionary || pdfObject28 is PdfArray))
                            {
                                TransitiveClosureImplementation(objects, pdfObject28 /*, ref depth*/);
                            }
                        }
                    }
                }
            }
            finally
            {
                _nestingLevel--;
            }
        }
예제 #18
0
 public void Write(PdfReference iref)
 {
   WriteSeparator(CharCat.Character);
   WriteRaw(iref.ToString());
   this.lastCat = CharCat.Character;
 }
예제 #19
0
        /// <summary>
        /// Reads the compressed object with the specified index.
        /// </summary>
        internal void ReadReferences(PdfCrossReferenceTable xrefTable)
        {
            ////// Create parser for stream.
            ////Parser parser = new Parser(_document, new MemoryStream(Stream.Value));
            for (int idx = 0; idx < _header.Length; idx++)
            {
                int objectNumber = _header[idx][0];
                int offset = _header[idx][1];

                PdfObjectID objectID = new PdfObjectID(objectNumber);

                // HACK: -1 indicates compressed object.
                PdfReference iref = new PdfReference(objectID, -1);
                ////iref.ObjectID = objectID;
                ////iref.Value = xrefStream;
                if (!xrefTable.Contains(iref.ObjectID))
                {
                    xrefTable.Add(iref);
                }
                else
                {
                    GetType();
                }
            }
        }