Reading JPEG 2000 images

I need to read JPEG 2000 images. Available options are:

Both of these are bindings to OpenJPEG, which is in C. They're very low level; they just expose the C API in Rust. Is there anything higher level that offers a safe interface? Does anything use these packages?

Also, the image crate wraps the crate mentioned by @H2CO3 and many more, if you need multiple image formats

Note that JPEG 2000 is not the same format as JPEG, and can’t be read with a JPEG decoder.

3 Likes

Oh, right, I missed the "2000" part…

Right, JPEG 2000 needs a completely different decoder than classic JPEG.

JPEG 2000 decoders are both rare and buggy. The main free one is OpenJPEG.. It's notorious for having subscript out of range errors in C code, some of which are exploitable. PDF decoders have been attacked that way. Latest vulnerability reports are CVE-2019-6988, CVE-2018-20846 and CVE-2018-16376.

Converting OpenJPEG to safe Rust would be a great project for someone. I put in a feature request in the image crate for that.

If there's nothing better, I'm considering running a command-line JPEG 2000 tool in a subprocess, for containment.

3 Likes

Maintainer speaking: Feature requests on image are more like a wish list for people to refer to when they want to contribute. Afaik there is not a single organization with a dedicated programmer contributing on a regular and frequent basis (It works just too well :smile:). We have some very awesome, somewhat singular, individual contributions though. And definitely not enough eyes to understand a possibly license/patent encumbered and non-free ISO standard. I mean, even Mozilla did not want to opt in to dedicating programmers for maintaining such a decoder.

If a quality decoder (preferrably in pure Rust) were to exist however I'd be honoured to go through PRs to integrate it.

There are good decoders, and open source decoders, but not good open source decoders.

Mozilla's comments were 12 years ago. The patent situation has improved, with most patents expired. That would have to be checked, of course.

It's too bad that none of the C to Rust transpilers generate safe Rust. Corrade, etc, would generate unsafe Rust code with the same subscript and pointer bugs. Useful automatic translation of C to Rust requires something which can deduce from C code how big arrays are supposed to be. As far as I know, nobody has done that yet. Decoders like the one for JPEG 2000 involve pulling array indices from the input data and using them as subscripts into tables. That's the worst case for buffer overflows. Great use case for safe Rust, if anyone does the job.

Current workaround: Run

opj_decompress -i signboard.j2k -o signboard.png

in a subprocess. Standard Ubuntu utility. If it crashes, it only takes down the subprocess instance.

Then someone with the available time and funds will have to do precisely that, but you can't expect that to happen naturally. Preferrably someone who already has access to ISO 15444 (note: 200 CHF to ISO is far too much to do this in the spare time for most hobbyists).

That's a bit of a naive understanding of buffer overflows. If one of the bad accesses turns out to be able to manipulate code flow (not very unlikely if there are multiple known 'crashes') then decoding might lead to remote code execution (RCE). That in turn compromises the system far beyond an isolated process.

2 Likes

I know. Maybe Rust's "subprocess" module should offer sandboxing.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.