Merge pull request #7491 from bgilbert/jpeg-tables-only

Implement `streamtype=1` option for tables-only JPEG encoding
This commit is contained in:
Andrew Murray 2023-11-11 16:06:34 +11:00 committed by GitHub
commit bf76320444
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 3 deletions

View File

@ -961,6 +961,28 @@ class TestFileJpeg:
im.load() im.load()
ImageFile.LOAD_TRUNCATED_IMAGES = False ImageFile.LOAD_TRUNCATED_IMAGES = False
def test_separate_tables(self):
im = hopper()
data = [] # [interchange, tables-only, image-only]
for streamtype in range(3):
out = BytesIO()
im.save(out, format="JPEG", streamtype=streamtype)
data.append(out.getvalue())
# SOI, EOI
for marker in b"\xff\xd8", b"\xff\xd9":
assert marker in data[1] and marker in data[2]
# DHT, DQT
for marker in b"\xff\xc4", b"\xff\xdb":
assert marker in data[1] and marker not in data[2]
# SOF0, SOS, APP0 (JFIF header)
for marker in b"\xff\xc0", b"\xff\xda", b"\xff\xe0":
assert marker not in data[1] and marker in data[2]
with Image.open(BytesIO(data[0])) as interchange_im:
with Image.open(BytesIO(data[1] + data[2])) as combined_im:
assert_image_equal(interchange_im, combined_im)
def test_repr_jpeg(self): def test_repr_jpeg(self):
im = hopper() im = hopper()

View File

@ -218,9 +218,9 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
} }
switch (context->streamtype) { switch (context->streamtype) {
case 1: case 1:
/* tables only -- not yet implemented */ /* tables only */
state->errcode = IMAGING_CODEC_CONFIG; jpeg_write_tables(&context->cinfo);
return -1; goto cleanup;
case 2: case 2:
/* image only */ /* image only */
jpeg_suppress_tables(&context->cinfo, TRUE); jpeg_suppress_tables(&context->cinfo, TRUE);
@ -316,6 +316,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8 *buf, int bytes) {
} }
jpeg_finish_compress(&context->cinfo); jpeg_finish_compress(&context->cinfo);
cleanup:
/* Clean up */ /* Clean up */
if (context->comment) { if (context->comment) {
free(context->comment); free(context->comment);