0351852d74
Currently some JPEG images are decoded by the built-in PDF.js decoder in `src/core/jpg.js`, while others attempt to use the browser JPEG decoder. This inconsistency seem unfortunate for a number of reasons:
- It adds, compared to the other image formats supported in the PDF specification, a fair amount of code/complexity to the image handling in the PDF.js library.
- The PDF specification support JPEG images with features, e.g. certain ColorSpaces, that browsers are unable to decode natively. Hence, determining if a JPEG image is possible to decode natively in the browser require a non-trivial amount of parsing. In particular, we're parsing (part of) the raw JPEG data to extract certain marker data and we also need to parse the ColorSpace for the JPEG image.
- While some JPEG images may, for all intents and purposes, appear to be natively supported there's still cases where the browser may fail to decode some JPEG images. In order to support those cases, we've had to implement a fallback to the PDF.js JPEG decoder if there's any issues during the native decoding. This also means that it's no longer possible to simply send the JPEG image to the main-thread and continue parsing, but you now need to actually wait for the main-thread to indicate success/failure first.
In practice this means that there's a code-path where the worker-thread is forced to wait for the main-thread, while the reverse should *always* be the case.
- The native decoding, for anything except the *simplest* of JPEG images, result in increased peak memory usage because there's a handful of short-lived copies of the JPEG data (see PR 11707).
Furthermore this also leads to data being *parsed* on the main-thread, rather than the worker-thread, which you usually want to avoid for e.g. performance and UI-reponsiveness reasons.
- Not all environments, e.g. Node.js, fully support native JPEG decoding. This has, historically, lead to some issues and support requests.
- Different browsers may use different JPEG decoders, possibly leading to images being rendered slightly differently depending on the platform/browser where the PDF.js library is used.
Originally the implementation in `src/core/jpg.js` were unable to handle all of the JPEG images in the test-suite, but over the last couple of years I've fixed (hopefully) all of those issues.
At this point in time, there's two kinds of failure with this patch:
- Changes which are basically imperceivable to the naked eye, where some pixels in the images are essentially off-by-one (in all components), which could probably be attributed to things such as different rounding behaviour in the browser/PDF.js JPEG decoder.
This type of "failure" accounts for the *vast* majority of the total number of changes in the reference tests.
- Changes where the JPEG images now looks *ever so slightly* blurrier than with the native browser decoder. For quite some time I've just assumed that this pointed to a general deficiency in the `src/core/jpg.js` implementation, however I've discovered when comparing two viewers side-by-side that the differences vanish at higher zoom levels (usually around 200% is enough).
Basically if you disable [this downscaling in canvas.js](
|
||
---|---|---|
.. | ||
annotation_spec.js | ||
api_spec.js | ||
bidi_spec.js | ||
cff_parser_spec.js | ||
clitests_helper.js | ||
clitests.json | ||
cmap_spec.js | ||
colorspace_spec.js | ||
core_utils_spec.js | ||
crypto_spec.js | ||
custom_spec.js | ||
display_svg_spec.js | ||
display_utils_spec.js | ||
document_spec.js | ||
encodings_spec.js | ||
evaluator_spec.js | ||
fetch_stream_spec.js | ||
function_spec.js | ||
jasmine-boot.js | ||
message_handler_spec.js | ||
metadata_spec.js | ||
murmurhash3_spec.js | ||
network_spec.js | ||
network_utils_spec.js | ||
node_stream_spec.js | ||
parser_spec.js | ||
pdf_find_controller_spec.js | ||
pdf_find_utils_spec.js | ||
pdf_history_spec.js | ||
primitives_spec.js | ||
stream_spec.js | ||
test_utils.js | ||
testreporter.js | ||
type1_parser_spec.js | ||
ui_utils_spec.js | ||
unicode_spec.js | ||
unit_test.html | ||
util_spec.js |