Whitepoint, Primary Chromaticities working

This commit is contained in:
wiredfool 2016-12-14 03:50:06 -08:00
parent 713d383e00
commit e1110b5a9c
6 changed files with 72 additions and 25 deletions

View File

@ -95,8 +95,8 @@ TAGS_V2 = {
278: ("RowsPerStrip", LONG, 1), 278: ("RowsPerStrip", LONG, 1),
279: ("StripByteCounts", LONG, 0), 279: ("StripByteCounts", LONG, 0),
280: ("MinSampleValue", LONG, 0), 280: ("MinSampleValue", LONG, 1),
281: ("MaxSampleValue", SHORT, 0), 281: ("MaxSampleValue", SHORT, 1),
282: ("XResolution", RATIONAL, 1), 282: ("XResolution", RATIONAL, 1),
283: ("YResolution", RATIONAL, 1), 283: ("YResolution", RATIONAL, 1),
284: ("PlanarConfiguration", SHORT, 1, {"Contiguous": 1, "Separate": 2}), 284: ("PlanarConfiguration", SHORT, 1, {"Contiguous": 1, "Separate": 2}),
@ -121,7 +121,7 @@ TAGS_V2 = {
316: ("HostComputer", ASCII, 1), 316: ("HostComputer", ASCII, 1),
317: ("Predictor", SHORT, 1, {"none": 1, "Horizontal Differencing": 2}), 317: ("Predictor", SHORT, 1, {"none": 1, "Horizontal Differencing": 2}),
318: ("WhitePoint", RATIONAL, 2), 318: ("WhitePoint", RATIONAL, 2),
319: ("PrimaryChromaticities", SHORT, 6), 319: ("PrimaryChromaticities", RATIONAL, 6),
320: ("ColorMap", SHORT, 0), 320: ("ColorMap", SHORT, 0),
321: ("HalftoneHints", SHORT, 2), 321: ("HalftoneHints", SHORT, 2),
@ -137,10 +137,10 @@ TAGS_V2 = {
336: ("DotRange", SHORT, 0), 336: ("DotRange", SHORT, 0),
337: ("TargetPrinter", ASCII, 1), 337: ("TargetPrinter", ASCII, 1),
338: ("ExtraSamples", SHORT, 0), 338: ("ExtraSamples", SHORT, 0),
339: ("SampleFormat", SHORT, 0), 339: ("SampleFormat", SHORT, 1),
340: ("SMinSampleValue", DOUBLE, 0), 340: ("SMinSampleValue", DOUBLE, 1),
341: ("SMaxSampleValue", DOUBLE, 0), 341: ("SMaxSampleValue", DOUBLE, 1),
342: ("TransferRange", SHORT, 6), 342: ("TransferRange", SHORT, 6),
# obsolete JPEG tags # obsolete JPEG tags
@ -161,7 +161,7 @@ TAGS_V2 = {
# sgi, in core # sgi, in core
32995:("Matteing", SHORT, 1), 32995:("Matteing", SHORT, 1),
32996:("DataType", SHORT, 0), 32996:("DataType", SHORT, 1),
32997:("ImageDepth", LONG, 1), 32997:("ImageDepth", LONG, 1),
32998:("TileDepth", LONG, 1), 32998:("TileDepth", LONG, 1),
@ -431,7 +431,9 @@ LIBTIFF_CORE = {255, 256, 257, 258, 259, 262, 263, 266, 274, 277,
296, 297, 321, 320, 338, 32995, 322, 323, 32998, 296, 297, 321, 320, 338, 32995, 322, 323, 32998,
32996, 339, 32997, 330, 531, 530, 301, 532, 333, 32996, 339, 32997, 330, 531, 530, 301, 532, 333,
# as above # as above
269 # this has been in our tests forever, and works 269, # this has been in our tests forever, and works
318, # Whitepoint, Specific test for it
319, # Primary Chromaticities
} }
LIBTIFF_CORE.remove(330) # subifd, requires extra support for uint64 payload LIBTIFF_CORE.remove(330) # subifd, requires extra support for uint64 payload

View File

@ -517,6 +517,16 @@ class TestFileLibTiff(LibTiffTestCase):
im.save(out, format='TIFF') im.save(out, format='TIFF')
TiffImagePlugin.WRITE_LIBTIFF = False TiffImagePlugin.WRITE_LIBTIFF = False
reloaded = Image.open(out)
self.assert_image_equal(im, reloaded)
for tag in (318, 319):
for ix in range(len(im.tag_v2[tag])):
self.assertAlmostEqual(float(im.tag_v2[tag][ix]),
float(reloaded.tag_v2[tag][ix]),
places=5)
def test_page_number_x_0(self): def test_page_number_x_0(self):
# Issue 973 # Issue 973
# Test TIFF with tag 297 (Page Number) having value of 0 0. # Test TIFF with tag 297 (Page Number) having value of 0 0.

View File

@ -54,8 +54,8 @@ them) of built in items that regular. These have one of three call
signatures: signatures:
* Individual: ``TIFFVSetField(tiff, tag, item)`` * Individual: ``TIFFVSetField(tiff, tag, item)``
* Multiple: ``TIFFVSetField(tiff, tag, ct, items* )`` * Multiple, passcount=1: ``TIFFVSetField(tiff, tag, ct, items* )``
* Alternate Multiple: ``TIFFVSetField(tiff, tag, items* )`` * Multiple, passcount=0: ``TIFFVSetField(tiff, tag, items* )``
In libtiff4, the individual integer like numeric items are passed as In libtiff4, the individual integer like numeric items are passed as
32 bit ints (signed or unsigned as appropriate) even if the actual 32 bit ints (signed or unsigned as appropriate) even if the actual

View File

@ -754,11 +754,17 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
if (arrav) {\ if (arrav) {\
for (i=0;i<len;i++) {\ for (i=0;i<len;i++) {\
((_type *)arrav)[i] = (_type)_PyFunction(PyTuple_GetItem(value,i)); \ ((_type *)arrav)[i] = (_type)_PyFunction(PyTuple_GetItem(value,i)); \
}\ } \
status = ImagingLibTiffSetField(&encoder->state,\ if (fi->field_passcount) { \
tag,\ status = ImagingLibTiffSetField(&encoder->state, \
len, arrav);\ tag, \
free(arrav);\ len, arrav); \
} else { \
status = ImagingLibTiffSetField(&encoder->state, \
tag, \
arrav); \
} \
free(arrav); \
} }
@ -783,6 +789,7 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
Py_ssize_t d_size; Py_ssize_t d_size;
PyObject *keys, *values; PyObject *keys, *values;
const TIFFFieldInfo* fi;
if (! PyArg_ParseTuple(args, "sssisO", &mode, &rawmode, &compname, &fp, &filename, &dir)) { if (! PyArg_ParseTuple(args, "sssisO", &mode, &rawmode, &compname, &fp, &filename, &dir)) {
return NULL; return NULL;
@ -834,6 +841,13 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
length = PyInt_AsLong(PyTuple_GetItem(valuetuple,2)); length = PyInt_AsLong(PyTuple_GetItem(valuetuple,2));
value = PyTuple_GetItem(valuetuple,3); value = PyTuple_GetItem(valuetuple,3);
fi = ImagingLibTiffGetFieldInfo(&encoder->state, tag);
if (!fi) {
/* undone, custom */
PyErr_SetString(PyExc_ValueError, "Couldn't find field info for tag.");
return NULL;
}
if (flarray == 0) { if (flarray == 0) {
if (length != 1) { if (length != 1) {
PyErr_SetString(PyExc_ValueError, "Expected length == 1 for non-array item"); PyErr_SetString(PyExc_ValueError, "Expected length == 1 for non-array item");
@ -969,21 +983,31 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
PyErr_SetString(PyExc_ValueError, "Requiring 6 items for for ReferenceBlackWhite"); PyErr_SetString(PyExc_ValueError, "Requiring 6 items for for ReferenceBlackWhite");
return NULL; return NULL;
} }
arrav = calloc(len, sizeof(float)); PUSHMETAARRAY(float, PyFloat_AsDouble);
if (arrav) {
for (i=0;i<len;i++) {
((float *)arrav)[i] = (float)PyFloat_AsDouble(PyTuple_GetItem(value,i));
}
status = ImagingLibTiffSetField(&encoder->state,
tag,
arrav);
free(arrav);
}
break; break;
case TIFFTAG_INKNAMES: case TIFFTAG_INKNAMES:
/* int length, char * names */ /* int length, char * names */
break; break;
default: default:
// Check for the right length for default case items
if (len > INT_MAX) {
PyErr_SetString(PyExc_MemoryError, "Metadata size error - int overflow");
return NULL;
}
if (fi->field_writecount == TIFF_VARIABLE ||
fi->field_writecount == TIFF_VARIABLE2) {
if (len != 1) {
PyErr_SetString(PyExc_ValueError, "Expected 1 item for tag");
return NULL;
}
} else if (fi->field_writecount == TIFF_SPP) {
/* need to check for samples per pixel here */
} else if (len != fi->field_writecount) {
PyErr_SetString(PyExc_ValueError, "Incorrect number of items for tag");
return NULL;
}
if ((int)len == length) { if ((int)len == length) {
switch (type) { switch (type) {
case 3: case 3:
@ -997,6 +1021,9 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
case 5: case 5:
case 10: case 10:
case 11: case 11:
TRACE((" %d elements, setting as float \n", (int)len));
PUSHMETAARRAY(float, PyFloat_AsDouble);
break;
case 12: case 12:
TRACE((" %d elements, setting as double \n", (int)len)); TRACE((" %d elements, setting as double \n", (int)len));
PUSHMETAARRAY(double, PyFloat_AsDouble); PUSHMETAARRAY(double, PyFloat_AsDouble);

View File

@ -336,6 +336,13 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
} }
const TIFFFieldInfo*
ImagingLibTiffGetFieldInfo(ImagingCodecState state, ttag_t tag) {
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
return TIFFFieldWithTag(clientstate->tiff, tag);
}
int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...){ int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...){
// after tif_dir.c->TIFFSetField. // after tif_dir.c->TIFFSetField.
TIFFSTATE *clientstate = (TIFFSTATE *)state->context; TIFFSTATE *clientstate = (TIFFSTATE *)state->context;

View File

@ -46,6 +46,7 @@ typedef struct {
extern int ImagingLibTiffInit(ImagingCodecState state, int fp, int offset); extern int ImagingLibTiffInit(ImagingCodecState state, int fp, int offset);
extern int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp); extern int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp);
extern int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...); extern int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...);
extern const TIFFFieldInfo* ImagingLibTiffGetFieldInfo(ImagingCodecState state, ttag_t tag);
/* /*