Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for libvips JPEG 2000 one-shot load option #4262

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mbklein
Copy link
Contributor

@mbklein mbklein commented Nov 12, 2024

Last month, I reported an issue (libvips/libvips#4205) to libvips regarding errors loading certain JPEG 2000 files. The core issue is in the OpenJPEG library itself, and the issue has been reported there as well (uclouvain/openjpeg#1558). In short, when the source image is a JPEG 2000 image with more than one tile and more than one tile-part per tile, OpenJPEG will throw an error immediately upon trying to access the second tile in a given operation.

Until the upstream issue is addressed, the only good workaround seems to be to have libvips load the entire image in one shot instead of tile by tile. This feature has been added in a branch, with the expectation that it will be released as part of libvips 8.17 in a few months' time.

In the meantime, I thought I would create this PR so that you can evaluate the interface, option name, etc. and request any changes before the time comes to support the new option. I've included a derivative copy of the relax.jp2 test fixture, relax_tileparts.jp2, which includes the problematic tile layout.

Demonstration of the issue and the proposed workaround, using a version of sharp built with OpenJPEG v2.5.2 and the libvips branch linked above:

$ node --experimental-repl-await
Welcome to Node.js v20.5.0.
Type ".help" for more information.
> const sharp = require('sharp');
undefined
> await sharp('test/fixtures/relax_tileparts.jp2').toFormat('tif').toBuffer()
Uncaught Error: jp2kload: Invalid tile part index for tile number 1. Got 7, expected 0

jp2kload: Fail to read the current marker segment (0xff90)

jp2kload: Failed to decode the codestream in the JP2 file
    at Sharp.toBuffer (/Users/mbk836/Workspace/repos/lovell/sharp/lib/output.js:163:17)
    at REPL2:1:98
> await sharp('test/fixtures/relax_tileparts.jp2', { jp2Oneshot: true }).toFormat('tif').toBuffer()
<Buffer 49 49 2a 00 ca 40 00 00 ff d8 ff c0 00 11 08 00 f0 01 40 03 01 22 00 02 11 01 03 11 01 ff da 00 0c 03 01 00 02 11 03 11 00 3f 00 f0 38 cb 2b 47 2d cc ... 17396 more bytes>

@lovell
Copy link
Owner

lovell commented Nov 18, 2024

Thank you for the PR Michael, and thank you for adding this feature to libvips also. I'll mark this as waiting for the upstream dependency to be released, then we can take a look at merging it. The API you propose looks good 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants