[poppler] patch for a progress callback

Adrian Johnson ajohnson at redneon.com
Sun Jan 6 00:05:56 PST 2013


On 06/01/13 06:56, Albert Astals Cid wrote:
> El Divendres, 4 de gener de 2013, a les 09:16:25, Damian Stewart va escriure:
>> Hey all,
> 
> Hi
> 
>> My wife makes makes generative images (http://liaworks.com) using
>> openFrameworks and exports them to PDF documents for large-format printing
>> (100cm width at 300dpi). She often ends up with 10MB pdf docs containing
>> tens of thousands of lines that can take between 30 minutes and 2 hours to
>> render at print resolution.
>>
>> To make the experience less miserable I built a progress callback into
>> poppler. It's integrated into Page::displaySlice. If a progress callback is
>> passed, displaySlice() does a preprocessing step where it constructs a
>> DummyOutputDev and asks Gfx to render to that dev, counting the number of
>> operations performed. Then it performs the real render to the passed output
>> dev, calling the progress callback for every operation with a progress
>> percent (0..1), a page number and optional user data.
> 
> Some comments:
>  * The cpp facing api seems quite "un-C++-ish", i think that a class with a 
> pure virtual progressDone() function and a Page::setProgressHandler method 
> would make it more C++ish
>  * How useful is this? I.e. i predict that there are operations that are 
> really fast and others really slow, does it really help?

This is the biggest problem I see with this patch. There are PDFs with
one huge image. In this case the progress will sit on 0% for a long time
then jump 100% when rendering is finished. It also doesn't take into
account XObjects and patterns which may also take a long time to render
with no progress available. There are PDFs with a single XObject painted
in the content stream. All the work is done in the XObject.

If we merge this feature what do we do when users start filing bugs
about these cases that don't provide useful progress feedback?

>  * The DummyOutputDev should take the real outputdev and return the values of 
> the real outputdev for the "querying" functions, e.g. your dummy outpudev 
> returns false for useTilingPatternFill, but SplashOutputDev returns true, this 
> probably means that you never get to 100% on files that have patterns, no?
>  * Have you measured the performance hit?

I would also like to know the performance cost of rendering to
DummyOutputDev.

Have you got a sample PDF we can test with? It would be interesting to
see if there is anything that can be done to speed up the rendering.

I don't think calling the progress callback on every operation is
efficient or necessary. It should be sufficient to call the callback
every n operations. I suggest making n = TotalOperations/100.

Instead of parsing the content twice to get the operation count you
could use the current position in the content stream to report progress.
You would have to use the compressed stream position
(getBaseStream()->getLength()) since the uncompressed length of a stream
is not stored in the pdf file.

> 
>>
>> As far as the outwards-facing parts of Poppler are concerned, I have only
>> added the progress callback to the poppler::page_renderer class in the C++
>> API. I can supply a demo application built using the C++ API if that helps.
>>
>> Please find the patch attached; apologies if this is not the correct way to
>> do submit patches.
> 
> This is fine.
> 
> Cheers,
>   Albert
> 
>>
>> Thanks (Poppler is awesome!)
>> Damian
> _______________________________________________
> poppler mailing list
> poppler at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/poppler
> 



More information about the poppler mailing list