]> granicus.if.org Git - graphviz/commitdiff
more webp loadimage bits...
authorJohn Ellson <ellson@research.att.com>
Wed, 11 Jan 2012 19:08:05 +0000 (14:08 -0500)
committerJohn Ellson <ellson@research.att.com>
Wed, 11 Jan 2012 19:08:05 +0000 (14:08 -0500)
plugin/webp/gvdevice_webp.c
plugin/webp/gvloadimage_webp.c

index 8e97322f7499f4c9690825d497bccaed01b716c8..8df9a41c76d36351cb0b976eaeed7f9301aadf9b 100644 (file)
 #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;
      }
 
index 3006ae30849a3abe0c7001de1b6f03715364b3d9..317bfdcb8294a9455a90e95e8d8841dd5b079f11 100644 (file)
@@ -23,7 +23,7 @@
 #ifdef HAVE_WEBP
 #ifdef HAVE_PANGOCAIRO
 #include <cairo.h>
-#include <webp/encode.h>
+#include <webp/decode.h>
 
 #ifdef WIN32 //*dependencies
     #pragma comment( lib, "gvc.lib" )
     #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;