mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-05-06 08:53:41 +03:00
Added custom int and float TIFF tags
This commit is contained in:
parent
990fb03218
commit
a3d45e9cef
|
@ -231,6 +231,24 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
|
|
||||||
TiffImagePlugin.WRITE_LIBTIFF = False
|
TiffImagePlugin.WRITE_LIBTIFF = False
|
||||||
|
|
||||||
|
def test_custom_metadata(self):
|
||||||
|
custom = {
|
||||||
|
37000: 4,
|
||||||
|
37001: 4.2
|
||||||
|
}
|
||||||
|
for libtiff in [False, True]:
|
||||||
|
TiffImagePlugin.WRITE_LIBTIFF = libtiff
|
||||||
|
|
||||||
|
im = hopper()
|
||||||
|
|
||||||
|
out = self.tempfile("temp.tif")
|
||||||
|
im.save(out, tiffinfo=custom)
|
||||||
|
TiffImagePlugin.WRITE_LIBTIFF = False
|
||||||
|
|
||||||
|
reloaded = Image.open(out)
|
||||||
|
for tag, value in custom.items():
|
||||||
|
self.assertEqual(reloaded.tag_v2[tag], value)
|
||||||
|
|
||||||
def test_int_dpi(self):
|
def test_int_dpi(self):
|
||||||
# issue #1765
|
# issue #1765
|
||||||
im = hopper('RGB')
|
im = hopper('RGB')
|
||||||
|
|
|
@ -1499,11 +1499,10 @@ def _save(im, fp, filename):
|
||||||
getattr(im, 'tag_v2', {}).items(),
|
getattr(im, 'tag_v2', {}).items(),
|
||||||
legacy_ifd.items()):
|
legacy_ifd.items()):
|
||||||
# Libtiff can only process certain core items without adding
|
# Libtiff can only process certain core items without adding
|
||||||
# them to the custom dictionary. It will segfault if it attempts
|
# them to the custom dictionary. Support has only been been added
|
||||||
# to add a custom tag without the dictionary entry
|
# for int and float values
|
||||||
#
|
if tag not in TiffTags.LIBTIFF_CORE and not \
|
||||||
# UNDONE -- add code for the custom dictionary
|
(isinstance(value, int) or isinstance(value, float)):
|
||||||
if tag not in TiffTags.LIBTIFF_CORE:
|
|
||||||
continue
|
continue
|
||||||
if tag not in atts and tag not in blocklist:
|
if tag not in atts and tag not in blocklist:
|
||||||
if isinstance(value, str if py3 else unicode):
|
if isinstance(value, str if py3 else unicode):
|
||||||
|
|
|
@ -425,6 +425,7 @@ TYPES = {}
|
||||||
|
|
||||||
# some of these are not in our TAGS_V2 dict and were included from tiff.h
|
# some of these are not in our TAGS_V2 dict and were included from tiff.h
|
||||||
|
|
||||||
|
# This list also exists in encode.c
|
||||||
LIBTIFF_CORE = {255, 256, 257, 258, 259, 262, 263, 266, 274, 277,
|
LIBTIFF_CORE = {255, 256, 257, 258, 259, 262, 263, 266, 274, 277,
|
||||||
278, 280, 281, 340, 341, 282, 283, 284, 286, 287,
|
278, 280, 281, 340, 341, 282, 283, 284, 286, 287,
|
||||||
296, 297, 321, 320, 338, 32995, 322, 323, 32998,
|
296, 297, 321, 320, 338, 32995, 322, 323, 32998,
|
||||||
|
|
46
src/encode.c
46
src/encode.c
|
@ -804,7 +804,13 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
PyObject *dir;
|
PyObject *dir;
|
||||||
PyObject *key, *value;
|
PyObject *key, *value;
|
||||||
Py_ssize_t pos = 0;
|
Py_ssize_t pos = 0;
|
||||||
int status;
|
int key_int, status, is_core_tag, i;
|
||||||
|
// This list also exists in TiffTags.py
|
||||||
|
const int tags[32] = {
|
||||||
|
256, 257, 258, 259, 262, 263, 266, 269, 274, 277, 278, 280, 281, 340,
|
||||||
|
341, 282, 283, 284, 286, 287, 296, 297, 321, 338, 32995, 32998, 32996,
|
||||||
|
339, 32997, 330, 531, 530
|
||||||
|
};
|
||||||
|
|
||||||
Py_ssize_t d_size;
|
Py_ssize_t d_size;
|
||||||
PyObject *keys, *values;
|
PyObject *keys, *values;
|
||||||
|
@ -845,21 +851,33 @@ 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);
|
||||||
|
key_int = (int)PyInt_AsLong(key);
|
||||||
value = PyList_GetItem(values, pos);
|
value = PyList_GetItem(values, pos);
|
||||||
status = 0;
|
status = 0;
|
||||||
TRACE(("Attempting to set key: %d\n", (int)PyInt_AsLong(key)));
|
is_core_tag = 0;
|
||||||
|
for (i=0; i<32; i++) {
|
||||||
|
if (tags[i] == key_int) {
|
||||||
|
is_core_tag = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE(("Attempting to set key: %d\n", key_int));
|
||||||
if (PyInt_Check(value)) {
|
if (PyInt_Check(value)) {
|
||||||
TRACE(("Setting from Int: %d %ld \n", (int)PyInt_AsLong(key),PyInt_AsLong(value)));
|
TRACE(("Setting from Int: %d %ld \n", key_int, PyInt_AsLong(value)));
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
if (is_core_tag || !ImagingLibTiffMergeFieldInfo(&encoder->state, TIFF_LONG, key_int)) {
|
||||||
(ttag_t) PyInt_AsLong(key),
|
status = ImagingLibTiffSetField(&encoder->state,
|
||||||
PyInt_AsLong(value));
|
(ttag_t) PyInt_AsLong(key),
|
||||||
|
PyInt_AsLong(value));
|
||||||
|
}
|
||||||
} else if (PyFloat_Check(value)) {
|
} else 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", key_int, PyFloat_AsDouble(value)));
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
if (is_core_tag || !ImagingLibTiffMergeFieldInfo(&encoder->state, TIFF_DOUBLE, key_int)) {
|
||||||
(ttag_t) PyInt_AsLong(key),
|
status = ImagingLibTiffSetField(&encoder->state,
|
||||||
(float)PyFloat_AsDouble(value));
|
(ttag_t) PyInt_AsLong(key),
|
||||||
|
(double)PyFloat_AsDouble(value));
|
||||||
|
}
|
||||||
} else if (PyBytes_Check(value)) {
|
} else 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", key_int, PyBytes_AsString(value)));
|
||||||
status = ImagingLibTiffSetField(&encoder->state,
|
status = ImagingLibTiffSetField(&encoder->state,
|
||||||
(ttag_t) PyInt_AsLong(key),
|
(ttag_t) PyInt_AsLong(key),
|
||||||
PyBytes_AsString(value));
|
PyBytes_AsString(value));
|
||||||
|
@ -867,7 +885,7 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
Py_ssize_t len,i;
|
Py_ssize_t len,i;
|
||||||
float *floatav;
|
float *floatav;
|
||||||
int *intav;
|
int *intav;
|
||||||
TRACE(("Setting from Tuple: %d \n", (int)PyInt_AsLong(key)));
|
TRACE(("Setting from Tuple: %d \n", key_int));
|
||||||
len = PyTuple_Size(value);
|
len = PyTuple_Size(value);
|
||||||
if (len) {
|
if (len) {
|
||||||
if (PyInt_Check(PyTuple_GetItem(value,0))) {
|
if (PyInt_Check(PyTuple_GetItem(value,0))) {
|
||||||
|
@ -898,13 +916,13 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TRACE(("Unhandled type in tuple for key %d : %s \n",
|
TRACE(("Unhandled type in tuple for key %d : %s \n",
|
||||||
(int)PyInt_AsLong(key),
|
key_int,
|
||||||
PyBytes_AsString(PyObject_Str(value))));
|
PyBytes_AsString(PyObject_Str(value))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TRACE(("Unhandled type for key %d : %s \n",
|
TRACE(("Unhandled type for key %d : %s \n",
|
||||||
(int)PyInt_AsLong(key),
|
key_int,
|
||||||
PyBytes_AsString(PyObject_Str(value))));
|
PyBytes_AsString(PyObject_Str(value))));
|
||||||
}
|
}
|
||||||
if (!status) {
|
if (!status) {
|
||||||
|
|
|
@ -402,6 +402,19 @@ int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ImagingLibTiffMergeFieldInfo(ImagingCodecState state, TIFFDataType field_type, int key){
|
||||||
|
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
||||||
|
char field_name[10];
|
||||||
|
uint32 n;
|
||||||
|
|
||||||
|
const TIFFFieldInfo info[] = {
|
||||||
|
{ key, 0, 1, field_type, FIELD_CUSTOM, 1, 0, field_name }
|
||||||
|
};
|
||||||
|
n = sizeof(info) / sizeof(info[0]);
|
||||||
|
|
||||||
|
return TIFFMergeFieldInfo(clientstate->tiff, info, n);
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -45,6 +45,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 ImagingLibTiffMergeFieldInfo(ImagingCodecState state, TIFFDataType field_type, int key);
|
||||||
extern int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...);
|
extern int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user