I have come up with a (possibly hacky and short-sighted) solution to this issue. I've only done limited testing, but it does seem to work for me. There were actually two issues in appending to a PdfStreamedDocument:

1. As I previously mentioned, the objects the PdfStreamedDocument uses for the length of the object conflict (by having the same object number) as the next in the source. 2. m_vecObjects.GetSize() is not an accurate description of the number of objects in a PdfStreamedDocument because streams are popped out of m_vecObjects are they are completed.

The patch that I've attached attempts to correct these issues by:

1.  'Reserving' object numbers in m_vecObjects before appending any objects
2. Using m_vecObjects.GetObjectCount() - 1 for the difference (this may not work in all cases; can someone verify?)

Hopefully this will fix the issue, or at least inspire a better fix to make it into the project.

- Mike Slegeir

Mike Slegeir wrote:
Sorry about the excessive replies, but I've figured out what's wrong, and I don't know how to fix it myself. What happens is when you copy a stream to the PdfStreamedDocument, it creates a new object for the length. Then the next object is copied (which has a conflicting object number with the just created length object). I think in order to handle this, some tweaking to FixObjectReferences may be necessary (since we've just created a new object which throws off references even more so) or the immediate writing of the stream length as the next object should be reconsidered. Any thoughts from someone more familiar with this?

- Mike Slegeir

Mike Slegeir wrote:
Alright, I've made a bit more progress on debugging this, but its only gotten stranger. I believe the root cause is that a couple of objects are being duplicated (9 and 11 I think in the document I attached). The weird part is that it seems like the duplicates come all the way from PdfDocument::Append which is strange because the code there should be the same for both the PdfMemDocument and PdfStreamedDocument. Yet the duplicate detecting code I added in PdfVecObjects::push_back doesn't complain when I'm using a PdfMemDocument to merge into. I'm really perplexed here and any insight will be helpful.

- Mike Slegeir

Mike Slegeir wrote:
I've narrowed this down a little. It looks like the problem is writing out the XRef and Trailer. The XRef overlaps itself at a few points (that's valid though, right?) and so the trailer's listed size comes from the last XRef subsection's first object and count (which is wrong because the last subsection was a short, overlapping subsection). I'm attaching a PDF generated from the PdfStreamedDocument merging. If someone with a better understanding could take a look at the XRef, I'd appreciate it. Thanks.

- Mike Slegeir

Mike Slegeir wrote:
I'm trying to use PdfStreamedDocument like so:
    PoDoFo::PdfStreamedDocument doc(out_filename);

    for(int i=0; i<num_inputs; ++i) {
        doc.Append( PoDoFo::PdfMemDocument(in_filenames[i]) );
    }

    doc.Close();
but the result is just two blank pages. I'm currently doing something like this:
   PoDoFo::PdfMemDocument doc;

    for(int i=0; i<num_inputs; ++i) {
        doc.Append( PoDoFo::PdfMemDocument(in_filenames[i]) );
    }

    doc.Write(out_filename);
which works perfectly fine. Is anyone able to offer some insight on why this doesn't work or any technical reasons that it shouldn't? I'd like to be able to use PdfStreamedDocument for this as merging lots of documents can take up a lot of memory seemingly unnecessarily.

- Mike Slegeir

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users
Index: src/PdfDocument.cpp
===================================================================
--- src/PdfDocument.cpp	(revision 1131)
+++ src/PdfDocument.cpp	(working copy)
@@ -223,7 +223,7 @@
 
 const PdfDocument & PdfDocument::Append( const PdfMemDocument & rDoc, bool bAppendAll )
 {
-    unsigned int difference = static_cast<unsigned int>(m_vecObjects.GetSize() + m_vecObjects.GetFreeObjects().size());
+    unsigned int difference = m_vecObjects.GetObjectCount() - 1;
 
 
     // Ulrich Arnold 30.7.2009: Because GetNextObject uses m_nObjectCount instead 
@@ -240,6 +240,7 @@
         ++itFree;
     }
 
+    m_vecObjects.ReserveObjectCount(rDoc.GetObjects().GetSize());
 	// append all objects first and fix their references
     TCIVecObjects it           = rDoc.GetObjects().begin();
     while( it != rDoc.GetObjects().end() )
@@ -248,11 +249,11 @@
                                              static_cast<unsigned int>((*it)->Reference().ObjectNumber() + difference), 0 ), *(*it) );
         m_vecObjects.push_back( pObj );
 
+        FixObjectReferences( pObj, difference );
+        
         if( (*it)->IsDictionary() && (*it)->HasStream() )
             *(pObj->GetStream()) = *((*it)->GetStream());
 
-        FixObjectReferences( pObj, difference );
-
         ++it;
     }
 
Index: src/PdfVecObjects.h
===================================================================
--- src/PdfVecObjects.h	(revision 1145)
+++ src/PdfVecObjects.h	(working copy)
@@ -190,6 +190,11 @@
      *  \returns the highest object number in the vector 
      */
     size_t GetObjectCount() const { return m_nObjectCount; }
+    
+    /** Reserves a number of object numbers for future use
+     *  \param nObjects number of objects to reserve continuous object numbers for
+     */
+    void ReserveObjectCount(size_t nObjects) { m_nObjectCount += nObjects; }
 
     /** Finds the object with the given reference in m_vecOffsets 
      *  and returns a pointer to it if it is found.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to