From e3c0ee6ae22a951461a998a00118fa155a5c97a3 Mon Sep 17 00:00:00 2001 From: Kylian Ronfleux--Corail <35237015+Kyliroco@users.noreply.github.com> Date: Thu, 10 Apr 2025 07:31:05 +0000 Subject: [PATCH] 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. --- src/libImaging/JpegEncode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libImaging/JpegEncode.c b/src/libImaging/JpegEncode.c index 3c11eac22..a2e2945bc 100644 --- a/src/libImaging/JpegEncode.c +++ b/src/libImaging/JpegEncode.c @@ -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++) {