1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) The PHP Group                                          |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
16    |          Stig Bakken <ssb@php.net>                                   |
17    |          Jim Winstead <jimw@php.net>                                 |
18    +----------------------------------------------------------------------+
19  */
20 
21 /* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center,
22    Cold Spring Harbor Labs. */
23 
24 /* Note that there is no code from the gd package in this file */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #include "php.h"
31 #include "php_ini.h"
32 #include "ext/standard/head.h"
33 #include <math.h>
34 #include "SAPI.h"
35 #include "php_gd.h"
36 #include "ext/standard/info.h"
37 #include "php_open_temporary_file.h"
38 
39 
40 #ifdef HAVE_SYS_WAIT_H
41 # include <sys/wait.h>
42 #endif
43 #ifdef HAVE_UNISTD_H
44 # include <unistd.h>
45 #endif
46 #ifdef PHP_WIN32
47 # include <io.h>
48 # include <fcntl.h>
49 # include <windows.h>
50 # include <Winuser.h>
51 # include <Wingdi.h>
52 #endif
53 
54 #if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
55 # include <X11/xpm.h>
56 #endif
57 
58 # include "gd_compat.h"
59 
60 
61 static int le_gd, le_gd_font;
62 
63 #include <gd.h>
64 #include <gd_errors.h>
65 #include <gdfontt.h>  /* 1 Tiny font */
66 #include <gdfonts.h>  /* 2 Small font */
67 #include <gdfontmb.h> /* 3 Medium bold font */
68 #include <gdfontl.h>  /* 4 Large font */
69 #include <gdfontg.h>  /* 5 Giant font */
70 
71 #if defined(HAVE_GD_FREETYPE) && defined(HAVE_GD_BUNDLED)
72 # include <ft2build.h>
73 # include FT_FREETYPE_H
74 #endif
75 
76 #if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
77 # include "X11/xpm.h"
78 #endif
79 
80 #ifndef M_PI
81 #define M_PI 3.14159265358979323846
82 #endif
83 
84 #ifdef HAVE_GD_FREETYPE
85 static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int, int);
86 #endif
87 
88 #include "gd_ctx.c"
89 
90 /* as it is not really public, duplicate declaration here to avoid
91    pointless warnings */
92 int overflow2(int a, int b);
93 
94 /* Section Filters Declarations */
95 /* IMPORTANT NOTE FOR NEW FILTER
96  * Do not forget to update:
97  * IMAGE_FILTER_MAX: define the last filter index
98  * IMAGE_FILTER_MAX_ARGS: define the biggest amount of arguments
99  * image_filter array in PHP_FUNCTION(imagefilter)
100  * */
101 #define IMAGE_FILTER_NEGATE         0
102 #define IMAGE_FILTER_GRAYSCALE      1
103 #define IMAGE_FILTER_BRIGHTNESS     2
104 #define IMAGE_FILTER_CONTRAST       3
105 #define IMAGE_FILTER_COLORIZE       4
106 #define IMAGE_FILTER_EDGEDETECT     5
107 #define IMAGE_FILTER_EMBOSS         6
108 #define IMAGE_FILTER_GAUSSIAN_BLUR  7
109 #define IMAGE_FILTER_SELECTIVE_BLUR 8
110 #define IMAGE_FILTER_MEAN_REMOVAL   9
111 #define IMAGE_FILTER_SMOOTH         10
112 #define IMAGE_FILTER_PIXELATE       11
113 #define IMAGE_FILTER_SCATTER		12
114 #define IMAGE_FILTER_MAX            12
115 #define IMAGE_FILTER_MAX_ARGS       6
116 static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS);
117 static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS);
118 static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS);
119 static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS);
120 static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS);
121 static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS);
122 static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS);
123 static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS);
124 static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS);
125 static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS);
126 static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS);
127 static void php_image_filter_pixelate(INTERNAL_FUNCTION_PARAMETERS);
128 static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS);
129 
130 /* End Section filters declarations */
131 static gdImagePtr _php_image_create_from_string (zval *Data, char *tn, gdImagePtr (*ioctx_func_p)());
132 static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)());
133 static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)());
134 static int _php_image_type(char data[12]);
135 static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type);
136 
137 /* {{{ arginfo */
138 ZEND_BEGIN_ARG_INFO(arginfo_gd_info, 0)
139 ZEND_END_ARG_INFO()
140 
141 ZEND_BEGIN_ARG_INFO(arginfo_imageloadfont, 0)
142 	ZEND_ARG_INFO(0, filename)
143 ZEND_END_ARG_INFO()
144 
145 ZEND_BEGIN_ARG_INFO(arginfo_imagesetstyle, 0)
146 	ZEND_ARG_INFO(0, im)
147 	ZEND_ARG_INFO(0, styles) /* ARRAY_INFO(0, styles, 0) */
148 ZEND_END_ARG_INFO()
149 
150 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatetruecolor, 0)
151 	ZEND_ARG_INFO(0, x_size)
152 	ZEND_ARG_INFO(0, y_size)
153 ZEND_END_ARG_INFO()
154 
155 ZEND_BEGIN_ARG_INFO(arginfo_imageistruecolor, 0)
156 	ZEND_ARG_INFO(0, im)
157 ZEND_END_ARG_INFO()
158 
159 ZEND_BEGIN_ARG_INFO(arginfo_imagetruecolortopalette, 0)
160 	ZEND_ARG_INFO(0, im)
161 	ZEND_ARG_INFO(0, ditherFlag)
162 	ZEND_ARG_INFO(0, colorsWanted)
163 ZEND_END_ARG_INFO()
164 
165 ZEND_BEGIN_ARG_INFO(arginfo_imagepalettetotruecolor, 0)
166 	ZEND_ARG_INFO(0, im)
167 ZEND_END_ARG_INFO()
168 
169 ZEND_BEGIN_ARG_INFO(arginfo_imagecolormatch, 0)
170 	ZEND_ARG_INFO(0, im1)
171 	ZEND_ARG_INFO(0, im2)
172 ZEND_END_ARG_INFO()
173 
174 ZEND_BEGIN_ARG_INFO(arginfo_imagesetthickness, 0)
175 	ZEND_ARG_INFO(0, im)
176 	ZEND_ARG_INFO(0, thickness)
177 ZEND_END_ARG_INFO()
178 
179 ZEND_BEGIN_ARG_INFO(arginfo_imagefilledellipse, 0)
180 	ZEND_ARG_INFO(0, im)
181 	ZEND_ARG_INFO(0, cx)
182 	ZEND_ARG_INFO(0, cy)
183 	ZEND_ARG_INFO(0, w)
184 	ZEND_ARG_INFO(0, h)
185 	ZEND_ARG_INFO(0, color)
186 ZEND_END_ARG_INFO()
187 
188 ZEND_BEGIN_ARG_INFO(arginfo_imagefilledarc, 0)
189 	ZEND_ARG_INFO(0, im)
190 	ZEND_ARG_INFO(0, cx)
191 	ZEND_ARG_INFO(0, cy)
192 	ZEND_ARG_INFO(0, w)
193 	ZEND_ARG_INFO(0, h)
194 	ZEND_ARG_INFO(0, s)
195 	ZEND_ARG_INFO(0, e)
196 	ZEND_ARG_INFO(0, col)
197 	ZEND_ARG_INFO(0, style)
198 ZEND_END_ARG_INFO()
199 
200 ZEND_BEGIN_ARG_INFO(arginfo_imagealphablending, 0)
201 	ZEND_ARG_INFO(0, im)
202 	ZEND_ARG_INFO(0, blend)
203 ZEND_END_ARG_INFO()
204 
205 ZEND_BEGIN_ARG_INFO(arginfo_imagesavealpha, 0)
206 	ZEND_ARG_INFO(0, im)
207 	ZEND_ARG_INFO(0, save)
208 ZEND_END_ARG_INFO()
209 
210 ZEND_BEGIN_ARG_INFO(arginfo_imagelayereffect, 0)
211 	ZEND_ARG_INFO(0, im)
212 	ZEND_ARG_INFO(0, effect)
213 ZEND_END_ARG_INFO()
214 
215 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorallocatealpha, 0)
216 	ZEND_ARG_INFO(0, im)
217 	ZEND_ARG_INFO(0, red)
218 	ZEND_ARG_INFO(0, green)
219 	ZEND_ARG_INFO(0, blue)
220 	ZEND_ARG_INFO(0, alpha)
221 ZEND_END_ARG_INFO()
222 
223 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorresolvealpha, 0)
224 	ZEND_ARG_INFO(0, im)
225 	ZEND_ARG_INFO(0, red)
226 	ZEND_ARG_INFO(0, green)
227 	ZEND_ARG_INFO(0, blue)
228 	ZEND_ARG_INFO(0, alpha)
229 ZEND_END_ARG_INFO()
230 
231 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorclosestalpha, 0)
232 	ZEND_ARG_INFO(0, im)
233 	ZEND_ARG_INFO(0, red)
234 	ZEND_ARG_INFO(0, green)
235 	ZEND_ARG_INFO(0, blue)
236 	ZEND_ARG_INFO(0, alpha)
237 ZEND_END_ARG_INFO()
238 
239 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorexactalpha, 0)
240 	ZEND_ARG_INFO(0, im)
241 	ZEND_ARG_INFO(0, red)
242 	ZEND_ARG_INFO(0, green)
243 	ZEND_ARG_INFO(0, blue)
244 	ZEND_ARG_INFO(0, alpha)
245 ZEND_END_ARG_INFO()
246 
247 ZEND_BEGIN_ARG_INFO(arginfo_imagecopyresampled, 0)
248 	ZEND_ARG_INFO(0, dst_im)
249 	ZEND_ARG_INFO(0, src_im)
250 	ZEND_ARG_INFO(0, dst_x)
251 	ZEND_ARG_INFO(0, dst_y)
252 	ZEND_ARG_INFO(0, src_x)
253 	ZEND_ARG_INFO(0, src_y)
254 	ZEND_ARG_INFO(0, dst_w)
255 	ZEND_ARG_INFO(0, dst_h)
256 	ZEND_ARG_INFO(0, src_w)
257 	ZEND_ARG_INFO(0, src_h)
258 ZEND_END_ARG_INFO()
259 
260 #ifdef PHP_WIN32
261 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegrabwindow, 0, 0, 1)
262 	ZEND_ARG_INFO(0, handle)
263 	ZEND_ARG_INFO(0, client_area)
264 ZEND_END_ARG_INFO()
265 
266 ZEND_BEGIN_ARG_INFO(arginfo_imagegrabscreen, 0)
267 ZEND_END_ARG_INFO()
268 #endif
269 
270 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagerotate, 0, 0, 3)
271 	ZEND_ARG_INFO(0, im)
272 	ZEND_ARG_INFO(0, angle)
273 	ZEND_ARG_INFO(0, bgdcolor)
274 	ZEND_ARG_INFO(0, ignoretransparent)
275 ZEND_END_ARG_INFO()
276 
277 ZEND_BEGIN_ARG_INFO(arginfo_imagesettile, 0)
278 	ZEND_ARG_INFO(0, im)
279 	ZEND_ARG_INFO(0, tile)
280 ZEND_END_ARG_INFO()
281 
282 ZEND_BEGIN_ARG_INFO(arginfo_imagesetbrush, 0)
283 	ZEND_ARG_INFO(0, im)
284 	ZEND_ARG_INFO(0, brush)
285 ZEND_END_ARG_INFO()
286 
287 ZEND_BEGIN_ARG_INFO(arginfo_imagecreate, 0)
288 	ZEND_ARG_INFO(0, x_size)
289 	ZEND_ARG_INFO(0, y_size)
290 ZEND_END_ARG_INFO()
291 
292 ZEND_BEGIN_ARG_INFO(arginfo_imagetypes, 0)
293 ZEND_END_ARG_INFO()
294 
295 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromstring, 0)
296 	ZEND_ARG_INFO(0, image)
297 ZEND_END_ARG_INFO()
298 
299 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgif, 0)
300 	ZEND_ARG_INFO(0, filename)
301 ZEND_END_ARG_INFO()
302 
303 #ifdef HAVE_GD_JPG
304 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromjpeg, 0)
305 	ZEND_ARG_INFO(0, filename)
306 ZEND_END_ARG_INFO()
307 #endif
308 
309 #ifdef HAVE_GD_PNG
310 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefrompng, 0)
311 	ZEND_ARG_INFO(0, filename)
312 ZEND_END_ARG_INFO()
313 #endif
314 
315 #ifdef HAVE_GD_WEBP
316 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromwebp, 0)
317 	ZEND_ARG_INFO(0, filename)
318 ZEND_END_ARG_INFO()
319 #endif
320 
321 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromxbm, 0)
322 	ZEND_ARG_INFO(0, filename)
323 ZEND_END_ARG_INFO()
324 
325 #if defined(HAVE_GD_XPM)
326 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromxpm, 0)
327 	ZEND_ARG_INFO(0, filename)
328 ZEND_END_ARG_INFO()
329 #endif
330 
331 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromwbmp, 0)
332 	ZEND_ARG_INFO(0, filename)
333 ZEND_END_ARG_INFO()
334 
335 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd, 0)
336 	ZEND_ARG_INFO(0, filename)
337 ZEND_END_ARG_INFO()
338 
339 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd2, 0)
340 	ZEND_ARG_INFO(0, filename)
341 ZEND_END_ARG_INFO()
342 
343 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd2part, 0)
344 	ZEND_ARG_INFO(0, filename)
345 	ZEND_ARG_INFO(0, srcX)
346 	ZEND_ARG_INFO(0, srcY)
347 	ZEND_ARG_INFO(0, width)
348 	ZEND_ARG_INFO(0, height)
349 ZEND_END_ARG_INFO()
350 
351 #if defined(HAVE_GD_BMP)
352 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefrombmp, 0)
353 	ZEND_ARG_INFO(0, filename)
354 ZEND_END_ARG_INFO()
355 #endif
356 
357 #if defined(HAVE_GD_TGA)
358 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromtga, 0)
359 	ZEND_ARG_INFO(0, filename)
360 ZEND_END_ARG_INFO()
361 #endif
362 
363 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagexbm, 0, 0, 2)
364 	ZEND_ARG_INFO(0, im)
365 	ZEND_ARG_INFO(0, filename)
366 	ZEND_ARG_INFO(0, foreground)
367 ZEND_END_ARG_INFO()
368 
369 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegif, 0, 0, 1)
370 	ZEND_ARG_INFO(0, im)
371 	ZEND_ARG_INFO(0, to)
372 ZEND_END_ARG_INFO()
373 
374 #ifdef HAVE_GD_PNG
375 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagepng, 0, 0, 1)
376 	ZEND_ARG_INFO(0, im)
377 	ZEND_ARG_INFO(0, to)
378 	ZEND_ARG_INFO(0, quality)
379 	ZEND_ARG_INFO(0, filters)
380 ZEND_END_ARG_INFO()
381 #endif
382 
383 #ifdef HAVE_GD_WEBP
384 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagewebp, 0, 0, 1)
385 	ZEND_ARG_INFO(0, im)
386 	ZEND_ARG_INFO(0, to)
387 	ZEND_ARG_INFO(0, quality)
388 ZEND_END_ARG_INFO()
389 #endif
390 
391 #ifdef HAVE_GD_JPG
392 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagejpeg, 0, 0, 1)
393 	ZEND_ARG_INFO(0, im)
394 	ZEND_ARG_INFO(0, to)
395 	ZEND_ARG_INFO(0, quality)
396 ZEND_END_ARG_INFO()
397 #endif
398 
399 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagewbmp, 0, 0, 1)
400 	ZEND_ARG_INFO(0, im)
401 	ZEND_ARG_INFO(0, to)
402 	ZEND_ARG_INFO(0, foreground)
403 ZEND_END_ARG_INFO()
404 
405 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegd, 0, 0, 1)
406 	ZEND_ARG_INFO(0, im)
407 	ZEND_ARG_INFO(0, to)
408 ZEND_END_ARG_INFO()
409 
410 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegd2, 0, 0, 1)
411 	ZEND_ARG_INFO(0, im)
412 	ZEND_ARG_INFO(0, to)
413 	ZEND_ARG_INFO(0, chunk_size)
414 	ZEND_ARG_INFO(0, type)
415 ZEND_END_ARG_INFO()
416 
417 #if defined(HAVE_GD_BMP)
418 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagebmp, 0, 0, 1)
419 	ZEND_ARG_INFO(0, im)
420 	ZEND_ARG_INFO(0, to)
421 	ZEND_ARG_INFO(0, compressed)
422 ZEND_END_ARG_INFO()
423 #endif
424 
425 ZEND_BEGIN_ARG_INFO(arginfo_imagedestroy, 0)
426 	ZEND_ARG_INFO(0, im)
427 ZEND_END_ARG_INFO()
428 
429 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorallocate, 0)
430 	ZEND_ARG_INFO(0, im)
431 	ZEND_ARG_INFO(0, red)
432 	ZEND_ARG_INFO(0, green)
433 	ZEND_ARG_INFO(0, blue)
434 ZEND_END_ARG_INFO()
435 
436 ZEND_BEGIN_ARG_INFO(arginfo_imagepalettecopy, 0)
437 	ZEND_ARG_INFO(0, dst)
438 	ZEND_ARG_INFO(0, src)
439 ZEND_END_ARG_INFO()
440 
441 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorat, 0)
442 	ZEND_ARG_INFO(0, im)
443 	ZEND_ARG_INFO(0, x)
444 	ZEND_ARG_INFO(0, y)
445 ZEND_END_ARG_INFO()
446 
447 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorclosest, 0)
448 	ZEND_ARG_INFO(0, im)
449 	ZEND_ARG_INFO(0, red)
450 	ZEND_ARG_INFO(0, green)
451 	ZEND_ARG_INFO(0, blue)
452 ZEND_END_ARG_INFO()
453 
454 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorclosesthwb, 0)
455 	ZEND_ARG_INFO(0, im)
456 	ZEND_ARG_INFO(0, red)
457 	ZEND_ARG_INFO(0, green)
458 	ZEND_ARG_INFO(0, blue)
459 ZEND_END_ARG_INFO()
460 
461 ZEND_BEGIN_ARG_INFO(arginfo_imagecolordeallocate, 0)
462 	ZEND_ARG_INFO(0, im)
463 	ZEND_ARG_INFO(0, index)
464 ZEND_END_ARG_INFO()
465 
466 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorresolve, 0)
467 	ZEND_ARG_INFO(0, im)
468 	ZEND_ARG_INFO(0, red)
469 	ZEND_ARG_INFO(0, green)
470 	ZEND_ARG_INFO(0, blue)
471 ZEND_END_ARG_INFO()
472 
473 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorexact, 0)
474 	ZEND_ARG_INFO(0, im)
475 	ZEND_ARG_INFO(0, red)
476 	ZEND_ARG_INFO(0, green)
477 	ZEND_ARG_INFO(0, blue)
478 ZEND_END_ARG_INFO()
479 
480 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecolorset, 0, 0, 5)
481 	ZEND_ARG_INFO(0, im)
482 	ZEND_ARG_INFO(0, color)
483 	ZEND_ARG_INFO(0, red)
484 	ZEND_ARG_INFO(0, green)
485 	ZEND_ARG_INFO(0, blue)
486 	ZEND_ARG_INFO(0, alpha)
487 ZEND_END_ARG_INFO()
488 
489 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorsforindex, 0)
490 	ZEND_ARG_INFO(0, im)
491 	ZEND_ARG_INFO(0, index)
492 ZEND_END_ARG_INFO()
493 
494 ZEND_BEGIN_ARG_INFO(arginfo_imagegammacorrect, 0)
495 	ZEND_ARG_INFO(0, im)
496 	ZEND_ARG_INFO(0, inputgamma)
497 	ZEND_ARG_INFO(0, outputgamma)
498 ZEND_END_ARG_INFO()
499 
500 ZEND_BEGIN_ARG_INFO(arginfo_imagesetpixel, 0)
501 	ZEND_ARG_INFO(0, im)
502 	ZEND_ARG_INFO(0, x)
503 	ZEND_ARG_INFO(0, y)
504 	ZEND_ARG_INFO(0, col)
505 ZEND_END_ARG_INFO()
506 
507 ZEND_BEGIN_ARG_INFO(arginfo_imageline, 0)
508 	ZEND_ARG_INFO(0, im)
509 	ZEND_ARG_INFO(0, x1)
510 	ZEND_ARG_INFO(0, y1)
511 	ZEND_ARG_INFO(0, x2)
512 	ZEND_ARG_INFO(0, y2)
513 	ZEND_ARG_INFO(0, col)
514 ZEND_END_ARG_INFO()
515 
516 ZEND_BEGIN_ARG_INFO(arginfo_imagedashedline, 0)
517 	ZEND_ARG_INFO(0, im)
518 	ZEND_ARG_INFO(0, x1)
519 	ZEND_ARG_INFO(0, y1)
520 	ZEND_ARG_INFO(0, x2)
521 	ZEND_ARG_INFO(0, y2)
522 	ZEND_ARG_INFO(0, col)
523 ZEND_END_ARG_INFO()
524 
525 ZEND_BEGIN_ARG_INFO(arginfo_imagerectangle, 0)
526 	ZEND_ARG_INFO(0, im)
527 	ZEND_ARG_INFO(0, x1)
528 	ZEND_ARG_INFO(0, y1)
529 	ZEND_ARG_INFO(0, x2)
530 	ZEND_ARG_INFO(0, y2)
531 	ZEND_ARG_INFO(0, col)
532 ZEND_END_ARG_INFO()
533 
534 ZEND_BEGIN_ARG_INFO(arginfo_imagefilledrectangle, 0)
535 	ZEND_ARG_INFO(0, im)
536 	ZEND_ARG_INFO(0, x1)
537 	ZEND_ARG_INFO(0, y1)
538 	ZEND_ARG_INFO(0, x2)
539 	ZEND_ARG_INFO(0, y2)
540 	ZEND_ARG_INFO(0, col)
541 ZEND_END_ARG_INFO()
542 
543 ZEND_BEGIN_ARG_INFO(arginfo_imagearc, 0)
544 	ZEND_ARG_INFO(0, im)
545 	ZEND_ARG_INFO(0, cx)
546 	ZEND_ARG_INFO(0, cy)
547 	ZEND_ARG_INFO(0, w)
548 	ZEND_ARG_INFO(0, h)
549 	ZEND_ARG_INFO(0, s)
550 	ZEND_ARG_INFO(0, e)
551 	ZEND_ARG_INFO(0, col)
552 ZEND_END_ARG_INFO()
553 
554 ZEND_BEGIN_ARG_INFO(arginfo_imageellipse, 0)
555 	ZEND_ARG_INFO(0, im)
556 	ZEND_ARG_INFO(0, cx)
557 	ZEND_ARG_INFO(0, cy)
558 	ZEND_ARG_INFO(0, w)
559 	ZEND_ARG_INFO(0, h)
560 	ZEND_ARG_INFO(0, color)
561 ZEND_END_ARG_INFO()
562 
563 ZEND_BEGIN_ARG_INFO(arginfo_imagefilltoborder, 0)
564 	ZEND_ARG_INFO(0, im)
565 	ZEND_ARG_INFO(0, x)
566 	ZEND_ARG_INFO(0, y)
567 	ZEND_ARG_INFO(0, border)
568 	ZEND_ARG_INFO(0, col)
569 ZEND_END_ARG_INFO()
570 
571 ZEND_BEGIN_ARG_INFO(arginfo_imagefill, 0)
572 	ZEND_ARG_INFO(0, im)
573 	ZEND_ARG_INFO(0, x)
574 	ZEND_ARG_INFO(0, y)
575 	ZEND_ARG_INFO(0, col)
576 ZEND_END_ARG_INFO()
577 
578 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorstotal, 0)
579 	ZEND_ARG_INFO(0, im)
580 ZEND_END_ARG_INFO()
581 
582 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecolortransparent, 0, 0, 1)
583 	ZEND_ARG_INFO(0, im)
584 	ZEND_ARG_INFO(0, col)
585 ZEND_END_ARG_INFO()
586 
587 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageinterlace, 0, 0, 1)
588 	ZEND_ARG_INFO(0, im)
589 	ZEND_ARG_INFO(0, interlace)
590 ZEND_END_ARG_INFO()
591 
592 ZEND_BEGIN_ARG_INFO(arginfo_imagepolygon, 0)
593 	ZEND_ARG_INFO(0, im)
594 	ZEND_ARG_INFO(0, points) /* ARRAY_INFO(0, points, 0) */
595 	ZEND_ARG_INFO(0, num_pos)
596 	ZEND_ARG_INFO(0, col)
597 ZEND_END_ARG_INFO()
598 
599 ZEND_BEGIN_ARG_INFO(arginfo_imageopenpolygon, 0)
600 	ZEND_ARG_INFO(0, im)
601 	ZEND_ARG_INFO(0, points) /* ARRAY_INFO(0, points, 0) */
602 	ZEND_ARG_INFO(0, num_pos)
603 	ZEND_ARG_INFO(0, col)
604 ZEND_END_ARG_INFO()
605 
606 ZEND_BEGIN_ARG_INFO(arginfo_imagefilledpolygon, 0)
607 	ZEND_ARG_INFO(0, im)
608 	ZEND_ARG_INFO(0, points) /* ARRAY_INFO(0, points, 0) */
609 	ZEND_ARG_INFO(0, num_pos)
610 	ZEND_ARG_INFO(0, col)
611 ZEND_END_ARG_INFO()
612 
613 ZEND_BEGIN_ARG_INFO(arginfo_imagefontwidth, 0)
614 	ZEND_ARG_INFO(0, font)
615 ZEND_END_ARG_INFO()
616 
617 ZEND_BEGIN_ARG_INFO(arginfo_imagefontheight, 0)
618 	ZEND_ARG_INFO(0, font)
619 ZEND_END_ARG_INFO()
620 
621 ZEND_BEGIN_ARG_INFO(arginfo_imagechar, 0)
622 	ZEND_ARG_INFO(0, im)
623 	ZEND_ARG_INFO(0, font)
624 	ZEND_ARG_INFO(0, x)
625 	ZEND_ARG_INFO(0, y)
626 	ZEND_ARG_INFO(0, c)
627 	ZEND_ARG_INFO(0, col)
628 ZEND_END_ARG_INFO()
629 
630 ZEND_BEGIN_ARG_INFO(arginfo_imagecharup, 0)
631 	ZEND_ARG_INFO(0, im)
632 	ZEND_ARG_INFO(0, font)
633 	ZEND_ARG_INFO(0, x)
634 	ZEND_ARG_INFO(0, y)
635 	ZEND_ARG_INFO(0, c)
636 	ZEND_ARG_INFO(0, col)
637 ZEND_END_ARG_INFO()
638 
639 ZEND_BEGIN_ARG_INFO(arginfo_imagestring, 0)
640 	ZEND_ARG_INFO(0, im)
641 	ZEND_ARG_INFO(0, font)
642 	ZEND_ARG_INFO(0, x)
643 	ZEND_ARG_INFO(0, y)
644 	ZEND_ARG_INFO(0, str)
645 	ZEND_ARG_INFO(0, col)
646 ZEND_END_ARG_INFO()
647 
648 ZEND_BEGIN_ARG_INFO(arginfo_imagestringup, 0)
649 	ZEND_ARG_INFO(0, im)
650 	ZEND_ARG_INFO(0, font)
651 	ZEND_ARG_INFO(0, x)
652 	ZEND_ARG_INFO(0, y)
653 	ZEND_ARG_INFO(0, str)
654 	ZEND_ARG_INFO(0, col)
655 ZEND_END_ARG_INFO()
656 
657 ZEND_BEGIN_ARG_INFO(arginfo_imagecopy, 0)
658 	ZEND_ARG_INFO(0, dst_im)
659 	ZEND_ARG_INFO(0, src_im)
660 	ZEND_ARG_INFO(0, dst_x)
661 	ZEND_ARG_INFO(0, dst_y)
662 	ZEND_ARG_INFO(0, src_x)
663 	ZEND_ARG_INFO(0, src_y)
664 	ZEND_ARG_INFO(0, src_w)
665 	ZEND_ARG_INFO(0, src_h)
666 ZEND_END_ARG_INFO()
667 
668 ZEND_BEGIN_ARG_INFO(arginfo_imagecopymerge, 0)
669 	ZEND_ARG_INFO(0, dst_im)
670 	ZEND_ARG_INFO(0, src_im)
671 	ZEND_ARG_INFO(0, dst_x)
672 	ZEND_ARG_INFO(0, dst_y)
673 	ZEND_ARG_INFO(0, src_x)
674 	ZEND_ARG_INFO(0, src_y)
675 	ZEND_ARG_INFO(0, src_w)
676 	ZEND_ARG_INFO(0, src_h)
677 	ZEND_ARG_INFO(0, pct)
678 ZEND_END_ARG_INFO()
679 
680 ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergegray, 0)
681 	ZEND_ARG_INFO(0, dst_im)
682 	ZEND_ARG_INFO(0, src_im)
683 	ZEND_ARG_INFO(0, dst_x)
684 	ZEND_ARG_INFO(0, dst_y)
685 	ZEND_ARG_INFO(0, src_x)
686 	ZEND_ARG_INFO(0, src_y)
687 	ZEND_ARG_INFO(0, src_w)
688 	ZEND_ARG_INFO(0, src_h)
689 	ZEND_ARG_INFO(0, pct)
690 ZEND_END_ARG_INFO()
691 
692 ZEND_BEGIN_ARG_INFO(arginfo_imagecopyresized, 0)
693 	ZEND_ARG_INFO(0, dst_im)
694 	ZEND_ARG_INFO(0, src_im)
695 	ZEND_ARG_INFO(0, dst_x)
696 	ZEND_ARG_INFO(0, dst_y)
697 	ZEND_ARG_INFO(0, src_x)
698 	ZEND_ARG_INFO(0, src_y)
699 	ZEND_ARG_INFO(0, dst_w)
700 	ZEND_ARG_INFO(0, dst_h)
701 	ZEND_ARG_INFO(0, src_w)
702 	ZEND_ARG_INFO(0, src_h)
703 ZEND_END_ARG_INFO()
704 
705 ZEND_BEGIN_ARG_INFO(arginfo_imagesx, 0)
706 	ZEND_ARG_INFO(0, im)
707 ZEND_END_ARG_INFO()
708 
709 ZEND_BEGIN_ARG_INFO(arginfo_imagesy, 0)
710 	ZEND_ARG_INFO(0, im)
711 ZEND_END_ARG_INFO()
712 
713 ZEND_BEGIN_ARG_INFO(arginfo_imagesetclip, 0)
714 	ZEND_ARG_INFO(0, im)
715 	ZEND_ARG_INFO(0, x1)
716 	ZEND_ARG_INFO(0, y1)
717 	ZEND_ARG_INFO(0, x2)
718 	ZEND_ARG_INFO(0, y2)
719 ZEND_END_ARG_INFO()
720 
721 ZEND_BEGIN_ARG_INFO(arginfo_imagegetclip, 0)
722 	ZEND_ARG_INFO(0, im)
723 ZEND_END_ARG_INFO()
724 
725 #ifdef HAVE_GD_FREETYPE
726 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageftbbox, 0, 0, 4)
727 	ZEND_ARG_INFO(0, size)
728 	ZEND_ARG_INFO(0, angle)
729 	ZEND_ARG_INFO(0, font_file)
730 	ZEND_ARG_INFO(0, text)
731 	ZEND_ARG_INFO(0, extrainfo) /* ARRAY_INFO(0, extrainfo, 0) */
732 ZEND_END_ARG_INFO()
733 
734 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagefttext, 0, 0, 8)
735 	ZEND_ARG_INFO(0, im)
736 	ZEND_ARG_INFO(0, size)
737 	ZEND_ARG_INFO(0, angle)
738 	ZEND_ARG_INFO(0, x)
739 	ZEND_ARG_INFO(0, y)
740 	ZEND_ARG_INFO(0, col)
741 	ZEND_ARG_INFO(0, font_file)
742 	ZEND_ARG_INFO(0, text)
743 	ZEND_ARG_INFO(0, extrainfo) /* ARRAY_INFO(0, extrainfo, 0) */
744 ZEND_END_ARG_INFO()
745 
746 ZEND_BEGIN_ARG_INFO(arginfo_imagettfbbox, 0)
747 	ZEND_ARG_INFO(0, size)
748 	ZEND_ARG_INFO(0, angle)
749 	ZEND_ARG_INFO(0, font_file)
750 	ZEND_ARG_INFO(0, text)
751 ZEND_END_ARG_INFO()
752 
753 ZEND_BEGIN_ARG_INFO(arginfo_imagettftext, 0)
754 	ZEND_ARG_INFO(0, im)
755 	ZEND_ARG_INFO(0, size)
756 	ZEND_ARG_INFO(0, angle)
757 	ZEND_ARG_INFO(0, x)
758 	ZEND_ARG_INFO(0, y)
759 	ZEND_ARG_INFO(0, col)
760 	ZEND_ARG_INFO(0, font_file)
761 	ZEND_ARG_INFO(0, text)
762 ZEND_END_ARG_INFO()
763 #endif
764 
765 ZEND_BEGIN_ARG_INFO_EX(arginfo_image2wbmp, 0, 0, 1)
766 	ZEND_ARG_INFO(0, im)
767 	ZEND_ARG_INFO(0, filename)
768 	ZEND_ARG_INFO(0, foreground)
769 ZEND_END_ARG_INFO()
770 
771 #if defined(HAVE_GD_JPG)
772 ZEND_BEGIN_ARG_INFO(arginfo_jpeg2wbmp, 0)
773 	ZEND_ARG_INFO(0, f_org)
774 	ZEND_ARG_INFO(0, f_dest)
775 	ZEND_ARG_INFO(0, d_height)
776 	ZEND_ARG_INFO(0, d_width)
777 	ZEND_ARG_INFO(0, d_threshold)
778 ZEND_END_ARG_INFO()
779 #endif
780 
781 #if defined(HAVE_GD_PNG)
782 ZEND_BEGIN_ARG_INFO(arginfo_png2wbmp, 0)
783 	ZEND_ARG_INFO(0, f_org)
784 	ZEND_ARG_INFO(0, f_dest)
785 	ZEND_ARG_INFO(0, d_height)
786 	ZEND_ARG_INFO(0, d_width)
787 	ZEND_ARG_INFO(0, d_threshold)
788 ZEND_END_ARG_INFO()
789 #endif
790 
791 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagefilter, 0, 0, 2)
792 	ZEND_ARG_INFO(0, im)
793 	ZEND_ARG_INFO(0, filtertype)
794 	ZEND_ARG_INFO(0, arg1)
795 	ZEND_ARG_INFO(0, arg2)
796 	ZEND_ARG_INFO(0, arg3)
797 	ZEND_ARG_INFO(0, arg4)
798 ZEND_END_ARG_INFO()
799 
800 ZEND_BEGIN_ARG_INFO(arginfo_imageconvolution, 0)
801 	ZEND_ARG_INFO(0, im)
802 	ZEND_ARG_INFO(0, matrix3x3) /* ARRAY_INFO(0, matrix3x3, 0) */
803 	ZEND_ARG_INFO(0, div)
804 	ZEND_ARG_INFO(0, offset)
805 ZEND_END_ARG_INFO()
806 
807 ZEND_BEGIN_ARG_INFO(arginfo_imageflip, 0)
808 	ZEND_ARG_INFO(0, im)
809 	ZEND_ARG_INFO(0, mode)
810 ZEND_END_ARG_INFO()
811 
812 ZEND_BEGIN_ARG_INFO(arginfo_imageantialias, 0)
813 	ZEND_ARG_INFO(0, im)
814 	ZEND_ARG_INFO(0, on)
815 ZEND_END_ARG_INFO()
816 
817 ZEND_BEGIN_ARG_INFO(arginfo_imagecrop, 0)
818 	ZEND_ARG_INFO(0, im)
819 	ZEND_ARG_INFO(0, rect)
820 ZEND_END_ARG_INFO()
821 
822 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecropauto, 0, 0, 1)
823 	ZEND_ARG_INFO(0, im)
824 	ZEND_ARG_INFO(0, mode)
825 	ZEND_ARG_INFO(0, threshold)
826 	ZEND_ARG_INFO(0, color)
827 ZEND_END_ARG_INFO()
828 
829 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagescale, 0, 0, 2)
830 	ZEND_ARG_INFO(0, im)
831 	ZEND_ARG_INFO(0, new_width)
832 	ZEND_ARG_INFO(0, new_height)
833 	ZEND_ARG_INFO(0, mode)
834 ZEND_END_ARG_INFO()
835 
836 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageaffine, 0, 0, 2)
837 	ZEND_ARG_INFO(0, im)
838 	ZEND_ARG_INFO(0, affine)
839 	ZEND_ARG_INFO(0, clip)
840 ZEND_END_ARG_INFO()
841 
842 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageaffinematrixget, 0, 0, 1)
843 	ZEND_ARG_INFO(0, type)
844 	ZEND_ARG_INFO(0, options)
845 ZEND_END_ARG_INFO()
846 
847 ZEND_BEGIN_ARG_INFO(arginfo_imageaffinematrixconcat, 0)
848 	ZEND_ARG_INFO(0, m1)
849 	ZEND_ARG_INFO(0, m2)
850 ZEND_END_ARG_INFO()
851 
852 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagesetinterpolation, 0, 0, 1)
853 	ZEND_ARG_INFO(0, im)
854 	ZEND_ARG_INFO(0, method)
855 ZEND_END_ARG_INFO()
856 
857 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageresolution, 0, 0, 1)
858 	ZEND_ARG_INFO(0, im)
859 	ZEND_ARG_INFO(0, res_x)
860 	ZEND_ARG_INFO(0, res_y)
861 ZEND_END_ARG_INFO()
862 
863 /* }}} */
864 
865 /* {{{ gd_functions[]
866  */
867 static const zend_function_entry gd_functions[] = {
868 	PHP_FE(gd_info,                                 arginfo_gd_info)
869 	PHP_FE(imagearc,								arginfo_imagearc)
870 	PHP_FE(imageellipse,							arginfo_imageellipse)
871 	PHP_FE(imagechar,								arginfo_imagechar)
872 	PHP_FE(imagecharup,								arginfo_imagecharup)
873 	PHP_FE(imagecolorat,							arginfo_imagecolorat)
874 	PHP_FE(imagecolorallocate,						arginfo_imagecolorallocate)
875 	PHP_FE(imagepalettecopy,						arginfo_imagepalettecopy)
876 	PHP_FE(imagecreatefromstring,					arginfo_imagecreatefromstring)
877 	PHP_FE(imagecolorclosest,						arginfo_imagecolorclosest)
878 	PHP_FE(imagecolorclosesthwb,					arginfo_imagecolorclosesthwb)
879 	PHP_FE(imagecolordeallocate,					arginfo_imagecolordeallocate)
880 	PHP_FE(imagecolorresolve,						arginfo_imagecolorresolve)
881 	PHP_FE(imagecolorexact,							arginfo_imagecolorexact)
882 	PHP_FE(imagecolorset,							arginfo_imagecolorset)
883 	PHP_FE(imagecolortransparent,					arginfo_imagecolortransparent)
884 	PHP_FE(imagecolorstotal,						arginfo_imagecolorstotal)
885 	PHP_FE(imagecolorsforindex,						arginfo_imagecolorsforindex)
886 	PHP_FE(imagecopy,								arginfo_imagecopy)
887 	PHP_FE(imagecopymerge,							arginfo_imagecopymerge)
888 	PHP_FE(imagecopymergegray,						arginfo_imagecopymergegray)
889 	PHP_FE(imagecopyresized,						arginfo_imagecopyresized)
890 	PHP_FE(imagecreate,								arginfo_imagecreate)
891 	PHP_FE(imagecreatetruecolor,					arginfo_imagecreatetruecolor)
892 	PHP_FE(imageistruecolor,						arginfo_imageistruecolor)
893 	PHP_FE(imagetruecolortopalette,					arginfo_imagetruecolortopalette)
894 	PHP_FE(imagepalettetotruecolor,					arginfo_imagepalettetotruecolor)
895 	PHP_FE(imagesetthickness,						arginfo_imagesetthickness)
896 	PHP_FE(imagefilledarc,							arginfo_imagefilledarc)
897 	PHP_FE(imagefilledellipse,						arginfo_imagefilledellipse)
898 	PHP_FE(imagealphablending,						arginfo_imagealphablending)
899 	PHP_FE(imagesavealpha,							arginfo_imagesavealpha)
900 	PHP_FE(imagecolorallocatealpha,					arginfo_imagecolorallocatealpha)
901 	PHP_FE(imagecolorresolvealpha, 					arginfo_imagecolorresolvealpha)
902 	PHP_FE(imagecolorclosestalpha,					arginfo_imagecolorclosestalpha)
903 	PHP_FE(imagecolorexactalpha,					arginfo_imagecolorexactalpha)
904 	PHP_FE(imagecopyresampled,						arginfo_imagecopyresampled)
905 
906 #ifdef PHP_WIN32
907 	PHP_FE(imagegrabwindow,							arginfo_imagegrabwindow)
908 	PHP_FE(imagegrabscreen,							arginfo_imagegrabscreen)
909 #endif
910 
911 	PHP_FE(imagerotate,     						arginfo_imagerotate)
912 	PHP_FE(imageflip,								arginfo_imageflip)
913 
914 	PHP_FE(imageantialias,							arginfo_imageantialias)
915 	PHP_FE(imagecrop,								arginfo_imagecrop)
916 	PHP_FE(imagecropauto,							arginfo_imagecropauto)
917 	PHP_FE(imagescale,								arginfo_imagescale)
918 	PHP_FE(imageaffine,								arginfo_imageaffine)
919 	PHP_FE(imageaffinematrixconcat,					arginfo_imageaffinematrixconcat)
920 	PHP_FE(imageaffinematrixget,					arginfo_imageaffinematrixget)
921 	PHP_FE(imagesetinterpolation,                   arginfo_imagesetinterpolation)
922 	PHP_FE(imagesettile,							arginfo_imagesettile)
923 	PHP_FE(imagesetbrush,							arginfo_imagesetbrush)
924 	PHP_FE(imagesetstyle,							arginfo_imagesetstyle)
925 
926 #ifdef HAVE_GD_PNG
927 	PHP_FE(imagecreatefrompng,						arginfo_imagecreatefrompng)
928 #endif
929 #ifdef HAVE_GD_WEBP
930 	PHP_FE(imagecreatefromwebp,						arginfo_imagecreatefromwebp)
931 #endif
932 	PHP_FE(imagecreatefromgif,						arginfo_imagecreatefromgif)
933 #ifdef HAVE_GD_JPG
934 	PHP_FE(imagecreatefromjpeg,						arginfo_imagecreatefromjpeg)
935 #endif
936 	PHP_FE(imagecreatefromwbmp,						arginfo_imagecreatefromwbmp)
937 	PHP_FE(imagecreatefromxbm,						arginfo_imagecreatefromxbm)
938 #if defined(HAVE_GD_XPM)
939 	PHP_FE(imagecreatefromxpm,						arginfo_imagecreatefromxpm)
940 #endif
941 	PHP_FE(imagecreatefromgd,						arginfo_imagecreatefromgd)
942 	PHP_FE(imagecreatefromgd2,						arginfo_imagecreatefromgd2)
943 	PHP_FE(imagecreatefromgd2part,					arginfo_imagecreatefromgd2part)
944 #ifdef HAVE_GD_BMP
945 	PHP_FE(imagecreatefrombmp,						arginfo_imagecreatefrombmp)
946 #endif
947 #ifdef HAVE_GD_TGA
948 	PHP_FE(imagecreatefromtga,						arginfo_imagecreatefromtga)
949 #endif
950 #ifdef HAVE_GD_PNG
951 	PHP_FE(imagepng,								arginfo_imagepng)
952 #endif
953 #ifdef HAVE_GD_WEBP
954 	PHP_FE(imagewebp,								arginfo_imagewebp)
955 #endif
956 	PHP_FE(imagegif,								arginfo_imagegif)
957 #ifdef HAVE_GD_JPG
958 	PHP_FE(imagejpeg,								arginfo_imagejpeg)
959 #endif
960 	PHP_FE(imagewbmp,                               arginfo_imagewbmp)
961 	PHP_FE(imagegd,									arginfo_imagegd)
962 	PHP_FE(imagegd2,								arginfo_imagegd2)
963 #ifdef HAVE_GD_BMP
964 	PHP_FE(imagebmp,								arginfo_imagebmp)
965 #endif
966 
967 	PHP_FE(imagedestroy,							arginfo_imagedestroy)
968 	PHP_FE(imagegammacorrect,						arginfo_imagegammacorrect)
969 	PHP_FE(imagefill,								arginfo_imagefill)
970 	PHP_FE(imagefilledpolygon,						arginfo_imagefilledpolygon)
971 	PHP_FE(imagefilledrectangle,					arginfo_imagefilledrectangle)
972 	PHP_FE(imagefilltoborder,						arginfo_imagefilltoborder)
973 	PHP_FE(imagefontwidth,							arginfo_imagefontwidth)
974 	PHP_FE(imagefontheight,							arginfo_imagefontheight)
975 	PHP_FE(imageinterlace,							arginfo_imageinterlace)
976 	PHP_FE(imageline,								arginfo_imageline)
977 	PHP_FE(imageloadfont,							arginfo_imageloadfont)
978 	PHP_FE(imagepolygon,							arginfo_imagepolygon)
979 	PHP_FE(imageopenpolygon,						arginfo_imageopenpolygon)
980 	PHP_FE(imagerectangle,							arginfo_imagerectangle)
981 	PHP_FE(imagesetpixel,							arginfo_imagesetpixel)
982 	PHP_FE(imagestring,								arginfo_imagestring)
983 	PHP_FE(imagestringup,							arginfo_imagestringup)
984 	PHP_FE(imagesx,									arginfo_imagesx)
985 	PHP_FE(imagesy,									arginfo_imagesy)
986 	PHP_FE(imagesetclip,							arginfo_imagesetclip)
987 	PHP_FE(imagegetclip,							arginfo_imagegetclip)
988 	PHP_FE(imagedashedline,							arginfo_imagedashedline)
989 
990 #ifdef HAVE_GD_FREETYPE
991 	PHP_FE(imagettfbbox,							arginfo_imagettfbbox)
992 	PHP_FE(imagettftext,							arginfo_imagettftext)
993 	PHP_FE(imageftbbox,								arginfo_imageftbbox)
994 	PHP_FE(imagefttext,								arginfo_imagefttext)
995 #endif
996 
997 	PHP_FE(imagetypes,								arginfo_imagetypes)
998 
999 #if defined(HAVE_GD_JPG)
1000 	PHP_DEP_FE(jpeg2wbmp,							arginfo_jpeg2wbmp)
1001 #endif
1002 #if defined(HAVE_GD_PNG)
1003 	PHP_DEP_FE(png2wbmp,							arginfo_png2wbmp)
1004 #endif
1005 	PHP_DEP_FE(image2wbmp,							arginfo_image2wbmp)
1006 	PHP_FE(imagelayereffect,						arginfo_imagelayereffect)
1007 	PHP_FE(imagexbm,                                arginfo_imagexbm)
1008 
1009 	PHP_FE(imagecolormatch,							arginfo_imagecolormatch)
1010 
1011 /* gd filters */
1012 	PHP_FE(imagefilter,     						arginfo_imagefilter)
1013 	PHP_FE(imageconvolution,						arginfo_imageconvolution)
1014 
1015 	PHP_FE(imageresolution,							arginfo_imageresolution)
1016 
1017 	PHP_FE_END
1018 };
1019 /* }}} */
1020 
1021 zend_module_entry gd_module_entry = {
1022 	STANDARD_MODULE_HEADER,
1023 	"gd",
1024 	gd_functions,
1025 	PHP_MINIT(gd),
1026 	PHP_MSHUTDOWN(gd),
1027 	NULL,
1028 	PHP_RSHUTDOWN(gd),
1029 	PHP_MINFO(gd),
1030 	PHP_GD_VERSION,
1031 	STANDARD_MODULE_PROPERTIES
1032 };
1033 
1034 #ifdef COMPILE_DL_GD
1035 ZEND_GET_MODULE(gd)
1036 #endif
1037 
1038 /* {{{ PHP_INI_BEGIN */
1039 PHP_INI_BEGIN()
1040 	PHP_INI_ENTRY("gd.jpeg_ignore_warning", "1", PHP_INI_ALL, NULL)
1041 PHP_INI_END()
1042 /* }}} */
1043 
1044 /* {{{ php_free_gd_image
1045  */
php_free_gd_image(zend_resource *rsrc)1046 static void php_free_gd_image(zend_resource *rsrc)
1047 {
1048 	gdImageDestroy((gdImagePtr) rsrc->ptr);
1049 }
1050 /* }}} */
1051 
1052 /* {{{ php_free_gd_font
1053  */
php_free_gd_font(zend_resource *rsrc)1054 static void php_free_gd_font(zend_resource *rsrc)
1055 {
1056 	gdFontPtr fp = (gdFontPtr) rsrc->ptr;
1057 
1058 	if (fp->data) {
1059 		efree(fp->data);
1060 	}
1061 
1062 	efree(fp);
1063 }
1064 /* }}} */
1065 
1066 /* {{{ php_gd_error_method
1067  */
php_gd_error_method(int type, const char *format, va_list args)1068 void php_gd_error_method(int type, const char *format, va_list args)
1069 {
1070 
1071 	switch (type) {
1072 #ifndef PHP_WIN32
1073 		case GD_DEBUG:
1074 		case GD_INFO:
1075 #endif
1076 		case GD_NOTICE:
1077 			type = E_NOTICE;
1078 			break;
1079 		case GD_WARNING:
1080 			type = E_WARNING;
1081 			break;
1082 		default:
1083 			type = E_ERROR;
1084 	}
1085 	php_verror(NULL, "", type, format, args);
1086 }
1087 /* }}} */
1088 
1089 /* {{{ PHP_MINIT_FUNCTION
1090  */
PHP_MINIT_FUNCTIONnull1091 PHP_MINIT_FUNCTION(gd)
1092 {
1093 	le_gd = zend_register_list_destructors_ex(php_free_gd_image, NULL, "gd", module_number);
1094 	le_gd_font = zend_register_list_destructors_ex(php_free_gd_font, NULL, "gd font", module_number);
1095 
1096 #if defined(HAVE_GD_FREETYPE) && defined(HAVE_GD_BUNDLED)
1097 	gdFontCacheMutexSetup();
1098 #endif
1099 	gdSetErrorMethod(php_gd_error_method);
1100 
1101 	REGISTER_INI_ENTRIES();
1102 
1103 	REGISTER_LONG_CONSTANT("IMG_GIF", PHP_IMG_GIF, CONST_CS | CONST_PERSISTENT);
1104 	REGISTER_LONG_CONSTANT("IMG_JPG", PHP_IMG_JPG, CONST_CS | CONST_PERSISTENT);
1105 	REGISTER_LONG_CONSTANT("IMG_JPEG", PHP_IMG_JPEG, CONST_CS | CONST_PERSISTENT);
1106 	REGISTER_LONG_CONSTANT("IMG_PNG", PHP_IMG_PNG, CONST_CS | CONST_PERSISTENT);
1107 	REGISTER_LONG_CONSTANT("IMG_WBMP", PHP_IMG_WBMP, CONST_CS | CONST_PERSISTENT);
1108 	REGISTER_LONG_CONSTANT("IMG_XPM", PHP_IMG_XPM, CONST_CS | CONST_PERSISTENT);
1109 	REGISTER_LONG_CONSTANT("IMG_WEBP", PHP_IMG_WEBP, CONST_CS | CONST_PERSISTENT);
1110 	REGISTER_LONG_CONSTANT("IMG_BMP", PHP_IMG_BMP, CONST_CS | CONST_PERSISTENT);
1111 	REGISTER_LONG_CONSTANT("IMG_TGA", PHP_IMG_TGA, CONST_CS | CONST_PERSISTENT);
1112 
1113 	/* special colours for gd */
1114 	REGISTER_LONG_CONSTANT("IMG_COLOR_TILED", gdTiled, CONST_CS | CONST_PERSISTENT);
1115 	REGISTER_LONG_CONSTANT("IMG_COLOR_STYLED", gdStyled, CONST_CS | CONST_PERSISTENT);
1116 	REGISTER_LONG_CONSTANT("IMG_COLOR_BRUSHED", gdBrushed, CONST_CS | CONST_PERSISTENT);
1117 	REGISTER_LONG_CONSTANT("IMG_COLOR_STYLEDBRUSHED", gdStyledBrushed, CONST_CS | CONST_PERSISTENT);
1118 	REGISTER_LONG_CONSTANT("IMG_COLOR_TRANSPARENT", gdTransparent, CONST_CS | CONST_PERSISTENT);
1119 
1120 	/* for imagefilledarc */
1121 	REGISTER_LONG_CONSTANT("IMG_ARC_ROUNDED", gdArc, CONST_CS | CONST_PERSISTENT);
1122 	REGISTER_LONG_CONSTANT("IMG_ARC_PIE", gdPie, CONST_CS | CONST_PERSISTENT);
1123 	REGISTER_LONG_CONSTANT("IMG_ARC_CHORD", gdChord, CONST_CS | CONST_PERSISTENT);
1124 	REGISTER_LONG_CONSTANT("IMG_ARC_NOFILL", gdNoFill, CONST_CS | CONST_PERSISTENT);
1125 	REGISTER_LONG_CONSTANT("IMG_ARC_EDGED", gdEdged, CONST_CS | CONST_PERSISTENT);
1126 
1127     /* GD2 image format types */
1128 	REGISTER_LONG_CONSTANT("IMG_GD2_RAW", GD2_FMT_RAW, CONST_CS | CONST_PERSISTENT);
1129 	REGISTER_LONG_CONSTANT("IMG_GD2_COMPRESSED", GD2_FMT_COMPRESSED, CONST_CS | CONST_PERSISTENT);
1130 	REGISTER_LONG_CONSTANT("IMG_FLIP_HORIZONTAL", GD_FLIP_HORINZONTAL, CONST_CS | CONST_PERSISTENT);
1131 	REGISTER_LONG_CONSTANT("IMG_FLIP_VERTICAL", GD_FLIP_VERTICAL, CONST_CS | CONST_PERSISTENT);
1132 	REGISTER_LONG_CONSTANT("IMG_FLIP_BOTH", GD_FLIP_BOTH, CONST_CS | CONST_PERSISTENT);
1133 	REGISTER_LONG_CONSTANT("IMG_EFFECT_REPLACE", gdEffectReplace, CONST_CS | CONST_PERSISTENT);
1134 	REGISTER_LONG_CONSTANT("IMG_EFFECT_ALPHABLEND", gdEffectAlphaBlend, CONST_CS | CONST_PERSISTENT);
1135 	REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT);
1136 	REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT);
1137 #ifdef gdEffectMultiply
1138 	REGISTER_LONG_CONSTANT("IMG_EFFECT_MULTIPLY", gdEffectMultiply, CONST_CS | CONST_PERSISTENT);
1139 #endif
1140 
1141 	REGISTER_LONG_CONSTANT("IMG_CROP_DEFAULT", GD_CROP_DEFAULT, CONST_CS | CONST_PERSISTENT);
1142 	REGISTER_LONG_CONSTANT("IMG_CROP_TRANSPARENT", GD_CROP_TRANSPARENT, CONST_CS | CONST_PERSISTENT);
1143 	REGISTER_LONG_CONSTANT("IMG_CROP_BLACK", GD_CROP_BLACK, CONST_CS | CONST_PERSISTENT);
1144 	REGISTER_LONG_CONSTANT("IMG_CROP_WHITE", GD_CROP_WHITE, CONST_CS | CONST_PERSISTENT);
1145 	REGISTER_LONG_CONSTANT("IMG_CROP_SIDES", GD_CROP_SIDES, CONST_CS | CONST_PERSISTENT);
1146 	REGISTER_LONG_CONSTANT("IMG_CROP_THRESHOLD", GD_CROP_THRESHOLD, CONST_CS | CONST_PERSISTENT);
1147 
1148 
1149 	REGISTER_LONG_CONSTANT("IMG_BELL", GD_BELL, CONST_CS | CONST_PERSISTENT);
1150 	REGISTER_LONG_CONSTANT("IMG_BESSEL", GD_BESSEL, CONST_CS | CONST_PERSISTENT);
1151 	REGISTER_LONG_CONSTANT("IMG_BILINEAR_FIXED", GD_BILINEAR_FIXED, CONST_CS | CONST_PERSISTENT);
1152 	REGISTER_LONG_CONSTANT("IMG_BICUBIC", GD_BICUBIC, CONST_CS | CONST_PERSISTENT);
1153 	REGISTER_LONG_CONSTANT("IMG_BICUBIC_FIXED", GD_BICUBIC_FIXED, CONST_CS | CONST_PERSISTENT);
1154 	REGISTER_LONG_CONSTANT("IMG_BLACKMAN", GD_BLACKMAN, CONST_CS | CONST_PERSISTENT);
1155 	REGISTER_LONG_CONSTANT("IMG_BOX", GD_BOX, CONST_CS | CONST_PERSISTENT);
1156 	REGISTER_LONG_CONSTANT("IMG_BSPLINE", GD_BSPLINE, CONST_CS | CONST_PERSISTENT);
1157 	REGISTER_LONG_CONSTANT("IMG_CATMULLROM", GD_CATMULLROM, CONST_CS | CONST_PERSISTENT);
1158 	REGISTER_LONG_CONSTANT("IMG_GAUSSIAN", GD_GAUSSIAN, CONST_CS | CONST_PERSISTENT);
1159 	REGISTER_LONG_CONSTANT("IMG_GENERALIZED_CUBIC", GD_GENERALIZED_CUBIC, CONST_CS | CONST_PERSISTENT);
1160 	REGISTER_LONG_CONSTANT("IMG_HERMITE", GD_HERMITE, CONST_CS | CONST_PERSISTENT);
1161 	REGISTER_LONG_CONSTANT("IMG_HAMMING", GD_HAMMING, CONST_CS | CONST_PERSISTENT);
1162 	REGISTER_LONG_CONSTANT("IMG_HANNING", GD_HANNING, CONST_CS | CONST_PERSISTENT);
1163 	REGISTER_LONG_CONSTANT("IMG_MITCHELL", GD_MITCHELL, CONST_CS | CONST_PERSISTENT);
1164 	REGISTER_LONG_CONSTANT("IMG_POWER", GD_POWER, CONST_CS | CONST_PERSISTENT);
1165 	REGISTER_LONG_CONSTANT("IMG_QUADRATIC", GD_QUADRATIC, CONST_CS | CONST_PERSISTENT);
1166 	REGISTER_LONG_CONSTANT("IMG_SINC", GD_SINC, CONST_CS | CONST_PERSISTENT);
1167 	REGISTER_LONG_CONSTANT("IMG_NEAREST_NEIGHBOUR", GD_NEAREST_NEIGHBOUR, CONST_CS | CONST_PERSISTENT);
1168 	REGISTER_LONG_CONSTANT("IMG_WEIGHTED4", GD_WEIGHTED4, CONST_CS | CONST_PERSISTENT);
1169 	REGISTER_LONG_CONSTANT("IMG_TRIANGLE", GD_TRIANGLE, CONST_CS | CONST_PERSISTENT);
1170 
1171 	REGISTER_LONG_CONSTANT("IMG_AFFINE_TRANSLATE", GD_AFFINE_TRANSLATE, CONST_CS | CONST_PERSISTENT);
1172 	REGISTER_LONG_CONSTANT("IMG_AFFINE_SCALE", GD_AFFINE_SCALE, CONST_CS | CONST_PERSISTENT);
1173 	REGISTER_LONG_CONSTANT("IMG_AFFINE_ROTATE", GD_AFFINE_ROTATE, CONST_CS | CONST_PERSISTENT);
1174 	REGISTER_LONG_CONSTANT("IMG_AFFINE_SHEAR_HORIZONTAL", GD_AFFINE_SHEAR_HORIZONTAL, CONST_CS | CONST_PERSISTENT);
1175 	REGISTER_LONG_CONSTANT("IMG_AFFINE_SHEAR_VERTICAL", GD_AFFINE_SHEAR_VERTICAL, CONST_CS | CONST_PERSISTENT);
1176 
1177 #if defined(HAVE_GD_BUNDLED)
1178 	REGISTER_LONG_CONSTANT("GD_BUNDLED", 1, CONST_CS | CONST_PERSISTENT);
1179 #else
1180 	REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT);
1181 #endif
1182 
1183 	/* Section Filters */
1184 	REGISTER_LONG_CONSTANT("IMG_FILTER_NEGATE", IMAGE_FILTER_NEGATE, CONST_CS | CONST_PERSISTENT);
1185 	REGISTER_LONG_CONSTANT("IMG_FILTER_GRAYSCALE", IMAGE_FILTER_GRAYSCALE, CONST_CS | CONST_PERSISTENT);
1186 	REGISTER_LONG_CONSTANT("IMG_FILTER_BRIGHTNESS", IMAGE_FILTER_BRIGHTNESS, CONST_CS | CONST_PERSISTENT);
1187 	REGISTER_LONG_CONSTANT("IMG_FILTER_CONTRAST", IMAGE_FILTER_CONTRAST, CONST_CS | CONST_PERSISTENT);
1188 	REGISTER_LONG_CONSTANT("IMG_FILTER_COLORIZE", IMAGE_FILTER_COLORIZE, CONST_CS | CONST_PERSISTENT);
1189 	REGISTER_LONG_CONSTANT("IMG_FILTER_EDGEDETECT", IMAGE_FILTER_EDGEDETECT, CONST_CS | CONST_PERSISTENT);
1190 	REGISTER_LONG_CONSTANT("IMG_FILTER_GAUSSIAN_BLUR", IMAGE_FILTER_GAUSSIAN_BLUR, CONST_CS | CONST_PERSISTENT);
1191 	REGISTER_LONG_CONSTANT("IMG_FILTER_SELECTIVE_BLUR", IMAGE_FILTER_SELECTIVE_BLUR, CONST_CS | CONST_PERSISTENT);
1192 	REGISTER_LONG_CONSTANT("IMG_FILTER_EMBOSS", IMAGE_FILTER_EMBOSS, CONST_CS | CONST_PERSISTENT);
1193 	REGISTER_LONG_CONSTANT("IMG_FILTER_MEAN_REMOVAL", IMAGE_FILTER_MEAN_REMOVAL, CONST_CS | CONST_PERSISTENT);
1194 	REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_CS | CONST_PERSISTENT);
1195 	REGISTER_LONG_CONSTANT("IMG_FILTER_PIXELATE", IMAGE_FILTER_PIXELATE, CONST_CS | CONST_PERSISTENT);
1196 	REGISTER_LONG_CONSTANT("IMG_FILTER_SCATTER", IMAGE_FILTER_SCATTER, CONST_CS | CONST_PERSISTENT);
1197 	/* End Section Filters */
1198 
1199 #ifdef GD_VERSION_STRING
1200 	REGISTER_STRING_CONSTANT("GD_VERSION", GD_VERSION_STRING, CONST_CS | CONST_PERSISTENT);
1201 #endif
1202 
1203 #if defined(GD_MAJOR_VERSION) && defined(GD_MINOR_VERSION) && defined(GD_RELEASE_VERSION) && defined(GD_EXTRA_VERSION)
1204 	REGISTER_LONG_CONSTANT("GD_MAJOR_VERSION", GD_MAJOR_VERSION, CONST_CS | CONST_PERSISTENT);
1205 	REGISTER_LONG_CONSTANT("GD_MINOR_VERSION", GD_MINOR_VERSION, CONST_CS | CONST_PERSISTENT);
1206 	REGISTER_LONG_CONSTANT("GD_RELEASE_VERSION", GD_RELEASE_VERSION, CONST_CS | CONST_PERSISTENT);
1207 	REGISTER_STRING_CONSTANT("GD_EXTRA_VERSION", GD_EXTRA_VERSION, CONST_CS | CONST_PERSISTENT);
1208 #endif
1209 
1210 
1211 #ifdef HAVE_GD_PNG
1212 
1213 	/*
1214 	 * cannot include #include "png.h"
1215 	 * /usr/include/pngconf.h:310:2: error: #error png.h already includes setjmp.h with some additional fixup.
1216 	 * as error, use the values for now...
1217 	 */
1218 	REGISTER_LONG_CONSTANT("PNG_NO_FILTER",	    0x00, CONST_CS | CONST_PERSISTENT);
1219 	REGISTER_LONG_CONSTANT("PNG_FILTER_NONE",   0x08, CONST_CS | CONST_PERSISTENT);
1220 	REGISTER_LONG_CONSTANT("PNG_FILTER_SUB",    0x10, CONST_CS | CONST_PERSISTENT);
1221 	REGISTER_LONG_CONSTANT("PNG_FILTER_UP",     0x20, CONST_CS | CONST_PERSISTENT);
1222 	REGISTER_LONG_CONSTANT("PNG_FILTER_AVG",    0x40, CONST_CS | CONST_PERSISTENT);
1223 	REGISTER_LONG_CONSTANT("PNG_FILTER_PAETH",  0x80, CONST_CS | CONST_PERSISTENT);
1224 	REGISTER_LONG_CONSTANT("PNG_ALL_FILTERS",   0x08 | 0x10 | 0x20 | 0x40 | 0x80, CONST_CS | CONST_PERSISTENT);
1225 #endif
1226 
1227 	return SUCCESS;
1228 }
1229 /* }}} */
1230 
1231 /* {{{ PHP_MSHUTDOWN_FUNCTION
1232  */
PHP_MSHUTDOWN_FUNCTIONnull1233 PHP_MSHUTDOWN_FUNCTION(gd)
1234 {
1235 #if defined(HAVE_GD_FREETYPE) && defined(HAVE_GD_BUNDLED)
1236 	gdFontCacheMutexShutdown();
1237 #endif
1238 	UNREGISTER_INI_ENTRIES();
1239 	return SUCCESS;
1240 }
1241 /* }}} */
1242 
1243 /* {{{ PHP_RSHUTDOWN_FUNCTION
1244  */
PHP_RSHUTDOWN_FUNCTIONnull1245 PHP_RSHUTDOWN_FUNCTION(gd)
1246 {
1247 #ifdef HAVE_GD_FREETYPE
1248 	gdFontCacheShutdown();
1249 #endif
1250 	return SUCCESS;
1251 }
1252 /* }}} */
1253 
1254 #if defined(HAVE_GD_BUNDLED)
1255 #define PHP_GD_VERSION_STRING "bundled (2.1.0 compatible)"
1256 #else
1257 # define PHP_GD_VERSION_STRING GD_VERSION_STRING
1258 #endif
1259 
1260 /* {{{ PHP_MINFO_FUNCTION
1261  */
PHP_MINFO_FUNCTIONnull1262 PHP_MINFO_FUNCTION(gd)
1263 {
1264 	php_info_print_table_start();
1265 	php_info_print_table_row(2, "GD Support", "enabled");
1266 
1267 	/* need to use a PHPAPI function here because it is external module in windows */
1268 
1269 #if defined(HAVE_GD_BUNDLED)
1270 	php_info_print_table_row(2, "GD Version", PHP_GD_VERSION_STRING);
1271 #else
1272 	php_info_print_table_row(2, "GD headers Version", PHP_GD_VERSION_STRING);
1273 #if defined(HAVE_GD_LIBVERSION)
1274 	php_info_print_table_row(2, "GD library Version", gdVersionString());
1275 #endif
1276 #endif
1277 
1278 #ifdef HAVE_GD_FREETYPE
1279 	php_info_print_table_row(2, "FreeType Support", "enabled");
1280 	php_info_print_table_row(2, "FreeType Linkage", "with freetype");
1281 #ifdef HAVE_GD_BUNDLED
1282 	{
1283 		char tmp[256];
1284 
1285 #ifdef FREETYPE_PATCH
1286 		snprintf(tmp, sizeof(tmp), "%d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
1287 #elif defined(FREETYPE_MAJOR)
1288 		snprintf(tmp, sizeof(tmp), "%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR);
1289 #else
1290 		snprintf(tmp, sizeof(tmp), "1.x");
1291 #endif
1292 		php_info_print_table_row(2, "FreeType Version", tmp);
1293 	}
1294 #endif
1295 #endif
1296 
1297 	php_info_print_table_row(2, "GIF Read Support", "enabled");
1298 	php_info_print_table_row(2, "GIF Create Support", "enabled");
1299 
1300 #ifdef HAVE_GD_JPG
1301 	{
1302 		php_info_print_table_row(2, "JPEG Support", "enabled");
1303 #if defined(HAVE_GD_BUNDLED)
1304 		php_info_print_table_row(2, "libJPEG Version", gdJpegGetVersionString());
1305 #endif
1306 	}
1307 #endif
1308 
1309 #ifdef HAVE_GD_PNG
1310 	php_info_print_table_row(2, "PNG Support", "enabled");
1311 #if defined(HAVE_GD_BUNDLED)
1312 	php_info_print_table_row(2, "libPNG Version", gdPngGetVersionString());
1313 #endif
1314 #endif
1315 	php_info_print_table_row(2, "WBMP Support", "enabled");
1316 #if defined(HAVE_GD_XPM)
1317 	php_info_print_table_row(2, "XPM Support", "enabled");
1318 #if defined(HAVE_GD_BUNDLED)
1319 	{
1320 		char tmp[12];
1321 		snprintf(tmp, sizeof(tmp), "%d", XpmLibraryVersion());
1322 		php_info_print_table_row(2, "libXpm Version", tmp);
1323 	}
1324 #endif
1325 #endif
1326 	php_info_print_table_row(2, "XBM Support", "enabled");
1327 #if defined(USE_GD_JISX0208)
1328 	php_info_print_table_row(2, "JIS-mapped Japanese Font Support", "enabled");
1329 #endif
1330 #ifdef HAVE_GD_WEBP
1331 	php_info_print_table_row(2, "WebP Support", "enabled");
1332 #endif
1333 #ifdef HAVE_GD_BMP
1334 	php_info_print_table_row(2, "BMP Support", "enabled");
1335 #endif
1336 #ifdef HAVE_GD_TGA
1337 	php_info_print_table_row(2, "TGA Read Support", "enabled");
1338 #endif
1339 	php_info_print_table_end();
1340 	DISPLAY_INI_ENTRIES();
1341 }
1342 /* }}} */
1343 
1344 /* {{{ proto array gd_info()
1345  */
PHP_FUNCTIONnull1346 PHP_FUNCTION(gd_info)
1347 {
1348 	if (zend_parse_parameters_none() == FAILURE) {
1349 		return;
1350 	}
1351 
1352 	array_init(return_value);
1353 
1354 	add_assoc_string(return_value, "GD Version", PHP_GD_VERSION_STRING);
1355 
1356 #ifdef HAVE_GD_FREETYPE
1357 	add_assoc_bool(return_value, "FreeType Support", 1);
1358 	add_assoc_string(return_value, "FreeType Linkage", "with freetype");
1359 #else
1360 	add_assoc_bool(return_value, "FreeType Support", 0);
1361 #endif
1362 	add_assoc_bool(return_value, "GIF Read Support", 1);
1363 	add_assoc_bool(return_value, "GIF Create Support", 1);
1364 #ifdef HAVE_GD_JPG
1365 	add_assoc_bool(return_value, "JPEG Support", 1);
1366 #else
1367 	add_assoc_bool(return_value, "JPEG Support", 0);
1368 #endif
1369 #ifdef HAVE_GD_PNG
1370 	add_assoc_bool(return_value, "PNG Support", 1);
1371 #else
1372 	add_assoc_bool(return_value, "PNG Support", 0);
1373 #endif
1374 	add_assoc_bool(return_value, "WBMP Support", 1);
1375 #if defined(HAVE_GD_XPM)
1376 	add_assoc_bool(return_value, "XPM Support", 1);
1377 #else
1378 	add_assoc_bool(return_value, "XPM Support", 0);
1379 #endif
1380 	add_assoc_bool(return_value, "XBM Support", 1);
1381 #ifdef HAVE_GD_WEBP
1382 	add_assoc_bool(return_value, "WebP Support", 1);
1383 #else
1384 	add_assoc_bool(return_value, "WebP Support", 0);
1385 #endif
1386 #ifdef HAVE_GD_BMP
1387 	add_assoc_bool(return_value, "BMP Support", 1);
1388 #else
1389 	add_assoc_bool(return_value, "BMP Support", 0);
1390 #endif
1391 #ifdef HAVE_GD_TGA
1392 	add_assoc_bool(return_value, "TGA Read Support", 1);
1393 #else
1394 	add_assoc_bool(return_value, "TGA Read Support", 0);
1395 #endif
1396 #if defined(USE_GD_JISX0208)
1397 	add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 1);
1398 #else
1399 	add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 0);
1400 #endif
1401 }
1402 /* }}} */
1403 
1404 /* Need this for cpdf. See also comment in file.c php3i_get_le_fp() */
phpi_get_le_gd(void)1405 PHP_GD_API int phpi_get_le_gd(void)
1406 {
1407 	return le_gd;
1408 }
1409 /* }}} */
1410 
1411 #define FLIPWORD(a) (((a & 0xff000000) >> 24) | ((a & 0x00ff0000) >> 8) | ((a & 0x0000ff00) << 8) | ((a & 0x000000ff) << 24))
1412 
1413 /* {{{ proto int imageloadfont(string filename)
1414    Load a new font */
PHP_FUNCTIONnull1415 PHP_FUNCTION(imageloadfont)
1416 {
1417 	zval *ind;
1418 	zend_string *file;
1419 	int hdr_size = sizeof(gdFont) - sizeof(char *);
1420 	int body_size, n = 0, b, i, body_size_check;
1421 	gdFontPtr font;
1422 	php_stream *stream;
1423 
1424 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file) == FAILURE) {
1425 		return;
1426 	}
1427 
1428 	stream = php_stream_open_wrapper(ZSTR_VAL(file), "rb", IGNORE_PATH | IGNORE_URL_WIN | REPORT_ERRORS, NULL);
1429 	if (stream == NULL) {
1430 		RETURN_FALSE;
1431 	}
1432 
1433 	/* Only supports a architecture-dependent binary dump format
1434 	 * at the moment.
1435 	 * The file format is like this on machines with 32-byte integers:
1436 	 *
1437 	 * byte 0-3:   (int) number of characters in the font
1438 	 * byte 4-7:   (int) value of first character in the font (often 32, space)
1439 	 * byte 8-11:  (int) pixel width of each character
1440 	 * byte 12-15: (int) pixel height of each character
1441 	 * bytes 16-:  (char) array with character data, one byte per pixel
1442 	 *                    in each character, for a total of
1443 	 *                    (nchars*width*height) bytes.
1444 	 */
1445 	font = (gdFontPtr) emalloc(sizeof(gdFont));
1446 	b = 0;
1447 	while (b < hdr_size && (n = php_stream_read(stream, (char*)&font[b], hdr_size - b)) > 0) {
1448 		b += n;
1449 	}
1450 
1451 	if (n <= 0) {
1452 		efree(font);
1453 		if (php_stream_eof(stream)) {
1454 			php_error_docref(NULL, E_WARNING, "End of file while reading header");
1455 		} else {
1456 			php_error_docref(NULL, E_WARNING, "Error while reading header");
1457 		}
1458 		php_stream_close(stream);
1459 		RETURN_FALSE;
1460 	}
1461 	i = php_stream_tell(stream);
1462 	php_stream_seek(stream, 0, SEEK_END);
1463 	body_size_check = php_stream_tell(stream) - hdr_size;
1464 	php_stream_seek(stream, i, SEEK_SET);
1465 
1466 	if (overflow2(font->nchars, font->h) || overflow2(font->nchars * font->h, font->w )) {
1467 		php_error_docref(NULL, E_WARNING, "Error reading font, invalid font header");
1468 		efree(font);
1469 		php_stream_close(stream);
1470 		RETURN_FALSE;
1471 	}
1472 
1473 	body_size = font->w * font->h * font->nchars;
1474 	if (body_size != body_size_check) {
1475 		font->w = FLIPWORD(font->w);
1476 		font->h = FLIPWORD(font->h);
1477 		font->nchars = FLIPWORD(font->nchars);
1478 		body_size = font->w * font->h * font->nchars;
1479 	}
1480 
1481 	if (body_size != body_size_check) {
1482 		php_error_docref(NULL, E_WARNING, "Error reading font");
1483 		efree(font);
1484 		php_stream_close(stream);
1485 		RETURN_FALSE;
1486 	}
1487 
1488 	font->data = emalloc(body_size);
1489 	b = 0;
1490 	while (b < body_size && (n = php_stream_read(stream, &font->data[b], body_size - b)) > 0) {
1491 		b += n;
1492 	}
1493 
1494 	if (n <= 0) {
1495 		efree(font->data);
1496 		efree(font);
1497 		if (php_stream_eof(stream)) {
1498 			php_error_docref(NULL, E_WARNING, "End of file while reading body");
1499 		} else {
1500 			php_error_docref(NULL, E_WARNING, "Error while reading body");
1501 		}
1502 		php_stream_close(stream);
1503 		RETURN_FALSE;
1504 	}
1505 	php_stream_close(stream);
1506 
1507 	ind = zend_list_insert(font, le_gd_font);
1508 
1509 	/* Adding 5 to the font index so we will never have font indices
1510 	 * that overlap with the old fonts (with indices 1-5).  The first
1511 	 * list index given out is always 1.
1512 	 */
1513 	RETURN_LONG(Z_RES_HANDLE_P(ind) + 5);
1514 }
1515 /* }}} */
1516 
1517 /* {{{ proto bool imagesetstyle(resource im, array styles)
1518    Set the line drawing styles for use with imageline and IMG_COLOR_STYLED. */
PHP_FUNCTIONnull1519 PHP_FUNCTION(imagesetstyle)
1520 {
1521 	zval *IM, *styles, *item;
1522 	gdImagePtr im;
1523 	int *stylearr;
1524 	int index = 0;
1525     uint32_t num_styles;
1526 
1527 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra", &IM, &styles) == FAILURE)  {
1528 		return;
1529 	}
1530 
1531 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1532 		RETURN_FALSE;
1533 	}
1534 
1535     num_styles = zend_hash_num_elements(Z_ARRVAL_P(styles));
1536     if (num_styles == 0) {
1537         php_error_docref(NULL, E_WARNING, "styles array must not be empty");
1538         RETURN_FALSE;
1539     }
1540 
1541 	/* copy the style values in the stylearr */
1542 	stylearr = safe_emalloc(sizeof(int), num_styles, 0);
1543 
1544 	ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(styles), item) {
1545 		stylearr[index++] = zval_get_long(item);
1546 	} ZEND_HASH_FOREACH_END();
1547 
1548 	gdImageSetStyle(im, stylearr, index);
1549 
1550 	efree(stylearr);
1551 
1552 	RETURN_TRUE;
1553 }
1554 /* }}} */
1555 
1556 /* {{{ proto resource imagecreatetruecolor(int x_size, int y_size)
1557    Create a new true color image */
PHP_FUNCTIONnull1558 PHP_FUNCTION(imagecreatetruecolor)
1559 {
1560 	zend_long x_size, y_size;
1561 	gdImagePtr im;
1562 
1563 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &x_size, &y_size) == FAILURE) {
1564 		return;
1565 	}
1566 
1567 	if (x_size <= 0 || y_size <= 0 || x_size >= INT_MAX || y_size >= INT_MAX) {
1568 		php_error_docref(NULL, E_WARNING, "Invalid image dimensions");
1569 		RETURN_FALSE;
1570 	}
1571 
1572 	im = gdImageCreateTrueColor(x_size, y_size);
1573 
1574 	if (!im) {
1575 		RETURN_FALSE;
1576 	}
1577 
1578 	RETURN_RES(zend_register_resource(im, le_gd));
1579 }
1580 /* }}} */
1581 
1582 /* {{{ proto bool imageistruecolor(resource im)
1583    return true if the image uses truecolor */
PHP_FUNCTIONnull1584 PHP_FUNCTION(imageistruecolor)
1585 {
1586 	zval *IM;
1587 	gdImagePtr im;
1588 
1589 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) {
1590 		return;
1591 	}
1592 
1593 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1594 		RETURN_FALSE;
1595 	}
1596 
1597 	RETURN_BOOL(im->trueColor);
1598 }
1599 /* }}} */
1600 
1601 /* {{{ proto void imagetruecolortopalette(resource im, bool ditherFlag, int colorsWanted)
1602    Convert a true color image to a palette based image with a number of colors, optionally using dithering. */
PHP_FUNCTIONnull1603 PHP_FUNCTION(imagetruecolortopalette)
1604 {
1605 	zval *IM;
1606 	zend_bool dither;
1607 	zend_long ncolors;
1608 	gdImagePtr im;
1609 
1610 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rbl", &IM, &dither, &ncolors) == FAILURE)  {
1611 		return;
1612 	}
1613 
1614 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1615 		RETURN_FALSE;
1616 	}
1617 
1618 	if (ncolors <= 0 || ZEND_LONG_INT_OVFL(ncolors)) {
1619 		php_error_docref(NULL, E_WARNING, "Number of colors has to be greater than zero and no more than %d", INT_MAX);
1620 		RETURN_FALSE;
1621 	}
1622 	if (gdImageTrueColorToPalette(im, dither, (int)ncolors)) {
1623 		RETURN_TRUE;
1624 	} else {
1625 		php_error_docref(NULL, E_WARNING, "Couldn't convert to palette");
1626 		RETURN_FALSE;
1627 	}
1628 }
1629 /* }}} */
1630 
1631 /* {{{ proto void imagepalettetotruecolor(resource im)
1632    Convert a palette based image to a true color image. */
PHP_FUNCTIONnull1633 PHP_FUNCTION(imagepalettetotruecolor)
1634 {
1635 	zval *IM;
1636 	gdImagePtr im;
1637 
1638 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE)  {
1639 		return;
1640 	}
1641 
1642 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1643 		RETURN_FALSE;
1644 	}
1645 
1646 	if (gdImagePaletteToTrueColor(im) == 0) {
1647 		RETURN_FALSE;
1648 	}
1649 
1650 	RETURN_TRUE;
1651 }
1652 /* }}} */
1653 
1654 /* {{{ proto bool imagecolormatch(resource im1, resource im2)
1655    Makes the colors of the palette version of an image more closely match the true color version */
PHP_FUNCTIONnull1656 PHP_FUNCTION(imagecolormatch)
1657 {
1658 	zval *IM1, *IM2;
1659 	gdImagePtr im1, im2;
1660 	int result;
1661 
1662 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &IM1, &IM2) == FAILURE) {
1663 		return;
1664 	}
1665 
1666 	if ((im1 = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM1), "Image", le_gd)) == NULL) {
1667 		RETURN_FALSE;
1668 	}
1669 	if ((im2 = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM2), "Image", le_gd)) == NULL) {
1670 		RETURN_FALSE;
1671 	}
1672 
1673 	result = gdImageColorMatch(im1, im2);
1674 	switch (result) {
1675 		case -1:
1676 			php_error_docref(NULL, E_WARNING, "Image1 must be TrueColor" );
1677 			RETURN_FALSE;
1678 			break;
1679 		case -2:
1680 			php_error_docref(NULL, E_WARNING, "Image2 must be Palette" );
1681 			RETURN_FALSE;
1682 			break;
1683 		case -3:
1684 			php_error_docref(NULL, E_WARNING, "Image1 and Image2 must be the same size" );
1685 			RETURN_FALSE;
1686 			break;
1687 		case -4:
1688 			php_error_docref(NULL, E_WARNING, "Image2 must have at least one color" );
1689 			RETURN_FALSE;
1690 			break;
1691 	}
1692 
1693 	RETURN_TRUE;
1694 }
1695 /* }}} */
1696 
1697 /* {{{ proto bool imagesetthickness(resource im, int thickness)
1698    Set line thickness for drawing lines, ellipses, rectangles, polygons etc. */
PHP_FUNCTIONnull1699 PHP_FUNCTION(imagesetthickness)
1700 {
1701 	zval *IM;
1702 	zend_long thick;
1703 	gdImagePtr im;
1704 
1705 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &thick) == FAILURE) {
1706 		return;
1707 	}
1708 
1709 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1710 		RETURN_FALSE;
1711 	}
1712 
1713 	gdImageSetThickness(im, thick);
1714 
1715 	RETURN_TRUE;
1716 }
1717 /* }}} */
1718 
1719 /* {{{ proto bool imagefilledellipse(resource im, int cx, int cy, int w, int h, int color)
1720    Draw an ellipse */
PHP_FUNCTIONnull1721 PHP_FUNCTION(imagefilledellipse)
1722 {
1723 	zval *IM;
1724 	zend_long cx, cy, w, h, color;
1725 	gdImagePtr im;
1726 
1727 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &cx, &cy, &w, &h, &color) == FAILURE) {
1728 		return;
1729 	}
1730 
1731 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1732 		RETURN_FALSE;
1733 	}
1734 
1735 	gdImageFilledEllipse(im, cx, cy, w, h, color);
1736 
1737 	RETURN_TRUE;
1738 }
1739 /* }}} */
1740 
1741 /* {{{ proto bool imagefilledarc(resource im, int cx, int cy, int w, int h, int s, int e, int col, int style)
1742    Draw a filled partial ellipse */
PHP_FUNCTIONnull1743 PHP_FUNCTION(imagefilledarc)
1744 {
1745 	zval *IM;
1746 	zend_long cx, cy, w, h, ST, E, col, style;
1747 	gdImagePtr im;
1748 	int e, st;
1749 
1750 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllllllll", &IM, &cx, &cy, &w, &h, &ST, &E, &col, &style) == FAILURE) {
1751 		return;
1752 	}
1753 
1754 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1755 		RETURN_FALSE;
1756 	}
1757 
1758 	e = E;
1759 	if (e < 0) {
1760 		e %= 360;
1761 	}
1762 
1763 	st = ST;
1764 	if (st < 0) {
1765 		st %= 360;
1766 	}
1767 
1768 	gdImageFilledArc(im, cx, cy, w, h, st, e, col, style);
1769 
1770 	RETURN_TRUE;
1771 }
1772 /* }}} */
1773 
1774 /* {{{ proto bool imagealphablending(resource im, bool on)
1775    Turn alpha blending mode on or off for the given image */
PHP_FUNCTIONnull1776 PHP_FUNCTION(imagealphablending)
1777 {
1778 	zval *IM;
1779 	zend_bool blend;
1780 	gdImagePtr im;
1781 
1782 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rb", &IM, &blend) == FAILURE) {
1783 		return;
1784 	}
1785 
1786 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1787 		RETURN_FALSE;
1788 	}
1789 
1790 	gdImageAlphaBlending(im, blend);
1791 
1792 	RETURN_TRUE;
1793 }
1794 /* }}} */
1795 
1796 /* {{{ proto bool imagesavealpha(resource im, bool on)
1797    Include alpha channel to a saved image */
PHP_FUNCTIONnull1798 PHP_FUNCTION(imagesavealpha)
1799 {
1800 	zval *IM;
1801 	zend_bool save;
1802 	gdImagePtr im;
1803 
1804 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rb", &IM, &save) == FAILURE) {
1805 		return;
1806 	}
1807 
1808 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1809 		RETURN_FALSE;
1810 	}
1811 
1812 	gdImageSaveAlpha(im, save);
1813 
1814 	RETURN_TRUE;
1815 }
1816 /* }}} */
1817 
1818 /* {{{ proto bool imagelayereffect(resource im, int effect)
1819    Set the alpha blending flag to use the bundled libgd layering effects */
PHP_FUNCTIONnull1820 PHP_FUNCTION(imagelayereffect)
1821 {
1822 	zval *IM;
1823 	zend_long effect;
1824 	gdImagePtr im;
1825 
1826 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &effect) == FAILURE) {
1827 		return;
1828 	}
1829 
1830 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1831 		RETURN_FALSE;
1832 	}
1833 
1834 	gdImageAlphaBlending(im, effect);
1835 
1836 	RETURN_TRUE;
1837 }
1838 /* }}} */
1839 
1840 #define CHECK_RGBA_RANGE(component, name) \
1841 	if (component < 0 || component > gd##name##Max) { \
1842 		php_error_docref(NULL, E_WARNING, #name " component is out of range"); \
1843 		RETURN_FALSE; \
1844 	}
1845 
1846 /* {{{ proto int imagecolorallocatealpha(resource im, int red, int green, int blue, int alpha)
1847    Allocate a color with an alpha level.  Works for true color and palette based images */
PHP_FUNCTIONnull1848 PHP_FUNCTION(imagecolorallocatealpha)
1849 {
1850 	zval *IM;
1851 	zend_long red, green, blue, alpha;
1852 	gdImagePtr im;
1853 	int ct = (-1);
1854 
1855 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
1856 		RETURN_FALSE;
1857 	}
1858 
1859 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1860 		RETURN_FALSE;
1861 	}
1862 
1863 	CHECK_RGBA_RANGE(red, Red);
1864 	CHECK_RGBA_RANGE(green, Green);
1865 	CHECK_RGBA_RANGE(blue, Blue);
1866 	CHECK_RGBA_RANGE(alpha, Alpha);
1867 
1868 	ct = gdImageColorAllocateAlpha(im, red, green, blue, alpha);
1869 	if (ct < 0) {
1870 		RETURN_FALSE;
1871 	}
1872 	RETURN_LONG((zend_long)ct);
1873 }
1874 /* }}} */
1875 
1876 /* {{{ proto int imagecolorresolvealpha(resource im, int red, int green, int blue, int alpha)
1877    Resolve/Allocate a colour with an alpha level.  Works for true colour and palette based images */
PHP_FUNCTIONnull1878 PHP_FUNCTION(imagecolorresolvealpha)
1879 {
1880 	zval *IM;
1881 	zend_long red, green, blue, alpha;
1882 	gdImagePtr im;
1883 
1884 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
1885 		return;
1886 	}
1887 
1888 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1889 		RETURN_FALSE;
1890 	}
1891 
1892 	CHECK_RGBA_RANGE(red, Red);
1893 	CHECK_RGBA_RANGE(green, Green);
1894 	CHECK_RGBA_RANGE(blue, Blue);
1895 	CHECK_RGBA_RANGE(alpha, Alpha);
1896 
1897 	RETURN_LONG(gdImageColorResolveAlpha(im, red, green, blue, alpha));
1898 }
1899 /* }}} */
1900 
1901 /* {{{ proto int imagecolorclosestalpha(resource im, int red, int green, int blue, int alpha)
1902    Find the closest matching colour with alpha transparency */
PHP_FUNCTIONnull1903 PHP_FUNCTION(imagecolorclosestalpha)
1904 {
1905 	zval *IM;
1906 	zend_long red, green, blue, alpha;
1907 	gdImagePtr im;
1908 
1909 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
1910 		return;
1911 	}
1912 
1913 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1914 		RETURN_FALSE;
1915 	}
1916 
1917 	CHECK_RGBA_RANGE(red, Red);
1918 	CHECK_RGBA_RANGE(green, Green);
1919 	CHECK_RGBA_RANGE(blue, Blue);
1920 	CHECK_RGBA_RANGE(alpha, Alpha);
1921 
1922 	RETURN_LONG(gdImageColorClosestAlpha(im, red, green, blue, alpha));
1923 }
1924 /* }}} */
1925 
1926 /* {{{ proto int imagecolorexactalpha(resource im, int red, int green, int blue, int alpha)
1927    Find exact match for colour with transparency */
PHP_FUNCTIONnull1928 PHP_FUNCTION(imagecolorexactalpha)
1929 {
1930 	zval *IM;
1931 	zend_long red, green, blue, alpha;
1932 	gdImagePtr im;
1933 
1934 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
1935 		return;
1936 	}
1937 
1938 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1939 		RETURN_FALSE;
1940 	}
1941 
1942 	CHECK_RGBA_RANGE(red, Red);
1943 	CHECK_RGBA_RANGE(green, Green);
1944 	CHECK_RGBA_RANGE(blue, Blue);
1945 	CHECK_RGBA_RANGE(alpha, Alpha);
1946 
1947 	RETURN_LONG(gdImageColorExactAlpha(im, red, green, blue, alpha));
1948 }
1949 /* }}} */
1950 
1951 /* {{{ proto bool imagecopyresampled(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h)
1952    Copy and resize part of an image using resampling to help ensure clarity */
PHP_FUNCTIONnull1953 PHP_FUNCTION(imagecopyresampled)
1954 {
1955 	zval *SIM, *DIM;
1956 	zend_long SX, SY, SW, SH, DX, DY, DW, DH;
1957 	gdImagePtr im_dst, im_src;
1958 	int srcH, srcW, dstH, dstW, srcY, srcX, dstY, dstX;
1959 
1960 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrllllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &DW, &DH, &SW, &SH) == FAILURE) {
1961 		return;
1962 	}
1963 
1964 	if ((im_dst = (gdImagePtr)zend_fetch_resource(Z_RES_P(DIM), "Image", le_gd)) == NULL) {
1965 		RETURN_FALSE;
1966 	}
1967 
1968 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
1969 		RETURN_FALSE;
1970 	}
1971 
1972 	srcX = SX;
1973 	srcY = SY;
1974 	srcH = SH;
1975 	srcW = SW;
1976 	dstX = DX;
1977 	dstY = DY;
1978 	dstH = DH;
1979 	dstW = DW;
1980 
1981 	gdImageCopyResampled(im_dst, im_src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
1982 
1983 	RETURN_TRUE;
1984 }
1985 /* }}} */
1986 
1987 #ifdef PHP_WIN32
1988 /* {{{ proto resource imagegrabwindow(int window_handle [, int client_area])
1989    Grab a window or its client area using a windows handle (HWND property in COM instance) */
PHP_FUNCTIONnull1990 PHP_FUNCTION(imagegrabwindow)
1991 {
1992 	HWND window;
1993 	zend_long client_area = 0;
1994 	RECT rc = {0};
1995 	int Width, Height;
1996 	HDC		hdc;
1997 	HDC memDC;
1998 	HBITMAP memBM;
1999 	HBITMAP hOld;
2000 	zend_long lwindow_handle;
2001 	gdImagePtr im = NULL;
2002 
2003 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &lwindow_handle, &client_area) == FAILURE) {
2004 		RETURN_FALSE;
2005 	}
2006 
2007 	window = (HWND) lwindow_handle;
2008 
2009 	if (!IsWindow(window)) {
2010 		php_error_docref(NULL, E_NOTICE, "Invalid window handle");
2011 		RETURN_FALSE;
2012 	}
2013 
2014 	hdc		= GetDC(0);
2015 
2016 	if (client_area) {
2017 		GetClientRect(window, &rc);
2018 		Width = rc.right;
2019 		Height = rc.bottom;
2020 	} else {
2021 		GetWindowRect(window, &rc);
2022 		Width	= rc.right - rc.left;
2023 		Height	= rc.bottom - rc.top;
2024 	}
2025 
2026 	Width		= (Width/4)*4;
2027 
2028 	memDC	= CreateCompatibleDC(hdc);
2029 	memBM	= CreateCompatibleBitmap(hdc, Width, Height);
2030 	hOld	= (HBITMAP) SelectObject (memDC, memBM);
2031 
2032 	PrintWindow(window, memDC, (UINT) client_area);
2033 
2034 	im = gdImageCreateTrueColor(Width, Height);
2035 	if (im) {
2036 		int x,y;
2037 		for (y=0; y <= Height; y++) {
2038 			for (x=0; x <= Width; x++) {
2039 				int c = GetPixel(memDC, x,y);
2040 				gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
2041 			}
2042 		}
2043 	}
2044 
2045 	SelectObject(memDC,hOld);
2046 	DeleteObject(memBM);
2047 	DeleteDC(memDC);
2048 	ReleaseDC( 0, hdc );
2049 
2050 	if (!im) {
2051 		RETURN_FALSE;
2052 	} else {
2053 		RETURN_RES(zend_register_resource(im, le_gd));
2054 	}
2055 }
2056 /* }}} */
2057 
2058 /* {{{ proto resource imagegrabscreen()
2059    Grab a screenshot */
PHP_FUNCTIONnull2060 PHP_FUNCTION(imagegrabscreen)
2061 {
2062 	HWND window = GetDesktopWindow();
2063 	RECT rc = {0};
2064 	int Width, Height;
2065 	HDC		hdc;
2066 	HDC memDC;
2067 	HBITMAP memBM;
2068 	HBITMAP hOld;
2069 	gdImagePtr im;
2070 	hdc		= GetDC(0);
2071 
2072 	if (zend_parse_parameters_none() == FAILURE) {
2073 		return;
2074 	}
2075 
2076 	if (!hdc) {
2077 		RETURN_FALSE;
2078 	}
2079 
2080 	GetWindowRect(window, &rc);
2081 	Width	= rc.right - rc.left;
2082 	Height	= rc.bottom - rc.top;
2083 
2084 	Width		= (Width/4)*4;
2085 
2086 	memDC	= CreateCompatibleDC(hdc);
2087 	memBM	= CreateCompatibleBitmap(hdc, Width, Height);
2088 	hOld	= (HBITMAP) SelectObject (memDC, memBM);
2089 	BitBlt( memDC, 0, 0, Width, Height , hdc, rc.left, rc.top , SRCCOPY );
2090 
2091 	im = gdImageCreateTrueColor(Width, Height);
2092 	if (im) {
2093 		int x,y;
2094 		for (y=0; y <= Height; y++) {
2095 			for (x=0; x <= Width; x++) {
2096 				int c = GetPixel(memDC, x,y);
2097 				gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
2098 			}
2099 		}
2100 	}
2101 
2102 	SelectObject(memDC,hOld);
2103 	DeleteObject(memBM);
2104 	DeleteDC(memDC);
2105 	ReleaseDC( 0, hdc );
2106 
2107 	if (!im) {
2108 		RETURN_FALSE;
2109 	} else {
2110 		RETURN_RES(zend_register_resource(im, le_gd));
2111 	}
2112 }
2113 /* }}} */
2114 #endif /* PHP_WIN32 */
2115 
2116 /* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor [, int ignoretransparent])
2117    Rotate an image using a custom angle */
PHP_FUNCTIONnull2118 PHP_FUNCTION(imagerotate)
2119 {
2120 	zval *SIM;
2121 	gdImagePtr im_dst, im_src;
2122 	double degrees;
2123 	zend_long color;
2124 	zend_long ignoretransparent = 0;
2125 
2126 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rdl|l", &SIM, &degrees, &color, &ignoretransparent) == FAILURE) {
2127 		RETURN_FALSE;
2128 	}
2129 
2130 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
2131 		RETURN_FALSE;
2132 	}
2133 
2134 	im_dst = gdImageRotateInterpolated(im_src, (const float)degrees, color);
2135 
2136 	if (im_dst != NULL) {
2137 		RETURN_RES(zend_register_resource(im_dst, le_gd));
2138 	} else {
2139 		RETURN_FALSE;
2140 	}
2141 }
2142 /* }}} */
2143 
2144 /* {{{ proto bool imagesettile(resource image, resource tile)
2145    Set the tile image to $tile when filling $image with the "IMG_COLOR_TILED" color */
PHP_FUNCTIONnull2146 PHP_FUNCTION(imagesettile)
2147 {
2148 	zval *IM, *TILE;
2149 	gdImagePtr im, tile;
2150 
2151 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &IM, &TILE) == FAILURE) {
2152 		return;
2153 	}
2154 
2155 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2156 		RETURN_FALSE;
2157 	}
2158 
2159 	if ((tile = (gdImagePtr)zend_fetch_resource(Z_RES_P(TILE), "Image", le_gd)) == NULL) {
2160 		RETURN_FALSE;
2161 	}
2162 
2163 	gdImageSetTile(im, tile);
2164 
2165 	RETURN_TRUE;
2166 }
2167 /* }}} */
2168 
2169 /* {{{ proto bool imagesetbrush(resource image, resource brush)
2170    Set the brush image to $brush when filling $image with the "IMG_COLOR_BRUSHED" color */
PHP_FUNCTIONnull2171 PHP_FUNCTION(imagesetbrush)
2172 {
2173 	zval *IM, *TILE;
2174 	gdImagePtr im, tile;
2175 
2176 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &IM, &TILE) == FAILURE) {
2177 		return;
2178 	}
2179 
2180 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2181 		RETURN_FALSE;
2182 	}
2183 
2184 	if ((tile = (gdImagePtr)zend_fetch_resource(Z_RES_P(TILE), "Image", le_gd)) == NULL) {
2185 		RETURN_FALSE;
2186 	}
2187 
2188 	gdImageSetBrush(im, tile);
2189 
2190 	RETURN_TRUE;
2191 }
2192 /* }}} */
2193 
2194 /* {{{ proto resource imagecreate(int x_size, int y_size)
2195    Create a new image */
PHP_FUNCTIONnull2196 PHP_FUNCTION(imagecreate)
2197 {
2198 	zend_long x_size, y_size;
2199 	gdImagePtr im;
2200 
2201 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &x_size, &y_size) == FAILURE) {
2202 		return;
2203 	}
2204 
2205 	if (x_size <= 0 || y_size <= 0 || x_size >= INT_MAX || y_size >= INT_MAX) {
2206 		php_error_docref(NULL, E_WARNING, "Invalid image dimensions");
2207 		RETURN_FALSE;
2208 	}
2209 
2210 	im = gdImageCreate(x_size, y_size);
2211 
2212 	if (!im) {
2213 		RETURN_FALSE;
2214 	}
2215 
2216 	RETURN_RES(zend_register_resource(im, le_gd));
2217 }
2218 /* }}} */
2219 
2220 /* {{{ proto int imagetypes(void)
2221    Return the types of images supported in a bitfield - 1=GIF, 2=JPEG, 4=PNG, 8=WBMP, 16=XPM */
PHP_FUNCTIONnull2222 PHP_FUNCTION(imagetypes)
2223 {
2224 	int ret = 0;
2225 	ret = PHP_IMG_GIF;
2226 #ifdef HAVE_GD_JPG
2227 	ret |= PHP_IMG_JPG;
2228 #endif
2229 #ifdef HAVE_GD_PNG
2230 	ret |= PHP_IMG_PNG;
2231 #endif
2232 	ret |= PHP_IMG_WBMP;
2233 #if defined(HAVE_GD_XPM)
2234 	ret |= PHP_IMG_XPM;
2235 #endif
2236 #ifdef HAVE_GD_WEBP
2237 	ret |= PHP_IMG_WEBP;
2238 #endif
2239 #ifdef HAVE_GD_BMP
2240 	ret |= PHP_IMG_BMP;
2241 #endif
2242 #ifdef HAVE_GD_TGA
2243 	ret |= PHP_IMG_TGA;
2244 #endif
2245 
2246 	if (zend_parse_parameters_none() == FAILURE) {
2247 		return;
2248 	}
2249 
2250 	RETURN_LONG(ret);
2251 }
2252 /* }}} */
2253 
2254 /* {{{ _php_ctx_getmbi
2255  */
2256 
_php_ctx_getmbi(gdIOCtx *ctx)2257 static int _php_ctx_getmbi(gdIOCtx *ctx)
2258 {
2259 	int i, mbi = 0;
2260 
2261 	do {
2262 		i = (ctx->getC)(ctx);
2263 		if (i < 0) {
2264 			return -1;
2265 		}
2266 		mbi = (mbi << 7) | (i & 0x7f);
2267 	} while (i & 0x80);
2268 
2269 	return mbi;
2270 }
2271 /* }}} */
2272 
2273 /* {{{ _php_image_type
2274  */
2275 static const char php_sig_gd2[3] = {'g', 'd', '2'};
2276 
_php_image_type(char data[12])2277 static int _php_image_type (char data[12])
2278 {
2279 	/* Based on ext/standard/image.c */
2280 
2281 	if (data == NULL) {
2282 		return -1;
2283 	}
2284 
2285 	if (!memcmp(data, php_sig_gd2, sizeof(php_sig_gd2))) {
2286 		return PHP_GDIMG_TYPE_GD2;
2287 	} else if (!memcmp(data, php_sig_jpg, sizeof(php_sig_jpg))) {
2288 		return PHP_GDIMG_TYPE_JPG;
2289 	} else if (!memcmp(data, php_sig_png, sizeof(php_sig_png))) {
2290 		return PHP_GDIMG_TYPE_PNG;
2291 	} else if (!memcmp(data, php_sig_gif, sizeof(php_sig_gif))) {
2292 		return PHP_GDIMG_TYPE_GIF;
2293 	} else if (!memcmp(data, php_sig_bmp, sizeof(php_sig_bmp))) {
2294 		return PHP_GDIMG_TYPE_BMP;
2295 	} else if(!memcmp(data, php_sig_riff, sizeof(php_sig_riff)) && !memcmp(data + sizeof(php_sig_riff) + sizeof(uint32_t), php_sig_webp, sizeof(php_sig_webp))) {
2296 		return PHP_GDIMG_TYPE_WEBP;
2297 	}
2298 	else {
2299 		gdIOCtx *io_ctx;
2300 		io_ctx = gdNewDynamicCtxEx(8, data, 0);
2301 		if (io_ctx) {
2302 			if (_php_ctx_getmbi(io_ctx) == 0 && _php_ctx_getmbi(io_ctx) >= 0) {
2303 				io_ctx->gd_free(io_ctx);
2304 				return PHP_GDIMG_TYPE_WBM;
2305 			} else {
2306 				io_ctx->gd_free(io_ctx);
2307 			}
2308 		}
2309 	}
2310 	return -1;
2311 }
2312 /* }}} */
2313 
2314 /* {{{ _php_image_create_from_string
2315  */
_php_image_create_from_string(zval *data, char *tn, gdImagePtr (*ioctx_func_p)())2316 gdImagePtr _php_image_create_from_string(zval *data, char *tn, gdImagePtr (*ioctx_func_p)())
2317 {
2318 	gdImagePtr im;
2319 	gdIOCtx *io_ctx;
2320 
2321 	io_ctx = gdNewDynamicCtxEx(Z_STRLEN_P(data), Z_STRVAL_P(data), 0);
2322 
2323 	if (!io_ctx) {
2324 		return NULL;
2325 	}
2326 
2327 	im = (*ioctx_func_p)(io_ctx);
2328 	if (!im) {
2329 		php_error_docref(NULL, E_WARNING, "Passed data is not in '%s' format", tn);
2330 		io_ctx->gd_free(io_ctx);
2331 		return NULL;
2332 	}
2333 
2334 	io_ctx->gd_free(io_ctx);
2335 
2336 	return im;
2337 }
2338 /* }}} */
2339 
2340 /* {{{ proto resource imagecreatefromstring(string image)
2341    Create a new image from the image stream in the string */
PHP_FUNCTIONnull2342 PHP_FUNCTION(imagecreatefromstring)
2343 {
2344 	zval *data;
2345 	gdImagePtr im;
2346 	int imtype;
2347 	char sig[12];
2348 
2349 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &data) == FAILURE) {
2350 		return;
2351 	}
2352 
2353 	if (!try_convert_to_string(data)) {
2354 		return;
2355 	}
2356 
2357 	if (Z_STRLEN_P(data) < sizeof(sig)) {
2358 		php_error_docref(NULL, E_WARNING, "Empty string or invalid image");
2359 		RETURN_FALSE;
2360 	}
2361 
2362 	memcpy(sig, Z_STRVAL_P(data), sizeof(sig));
2363 
2364 	imtype = _php_image_type(sig);
2365 
2366 	switch (imtype) {
2367 		case PHP_GDIMG_TYPE_JPG:
2368 #ifdef HAVE_GD_JPG
2369 			im = _php_image_create_from_string(data, "JPEG", gdImageCreateFromJpegCtx);
2370 #else
2371 			php_error_docref(NULL, E_WARNING, "No JPEG support in this PHP build");
2372 			RETURN_FALSE;
2373 #endif
2374 			break;
2375 
2376 		case PHP_GDIMG_TYPE_PNG:
2377 #ifdef HAVE_GD_PNG
2378 			im = _php_image_create_from_string(data, "PNG", gdImageCreateFromPngCtx);
2379 #else
2380 			php_error_docref(NULL, E_WARNING, "No PNG support in this PHP build");
2381 			RETURN_FALSE;
2382 #endif
2383 			break;
2384 
2385 		case PHP_GDIMG_TYPE_GIF:
2386 			im = _php_image_create_from_string(data, "GIF", gdImageCreateFromGifCtx);
2387 			break;
2388 
2389 		case PHP_GDIMG_TYPE_WBM:
2390 			im = _php_image_create_from_string(data, "WBMP", gdImageCreateFromWBMPCtx);
2391 			break;
2392 
2393 		case PHP_GDIMG_TYPE_GD2:
2394 			im = _php_image_create_from_string(data, "GD2", gdImageCreateFromGd2Ctx);
2395 			break;
2396 
2397 		case PHP_GDIMG_TYPE_BMP:
2398 			im = _php_image_create_from_string(data, "BMP", gdImageCreateFromBmpCtx);
2399 			break;
2400 
2401 		case PHP_GDIMG_TYPE_WEBP:
2402 #ifdef HAVE_GD_WEBP
2403 			im = _php_image_create_from_string(data, "WEBP", gdImageCreateFromWebpCtx);
2404 			break;
2405 #else
2406 			php_error_docref(NULL, E_WARNING, "No WEBP support in this PHP build");
2407 			RETURN_FALSE;
2408 #endif
2409 
2410 		default:
2411 			php_error_docref(NULL, E_WARNING, "Data is not in a recognized format");
2412 			RETURN_FALSE;
2413 	}
2414 
2415 	if (!im) {
2416 		php_error_docref(NULL, E_WARNING, "Couldn't create GD Image Stream out of Data");
2417 		RETURN_FALSE;
2418 	}
2419 
2420 	RETURN_RES(zend_register_resource(im, le_gd));
2421 }
2422 /* }}} */
2423 
2424 /* {{{ _php_image_create_from
2425  */
_php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)())2426 static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)())
2427 {
2428 	char *file;
2429 	size_t file_len;
2430 	zend_long srcx, srcy, width, height;
2431 	gdImagePtr im = NULL;
2432 	php_stream *stream;
2433 	FILE * fp = NULL;
2434 #ifdef HAVE_GD_JPG
2435 	long ignore_warning;
2436 #endif
2437 
2438 	if (image_type == PHP_GDIMG_TYPE_GD2PART) {
2439 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "pllll", &file, &file_len, &srcx, &srcy, &width, &height) == FAILURE) {
2440 			return;
2441 		}
2442 		if (width < 1 || height < 1) {
2443 			php_error_docref(NULL, E_WARNING, "Zero width or height not allowed");
2444 			RETURN_FALSE;
2445 		}
2446 	} else {
2447 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &file, &file_len) == FAILURE) {
2448 			return;
2449 		}
2450 	}
2451 
2452 
2453 	stream = php_stream_open_wrapper(file, "rb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL);
2454 	if (stream == NULL)	{
2455 		RETURN_FALSE;
2456 	}
2457 
2458 	/* try and avoid allocating a FILE* if the stream is not naturally a FILE* */
2459 	if (php_stream_is(stream, PHP_STREAM_IS_STDIO))	{
2460 		if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) {
2461 			goto out_err;
2462 		}
2463 	} else if (ioctx_func_p) {
2464 		/* we can create an io context */
2465 		gdIOCtx* io_ctx;
2466 		zend_string *buff;
2467 		char *pstr;
2468 
2469 		buff = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
2470 
2471 		if (!buff) {
2472 			php_error_docref(NULL, E_WARNING,"Cannot read image data");
2473 			goto out_err;
2474 		}
2475 
2476 		/* needs to be malloc (persistent) - GD will free() it later */
2477 		pstr = pestrndup(ZSTR_VAL(buff), ZSTR_LEN(buff), 1);
2478 		io_ctx = gdNewDynamicCtxEx(ZSTR_LEN(buff), pstr, 0);
2479 		if (!io_ctx) {
2480 			pefree(pstr, 1);
2481 			zend_string_release_ex(buff, 0);
2482 			php_error_docref(NULL, E_WARNING,"Cannot allocate GD IO context");
2483 			goto out_err;
2484 		}
2485 
2486 		if (image_type == PHP_GDIMG_TYPE_GD2PART) {
2487 			im = (*ioctx_func_p)(io_ctx, srcx, srcy, width, height);
2488 		} else {
2489 			im = (*ioctx_func_p)(io_ctx);
2490 		}
2491 		io_ctx->gd_free(io_ctx);
2492 		pefree(pstr, 1);
2493 		zend_string_release_ex(buff, 0);
2494 	}
2495 	else if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO)) {
2496 		/* try and force the stream to be FILE* */
2497 		if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_TRY_HARD, (void **) &fp, REPORT_ERRORS)) {
2498 			goto out_err;
2499 		}
2500 	}
2501 
2502 	if (!im && fp) {
2503 		switch (image_type) {
2504 			case PHP_GDIMG_TYPE_GD2PART:
2505 				im = (*func_p)(fp, srcx, srcy, width, height);
2506 				break;
2507 #if defined(HAVE_GD_XPM)
2508 			case PHP_GDIMG_TYPE_XPM:
2509 				im = gdImageCreateFromXpm(file);
2510 				break;
2511 #endif
2512 
2513 #ifdef HAVE_GD_JPG
2514 			case PHP_GDIMG_TYPE_JPG:
2515 				ignore_warning = INI_INT("gd.jpeg_ignore_warning");
2516 				im = gdImageCreateFromJpegEx(fp, ignore_warning);
2517 			break;
2518 #endif
2519 
2520 			default:
2521 				im = (*func_p)(fp);
2522 				break;
2523 		}
2524 
2525 		fflush(fp);
2526 	}
2527 
2528 /* register_im: */
2529 	if (im) {
2530 		RETVAL_RES(zend_register_resource(im, le_gd));
2531 		php_stream_close(stream);
2532 		return;
2533 	}
2534 
2535 	php_error_docref(NULL, E_WARNING, "'%s' is not a valid %s file", file, tn);
2536 out_err:
2537 	php_stream_close(stream);
2538 	RETURN_FALSE;
2539 
2540 }
2541 /* }}} */
2542 
2543 /* {{{ proto resource imagecreatefromgif(string filename)
2544    Create a new image from GIF file or URL */
PHP_FUNCTIONnull2545 PHP_FUNCTION(imagecreatefromgif)
2546 {
2547 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageCreateFromGif, gdImageCreateFromGifCtx);
2548 }
2549 /* }}} */
2550 
2551 #ifdef HAVE_GD_JPG
2552 /* {{{ proto resource imagecreatefromjpeg(string filename)
2553    Create a new image from JPEG file or URL */
PHP_FUNCTIONnull2554 PHP_FUNCTION(imagecreatefromjpeg)
2555 {
2556 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageCreateFromJpeg, gdImageCreateFromJpegCtx);
2557 }
2558 /* }}} */
2559 #endif /* HAVE_GD_JPG */
2560 
2561 #ifdef HAVE_GD_PNG
2562 /* {{{ proto resource imagecreatefrompng(string filename)
2563    Create a new image from PNG file or URL */
PHP_FUNCTIONnull2564 PHP_FUNCTION(imagecreatefrompng)
2565 {
2566 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImageCreateFromPng, gdImageCreateFromPngCtx);
2567 }
2568 /* }}} */
2569 #endif /* HAVE_GD_PNG */
2570 
2571 #ifdef HAVE_GD_WEBP
2572 /* {{{ proto resource imagecreatefromwebp(string filename)
2573    Create a new image from WEBP file or URL */
PHP_FUNCTIONnull2574 PHP_FUNCTION(imagecreatefromwebp)
2575 {
2576 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageCreateFromWebp, gdImageCreateFromWebpCtx);
2577 }
2578 /* }}} */
2579 #endif /* HAVE_GD_WEBP */
2580 
2581 /* {{{ proto resource imagecreatefromxbm(string filename)
2582    Create a new image from XBM file or URL */
PHP_FUNCTIONnull2583 PHP_FUNCTION(imagecreatefromxbm)
2584 {
2585 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageCreateFromXbm, NULL);
2586 }
2587 /* }}} */
2588 
2589 #if defined(HAVE_GD_XPM)
2590 /* {{{ proto resource imagecreatefromxpm(string filename)
2591    Create a new image from XPM file or URL */
PHP_FUNCTIONnull2592 PHP_FUNCTION(imagecreatefromxpm)
2593 {
2594 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XPM, "XPM", gdImageCreateFromXpm, NULL);
2595 }
2596 /* }}} */
2597 #endif
2598 
2599 /* {{{ proto resource imagecreatefromwbmp(string filename)
2600    Create a new image from WBMP file or URL */
PHP_FUNCTIONnull2601 PHP_FUNCTION(imagecreatefromwbmp)
2602 {
2603 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageCreateFromWBMP, gdImageCreateFromWBMPCtx);
2604 }
2605 /* }}} */
2606 
2607 /* {{{ proto resource imagecreatefromgd(string filename)
2608    Create a new image from GD file or URL */
PHP_FUNCTIONnull2609 PHP_FUNCTION(imagecreatefromgd)
2610 {
2611 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD, "GD", gdImageCreateFromGd, gdImageCreateFromGdCtx);
2612 }
2613 /* }}} */
2614 
2615 /* {{{ proto resource imagecreatefromgd2(string filename)
2616    Create a new image from GD2 file or URL */
PHP_FUNCTIONnull2617 PHP_FUNCTION(imagecreatefromgd2)
2618 {
2619 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2", gdImageCreateFromGd2, gdImageCreateFromGd2Ctx);
2620 }
2621 /* }}} */
2622 
2623 /* {{{ proto resource imagecreatefromgd2part(string filename, int srcX, int srcY, int width, int height)
2624    Create a new image from a given part of GD2 file or URL */
PHP_FUNCTIONnull2625 PHP_FUNCTION(imagecreatefromgd2part)
2626 {
2627 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2PART, "GD2", gdImageCreateFromGd2Part, gdImageCreateFromGd2PartCtx);
2628 }
2629 /* }}} */
2630 
2631 #if defined(HAVE_GD_BMP)
2632 /* {{{ proto resource imagecreatefrombmp(string filename)
2633    Create a new image from BMP file or URL */
PHP_FUNCTIONnull2634 PHP_FUNCTION(imagecreatefrombmp)
2635 {
2636 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_BMP, "BMP", gdImageCreateFromBmp, gdImageCreateFromBmpCtx);
2637 }
2638 /* }}} */
2639 #endif
2640 
2641 #if defined(HAVE_GD_TGA)
2642 /* {{{ proto resource imagecreatefromtga(string filename)
2643    Create a new image from TGA file or URL */
PHP_FUNCTIONnull2644 PHP_FUNCTION(imagecreatefromtga)
2645 {
2646 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_TGA, "TGA", gdImageCreateFromTga, gdImageCreateFromTgaCtx);
2647 }
2648 /* }}} */
2649 #endif
2650 
2651 /* {{{ _php_image_output
2652  */
_php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())2653 static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
2654 {
2655 	zval *imgind;
2656 	char *file = NULL;
2657 	zend_long quality = 0, type = 0;
2658 	gdImagePtr im;
2659 	char *fn = NULL;
2660 	FILE *fp;
2661 	size_t file_len = 0;
2662 	int argc = ZEND_NUM_ARGS();
2663 	int q = -1, t = 1;
2664 
2665 	/* The quality parameter for Wbmp stands for the foreground when called from image2wbmp() */
2666 	/* The quality parameter for gd2 stands for chunk size */
2667 
2668 	if (zend_parse_parameters(argc, "r|pll", &imgind, &file, &file_len, &quality, &type) == FAILURE) {
2669 		return;
2670 	}
2671 
2672 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(imgind), "Image", le_gd)) == NULL) {
2673 		RETURN_FALSE;
2674 	}
2675 
2676 	if (argc > 1) {
2677 		fn = file;
2678 		if (argc >= 3) {
2679 			q = quality;
2680 			if (argc == 4) {
2681 				t = type;
2682 			}
2683 		}
2684 	}
2685 
2686 	if (argc >= 2 && file_len) {
2687 		PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
2688 
2689 		fp = VCWD_FOPEN(fn, "wb");
2690 		if (!fp) {
2691 			php_error_docref(NULL, E_WARNING, "Unable to open '%s' for writing", fn);
2692 			RETURN_FALSE;
2693 		}
2694 
2695 		switch (image_type) {
2696 			case PHP_GDIMG_CONVERT_WBM:
2697 				if (q == -1) {
2698 					q = 0;
2699 				} else if (q < 0 || q > 255) {
2700 					php_error_docref(NULL, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q);
2701 					q = 0;
2702 				}
2703 				gdImageWBMP(im, q, fp);
2704 				break;
2705 			case PHP_GDIMG_TYPE_GD:
2706 				(*func_p)(im, fp);
2707 				break;
2708 			case PHP_GDIMG_TYPE_GD2:
2709 				if (q == -1) {
2710 					q = 128;
2711 				}
2712 				(*func_p)(im, fp, q, t);
2713 				break;
2714 			default:
2715 				ZEND_ASSERT(0);
2716 		}
2717 		fflush(fp);
2718 		fclose(fp);
2719 	} else {
2720 		int   b;
2721 		FILE *tmp;
2722 		char  buf[4096];
2723 		zend_string *path;
2724 
2725 		tmp = php_open_temporary_file(NULL, NULL, &path);
2726 		if (tmp == NULL) {
2727 			php_error_docref(NULL, E_WARNING, "Unable to open temporary file");
2728 			RETURN_FALSE;
2729 		}
2730 
2731 		switch (image_type) {
2732 			case PHP_GDIMG_CONVERT_WBM:
2733  				if (q == -1) {
2734   					q = 0;
2735   				} else if (q < 0 || q > 255) {
2736   					php_error_docref(NULL, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q);
2737  					q = 0;
2738   				}
2739 				gdImageWBMP(im, q, tmp);
2740 				break;
2741 			case PHP_GDIMG_TYPE_GD:
2742 				(*func_p)(im, tmp);
2743 				break;
2744 			case PHP_GDIMG_TYPE_GD2:
2745 				if (q == -1) {
2746 					q = 128;
2747 				}
2748 				(*func_p)(im, tmp, q, t);
2749 				break;
2750 			default:
2751 				ZEND_ASSERT(0);
2752 		}
2753 
2754 		fseek(tmp, 0, SEEK_SET);
2755 
2756 		while ((b = fread(buf, 1, sizeof(buf), tmp)) > 0) {
2757 			php_write(buf, b);
2758 		}
2759 
2760 		fclose(tmp);
2761 		VCWD_UNLINK((const char *)ZSTR_VAL(path)); /* make sure that the temporary file is removed */
2762 		zend_string_release_ex(path, 0);
2763 	}
2764 	RETURN_TRUE;
2765 }
2766 /* }}} */
2767 
2768 /* {{{ proto int imagexbm(int im, string filename [, int foreground])
2769    Output XBM image to browser or file */
PHP_FUNCTIONnull2770 PHP_FUNCTION(imagexbm)
2771 {
2772 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx);
2773 }
2774 /* }}} */
2775 
2776 /* {{{ proto bool imagegif(resource im [, mixed to])
2777    Output GIF image to browser or file */
PHP_FUNCTIONnull2778 PHP_FUNCTION(imagegif)
2779 {
2780 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageGifCtx);
2781 }
2782 /* }}} */
2783 
2784 #ifdef HAVE_GD_PNG
2785 /* {{{ proto bool imagepng(resource im [, mixed to])
2786    Output PNG image to browser or file */
PHP_FUNCTIONnull2787 PHP_FUNCTION(imagepng)
2788 {
2789 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtxEx);
2790 }
2791 /* }}} */
2792 #endif /* HAVE_GD_PNG */
2793 
2794 
2795 #ifdef HAVE_GD_WEBP
2796 /* {{{ proto bool imagewebp(resource im [, mixed to[, int quality]] )
2797    Output WEBP image to browser or file */
PHP_FUNCTIONnull2798 PHP_FUNCTION(imagewebp)
2799 {
2800 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageWebpCtx);
2801 }
2802 /* }}} */
2803 #endif /* HAVE_GD_WEBP */
2804 
2805 
2806 #ifdef HAVE_GD_JPG
2807 /* {{{ proto bool imagejpeg(resource im [, mixed to [, int quality]])
2808    Output JPEG image to browser or file */
PHP_FUNCTIONnull2809 PHP_FUNCTION(imagejpeg)
2810 {
2811 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageJpegCtx);
2812 }
2813 /* }}} */
2814 #endif /* HAVE_GD_JPG */
2815 
2816 /* {{{ proto bool imagewbmp(resource im [, mixed to [, int foreground]])
2817    Output WBMP image to browser or file */
PHP_FUNCTIONnull2818 PHP_FUNCTION(imagewbmp)
2819 {
2820 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMPCtx);
2821 }
2822 /* }}} */
2823 
2824 /* {{{ proto bool imagegd(resource im [, mixed to])
2825    Output GD image to browser or file */
PHP_FUNCTIONnull2826 PHP_FUNCTION(imagegd)
2827 {
2828 	_php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD, "GD", gdImageGd);
2829 }
2830 /* }}} */
2831 
2832 /* {{{ proto bool imagegd2(resource im [, mixed to [, int chunk_size [, int type]]])
2833    Output GD2 image to browser or file */
PHP_FUNCTIONnull2834 PHP_FUNCTION(imagegd2)
2835 {
2836 	_php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2", gdImageGd2);
2837 }
2838 /* }}} */
2839 
2840 #ifdef HAVE_GD_BMP
2841 /* {{{ proto bool imagebmp(resource im [, mixed to [, bool compressed]])
2842    Output BMP image to browser or file */
PHP_FUNCTIONnull2843 PHP_FUNCTION(imagebmp)
2844 {
2845 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_BMP, "BMP", gdImageBmpCtx);
2846 }
2847 /* }}} */
2848 #endif
2849 
2850 /* {{{ proto bool imagedestroy(resource im)
2851    Destroy an image */
PHP_FUNCTIONnull2852 PHP_FUNCTION(imagedestroy)
2853 {
2854 	zval *IM;
2855 	gdImagePtr im;
2856 
2857 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) {
2858 		return;
2859 	}
2860 
2861 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2862 		RETURN_FALSE;
2863 	}
2864 
2865 	zend_list_close(Z_RES_P(IM));
2866 
2867 	RETURN_TRUE;
2868 }
2869 /* }}} */
2870 
2871 /* {{{ proto int imagecolorallocate(resource im, int red, int green, int blue)
2872    Allocate a color for an image */
PHP_FUNCTIONnull2873 PHP_FUNCTION(imagecolorallocate)
2874 {
2875 	zval *IM;
2876 	zend_long red, green, blue;
2877 	gdImagePtr im;
2878 	int ct = (-1);
2879 
2880 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
2881 		return;
2882 	}
2883 
2884 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2885 		RETURN_FALSE;
2886 	}
2887 
2888 	CHECK_RGBA_RANGE(red, Red);
2889 	CHECK_RGBA_RANGE(green, Green);
2890 	CHECK_RGBA_RANGE(blue, Blue);
2891 
2892 	ct = gdImageColorAllocate(im, red, green, blue);
2893 	if (ct < 0) {
2894 		RETURN_FALSE;
2895 	}
2896 	RETURN_LONG(ct);
2897 }
2898 /* }}} */
2899 
2900 /* {{{ proto void imagepalettecopy(resource dst, resource src)
2901    Copy the palette from the src image onto the dst image */
PHP_FUNCTIONnull2902 PHP_FUNCTION(imagepalettecopy)
2903 {
2904 	zval *dstim, *srcim;
2905 	gdImagePtr dst, src;
2906 
2907 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &dstim, &srcim) == FAILURE) {
2908 		return;
2909 	}
2910 
2911 	if ((dst = (gdImagePtr)zend_fetch_resource(Z_RES_P(dstim), "Image", le_gd)) == NULL) {
2912 		RETURN_FALSE;
2913 	}
2914 
2915 	if ((src = (gdImagePtr)zend_fetch_resource(Z_RES_P(srcim), "Image", le_gd)) == NULL) {
2916 		RETURN_FALSE;
2917 	}
2918 
2919 	gdImagePaletteCopy(dst, src);
2920 }
2921 /* }}} */
2922 
2923 /* {{{ proto int imagecolorat(resource im, int x, int y)
2924    Get the index of the color of a pixel */
PHP_FUNCTIONnull2925 PHP_FUNCTION(imagecolorat)
2926 {
2927 	zval *IM;
2928 	zend_long x, y;
2929 	gdImagePtr im;
2930 
2931 	ZEND_PARSE_PARAMETERS_START(3, 3)
2932 		Z_PARAM_RESOURCE(IM)
2933 		Z_PARAM_LONG(x)
2934 		Z_PARAM_LONG(y)
2935 	ZEND_PARSE_PARAMETERS_END();
2936 
2937 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2938 		RETURN_FALSE;
2939 	}
2940 
2941 	if (gdImageTrueColor(im)) {
2942 		if (im->tpixels && gdImageBoundsSafe(im, x, y)) {
2943 			RETURN_LONG(gdImageTrueColorPixel(im, x, y));
2944 		} else {
2945 			php_error_docref(NULL, E_NOTICE, "" ZEND_LONG_FMT "," ZEND_LONG_FMT " is out of bounds", x, y);
2946 			RETURN_FALSE;
2947 		}
2948 	} else {
2949 		if (im->pixels && gdImageBoundsSafe(im, x, y)) {
2950 			RETURN_LONG(im->pixels[y][x]);
2951 		} else {
2952 			php_error_docref(NULL, E_NOTICE, "" ZEND_LONG_FMT "," ZEND_LONG_FMT " is out of bounds", x, y);
2953 			RETURN_FALSE;
2954 		}
2955 	}
2956 }
2957 /* }}} */
2958 
2959 /* {{{ proto int imagecolorclosest(resource im, int red, int green, int blue)
2960    Get the index of the closest color to the specified color */
PHP_FUNCTIONnull2961 PHP_FUNCTION(imagecolorclosest)
2962 {
2963 	zval *IM;
2964 	zend_long red, green, blue;
2965 	gdImagePtr im;
2966 
2967 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
2968 		return;
2969 	}
2970 
2971 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2972 		RETURN_FALSE;
2973 	}
2974 
2975 	CHECK_RGBA_RANGE(red, Red);
2976 	CHECK_RGBA_RANGE(green, Green);
2977 	CHECK_RGBA_RANGE(blue, Blue);
2978 
2979 	RETURN_LONG(gdImageColorClosest(im, red, green, blue));
2980 }
2981 /* }}} */
2982 
2983 /* {{{ proto int imagecolorclosesthwb(resource im, int red, int green, int blue)
2984    Get the index of the color which has the hue, white and blackness nearest to the given color */
PHP_FUNCTIONnull2985 PHP_FUNCTION(imagecolorclosesthwb)
2986 {
2987 	zval *IM;
2988 	zend_long red, green, blue;
2989 	gdImagePtr im;
2990 
2991 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
2992 		return;
2993 	}
2994 
2995 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2996 		RETURN_FALSE;
2997 	}
2998 
2999 	CHECK_RGBA_RANGE(red, Red);
3000 	CHECK_RGBA_RANGE(green, Green);
3001 	CHECK_RGBA_RANGE(blue, Blue);
3002 
3003 	RETURN_LONG(gdImageColorClosestHWB(im, red, green, blue));
3004 }
3005 /* }}} */
3006 
3007 /* {{{ proto bool imagecolordeallocate(resource im, int index)
3008    De-allocate a color for an image */
PHP_FUNCTIONnull3009 PHP_FUNCTION(imagecolordeallocate)
3010 {
3011 	zval *IM;
3012 	zend_long index;
3013 	int col;
3014 	gdImagePtr im;
3015 
3016 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &index) == FAILURE) {
3017 		return;
3018 	}
3019 
3020 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3021 		RETURN_FALSE;
3022 	}
3023 
3024 	/* We can return right away for a truecolor image as deallocating colours is meaningless here */
3025 	if (gdImageTrueColor(im)) {
3026 		RETURN_TRUE;
3027 	}
3028 
3029 	col = index;
3030 
3031 	if (col >= 0 && col < gdImageColorsTotal(im)) {
3032 		gdImageColorDeallocate(im, col);
3033 		RETURN_TRUE;
3034 	} else {
3035 		php_error_docref(NULL, E_WARNING, "Color index %d out of range",	col);
3036 		RETURN_FALSE;
3037 	}
3038 }
3039 /* }}} */
3040 
3041 /* {{{ proto int imagecolorresolve(resource im, int red, int green, int blue)
3042    Get the index of the specified color or its closest possible alternative */
PHP_FUNCTIONnull3043 PHP_FUNCTION(imagecolorresolve)
3044 {
3045 	zval *IM;
3046 	zend_long red, green, blue;
3047 	gdImagePtr im;
3048 
3049 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
3050 		return;
3051 	}
3052 
3053 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3054 		RETURN_FALSE;
3055 	}
3056 
3057 	CHECK_RGBA_RANGE(red, Red);
3058 	CHECK_RGBA_RANGE(green, Green);
3059 	CHECK_RGBA_RANGE(blue, Blue);
3060 
3061 	RETURN_LONG(gdImageColorResolve(im, red, green, blue));
3062 }
3063 /* }}} */
3064 
3065 /* {{{ proto int imagecolorexact(resource im, int red, int green, int blue)
3066    Get the index of the specified color */
PHP_FUNCTIONnull3067 PHP_FUNCTION(imagecolorexact)
3068 {
3069 	zval *IM;
3070 	zend_long red, green, blue;
3071 	gdImagePtr im;
3072 
3073 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
3074 		return;
3075 	}
3076 
3077 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3078 		RETURN_FALSE;
3079 	}
3080 
3081 	CHECK_RGBA_RANGE(red, Red);
3082 	CHECK_RGBA_RANGE(green, Green);
3083 	CHECK_RGBA_RANGE(blue, Blue);
3084 
3085 	RETURN_LONG(gdImageColorExact(im, red, green, blue));
3086 }
3087 /* }}} */
3088 
3089 /* {{{ proto bool imagecolorset(resource im, int col, int red, int green, int blue)
3090    Set the color for the specified palette index */
PHP_FUNCTIONnull3091 PHP_FUNCTION(imagecolorset)
3092 {
3093 	zval *IM;
3094 	zend_long color, red, green, blue, alpha = 0;
3095 	int col;
3096 	gdImagePtr im;
3097 
3098 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll|l", &IM, &color, &red, &green, &blue, &alpha) == FAILURE) {
3099 		return;
3100 	}
3101 
3102 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3103 		RETURN_FALSE;
3104 	}
3105 
3106 	CHECK_RGBA_RANGE(red, Red);
3107 	CHECK_RGBA_RANGE(green, Green);
3108 	CHECK_RGBA_RANGE(blue, Blue);
3109 	CHECK_RGBA_RANGE(alpha, Alpha);
3110 
3111 	col = color;
3112 
3113 	if (col >= 0 && col < gdImageColorsTotal(im)) {
3114 		im->red[col]   = red;
3115 		im->green[col] = green;
3116 		im->blue[col]  = blue;
3117 		im->alpha[col]  = alpha;
3118 	} else {
3119 		RETURN_FALSE;
3120 	}
3121 }
3122 /* }}} */
3123 
3124 /* {{{ proto array imagecolorsforindex(resource im, int col)
3125    Get the colors for an index */
PHP_FUNCTIONnull3126 PHP_FUNCTION(imagecolorsforindex)
3127 {
3128 	zval *IM;
3129 	zend_long index;
3130 	int col;
3131 	gdImagePtr im;
3132 
3133 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &index) == FAILURE) {
3134 		return;
3135 	}
3136 
3137 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3138 		RETURN_FALSE;
3139 	}
3140 
3141 	col = index;
3142 
3143 	if ((col >= 0 && gdImageTrueColor(im)) || (!gdImageTrueColor(im) && col >= 0 && col < gdImageColorsTotal(im))) {
3144 		array_init(return_value);
3145 
3146 		add_assoc_long(return_value,"red",  gdImageRed(im,col));
3147 		add_assoc_long(return_value,"green", gdImageGreen(im,col));
3148 		add_assoc_long(return_value,"blue", gdImageBlue(im,col));
3149 		add_assoc_long(return_value,"alpha", gdImageAlpha(im,col));
3150 	} else {
3151 		php_error_docref(NULL, E_WARNING, "Color index %d out of range", col);
3152 		RETURN_FALSE;
3153 	}
3154 }
3155 /* }}} */
3156 
3157 /* {{{ proto bool imagegammacorrect(resource im, float inputgamma, float outputgamma)
3158    Apply a gamma correction to a GD image */
PHP_FUNCTIONnull3159 PHP_FUNCTION(imagegammacorrect)
3160 {
3161 	zval *IM;
3162 	gdImagePtr im;
3163 	int i;
3164 	double input, output, gamma;
3165 
3166 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rdd", &IM, &input, &output) == FAILURE) {
3167 		return;
3168 	}
3169 
3170 	if ( input <= 0.0 || output <= 0.0 ) {
3171 		php_error_docref(NULL, E_WARNING, "Gamma values should be positive");
3172 		RETURN_FALSE;
3173 	}
3174 
3175 	gamma = input / output;
3176 
3177 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3178 		RETURN_FALSE;
3179 	}
3180 
3181 	if (gdImageTrueColor(im))	{
3182 		int x, y, c;
3183 
3184 		for (y = 0; y < gdImageSY(im); y++)	{
3185 			for (x = 0; x < gdImageSX(im); x++)	{
3186 				c = gdImageGetPixel(im, x, y);
3187 				gdImageSetPixel(im, x, y,
3188 					gdTrueColorAlpha(
3189 						(int) ((pow((gdTrueColorGetRed(c)   / 255.0), gamma) * 255) + .5),
3190 						(int) ((pow((gdTrueColorGetGreen(c) / 255.0), gamma) * 255) + .5),
3191 						(int) ((pow((gdTrueColorGetBlue(c)  / 255.0), gamma) * 255) + .5),
3192 						gdTrueColorGetAlpha(c)
3193 					)
3194 				);
3195 			}
3196 		}
3197 		RETURN_TRUE;
3198 	}
3199 
3200 	for (i = 0; i < gdImageColorsTotal(im); i++) {
3201 		im->red[i]   = (int)((pow((im->red[i]   / 255.0), gamma) * 255) + .5);
3202 		im->green[i] = (int)((pow((im->green[i] / 255.0), gamma) * 255) + .5);
3203 		im->blue[i]  = (int)((pow((im->blue[i]  / 255.0), gamma) * 255) + .5);
3204 	}
3205 
3206 	RETURN_TRUE;
3207 }
3208 /* }}} */
3209 
3210 /* {{{ proto bool imagesetpixel(resource im, int x, int y, int col)
3211    Set a single pixel */
PHP_FUNCTIONnull3212 PHP_FUNCTION(imagesetpixel)
3213 {
3214 	zval *IM;
3215 	zend_long x, y, col;
3216 	gdImagePtr im;
3217 
3218 	ZEND_PARSE_PARAMETERS_START(4, 4)
3219 		Z_PARAM_RESOURCE(IM)
3220 		Z_PARAM_LONG(x)
3221 		Z_PARAM_LONG(y)
3222 		Z_PARAM_LONG(col)
3223 	ZEND_PARSE_PARAMETERS_END();
3224 
3225 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3226 		RETURN_FALSE;
3227 	}
3228 
3229 	gdImageSetPixel(im, x, y, col);
3230 	RETURN_TRUE;
3231 }
3232 /* }}} */
3233 
3234 /* {{{ proto bool imageline(resource im, int x1, int y1, int x2, int y2, int col)
3235    Draw a line */
PHP_FUNCTIONnull3236 PHP_FUNCTION(imageline)
3237 {
3238 	zval *IM;
3239 	zend_long x1, y1, x2, y2, col;
3240 	gdImagePtr im;
3241 
3242 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &x1, &y1, &x2, &y2, &col) == FAILURE) {
3243 		return;
3244 	}
3245 
3246 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3247 		RETURN_FALSE;
3248 	}
3249 
3250 	if (im->AA) {
3251 		gdImageSetAntiAliased(im, col);
3252 		col = gdAntiAliased;
3253 	}
3254 	gdImageLine(im, x1, y1, x2, y2, col);
3255 	RETURN_TRUE;
3256 }
3257 /* }}} */
3258 
3259 /* {{{ proto bool imagedashedline(resource im, int x1, int y1, int x2, int y2, int col)
3260    Draw a dashed line */
PHP_FUNCTIONnull3261 PHP_FUNCTION(imagedashedline)
3262 {
3263 	zval *IM;
3264 	zend_long x1, y1, x2, y2, col;
3265 	gdImagePtr im;
3266 
3267 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &x1, &y1, &x2, &y2, &col) == FAILURE) {
3268 		return;
3269 	}
3270 
3271 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3272 		RETURN_FALSE;
3273 	}
3274 
3275 	gdImageDashedLine(im, x1, y1, x2, y2, col);
3276 	RETURN_TRUE;
3277 }
3278 /* }}} */
3279 
3280 /* {{{ proto bool imagerectangle(resource im, int x1, int y1, int x2, int y2, int col)
3281    Draw a rectangle */
PHP_FUNCTIONnull3282 PHP_FUNCTION(imagerectangle)
3283 {
3284 	zval *IM;
3285 	zend_long x1, y1, x2, y2, col;
3286 	gdImagePtr im;
3287 
3288 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &x1, &y1, &x2, &y2, &col) == FAILURE) {
3289 		return;
3290 	}
3291 
3292 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3293 		RETURN_FALSE;
3294 	}
3295 
3296 	gdImageRectangle(im, x1, y1, x2, y2, col);
3297 	RETURN_TRUE;
3298 }
3299 /* }}} */
3300 
3301 /* {{{ proto bool imagefilledrectangle(resource im, int x1, int y1, int x2, int y2, int col)
3302    Draw a filled rectangle */
PHP_FUNCTIONnull3303 PHP_FUNCTION(imagefilledrectangle)
3304 {
3305 	zval *IM;
3306 	zend_long x1, y1, x2, y2, col;
3307 	gdImagePtr im;
3308 
3309 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &x1, &y1, &x2, &y2, &col) == FAILURE) {
3310 		return;
3311 	}
3312 
3313 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3314 		RETURN_FALSE;
3315 	}
3316 	gdImageFilledRectangle(im, x1, y1, x2, y2, col);
3317 	RETURN_TRUE;
3318 }
3319 /* }}} */
3320 
3321 /* {{{ proto bool imagearc(resource im, int cx, int cy, int w, int h, int s, int e, int col)
3322    Draw a partial ellipse */
PHP_FUNCTIONnull3323 PHP_FUNCTION(imagearc)
3324 {
3325 	zval *IM;
3326 	zend_long cx, cy, w, h, ST, E, col;
3327 	gdImagePtr im;
3328 	int e, st;
3329 
3330 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllllll", &IM, &cx, &cy, &w, &h, &ST, &E, &col) == FAILURE) {
3331 		return;
3332 	}
3333 
3334 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3335 		RETURN_FALSE;
3336 	}
3337 
3338 	e = E;
3339 	if (e < 0) {
3340 		e %= 360;
3341 	}
3342 
3343 	st = ST;
3344 	if (st < 0) {
3345 		st %= 360;
3346 	}
3347 
3348 	gdImageArc(im, cx, cy, w, h, st, e, col);
3349 	RETURN_TRUE;
3350 }
3351 /* }}} */
3352 
3353 /* {{{ proto bool imageellipse(resource im, int cx, int cy, int w, int h, int color)
3354    Draw an ellipse */
PHP_FUNCTIONnull3355 PHP_FUNCTION(imageellipse)
3356 {
3357 	zval *IM;
3358 	zend_long cx, cy, w, h, color;
3359 	gdImagePtr im;
3360 
3361 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &cx, &cy, &w, &h, &color) == FAILURE) {
3362 		return;
3363 	}
3364 
3365 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3366 		RETURN_FALSE;
3367 	}
3368 
3369 	gdImageEllipse(im,