mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	add support for webp
This commit is contained in:
		
							parent
							
								
									af7e80ea0c
								
							
						
					
					
						commit
						a49ea5d326
					
				
							
								
								
									
										
											BIN
										
									
								
								Images/lena.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Images/lena.webp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.8 KiB | 
							
								
								
									
										33
									
								
								PIL/WebPImagePlugin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								PIL/WebPImagePlugin.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | ||||||
|  | import Image | ||||||
|  | import ImageFile | ||||||
|  | import StringIO | ||||||
|  | import _webp | ||||||
|  | 
 | ||||||
|  | def _accept(prefix): | ||||||
|  |     return prefix[:4] == "RIFF" and prefix[8:16] == "WEBPVP8 " | ||||||
|  | 
 | ||||||
|  | class WebPImageFile(ImageFile.ImageFile): | ||||||
|  | 
 | ||||||
|  |     format = "WEBP" | ||||||
|  |     format_description = "WebP image" | ||||||
|  | 
 | ||||||
|  |     def _open(self): | ||||||
|  |         self.mode = "RGB" | ||||||
|  |         data, width, height = _webp.WebPDecodeRGB(self.fp.read()) | ||||||
|  |         self.size = width, height | ||||||
|  |         self.fp = StringIO.StringIO(data) | ||||||
|  |         self.tile = [("raw", (0, 0) + self.size, 0, 'RGB')] | ||||||
|  | 
 | ||||||
|  | def _save(im, fp, filename): | ||||||
|  |     if im.mode != "RGB": | ||||||
|  |         raise IOError("cannot write mode %s as WEBP" % im.mode) | ||||||
|  |     quality = im.encoderinfo.get("quality", 80) | ||||||
|  |      | ||||||
|  |     data = _webp.WebPEncodeRGB(im.tostring(), im.size[0], im.size[1], im.size[0] * 3, float(quality)) | ||||||
|  |     fp.write(data) | ||||||
|  | 
 | ||||||
|  | Image.register_open("WEBP", WebPImageFile, _accept) | ||||||
|  | Image.register_save("WEBP", _save) | ||||||
|  | 
 | ||||||
|  | Image.register_extension("WEBP", ".webp") | ||||||
|  | Image.register_mime("WEBP", "image/webp") | ||||||
							
								
								
									
										72
									
								
								_webp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								_webp.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,72 @@ | ||||||
|  | #include <Python.h> | ||||||
|  | #include <webp/encode.h> | ||||||
|  | #include <webp/decode.h> | ||||||
|  | 
 | ||||||
|  | PyObject* WebPEncodeRGB_wrapper(PyObject* self, PyObject* args) | ||||||
|  | { | ||||||
|  |     PyStringObject *rgb_string; | ||||||
|  |     int width; | ||||||
|  |     int height; | ||||||
|  |     int stride; | ||||||
|  |     float quality_factor; | ||||||
|  | 
 | ||||||
|  |     if (!PyArg_ParseTuple(args, "Siiif", &rgb_string, &width, &height, &stride, &quality_factor)) { | ||||||
|  |         Py_INCREF(Py_None); | ||||||
|  |         return Py_None; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     uint8_t *rgb; | ||||||
|  |     Py_ssize_t size; | ||||||
|  |     PyString_AsStringAndSize((struct PyObject *) rgb_string, &rgb, &size); | ||||||
|  | 
 | ||||||
|  |     if (stride * height > size) { | ||||||
|  |         Py_INCREF(Py_None); | ||||||
|  |         return Py_None; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uint8_t *output; | ||||||
|  |     size_t ret_size = WebPEncodeRGB(rgb, width, height, stride, quality_factor, &output); | ||||||
|  |     if (ret_size > 0) { | ||||||
|  |         PyObject *ret = PyString_FromStringAndSize(output, ret_size); | ||||||
|  |         free(output); | ||||||
|  |         return ret; | ||||||
|  |     } | ||||||
|  |     Py_INCREF(Py_None); | ||||||
|  |     return Py_None; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PyObject* WebPDecodeRGB_wrapper(PyObject* self, PyObject* args) | ||||||
|  | { | ||||||
|  |     PyStringObject *webp_string; | ||||||
|  |     float quality_factor; | ||||||
|  | 
 | ||||||
|  |     if (!PyArg_ParseTuple(args, "S", &webp_string)) { | ||||||
|  |         Py_INCREF(Py_None); | ||||||
|  |         return Py_None; | ||||||
|  |     }     | ||||||
|  |     uint8_t *webp; | ||||||
|  |     Py_ssize_t size; | ||||||
|  |     PyString_AsStringAndSize((struct PyObject *) webp_string, &webp, &size); | ||||||
|  | 
 | ||||||
|  |     int width; | ||||||
|  |     int height; | ||||||
|  |     uint8_t *output = WebPDecodeRGB(webp, size, &width, &height); | ||||||
|  | 
 | ||||||
|  |     PyObject *ret = PyString_FromStringAndSize(output, width * height * 3); | ||||||
|  |     free(output); | ||||||
|  |     return Py_BuildValue("Sii", ret, width, height); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static PyMethodDef webpMethods[] = | ||||||
|  | { | ||||||
|  |     {"WebPEncodeRGB", WebPEncodeRGB_wrapper, METH_VARARGS, "WebPEncodeRGB"}, | ||||||
|  |     {"WebPDecodeRGB", WebPDecodeRGB_wrapper, METH_VARARGS, "WebPEncodeRGB"}, | ||||||
|  |     {NULL, NULL} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void init_webp() | ||||||
|  | { | ||||||
|  |     PyObject* m; | ||||||
|  |     m = Py_InitModule("_webp", webpMethods); | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								setup.py
									
									
									
									
									
								
							|  | @ -211,7 +211,7 @@ class pil_build_ext(build_ext): | ||||||
|         # look for available libraries |         # look for available libraries | ||||||
| 
 | 
 | ||||||
|         class feature: |         class feature: | ||||||
|             zlib = jpeg = tiff = freetype = tcl = tk = lcms = None |             zlib = jpeg = tiff = freetype = tcl = tk = lcms = webp = None | ||||||
|         feature = feature() |         feature = feature() | ||||||
| 
 | 
 | ||||||
|         if _find_include_file(self, "zlib.h"): |         if _find_include_file(self, "zlib.h"): | ||||||
|  | @ -267,6 +267,10 @@ class pil_build_ext(build_ext): | ||||||
|             elif _find_library_file(self, "tk" + TCL_VERSION): |             elif _find_library_file(self, "tk" + TCL_VERSION): | ||||||
|                 feature.tk = "tk" + TCL_VERSION |                 feature.tk = "tk" + TCL_VERSION | ||||||
| 
 | 
 | ||||||
|  |         if _find_include_file(self, "webp/encode.h") and _find_include_file(self, "webp/decode.h"): | ||||||
|  |             if _find_library_file(self, "webp"): | ||||||
|  |                 feature.webp = "webp" | ||||||
|  | 
 | ||||||
|         # |         # | ||||||
|         # core library |         # core library | ||||||
| 
 | 
 | ||||||
|  | @ -314,6 +318,11 @@ class pil_build_ext(build_ext): | ||||||
|             exts.append(Extension( |             exts.append(Extension( | ||||||
|                 "_imagingcms", ["_imagingcms.c"], libraries=["lcms"] + extra)) |                 "_imagingcms", ["_imagingcms.c"], libraries=["lcms"] + extra)) | ||||||
| 
 | 
 | ||||||
|  |         if os.path.isfile("_webp.c") and feature.webp: | ||||||
|  |             exts.append(Extension( | ||||||
|  |                 "_webp", ["_webp.c"], libraries=["webp"])) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|         if sys.platform == "darwin": |         if sys.platform == "darwin": | ||||||
|             # locate Tcl/Tk frameworks |             # locate Tcl/Tk frameworks | ||||||
|             frameworks = [] |             frameworks = [] | ||||||
|  | @ -376,6 +385,7 @@ class pil_build_ext(build_ext): | ||||||
|             # (feature.tiff, "experimental TIFF G3/G4 read"), |             # (feature.tiff, "experimental TIFF G3/G4 read"), | ||||||
|             (feature.freetype, "FREETYPE2"), |             (feature.freetype, "FREETYPE2"), | ||||||
|             (feature.lcms, "LITTLECMS"), |             (feature.lcms, "LITTLECMS"), | ||||||
|  |             (feature.webp, "WEBP"), | ||||||
|             ] |             ] | ||||||
| 
 | 
 | ||||||
|         all = 1 |         all = 1 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user