serverless-iiif icon indicating copy to clipboard operation
serverless-iiif copied to clipboard

Mostly jp2 images are not opening it is working in cantaloupe.Attaching error screenshot

Open ranjeetsinghthirdrock opened this issue 1 year ago • 18 comments

Screenshot from 2024-08-07 12-00-39

ranjeetsinghthirdrock avatar Aug 07 '24 06:08 ranjeetsinghthirdrock

Image url=https://uat-iiif.newmanstudies.org/iiif/2/TRT%2F01_Franciscan_Christocentrism_page-0003.jp2/full/full/0/default.jpg

ranjeetsinghthirdrock avatar Aug 07 '24 07:08 ranjeetsinghthirdrock

@orangewolf Is this something you've seen before?

mbklein avatar Aug 12 '24 17:08 mbklein

I was wondering if this was resolved. I ran into the same problem when using jp2 images.

guillenjs avatar Oct 04 '24 15:10 guillenjs

@ranjeetsinghthirdrock @guillenjs Do you have any jp2 source images you can share with me so that I can try to reproduce and fix this issue? You can either attach them here or email them to [my github username] at gmail.

mbklein avatar Oct 08 '24 14:10 mbklein

@ranjeetsinghthirdrock After some debugging with a sample file provided by @guillenjs, I have narrowed the issue down to the JP2 loader in the underlying libvips image processing library. I have submitted a bug report in hopes of getting things working. If either of you would be willing to let me attach any of the files that are giving you trouble to that issue (or even attach them yourselves in comments), it would go a long way to helping resolve the issue.

mbklein avatar Oct 15 '24 22:10 mbklein

@mbklein here is another sample image that is not opening https://4slvho3i5lch7kp6zdultsdumq0ihqta.lambda-url.us-east-1.on.aws/iiif/2/TRT%2F01_A8.jp2/full/100,/0/default.jpg

ranjeetsinghthirdrock avatar Oct 16 '24 05:10 ranjeetsinghthirdrock

@ranjeetsinghthirdrock Would it be possible to share the source JP2 file for that image? Either by zipping/attaching it here, or by emailing it to mbklein at gmail?

mbklein avatar Oct 16 '24 16:10 mbklein

@ranjeetsinghthirdrock @guillenjs The underlying issue is with the OpenJPEG library that provides JPEG 2000 support. It looks like there's going to be a libvips release with a workaround – not an ideal one, as it depends on loading the entire frame instead of just the tiles required to complete the request, but I've tested it on my development server and the lag isn't terrible. But it's the best option available until the upstream issue is addressed.

I've also reached out to the team at Kakadu to ask how their licensing might work given the way our distribution works. It would require downstream users (i.e., you) to obtain a valid license for the Kakadu libraries, but if you've had this working in Cantaloupe, it's possible you've already been using the KakaduNativeProcessor with a license? (If you've been using the Cantaloupe OpenJpegProcessor, you may not even notice the performance hit from the libvips workaround mentioned above.)

mbklein avatar Oct 29 '24 20:10 mbklein

@mbklein Thank you for all the work on this front! Is there a projected date when this update may be released so we can start testing on our end?

guillenjs avatar Oct 30 '24 19:10 guillenjs

I'm currently testing with the libvips branch with the fix in it. Once it's stable, the maintainer will have to approve, merge, and release it, and then I can build and push a Lambda layer with support for it. I hope it'll be soon – closer to "a couple weeks" than "a few weeks."

mbklein avatar Oct 30 '24 23:10 mbklein

I'm afraid I didn't quite understand the libvips release schedule, so it might be six months or so before the fix is in a release. That said, there's nothing stopping me from building a lambda layer with the pre-release workaround in it, so I'll let you know when it's available.

mbklein avatar Nov 01 '24 17:11 mbklein

@ranjeetsinghthirdrock @guillenjs I've just released serverless-iiif v5.1.1 with support for the sharp/libvips/openjpeg workaround for this issue. It uses as-yet unreleased code from libvips and a forked version of sharp that enables the workaround code. I'll update to the released versions as the code make it into upstream releases.

If you have a chance, could you install or upgrade to that version and see if it fixes the problems you're having?

mbklein avatar Nov 09 '24 17:11 mbklein

@mbklein, thank you for the update. I will test this out this week and get back to you about it.

guillenjs avatar Nov 12 '24 14:11 guillenjs

@mbklein I have been testing the new v5.1.1 release, and generally, everything seems to be working fine. I did try and find a large file that is 20,000+ pixels and 18.6MB. That is the one file that I seem to be struggling to work correctly. It is not the same issue as before. If I request a smaller size, I get the image returned, but when I request a full-size image, I get an "Internal server error."

So, I am wondering if there is a max pixel width/height that would be ideal to stay under.

Thanks again for the all the help!

guillenjs avatar Nov 19 '24 14:11 guillenjs

It's less about pixel width and more about memory – if you look at the CloudWatch logs for that request you'll probably see something like

REPORT RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Billed Duration: 3000 ms   Memory Size: 3008 MB   Max Memory Used: 3009 MB
RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Process exited before completing request

If you deployed it using the default parameters, you could try bumping up the IiifLambdaMemory setting. It can go as high as 10240. But since the workaround for the issue we've been focused on involves loading the entire image into memory in one shot (instead of one tile at a time), it's also very likely that very large JPEG 2000 images with the multipart tile layout will eat way more memory than they would otherwise.

mbklein avatar Nov 20 '24 04:11 mbklein

Hello, I saw related issue opened on openjpeg tracker - there is an alternative to OpenJPEG and Kakadu that might help

https://github.com/GrokImageCompression/grok https://www.bitsgalore.org/2022/03/30/generating-lossy-access-jp2s-from-lossless-preservation-masters

Grok (an older version) has been integrated into Cantaloupe but I'm not sure about adoption.

boxerab avatar Nov 27 '24 16:11 boxerab

Thanks for pointing that out, @boxerab. I've passed that info along to the libvips maintainer; it'll be up to him to decide whether to add support for it.

mbklein avatar Dec 02 '24 15:12 mbklein

libvips v8.17.0 has been released with support for the jp2Oneshot option, and the flag to enable it is in the current sharp release candidate. Once sharp is released with the flag, I'll update the lambda layer with the released versions.

mbklein avatar Jun 23 '25 18:06 mbklein

@mbklein was the jp2Oneshot option added into the 6.0.1 release? Unfortunately, still seeing the issue if it was added. I can provide a source image to reproduce if it helps with your testing. Thanks in advance.

START RequestId: 66ca7d44-7eb3-4af8-800c-831bd123c648 Version: $LATEST	
2025-11-19T15:26:42.100-08:00
	
2025-11-19T23:26:42.100Z 66ca7d44-7eb3-4af8-800c-831bd123c648 WARN Unable to get dimensions for healthcheckimage.jpx using custom function. Falling back to sharp.metadata().
	
2025-11-19T15:26:42.429-08:00
	
2025-11-19T23:26:42.429Z 66ca7d44-7eb3-4af8-800c-831bd123c648 INFO Encountered JP2 tile part index error. Trying oneshot load.
	
2025-11-19T15:26:42.470-08:00
	
2025-11-19T23:26:42.470Z 66ca7d44-7eb3-4af8-800c-831bd123c648 WARN Unable to get dimensions for healthcheckimage.jpx using custom function. Falling back to sharp.metadata().
	
2025-11-19T15:26:42.675-08:00
	
2025-11-19T23:26:42.675Z 66ca7d44-7eb3-4af8-800c-831bd123c648 ERROR Error: jp2kload_buffer: Invalid tile part index for tile number 1. Got 6, expected 0 jp2kload_buffer: Fail to read the current marker segment (0xff90) jp2kload_buffer: Failed to decode the codestream in the JP2 file at Sharp.toBuffer (/opt/nodejs/node_modules/sharp/lib/output.js:163:17) at /var/task/index.js:44144:32 at process.processTicksAndRejections (node:internal/process/task_queues:105:5) at async Processor.withStream (/var/task/index.js:44056:14) at async Processor.iiifImage (/var/task/index.js:44137:20) at async Processor.execute (/var/task/index.js:44160:14) at async executeWithJp2Retry (/var/task/index.js:44506:14) at async handleImageRequest (/var/task/index.js:44523:20) at async /var/task/index.js:44463:16 at async Runtime.handler (/var/task/index.js:44410:20)
	
2025-11-19T15:26:42.678-08:00
	
END RequestId: 66ca7d44-7eb3-4af8-800c-831bd123c648
	
2025-11-19T15:26:42.678-08:00
	
REPORT RequestId: 66ca7d44-7eb3-4af8-800c-831bd123c648 Duration: 600.45 ms Billed Duration: 601 ms Memory Size: 2048 MB Max Memory Used: 162 MB ```

cachemeoutside avatar Nov 19 '25 23:11 cachemeoutside

@cachemeoutside Yes, jp2Oneshot should be working in 6.0.1. A source image would be great.

mbklein avatar Nov 25 '25 15:11 mbklein

v6.0.2 released. I missed where sharp had nested all of its format-specific constructor options, so jp2Oneshot became jp2.oneshot.

mbklein avatar Dec 01 '25 22:12 mbklein