pulling out special cases, referenceblackwhite works

This commit is contained in:
wiredfool 2016-12-09 10:25:52 +00:00
parent 18b0a376e3
commit 1ad3dd7212
4 changed files with 116 additions and 54 deletions

View File

@ -1448,6 +1448,8 @@ def _save(im, fp, filename):
legacy_ifd = {} legacy_ifd = {}
if hasattr(im, 'tag'): if hasattr(im, 'tag'):
legacy_ifd = im.tag.to_v2() legacy_ifd = im.tag.to_v2()
if DEBUG:
print("Legacy IFD items: %s" % sorted(legacy_ifd.items()))
for tag, value in itertools.chain(ifd.items(), for tag, value in itertools.chain(ifd.items(),
getattr(im, 'tag_v2', {}).items(), getattr(im, 'tag_v2', {}).items(),
legacy_ifd.items()): legacy_ifd.items()):

View File

@ -157,7 +157,7 @@ TAGS_V2 = {
529: ("YCbCrCoefficients", RATIONAL, 3), 529: ("YCbCrCoefficients", RATIONAL, 3),
530: ("YCbCrSubSampling", SHORT, 2), 530: ("YCbCrSubSampling", SHORT, 2),
531: ("YCbCrPositioning", SHORT, 1), 531: ("YCbCrPositioning", SHORT, 1),
532: ("ReferenceBlackWhite", LONG, 0), 532: ("ReferenceBlackWhite", RATIONAL, 6),
# sgi, in core # sgi, in core
32995:("Matteing", SHORT, 1), 32995:("Matteing", SHORT, 1),
@ -436,7 +436,7 @@ LIBTIFF_CORE = {255, 256, 257, 258, 259, 262, 263, 266, 274, 277,
LIBTIFF_CORE.remove(320) # Array of short, crashes LIBTIFF_CORE.remove(320) # Array of short, crashes
LIBTIFF_CORE.remove(301) # Array of short, crashes LIBTIFF_CORE.remove(301) # Array of short, crashes
LIBTIFF_CORE.remove(532) # Array of long, crashes #LIBTIFF_CORE.remove(532) # Array of long, crashes
LIBTIFF_CORE.remove(330) # subifd, requires extra support for uint64 payload LIBTIFF_CORE.remove(330) # subifd, requires extra support for uint64 payload

View File

@ -222,7 +222,7 @@ class TestFileLibTiff(LibTiffTestCase):
out = self.tempfile("temp.tif") out = self.tempfile("temp.tif")
TiffImagePlugin.WRITE_LIBTIFF = True TiffImagePlugin.WRITE_LIBTIFF = True
im.save(out, tiffinfo=new_ifd) im.save(out, tiffinfo=new_ifd)
TiffImagePlugin.WRITE_LIBTIFF = False TiffImagePlugin.WRITE_LIBTIFF = False

162
encode.c
View File

@ -756,7 +756,7 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
((_type *)arrav)[i] = (_type)_PyFunction(PyTuple_GetItem(value,i)); \ ((_type *)arrav)[i] = (_type)_PyFunction(PyTuple_GetItem(value,i)); \
}\ }\
status = ImagingLibTiffSetField(&encoder->state,\ status = ImagingLibTiffSetField(&encoder->state,\
(ttag_t) PyInt_AsLong(key),\ tag,\
len, arrav);\ len, arrav);\
free(arrav);\ free(arrav);\
} }
@ -775,6 +775,7 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
PyObject *dir; PyObject *dir;
PyObject *key, *value, *valuetuple; PyObject *key, *value, *valuetuple;
ttag_t tag;
int type, length, flarray; int type, length, flarray;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
int status; int status;
@ -818,6 +819,7 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
for (pos = 0; pos < d_size; pos++) { for (pos = 0; pos < d_size; pos++) {
key = PyList_GetItem(keys, pos); key = PyList_GetItem(keys, pos);
tag = (ttag_t) PyInt_AsLong(key);
valuetuple = PyList_GetItem(values, pos); valuetuple = PyList_GetItem(values, pos);
status = 0; status = 0;
TRACE(("Attempting to set key: %d\n", (int)PyInt_AsLong(key))); TRACE(("Attempting to set key: %d\n", (int)PyInt_AsLong(key)));
@ -838,19 +840,48 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
return NULL; return NULL;
} }
switch (type) { switch (type) {
case 3: case TIFF_BYTE:
case 4: case TIFF_UNDEFINED:
case 6: case TIFF_SBYTE:
case 8: case TIFF_SHORT:
case 9: case TIFF_SSHORT:
if (PyInt_Check(value)) { if (PyInt_Check(value)) {
TRACE(("Setting %d from Int: %d %ld \n", TRACE(("Setting %d from Int: %d %ld \n",
(int)PyInt_AsLong(key), (int)PyInt_AsLong(key),
type, type,
PyInt_AsLong(value))); PyInt_AsLong(value)));
status = ImagingLibTiffSetField(&encoder->state, status = ImagingLibTiffSetField(&encoder->state,
(ttag_t) PyInt_AsLong(key), tag,
PyInt_AsLong(value)); (int)PyInt_AsLong(value));
} else {
PyErr_SetString(PyExc_ValueError, "Expected int for metadata value");
return NULL;
}
break;
case TIFF_LONG:
case TIFF_IFD:
if (PyInt_Check(value)) {
TRACE(("Setting %d from uInt: %d %ld \n",
(int)PyInt_AsLong(key),
type,
PyInt_AsLong(value)));
status = ImagingLibTiffSetField(&encoder->state,
tag,
(uint32)PyLong_AsUnsignedLong(value));
} else {
PyErr_SetString(PyExc_ValueError, "Expected int for metadata value");
return NULL;
}
break;
case TIFF_SLONG:
if (PyInt_Check(value)) {
TRACE(("Setting %d from Int: %d %ld \n",
(int)PyInt_AsLong(key),
type,
PyInt_AsLong(value)));
status = ImagingLibTiffSetField(&encoder->state,
tag,
(int32)PyInt_AsLong(value));
} else { } else {
PyErr_SetString(PyExc_ValueError, "Expected int for metadata value"); PyErr_SetString(PyExc_ValueError, "Expected int for metadata value");
return NULL; return NULL;
@ -863,8 +894,8 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
if (PyFloat_Check(value)) { if (PyFloat_Check(value)) {
TRACE(("Setting from Float: %d, %f \n", (int)PyInt_AsLong(key),PyFloat_AsDouble(value))); TRACE(("Setting from Float: %d, %f \n", (int)PyInt_AsLong(key),PyFloat_AsDouble(value)));
status = ImagingLibTiffSetField(&encoder->state, status = ImagingLibTiffSetField(&encoder->state,
(ttag_t) PyInt_AsLong(key), tag,
(float)PyFloat_AsDouble(value)); (double)PyFloat_AsDouble(value));
} else { } else {
PyErr_SetString(PyExc_ValueError, "Expected floatlike for metadata value"); PyErr_SetString(PyExc_ValueError, "Expected floatlike for metadata value");
return NULL; return NULL;
@ -874,7 +905,7 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
if (PyBytes_Check(value)) { if (PyBytes_Check(value)) {
TRACE(("Setting from Bytes: %d, %s \n", (int)PyInt_AsLong(key),PyBytes_AsString(value))); TRACE(("Setting from Bytes: %d, %s \n", (int)PyInt_AsLong(key),PyBytes_AsString(value)));
status = ImagingLibTiffSetField(&encoder->state, status = ImagingLibTiffSetField(&encoder->state,
(ttag_t) PyInt_AsLong(key), tag,
PyBytes_AsString(value)); PyBytes_AsString(value));
} else { } else {
PyErr_SetString(PyExc_ValueError, "Expected stringlike for metadata value"); PyErr_SetString(PyExc_ValueError, "Expected stringlike for metadata value");
@ -885,49 +916,78 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
Py_ssize_t len,i; Py_ssize_t len,i;
void *arrav; void *arrav;
TRACE(("Setting from Tuple: %d \n", (int)PyInt_AsLong(key))); TRACE(("Setting from Tuple: %d, type: %d \n", (int)PyInt_AsLong(key), type));
len = PyTuple_Size(value); len = PyTuple_Size(value);
if ((int)len == length) {
switch (type) { switch (tag) {
case 3: /* special cases */
TRACE((" %d elements, setting as short \n", (int)len)); case TIFFTAG_PAGENUMBER:
PUSHMETAARRAY(short, PyInt_AsLong); case TIFFTAG_HALFTONEHINTS:
break; case TIFFTAG_YCBCRSUBSAMPLING:
case 4: /* not an array, passing two int items */
TRACE((" %d elements, setting as ints \n", (int)len)); if (len != 2) {
PUSHMETAARRAY(int, PyInt_AsLong); PyErr_SetString(PyExc_ValueError, "Requiring 2 items for for tag");
/*arrav = calloc(len, sizeof(int)); return NULL;
if (arrav) {
for (i=0;i<len;i++) {
(int *arrav)[i] = (int)PyInt_AsLong(PyTuple_GetItem(value,i));
}
status = ImagingLibTiffSetField(&encoder->state,
(ttag_t) PyInt_AsLong(key),
len, arrav);
free(arrav);
}*/
break;
case 5:
case 10:
case 11:
TRACE((" %d elements, setting as floats \n", (int)len));
/* malloc check ok, calloc checks for overflow */
PUSHMETAARRAY(float, PyFloat_AsDouble);
break;
case 12:
TRACE((" %d elements, setting as double \n", (int)len));
PUSHMETAARRAY(double, PyFloat_AsDouble);
break;
default:
TRACE(("Unhandled type in tuple for key %d : %d, len: %d \n",
(int)PyInt_AsLong(key),
type, length));
} }
status = ImagingLibTiffSetField(&encoder->state,
tag,
(int)PyInt_AsLong(PyTuple_GetItem(value,0)),
(int)PyInt_AsLong(PyTuple_GetItem(value,1)));
break;
case TIFFTAG_COLORMAP:
/* 3x uint16 * arrays of r,g,b palette values, len=2^^bpp */
break;
case TIFFTAG_SUBIFD:
/* int short length, uint32* data */
break;
case TIFFTAG_TRANSFERFUNCTION:
/* 1 or 3 uint16 * arrays len=2^^bpp */
break;
case TIFFTAG_REFERENCEBLACKWHITE:
/* float *, array len==6 */
if (len != 6) {
PyErr_SetString(PyExc_ValueError, "Requiring 6 items for for ReferenceBlackWhite");
return NULL;
}
arrav = calloc(len, sizeof(float));
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;
case TIFFTAG_INKNAMES:
/* int length, char * names */
break;
default:
if ((int)len == length) {
switch (type) {
case 3:
TRACE((" %d elements, setting as short \n", (int)len));
PUSHMETAARRAY(short, PyInt_AsLong);
break;
case 4:
TRACE((" %d elements, setting as ints \n", (int)len));
PUSHMETAARRAY(int, PyInt_AsLong);
break;
case 5:
case 10:
case 11:
case 12:
TRACE((" %d elements, setting as double \n", (int)len));
PUSHMETAARRAY(double, PyFloat_AsDouble);
break;
default:
TRACE(("Unhandled type in tuple for key %d : %d, len: %d \n",
(int)PyInt_AsLong(key),
type, length));
}
}
} }
/* } else {
TRACE(("Unhandled type for key %d : %s \n",
(int)PyInt_AsLong(key),
PyBytes_AsString(PyObject_Str(value))));*/
} }
if (!status) { if (!status) {
TRACE(("Error setting Field\n")); TRACE(("Error setting Field\n"));