mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	Added possibility to save exif information in jpeg-files
This commit is contained in:
		
							parent
							
								
									54d4f5eb3c
								
							
						
					
					
						commit
						addf0f4d95
					
				|  | @ -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)]) | ||||
|  |  | |||
							
								
								
									
										26
									
								
								encode.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								encode.c
									
									
									
									
									
								
							|  | @ -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; | ||||
| } | ||||
|  |  | |||
|  | @ -100,5 +100,8 @@ typedef struct { | |||
|     JPEGDESTINATION destination; | ||||
| 
 | ||||
|     int extra_offset; | ||||
|      | ||||
|     int rawExifLen;   /* EXIF data length */ | ||||
|     char* rawExif;  /* EXIF buffer pointer */ | ||||
| 
 | ||||
| } JPEGENCODERSTATE; | ||||
|  |  | |||
|  | @ -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
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								py3.h
									
									
									
									
									
								
							|  | @ -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 */ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user