This source file includes following definitions.
- gdImageCreateFromWebp
- gdImageCreateFromWebpPtr
- gdImageCreateFromWebpCtx
- gdImageWebpCtx
- gdImageWebpEx
- gdImageWebp
- gdImageWebpPtr
- 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
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