inprogress, sorta working

This commit is contained in:
wiredfool 2013-05-13 20:50:10 -07:00
parent 4852aa5b65
commit b52c22316f
2 changed files with 51 additions and 49 deletions

View File

@ -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
View File

@ -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}
}; };