mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 18:06:18 +03:00
inprogress, sorta working
This commit is contained in:
parent
4852aa5b65
commit
b52c22316f
|
@ -11,8 +11,8 @@ _VALID_WEBP_ENCODERS_BY_MODE = {
|
||||||
|
|
||||||
|
|
||||||
_VALID_WEBP_DECODERS_BY_MODE = {
|
_VALID_WEBP_DECODERS_BY_MODE = {
|
||||||
"RGB": _webp.WebPDecodeRGB,
|
"RGB": _webp.WebPDecode,
|
||||||
"RGBA": _webp.WebPDecodeRGBA,
|
"RGBA": _webp.WebPDecode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,22 +42,10 @@ class WebPImageFile(ImageFile.ImageFile):
|
||||||
format_description = "WebP image"
|
format_description = "WebP image"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self):
|
||||||
file_header = self.fp.read(16)
|
data, width, height, self.mode = _webp.WebPDecode(self.fp.read())
|
||||||
vp8_header = file_header[12:16]
|
|
||||||
try:
|
|
||||||
webp_file_mode = _VP8_MODES_BY_IDENTIFIER[vp8_header]
|
|
||||||
except KeyError:
|
|
||||||
raise IOError("Unknown webp file mode")
|
|
||||||
finally:
|
|
||||||
self.fp.seek(0)
|
|
||||||
|
|
||||||
self.mode = webp_file_mode
|
|
||||||
webp_decoder = _VALID_WEBP_DECODERS_BY_MODE[webp_file_mode]
|
|
||||||
|
|
||||||
data, width, height = webp_decoder(self.fp.read())
|
|
||||||
self.size = width, height
|
self.size = width, height
|
||||||
self.fp = BytesIO(data)
|
self.fp = BytesIO(data)
|
||||||
self.tile = [("raw", (0, 0) + self.size, 0, webp_file_mode)]
|
self.tile = [("raw", (0, 0) + self.size, 0, self.mode)]
|
||||||
|
|
||||||
|
|
||||||
def _save(im, fp, filename):
|
def _save(im, fp, filename):
|
||||||
|
|
76
_webp.c
76
_webp.c
|
@ -21,7 +21,7 @@ PyObject* WebPGetFeatures_wrapper(PyObject* self, PyObject* args)
|
||||||
|
|
||||||
PyBytes_AsStringAndSize((PyObject *) webp_string, (char**)&webp, &size);
|
PyBytes_AsStringAndSize((PyObject *) webp_string, (char**)&webp, &size);
|
||||||
|
|
||||||
vp8_status_code = WebPGetFeatures(webp, size, (WebPBitstreamFeatures *)&features);
|
vp8_status_code = WebPGetFeatures(webp, size, &features);
|
||||||
|
|
||||||
if (vp8_status_code == VP8_STATUS_OK) {
|
if (vp8_status_code == VP8_STATUS_OK) {
|
||||||
printf("%i", features.has_alpha);
|
printf("%i", features.has_alpha);
|
||||||
|
@ -109,63 +109,77 @@ PyObject* WebPEncodeRGBA_wrapper(PyObject* self, PyObject* args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PyObject* WebPDecodeRGB_wrapper(PyObject* self, PyObject* args)
|
PyObject* WebPDecode_wrapper(PyObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
PyBytesObject *webp_string;
|
PyBytesObject *webp_string;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
uint8_t *webp;
|
uint8_t *webp;
|
||||||
uint8_t *output;
|
uint8_t *output;
|
||||||
Py_ssize_t size;
|
Py_ssize_t size;
|
||||||
PyObject *ret;
|
PyObject *ret, *bytes;
|
||||||
|
WebPDecoderConfig config;
|
||||||
|
VP8StatusCode vp8_status_code = VP8_STATUS_OK;
|
||||||
|
char* mode = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "S", &webp_string)) {
|
if (!PyArg_ParseTuple(args, "S", &webp_string)) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyBytes_AsStringAndSize((PyObject *) webp_string, (char**)&webp, &size);
|
if (!WebPInitDecoderConfig(&config)) {
|
||||||
|
|
||||||
output = WebPDecodeRGB(webp, size, &width, &height);
|
|
||||||
|
|
||||||
ret = PyBytes_FromStringAndSize((char*)output, width * height * 3);
|
|
||||||
free(output);
|
|
||||||
return Py_BuildValue("Sii", ret, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PyObject* WebPDecodeRGBA_wrapper(PyObject* self, PyObject* args)
|
|
||||||
{
|
|
||||||
PyBytesObject *webp_string;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
uint8_t *webp;
|
|
||||||
uint8_t *output;
|
|
||||||
Py_ssize_t size;
|
|
||||||
PyObject *ret;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "S", &webp_string)) {
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyBytes_AsStringAndSize((PyObject *) webp_string, (char**)&webp, &size);
|
PyBytes_AsStringAndSize((PyObject *) webp_string, (char**)&webp, &size);
|
||||||
|
|
||||||
output = WebPDecodeRGBA(webp, size, &width, &height);
|
vp8_status_code = WebPGetFeatures(webp, size, &config.input);
|
||||||
|
if (vp8_status_code == VP8_STATUS_OK) {
|
||||||
|
vp8_status_code = WebPDecode(webp, size, &config);
|
||||||
|
}
|
||||||
|
|
||||||
ret = PyBytes_FromStringAndSize((char*)output, width * height * 4);
|
if (vp8_status_code != VP8_STATUS_OK) {
|
||||||
free(output);
|
Py_INCREF(Py_None);
|
||||||
return Py_BuildValue("Sii", ret, width, height);
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.output.colorspace < MODE_YUV) {
|
||||||
|
bytes = PyBytes_FromStringAndSize((char *)config.output.u.RGBA.rgba, config.output.u.RGBA.size);
|
||||||
|
} else {
|
||||||
|
// Skipping YUV for now.
|
||||||
|
bytes = PyBytes_FromStringAndSize((char *)config.output.u.YUVA.y, config.output.u.YUVA.y_size);
|
||||||
|
}
|
||||||
|
switch(config.output.colorspace) {
|
||||||
|
// UNDONE, alternate orderings
|
||||||
|
case MODE_RGB:
|
||||||
|
mode = "RGB";
|
||||||
|
break;
|
||||||
|
case MODE_RGBA:
|
||||||
|
mode = "RGBA";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mode = "ERR";
|
||||||
|
}
|
||||||
|
|
||||||
|
height = config.output.height;
|
||||||
|
width = config.output.width;
|
||||||
|
|
||||||
|
|
||||||
|
ret = Py_BuildValue("SiiS", bytes, width, height, PyBytes_FromString(mode));
|
||||||
|
WebPFreeDecBuffer(&config.output);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef webpMethods[] =
|
static PyMethodDef webpMethods[] =
|
||||||
{
|
{
|
||||||
{"WebPGetFeatures", WebPGetFeatures_wrapper, METH_VARARGS, "WebPGetFeatures"},
|
{"WebPGetFeatures", WebPGetFeatures_wrapper, METH_VARARGS, "WebPGetFeatures"},
|
||||||
{"WebPEncodeRGB", WebPEncodeRGB_wrapper, METH_VARARGS, "WebPEncodeRGB"},
|
{"WebPEncodeRGB", WebPEncodeRGB_wrapper, METH_VARARGS, "WebPEncodeRGB"},
|
||||||
{"WebPEncodeRGBA", WebPEncodeRGBA_wrapper, METH_VARARGS, "WebPEncodeRGBA"},
|
{"WebPEncodeRGBA", WebPEncodeRGBA_wrapper, METH_VARARGS, "WebPEncodeRGBA"},
|
||||||
{"WebPDecodeRGB", WebPDecodeRGB_wrapper, METH_VARARGS, "WebPDecodeRGB"},
|
{"WebPDecode", WebPDecode_wrapper, METH_VARARGS, "WebPDecode"},
|
||||||
{"WebPDecodeRGBA", WebPDecodeRGBA_wrapper, METH_VARARGS, "WebPDecodeRGBA"},
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user