mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-27 09:44:31 +03:00
Add support for 16-bit precision JPEG quantization values
Don't force JPEG quantization to be baseline-compatible Quantization values will not be limited to values 1..255 and may be 16 bits if needed. This may cause compatibility issues.
This commit is contained in:
parent
2e029d9a79
commit
6db0843af4
|
@ -36,6 +36,7 @@ import io
|
||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
@ -244,15 +245,16 @@ def DQT(self, marker):
|
||||||
n = i16(self.fp.read(2)) - 2
|
n = i16(self.fp.read(2)) - 2
|
||||||
s = ImageFile._safe_read(self.fp, n)
|
s = ImageFile._safe_read(self.fp, n)
|
||||||
while len(s):
|
while len(s):
|
||||||
if len(s) < 65:
|
|
||||||
raise SyntaxError("bad quantization table marker")
|
|
||||||
v = i8(s[0])
|
v = i8(s[0])
|
||||||
if v // 16 == 0:
|
precision = 1 if (v // 16 == 0) else 2 # in bytes
|
||||||
self.quantization[v & 15] = array.array("B", s[1:65])
|
qt_length = 1 + precision * 64
|
||||||
s = s[65:]
|
if len(s) < qt_length:
|
||||||
else:
|
raise SyntaxError("bad quantization table marker")
|
||||||
return # FIXME: add code to read 16-bit tables!
|
data = array.array("B" if precision == 1 else "H", s[1:qt_length])
|
||||||
# raise SyntaxError, "bad quantization table element size"
|
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:
|
try:
|
||||||
if len(table) != 64:
|
if len(table) != 64:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
table = array.array("B", table)
|
table = array.array("H", table)
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
raise ValueError("Invalid quantization table") from e
|
raise ValueError("Invalid quantization table") from e
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -159,22 +159,21 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
quality = context->quality;
|
quality = context->quality;
|
||||||
}
|
}
|
||||||
for (i = 0; i < context->qtablesLen; i++) {
|
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],
|
jpeg_add_quant_table(&context->cinfo, i, &context->qtables[i * DCTSIZE2],
|
||||||
quality, TRUE);
|
quality, FALSE);
|
||||||
context->cinfo.comp_info[i].quant_tbl_no = i;
|
context->cinfo.comp_info[i].quant_tbl_no = i;
|
||||||
last_q = i;
|
last_q = i;
|
||||||
}
|
}
|
||||||
if (context->qtablesLen == 1) {
|
if (context->qtablesLen == 1) {
|
||||||
// jpeg_set_defaults created two qtables internally, but we only wanted one.
|
// jpeg_set_defaults created two qtables internally, but we only wanted one.
|
||||||
jpeg_add_quant_table(&context->cinfo, 1, &context->qtables[0],
|
jpeg_add_quant_table(&context->cinfo, 1, &context->qtables[0],
|
||||||
quality, TRUE);
|
quality, FALSE);
|
||||||
}
|
}
|
||||||
for (i = last_q; i < context->cinfo.num_components; i++) {
|
for (i = last_q; i < context->cinfo.num_components; i++) {
|
||||||
context->cinfo.comp_info[i].quant_tbl_no = last_q;
|
context->cinfo.comp_info[i].quant_tbl_no = last_q;
|
||||||
}
|
}
|
||||||
} else if (context->quality != -1) {
|
} else if (context->quality != -1) {
|
||||||
jpeg_set_quality(&context->cinfo, context->quality, 1);
|
jpeg_set_quality(&context->cinfo, context->quality, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set subsampling options */
|
/* Set subsampling options */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user