diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index 6145e5da7..7d2a8fdc6 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -36,6 +36,7 @@ import io import os import struct import subprocess +import sys import tempfile import warnings @@ -244,15 +245,16 @@ def DQT(self, marker): n = i16(self.fp.read(2)) - 2 s = ImageFile._safe_read(self.fp, n) while len(s): - if len(s) < 65: - raise SyntaxError("bad quantization table marker") v = i8(s[0]) - if v // 16 == 0: - self.quantization[v & 15] = array.array("B", s[1:65]) - s = s[65:] - else: - return # FIXME: add code to read 16-bit tables! - # raise SyntaxError, "bad quantization table element size" + precision = 1 if (v // 16 == 0) else 2 # in bytes + qt_length = 1 + precision * 64 + if len(s) < qt_length: + raise SyntaxError("bad quantization table marker") + data = array.array("B" if precision == 1 else "H", s[1:qt_length]) + if sys.byteorder == "little" and precision > 1: + data.byteswap() # the values are always big-endian + self.quantization[v & 15] = data + s = s[qt_length:] # @@ -683,7 +685,7 @@ def _save(im, fp, filename): try: if len(table) != 64: raise TypeError - table = array.array("B", table) + table = array.array("H", table) except TypeError as e: raise ValueError("Invalid quantization table") from e else: diff --git a/src/libImaging/JpegEncode.c b/src/libImaging/JpegEncode.c index b255025fa..0f73666f1 100644 --- a/src/libImaging/JpegEncode.c +++ b/src/libImaging/JpegEncode.c @@ -159,22 +159,21 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) quality = context->quality; } for (i = 0; i < context->qtablesLen; i++) { - // TODO: Should add support for none baseline jpeg_add_quant_table(&context->cinfo, i, &context->qtables[i * DCTSIZE2], - quality, TRUE); + quality, FALSE); context->cinfo.comp_info[i].quant_tbl_no = i; last_q = i; } if (context->qtablesLen == 1) { // jpeg_set_defaults created two qtables internally, but we only wanted one. jpeg_add_quant_table(&context->cinfo, 1, &context->qtables[0], - quality, TRUE); + quality, FALSE); } for (i = last_q; i < context->cinfo.num_components; i++) { context->cinfo.comp_info[i].quant_tbl_no = last_q; } } else if (context->quality != -1) { - jpeg_set_quality(&context->cinfo, context->quality, 1); + jpeg_set_quality(&context->cinfo, context->quality, FALSE); } /* Set subsampling options */