However, using this default JxlExportParams, the export time will be multiple times the magnitude of the time using vips/cjxl.
From cjxl --help:
-e EFFORT, --effort=EFFORT
Encoder effort setting. Range: 1 .. 9.
Default: 7. Higher number is more effort (slower).
-d maxError, --distance=maxError
Max. butteraugli distance, lower = higher quality.
0.0 = mathematically lossless. Default for already-lossy input (JPEG/GIF).
1.0 = visually lossless. Default for other input.
Recommended range: 0.5 .. 3.0. Allowed range: 0.0 ... 25.0.
Mutually exclusive with --quality.
--compress_boxes=0|1
Disable/enable Brotli compression for metadata boxes (not provided = default, 0 = disable, 1 = enable).
--brotli_effort=B_EFFORT
Brotli effort setting. Range: 0 .. 11.
Default: 9. Higher number is more effort (slower).
--faster_decoding=0|1|2|3|4
Favour higher decoding speed. 0 = default, higher values give higher speed at the expense of quality
From libvips:
/**
* vips_jxlsave: (method)
* @in: image to save
* @filename: file to write to
* @...: %NULL-terminated list of optional named arguments
*
* Optional arguments:
*
* * @tier: %gint, decode speed tier
* * @distance: %gdouble, maximum encoding error
* * @effort: %gint, encoding effort
* * @lossless: %gboolean, enables lossless compression
* * @Q: %gint, quality setting
*
* Write a VIPS image to a file in JPEG-XL format.
*
* The JPEG-XL loader and saver are experimental features and may change
* in future libvips versions.
*
* @tier sets the overall decode speed the encoder will target. Minimum is 0
* (highest quality), and maximum is 4 (lowest quality). Default is 0.
*
* @distance sets the target maximum encoding error. Minimum is 0
* (highest quality), and maximum is 15 (lowest quality). Default is 1.0
* (visually lossless).
*
* As a convenience, you can also use @Q to set @distance. @Q uses
* approximately the same scale as regular JPEG.
*
* Set @lossless to enable lossless compression.
*
* Returns: 0 on success, -1 on error.
*/
We can see that default distance used by libvips is 1.0(rather than zero-value in Go of 0.0), so this PR adds Distance 1.0 to NewJxlExportParams.
And there seems a mismatch that tier option is not available in cjxl.
The only tier I can find in libjxl are these:
enum class SpeedTier {
// Try multiple combinations of Glacier flags for modular mode. Otherwise
// like kGlacier.
kTectonicPlate = -1,
// Learn a global tree in Modular mode.
kGlacier = 0,
// Turns on FindBestQuantizationHQ loop. Equivalent to "guetzli" mode.
kTortoise = 1,
// Turns on FindBestQuantization butteraugli loop.
kKitten = 2,
// Turns on dots, patches, and spline detection by default, as well as full
// context clustering. Default.
kSquirrel = 3,
// Turns on error diffusion and full AC strategy heuristics. Equivalent to
// "fast" mode.
kWombat = 4,
// Turns on gaborish by default, non-default cmap, initial quant field.
kHare = 5,
// Turns on simple heuristics for AC strategy, quant field, and clustering;
// also enables coefficient reordering.
kCheetah = 6,
// Turns off most encoder features. Does context clustering.
// Modular: uses fixed tree with Weighted predictor.
kFalcon = 7,
// Currently fastest possible setting for VarDCT.
// Modular: uses fixed tree with Gradient predictor.
kThunder = 8,
// VarDCT: same as kThunder.
// Modular: no tree, Gradient predictor, fast histograms
kLightning = 9
};
Tests
I have a JPG photo shot by Sony A7M3 with size of 11MB.
Using vips took 3.8s
time vips copy 1.jpg output.jxl --vips-progress
vips temp-4: 6000 x 4000 pixels, 16 threads, 6000 x 16 tiles, 384 lines in buffer
vips temp-4: done in 0.181s
vips copy 1.jpg output.jxl --vips-progress 13.55s user 2.20s system 413% cpu 3.804 total
Using cjxl 0.8.2 took 1.7s
time cjxl --num_threads=0 1.jpg 1.jxl
JPEG XL encoder v0.8.2 [AVX2,SSE4,SSSE3,SSE2]
Note: Implicit-default for JPEG is lossless-transcoding. To silence this message, set --lossless_jpeg=(1|0).
Read JPEG image with 11942483 bytes.
Encoding [Container | JPEG, lossless transcode, effort: 7 | JPEG reconstruction data],
Compressed to 9922997 bytes including container
cjxl --num_threads=0 1.jpg 1.jxl 1.33s user 0.44s system 99% cpu 1.769 total
coverage: 73.206% (-0.03%) from 73.232%
when pulling 3336e6def156d2997e79d565d80836e41a69fb0a on webp-sh:master
into 143c4c119b385f38e85f0402b9bb1d161c6ccb5d on davidbyttow:master.
Currently
NewJxlExportParams
returns the following struct:However, using this default
JxlExportParams
, the export time will be multiple times the magnitude of the time usingvips
/cjxl
.From
cjxl --help
:From
libvips
:We can see that default
distance
used bylibvips
is 1.0(rather than zero-value in Go of 0.0), so this PR adds Distance 1.0 toNewJxlExportParams
.And there seems a mismatch that
tier
option is not available incjxl
.The only
tier
I can find inlibjxl
are these:Tests
I have a JPG photo shot by Sony A7M3 with size of 11MB.
Using
vips
took 3.8sUsing
cjxl
0.8.2 took 1.7sUsing
govips
withNewJxlExportParams
took 85.89sUsing
govips
withDistance 1.0
took 8.28sHowever, this is still much slower than
vips
orcjxl
, maybe we should change defaultEffort
orTier
to 4? I have some benchmark here: