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