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>