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

Refactor jpegtran as a re-usable module #696

Open
malaterre opened this issue Jun 15, 2023 · 4 comments
Open

Refactor jpegtran as a re-usable module #696

malaterre opened this issue Jun 15, 2023 · 4 comments

Comments

@malaterre
Copy link

I would make sense to provide the jpegtran functionalities through a module with a clean API.

Right now users have to copy portion of the JPEG internals in particular the famous jpegint.h private header to compile most of the jpegtran/transupp code.

This would expose functionalities of lossless editing of JPEG in a clean way (rotate, crop ...).

Thanks

@dcommander
Copy link
Member

It sounds simple, but the ramifications of it would be more complicated. It would mean supporting the jpegtran functions as a new external API (an extension of the libjpeg API), even though they were never designed as such. That would require paying more attention to the transform API design, with a specific eye toward user-friendliness, user-proofness, extensibility, and security. Whereas libjpeg-turbo stopped tracking libjpeg API/ABI changes introduced in libjpeg v9+, we still do borrow jpegtran features from libjpeg v9+ from time to time (since those are among the few IJG innovations in the post-Tom Lane era that didn't rely on extending the JPEG format in incompatible and non-standard/unsanctioned ways.) What you ask is possible, but it would require a lot of funding for the implementation and ongoing maintenance/support of the feature. Given that our project's budget is exhausted for the next year, that funding would have to be specifically provided by an organization that is willing to sponsor this feature.

Note that the TurboJPEG API already exposes some of the transform functionality. It would be a much easier task to extend that API to cover the transform features you need than it would be to add transform functionality to the libjpeg API.

@dcommander
Copy link
Member

@malaterre Would you be open to using the TurboJPEG API to satisfy this feature requirement? That would be much more likely to happen in the near term.

@malaterre
Copy link
Author

Would you be open to using the TurboJPEG API to satisfy this feature requirement?

Honestly, I am ok with the current API, even jtransform_parse_crop_spec is acceptable for my requirement. I'd like to keep the libjpeg API to be able to switch the implementation if need be.

0000000000006246 T jcopy_markers_execute
00000000000061a8 T jcopy_markers_setup
00000000000058b3 T jtransform_adjust_parameters
0000000000005bd2 T jtransform_execute_transform
0000000000003e37 T jtransform_parse_crop_spec
00000000000060be T jtransform_perfect_transform
00000000000041af T jtransform_request_workspace

@dcommander
Copy link
Member

What implementation would you switch to? libjpeg-turbo is backward API/ABI compatible with jpeg-6b through jpeg-8x (although it doesn't support all of the features in jpeg-8x), but it isn't compatible with jpeg-9x. The only other available implementation, AFAIK, is mozjpeg, which makes extreme performance sacrifices in the name of 10-15% better compression. And it goes without saying that, if I exposed the transformation functions, that would make us less compatible with the other implementations, and you would be even less able to switch.

I am trying my best to evolve the TurboJPEG API into a much more modern interface for JPEG compression/decompression/transformation than the libjpeg API, which is beholden to a 32-year legacy. I also proposed in #313 that the industry come together around completely rethinking the libjpeg API from the ground up, but IIRC only one person cared enough about that to even chime in. Absent that kind of overhaul, I am doing what I can with the limited funding I have, which is to keep incrementally improving TurboJPEG until it covers all but the most esoteric and legacy libjpeg use cases. Strategically, it makes more sense to invest in that than to invest in hacking a 32-year-old API. The libjpeg API is fundamentally fragile because it is so fine-grained and has so many different usage scenarios. It is essentially the API equivalent of CISC, and I would prefer to see the API equivalent of RISC. :) It seems like every time we extend the libjpeg API (for instance, to implement partial image decompression or lossless JPEG), it becomes a security albatross because we weren't able to test some of the millions of permutations of esoteric libjpeg features, and one or more of them inevitably exposes a security flaw in the new API feature. (Inevitably, this happens months or years after the funded development engagement has ended.) It is difficult to fuzz test the libjpeg API because it is so fine-grained, so most of our fuzzers are written against TurboJPEG.

All of that is not to say that what you propose is impossible, but all of that is to say that what you propose is expensive.

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

No branches or pull requests

2 participants