root/ext/gd/libgd/gd_webp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gdImageCreateFromWebp
  2. gdImageCreateFromWebpPtr
  3. gdImageCreateFromWebpCtx
  4. gdImageWebpCtx
  5. gdImageWebpEx
  6. gdImageWebp
  7. gdImageWebpPtr
  8. gdImageWebpPtrEx

   1 #ifdef HAVE_LIBWEBP
   2 #include <stdio.h>
   3 #include <math.h>
   4 #include <string.h>
   5 #include <stdlib.h>
   6 #include "gd.h"
   7 #include "gdhelpers.h"
   8 #include "webp/decode.h"
   9 #include "webp/encode.h"
  10 
  11 #define GD_WEBP_ALLOC_STEP (4*1024)
  12 
  13 gdImagePtr gdImageCreateFromWebp (FILE * inFile)
  14 {
  15         gdImagePtr im;
  16         gdIOCtx *in = gdNewFileCtx(inFile);
  17         if (!in)
  18                 return 0;
  19         im = gdImageCreateFromWebpCtx(in);
  20         in->gd_free(in);
  21 
  22         return im;
  23 }
  24 
  25 
  26 gdImagePtr gdImageCreateFromWebpPtr (int size, void *data)
  27 {
  28         gdImagePtr im;
  29         gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
  30         if (!in)
  31                 return 0;
  32         im = gdImageCreateFromWebpCtx(in);
  33         in->gd_free(in);
  34         return im;
  35 }
  36 
  37 gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile)
  38 {
  39         int    width, height;
  40         uint8_t   *filedata = NULL;
  41         uint8_t    *argb = NULL;
  42         size_t size = 0, n;
  43         gdImagePtr im;
  44         int x, y;
  45         uint8_t *p;
  46 
  47         do {
  48                 unsigned char *read, *temp;
  49 
  50                 temp = gdRealloc(filedata, size+GD_WEBP_ALLOC_STEP);
  51                 if (temp) {
  52                         filedata = temp;
  53                         read = temp + size;
  54                 } else {
  55                         if (filedata) {
  56                                 gdFree(filedata);
  57                         }
  58                         zend_error(E_ERROR, "WebP decode: realloc failed");
  59                         return NULL;
  60                 }
  61 
  62                 n = gdGetBuf(read, GD_WEBP_ALLOC_STEP, infile);
  63                 if (n>0 && n!=EOF) {
  64                         size += n;
  65                 }
  66         } while (n>0 && n!=EOF);
  67 
  68         if (WebPGetInfo(filedata,size, &width, &height) == 0) {
  69                 zend_error(E_ERROR, "gd-webp cannot get webp info");
  70                 gdFree(filedata);
  71                 return NULL;
  72         }
  73 
  74         im = gdImageCreateTrueColor(width, height);
  75         if (!im) {
  76                 gdFree(filedata);
  77                 return NULL;
  78         }
  79         argb = WebPDecodeARGB(filedata, size, &width, &height);
  80         if (!argb) {
  81                 zend_error(E_ERROR, "gd-webp cannot allocate temporary buffer");
  82                 gdFree(filedata);
  83                 gdImageDestroy(im);
  84                 return NULL;
  85         }
  86         for (y = 0, p = argb;  y < height; y++) {
  87                 for (x = 0; x < width; x++) {
  88                         register uint8_t a = gdAlphaMax - (*(p++) >> 1);
  89                         register uint8_t r = *(p++);
  90                         register uint8_t g = *(p++);
  91                         register uint8_t b = *(p++);
  92                         im->tpixels[y][x] = gdTrueColorAlpha(r, g, b, a);
  93                 }
  94         }
  95         gdFree(filedata);
  96         /* do not use gdFree here, in case gdFree/alloc is mapped to something else than libc */
  97         free(argb);
  98         im->saveAlphaFlag = 1;
  99         return im;
 100 }
 101 
 102 void gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quantization)
 103 {
 104         uint8_t *argb;
 105         int x, y;
 106         uint8_t *p;
 107         uint8_t *out;
 108         size_t out_size;
 109 
 110         if (im == NULL) {
 111                 return;
 112         }
 113 
 114         if (!gdImageTrueColor(im)) {
 115                 zend_error(E_ERROR, "Paletter image not supported by webp");
 116                 return;
 117         }
 118 
 119         if (quantization == -1) {
 120                 quantization = 80;
 121         }
 122 
 123         argb = (uint8_t *)gdMalloc(gdImageSX(im) * 4 * gdImageSY(im));
 124         if (!argb) {
 125                 return;
 126         }
 127         p = argb;
 128         for (y = 0; y < gdImageSY(im); y++) {
 129                 for (x = 0; x < gdImageSX(im); x++) {
 130                         register int c;
 131                         register char a;
 132                         c = im->tpixels[y][x];
 133                         a = gdTrueColorGetAlpha(c);
 134                         if (a == 127) {
 135                                 a = 0;
 136                         } else {
 137                                 a = 255 - ((a << 1) + (a >> 6));
 138                         }
 139                         *(p++) = gdTrueColorGetRed(c);
 140                         *(p++) = gdTrueColorGetGreen(c);
 141                         *(p++) = gdTrueColorGetBlue(c); 
 142                         *(p++) = a;
 143                 }
 144         }
 145         out_size = WebPEncodeRGBA(argb, gdImageSX(im), gdImageSY(im), gdImageSX(im) * 4, quantization, &out);
 146         if (out_size == 0) {
 147                 zend_error(E_ERROR, "gd-webp encoding failed");
 148                 goto freeargb;
 149         }
 150         gdPutBuf(out, out_size, outfile);
 151         free(out);
 152 
 153 freeargb:
 154         gdFree(argb);
 155 }
 156 
 157 void gdImageWebpEx (gdImagePtr im, FILE * outFile, int quantization)
 158 {
 159         gdIOCtx *out = gdNewFileCtx(outFile);
 160         gdImageWebpCtx(im, out, quantization);
 161         out->gd_free(out);
 162 }
 163 
 164 void gdImageWebp (gdImagePtr im, FILE * outFile)
 165 {
 166         gdIOCtx *out = gdNewFileCtx(outFile);
 167         gdImageWebpCtx(im, out, -1);
 168         out->gd_free(out);
 169 }
 170 
 171 void * gdImageWebpPtr (gdImagePtr im, int *size)
 172 {
 173         void *rv;
 174         gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
 175         gdImageWebpCtx(im, out, -1);
 176         rv = gdDPExtractData(out, size);
 177         out->gd_free(out);
 178 
 179         return rv;
 180 }
 181 
 182 void * gdImageWebpPtrEx (gdImagePtr im, int *size, int quantization)
 183 {
 184         void *rv;
 185         gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
 186         gdImageWebpCtx(im, out, quantization);
 187         rv = gdDPExtractData(out, size);
 188         out->gd_free(out);
 189         return rv;
 190 }
 191 #endif /* HAVE_LIBWEBP */

/* [<][>][^][v][top][bottom][index][help] */