Skip to content

Commit 7dd8837

Browse files
authored
Merge pull request #4647 from radarhere/blocklist
Allow libtiff to write COLORMAP tag
2 parents c9745f4 + d728cd5 commit 7dd8837

4 files changed

Lines changed: 34 additions & 4 deletions

File tree

Tests/test_file_libtiff.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ def test_additional_metadata(self, tmp_path):
207207
del core_items[tag]
208208
except KeyError:
209209
pass
210+
del core_items[320] # colormap is special, tested below
210211

211212
# Type codes:
212213
# 2: "ascii",
@@ -491,6 +492,18 @@ def test_cmyk_save(self, tmp_path):
491492
with Image.open(out) as im2:
492493
assert_image_equal(im, im2)
493494

495+
def test_palette_save(self, tmp_path):
496+
im = hopper("P")
497+
out = str(tmp_path / "temp.tif")
498+
499+
TiffImagePlugin.WRITE_LIBTIFF = True
500+
im.save(out)
501+
TiffImagePlugin.WRITE_LIBTIFF = False
502+
503+
with Image.open(out) as reloaded:
504+
# colormap/palette tag
505+
assert len(reloaded.tag_v2[320]) == 768
506+
494507
def xtest_bw_compression_w_rgb(self, tmp_path):
495508
""" This test passes, but when running all tests causes a failure due
496509
to output on stderr from the error thrown by libtiff. We need to

src/PIL/TiffImagePlugin.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1530,7 +1530,6 @@ def _save(im, fp, filename):
15301530
# BITSPERSAMPLE, etc), passing arrays with a different length will result in
15311531
# segfaults. Block these tags until we add extra validation.
15321532
blocklist = [
1533-
COLORMAP,
15341533
REFERENCEBLACKWHITE,
15351534
SAMPLEFORMAT,
15361535
STRIPBYTECOUNTS,

src/PIL/TiffTags.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,6 @@ def _populate():
483483
65537,
484484
}
485485

486-
LIBTIFF_CORE.remove(320) # Array of short, crashes
487486
LIBTIFF_CORE.remove(301) # Array of short, crashes
488487
LIBTIFF_CORE.remove(532) # Array of long, crashes
489488

src/encode.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
671671
// This list also exists in TiffTags.py
672672
const int core_tags[] = {
673673
256, 257, 258, 259, 262, 263, 266, 269, 274, 277, 278, 280, 281, 340,
674-
341, 282, 283, 284, 286, 287, 296, 297, 321, 338, 32995, 32998, 32996,
674+
341, 282, 283, 284, 286, 287, 296, 297, 320, 321, 338, 32995, 32998, 32996,
675675
339, 32997, 330, 531, 530, 65537
676676
};
677677

@@ -801,7 +801,26 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
801801
TRACE(("Setting from Tuple: %d \n", key_int));
802802
len = PyTuple_Size(value);
803803

804-
if (type == TIFF_SHORT) {
804+
if (key_int == TIFFTAG_COLORMAP) {
805+
int stride = 256;
806+
if (len != 768) {
807+
PyErr_SetString(PyExc_ValueError, "Requiring 768 items for for Colormap");
808+
return NULL;
809+
}
810+
UINT16 *av;
811+
/* malloc check ok, calloc checks for overflow */
812+
av = calloc(len, sizeof(UINT16));
813+
if (av) {
814+
for (i=0;i<len;i++) {
815+
av[i] = (UINT16)PyLong_AsLong(PyTuple_GetItem(value,i));
816+
}
817+
status = ImagingLibTiffSetField(&encoder->state, (ttag_t) key_int,
818+
av,
819+
av + stride,
820+
av + stride * 2);
821+
free(av);
822+
}
823+
} else if (type == TIFF_SHORT) {
805824
UINT16 *av;
806825
/* malloc check ok, calloc checks for overflow */
807826
av = calloc(len, sizeof(UINT16));

0 commit comments

Comments
 (0)