Annotation of embedaddon/php/ext/gd/libgd/gd_webp.c, revision 1.1.1.1

1.1       misho       1: #include <stdio.h>
                      2: #include <math.h>
                      3: #include <string.h>
                      4: #include <stdlib.h>
                      5: #include "gd.h"
                      6: 
                      7: 
                      8: #ifdef HAVE_LIBVPX
                      9: #include "webpimg.h"
                     10: #include "gdhelpers.h"
                     11: 
                     12: extern void gd_YUV420toRGBA(uint8* Y,
                     13:                   uint8* U,
                     14:                   uint8* V,
                     15:                   gdImagePtr im);
                     16: 
                     17: extern void gd_RGBAToYUV420(gdImagePtr im2,
                     18:                   uint8* Y,
                     19:                   uint8* U,
                     20:                   uint8* V);
                     21: 
                     22: const char * gdWebpGetVersionString()
                     23: {
                     24:        return "not defined";
                     25: }
                     26: 
                     27: gdImagePtr gdImageCreateFromWebp (FILE * inFile)
                     28: {
                     29:        gdImagePtr im;
                     30:        gdIOCtx *in = gdNewFileCtx(inFile);
                     31:        im = gdImageCreateFromWebpCtx(in);
                     32:        in->gd_free(in);
                     33: 
                     34:        return im;
                     35: }
                     36: 
                     37: gdImagePtr gdImageCreateFromWebpPtr (int size, void *data)
                     38: {
                     39:        int    width, height, ret;
                     40:        unsigned char   *Y = NULL;
                     41:        unsigned char   *U = NULL;
                     42:        unsigned char   *V = NULL;
                     43:        gdImagePtr im;
                     44: 
                     45:        ret = WebPDecode(data, size, &Y, &U, &V, &width, &height);
                     46:        if (ret != webp_success) {
                     47:                if (Y) free(Y);
                     48:                if (U) free(U);
                     49:                if (V) free(V);
                     50:                php_gd_error("WebP decode: fail to decode input data");
                     51:                return NULL;
                     52:        }
                     53:        im = gdImageCreateTrueColor(width, height);
                     54:        if (!im) {
                     55:                return NULL;
                     56:        }
                     57:        gd_YUV420toRGBA(Y, U, V, im);
                     58:        return im;
                     59: }
                     60: 
                     61: gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile)
                     62: {
                     63:        int    width, height, ret;
                     64:        unsigned char   *filedata;
                     65:        unsigned char   dummy[1024];
                     66:        unsigned char   *Y = NULL;
                     67:        unsigned char   *U = NULL;
                     68:        unsigned char   *V = NULL;
                     69:        size_t size = 0, n;
                     70:        gdImagePtr im;
                     71: 
                     72:        do {
                     73:                n = gdGetBuf(dummy, 1024, infile);
                     74:                size += n;
                     75:        } while (n != EOF);
                     76: 
                     77:        filedata = gdMalloc(size);
                     78:        if  (!filedata) {
                     79:                php_gd_error("WebP decode: alloc failed");
                     80:                return NULL;
                     81:        }
                     82:        gdGetBuf(filedata, size, infile);
                     83:        ret = WebPDecode(filedata, size, &Y, &U, &V, &width, &height);
                     84:        gdFree(filedata);
                     85:        if (ret != webp_success) {
                     86:                if (Y) free(Y);
                     87:                if (U) free(U);
                     88:                if (V) free(V);
                     89:                php_gd_error("WebP decode: fail to decode input data");
                     90:                return NULL;
                     91:        }
                     92:        im = gdImageCreateTrueColor(width, height);
                     93:        gd_YUV420toRGBA(Y, U, V, im);
                     94:        return im;
                     95: }
                     96: 
                     97: void gdImageWebpEx (gdImagePtr im, FILE * outFile, int quantization)
                     98: {
                     99:        gdIOCtx *out = gdNewFileCtx(outFile);
                    100:        gdImageWebpCtx(im, out, quantization);
                    101:        out->gd_free(out);
                    102: }
                    103: 
                    104: void gdImageWebp (gdImagePtr im, FILE * outFile)
                    105: {
                    106:        gdIOCtx *out = gdNewFileCtx(outFile);
                    107:        gdImageWebpCtx(im, out, -1);
                    108:        out->gd_free(out);
                    109: }
                    110: 
                    111: void * gdImageWebpPtr (gdImagePtr im, int *size)
                    112: {
                    113:        void *rv;
                    114:        gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
                    115:        gdImageWebpCtx(im, out, -1);
                    116:        rv = gdDPExtractData(out, size);
                    117:        out->gd_free(out);
                    118: 
                    119:        return rv;
                    120: }
                    121: 
                    122: void * gdImageWebpPtrEx (gdImagePtr im, int *size, int quantization)
                    123: {
                    124:        void *rv;
                    125:        gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
                    126:        gdImageWebpCtx(im, out, quantization);
                    127:        rv = gdDPExtractData(out, size);
                    128:        out->gd_free(out);
                    129:        return rv;
                    130: }
                    131: 
                    132: /*
                    133:  * Maps normalized QP (quality) to VP8 QP
                    134:  */
                    135: int mapQualityToVP8QP(int quality) {
                    136: #define MIN_QUALITY 0
                    137: #define MAX_QUALITY 100
                    138: #define MIN_VP8QP 1
                    139: #define MAX_VP8QP 63
                    140:        const float scale = MAX_VP8QP - MIN_VP8QP;
                    141:        const float vp8qp =
                    142:        scale * (MAX_QUALITY - quality) / (MAX_QUALITY - MIN_QUALITY) + MIN_VP8QP;
                    143:        if (quality < MIN_QUALITY || quality > MAX_QUALITY) {
                    144:                php_gd_error("Wrong quality value %d.", quality);
                    145:                return -1;
                    146:        }
                    147: 
                    148:        return (int)(vp8qp + 0.5);
                    149: }
                    150: 
                    151: /* This routine is based in part on code from Dale Lutz (Safe Software Inc.)
                    152:  *  and in part on demo code from Chapter 15 of "PNG: The Definitive Guide"
                    153:  *  (http://www.cdrom.com/pub/png/pngbook.html).
                    154:  */
                    155: void gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quantization)
                    156: {
                    157:        int width = im->sx;
                    158:        int height = im->sy;
                    159:        int colors = im->colorsTotal;
                    160:        int *open = im->open;
                    161: 
                    162:        int  yuv_width, yuv_height, yuv_nbytes, ret;
                    163:        int vp8_quality;
                    164:        unsigned char *Y = NULL,
                    165:                                  *U = NULL,
                    166:                                  *V = NULL;
                    167:        unsigned char *filedata = NULL;
                    168: 
                    169:        /* Conversion to Y,U,V buffer */
                    170:     yuv_width = (width + 1) >> 1;
                    171:     yuv_height = (height + 1) >> 1;
                    172:     yuv_nbytes = width * height + 2 * yuv_width * yuv_height;
                    173: 
                    174:     if ((Y = (unsigned char *)gdCalloc(yuv_nbytes, sizeof(unsigned char))) == NULL) {
                    175:        php_gd_error("gd-webp error: cannot allocate Y buffer");
                    176:         return;
                    177:     }
                    178:        vp8_quality = mapQualityToVP8QP(quantization);
                    179: 
                    180:     U = Y + width * height;
                    181:     V = U + yuv_width * yuv_height;
                    182:     gd_RGBAToYUV420(im, Y, U, V);
                    183: 
                    184:        /* Encode Y,U,V and write data to file */
                    185:     ret = WebPEncode(Y, U, V, width, height, width, yuv_width, yuv_height, yuv_width,
                    186:                      vp8_quality, &filedata, &yuv_nbytes, NULL);
                    187:        gdFree(Y);
                    188: 
                    189:     if (ret != webp_success) {
                    190:        if (filedata) {
                    191:                free(filedata);
                    192:                }
                    193:                php_gd_error("gd-webp error: WebP Encoder failed");
                    194:                return;
                    195:     }
                    196: 
                    197:     gdPutBuf (filedata, yuv_nbytes, outfile);
                    198:     free(filedata);
                    199: }
                    200: 
                    201: #endif /* HAVE_LIBVPX */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>