From 7a2e240b27c045d9279e107b10a5b8f9b097ab92 Mon Sep 17 00:00:00 2001 From: John Ellson Date: Wed, 11 Jan 2012 14:08:05 -0500 Subject: [PATCH] more webp loadimage bits... --- plugin/webp/gvdevice_webp.c | 23 +++++++++- plugin/webp/gvloadimage_webp.c | 76 ++++++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/plugin/webp/gvdevice_webp.c b/plugin/webp/gvdevice_webp.c index 8e97322f7..8df9a41c7 100644 --- a/plugin/webp/gvdevice_webp.c +++ b/plugin/webp/gvdevice_webp.c @@ -21,6 +21,25 @@ #ifdef HAVE_WEBP #include "webp/encode.h" +static const char* const kErrorMessages[] = { + "OK", + "OUT_OF_MEMORY: Out of memory allocating objects", + "BITSTREAM_OUT_OF_MEMORY: Out of memory re-allocating byte buffer", + "NULL_PARAMETER: NULL parameter passed to function", + "INVALID_CONFIGURATION: configuration is invalid", + "BAD_DIMENSION: Bad picture dimension. Maximum width and height " + "allowed is 16383 pixels.", + "PARTITION0_OVERFLOW: Partition #0 is too big to fit 512k.\n" + "To reduce the size of this partition, try using less segments " + "with the -segments option, and eventually reduce the number of " + "header bits using -partition_limit. More details are available " + "in the manual (`man cwebp`)", + "PARTITION_OVERFLOW: Partition is too big to fit 16M", + "BAD_WRITE: Picture writer returned an I/O error", + "FILE_TOO_BIG: File would be too big to fit in 4G", + "USER_ABORT: encoding abort requested by user" +}; + typedef enum { FORMAT_WEBP, } format_type; @@ -100,8 +119,8 @@ static void webp_format(GVJ_t * job) if (!WebPEncode(&config, &picture)) { fprintf(stderr, "Error! Cannot encode picture as WebP\n"); -// fprintf(stderr, "Error code: %d (%s)\n", -// pic.error_code, kErrorMessages[picture.error_code]); + fprintf(stderr, "Error code: %d (%s)\n", + picture.error_code, kErrorMessages[picture.error_code]); goto Error; } diff --git a/plugin/webp/gvloadimage_webp.c b/plugin/webp/gvloadimage_webp.c index 3006ae308..317bfdcb8 100644 --- a/plugin/webp/gvloadimage_webp.c +++ b/plugin/webp/gvloadimage_webp.c @@ -23,7 +23,7 @@ #ifdef HAVE_WEBP #ifdef HAVE_PANGOCAIRO #include -#include +#include #ifdef WIN32 //*dependencies #pragma comment( lib, "gvc.lib" ) @@ -36,22 +36,74 @@ #pragma comment( lib, "webp.lib" ) #endif +static const char* const kStatusMessages[] = { + "OK", "OUT_OF_MEMORY", "INVALID_PARAM", "BITSTREAM_ERROR", + "UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA" +}; + typedef enum { FORMAT_WEBP_CAIRO, } format_type; -static cairo_status_t -reader (void *closure, unsigned char *data, unsigned int length) +static void webp_freeimage(usershape_t *us) { - if (length == fread(data, 1, length, (FILE *)closure) - || feof((FILE *)closure)) - return CAIRO_STATUS_SUCCESS; - return CAIRO_STATUS_READ_ERROR; + cairo_surface_destroy((cairo_surface_t*)(us->data)); } -static void webp_freeimage(usershape_t *us) +static cairo_surface_t* webp_really_loadimage(const char *in_file, FILE* const in) { - cairo_surface_destroy((cairo_surface_t*)(us->data)); + WebPDecoderConfig config; + WebPDecBuffer* const output_buffer = &config.output; + WebPBitstreamFeatures* const bitstream = &config.input; + VP8StatusCode status = VP8_STATUS_OK; + cairo_surface_t *surface = NULL; /* source surface */ + int ok; + uint32_t data_size = 0; + void* data = NULL; + + if (!WebPInitDecoderConfig(&config)) { + fprintf(stderr, "Error: WebP library version mismatch!\n"); + return NULL; + } + + fseek(in, 0, SEEK_END); + data_size = ftell(in); + fseek(in, 0, SEEK_SET); + data = malloc(data_size); + ok = (fread(data, data_size, 1, in) == 1); + if (!ok) { + fprintf(stderr, "Error: WebP could not read %d bytes of data from %s\n", + data_size, in_file); + free(data); + return NULL; + } + + status = WebPGetFeatures((const uint8_t*)data, data_size, bitstream); + if (status != VP8_STATUS_OK) { + goto end; + } + + output_buffer->colorspace = MODE_RGBA; + status = WebPDecode((const uint8_t*)data, data_size, &config); + +end: + free(data); + ok = (status == VP8_STATUS_OK); + if (!ok) { + fprintf(stderr, "Error: WebP decoding of %s failed.\n", in_file); + fprintf(stderr, "Status: %d (%s)\n", status, kStatusMessages[status]); + return NULL; + } + + // FIXME - convert data to cairo surface ... + +#if 1 + fprintf(stderr, "Info: WebP file %s can be decoded (dimensions: %d x %d)%s.\n", + in_file, output_buffer->width, output_buffer->height, + bitstream->has_alpha ? " (with alpha)" : ""); +#endif + + return surface; } static cairo_surface_t* webp_loadimage(GVJ_t * job, usershape_t *us) @@ -76,10 +128,8 @@ static cairo_surface_t* webp_loadimage(GVJ_t * job, usershape_t *us) return NULL; switch (us->type) { case FT_WEBP: -#if 0 // FIXME - surface = cairo_image_surface_create_from_png_stream(reader, us->f); - cairo_surface_reference(surface); -#endif + if ((surface = webp_really_loadimage(us->name, us->f))) + cairo_surface_reference(surface); break; default: surface = NULL; -- 2.40.0