Skip to content

Commit

Permalink
Added tags when saving YCbCr TIFF
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jul 9, 2021
1 parent be30792 commit 8d1e269
Show file tree
Hide file tree
Showing 3 changed files with 37 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 @@ -1593,6 +1594,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
20 changes: 20 additions & 0 deletions src/encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,26 @@ 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 (key_int == TIFFTAG_REFERENCEBLACKWHITE) {
FLOAT32 *av;
/* malloc check ok, calloc checks for overflow */
av = calloc(len, sizeof(UINT16));
if (av) {
for (i = 0; i < len; i++) {
av[i] = (FLOAT32)PyFloat_AsDouble(PyTuple_GetItem(value, i));
}
status = ImagingLibTiffSetField(
&encoder->state,
(ttag_t)key_int,
av);
free(av);
}
} else if (type == TIFF_SHORT) {
UINT16 *av;
/* malloc check ok, calloc checks for overflow */
Expand Down

0 comments on commit 8d1e269

Please sign in to comment.