Added possibility to save exif information in jpeg-files

This commit is contained in:
d-schmidt 2013-01-10 21:36:21 +01:00
parent 54d4f5eb3c
commit addf0f4d95
5 changed files with 40 additions and 12 deletions

View File

@ -465,6 +465,7 @@ def _save(im, fp, filename):
dpi[0], dpi[1],
subsampling,
extra,
info.get("exif", "")
)
ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])

View File

@ -15,7 +15,7 @@
* 1999-02-07 fl Added PCX encoder
*
* Copyright (c) 1997-2001 by Secret Labs AB
* Copyright (c) 1996-1997 by Fredrik Lundh
* Copyright (c) 1996-1997 by Fredrik Lundh
*
* See the README file for information on usage and redistribution.
*/
@ -93,7 +93,7 @@ _dealloc(ImagingEncoderObject* encoder)
PyObject_Del(encoder);
}
static PyObject*
static PyObject*
_encode(ImagingEncoderObject* encoder, PyObject* args)
{
PyObject* buf;
@ -125,7 +125,7 @@ _encode(ImagingEncoderObject* encoder, PyObject* args)
return result;
}
static PyObject*
static PyObject*
_encode_to_file(ImagingEncoderObject* encoder, PyObject* args)
{
UINT8* buf;
@ -520,11 +520,16 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
int streamtype = 0; /* 0=interchange, 1=tables only, 2=image only */
int xdpi = 0, ydpi = 0;
int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */
char* extra = NULL; int extra_size;
char* extra = NULL;
int extra_size;
char* rawExif = NULL;
int rawExifLen = 0;
if (!PyArg_ParseTuple(args, "ss|iiiiiiii"PY_ARG_BYTES_LENGTH,
&mode, &rawmode, &quality,
&progressive, &smooth, &optimize, &streamtype,
&xdpi, &ydpi, &subsampling, &extra, &extra_size))
&xdpi, &ydpi, &subsampling, &extra, &extra_size,
&rawExif, &rawExifLen))
return NULL;
encoder = PyImaging_EncoderNew(sizeof(JPEGENCODERSTATE));
@ -543,6 +548,15 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
} else
extra = NULL;
if (rawExif && rawExifLen > 0) {
char* pp = malloc(rawExifLen);
if (!pp)
return PyErr_NoMemory();
memcpy(pp, rawExif, rawExifLen);
rawExif = pp;
} else
rawExif = NULL;
encoder->encode = ImagingJpegEncode;
((JPEGENCODERSTATE*)encoder->state.context)->quality = quality;
@ -555,6 +569,8 @@ PyImaging_JpegEncoderNew(PyObject* self, PyObject* args)
((JPEGENCODERSTATE*)encoder->state.context)->ydpi = ydpi;
((JPEGENCODERSTATE*)encoder->state.context)->extra = extra;
((JPEGENCODERSTATE*)encoder->state.context)->extra_size = extra_size;
((JPEGENCODERSTATE*)encoder->state.context)->rawExif = rawExif;
((JPEGENCODERSTATE*)encoder->state.context)->rawExifLen = rawExifLen;
return (PyObject*) encoder;
}

View File

@ -100,5 +100,8 @@ typedef struct {
JPEGDESTINATION destination;
int extra_offset;
int rawExifLen; /* EXIF data length */
char* rawExif; /* EXIF buffer pointer */
} JPEGENCODERSTATE;

View File

@ -24,9 +24,9 @@
#ifdef HAVE_LIBJPEG
#undef HAVE_PROTOTYPES
#undef HAVE_STDLIB_H
#undef HAVE_STDDEF_H
#undef HAVE_PROTOTYPES
#undef HAVE_STDLIB_H
#undef HAVE_STDDEF_H
#undef UINT8
#undef UINT16
#undef UINT32
@ -145,7 +145,7 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
jpeg_set_defaults(&context->cinfo);
if (context->quality > 0)
jpeg_set_quality(&context->cinfo, context->quality, 1);
/* Set subsampling options */
switch (context->subsampling)
{
@ -205,11 +205,19 @@ ImagingJpegEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
jpeg_start_compress(&context->cinfo, FALSE);
/* suppress extra section */
context->extra_offset = context->extra_size;
//add exif header
if (context->rawExifLen > 0)
jpeg_write_marker(&context->cinfo, JPEG_APP0+1, context->rawExif, context->rawExifLen);
break;
default:
/* interchange stream */
jpeg_start_compress(&context->cinfo, TRUE);
break;
//add exif header
if (context->rawExifLen > 0)
jpeg_write_marker(&context->cinfo, JPEG_APP0+1, context->rawExif, context->rawExifLen);
break;
}
state->state++;
/* fall through */

4
py3.h
View File

@ -11,7 +11,7 @@
*/
#if PY_VERSION_HEX >= 0x03000000
#define PY_ARG_BYTES_LENGTH "y#"
#define PY_ARG_BYTES_LENGTH "y#y#"
/* Map PyInt -> PyLong */
#define PyInt_AsLong PyLong_AsLong
@ -20,7 +20,7 @@
#define PyInt_AS_LONG PyLong_AS_LONG
#else /* PY_VERSION_HEX < 0x03000000 */
#define PY_ARG_BYTES_LENGTH "s#"
#define PY_ARG_BYTES_LENGTH "s#s#"
#if !defined(KEEP_PY_UNICODE)
/* Map PyUnicode -> PyString */