- Package:
- src:pdf2djvu
- Source:
- pdf2djvu
- Submitter:
- Vincent Fourmond
- Date:
- 2022-02-17 22:39:02 UTC
- Severity:
- normal
- Tags:
- Blocked By:
-
Bug Title 764458 3
libpoppler46: splash backend interpolates images without Interpolate flag normal about 3 years ago
Hello, It seems that recent versions of pdf2djvu have dreadfully lowered their compression, to the point that now, systematically, the PDF file is smaller than the DJVU file. It used to work for me:
Hi Vincent! Upstream speaking here. * Vincent Fourmond <fourmond@debian.org>, 2014-09-03, 18:14: Do you have a practical use case for converting DjVu to PDF, and then back to DjVu? Or are you just using this example to illustrate the general problem? If you could send the files to me, it would be great.
I took a look at the files that were sent to me by Vincent, and I confirm there's a severe regression somewhere. I haven't understood the nature of the bug yet. I will investigate further.
As far as the PDF file Vincent sent to me in concerned, the problem is that Poppler tries to scale a binary image from 2566x3340 to 2566x3341. (Which is a bit odd, because the resulting page size is 2566x3340. I'm not sure yet if that's a bug in the PDF, or in Poppler.) This worked uneventfully until bilinear image scaling was implemented in Poppler: http://cgit.freedesktop.org/poppler/poppler/commit/?id=7248da095f67d57c3999cee7d980e62fd8a7cf49 https://bugs.freedesktop.org/show_bug.cgi?id=22138 Bilinear scaling introduces lots of gray pixels, which pdf2djvu tries to preserve, which has disastrous effect on the compression ratio. I think I could disable bilinear scaling in pdf2djvu, although I'd have to double check. But perhaps Poppler should be fixed not to use bilinear scaling when source and destination sizes are very close to each other. I'm not sure.
* Jakub Wilk <jwilk@debian.org>, 2014-09-11, 15:19: http://cgit.freedesktop.org/poppler/poppler/commit/?id=a97aead193a927b91a4e33d7b5d2ba7179e664df
* Jakub Wilk <jwilk@debian.org>, 2014-09-11, 15:19:
interpolate images or not:
static GBool isImageInterpolationRequired(int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
GBool interpolate) {
if (interpolate)
return gTrue;
/* When scale factor is >= 400% we don't interpolate. See bugs #25268, #9860 */
if (scaledWidth / srcWidth >= 4 || scaledHeight / srcHeight >= 4)
return gFalse;
return gTrue;
}
While I could force the “interpolate” flag to be always false, the
function returns true in the typical case anyway! And the function is
static, so there's no way to preempt it. :-(
This isImageInterpolationRequired() implementation does not seem to be
compliant with what PDF Reference 1.7 says:
“When the resolution of a source image is significantly lower than that
of the output device, each source sample covers many device pixels. As a
result, images can appear jaggy or blocky. These visual artifacts can be
reduced by applying an image interpolation algorithm during rendering.
Instead of painting all pixels covered by a source sample with the same
color, image interpolation attempts to produce a smooth transition
between adjacent sample values. Image interpolation is enabled by
setting the Interpolate entry in the image dictionary to true. It is
disabled by default because it may increase the time required to render
the image.
Note: The interpolation algorithm is implementation-dependent and is not
specified by PDF. Image interpolation may not always be performed for
some classes of images or on some output devices.”