Fix incorrect quality scaling when using qtables in JPEG encoder

When both `qtables` and `quality` are provided, Pillow previously passed
the raw `quality` value directly to `jpeg_add_quant_table()` as the scale
factor, which caused incorrect quantization.

This commit corrects the behavior by using `jpeg_quality_scaling(quality)`
to compute the proper JPEG quantization scaling factor, consistent with
`jpeg_set_quality()`.

This ensures expected compression behavior when custom qtables are used
alongside a specified quality level.
This commit is contained in:
Kylian Ronfleux--Corail 2025-04-10 07:31:05 +00:00
parent c8d98d56a0
commit e3c0ee6ae2

View File

@ -178,12 +178,13 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
if (context->quality != -1) {
quality = context->quality;
}
int scale_factor = jpeg_quality_scaling(quality);
for (i = 0; i < context->qtablesLen; i++) {
jpeg_add_quant_table(
&context->cinfo,
i,
&context->qtables[i * DCTSIZE2],
quality,
scale_factor,
FALSE
);
context->cinfo.comp_info[i].quant_tbl_no = i;
@ -193,7 +194,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
// jpeg_set_defaults created two qtables internally, but we only
// wanted one.
jpeg_add_quant_table(
&context->cinfo, 1, &context->qtables[0], quality, FALSE
&context->cinfo, 1, &context->qtables[0], scale_factor, FALSE
);
}
for (i = last_q; i < context->cinfo.num_components; i++) {