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

Support for MozJPEG #7

Open
shirok1 opened this issue Sep 10, 2022 · 8 comments
Open

Support for MozJPEG #7

shirok1 opened this issue Sep 10, 2022 · 8 comments

Comments

@shirok1
Copy link

shirok1 commented Sep 10, 2022

Hi, I heard that MozJPEG is a immediate replacement(actually a fork) of turbojpeg. Would you consider making it an option?

@shirok1
Copy link
Author

shirok1 commented Sep 10, 2022

Existing crate https://github.com/ImageOptim/mozjpeg-rust don't have support for image, and require to use std::panic::catch_unwind.

@honzasp
Copy link
Owner

honzasp commented Sep 11, 2022

Hi, thanks for the suggestion! :) I will look into this in a few days and will get back to you.

@honzasp
Copy link
Owner

honzasp commented Sep 15, 2022

I verified that turbojpeg-sys works with MozJPEG without problems. One way to use MozJPEG right now is to build it from source and use TURBOJPEG_SOURCE=explicit and TURBOJPEG_LIB_DIR environment variables when building turbojpeg-sys:

# grab a copy of mozjpeg to /tmp/mozjpeg
$ git clone [email protected]:mozilla/mozjpeg.git /tmp/mozjpeg --depth 1

# build it
$ pushd /tmp/mozjpeg && mkdir build && cd build
$ cmake ..
$ make
$ popd

# point `turbojpeg-sys` towards your build of mozjpeg
$ TURBOJPEG_SOURCE=explicit TURBOJPEG_LIB_DIR=/tmp/mozjpeg/build cargo b

One way to make it easier to use MozJPEG instead of TurboJPEG would be to vendor MozJPEG into the turbojpeg-sys crate and let the user pick which one to use using an optional feature. However, this would increase the crate size by another 4 MB, putting the overall crate size dangerously close to the 10 MB limit on crates.io.

But I see that mozjpeg is about 16x more popular than turbojpeg on crates.io, so perhaps this would be the way forward? I wonder, what is your use case and the reason that you prefer MozJPEG to TurboJPEG? :)

@shirok1
Copy link
Author

shirok1 commented Sep 15, 2022

use TURBOJPEG_SOURCE=explicit and TURBOJPEG_LIB_DIR environment variables when building turbojpeg-sys

I'll take that. It seems that environment variables can be easily set in .cargo/config.toml, and MozJPEG is not a "standard" library to be accepted by major distrobutions. (I'm using MozJPEG from AUR, as a replacement of system libjpeg-turbo packackge. Wait, does that mean I can just build it using TURBOJPEG_SOURCE=pkg-config?)

what is your use case and the reason that you prefer MozJPEG to TurboJPEG?

I heard that file encoded by MozJPEG have better quality? Anyway I'm just finding a replacement for image's builtin JPEG encoder for my robotic communication. The builtin one is far too slow.

@honzasp
Copy link
Owner

honzasp commented Sep 15, 2022

Wait, does that mean I can just build it using TURBOJPEG_SOURCE=pkg-config?

I think so, if pkg-config libturbojpeg points to MozJPEG and you pass TURBOJPEG_SOURCE=pkg-config, then turbojpeg-sys should pick it up.

Anyway I'm just finding a replacement for image's builtin JPEG encoder for my robotic communication. The builtin one is far too slow.

As far as I understand, MozJPEG trades small increase in compression ratio for a large increase in compression time. If you are concerned about speed, then maybe TurboJPEG will work better?

https://libjpeg-turbo.org/About/Mozjpeg

@uwejan
Copy link

uwejan commented Jan 30, 2023

One way to make it easier to use MozJPEG instead of TurboJPEG would be to vendor MozJPEG into the turbojpeg-sys crate and let the user pick which one to use using an optional feature. However, this would increase the crate size by another 4 MB, putting the overall crate size dangerously close to the 10 MB limit on crates.io.

This is completley worth it. I would really like the flexibility where you can get the best of two worlds.
Can we have this please?

@honzasp
Copy link
Owner

honzasp commented Feb 1, 2023

This is completley worth it. I would really like the flexibility where you can get the best of two worlds. Can we have this please?

Thank you for your interest in this library, @uwejan! :) The problem with MozJPEG is that it has opposite goals than libjpeg-turbo: libjpeg-turbo aims to be very fast, and MozJPEG aims to provide high-quality compression and is therefore much slower.

This means that we cannot use a Cargo feature to switch from TurboJPEG to MozJPEG: if two crates in the same project depended on turbojpeg crate, and crate A wanted TurboJPEG (no features) and crate B wanted MozJPEG (feature mozjpeg), the features would get unified and crate A would get linked with MozJPEG!

Another problem is that mozjpeg extensions are exposed via the original libjpeg API, but this crate uses the TurboJPEG API.


This means that the ideal scenario is as follows:

  • This crate uses normal libjpeg-turbo by default.
  • An optional feature mozjpeg will apply the MozJPEG patches to libjpeg-turbo.
  • When mozjpeg is enabled, an additional runtime method on the Compressor struct can be used to enable MozJPEG optimization. (This makes sure that code that does not explicitly opt-in for MozJPEG optimizations will get TurboJPEG performance.)

To do this, we will need to resolve these technical questions:

  1. How to optionally apply the MozJPEG patches when building turbojpeg-sys (this might be as easy as distributing a literal patch file and applying it to the libjpeg-turbo sources before compilation).
  2. How to turn the MozJPEG optimizations on and off when using the TurboJPEG API.

The second question is the harder problem: I have zero experience with the libjpeg API (that's why I use the TurboJPEG API in the first place!), so I will welcome any advice on how to solve this :)

@uwejan
Copy link

uwejan commented Feb 1, 2023

@honzasp Thank you for sharing. Here is my 1 cent.
Regarding the second question. I am not familar at all for libjpeg. The reason i suggested is that once i was testing compression crates, I came accross mozjpeg-sys, the API seems over complicated cpmaring to the nice one you have made here. BUT it seems that mozjpeg-sys has an option to have fast encoding, adn also helped reducing the image size 50kb lesss that rust-turbojpeg, the comparsion criteria are tricky here i know that but i would say i tried my best to make it semilare till i got same eye visual quality but less 50kb. Now the speed/performance part am not sure about but i opted for the fast option.
I could not go further and do propper testing because there was not an easy way to abstract it as struct and play with the encoding params on the fly and watch out resources consumption.

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

No branches or pull requests

3 participants