Skip to content

Commit

Permalink
Merge pull request #5597 from radarhere/ycbcr_tiff
Browse files Browse the repository at this point in the history
Added tags when saving YCbCr TIFF
  • Loading branch information
hugovk committed Jul 28, 2021
2 parents 5f39e8e + 5cdcc2c commit 4e4d580
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Tests/test_file_libtiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,15 @@ def save_bytesio(compression=None):
TiffImagePlugin.WRITE_LIBTIFF = False
TiffImagePlugin.READ_LIBTIFF = False

def test_save_ycbcr(self, tmp_path):
im = hopper("YCbCr")
outfile = str(tmp_path / "temp.tif")
im.save(outfile, compression="jpeg")

with Image.open(outfile) as reloaded:
assert reloaded.tag_v2[530] == (1, 1)
assert reloaded.tag_v2[532] == (0, 255, 128, 255, 128, 255)

def test_crashing_metadata(self, tmp_path):
# issue 1597
with Image.open("Tests/images/rdf.tif") as im:
Expand Down
8 changes: 8 additions & 0 deletions src/PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
EXTRASAMPLES = 338
SAMPLEFORMAT = 339
JPEGTABLES = 347
YCBCRSUBSAMPLING = 530
REFERENCEBLACKWHITE = 532
COPYRIGHT = 33432
IPTC_NAA_CHUNK = 33723 # newsphoto properties
Expand Down Expand Up @@ -1596,6 +1597,13 @@ def _save(im, fp, filename):
# no compression by default:
ifd[COMPRESSION] = COMPRESSION_INFO_REV.get(compression, 1)

if im.mode == "YCbCr":
for tag, value in {
YCBCRSUBSAMPLING: (1, 1),
REFERENCEBLACKWHITE: (0, 255, 128, 255, 128, 255),
}.items():
ifd.setdefault(tag, value)

if libtiff:
if "quality" in im.encoderinfo:
quality = im.encoderinfo["quality"]
Expand Down
6 changes: 6 additions & 0 deletions src/encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,12 @@ PyImaging_LibTiffEncoderNew(PyObject *self, PyObject *args) {
av + stride * 2);
free(av);
}
} else if (key_int == TIFFTAG_YCBCRSUBSAMPLING) {
status = ImagingLibTiffSetField(
&encoder->state,
(ttag_t)key_int,
(UINT16)PyLong_AsLong(PyTuple_GetItem(value, 0)),
(UINT16)PyLong_AsLong(PyTuple_GetItem(value, 1)));
} else if (type == TIFF_SHORT) {
UINT16 *av;
/* malloc check ok, calloc checks for overflow */
Expand Down

0 comments on commit 4e4d580

Please sign in to comment.