mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-17 18:54:46 +03:00
pulling out special cases, referenceblackwhite works
This commit is contained in:
parent
18b0a376e3
commit
1ad3dd7212
|
@ -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()):
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
162
encode.c
|
@ -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"));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user