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 #ifdef HAVE_GD_BUNDLED
64 # include "libgd/gd.h"
65 # include "libgd/gd_errors.h"
66 # include "libgd/gdfontt.h"  /* 1 Tiny font */
67 # include "libgd/gdfonts.h"  /* 2 Small font */
68 # include "libgd/gdfontmb.h" /* 3 Medium bold font */
69 # include "libgd/gdfontl.h"  /* 4 Large font */
70 # include "libgd/gdfontg.h"  /* 5 Giant font */
71 #else
72 # include <gd.h>
73 # include <gd_errors.h>
74 # include <gdfontt.h>  /* 1 Tiny font */
75 # include <gdfonts.h>  /* 2 Small font */
76 # include <gdfontmb.h> /* 3 Medium bold font */
77 # include <gdfontl.h>  /* 4 Large font */
78 # include <gdfontg.h>  /* 5 Giant font */
79 #endif
80 
81 #if defined(HAVE_GD_FREETYPE) && defined(HAVE_GD_BUNDLED)
82 # include <ft2build.h>
83 # include FT_FREETYPE_H
84 #endif
85 
86 #if defined(HAVE_XPM) && defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
87 # include "X11/xpm.h"
88 #endif
89 
90 #ifndef M_PI
91 #define M_PI 3.14159265358979323846
92 #endif
93 
94 #ifdef HAVE_GD_FREETYPE
95 static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int, int);
96 #endif
97 
98 #include "gd_ctx.c"
99 
100 /* as it is not really public, duplicate declaration here to avoid
101    pointless warnings */
102 int overflow2(int a, int b);
103 
104 /* Section Filters Declarations */
105 /* IMPORTANT NOTE FOR NEW FILTER
106  * Do not forget to update:
107  * IMAGE_FILTER_MAX: define the last filter index
108  * IMAGE_FILTER_MAX_ARGS: define the biggest amount of arguments
109  * image_filter array in PHP_FUNCTION(imagefilter)
110  * */
111 #define IMAGE_FILTER_NEGATE         0
112 #define IMAGE_FILTER_GRAYSCALE      1
113 #define IMAGE_FILTER_BRIGHTNESS     2
114 #define IMAGE_FILTER_CONTRAST       3
115 #define IMAGE_FILTER_COLORIZE       4
116 #define IMAGE_FILTER_EDGEDETECT     5
117 #define IMAGE_FILTER_EMBOSS         6
118 #define IMAGE_FILTER_GAUSSIAN_BLUR  7
119 #define IMAGE_FILTER_SELECTIVE_BLUR 8
120 #define IMAGE_FILTER_MEAN_REMOVAL   9
121 #define IMAGE_FILTER_SMOOTH         10
122 #define IMAGE_FILTER_PIXELATE       11
123 #define IMAGE_FILTER_SCATTER		12
124 #define IMAGE_FILTER_MAX            12
125 #define IMAGE_FILTER_MAX_ARGS       6
126 static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS);
127 static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS);
128 static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS);
129 static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS);
130 static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS);
131 static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS);
132 static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS);
133 static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS);
134 static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS);
135 static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS);
136 static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS);
137 static void php_image_filter_pixelate(INTERNAL_FUNCTION_PARAMETERS);
138 static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS);
139 
140 /* End Section filters declarations */
141 static gdImagePtr _php_image_create_from_string (zval *Data, char *tn, gdImagePtr (*ioctx_func_p)());
142 static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)());
143 static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)());
144 static int _php_image_type(char data[12]);
145 static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type);
146 
147 /* {{{ arginfo */
148 ZEND_BEGIN_ARG_INFO(arginfo_gd_info, 0)
149 ZEND_END_ARG_INFO()
150 
151 ZEND_BEGIN_ARG_INFO(arginfo_imageloadfont, 0)
152 	ZEND_ARG_INFO(0, filename)
153 ZEND_END_ARG_INFO()
154 
155 ZEND_BEGIN_ARG_INFO(arginfo_imagesetstyle, 0)
156 	ZEND_ARG_INFO(0, im)
157 	ZEND_ARG_INFO(0, styles) /* ARRAY_INFO(0, styles, 0) */
158 ZEND_END_ARG_INFO()
159 
160 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatetruecolor, 0)
161 	ZEND_ARG_INFO(0, x_size)
162 	ZEND_ARG_INFO(0, y_size)
163 ZEND_END_ARG_INFO()
164 
165 ZEND_BEGIN_ARG_INFO(arginfo_imageistruecolor, 0)
166 	ZEND_ARG_INFO(0, im)
167 ZEND_END_ARG_INFO()
168 
169 ZEND_BEGIN_ARG_INFO(arginfo_imagetruecolortopalette, 0)
170 	ZEND_ARG_INFO(0, im)
171 	ZEND_ARG_INFO(0, ditherFlag)
172 	ZEND_ARG_INFO(0, colorsWanted)
173 ZEND_END_ARG_INFO()
174 
175 ZEND_BEGIN_ARG_INFO(arginfo_imagepalettetotruecolor, 0)
176 	ZEND_ARG_INFO(0, im)
177 ZEND_END_ARG_INFO()
178 
179 ZEND_BEGIN_ARG_INFO(arginfo_imagecolormatch, 0)
180 	ZEND_ARG_INFO(0, im1)
181 	ZEND_ARG_INFO(0, im2)
182 ZEND_END_ARG_INFO()
183 
184 ZEND_BEGIN_ARG_INFO(arginfo_imagesetthickness, 0)
185 	ZEND_ARG_INFO(0, im)
186 	ZEND_ARG_INFO(0, thickness)
187 ZEND_END_ARG_INFO()
188 
189 ZEND_BEGIN_ARG_INFO(arginfo_imagefilledellipse, 0)
190 	ZEND_ARG_INFO(0, im)
191 	ZEND_ARG_INFO(0, cx)
192 	ZEND_ARG_INFO(0, cy)
193 	ZEND_ARG_INFO(0, w)
194 	ZEND_ARG_INFO(0, h)
195 	ZEND_ARG_INFO(0, color)
196 ZEND_END_ARG_INFO()
197 
198 ZEND_BEGIN_ARG_INFO(arginfo_imagefilledarc, 0)
199 	ZEND_ARG_INFO(0, im)
200 	ZEND_ARG_INFO(0, cx)
201 	ZEND_ARG_INFO(0, cy)
202 	ZEND_ARG_INFO(0, w)
203 	ZEND_ARG_INFO(0, h)
204 	ZEND_ARG_INFO(0, s)
205 	ZEND_ARG_INFO(0, e)
206 	ZEND_ARG_INFO(0, col)
207 	ZEND_ARG_INFO(0, style)
208 ZEND_END_ARG_INFO()
209 
210 ZEND_BEGIN_ARG_INFO(arginfo_imagealphablending, 0)
211 	ZEND_ARG_INFO(0, im)
212 	ZEND_ARG_INFO(0, blend)
213 ZEND_END_ARG_INFO()
214 
215 ZEND_BEGIN_ARG_INFO(arginfo_imagesavealpha, 0)
216 	ZEND_ARG_INFO(0, im)
217 	ZEND_ARG_INFO(0, save)
218 ZEND_END_ARG_INFO()
219 
220 ZEND_BEGIN_ARG_INFO(arginfo_imagelayereffect, 0)
221 	ZEND_ARG_INFO(0, im)
222 	ZEND_ARG_INFO(0, effect)
223 ZEND_END_ARG_INFO()
224 
225 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorallocatealpha, 0)
226 	ZEND_ARG_INFO(0, im)
227 	ZEND_ARG_INFO(0, red)
228 	ZEND_ARG_INFO(0, green)
229 	ZEND_ARG_INFO(0, blue)
230 	ZEND_ARG_INFO(0, alpha)
231 ZEND_END_ARG_INFO()
232 
233 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorresolvealpha, 0)
234 	ZEND_ARG_INFO(0, im)
235 	ZEND_ARG_INFO(0, red)
236 	ZEND_ARG_INFO(0, green)
237 	ZEND_ARG_INFO(0, blue)
238 	ZEND_ARG_INFO(0, alpha)
239 ZEND_END_ARG_INFO()
240 
241 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorclosestalpha, 0)
242 	ZEND_ARG_INFO(0, im)
243 	ZEND_ARG_INFO(0, red)
244 	ZEND_ARG_INFO(0, green)
245 	ZEND_ARG_INFO(0, blue)
246 	ZEND_ARG_INFO(0, alpha)
247 ZEND_END_ARG_INFO()
248 
249 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorexactalpha, 0)
250 	ZEND_ARG_INFO(0, im)
251 	ZEND_ARG_INFO(0, red)
252 	ZEND_ARG_INFO(0, green)
253 	ZEND_ARG_INFO(0, blue)
254 	ZEND_ARG_INFO(0, alpha)
255 ZEND_END_ARG_INFO()
256 
257 ZEND_BEGIN_ARG_INFO(arginfo_imagecopyresampled, 0)
258 	ZEND_ARG_INFO(0, dst_im)
259 	ZEND_ARG_INFO(0, src_im)
260 	ZEND_ARG_INFO(0, dst_x)
261 	ZEND_ARG_INFO(0, dst_y)
262 	ZEND_ARG_INFO(0, src_x)
263 	ZEND_ARG_INFO(0, src_y)
264 	ZEND_ARG_INFO(0, dst_w)
265 	ZEND_ARG_INFO(0, dst_h)
266 	ZEND_ARG_INFO(0, src_w)
267 	ZEND_ARG_INFO(0, src_h)
268 ZEND_END_ARG_INFO()
269 
270 #ifdef PHP_WIN32
271 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegrabwindow, 0, 0, 1)
272 	ZEND_ARG_INFO(0, handle)
273 	ZEND_ARG_INFO(0, client_area)
274 ZEND_END_ARG_INFO()
275 
276 ZEND_BEGIN_ARG_INFO(arginfo_imagegrabscreen, 0)
277 ZEND_END_ARG_INFO()
278 #endif
279 
280 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagerotate, 0, 0, 3)
281 	ZEND_ARG_INFO(0, im)
282 	ZEND_ARG_INFO(0, angle)
283 	ZEND_ARG_INFO(0, bgdcolor)
284 	ZEND_ARG_INFO(0, ignoretransparent)
285 ZEND_END_ARG_INFO()
286 
287 ZEND_BEGIN_ARG_INFO(arginfo_imagesettile, 0)
288 	ZEND_ARG_INFO(0, im)
289 	ZEND_ARG_INFO(0, tile)
290 ZEND_END_ARG_INFO()
291 
292 ZEND_BEGIN_ARG_INFO(arginfo_imagesetbrush, 0)
293 	ZEND_ARG_INFO(0, im)
294 	ZEND_ARG_INFO(0, brush)
295 ZEND_END_ARG_INFO()
296 
297 ZEND_BEGIN_ARG_INFO(arginfo_imagecreate, 0)
298 	ZEND_ARG_INFO(0, x_size)
299 	ZEND_ARG_INFO(0, y_size)
300 ZEND_END_ARG_INFO()
301 
302 ZEND_BEGIN_ARG_INFO(arginfo_imagetypes, 0)
303 ZEND_END_ARG_INFO()
304 
305 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromstring, 0)
306 	ZEND_ARG_INFO(0, image)
307 ZEND_END_ARG_INFO()
308 
309 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgif, 0)
310 	ZEND_ARG_INFO(0, filename)
311 ZEND_END_ARG_INFO()
312 
313 #ifdef HAVE_GD_JPG
314 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromjpeg, 0)
315 	ZEND_ARG_INFO(0, filename)
316 ZEND_END_ARG_INFO()
317 #endif
318 
319 #ifdef HAVE_GD_PNG
320 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefrompng, 0)
321 	ZEND_ARG_INFO(0, filename)
322 ZEND_END_ARG_INFO()
323 #endif
324 
325 #ifdef HAVE_GD_WEBP
326 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromwebp, 0)
327 	ZEND_ARG_INFO(0, filename)
328 ZEND_END_ARG_INFO()
329 #endif
330 
331 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromxbm, 0)
332 	ZEND_ARG_INFO(0, filename)
333 ZEND_END_ARG_INFO()
334 
335 #if defined(HAVE_XPM) && defined(HAVE_GD_XPM)
336 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromxpm, 0)
337 	ZEND_ARG_INFO(0, filename)
338 ZEND_END_ARG_INFO()
339 #endif
340 
341 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromwbmp, 0)
342 	ZEND_ARG_INFO(0, filename)
343 ZEND_END_ARG_INFO()
344 
345 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd, 0)
346 	ZEND_ARG_INFO(0, filename)
347 ZEND_END_ARG_INFO()
348 
349 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd2, 0)
350 	ZEND_ARG_INFO(0, filename)
351 ZEND_END_ARG_INFO()
352 
353 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd2part, 0)
354 	ZEND_ARG_INFO(0, filename)
355 	ZEND_ARG_INFO(0, srcX)
356 	ZEND_ARG_INFO(0, srcY)
357 	ZEND_ARG_INFO(0, width)
358 	ZEND_ARG_INFO(0, height)
359 ZEND_END_ARG_INFO()
360 
361 #if defined(HAVE_GD_BMP)
362 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefrombmp, 0)
363 	ZEND_ARG_INFO(0, filename)
364 ZEND_END_ARG_INFO()
365 #endif
366 
367 #if defined(HAVE_GD_TGA)
368 ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromtga, 0)
369 	ZEND_ARG_INFO(0, filename)
370 ZEND_END_ARG_INFO()
371 #endif
372 
373 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagexbm, 0, 0, 2)
374 	ZEND_ARG_INFO(0, im)
375 	ZEND_ARG_INFO(0, filename)
376 	ZEND_ARG_INFO(0, foreground)
377 ZEND_END_ARG_INFO()
378 
379 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegif, 0, 0, 1)
380 	ZEND_ARG_INFO(0, im)
381 	ZEND_ARG_INFO(0, to)
382 ZEND_END_ARG_INFO()
383 
384 #ifdef HAVE_GD_PNG
385 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagepng, 0, 0, 1)
386 	ZEND_ARG_INFO(0, im)
387 	ZEND_ARG_INFO(0, to)
388 	ZEND_ARG_INFO(0, quality)
389 	ZEND_ARG_INFO(0, filters)
390 ZEND_END_ARG_INFO()
391 #endif
392 
393 #ifdef HAVE_GD_WEBP
394 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagewebp, 0, 0, 1)
395 	ZEND_ARG_INFO(0, im)
396 	ZEND_ARG_INFO(0, to)
397 	ZEND_ARG_INFO(0, quality)
398 ZEND_END_ARG_INFO()
399 #endif
400 
401 #ifdef HAVE_GD_JPG
402 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagejpeg, 0, 0, 1)
403 	ZEND_ARG_INFO(0, im)
404 	ZEND_ARG_INFO(0, to)
405 	ZEND_ARG_INFO(0, quality)
406 ZEND_END_ARG_INFO()
407 #endif
408 
409 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagewbmp, 0, 0, 1)
410 	ZEND_ARG_INFO(0, im)
411 	ZEND_ARG_INFO(0, to)
412 	ZEND_ARG_INFO(0, foreground)
413 ZEND_END_ARG_INFO()
414 
415 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegd, 0, 0, 1)
416 	ZEND_ARG_INFO(0, im)
417 	ZEND_ARG_INFO(0, to)
418 ZEND_END_ARG_INFO()
419 
420 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegd2, 0, 0, 1)
421 	ZEND_ARG_INFO(0, im)
422 	ZEND_ARG_INFO(0, to)
423 	ZEND_ARG_INFO(0, chunk_size)
424 	ZEND_ARG_INFO(0, type)
425 ZEND_END_ARG_INFO()
426 
427 #if defined(HAVE_GD_BMP)
428 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagebmp, 0, 0, 1)
429 	ZEND_ARG_INFO(0, im)
430 	ZEND_ARG_INFO(0, to)
431 	ZEND_ARG_INFO(0, compressed)
432 ZEND_END_ARG_INFO()
433 #endif
434 
435 ZEND_BEGIN_ARG_INFO(arginfo_imagedestroy, 0)
436 	ZEND_ARG_INFO(0, im)
437 ZEND_END_ARG_INFO()
438 
439 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorallocate, 0)
440 	ZEND_ARG_INFO(0, im)
441 	ZEND_ARG_INFO(0, red)
442 	ZEND_ARG_INFO(0, green)
443 	ZEND_ARG_INFO(0, blue)
444 ZEND_END_ARG_INFO()
445 
446 ZEND_BEGIN_ARG_INFO(arginfo_imagepalettecopy, 0)
447 	ZEND_ARG_INFO(0, dst)
448 	ZEND_ARG_INFO(0, src)
449 ZEND_END_ARG_INFO()
450 
451 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorat, 0)
452 	ZEND_ARG_INFO(0, im)
453 	ZEND_ARG_INFO(0, x)
454 	ZEND_ARG_INFO(0, y)
455 ZEND_END_ARG_INFO()
456 
457 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorclosest, 0)
458 	ZEND_ARG_INFO(0, im)
459 	ZEND_ARG_INFO(0, red)
460 	ZEND_ARG_INFO(0, green)
461 	ZEND_ARG_INFO(0, blue)
462 ZEND_END_ARG_INFO()
463 
464 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorclosesthwb, 0)
465 	ZEND_ARG_INFO(0, im)
466 	ZEND_ARG_INFO(0, red)
467 	ZEND_ARG_INFO(0, green)
468 	ZEND_ARG_INFO(0, blue)
469 ZEND_END_ARG_INFO()
470 
471 ZEND_BEGIN_ARG_INFO(arginfo_imagecolordeallocate, 0)
472 	ZEND_ARG_INFO(0, im)
473 	ZEND_ARG_INFO(0, index)
474 ZEND_END_ARG_INFO()
475 
476 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorresolve, 0)
477 	ZEND_ARG_INFO(0, im)
478 	ZEND_ARG_INFO(0, red)
479 	ZEND_ARG_INFO(0, green)
480 	ZEND_ARG_INFO(0, blue)
481 ZEND_END_ARG_INFO()
482 
483 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorexact, 0)
484 	ZEND_ARG_INFO(0, im)
485 	ZEND_ARG_INFO(0, red)
486 	ZEND_ARG_INFO(0, green)
487 	ZEND_ARG_INFO(0, blue)
488 ZEND_END_ARG_INFO()
489 
490 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecolorset, 0, 0, 5)
491 	ZEND_ARG_INFO(0, im)
492 	ZEND_ARG_INFO(0, color)
493 	ZEND_ARG_INFO(0, red)
494 	ZEND_ARG_INFO(0, green)
495 	ZEND_ARG_INFO(0, blue)
496 	ZEND_ARG_INFO(0, alpha)
497 ZEND_END_ARG_INFO()
498 
499 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorsforindex, 0)
500 	ZEND_ARG_INFO(0, im)
501 	ZEND_ARG_INFO(0, index)
502 ZEND_END_ARG_INFO()
503 
504 ZEND_BEGIN_ARG_INFO(arginfo_imagegammacorrect, 0)
505 	ZEND_ARG_INFO(0, im)
506 	ZEND_ARG_INFO(0, inputgamma)
507 	ZEND_ARG_INFO(0, outputgamma)
508 ZEND_END_ARG_INFO()
509 
510 ZEND_BEGIN_ARG_INFO(arginfo_imagesetpixel, 0)
511 	ZEND_ARG_INFO(0, im)
512 	ZEND_ARG_INFO(0, x)
513 	ZEND_ARG_INFO(0, y)
514 	ZEND_ARG_INFO(0, col)
515 ZEND_END_ARG_INFO()
516 
517 ZEND_BEGIN_ARG_INFO(arginfo_imageline, 0)
518 	ZEND_ARG_INFO(0, im)
519 	ZEND_ARG_INFO(0, x1)
520 	ZEND_ARG_INFO(0, y1)
521 	ZEND_ARG_INFO(0, x2)
522 	ZEND_ARG_INFO(0, y2)
523 	ZEND_ARG_INFO(0, col)
524 ZEND_END_ARG_INFO()
525 
526 ZEND_BEGIN_ARG_INFO(arginfo_imagedashedline, 0)
527 	ZEND_ARG_INFO(0, im)
528 	ZEND_ARG_INFO(0, x1)
529 	ZEND_ARG_INFO(0, y1)
530 	ZEND_ARG_INFO(0, x2)
531 	ZEND_ARG_INFO(0, y2)
532 	ZEND_ARG_INFO(0, col)
533 ZEND_END_ARG_INFO()
534 
535 ZEND_BEGIN_ARG_INFO(arginfo_imagerectangle, 0)
536 	ZEND_ARG_INFO(0, im)
537 	ZEND_ARG_INFO(0, x1)
538 	ZEND_ARG_INFO(0, y1)
539 	ZEND_ARG_INFO(0, x2)
540 	ZEND_ARG_INFO(0, y2)
541 	ZEND_ARG_INFO(0, col)
542 ZEND_END_ARG_INFO()
543 
544 ZEND_BEGIN_ARG_INFO(arginfo_imagefilledrectangle, 0)
545 	ZEND_ARG_INFO(0, im)
546 	ZEND_ARG_INFO(0, x1)
547 	ZEND_ARG_INFO(0, y1)
548 	ZEND_ARG_INFO(0, x2)
549 	ZEND_ARG_INFO(0, y2)
550 	ZEND_ARG_INFO(0, col)
551 ZEND_END_ARG_INFO()
552 
553 ZEND_BEGIN_ARG_INFO(arginfo_imagearc, 0)
554 	ZEND_ARG_INFO(0, im)
555 	ZEND_ARG_INFO(0, cx)
556 	ZEND_ARG_INFO(0, cy)
557 	ZEND_ARG_INFO(0, w)
558 	ZEND_ARG_INFO(0, h)
559 	ZEND_ARG_INFO(0, s)
560 	ZEND_ARG_INFO(0, e)
561 	ZEND_ARG_INFO(0, col)
562 ZEND_END_ARG_INFO()
563 
564 ZEND_BEGIN_ARG_INFO(arginfo_imageellipse, 0)
565 	ZEND_ARG_INFO(0, im)
566 	ZEND_ARG_INFO(0, cx)
567 	ZEND_ARG_INFO(0, cy)
568 	ZEND_ARG_INFO(0, w)
569 	ZEND_ARG_INFO(0, h)
570 	ZEND_ARG_INFO(0, color)
571 ZEND_END_ARG_INFO()
572 
573 ZEND_BEGIN_ARG_INFO(arginfo_imagefilltoborder, 0)
574 	ZEND_ARG_INFO(0, im)
575 	ZEND_ARG_INFO(0, x)
576 	ZEND_ARG_INFO(0, y)
577 	ZEND_ARG_INFO(0, border)
578 	ZEND_ARG_INFO(0, col)
579 ZEND_END_ARG_INFO()
580 
581 ZEND_BEGIN_ARG_INFO(arginfo_imagefill, 0)
582 	ZEND_ARG_INFO(0, im)
583 	ZEND_ARG_INFO(0, x)
584 	ZEND_ARG_INFO(0, y)
585 	ZEND_ARG_INFO(0, col)
586 ZEND_END_ARG_INFO()
587 
588 ZEND_BEGIN_ARG_INFO(arginfo_imagecolorstotal, 0)
589 	ZEND_ARG_INFO(0, im)
590 ZEND_END_ARG_INFO()
591 
592 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecolortransparent, 0, 0, 1)
593 	ZEND_ARG_INFO(0, im)
594 	ZEND_ARG_INFO(0, col)
595 ZEND_END_ARG_INFO()
596 
597 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageinterlace, 0, 0, 1)
598 	ZEND_ARG_INFO(0, im)
599 	ZEND_ARG_INFO(0, interlace)
600 ZEND_END_ARG_INFO()
601 
602 ZEND_BEGIN_ARG_INFO(arginfo_imagepolygon, 0)
603 	ZEND_ARG_INFO(0, im)
604 	ZEND_ARG_INFO(0, points) /* ARRAY_INFO(0, points, 0) */
605 	ZEND_ARG_INFO(0, num_pos)
606 	ZEND_ARG_INFO(0, col)
607 ZEND_END_ARG_INFO()
608 
609 ZEND_BEGIN_ARG_INFO(arginfo_imageopenpolygon, 0)
610 	ZEND_ARG_INFO(0, im)
611 	ZEND_ARG_INFO(0, points) /* ARRAY_INFO(0, points, 0) */
612 	ZEND_ARG_INFO(0, num_pos)
613 	ZEND_ARG_INFO(0, col)
614 ZEND_END_ARG_INFO()
615 
616 ZEND_BEGIN_ARG_INFO(arginfo_imagefilledpolygon, 0)
617 	ZEND_ARG_INFO(0, im)
618 	ZEND_ARG_INFO(0, points) /* ARRAY_INFO(0, points, 0) */
619 	ZEND_ARG_INFO(0, num_pos)
620 	ZEND_ARG_INFO(0, col)
621 ZEND_END_ARG_INFO()
622 
623 ZEND_BEGIN_ARG_INFO(arginfo_imagefontwidth, 0)
624 	ZEND_ARG_INFO(0, font)
625 ZEND_END_ARG_INFO()
626 
627 ZEND_BEGIN_ARG_INFO(arginfo_imagefontheight, 0)
628 	ZEND_ARG_INFO(0, font)
629 ZEND_END_ARG_INFO()
630 
631 ZEND_BEGIN_ARG_INFO(arginfo_imagechar, 0)
632 	ZEND_ARG_INFO(0, im)
633 	ZEND_ARG_INFO(0, font)
634 	ZEND_ARG_INFO(0, x)
635 	ZEND_ARG_INFO(0, y)
636 	ZEND_ARG_INFO(0, c)
637 	ZEND_ARG_INFO(0, col)
638 ZEND_END_ARG_INFO()
639 
640 ZEND_BEGIN_ARG_INFO(arginfo_imagecharup, 0)
641 	ZEND_ARG_INFO(0, im)
642 	ZEND_ARG_INFO(0, font)
643 	ZEND_ARG_INFO(0, x)
644 	ZEND_ARG_INFO(0, y)
645 	ZEND_ARG_INFO(0, c)
646 	ZEND_ARG_INFO(0, col)
647 ZEND_END_ARG_INFO()
648 
649 ZEND_BEGIN_ARG_INFO(arginfo_imagestring, 0)
650 	ZEND_ARG_INFO(0, im)
651 	ZEND_ARG_INFO(0, font)
652 	ZEND_ARG_INFO(0, x)
653 	ZEND_ARG_INFO(0, y)
654 	ZEND_ARG_INFO(0, str)
655 	ZEND_ARG_INFO(0, col)
656 ZEND_END_ARG_INFO()
657 
658 ZEND_BEGIN_ARG_INFO(arginfo_imagestringup, 0)
659 	ZEND_ARG_INFO(0, im)
660 	ZEND_ARG_INFO(0, font)
661 	ZEND_ARG_INFO(0, x)
662 	ZEND_ARG_INFO(0, y)
663 	ZEND_ARG_INFO(0, str)
664 	ZEND_ARG_INFO(0, col)
665 ZEND_END_ARG_INFO()
666 
667 ZEND_BEGIN_ARG_INFO(arginfo_imagecopy, 0)
668 	ZEND_ARG_INFO(0, dst_im)
669 	ZEND_ARG_INFO(0, src_im)
670 	ZEND_ARG_INFO(0, dst_x)
671 	ZEND_ARG_INFO(0, dst_y)
672 	ZEND_ARG_INFO(0, src_x)
673 	ZEND_ARG_INFO(0, src_y)
674 	ZEND_ARG_INFO(0, src_w)
675 	ZEND_ARG_INFO(0, src_h)
676 ZEND_END_ARG_INFO()
677 
678 ZEND_BEGIN_ARG_INFO(arginfo_imagecopymerge, 0)
679 	ZEND_ARG_INFO(0, dst_im)
680 	ZEND_ARG_INFO(0, src_im)
681 	ZEND_ARG_INFO(0, dst_x)
682 	ZEND_ARG_INFO(0, dst_y)
683 	ZEND_ARG_INFO(0, src_x)
684 	ZEND_ARG_INFO(0, src_y)
685 	ZEND_ARG_INFO(0, src_w)
686 	ZEND_ARG_INFO(0, src_h)
687 	ZEND_ARG_INFO(0, pct)
688 ZEND_END_ARG_INFO()
689 
690 ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergegray, 0)
691 	ZEND_ARG_INFO(0, dst_im)
692 	ZEND_ARG_INFO(0, src_im)
693 	ZEND_ARG_INFO(0, dst_x)
694 	ZEND_ARG_INFO(0, dst_y)
695 	ZEND_ARG_INFO(0, src_x)
696 	ZEND_ARG_INFO(0, src_y)
697 	ZEND_ARG_INFO(0, src_w)
698 	ZEND_ARG_INFO(0, src_h)
699 	ZEND_ARG_INFO(0, pct)
700 ZEND_END_ARG_INFO()
701 
702 ZEND_BEGIN_ARG_INFO(arginfo_imagecopyresized, 0)
703 	ZEND_ARG_INFO(0, dst_im)
704 	ZEND_ARG_INFO(0, src_im)
705 	ZEND_ARG_INFO(0, dst_x)
706 	ZEND_ARG_INFO(0, dst_y)
707 	ZEND_ARG_INFO(0, src_x)
708 	ZEND_ARG_INFO(0, src_y)
709 	ZEND_ARG_INFO(0, dst_w)
710 	ZEND_ARG_INFO(0, dst_h)
711 	ZEND_ARG_INFO(0, src_w)
712 	ZEND_ARG_INFO(0, src_h)
713 ZEND_END_ARG_INFO()
714 
715 ZEND_BEGIN_ARG_INFO(arginfo_imagesx, 0)
716 	ZEND_ARG_INFO(0, im)
717 ZEND_END_ARG_INFO()
718 
719 ZEND_BEGIN_ARG_INFO(arginfo_imagesy, 0)
720 	ZEND_ARG_INFO(0, im)
721 ZEND_END_ARG_INFO()
722 
723 ZEND_BEGIN_ARG_INFO(arginfo_imagesetclip, 0)
724 	ZEND_ARG_INFO(0, im)
725 	ZEND_ARG_INFO(0, x1)
726 	ZEND_ARG_INFO(0, y1)
727 	ZEND_ARG_INFO(0, x2)
728 	ZEND_ARG_INFO(0, y2)
729 ZEND_END_ARG_INFO()
730 
731 ZEND_BEGIN_ARG_INFO(arginfo_imagegetclip, 0)
732 	ZEND_ARG_INFO(0, im)
733 ZEND_END_ARG_INFO()
734 
735 #ifdef HAVE_GD_FREETYPE
736 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageftbbox, 0, 0, 4)
737 	ZEND_ARG_INFO(0, size)
738 	ZEND_ARG_INFO(0, angle)
739 	ZEND_ARG_INFO(0, font_file)
740 	ZEND_ARG_INFO(0, text)
741 	ZEND_ARG_INFO(0, extrainfo) /* ARRAY_INFO(0, extrainfo, 0) */
742 ZEND_END_ARG_INFO()
743 
744 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagefttext, 0, 0, 8)
745 	ZEND_ARG_INFO(0, im)
746 	ZEND_ARG_INFO(0, size)
747 	ZEND_ARG_INFO(0, angle)
748 	ZEND_ARG_INFO(0, x)
749 	ZEND_ARG_INFO(0, y)
750 	ZEND_ARG_INFO(0, col)
751 	ZEND_ARG_INFO(0, font_file)
752 	ZEND_ARG_INFO(0, text)
753 	ZEND_ARG_INFO(0, extrainfo) /* ARRAY_INFO(0, extrainfo, 0) */
754 ZEND_END_ARG_INFO()
755 
756 ZEND_BEGIN_ARG_INFO(arginfo_imagettfbbox, 0)
757 	ZEND_ARG_INFO(0, size)
758 	ZEND_ARG_INFO(0, angle)
759 	ZEND_ARG_INFO(0, font_file)
760 	ZEND_ARG_INFO(0, text)
761 ZEND_END_ARG_INFO()
762 
763 ZEND_BEGIN_ARG_INFO(arginfo_imagettftext, 0)
764 	ZEND_ARG_INFO(0, im)
765 	ZEND_ARG_INFO(0, size)
766 	ZEND_ARG_INFO(0, angle)
767 	ZEND_ARG_INFO(0, x)
768 	ZEND_ARG_INFO(0, y)
769 	ZEND_ARG_INFO(0, col)
770 	ZEND_ARG_INFO(0, font_file)
771 	ZEND_ARG_INFO(0, text)
772 ZEND_END_ARG_INFO()
773 #endif
774 
775 ZEND_BEGIN_ARG_INFO_EX(arginfo_image2wbmp, 0, 0, 1)
776 	ZEND_ARG_INFO(0, im)
777 	ZEND_ARG_INFO(0, filename)
778 	ZEND_ARG_INFO(0, foreground)
779 ZEND_END_ARG_INFO()
780 
781 #if defined(HAVE_GD_JPG)
782 ZEND_BEGIN_ARG_INFO(arginfo_jpeg2wbmp, 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 #if defined(HAVE_GD_PNG)
792 ZEND_BEGIN_ARG_INFO(arginfo_png2wbmp, 0)
793 	ZEND_ARG_INFO(0, f_org)
794 	ZEND_ARG_INFO(0, f_dest)
795 	ZEND_ARG_INFO(0, d_height)
796 	ZEND_ARG_INFO(0, d_width)
797 	ZEND_ARG_INFO(0, d_threshold)
798 ZEND_END_ARG_INFO()
799 #endif
800 
801 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagefilter, 0, 0, 2)
802 	ZEND_ARG_INFO(0, im)
803 	ZEND_ARG_INFO(0, filtertype)
804 	ZEND_ARG_INFO(0, arg1)
805 	ZEND_ARG_INFO(0, arg2)
806 	ZEND_ARG_INFO(0, arg3)
807 	ZEND_ARG_INFO(0, arg4)
808 ZEND_END_ARG_INFO()
809 
810 ZEND_BEGIN_ARG_INFO(arginfo_imageconvolution, 0)
811 	ZEND_ARG_INFO(0, im)
812 	ZEND_ARG_INFO(0, matrix3x3) /* ARRAY_INFO(0, matrix3x3, 0) */
813 	ZEND_ARG_INFO(0, div)
814 	ZEND_ARG_INFO(0, offset)
815 ZEND_END_ARG_INFO()
816 
817 ZEND_BEGIN_ARG_INFO(arginfo_imageflip, 0)
818 	ZEND_ARG_INFO(0, im)
819 	ZEND_ARG_INFO(0, mode)
820 ZEND_END_ARG_INFO()
821 
822 ZEND_BEGIN_ARG_INFO(arginfo_imageantialias, 0)
823 	ZEND_ARG_INFO(0, im)
824 	ZEND_ARG_INFO(0, on)
825 ZEND_END_ARG_INFO()
826 
827 ZEND_BEGIN_ARG_INFO(arginfo_imagecrop, 0)
828 	ZEND_ARG_INFO(0, im)
829 	ZEND_ARG_INFO(0, rect)
830 ZEND_END_ARG_INFO()
831 
832 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecropauto, 0, 0, 1)
833 	ZEND_ARG_INFO(0, im)
834 	ZEND_ARG_INFO(0, mode)
835 	ZEND_ARG_INFO(0, threshold)
836 	ZEND_ARG_INFO(0, color)
837 ZEND_END_ARG_INFO()
838 
839 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagescale, 0, 0, 2)
840 	ZEND_ARG_INFO(0, im)
841 	ZEND_ARG_INFO(0, new_width)
842 	ZEND_ARG_INFO(0, new_height)
843 	ZEND_ARG_INFO(0, mode)
844 ZEND_END_ARG_INFO()
845 
846 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageaffine, 0, 0, 2)
847 	ZEND_ARG_INFO(0, im)
848 	ZEND_ARG_INFO(0, affine)
849 	ZEND_ARG_INFO(0, clip)
850 ZEND_END_ARG_INFO()
851 
852 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageaffinematrixget, 0, 0, 1)
853 	ZEND_ARG_INFO(0, type)
854 	ZEND_ARG_INFO(0, options)
855 ZEND_END_ARG_INFO()
856 
857 ZEND_BEGIN_ARG_INFO(arginfo_imageaffinematrixconcat, 0)
858 	ZEND_ARG_INFO(0, m1)
859 	ZEND_ARG_INFO(0, m2)
860 ZEND_END_ARG_INFO()
861 
862 ZEND_BEGIN_ARG_INFO_EX(arginfo_imagesetinterpolation, 0, 0, 1)
863 	ZEND_ARG_INFO(0, im)
864 	ZEND_ARG_INFO(0, method)
865 ZEND_END_ARG_INFO()
866 
867 ZEND_BEGIN_ARG_INFO_EX(arginfo_imageresolution, 0, 0, 1)
868 	ZEND_ARG_INFO(0, im)
869 	ZEND_ARG_INFO(0, res_x)
870 	ZEND_ARG_INFO(0, res_y)
871 ZEND_END_ARG_INFO()
872 
873 /* }}} */
874 
875 /* {{{ gd_functions[]
876  */
877 static const zend_function_entry gd_functions[] = {
878 	PHP_FE(gd_info,                                 arginfo_gd_info)
879 	PHP_FE(imagearc,								arginfo_imagearc)
880 	PHP_FE(imageellipse,							arginfo_imageellipse)
881 	PHP_FE(imagechar,								arginfo_imagechar)
882 	PHP_FE(imagecharup,								arginfo_imagecharup)
883 	PHP_FE(imagecolorat,							arginfo_imagecolorat)
884 	PHP_FE(imagecolorallocate,						arginfo_imagecolorallocate)
885 	PHP_FE(imagepalettecopy,						arginfo_imagepalettecopy)
886 	PHP_FE(imagecreatefromstring,					arginfo_imagecreatefromstring)
887 	PHP_FE(imagecolorclosest,						arginfo_imagecolorclosest)
888 	PHP_FE(imagecolorclosesthwb,					arginfo_imagecolorclosesthwb)
889 	PHP_FE(imagecolordeallocate,					arginfo_imagecolordeallocate)
890 	PHP_FE(imagecolorresolve,						arginfo_imagecolorresolve)
891 	PHP_FE(imagecolorexact,							arginfo_imagecolorexact)
892 	PHP_FE(imagecolorset,							arginfo_imagecolorset)
893 	PHP_FE(imagecolortransparent,					arginfo_imagecolortransparent)
894 	PHP_FE(imagecolorstotal,						arginfo_imagecolorstotal)
895 	PHP_FE(imagecolorsforindex,						arginfo_imagecolorsforindex)
896 	PHP_FE(imagecopy,								arginfo_imagecopy)
897 	PHP_FE(imagecopymerge,							arginfo_imagecopymerge)
898 	PHP_FE(imagecopymergegray,						arginfo_imagecopymergegray)
899 	PHP_FE(imagecopyresized,						arginfo_imagecopyresized)
900 	PHP_FE(imagecreate,								arginfo_imagecreate)
901 	PHP_FE(imagecreatetruecolor,					arginfo_imagecreatetruecolor)
902 	PHP_FE(imageistruecolor,						arginfo_imageistruecolor)
903 	PHP_FE(imagetruecolortopalette,					arginfo_imagetruecolortopalette)
904 	PHP_FE(imagepalettetotruecolor,					arginfo_imagepalettetotruecolor)
905 	PHP_FE(imagesetthickness,						arginfo_imagesetthickness)
906 	PHP_FE(imagefilledarc,							arginfo_imagefilledarc)
907 	PHP_FE(imagefilledellipse,						arginfo_imagefilledellipse)
908 	PHP_FE(imagealphablending,						arginfo_imagealphablending)
909 	PHP_FE(imagesavealpha,							arginfo_imagesavealpha)
910 	PHP_FE(imagecolorallocatealpha,					arginfo_imagecolorallocatealpha)
911 	PHP_FE(imagecolorresolvealpha, 					arginfo_imagecolorresolvealpha)
912 	PHP_FE(imagecolorclosestalpha,					arginfo_imagecolorclosestalpha)
913 	PHP_FE(imagecolorexactalpha,					arginfo_imagecolorexactalpha)
914 	PHP_FE(imagecopyresampled,						arginfo_imagecopyresampled)
915 
916 #ifdef PHP_WIN32
917 	PHP_FE(imagegrabwindow,							arginfo_imagegrabwindow)
918 	PHP_FE(imagegrabscreen,							arginfo_imagegrabscreen)
919 #endif
920 
921 	PHP_FE(imagerotate,     						arginfo_imagerotate)
922 	PHP_FE(imageflip,								arginfo_imageflip)
923 
924 	PHP_FE(imageantialias,							arginfo_imageantialias)
925 	PHP_FE(imagecrop,								arginfo_imagecrop)
926 	PHP_FE(imagecropauto,							arginfo_imagecropauto)
927 	PHP_FE(imagescale,								arginfo_imagescale)
928 	PHP_FE(imageaffine,								arginfo_imageaffine)
929 	PHP_FE(imageaffinematrixconcat,					arginfo_imageaffinematrixconcat)
930 	PHP_FE(imageaffinematrixget,					arginfo_imageaffinematrixget)
931 	PHP_FE(imagesetinterpolation,                   arginfo_imagesetinterpolation)
932 	PHP_FE(imagesettile,							arginfo_imagesettile)
933 	PHP_FE(imagesetbrush,							arginfo_imagesetbrush)
934 	PHP_FE(imagesetstyle,							arginfo_imagesetstyle)
935 
936 #ifdef HAVE_GD_PNG
937 	PHP_FE(imagecreatefrompng,						arginfo_imagecreatefrompng)
938 #endif
939 #ifdef HAVE_GD_WEBP
940 	PHP_FE(imagecreatefromwebp,						arginfo_imagecreatefromwebp)
941 #endif
942 	PHP_FE(imagecreatefromgif,						arginfo_imagecreatefromgif)
943 #ifdef HAVE_GD_JPG
944 	PHP_FE(imagecreatefromjpeg,						arginfo_imagecreatefromjpeg)
945 #endif
946 	PHP_FE(imagecreatefromwbmp,						arginfo_imagecreatefromwbmp)
947 	PHP_FE(imagecreatefromxbm,						arginfo_imagecreatefromxbm)
948 #if defined(HAVE_XPM) && defined(HAVE_GD_XPM)
949 	PHP_FE(imagecreatefromxpm,						arginfo_imagecreatefromxpm)
950 #endif
951 	PHP_FE(imagecreatefromgd,						arginfo_imagecreatefromgd)
952 	PHP_FE(imagecreatefromgd2,						arginfo_imagecreatefromgd2)
953 	PHP_FE(imagecreatefromgd2part,					arginfo_imagecreatefromgd2part)
954 #ifdef HAVE_GD_BMP
955 	PHP_FE(imagecreatefrombmp,						arginfo_imagecreatefrombmp)
956 #endif
957 #ifdef HAVE_GD_TGA
958 	PHP_FE(imagecreatefromtga,						arginfo_imagecreatefromtga)
959 #endif
960 #ifdef HAVE_GD_PNG
961 	PHP_FE(imagepng,								arginfo_imagepng)
962 #endif
963 #ifdef HAVE_GD_WEBP
964 	PHP_FE(imagewebp,								arginfo_imagewebp)
965 #endif
966 	PHP_FE(imagegif,								arginfo_imagegif)
967 #ifdef HAVE_GD_JPG
968 	PHP_FE(imagejpeg,								arginfo_imagejpeg)
969 #endif
970 	PHP_FE(imagewbmp,                               arginfo_imagewbmp)
971 	PHP_FE(imagegd,									arginfo_imagegd)
972 	PHP_FE(imagegd2,								arginfo_imagegd2)
973 #ifdef HAVE_GD_BMP
974 	PHP_FE(imagebmp,								arginfo_imagebmp)
975 #endif
976 
977 	PHP_FE(imagedestroy,							arginfo_imagedestroy)
978 	PHP_FE(imagegammacorrect,						arginfo_imagegammacorrect)
979 	PHP_FE(imagefill,								arginfo_imagefill)
980 	PHP_FE(imagefilledpolygon,						arginfo_imagefilledpolygon)
981 	PHP_FE(imagefilledrectangle,					arginfo_imagefilledrectangle)
982 	PHP_FE(imagefilltoborder,						arginfo_imagefilltoborder)
983 	PHP_FE(imagefontwidth,							arginfo_imagefontwidth)
984 	PHP_FE(imagefontheight,							arginfo_imagefontheight)
985 	PHP_FE(imageinterlace,							arginfo_imageinterlace)
986 	PHP_FE(imageline,								arginfo_imageline)
987 	PHP_FE(imageloadfont,							arginfo_imageloadfont)
988 	PHP_FE(imagepolygon,							arginfo_imagepolygon)
989 	PHP_FE(imageopenpolygon,						arginfo_imageopenpolygon)
990 	PHP_FE(imagerectangle,							arginfo_imagerectangle)
991 	PHP_FE(imagesetpixel,							arginfo_imagesetpixel)
992 	PHP_FE(imagestring,								arginfo_imagestring)
993 	PHP_FE(imagestringup,							arginfo_imagestringup)
994 	PHP_FE(imagesx,									arginfo_imagesx)
995 	PHP_FE(imagesy,									arginfo_imagesy)
996 	PHP_FE(imagesetclip,							arginfo_imagesetclip)
997 	PHP_FE(imagegetclip,							arginfo_imagegetclip)
998 	PHP_FE(imagedashedline,							arginfo_imagedashedline)
999 
1000 #ifdef HAVE_GD_FREETYPE
1001 	PHP_FE(imagettfbbox,							arginfo_imagettfbbox)
1002 	PHP_FE(imagettftext,							arginfo_imagettftext)
1003 	PHP_FE(imageftbbox,								arginfo_imageftbbox)
1004 	PHP_FE(imagefttext,								arginfo_imagefttext)
1005 #endif
1006 
1007 	PHP_FE(imagetypes,								arginfo_imagetypes)
1008 
1009 #if defined(HAVE_GD_JPG)
1010 	PHP_DEP_FE(jpeg2wbmp,							arginfo_jpeg2wbmp)
1011 #endif
1012 #if defined(HAVE_GD_PNG)
1013 	PHP_DEP_FE(png2wbmp,							arginfo_png2wbmp)
1014 #endif
1015 	PHP_DEP_FE(image2wbmp,							arginfo_image2wbmp)
1016 	PHP_FE(imagelayereffect,						arginfo_imagelayereffect)
1017 	PHP_FE(imagexbm,                                arginfo_imagexbm)
1018 
1019 	PHP_FE(imagecolormatch,							arginfo_imagecolormatch)
1020 
1021 /* gd filters */
1022 	PHP_FE(imagefilter,     						arginfo_imagefilter)
1023 	PHP_FE(imageconvolution,						arginfo_imageconvolution)
1024 
1025 	PHP_FE(imageresolution,							arginfo_imageresolution)
1026 
1027 	PHP_FE_END
1028 };
1029 /* }}} */
1030 
1031 zend_module_entry gd_module_entry = {
1032 	STANDARD_MODULE_HEADER,
1033 	"gd",
1034 	gd_functions,
1035 	PHP_MINIT(gd),
1036 	PHP_MSHUTDOWN(gd),
1037 	NULL,
1038 	PHP_RSHUTDOWN(gd),
1039 	PHP_MINFO(gd),
1040 	PHP_GD_VERSION,
1041 	STANDARD_MODULE_PROPERTIES
1042 };
1043 
1044 #ifdef COMPILE_DL_GD
1045 ZEND_GET_MODULE(gd)
1046 #endif
1047 
1048 /* {{{ PHP_INI_BEGIN */
PHP_INI_BEGIN()1049 PHP_INI_BEGIN()
1050 	PHP_INI_ENTRY("gd.jpeg_ignore_warning", "1", PHP_INI_ALL, NULL)
1051 PHP_INI_END()
1052 /* }}} */
1053 
1054 /* {{{ php_free_gd_image
1055  */
1056 static void php_free_gd_image(zend_resource *rsrc)
1057 {
1058 	gdImageDestroy((gdImagePtr) rsrc->ptr);
1059 }
1060 /* }}} */
1061 
1062 /* {{{ php_free_gd_font
1063  */
php_free_gd_font(zend_resource * rsrc)1064 static void php_free_gd_font(zend_resource *rsrc)
1065 {
1066 	gdFontPtr fp = (gdFontPtr) rsrc->ptr;
1067 
1068 	if (fp->data) {
1069 		efree(fp->data);
1070 	}
1071 
1072 	efree(fp);
1073 }
1074 /* }}} */
1075 
1076 /* {{{ php_gd_error_method
1077  */
php_gd_error_method(int type,const char * format,va_list args)1078 void php_gd_error_method(int type, const char *format, va_list args)
1079 {
1080 
1081 	switch (type) {
1082 #ifndef PHP_WIN32
1083 		case GD_DEBUG:
1084 		case GD_INFO:
1085 #endif
1086 		case GD_NOTICE:
1087 			type = E_NOTICE;
1088 			break;
1089 		case GD_WARNING:
1090 			type = E_WARNING;
1091 			break;
1092 		default:
1093 			type = E_ERROR;
1094 	}
1095 	php_verror(NULL, "", type, format, args);
1096 }
1097 /* }}} */
1098 
1099 /* {{{ PHP_MINIT_FUNCTION
1100  */
PHP_MINIT_FUNCTION(gd)1101 PHP_MINIT_FUNCTION(gd)
1102 {
1103 	le_gd = zend_register_list_destructors_ex(php_free_gd_image, NULL, "gd", module_number);
1104 	le_gd_font = zend_register_list_destructors_ex(php_free_gd_font, NULL, "gd font", module_number);
1105 
1106 #if defined(HAVE_GD_FREETYPE) && defined(HAVE_GD_BUNDLED)
1107 	gdFontCacheMutexSetup();
1108 #endif
1109 	gdSetErrorMethod(php_gd_error_method);
1110 
1111 	REGISTER_INI_ENTRIES();
1112 
1113 	REGISTER_LONG_CONSTANT("IMG_GIF", PHP_IMG_GIF, CONST_CS | CONST_PERSISTENT);
1114 	REGISTER_LONG_CONSTANT("IMG_JPG", PHP_IMG_JPG, CONST_CS | CONST_PERSISTENT);
1115 	REGISTER_LONG_CONSTANT("IMG_JPEG", PHP_IMG_JPEG, CONST_CS | CONST_PERSISTENT);
1116 	REGISTER_LONG_CONSTANT("IMG_PNG", PHP_IMG_PNG, CONST_CS | CONST_PERSISTENT);
1117 	REGISTER_LONG_CONSTANT("IMG_WBMP", PHP_IMG_WBMP, CONST_CS | CONST_PERSISTENT);
1118 	REGISTER_LONG_CONSTANT("IMG_XPM", PHP_IMG_XPM, CONST_CS | CONST_PERSISTENT);
1119 	REGISTER_LONG_CONSTANT("IMG_WEBP", PHP_IMG_WEBP, CONST_CS | CONST_PERSISTENT);
1120 	REGISTER_LONG_CONSTANT("IMG_BMP", PHP_IMG_BMP, CONST_CS | CONST_PERSISTENT);
1121 	REGISTER_LONG_CONSTANT("IMG_TGA", PHP_IMG_TGA, CONST_CS | CONST_PERSISTENT);
1122 
1123 	/* special colours for gd */
1124 	REGISTER_LONG_CONSTANT("IMG_COLOR_TILED", gdTiled, CONST_CS | CONST_PERSISTENT);
1125 	REGISTER_LONG_CONSTANT("IMG_COLOR_STYLED", gdStyled, CONST_CS | CONST_PERSISTENT);
1126 	REGISTER_LONG_CONSTANT("IMG_COLOR_BRUSHED", gdBrushed, CONST_CS | CONST_PERSISTENT);
1127 	REGISTER_LONG_CONSTANT("IMG_COLOR_STYLEDBRUSHED", gdStyledBrushed, CONST_CS | CONST_PERSISTENT);
1128 	REGISTER_LONG_CONSTANT("IMG_COLOR_TRANSPARENT", gdTransparent, CONST_CS | CONST_PERSISTENT);
1129 
1130 	/* for imagefilledarc */
1131 	REGISTER_LONG_CONSTANT("IMG_ARC_ROUNDED", gdArc, CONST_CS | CONST_PERSISTENT);
1132 	REGISTER_LONG_CONSTANT("IMG_ARC_PIE", gdPie, CONST_CS | CONST_PERSISTENT);
1133 	REGISTER_LONG_CONSTANT("IMG_ARC_CHORD", gdChord, CONST_CS | CONST_PERSISTENT);
1134 	REGISTER_LONG_CONSTANT("IMG_ARC_NOFILL", gdNoFill, CONST_CS | CONST_PERSISTENT);
1135 	REGISTER_LONG_CONSTANT("IMG_ARC_EDGED", gdEdged, CONST_CS | CONST_PERSISTENT);
1136 
1137     /* GD2 image format types */
1138 	REGISTER_LONG_CONSTANT("IMG_GD2_RAW", GD2_FMT_RAW, CONST_CS | CONST_PERSISTENT);
1139 	REGISTER_LONG_CONSTANT("IMG_GD2_COMPRESSED", GD2_FMT_COMPRESSED, CONST_CS | CONST_PERSISTENT);
1140 	REGISTER_LONG_CONSTANT("IMG_FLIP_HORIZONTAL", GD_FLIP_HORINZONTAL, CONST_CS | CONST_PERSISTENT);
1141 	REGISTER_LONG_CONSTANT("IMG_FLIP_VERTICAL", GD_FLIP_VERTICAL, CONST_CS | CONST_PERSISTENT);
1142 	REGISTER_LONG_CONSTANT("IMG_FLIP_BOTH", GD_FLIP_BOTH, CONST_CS | CONST_PERSISTENT);
1143 	REGISTER_LONG_CONSTANT("IMG_EFFECT_REPLACE", gdEffectReplace, CONST_CS | CONST_PERSISTENT);
1144 	REGISTER_LONG_CONSTANT("IMG_EFFECT_ALPHABLEND", gdEffectAlphaBlend, CONST_CS | CONST_PERSISTENT);
1145 	REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT);
1146 	REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT);
1147 #ifdef gdEffectMultiply
1148 	REGISTER_LONG_CONSTANT("IMG_EFFECT_MULTIPLY", gdEffectMultiply, CONST_CS | CONST_PERSISTENT);
1149 #endif
1150 
1151 	REGISTER_LONG_CONSTANT("IMG_CROP_DEFAULT", GD_CROP_DEFAULT, CONST_CS | CONST_PERSISTENT);
1152 	REGISTER_LONG_CONSTANT("IMG_CROP_TRANSPARENT", GD_CROP_TRANSPARENT, CONST_CS | CONST_PERSISTENT);
1153 	REGISTER_LONG_CONSTANT("IMG_CROP_BLACK", GD_CROP_BLACK, CONST_CS | CONST_PERSISTENT);
1154 	REGISTER_LONG_CONSTANT("IMG_CROP_WHITE", GD_CROP_WHITE, CONST_CS | CONST_PERSISTENT);
1155 	REGISTER_LONG_CONSTANT("IMG_CROP_SIDES", GD_CROP_SIDES, CONST_CS | CONST_PERSISTENT);
1156 	REGISTER_LONG_CONSTANT("IMG_CROP_THRESHOLD", GD_CROP_THRESHOLD, CONST_CS | CONST_PERSISTENT);
1157 
1158 
1159 	REGISTER_LONG_CONSTANT("IMG_BELL", GD_BELL, CONST_CS | CONST_PERSISTENT);
1160 	REGISTER_LONG_CONSTANT("IMG_BESSEL", GD_BESSEL, CONST_CS | CONST_PERSISTENT);
1161 	REGISTER_LONG_CONSTANT("IMG_BILINEAR_FIXED", GD_BILINEAR_FIXED, CONST_CS | CONST_PERSISTENT);
1162 	REGISTER_LONG_CONSTANT("IMG_BICUBIC", GD_BICUBIC, CONST_CS | CONST_PERSISTENT);
1163 	REGISTER_LONG_CONSTANT("IMG_BICUBIC_FIXED", GD_BICUBIC_FIXED, CONST_CS | CONST_PERSISTENT);
1164 	REGISTER_LONG_CONSTANT("IMG_BLACKMAN", GD_BLACKMAN, CONST_CS | CONST_PERSISTENT);
1165 	REGISTER_LONG_CONSTANT("IMG_BOX", GD_BOX, CONST_CS | CONST_PERSISTENT);
1166 	REGISTER_LONG_CONSTANT("IMG_BSPLINE", GD_BSPLINE, CONST_CS | CONST_PERSISTENT);
1167 	REGISTER_LONG_CONSTANT("IMG_CATMULLROM", GD_CATMULLROM, CONST_CS | CONST_PERSISTENT);
1168 	REGISTER_LONG_CONSTANT("IMG_GAUSSIAN", GD_GAUSSIAN, CONST_CS | CONST_PERSISTENT);
1169 	REGISTER_LONG_CONSTANT("IMG_GENERALIZED_CUBIC", GD_GENERALIZED_CUBIC, CONST_CS | CONST_PERSISTENT);
1170 	REGISTER_LONG_CONSTANT("IMG_HERMITE", GD_HERMITE, CONST_CS | CONST_PERSISTENT);
1171 	REGISTER_LONG_CONSTANT("IMG_HAMMING", GD_HAMMING, CONST_CS | CONST_PERSISTENT);
1172 	REGISTER_LONG_CONSTANT("IMG_HANNING", GD_HANNING, CONST_CS | CONST_PERSISTENT);
1173 	REGISTER_LONG_CONSTANT("IMG_MITCHELL", GD_MITCHELL, CONST_CS | CONST_PERSISTENT);
1174 	REGISTER_LONG_CONSTANT("IMG_POWER", GD_POWER, CONST_CS | CONST_PERSISTENT);
1175 	REGISTER_LONG_CONSTANT("IMG_QUADRATIC", GD_QUADRATIC, CONST_CS | CONST_PERSISTENT);
1176 	REGISTER_LONG_CONSTANT("IMG_SINC", GD_SINC, CONST_CS | CONST_PERSISTENT);
1177 	REGISTER_LONG_CONSTANT("IMG_NEAREST_NEIGHBOUR", GD_NEAREST_NEIGHBOUR, CONST_CS | CONST_PERSISTENT);
1178 	REGISTER_LONG_CONSTANT("IMG_WEIGHTED4", GD_WEIGHTED4, CONST_CS | CONST_PERSISTENT);
1179 	REGISTER_LONG_CONSTANT("IMG_TRIANGLE", GD_TRIANGLE, CONST_CS | CONST_PERSISTENT);
1180 
1181 	REGISTER_LONG_CONSTANT("IMG_AFFINE_TRANSLATE", GD_AFFINE_TRANSLATE, CONST_CS | CONST_PERSISTENT);
1182 	REGISTER_LONG_CONSTANT("IMG_AFFINE_SCALE", GD_AFFINE_SCALE, CONST_CS | CONST_PERSISTENT);
1183 	REGISTER_LONG_CONSTANT("IMG_AFFINE_ROTATE", GD_AFFINE_ROTATE, CONST_CS | CONST_PERSISTENT);
1184 	REGISTER_LONG_CONSTANT("IMG_AFFINE_SHEAR_HORIZONTAL", GD_AFFINE_SHEAR_HORIZONTAL, CONST_CS | CONST_PERSISTENT);
1185 	REGISTER_LONG_CONSTANT("IMG_AFFINE_SHEAR_VERTICAL", GD_AFFINE_SHEAR_VERTICAL, CONST_CS | CONST_PERSISTENT);
1186 
1187 #if defined(HAVE_GD_BUNDLED)
1188 	REGISTER_LONG_CONSTANT("GD_BUNDLED", 1, CONST_CS | CONST_PERSISTENT);
1189 #else
1190 	REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT);
1191 #endif
1192 
1193 	/* Section Filters */
1194 	REGISTER_LONG_CONSTANT("IMG_FILTER_NEGATE", IMAGE_FILTER_NEGATE, CONST_CS | CONST_PERSISTENT);
1195 	REGISTER_LONG_CONSTANT("IMG_FILTER_GRAYSCALE", IMAGE_FILTER_GRAYSCALE, CONST_CS | CONST_PERSISTENT);
1196 	REGISTER_LONG_CONSTANT("IMG_FILTER_BRIGHTNESS", IMAGE_FILTER_BRIGHTNESS, CONST_CS | CONST_PERSISTENT);
1197 	REGISTER_LONG_CONSTANT("IMG_FILTER_CONTRAST", IMAGE_FILTER_CONTRAST, CONST_CS | CONST_PERSISTENT);
1198 	REGISTER_LONG_CONSTANT("IMG_FILTER_COLORIZE", IMAGE_FILTER_COLORIZE, CONST_CS | CONST_PERSISTENT);
1199 	REGISTER_LONG_CONSTANT("IMG_FILTER_EDGEDETECT", IMAGE_FILTER_EDGEDETECT, CONST_CS | CONST_PERSISTENT);
1200 	REGISTER_LONG_CONSTANT("IMG_FILTER_GAUSSIAN_BLUR", IMAGE_FILTER_GAUSSIAN_BLUR, CONST_CS | CONST_PERSISTENT);
1201 	REGISTER_LONG_CONSTANT("IMG_FILTER_SELECTIVE_BLUR", IMAGE_FILTER_SELECTIVE_BLUR, CONST_CS | CONST_PERSISTENT);
1202 	REGISTER_LONG_CONSTANT("IMG_FILTER_EMBOSS", IMAGE_FILTER_EMBOSS, CONST_CS | CONST_PERSISTENT);
1203 	REGISTER_LONG_CONSTANT("IMG_FILTER_MEAN_REMOVAL", IMAGE_FILTER_MEAN_REMOVAL, CONST_CS | CONST_PERSISTENT);
1204 	REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_CS | CONST_PERSISTENT);
1205 	REGISTER_LONG_CONSTANT("IMG_FILTER_PIXELATE", IMAGE_FILTER_PIXELATE, CONST_CS | CONST_PERSISTENT);
1206 	REGISTER_LONG_CONSTANT("IMG_FILTER_SCATTER", IMAGE_FILTER_SCATTER, CONST_CS | CONST_PERSISTENT);
1207 	/* End Section Filters */
1208 
1209 #ifdef GD_VERSION_STRING
1210 	REGISTER_STRING_CONSTANT("GD_VERSION", GD_VERSION_STRING, CONST_CS | CONST_PERSISTENT);
1211 #endif
1212 
1213 #if defined(GD_MAJOR_VERSION) && defined(GD_MINOR_VERSION) && defined(GD_RELEASE_VERSION) && defined(GD_EXTRA_VERSION)
1214 	REGISTER_LONG_CONSTANT("GD_MAJOR_VERSION", GD_MAJOR_VERSION, CONST_CS | CONST_PERSISTENT);
1215 	REGISTER_LONG_CONSTANT("GD_MINOR_VERSION", GD_MINOR_VERSION, CONST_CS | CONST_PERSISTENT);
1216 	REGISTER_LONG_CONSTANT("GD_RELEASE_VERSION", GD_RELEASE_VERSION, CONST_CS | CONST_PERSISTENT);
1217 	REGISTER_STRING_CONSTANT("GD_EXTRA_VERSION", GD_EXTRA_VERSION, CONST_CS | CONST_PERSISTENT);
1218 #endif
1219 
1220 
1221 #ifdef HAVE_GD_PNG
1222 
1223 	/*
1224 	 * cannot include #include "png.h"
1225 	 * /usr/include/pngconf.h:310:2: error: #error png.h already includes setjmp.h with some additional fixup.
1226 	 * as error, use the values for now...
1227 	 */
1228 	REGISTER_LONG_CONSTANT("PNG_NO_FILTER",	    0x00, CONST_CS | CONST_PERSISTENT);
1229 	REGISTER_LONG_CONSTANT("PNG_FILTER_NONE",   0x08, CONST_CS | CONST_PERSISTENT);
1230 	REGISTER_LONG_CONSTANT("PNG_FILTER_SUB",    0x10, CONST_CS | CONST_PERSISTENT);
1231 	REGISTER_LONG_CONSTANT("PNG_FILTER_UP",     0x20, CONST_CS | CONST_PERSISTENT);
1232 	REGISTER_LONG_CONSTANT("PNG_FILTER_AVG",    0x40, CONST_CS | CONST_PERSISTENT);
1233 	REGISTER_LONG_CONSTANT("PNG_FILTER_PAETH",  0x80, CONST_CS | CONST_PERSISTENT);
1234 	REGISTER_LONG_CONSTANT("PNG_ALL_FILTERS",   0x08 | 0x10 | 0x20 | 0x40 | 0x80, CONST_CS | CONST_PERSISTENT);
1235 #endif
1236 
1237 	return SUCCESS;
1238 }
1239 /* }}} */
1240 
1241 /* {{{ PHP_MSHUTDOWN_FUNCTION
1242  */
PHP_MSHUTDOWN_FUNCTION(gd)1243 PHP_MSHUTDOWN_FUNCTION(gd)
1244 {
1245 #if defined(HAVE_GD_FREETYPE) && defined(HAVE_GD_BUNDLED)
1246 	gdFontCacheMutexShutdown();
1247 #endif
1248 	UNREGISTER_INI_ENTRIES();
1249 	return SUCCESS;
1250 }
1251 /* }}} */
1252 
1253 /* {{{ PHP_RSHUTDOWN_FUNCTION
1254  */
PHP_RSHUTDOWN_FUNCTION(gd)1255 PHP_RSHUTDOWN_FUNCTION(gd)
1256 {
1257 #ifdef HAVE_GD_FREETYPE
1258 	gdFontCacheShutdown();
1259 #endif
1260 	return SUCCESS;
1261 }
1262 /* }}} */
1263 
1264 #if defined(HAVE_GD_BUNDLED)
1265 #define PHP_GD_VERSION_STRING "bundled (2.1.0 compatible)"
1266 #else
1267 # define PHP_GD_VERSION_STRING GD_VERSION_STRING
1268 #endif
1269 
1270 /* {{{ PHP_MINFO_FUNCTION
1271  */
PHP_MINFO_FUNCTION(gd)1272 PHP_MINFO_FUNCTION(gd)
1273 {
1274 	php_info_print_table_start();
1275 	php_info_print_table_row(2, "GD Support", "enabled");
1276 
1277 	/* need to use a PHPAPI function here because it is external module in windows */
1278 
1279 #if defined(HAVE_GD_BUNDLED)
1280 	php_info_print_table_row(2, "GD Version", PHP_GD_VERSION_STRING);
1281 #else
1282 	php_info_print_table_row(2, "GD headers Version", PHP_GD_VERSION_STRING);
1283 #if defined(HAVE_GD_LIBVERSION)
1284 	php_info_print_table_row(2, "GD library Version", gdVersionString());
1285 #endif
1286 #endif
1287 
1288 #ifdef HAVE_GD_FREETYPE
1289 	php_info_print_table_row(2, "FreeType Support", "enabled");
1290 	php_info_print_table_row(2, "FreeType Linkage", "with freetype");
1291 #ifdef HAVE_GD_BUNDLED
1292 	{
1293 		char tmp[256];
1294 
1295 #ifdef FREETYPE_PATCH
1296 		snprintf(tmp, sizeof(tmp), "%d.%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR, FREETYPE_PATCH);
1297 #elif defined(FREETYPE_MAJOR)
1298 		snprintf(tmp, sizeof(tmp), "%d.%d", FREETYPE_MAJOR, FREETYPE_MINOR);
1299 #else
1300 		snprintf(tmp, sizeof(tmp), "1.x");
1301 #endif
1302 		php_info_print_table_row(2, "FreeType Version", tmp);
1303 	}
1304 #endif
1305 #endif
1306 
1307 	php_info_print_table_row(2, "GIF Read Support", "enabled");
1308 	php_info_print_table_row(2, "GIF Create Support", "enabled");
1309 
1310 #ifdef HAVE_GD_JPG
1311 	{
1312 		php_info_print_table_row(2, "JPEG Support", "enabled");
1313 #if defined(HAVE_GD_BUNDLED)
1314 		php_info_print_table_row(2, "libJPEG Version", gdJpegGetVersionString());
1315 #endif
1316 	}
1317 #endif
1318 
1319 #ifdef HAVE_GD_PNG
1320 	php_info_print_table_row(2, "PNG Support", "enabled");
1321 #if defined(HAVE_GD_BUNDLED)
1322 	php_info_print_table_row(2, "libPNG Version", gdPngGetVersionString());
1323 #endif
1324 #endif
1325 	php_info_print_table_row(2, "WBMP Support", "enabled");
1326 #if defined(HAVE_XPM) && defined(HAVE_GD_XPM)
1327 	php_info_print_table_row(2, "XPM Support", "enabled");
1328 #if defined(HAVE_GD_BUNDLED)
1329 	{
1330 		char tmp[12];
1331 		snprintf(tmp, sizeof(tmp), "%d", XpmLibraryVersion());
1332 		php_info_print_table_row(2, "libXpm Version", tmp);
1333 	}
1334 #endif
1335 #endif
1336 	php_info_print_table_row(2, "XBM Support", "enabled");
1337 #if defined(USE_GD_JISX0208)
1338 	php_info_print_table_row(2, "JIS-mapped Japanese Font Support", "enabled");
1339 #endif
1340 #ifdef HAVE_GD_WEBP
1341 	php_info_print_table_row(2, "WebP Support", "enabled");
1342 #endif
1343 #ifdef HAVE_GD_BMP
1344 	php_info_print_table_row(2, "BMP Support", "enabled");
1345 #endif
1346 #ifdef HAVE_GD_TGA
1347 	php_info_print_table_row(2, "TGA Read Support", "enabled");
1348 #endif
1349 	php_info_print_table_end();
1350 	DISPLAY_INI_ENTRIES();
1351 }
1352 /* }}} */
1353 
1354 /* {{{ proto array gd_info()
1355  */
PHP_FUNCTION(gd_info)1356 PHP_FUNCTION(gd_info)
1357 {
1358 	if (zend_parse_parameters_none() == FAILURE) {
1359 		return;
1360 	}
1361 
1362 	array_init(return_value);
1363 
1364 	add_assoc_string(return_value, "GD Version", PHP_GD_VERSION_STRING);
1365 
1366 #ifdef HAVE_GD_FREETYPE
1367 	add_assoc_bool(return_value, "FreeType Support", 1);
1368 	add_assoc_string(return_value, "FreeType Linkage", "with freetype");
1369 #else
1370 	add_assoc_bool(return_value, "FreeType Support", 0);
1371 #endif
1372 	add_assoc_bool(return_value, "GIF Read Support", 1);
1373 	add_assoc_bool(return_value, "GIF Create Support", 1);
1374 #ifdef HAVE_GD_JPG
1375 	add_assoc_bool(return_value, "JPEG Support", 1);
1376 #else
1377 	add_assoc_bool(return_value, "JPEG Support", 0);
1378 #endif
1379 #ifdef HAVE_GD_PNG
1380 	add_assoc_bool(return_value, "PNG Support", 1);
1381 #else
1382 	add_assoc_bool(return_value, "PNG Support", 0);
1383 #endif
1384 	add_assoc_bool(return_value, "WBMP Support", 1);
1385 #if defined(HAVE_XPM) && defined(HAVE_GD_XPM)
1386 	add_assoc_bool(return_value, "XPM Support", 1);
1387 #else
1388 	add_assoc_bool(return_value, "XPM Support", 0);
1389 #endif
1390 	add_assoc_bool(return_value, "XBM Support", 1);
1391 #ifdef HAVE_GD_WEBP
1392 	add_assoc_bool(return_value, "WebP Support", 1);
1393 #else
1394 	add_assoc_bool(return_value, "WebP Support", 0);
1395 #endif
1396 #ifdef HAVE_GD_BMP
1397 	add_assoc_bool(return_value, "BMP Support", 1);
1398 #else
1399 	add_assoc_bool(return_value, "BMP Support", 0);
1400 #endif
1401 #ifdef HAVE_GD_TGA
1402 	add_assoc_bool(return_value, "TGA Read Support", 1);
1403 #else
1404 	add_assoc_bool(return_value, "TGA Read Support", 0);
1405 #endif
1406 #if defined(USE_GD_JISX0208)
1407 	add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 1);
1408 #else
1409 	add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 0);
1410 #endif
1411 }
1412 /* }}} */
1413 
1414 /* Need this for cpdf. See also comment in file.c php3i_get_le_fp() */
phpi_get_le_gd(void)1415 PHP_GD_API int phpi_get_le_gd(void)
1416 {
1417 	return le_gd;
1418 }
1419 /* }}} */
1420 
1421 #define FLIPWORD(a) (((a & 0xff000000) >> 24) | ((a & 0x00ff0000) >> 8) | ((a & 0x0000ff00) << 8) | ((a & 0x000000ff) << 24))
1422 
1423 /* {{{ proto int imageloadfont(string filename)
1424    Load a new font */
PHP_FUNCTION(imageloadfont)1425 PHP_FUNCTION(imageloadfont)
1426 {
1427 	zval *ind;
1428 	zend_string *file;
1429 	int hdr_size = sizeof(gdFont) - sizeof(char *);
1430 	int body_size, n = 0, b, i, body_size_check;
1431 	gdFontPtr font;
1432 	php_stream *stream;
1433 
1434 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file) == FAILURE) {
1435 		return;
1436 	}
1437 
1438 	stream = php_stream_open_wrapper(ZSTR_VAL(file), "rb", IGNORE_PATH | IGNORE_URL_WIN | REPORT_ERRORS, NULL);
1439 	if (stream == NULL) {
1440 		RETURN_FALSE;
1441 	}
1442 
1443 	/* Only supports a architecture-dependent binary dump format
1444 	 * at the moment.
1445 	 * The file format is like this on machines with 32-byte integers:
1446 	 *
1447 	 * byte 0-3:   (int) number of characters in the font
1448 	 * byte 4-7:   (int) value of first character in the font (often 32, space)
1449 	 * byte 8-11:  (int) pixel width of each character
1450 	 * byte 12-15: (int) pixel height of each character
1451 	 * bytes 16-:  (char) array with character data, one byte per pixel
1452 	 *                    in each character, for a total of
1453 	 *                    (nchars*width*height) bytes.
1454 	 */
1455 	font = (gdFontPtr) emalloc(sizeof(gdFont));
1456 	b = 0;
1457 	while (b < hdr_size && (n = php_stream_read(stream, (char*)&font[b], hdr_size - b)) > 0) {
1458 		b += n;
1459 	}
1460 
1461 	if (n <= 0) {
1462 		efree(font);
1463 		if (php_stream_eof(stream)) {
1464 			php_error_docref(NULL, E_WARNING, "End of file while reading header");
1465 		} else {
1466 			php_error_docref(NULL, E_WARNING, "Error while reading header");
1467 		}
1468 		php_stream_close(stream);
1469 		RETURN_FALSE;
1470 	}
1471 	i = php_stream_tell(stream);
1472 	php_stream_seek(stream, 0, SEEK_END);
1473 	body_size_check = php_stream_tell(stream) - hdr_size;
1474 	php_stream_seek(stream, i, SEEK_SET);
1475 
1476 	if (overflow2(font->nchars, font->h) || overflow2(font->nchars * font->h, font->w )) {
1477 		php_error_docref(NULL, E_WARNING, "Error reading font, invalid font header");
1478 		efree(font);
1479 		php_stream_close(stream);
1480 		RETURN_FALSE;
1481 	}
1482 
1483 	body_size = font->w * font->h * font->nchars;
1484 	if (body_size != body_size_check) {
1485 		font->w = FLIPWORD(font->w);
1486 		font->h = FLIPWORD(font->h);
1487 		font->nchars = FLIPWORD(font->nchars);
1488 		body_size = font->w * font->h * font->nchars;
1489 	}
1490 
1491 	if (body_size != body_size_check) {
1492 		php_error_docref(NULL, E_WARNING, "Error reading font");
1493 		efree(font);
1494 		php_stream_close(stream);
1495 		RETURN_FALSE;
1496 	}
1497 
1498 	font->data = emalloc(body_size);
1499 	b = 0;
1500 	while (b < body_size && (n = php_stream_read(stream, &font->data[b], body_size - b)) > 0) {
1501 		b += n;
1502 	}
1503 
1504 	if (n <= 0) {
1505 		efree(font->data);
1506 		efree(font);
1507 		if (php_stream_eof(stream)) {
1508 			php_error_docref(NULL, E_WARNING, "End of file while reading body");
1509 		} else {
1510 			php_error_docref(NULL, E_WARNING, "Error while reading body");
1511 		}
1512 		php_stream_close(stream);
1513 		RETURN_FALSE;
1514 	}
1515 	php_stream_close(stream);
1516 
1517 	ind = zend_list_insert(font, le_gd_font);
1518 
1519 	/* Adding 5 to the font index so we will never have font indices
1520 	 * that overlap with the old fonts (with indices 1-5).  The first
1521 	 * list index given out is always 1.
1522 	 */
1523 	RETURN_LONG(Z_RES_HANDLE_P(ind) + 5);
1524 }
1525 /* }}} */
1526 
1527 /* {{{ proto bool imagesetstyle(resource im, array styles)
1528    Set the line drawing styles for use with imageline and IMG_COLOR_STYLED. */
PHP_FUNCTION(imagesetstyle)1529 PHP_FUNCTION(imagesetstyle)
1530 {
1531 	zval *IM, *styles, *item;
1532 	gdImagePtr im;
1533 	int *stylearr;
1534 	int index = 0;
1535     uint32_t num_styles;
1536 
1537 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra", &IM, &styles) == FAILURE)  {
1538 		return;
1539 	}
1540 
1541 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1542 		RETURN_FALSE;
1543 	}
1544 
1545     num_styles = zend_hash_num_elements(Z_ARRVAL_P(styles));
1546     if (num_styles == 0) {
1547         php_error_docref(NULL, E_WARNING, "styles array must not be empty");
1548         RETURN_FALSE;
1549     }
1550 
1551 	/* copy the style values in the stylearr */
1552 	stylearr = safe_emalloc(sizeof(int), num_styles, 0);
1553 
1554 	ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(styles), item) {
1555 		stylearr[index++] = zval_get_long(item);
1556 	} ZEND_HASH_FOREACH_END();
1557 
1558 	gdImageSetStyle(im, stylearr, index);
1559 
1560 	efree(stylearr);
1561 
1562 	RETURN_TRUE;
1563 }
1564 /* }}} */
1565 
1566 /* {{{ proto resource imagecreatetruecolor(int x_size, int y_size)
1567    Create a new true color image */
PHP_FUNCTION(imagecreatetruecolor)1568 PHP_FUNCTION(imagecreatetruecolor)
1569 {
1570 	zend_long x_size, y_size;
1571 	gdImagePtr im;
1572 
1573 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &x_size, &y_size) == FAILURE) {
1574 		return;
1575 	}
1576 
1577 	if (x_size <= 0 || y_size <= 0 || x_size >= INT_MAX || y_size >= INT_MAX) {
1578 		php_error_docref(NULL, E_WARNING, "Invalid image dimensions");
1579 		RETURN_FALSE;
1580 	}
1581 
1582 	im = gdImageCreateTrueColor(x_size, y_size);
1583 
1584 	if (!im) {
1585 		RETURN_FALSE;
1586 	}
1587 
1588 	RETURN_RES(zend_register_resource(im, le_gd));
1589 }
1590 /* }}} */
1591 
1592 /* {{{ proto bool imageistruecolor(resource im)
1593    return true if the image uses truecolor */
PHP_FUNCTION(imageistruecolor)1594 PHP_FUNCTION(imageistruecolor)
1595 {
1596 	zval *IM;
1597 	gdImagePtr im;
1598 
1599 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) {
1600 		return;
1601 	}
1602 
1603 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1604 		RETURN_FALSE;
1605 	}
1606 
1607 	RETURN_BOOL(im->trueColor);
1608 }
1609 /* }}} */
1610 
1611 /* {{{ proto void imagetruecolortopalette(resource im, bool ditherFlag, int colorsWanted)
1612    Convert a true color image to a palette based image with a number of colors, optionally using dithering. */
PHP_FUNCTION(imagetruecolortopalette)1613 PHP_FUNCTION(imagetruecolortopalette)
1614 {
1615 	zval *IM;
1616 	zend_bool dither;
1617 	zend_long ncolors;
1618 	gdImagePtr im;
1619 
1620 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rbl", &IM, &dither, &ncolors) == FAILURE)  {
1621 		return;
1622 	}
1623 
1624 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1625 		RETURN_FALSE;
1626 	}
1627 
1628 	if (ncolors <= 0 || ZEND_LONG_INT_OVFL(ncolors)) {
1629 		php_error_docref(NULL, E_WARNING, "Number of colors has to be greater than zero and no more than %d", INT_MAX);
1630 		RETURN_FALSE;
1631 	}
1632 	if (gdImageTrueColorToPalette(im, dither, (int)ncolors)) {
1633 		RETURN_TRUE;
1634 	} else {
1635 		php_error_docref(NULL, E_WARNING, "Couldn't convert to palette");
1636 		RETURN_FALSE;
1637 	}
1638 }
1639 /* }}} */
1640 
1641 /* {{{ proto void imagepalettetotruecolor(resource im)
1642    Convert a palette based image to a true color image. */
PHP_FUNCTION(imagepalettetotruecolor)1643 PHP_FUNCTION(imagepalettetotruecolor)
1644 {
1645 	zval *IM;
1646 	gdImagePtr im;
1647 
1648 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE)  {
1649 		return;
1650 	}
1651 
1652 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1653 		RETURN_FALSE;
1654 	}
1655 
1656 	if (gdImagePaletteToTrueColor(im) == 0) {
1657 		RETURN_FALSE;
1658 	}
1659 
1660 	RETURN_TRUE;
1661 }
1662 /* }}} */
1663 
1664 /* {{{ proto bool imagecolormatch(resource im1, resource im2)
1665    Makes the colors of the palette version of an image more closely match the true color version */
PHP_FUNCTION(imagecolormatch)1666 PHP_FUNCTION(imagecolormatch)
1667 {
1668 	zval *IM1, *IM2;
1669 	gdImagePtr im1, im2;
1670 	int result;
1671 
1672 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &IM1, &IM2) == FAILURE) {
1673 		return;
1674 	}
1675 
1676 	if ((im1 = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM1), "Image", le_gd)) == NULL) {
1677 		RETURN_FALSE;
1678 	}
1679 	if ((im2 = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM2), "Image", le_gd)) == NULL) {
1680 		RETURN_FALSE;
1681 	}
1682 
1683 	result = gdImageColorMatch(im1, im2);
1684 	switch (result) {
1685 		case -1:
1686 			php_error_docref(NULL, E_WARNING, "Image1 must be TrueColor" );
1687 			RETURN_FALSE;
1688 			break;
1689 		case -2:
1690 			php_error_docref(NULL, E_WARNING, "Image2 must be Palette" );
1691 			RETURN_FALSE;
1692 			break;
1693 		case -3:
1694 			php_error_docref(NULL, E_WARNING, "Image1 and Image2 must be the same size" );
1695 			RETURN_FALSE;
1696 			break;
1697 		case -4:
1698 			php_error_docref(NULL, E_WARNING, "Image2 must have at least one color" );
1699 			RETURN_FALSE;
1700 			break;
1701 	}
1702 
1703 	RETURN_TRUE;
1704 }
1705 /* }}} */
1706 
1707 /* {{{ proto bool imagesetthickness(resource im, int thickness)
1708    Set line thickness for drawing lines, ellipses, rectangles, polygons etc. */
PHP_FUNCTION(imagesetthickness)1709 PHP_FUNCTION(imagesetthickness)
1710 {
1711 	zval *IM;
1712 	zend_long thick;
1713 	gdImagePtr im;
1714 
1715 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &thick) == FAILURE) {
1716 		return;
1717 	}
1718 
1719 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1720 		RETURN_FALSE;
1721 	}
1722 
1723 	gdImageSetThickness(im, thick);
1724 
1725 	RETURN_TRUE;
1726 }
1727 /* }}} */
1728 
1729 /* {{{ proto bool imagefilledellipse(resource im, int cx, int cy, int w, int h, int color)
1730    Draw an ellipse */
PHP_FUNCTION(imagefilledellipse)1731 PHP_FUNCTION(imagefilledellipse)
1732 {
1733 	zval *IM;
1734 	zend_long cx, cy, w, h, color;
1735 	gdImagePtr im;
1736 
1737 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &cx, &cy, &w, &h, &color) == FAILURE) {
1738 		return;
1739 	}
1740 
1741 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1742 		RETURN_FALSE;
1743 	}
1744 
1745 	gdImageFilledEllipse(im, cx, cy, w, h, color);
1746 
1747 	RETURN_TRUE;
1748 }
1749 /* }}} */
1750 
1751 /* {{{ proto bool imagefilledarc(resource im, int cx, int cy, int w, int h, int s, int e, int col, int style)
1752    Draw a filled partial ellipse */
PHP_FUNCTION(imagefilledarc)1753 PHP_FUNCTION(imagefilledarc)
1754 {
1755 	zval *IM;
1756 	zend_long cx, cy, w, h, ST, E, col, style;
1757 	gdImagePtr im;
1758 	int e, st;
1759 
1760 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllllllll", &IM, &cx, &cy, &w, &h, &ST, &E, &col, &style) == FAILURE) {
1761 		return;
1762 	}
1763 
1764 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1765 		RETURN_FALSE;
1766 	}
1767 
1768 	e = E;
1769 	if (e < 0) {
1770 		e %= 360;
1771 	}
1772 
1773 	st = ST;
1774 	if (st < 0) {
1775 		st %= 360;
1776 	}
1777 
1778 	gdImageFilledArc(im, cx, cy, w, h, st, e, col, style);
1779 
1780 	RETURN_TRUE;
1781 }
1782 /* }}} */
1783 
1784 /* {{{ proto bool imagealphablending(resource im, bool on)
1785    Turn alpha blending mode on or off for the given image */
PHP_FUNCTION(imagealphablending)1786 PHP_FUNCTION(imagealphablending)
1787 {
1788 	zval *IM;
1789 	zend_bool blend;
1790 	gdImagePtr im;
1791 
1792 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rb", &IM, &blend) == FAILURE) {
1793 		return;
1794 	}
1795 
1796 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1797 		RETURN_FALSE;
1798 	}
1799 
1800 	gdImageAlphaBlending(im, blend);
1801 
1802 	RETURN_TRUE;
1803 }
1804 /* }}} */
1805 
1806 /* {{{ proto bool imagesavealpha(resource im, bool on)
1807    Include alpha channel to a saved image */
PHP_FUNCTION(imagesavealpha)1808 PHP_FUNCTION(imagesavealpha)
1809 {
1810 	zval *IM;
1811 	zend_bool save;
1812 	gdImagePtr im;
1813 
1814 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rb", &IM, &save) == FAILURE) {
1815 		return;
1816 	}
1817 
1818 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1819 		RETURN_FALSE;
1820 	}
1821 
1822 	gdImageSaveAlpha(im, save);
1823 
1824 	RETURN_TRUE;
1825 }
1826 /* }}} */
1827 
1828 /* {{{ proto bool imagelayereffect(resource im, int effect)
1829    Set the alpha blending flag to use the bundled libgd layering effects */
PHP_FUNCTION(imagelayereffect)1830 PHP_FUNCTION(imagelayereffect)
1831 {
1832 	zval *IM;
1833 	zend_long effect;
1834 	gdImagePtr im;
1835 
1836 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &effect) == FAILURE) {
1837 		return;
1838 	}
1839 
1840 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1841 		RETURN_FALSE;
1842 	}
1843 
1844 	gdImageAlphaBlending(im, effect);
1845 
1846 	RETURN_TRUE;
1847 }
1848 /* }}} */
1849 
1850 #define CHECK_RGBA_RANGE(component, name) \
1851 	if (component < 0 || component > gd##name##Max) { \
1852 		php_error_docref(NULL, E_WARNING, #name " component is out of range"); \
1853 		RETURN_FALSE; \
1854 	}
1855 
1856 /* {{{ proto int imagecolorallocatealpha(resource im, int red, int green, int blue, int alpha)
1857    Allocate a color with an alpha level.  Works for true color and palette based images */
PHP_FUNCTION(imagecolorallocatealpha)1858 PHP_FUNCTION(imagecolorallocatealpha)
1859 {
1860 	zval *IM;
1861 	zend_long red, green, blue, alpha;
1862 	gdImagePtr im;
1863 	int ct = (-1);
1864 
1865 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
1866 		RETURN_FALSE;
1867 	}
1868 
1869 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1870 		RETURN_FALSE;
1871 	}
1872 
1873 	CHECK_RGBA_RANGE(red, Red);
1874 	CHECK_RGBA_RANGE(green, Green);
1875 	CHECK_RGBA_RANGE(blue, Blue);
1876 	CHECK_RGBA_RANGE(alpha, Alpha);
1877 
1878 	ct = gdImageColorAllocateAlpha(im, red, green, blue, alpha);
1879 	if (ct < 0) {
1880 		RETURN_FALSE;
1881 	}
1882 	RETURN_LONG((zend_long)ct);
1883 }
1884 /* }}} */
1885 
1886 /* {{{ proto int imagecolorresolvealpha(resource im, int red, int green, int blue, int alpha)
1887    Resolve/Allocate a colour with an alpha level.  Works for true colour and palette based images */
PHP_FUNCTION(imagecolorresolvealpha)1888 PHP_FUNCTION(imagecolorresolvealpha)
1889 {
1890 	zval *IM;
1891 	zend_long red, green, blue, alpha;
1892 	gdImagePtr im;
1893 
1894 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
1895 		return;
1896 	}
1897 
1898 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1899 		RETURN_FALSE;
1900 	}
1901 
1902 	CHECK_RGBA_RANGE(red, Red);
1903 	CHECK_RGBA_RANGE(green, Green);
1904 	CHECK_RGBA_RANGE(blue, Blue);
1905 	CHECK_RGBA_RANGE(alpha, Alpha);
1906 
1907 	RETURN_LONG(gdImageColorResolveAlpha(im, red, green, blue, alpha));
1908 }
1909 /* }}} */
1910 
1911 /* {{{ proto int imagecolorclosestalpha(resource im, int red, int green, int blue, int alpha)
1912    Find the closest matching colour with alpha transparency */
PHP_FUNCTION(imagecolorclosestalpha)1913 PHP_FUNCTION(imagecolorclosestalpha)
1914 {
1915 	zval *IM;
1916 	zend_long red, green, blue, alpha;
1917 	gdImagePtr im;
1918 
1919 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
1920 		return;
1921 	}
1922 
1923 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1924 		RETURN_FALSE;
1925 	}
1926 
1927 	CHECK_RGBA_RANGE(red, Red);
1928 	CHECK_RGBA_RANGE(green, Green);
1929 	CHECK_RGBA_RANGE(blue, Blue);
1930 	CHECK_RGBA_RANGE(alpha, Alpha);
1931 
1932 	RETURN_LONG(gdImageColorClosestAlpha(im, red, green, blue, alpha));
1933 }
1934 /* }}} */
1935 
1936 /* {{{ proto int imagecolorexactalpha(resource im, int red, int green, int blue, int alpha)
1937    Find exact match for colour with transparency */
PHP_FUNCTION(imagecolorexactalpha)1938 PHP_FUNCTION(imagecolorexactalpha)
1939 {
1940 	zval *IM;
1941 	zend_long red, green, blue, alpha;
1942 	gdImagePtr im;
1943 
1944 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &red, &green, &blue, &alpha) == FAILURE) {
1945 		return;
1946 	}
1947 
1948 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
1949 		RETURN_FALSE;
1950 	}
1951 
1952 	CHECK_RGBA_RANGE(red, Red);
1953 	CHECK_RGBA_RANGE(green, Green);
1954 	CHECK_RGBA_RANGE(blue, Blue);
1955 	CHECK_RGBA_RANGE(alpha, Alpha);
1956 
1957 	RETURN_LONG(gdImageColorExactAlpha(im, red, green, blue, alpha));
1958 }
1959 /* }}} */
1960 
1961 /* {{{ 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)
1962    Copy and resize part of an image using resampling to help ensure clarity */
PHP_FUNCTION(imagecopyresampled)1963 PHP_FUNCTION(imagecopyresampled)
1964 {
1965 	zval *SIM, *DIM;
1966 	zend_long SX, SY, SW, SH, DX, DY, DW, DH;
1967 	gdImagePtr im_dst, im_src;
1968 	int srcH, srcW, dstH, dstW, srcY, srcX, dstY, dstX;
1969 
1970 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrllllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &DW, &DH, &SW, &SH) == FAILURE) {
1971 		return;
1972 	}
1973 
1974 	if ((im_dst = (gdImagePtr)zend_fetch_resource(Z_RES_P(DIM), "Image", le_gd)) == NULL) {
1975 		RETURN_FALSE;
1976 	}
1977 
1978 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
1979 		RETURN_FALSE;
1980 	}
1981 
1982 	srcX = SX;
1983 	srcY = SY;
1984 	srcH = SH;
1985 	srcW = SW;
1986 	dstX = DX;
1987 	dstY = DY;
1988 	dstH = DH;
1989 	dstW = DW;
1990 
1991 	gdImageCopyResampled(im_dst, im_src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
1992 
1993 	RETURN_TRUE;
1994 }
1995 /* }}} */
1996 
1997 #ifdef PHP_WIN32
1998 /* {{{ proto resource imagegrabwindow(int window_handle [, int client_area])
1999    Grab a window or its client area using a windows handle (HWND property in COM instance) */
PHP_FUNCTION(imagegrabwindow)2000 PHP_FUNCTION(imagegrabwindow)
2001 {
2002 	HWND window;
2003 	zend_long client_area = 0;
2004 	RECT rc = {0};
2005 	int Width, Height;
2006 	HDC		hdc;
2007 	HDC memDC;
2008 	HBITMAP memBM;
2009 	HBITMAP hOld;
2010 	zend_long lwindow_handle;
2011 	gdImagePtr im = NULL;
2012 
2013 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &lwindow_handle, &client_area) == FAILURE) {
2014 		RETURN_FALSE;
2015 	}
2016 
2017 	window = (HWND) lwindow_handle;
2018 
2019 	if (!IsWindow(window)) {
2020 		php_error_docref(NULL, E_NOTICE, "Invalid window handle");
2021 		RETURN_FALSE;
2022 	}
2023 
2024 	hdc		= GetDC(0);
2025 
2026 	if (client_area) {
2027 		GetClientRect(window, &rc);
2028 		Width = rc.right;
2029 		Height = rc.bottom;
2030 	} else {
2031 		GetWindowRect(window, &rc);
2032 		Width	= rc.right - rc.left;
2033 		Height	= rc.bottom - rc.top;
2034 	}
2035 
2036 	Width		= (Width/4)*4;
2037 
2038 	memDC	= CreateCompatibleDC(hdc);
2039 	memBM	= CreateCompatibleBitmap(hdc, Width, Height);
2040 	hOld	= (HBITMAP) SelectObject (memDC, memBM);
2041 
2042 	PrintWindow(window, memDC, (UINT) client_area);
2043 
2044 	im = gdImageCreateTrueColor(Width, Height);
2045 	if (im) {
2046 		int x,y;
2047 		for (y=0; y <= Height; y++) {
2048 			for (x=0; x <= Width; x++) {
2049 				int c = GetPixel(memDC, x,y);
2050 				gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
2051 			}
2052 		}
2053 	}
2054 
2055 	SelectObject(memDC,hOld);
2056 	DeleteObject(memBM);
2057 	DeleteDC(memDC);
2058 	ReleaseDC( 0, hdc );
2059 
2060 	if (!im) {
2061 		RETURN_FALSE;
2062 	} else {
2063 		RETURN_RES(zend_register_resource(im, le_gd));
2064 	}
2065 }
2066 /* }}} */
2067 
2068 /* {{{ proto resource imagegrabscreen()
2069    Grab a screenshot */
PHP_FUNCTION(imagegrabscreen)2070 PHP_FUNCTION(imagegrabscreen)
2071 {
2072 	HWND window = GetDesktopWindow();
2073 	RECT rc = {0};
2074 	int Width, Height;
2075 	HDC		hdc;
2076 	HDC memDC;
2077 	HBITMAP memBM;
2078 	HBITMAP hOld;
2079 	gdImagePtr im;
2080 	hdc		= GetDC(0);
2081 
2082 	if (zend_parse_parameters_none() == FAILURE) {
2083 		return;
2084 	}
2085 
2086 	if (!hdc) {
2087 		RETURN_FALSE;
2088 	}
2089 
2090 	GetWindowRect(window, &rc);
2091 	Width	= rc.right - rc.left;
2092 	Height	= rc.bottom - rc.top;
2093 
2094 	Width		= (Width/4)*4;
2095 
2096 	memDC	= CreateCompatibleDC(hdc);
2097 	memBM	= CreateCompatibleBitmap(hdc, Width, Height);
2098 	hOld	= (HBITMAP) SelectObject (memDC, memBM);
2099 	BitBlt( memDC, 0, 0, Width, Height , hdc, rc.left, rc.top , SRCCOPY );
2100 
2101 	im = gdImageCreateTrueColor(Width, Height);
2102 	if (im) {
2103 		int x,y;
2104 		for (y=0; y <= Height; y++) {
2105 			for (x=0; x <= Width; x++) {
2106 				int c = GetPixel(memDC, x,y);
2107 				gdImageSetPixel(im, x, y, gdTrueColor(GetRValue(c), GetGValue(c), GetBValue(c)));
2108 			}
2109 		}
2110 	}
2111 
2112 	SelectObject(memDC,hOld);
2113 	DeleteObject(memBM);
2114 	DeleteDC(memDC);
2115 	ReleaseDC( 0, hdc );
2116 
2117 	if (!im) {
2118 		RETURN_FALSE;
2119 	} else {
2120 		RETURN_RES(zend_register_resource(im, le_gd));
2121 	}
2122 }
2123 /* }}} */
2124 #endif /* PHP_WIN32 */
2125 
2126 /* {{{ proto resource imagerotate(resource src_im, float angle, int bgdcolor [, int ignoretransparent])
2127    Rotate an image using a custom angle */
PHP_FUNCTION(imagerotate)2128 PHP_FUNCTION(imagerotate)
2129 {
2130 	zval *SIM;
2131 	gdImagePtr im_dst, im_src;
2132 	double degrees;
2133 	zend_long color;
2134 	zend_long ignoretransparent = 0;
2135 
2136 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rdl|l", &SIM, &degrees, &color, &ignoretransparent) == FAILURE) {
2137 		RETURN_FALSE;
2138 	}
2139 
2140 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
2141 		RETURN_FALSE;
2142 	}
2143 
2144 	im_dst = gdImageRotateInterpolated(im_src, (const float)degrees, color);
2145 
2146 	if (im_dst != NULL) {
2147 		RETURN_RES(zend_register_resource(im_dst, le_gd));
2148 	} else {
2149 		RETURN_FALSE;
2150 	}
2151 }
2152 /* }}} */
2153 
2154 /* {{{ proto bool imagesettile(resource image, resource tile)
2155    Set the tile image to $tile when filling $image with the "IMG_COLOR_TILED" color */
PHP_FUNCTION(imagesettile)2156 PHP_FUNCTION(imagesettile)
2157 {
2158 	zval *IM, *TILE;
2159 	gdImagePtr im, tile;
2160 
2161 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &IM, &TILE) == FAILURE) {
2162 		return;
2163 	}
2164 
2165 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2166 		RETURN_FALSE;
2167 	}
2168 
2169 	if ((tile = (gdImagePtr)zend_fetch_resource(Z_RES_P(TILE), "Image", le_gd)) == NULL) {
2170 		RETURN_FALSE;
2171 	}
2172 
2173 	gdImageSetTile(im, tile);
2174 
2175 	RETURN_TRUE;
2176 }
2177 /* }}} */
2178 
2179 /* {{{ proto bool imagesetbrush(resource image, resource brush)
2180    Set the brush image to $brush when filling $image with the "IMG_COLOR_BRUSHED" color */
PHP_FUNCTION(imagesetbrush)2181 PHP_FUNCTION(imagesetbrush)
2182 {
2183 	zval *IM, *TILE;
2184 	gdImagePtr im, tile;
2185 
2186 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &IM, &TILE) == FAILURE) {
2187 		return;
2188 	}
2189 
2190 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2191 		RETURN_FALSE;
2192 	}
2193 
2194 	if ((tile = (gdImagePtr)zend_fetch_resource(Z_RES_P(TILE), "Image", le_gd)) == NULL) {
2195 		RETURN_FALSE;
2196 	}
2197 
2198 	gdImageSetBrush(im, tile);
2199 
2200 	RETURN_TRUE;
2201 }
2202 /* }}} */
2203 
2204 /* {{{ proto resource imagecreate(int x_size, int y_size)
2205    Create a new image */
PHP_FUNCTION(imagecreate)2206 PHP_FUNCTION(imagecreate)
2207 {
2208 	zend_long x_size, y_size;
2209 	gdImagePtr im;
2210 
2211 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &x_size, &y_size) == FAILURE) {
2212 		return;
2213 	}
2214 
2215 	if (x_size <= 0 || y_size <= 0 || x_size >= INT_MAX || y_size >= INT_MAX) {
2216 		php_error_docref(NULL, E_WARNING, "Invalid image dimensions");
2217 		RETURN_FALSE;
2218 	}
2219 
2220 	im = gdImageCreate(x_size, y_size);
2221 
2222 	if (!im) {
2223 		RETURN_FALSE;
2224 	}
2225 
2226 	RETURN_RES(zend_register_resource(im, le_gd));
2227 }
2228 /* }}} */
2229 
2230 /* {{{ proto int imagetypes(void)
2231    Return the types of images supported in a bitfield - 1=GIF, 2=JPEG, 4=PNG, 8=WBMP, 16=XPM */
PHP_FUNCTION(imagetypes)2232 PHP_FUNCTION(imagetypes)
2233 {
2234 	int ret = 0;
2235 	ret = PHP_IMG_GIF;
2236 #ifdef HAVE_GD_JPG
2237 	ret |= PHP_IMG_JPG;
2238 #endif
2239 #ifdef HAVE_GD_PNG
2240 	ret |= PHP_IMG_PNG;
2241 #endif
2242 	ret |= PHP_IMG_WBMP;
2243 #if defined(HAVE_XPM) && defined(HAVE_GD_XPM)
2244 	ret |= PHP_IMG_XPM;
2245 #endif
2246 #ifdef HAVE_GD_WEBP
2247 	ret |= PHP_IMG_WEBP;
2248 #endif
2249 #ifdef HAVE_GD_BMP
2250 	ret |= PHP_IMG_BMP;
2251 #endif
2252 #ifdef HAVE_GD_TGA
2253 	ret |= PHP_IMG_TGA;
2254 #endif
2255 
2256 	if (zend_parse_parameters_none() == FAILURE) {
2257 		return;
2258 	}
2259 
2260 	RETURN_LONG(ret);
2261 }
2262 /* }}} */
2263 
2264 /* {{{ _php_ctx_getmbi
2265  */
2266 
_php_ctx_getmbi(gdIOCtx * ctx)2267 static int _php_ctx_getmbi(gdIOCtx *ctx)
2268 {
2269 	int i, mbi = 0;
2270 
2271 	do {
2272 		i = (ctx->getC)(ctx);
2273 		if (i < 0) {
2274 			return -1;
2275 		}
2276 		mbi = (mbi << 7) | (i & 0x7f);
2277 	} while (i & 0x80);
2278 
2279 	return mbi;
2280 }
2281 /* }}} */
2282 
2283 /* {{{ _php_image_type
2284  */
2285 static const char php_sig_gd2[3] = {'g', 'd', '2'};
2286 
_php_image_type(char data[12])2287 static int _php_image_type (char data[12])
2288 {
2289 	/* Based on ext/standard/image.c */
2290 
2291 	if (data == NULL) {
2292 		return -1;
2293 	}
2294 
2295 	if (!memcmp(data, php_sig_gd2, sizeof(php_sig_gd2))) {
2296 		return PHP_GDIMG_TYPE_GD2;
2297 	} else if (!memcmp(data, php_sig_jpg, sizeof(php_sig_jpg))) {
2298 		return PHP_GDIMG_TYPE_JPG;
2299 	} else if (!memcmp(data, php_sig_png, sizeof(php_sig_png))) {
2300 		return PHP_GDIMG_TYPE_PNG;
2301 	} else if (!memcmp(data, php_sig_gif, sizeof(php_sig_gif))) {
2302 		return PHP_GDIMG_TYPE_GIF;
2303 	} else if (!memcmp(data, php_sig_bmp, sizeof(php_sig_bmp))) {
2304 		return PHP_GDIMG_TYPE_BMP;
2305 	} 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))) {
2306 		return PHP_GDIMG_TYPE_WEBP;
2307 	}
2308 	else {
2309 		gdIOCtx *io_ctx;
2310 		io_ctx = gdNewDynamicCtxEx(8, data, 0);
2311 		if (io_ctx) {
2312 			if (_php_ctx_getmbi(io_ctx) == 0 && _php_ctx_getmbi(io_ctx) >= 0) {
2313 				io_ctx->gd_free(io_ctx);
2314 				return PHP_GDIMG_TYPE_WBM;
2315 			} else {
2316 				io_ctx->gd_free(io_ctx);
2317 			}
2318 		}
2319 	}
2320 	return -1;
2321 }
2322 /* }}} */
2323 
2324 /* {{{ _php_image_create_from_string
2325  */
_php_image_create_from_string(zval * data,char * tn,gdImagePtr (* ioctx_func_p)())2326 gdImagePtr _php_image_create_from_string(zval *data, char *tn, gdImagePtr (*ioctx_func_p)())
2327 {
2328 	gdImagePtr im;
2329 	gdIOCtx *io_ctx;
2330 
2331 	io_ctx = gdNewDynamicCtxEx(Z_STRLEN_P(data), Z_STRVAL_P(data), 0);
2332 
2333 	if (!io_ctx) {
2334 		return NULL;
2335 	}
2336 
2337 	im = (*ioctx_func_p)(io_ctx);
2338 	if (!im) {
2339 		php_error_docref(NULL, E_WARNING, "Passed data is not in '%s' format", tn);
2340 		io_ctx->gd_free(io_ctx);
2341 		return NULL;
2342 	}
2343 
2344 	io_ctx->gd_free(io_ctx);
2345 
2346 	return im;
2347 }
2348 /* }}} */
2349 
2350 /* {{{ proto resource imagecreatefromstring(string image)
2351    Create a new image from the image stream in the string */
PHP_FUNCTION(imagecreatefromstring)2352 PHP_FUNCTION(imagecreatefromstring)
2353 {
2354 	zval *data;
2355 	gdImagePtr im;
2356 	int imtype;
2357 	char sig[12];
2358 
2359 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &data) == FAILURE) {
2360 		return;
2361 	}
2362 
2363 	if (!try_convert_to_string(data)) {
2364 		return;
2365 	}
2366 
2367 	if (Z_STRLEN_P(data) < sizeof(sig)) {
2368 		php_error_docref(NULL, E_WARNING, "Empty string or invalid image");
2369 		RETURN_FALSE;
2370 	}
2371 
2372 	memcpy(sig, Z_STRVAL_P(data), sizeof(sig));
2373 
2374 	imtype = _php_image_type(sig);
2375 
2376 	switch (imtype) {
2377 		case PHP_GDIMG_TYPE_JPG:
2378 #ifdef HAVE_GD_JPG
2379 			im = _php_image_create_from_string(data, "JPEG", gdImageCreateFromJpegCtx);
2380 #else
2381 			php_error_docref(NULL, E_WARNING, "No JPEG support in this PHP build");
2382 			RETURN_FALSE;
2383 #endif
2384 			break;
2385 
2386 		case PHP_GDIMG_TYPE_PNG:
2387 #ifdef HAVE_GD_PNG
2388 			im = _php_image_create_from_string(data, "PNG", gdImageCreateFromPngCtx);
2389 #else
2390 			php_error_docref(NULL, E_WARNING, "No PNG support in this PHP build");
2391 			RETURN_FALSE;
2392 #endif
2393 			break;
2394 
2395 		case PHP_GDIMG_TYPE_GIF:
2396 			im = _php_image_create_from_string(data, "GIF", gdImageCreateFromGifCtx);
2397 			break;
2398 
2399 		case PHP_GDIMG_TYPE_WBM:
2400 			im = _php_image_create_from_string(data, "WBMP", gdImageCreateFromWBMPCtx);
2401 			break;
2402 
2403 		case PHP_GDIMG_TYPE_GD2:
2404 			im = _php_image_create_from_string(data, "GD2", gdImageCreateFromGd2Ctx);
2405 			break;
2406 
2407 		case PHP_GDIMG_TYPE_BMP:
2408 			im = _php_image_create_from_string(data, "BMP", gdImageCreateFromBmpCtx);
2409 			break;
2410 
2411 		case PHP_GDIMG_TYPE_WEBP:
2412 #ifdef HAVE_GD_WEBP
2413 			im = _php_image_create_from_string(data, "WEBP", gdImageCreateFromWebpCtx);
2414 			break;
2415 #else
2416 			php_error_docref(NULL, E_WARNING, "No WEBP support in this PHP build");
2417 			RETURN_FALSE;
2418 #endif
2419 
2420 		default:
2421 			php_error_docref(NULL, E_WARNING, "Data is not in a recognized format");
2422 			RETURN_FALSE;
2423 	}
2424 
2425 	if (!im) {
2426 		php_error_docref(NULL, E_WARNING, "Couldn't create GD Image Stream out of Data");
2427 		RETURN_FALSE;
2428 	}
2429 
2430 	RETURN_RES(zend_register_resource(im, le_gd));
2431 }
2432 /* }}} */
2433 
2434 /* {{{ _php_image_create_from
2435  */
_php_image_create_from(INTERNAL_FUNCTION_PARAMETERS,int image_type,char * tn,gdImagePtr (* func_p)(),gdImagePtr (* ioctx_func_p)())2436 static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)())
2437 {
2438 	char *file;
2439 	size_t file_len;
2440 	zend_long srcx, srcy, width, height;
2441 	gdImagePtr im = NULL;
2442 	php_stream *stream;
2443 	FILE * fp = NULL;
2444 #ifdef HAVE_GD_JPG
2445 	long ignore_warning;
2446 #endif
2447 
2448 	if (image_type == PHP_GDIMG_TYPE_GD2PART) {
2449 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "pllll", &file, &file_len, &srcx, &srcy, &width, &height) == FAILURE) {
2450 			return;
2451 		}
2452 		if (width < 1 || height < 1) {
2453 			php_error_docref(NULL, E_WARNING, "Zero width or height not allowed");
2454 			RETURN_FALSE;
2455 		}
2456 	} else {
2457 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", &file, &file_len) == FAILURE) {
2458 			return;
2459 		}
2460 	}
2461 
2462 
2463 	stream = php_stream_open_wrapper(file, "rb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL);
2464 	if (stream == NULL)	{
2465 		RETURN_FALSE;
2466 	}
2467 
2468 	/* try and avoid allocating a FILE* if the stream is not naturally a FILE* */
2469 	if (php_stream_is(stream, PHP_STREAM_IS_STDIO))	{
2470 		if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) {
2471 			goto out_err;
2472 		}
2473 	} else if (ioctx_func_p) {
2474 		/* we can create an io context */
2475 		gdIOCtx* io_ctx;
2476 		zend_string *buff;
2477 		char *pstr;
2478 
2479 		buff = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
2480 
2481 		if (!buff) {
2482 			php_error_docref(NULL, E_WARNING,"Cannot read image data");
2483 			goto out_err;
2484 		}
2485 
2486 		/* needs to be malloc (persistent) - GD will free() it later */
2487 		pstr = pestrndup(ZSTR_VAL(buff), ZSTR_LEN(buff), 1);
2488 		io_ctx = gdNewDynamicCtxEx(ZSTR_LEN(buff), pstr, 0);
2489 		if (!io_ctx) {
2490 			pefree(pstr, 1);
2491 			zend_string_release_ex(buff, 0);
2492 			php_error_docref(NULL, E_WARNING,"Cannot allocate GD IO context");
2493 			goto out_err;
2494 		}
2495 
2496 		if (image_type == PHP_GDIMG_TYPE_GD2PART) {
2497 			im = (*ioctx_func_p)(io_ctx, srcx, srcy, width, height);
2498 		} else {
2499 			im = (*ioctx_func_p)(io_ctx);
2500 		}
2501 		io_ctx->gd_free(io_ctx);
2502 		pefree(pstr, 1);
2503 		zend_string_release_ex(buff, 0);
2504 	}
2505 	else if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO)) {
2506 		/* try and force the stream to be FILE* */
2507 		if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_TRY_HARD, (void **) &fp, REPORT_ERRORS)) {
2508 			goto out_err;
2509 		}
2510 	}
2511 
2512 	if (!im && fp) {
2513 		switch (image_type) {
2514 			case PHP_GDIMG_TYPE_GD2PART:
2515 				im = (*func_p)(fp, srcx, srcy, width, height);
2516 				break;
2517 #if defined(HAVE_XPM) && defined(HAVE_GD_XPM)
2518 			case PHP_GDIMG_TYPE_XPM:
2519 				im = gdImageCreateFromXpm(file);
2520 				break;
2521 #endif
2522 
2523 #ifdef HAVE_GD_JPG
2524 			case PHP_GDIMG_TYPE_JPG:
2525 				ignore_warning = INI_INT("gd.jpeg_ignore_warning");
2526 				im = gdImageCreateFromJpegEx(fp, ignore_warning);
2527 			break;
2528 #endif
2529 
2530 			default:
2531 				im = (*func_p)(fp);
2532 				break;
2533 		}
2534 
2535 		fflush(fp);
2536 	}
2537 
2538 /* register_im: */
2539 	if (im) {
2540 		RETVAL_RES(zend_register_resource(im, le_gd));
2541 		php_stream_close(stream);
2542 		return;
2543 	}
2544 
2545 	php_error_docref(NULL, E_WARNING, "'%s' is not a valid %s file", file, tn);
2546 out_err:
2547 	php_stream_close(stream);
2548 	RETURN_FALSE;
2549 
2550 }
2551 /* }}} */
2552 
2553 /* {{{ proto resource imagecreatefromgif(string filename)
2554    Create a new image from GIF file or URL */
PHP_FUNCTION(imagecreatefromgif)2555 PHP_FUNCTION(imagecreatefromgif)
2556 {
2557 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageCreateFromGif, gdImageCreateFromGifCtx);
2558 }
2559 /* }}} */
2560 
2561 #ifdef HAVE_GD_JPG
2562 /* {{{ proto resource imagecreatefromjpeg(string filename)
2563    Create a new image from JPEG file or URL */
PHP_FUNCTION(imagecreatefromjpeg)2564 PHP_FUNCTION(imagecreatefromjpeg)
2565 {
2566 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageCreateFromJpeg, gdImageCreateFromJpegCtx);
2567 }
2568 /* }}} */
2569 #endif /* HAVE_GD_JPG */
2570 
2571 #ifdef HAVE_GD_PNG
2572 /* {{{ proto resource imagecreatefrompng(string filename)
2573    Create a new image from PNG file or URL */
PHP_FUNCTION(imagecreatefrompng)2574 PHP_FUNCTION(imagecreatefrompng)
2575 {
2576 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImageCreateFromPng, gdImageCreateFromPngCtx);
2577 }
2578 /* }}} */
2579 #endif /* HAVE_GD_PNG */
2580 
2581 #ifdef HAVE_GD_WEBP
2582 /* {{{ proto resource imagecreatefromwebp(string filename)
2583    Create a new image from WEBP file or URL */
PHP_FUNCTION(imagecreatefromwebp)2584 PHP_FUNCTION(imagecreatefromwebp)
2585 {
2586 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageCreateFromWebp, gdImageCreateFromWebpCtx);
2587 }
2588 /* }}} */
2589 #endif /* HAVE_GD_WEBP */
2590 
2591 /* {{{ proto resource imagecreatefromxbm(string filename)
2592    Create a new image from XBM file or URL */
PHP_FUNCTION(imagecreatefromxbm)2593 PHP_FUNCTION(imagecreatefromxbm)
2594 {
2595 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageCreateFromXbm, NULL);
2596 }
2597 /* }}} */
2598 
2599 #if defined(HAVE_XPM) && defined(HAVE_GD_XPM)
2600 /* {{{ proto resource imagecreatefromxpm(string filename)
2601    Create a new image from XPM file or URL */
PHP_FUNCTION(imagecreatefromxpm)2602 PHP_FUNCTION(imagecreatefromxpm)
2603 {
2604 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XPM, "XPM", gdImageCreateFromXpm, NULL);
2605 }
2606 /* }}} */
2607 #endif
2608 
2609 /* {{{ proto resource imagecreatefromwbmp(string filename)
2610    Create a new image from WBMP file or URL */
PHP_FUNCTION(imagecreatefromwbmp)2611 PHP_FUNCTION(imagecreatefromwbmp)
2612 {
2613 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageCreateFromWBMP, gdImageCreateFromWBMPCtx);
2614 }
2615 /* }}} */
2616 
2617 /* {{{ proto resource imagecreatefromgd(string filename)
2618    Create a new image from GD file or URL */
PHP_FUNCTION(imagecreatefromgd)2619 PHP_FUNCTION(imagecreatefromgd)
2620 {
2621 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD, "GD", gdImageCreateFromGd, gdImageCreateFromGdCtx);
2622 }
2623 /* }}} */
2624 
2625 /* {{{ proto resource imagecreatefromgd2(string filename)
2626    Create a new image from GD2 file or URL */
PHP_FUNCTION(imagecreatefromgd2)2627 PHP_FUNCTION(imagecreatefromgd2)
2628 {
2629 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2", gdImageCreateFromGd2, gdImageCreateFromGd2Ctx);
2630 }
2631 /* }}} */
2632 
2633 /* {{{ proto resource imagecreatefromgd2part(string filename, int srcX, int srcY, int width, int height)
2634    Create a new image from a given part of GD2 file or URL */
PHP_FUNCTION(imagecreatefromgd2part)2635 PHP_FUNCTION(imagecreatefromgd2part)
2636 {
2637 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2PART, "GD2", gdImageCreateFromGd2Part, gdImageCreateFromGd2PartCtx);
2638 }
2639 /* }}} */
2640 
2641 #if defined(HAVE_GD_BMP)
2642 /* {{{ proto resource imagecreatefrombmp(string filename)
2643    Create a new image from BMP file or URL */
PHP_FUNCTION(imagecreatefrombmp)2644 PHP_FUNCTION(imagecreatefrombmp)
2645 {
2646 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_BMP, "BMP", gdImageCreateFromBmp, gdImageCreateFromBmpCtx);
2647 }
2648 /* }}} */
2649 #endif
2650 
2651 #if defined(HAVE_GD_TGA)
2652 /* {{{ proto resource imagecreatefromtga(string filename)
2653    Create a new image from TGA file or URL */
PHP_FUNCTION(imagecreatefromtga)2654 PHP_FUNCTION(imagecreatefromtga)
2655 {
2656 	_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_TGA, "TGA", gdImageCreateFromTga, gdImageCreateFromTgaCtx);
2657 }
2658 /* }}} */
2659 #endif
2660 
2661 /* {{{ _php_image_output
2662  */
_php_image_output(INTERNAL_FUNCTION_PARAMETERS,int image_type,char * tn,void (* func_p)())2663 static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
2664 {
2665 	zval *imgind;
2666 	char *file = NULL;
2667 	zend_long quality = 0, type = 0;
2668 	gdImagePtr im;
2669 	char *fn = NULL;
2670 	FILE *fp;
2671 	size_t file_len = 0;
2672 	int argc = ZEND_NUM_ARGS();
2673 	int q = -1, t = 1;
2674 
2675 	/* The quality parameter for Wbmp stands for the foreground when called from image2wbmp() */
2676 	/* The quality parameter for gd2 stands for chunk size */
2677 
2678 	if (zend_parse_parameters(argc, "r|pll", &imgind, &file, &file_len, &quality, &type) == FAILURE) {
2679 		return;
2680 	}
2681 
2682 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(imgind), "Image", le_gd)) == NULL) {
2683 		RETURN_FALSE;
2684 	}
2685 
2686 	if (argc > 1) {
2687 		fn = file;
2688 		if (argc >= 3) {
2689 			q = quality;
2690 			if (argc == 4) {
2691 				t = type;
2692 			}
2693 		}
2694 	}
2695 
2696 	if (argc >= 2 && file_len) {
2697 		PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
2698 
2699 		fp = VCWD_FOPEN(fn, "wb");
2700 		if (!fp) {
2701 			php_error_docref(NULL, E_WARNING, "Unable to open '%s' for writing", fn);
2702 			RETURN_FALSE;
2703 		}
2704 
2705 		switch (image_type) {
2706 			case PHP_GDIMG_CONVERT_WBM:
2707 				if (q == -1) {
2708 					q = 0;
2709 				} else if (q < 0 || q > 255) {
2710 					php_error_docref(NULL, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q);
2711 					q = 0;
2712 				}
2713 				gdImageWBMP(im, q, fp);
2714 				break;
2715 			case PHP_GDIMG_TYPE_GD:
2716 				(*func_p)(im, fp);
2717 				break;
2718 			case PHP_GDIMG_TYPE_GD2:
2719 				if (q == -1) {
2720 					q = 128;
2721 				}
2722 				(*func_p)(im, fp, q, t);
2723 				break;
2724 			default:
2725 				ZEND_ASSERT(0);
2726 		}
2727 		fflush(fp);
2728 		fclose(fp);
2729 	} else {
2730 		int   b;
2731 		FILE *tmp;
2732 		char  buf[4096];
2733 		zend_string *path;
2734 
2735 		tmp = php_open_temporary_file(NULL, NULL, &path);
2736 		if (tmp == NULL) {
2737 			php_error_docref(NULL, E_WARNING, "Unable to open temporary file");
2738 			RETURN_FALSE;
2739 		}
2740 
2741 		switch (image_type) {
2742 			case PHP_GDIMG_CONVERT_WBM:
2743  				if (q == -1) {
2744   					q = 0;
2745   				} else if (q < 0 || q > 255) {
2746   					php_error_docref(NULL, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q);
2747  					q = 0;
2748   				}
2749 				gdImageWBMP(im, q, tmp);
2750 				break;
2751 			case PHP_GDIMG_TYPE_GD:
2752 				(*func_p)(im, tmp);
2753 				break;
2754 			case PHP_GDIMG_TYPE_GD2:
2755 				if (q == -1) {
2756 					q = 128;
2757 				}
2758 				(*func_p)(im, tmp, q, t);
2759 				break;
2760 			default:
2761 				ZEND_ASSERT(0);
2762 		}
2763 
2764 		fseek(tmp, 0, SEEK_SET);
2765 
2766 		while ((b = fread(buf, 1, sizeof(buf), tmp)) > 0) {
2767 			php_write(buf, b);
2768 		}
2769 
2770 		fclose(tmp);
2771 		VCWD_UNLINK((const char *)ZSTR_VAL(path)); /* make sure that the temporary file is removed */
2772 		zend_string_release_ex(path, 0);
2773 	}
2774 	RETURN_TRUE;
2775 }
2776 /* }}} */
2777 
2778 /* {{{ proto int imagexbm(int im, string filename [, int foreground])
2779    Output XBM image to browser or file */
PHP_FUNCTION(imagexbm)2780 PHP_FUNCTION(imagexbm)
2781 {
2782 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx);
2783 }
2784 /* }}} */
2785 
2786 /* {{{ proto bool imagegif(resource im [, mixed to])
2787    Output GIF image to browser or file */
PHP_FUNCTION(imagegif)2788 PHP_FUNCTION(imagegif)
2789 {
2790 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageGifCtx);
2791 }
2792 /* }}} */
2793 
2794 #ifdef HAVE_GD_PNG
2795 /* {{{ proto bool imagepng(resource im [, mixed to])
2796    Output PNG image to browser or file */
PHP_FUNCTION(imagepng)2797 PHP_FUNCTION(imagepng)
2798 {
2799 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtxEx);
2800 }
2801 /* }}} */
2802 #endif /* HAVE_GD_PNG */
2803 
2804 
2805 #ifdef HAVE_GD_WEBP
2806 /* {{{ proto bool imagewebp(resource im [, mixed to[, int quality]] )
2807    Output WEBP image to browser or file */
PHP_FUNCTION(imagewebp)2808 PHP_FUNCTION(imagewebp)
2809 {
2810 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageWebpCtx);
2811 }
2812 /* }}} */
2813 #endif /* HAVE_GD_WEBP */
2814 
2815 
2816 #ifdef HAVE_GD_JPG
2817 /* {{{ proto bool imagejpeg(resource im [, mixed to [, int quality]])
2818    Output JPEG image to browser or file */
PHP_FUNCTION(imagejpeg)2819 PHP_FUNCTION(imagejpeg)
2820 {
2821 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageJpegCtx);
2822 }
2823 /* }}} */
2824 #endif /* HAVE_GD_JPG */
2825 
2826 /* {{{ proto bool imagewbmp(resource im [, mixed to [, int foreground]])
2827    Output WBMP image to browser or file */
PHP_FUNCTION(imagewbmp)2828 PHP_FUNCTION(imagewbmp)
2829 {
2830 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMPCtx);
2831 }
2832 /* }}} */
2833 
2834 /* {{{ proto bool imagegd(resource im [, mixed to])
2835    Output GD image to browser or file */
PHP_FUNCTION(imagegd)2836 PHP_FUNCTION(imagegd)
2837 {
2838 	_php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD, "GD", gdImageGd);
2839 }
2840 /* }}} */
2841 
2842 /* {{{ proto bool imagegd2(resource im [, mixed to [, int chunk_size [, int type]]])
2843    Output GD2 image to browser or file */
PHP_FUNCTION(imagegd2)2844 PHP_FUNCTION(imagegd2)
2845 {
2846 	_php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2", gdImageGd2);
2847 }
2848 /* }}} */
2849 
2850 #ifdef HAVE_GD_BMP
2851 /* {{{ proto bool imagebmp(resource im [, mixed to [, bool compressed]])
2852    Output BMP image to browser or file */
PHP_FUNCTION(imagebmp)2853 PHP_FUNCTION(imagebmp)
2854 {
2855 	_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_BMP, "BMP", gdImageBmpCtx);
2856 }
2857 /* }}} */
2858 #endif
2859 
2860 /* {{{ proto bool imagedestroy(resource im)
2861    Destroy an image */
PHP_FUNCTION(imagedestroy)2862 PHP_FUNCTION(imagedestroy)
2863 {
2864 	zval *IM;
2865 	gdImagePtr im;
2866 
2867 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) {
2868 		return;
2869 	}
2870 
2871 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2872 		RETURN_FALSE;
2873 	}
2874 
2875 	zend_list_close(Z_RES_P(IM));
2876 
2877 	RETURN_TRUE;
2878 }
2879 /* }}} */
2880 
2881 /* {{{ proto int imagecolorallocate(resource im, int red, int green, int blue)
2882    Allocate a color for an image */
PHP_FUNCTION(imagecolorallocate)2883 PHP_FUNCTION(imagecolorallocate)
2884 {
2885 	zval *IM;
2886 	zend_long red, green, blue;
2887 	gdImagePtr im;
2888 	int ct = (-1);
2889 
2890 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
2891 		return;
2892 	}
2893 
2894 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2895 		RETURN_FALSE;
2896 	}
2897 
2898 	CHECK_RGBA_RANGE(red, Red);
2899 	CHECK_RGBA_RANGE(green, Green);
2900 	CHECK_RGBA_RANGE(blue, Blue);
2901 
2902 	ct = gdImageColorAllocate(im, red, green, blue);
2903 	if (ct < 0) {
2904 		RETURN_FALSE;
2905 	}
2906 	RETURN_LONG(ct);
2907 }
2908 /* }}} */
2909 
2910 /* {{{ proto void imagepalettecopy(resource dst, resource src)
2911    Copy the palette from the src image onto the dst image */
PHP_FUNCTION(imagepalettecopy)2912 PHP_FUNCTION(imagepalettecopy)
2913 {
2914 	zval *dstim, *srcim;
2915 	gdImagePtr dst, src;
2916 
2917 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr", &dstim, &srcim) == FAILURE) {
2918 		return;
2919 	}
2920 
2921 	if ((dst = (gdImagePtr)zend_fetch_resource(Z_RES_P(dstim), "Image", le_gd)) == NULL) {
2922 		RETURN_FALSE;
2923 	}
2924 
2925 	if ((src = (gdImagePtr)zend_fetch_resource(Z_RES_P(srcim), "Image", le_gd)) == NULL) {
2926 		RETURN_FALSE;
2927 	}
2928 
2929 	gdImagePaletteCopy(dst, src);
2930 }
2931 /* }}} */
2932 
2933 /* {{{ proto int imagecolorat(resource im, int x, int y)
2934    Get the index of the color of a pixel */
PHP_FUNCTION(imagecolorat)2935 PHP_FUNCTION(imagecolorat)
2936 {
2937 	zval *IM;
2938 	zend_long x, y;
2939 	gdImagePtr im;
2940 
2941 	ZEND_PARSE_PARAMETERS_START(3, 3)
2942 		Z_PARAM_RESOURCE(IM)
2943 		Z_PARAM_LONG(x)
2944 		Z_PARAM_LONG(y)
2945 	ZEND_PARSE_PARAMETERS_END();
2946 
2947 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2948 		RETURN_FALSE;
2949 	}
2950 
2951 	if (gdImageTrueColor(im)) {
2952 		if (im->tpixels && gdImageBoundsSafe(im, x, y)) {
2953 			RETURN_LONG(gdImageTrueColorPixel(im, x, y));
2954 		} else {
2955 			php_error_docref(NULL, E_NOTICE, "" ZEND_LONG_FMT "," ZEND_LONG_FMT " is out of bounds", x, y);
2956 			RETURN_FALSE;
2957 		}
2958 	} else {
2959 		if (im->pixels && gdImageBoundsSafe(im, x, y)) {
2960 			RETURN_LONG(im->pixels[y][x]);
2961 		} else {
2962 			php_error_docref(NULL, E_NOTICE, "" ZEND_LONG_FMT "," ZEND_LONG_FMT " is out of bounds", x, y);
2963 			RETURN_FALSE;
2964 		}
2965 	}
2966 }
2967 /* }}} */
2968 
2969 /* {{{ proto int imagecolorclosest(resource im, int red, int green, int blue)
2970    Get the index of the closest color to the specified color */
PHP_FUNCTION(imagecolorclosest)2971 PHP_FUNCTION(imagecolorclosest)
2972 {
2973 	zval *IM;
2974 	zend_long red, green, blue;
2975 	gdImagePtr im;
2976 
2977 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
2978 		return;
2979 	}
2980 
2981 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
2982 		RETURN_FALSE;
2983 	}
2984 
2985 	CHECK_RGBA_RANGE(red, Red);
2986 	CHECK_RGBA_RANGE(green, Green);
2987 	CHECK_RGBA_RANGE(blue, Blue);
2988 
2989 	RETURN_LONG(gdImageColorClosest(im, red, green, blue));
2990 }
2991 /* }}} */
2992 
2993 /* {{{ proto int imagecolorclosesthwb(resource im, int red, int green, int blue)
2994    Get the index of the color which has the hue, white and blackness nearest to the given color */
PHP_FUNCTION(imagecolorclosesthwb)2995 PHP_FUNCTION(imagecolorclosesthwb)
2996 {
2997 	zval *IM;
2998 	zend_long red, green, blue;
2999 	gdImagePtr im;
3000 
3001 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
3002 		return;
3003 	}
3004 
3005 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3006 		RETURN_FALSE;
3007 	}
3008 
3009 	CHECK_RGBA_RANGE(red, Red);
3010 	CHECK_RGBA_RANGE(green, Green);
3011 	CHECK_RGBA_RANGE(blue, Blue);
3012 
3013 	RETURN_LONG(gdImageColorClosestHWB(im, red, green, blue));
3014 }
3015 /* }}} */
3016 
3017 /* {{{ proto bool imagecolordeallocate(resource im, int index)
3018    De-allocate a color for an image */
PHP_FUNCTION(imagecolordeallocate)3019 PHP_FUNCTION(imagecolordeallocate)
3020 {
3021 	zval *IM;
3022 	zend_long index;
3023 	int col;
3024 	gdImagePtr im;
3025 
3026 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &index) == FAILURE) {
3027 		return;
3028 	}
3029 
3030 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3031 		RETURN_FALSE;
3032 	}
3033 
3034 	/* We can return right away for a truecolor image as deallocating colours is meaningless here */
3035 	if (gdImageTrueColor(im)) {
3036 		RETURN_TRUE;
3037 	}
3038 
3039 	col = index;
3040 
3041 	if (col >= 0 && col < gdImageColorsTotal(im)) {
3042 		gdImageColorDeallocate(im, col);
3043 		RETURN_TRUE;
3044 	} else {
3045 		php_error_docref(NULL, E_WARNING, "Color index %d out of range",	col);
3046 		RETURN_FALSE;
3047 	}
3048 }
3049 /* }}} */
3050 
3051 /* {{{ proto int imagecolorresolve(resource im, int red, int green, int blue)
3052    Get the index of the specified color or its closest possible alternative */
PHP_FUNCTION(imagecolorresolve)3053 PHP_FUNCTION(imagecolorresolve)
3054 {
3055 	zval *IM;
3056 	zend_long red, green, blue;
3057 	gdImagePtr im;
3058 
3059 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
3060 		return;
3061 	}
3062 
3063 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3064 		RETURN_FALSE;
3065 	}
3066 
3067 	CHECK_RGBA_RANGE(red, Red);
3068 	CHECK_RGBA_RANGE(green, Green);
3069 	CHECK_RGBA_RANGE(blue, Blue);
3070 
3071 	RETURN_LONG(gdImageColorResolve(im, red, green, blue));
3072 }
3073 /* }}} */
3074 
3075 /* {{{ proto int imagecolorexact(resource im, int red, int green, int blue)
3076    Get the index of the specified color */
PHP_FUNCTION(imagecolorexact)3077 PHP_FUNCTION(imagecolorexact)
3078 {
3079 	zval *IM;
3080 	zend_long red, green, blue;
3081 	gdImagePtr im;
3082 
3083 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &red, &green, &blue) == FAILURE) {
3084 		return;
3085 	}
3086 
3087 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3088 		RETURN_FALSE;
3089 	}
3090 
3091 	CHECK_RGBA_RANGE(red, Red);
3092 	CHECK_RGBA_RANGE(green, Green);
3093 	CHECK_RGBA_RANGE(blue, Blue);
3094 
3095 	RETURN_LONG(gdImageColorExact(im, red, green, blue));
3096 }
3097 /* }}} */
3098 
3099 /* {{{ proto bool imagecolorset(resource im, int col, int red, int green, int blue)
3100    Set the color for the specified palette index */
PHP_FUNCTION(imagecolorset)3101 PHP_FUNCTION(imagecolorset)
3102 {
3103 	zval *IM;
3104 	zend_long color, red, green, blue, alpha = 0;
3105 	int col;
3106 	gdImagePtr im;
3107 
3108 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll|l", &IM, &color, &red, &green, &blue, &alpha) == FAILURE) {
3109 		return;
3110 	}
3111 
3112 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3113 		RETURN_FALSE;
3114 	}
3115 
3116 	CHECK_RGBA_RANGE(red, Red);
3117 	CHECK_RGBA_RANGE(green, Green);
3118 	CHECK_RGBA_RANGE(blue, Blue);
3119 	CHECK_RGBA_RANGE(alpha, Alpha);
3120 
3121 	col = color;
3122 
3123 	if (col >= 0 && col < gdImageColorsTotal(im)) {
3124 		im->red[col]   = red;
3125 		im->green[col] = green;
3126 		im->blue[col]  = blue;
3127 		im->alpha[col]  = alpha;
3128 	} else {
3129 		RETURN_FALSE;
3130 	}
3131 }
3132 /* }}} */
3133 
3134 /* {{{ proto array imagecolorsforindex(resource im, int col)
3135    Get the colors for an index */
PHP_FUNCTION(imagecolorsforindex)3136 PHP_FUNCTION(imagecolorsforindex)
3137 {
3138 	zval *IM;
3139 	zend_long index;
3140 	int col;
3141 	gdImagePtr im;
3142 
3143 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &index) == FAILURE) {
3144 		return;
3145 	}
3146 
3147 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3148 		RETURN_FALSE;
3149 	}
3150 
3151 	col = index;
3152 
3153 	if ((col >= 0 && gdImageTrueColor(im)) || (!gdImageTrueColor(im) && col >= 0 && col < gdImageColorsTotal(im))) {
3154 		array_init(return_value);
3155 
3156 		add_assoc_long(return_value,"red",  gdImageRed(im,col));
3157 		add_assoc_long(return_value,"green", gdImageGreen(im,col));
3158 		add_assoc_long(return_value,"blue", gdImageBlue(im,col));
3159 		add_assoc_long(return_value,"alpha", gdImageAlpha(im,col));
3160 	} else {
3161 		php_error_docref(NULL, E_WARNING, "Color index %d out of range", col);
3162 		RETURN_FALSE;
3163 	}
3164 }
3165 /* }}} */
3166 
3167 /* {{{ proto bool imagegammacorrect(resource im, float inputgamma, float outputgamma)
3168    Apply a gamma correction to a GD image */
PHP_FUNCTION(imagegammacorrect)3169 PHP_FUNCTION(imagegammacorrect)
3170 {
3171 	zval *IM;
3172 	gdImagePtr im;
3173 	int i;
3174 	double input, output, gamma;
3175 
3176 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rdd", &IM, &input, &output) == FAILURE) {
3177 		return;
3178 	}
3179 
3180 	if ( input <= 0.0 || output <= 0.0 ) {
3181 		php_error_docref(NULL, E_WARNING, "Gamma values should be positive");
3182 		RETURN_FALSE;
3183 	}
3184 
3185 	gamma = input / output;
3186 
3187 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3188 		RETURN_FALSE;
3189 	}
3190 
3191 	if (gdImageTrueColor(im))	{
3192 		int x, y, c;
3193 
3194 		for (y = 0; y < gdImageSY(im); y++)	{
3195 			for (x = 0; x < gdImageSX(im); x++)	{
3196 				c = gdImageGetPixel(im, x, y);
3197 				gdImageSetPixel(im, x, y,
3198 					gdTrueColorAlpha(
3199 						(int) ((pow((gdTrueColorGetRed(c)   / 255.0), gamma) * 255) + .5),
3200 						(int) ((pow((gdTrueColorGetGreen(c) / 255.0), gamma) * 255) + .5),
3201 						(int) ((pow((gdTrueColorGetBlue(c)  / 255.0), gamma) * 255) + .5),
3202 						gdTrueColorGetAlpha(c)
3203 					)
3204 				);
3205 			}
3206 		}
3207 		RETURN_TRUE;
3208 	}
3209 
3210 	for (i = 0; i < gdImageColorsTotal(im); i++) {
3211 		im->red[i]   = (int)((pow((im->red[i]   / 255.0), gamma) * 255) + .5);
3212 		im->green[i] = (int)((pow((im->green[i] / 255.0), gamma) * 255) + .5);
3213 		im->blue[i]  = (int)((pow((im->blue[i]  / 255.0), gamma) * 255) + .5);
3214 	}
3215 
3216 	RETURN_TRUE;
3217 }
3218 /* }}} */
3219 
3220 /* {{{ proto bool imagesetpixel(resource im, int x, int y, int col)
3221    Set a single pixel */
PHP_FUNCTION(imagesetpixel)3222 PHP_FUNCTION(imagesetpixel)
3223 {
3224 	zval *IM;
3225 	zend_long x, y, col;
3226 	gdImagePtr im;
3227 
3228 	ZEND_PARSE_PARAMETERS_START(4, 4)
3229 		Z_PARAM_RESOURCE(IM)
3230 		Z_PARAM_LONG(x)
3231 		Z_PARAM_LONG(y)
3232 		Z_PARAM_LONG(col)
3233 	ZEND_PARSE_PARAMETERS_END();
3234 
3235 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3236 		RETURN_FALSE;
3237 	}
3238 
3239 	gdImageSetPixel(im, x, y, col);
3240 	RETURN_TRUE;
3241 }
3242 /* }}} */
3243 
3244 /* {{{ proto bool imageline(resource im, int x1, int y1, int x2, int y2, int col)
3245    Draw a line */
PHP_FUNCTION(imageline)3246 PHP_FUNCTION(imageline)
3247 {
3248 	zval *IM;
3249 	zend_long x1, y1, x2, y2, col;
3250 	gdImagePtr im;
3251 
3252 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &x1, &y1, &x2, &y2, &col) == FAILURE) {
3253 		return;
3254 	}
3255 
3256 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3257 		RETURN_FALSE;
3258 	}
3259 
3260 	if (im->AA) {
3261 		gdImageSetAntiAliased(im, col);
3262 		col = gdAntiAliased;
3263 	}
3264 	gdImageLine(im, x1, y1, x2, y2, col);
3265 	RETURN_TRUE;
3266 }
3267 /* }}} */
3268 
3269 /* {{{ proto bool imagedashedline(resource im, int x1, int y1, int x2, int y2, int col)
3270    Draw a dashed line */
PHP_FUNCTION(imagedashedline)3271 PHP_FUNCTION(imagedashedline)
3272 {
3273 	zval *IM;
3274 	zend_long x1, y1, x2, y2, col;
3275 	gdImagePtr im;
3276 
3277 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &x1, &y1, &x2, &y2, &col) == FAILURE) {
3278 		return;
3279 	}
3280 
3281 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3282 		RETURN_FALSE;
3283 	}
3284 
3285 	gdImageDashedLine(im, x1, y1, x2, y2, col);
3286 	RETURN_TRUE;
3287 }
3288 /* }}} */
3289 
3290 /* {{{ proto bool imagerectangle(resource im, int x1, int y1, int x2, int y2, int col)
3291    Draw a rectangle */
PHP_FUNCTION(imagerectangle)3292 PHP_FUNCTION(imagerectangle)
3293 {
3294 	zval *IM;
3295 	zend_long x1, y1, x2, y2, col;
3296 	gdImagePtr im;
3297 
3298 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &x1, &y1, &x2, &y2, &col) == FAILURE) {
3299 		return;
3300 	}
3301 
3302 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3303 		RETURN_FALSE;
3304 	}
3305 
3306 	gdImageRectangle(im, x1, y1, x2, y2, col);
3307 	RETURN_TRUE;
3308 }
3309 /* }}} */
3310 
3311 /* {{{ proto bool imagefilledrectangle(resource im, int x1, int y1, int x2, int y2, int col)
3312    Draw a filled rectangle */
PHP_FUNCTION(imagefilledrectangle)3313 PHP_FUNCTION(imagefilledrectangle)
3314 {
3315 	zval *IM;
3316 	zend_long x1, y1, x2, y2, col;
3317 	gdImagePtr im;
3318 
3319 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &x1, &y1, &x2, &y2, &col) == FAILURE) {
3320 		return;
3321 	}
3322 
3323 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3324 		RETURN_FALSE;
3325 	}
3326 	gdImageFilledRectangle(im, x1, y1, x2, y2, col);
3327 	RETURN_TRUE;
3328 }
3329 /* }}} */
3330 
3331 /* {{{ proto bool imagearc(resource im, int cx, int cy, int w, int h, int s, int e, int col)
3332    Draw a partial ellipse */
PHP_FUNCTION(imagearc)3333 PHP_FUNCTION(imagearc)
3334 {
3335 	zval *IM;
3336 	zend_long cx, cy, w, h, ST, E, col;
3337 	gdImagePtr im;
3338 	int e, st;
3339 
3340 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllllll", &IM, &cx, &cy, &w, &h, &ST, &E, &col) == FAILURE) {
3341 		return;
3342 	}
3343 
3344 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3345 		RETURN_FALSE;
3346 	}
3347 
3348 	e = E;
3349 	if (e < 0) {
3350 		e %= 360;
3351 	}
3352 
3353 	st = ST;
3354 	if (st < 0) {
3355 		st %= 360;
3356 	}
3357 
3358 	gdImageArc(im, cx, cy, w, h, st, e, col);
3359 	RETURN_TRUE;
3360 }
3361 /* }}} */
3362 
3363 /* {{{ proto bool imageellipse(resource im, int cx, int cy, int w, int h, int color)
3364    Draw an ellipse */
PHP_FUNCTION(imageellipse)3365 PHP_FUNCTION(imageellipse)
3366 {
3367 	zval *IM;
3368 	zend_long cx, cy, w, h, color;
3369 	gdImagePtr im;
3370 
3371 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllll", &IM, &cx, &cy, &w, &h, &color) == FAILURE) {
3372 		return;
3373 	}
3374 
3375 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3376 		RETURN_FALSE;
3377 	}
3378 
3379 	gdImageEllipse(im, cx, cy, w, h, color);
3380 	RETURN_TRUE;
3381 }
3382 /* }}} */
3383 
3384 /* {{{ proto bool imagefilltoborder(resource im, int x, int y, int border, int col)
3385    Flood fill to specific color */
PHP_FUNCTION(imagefilltoborder)3386 PHP_FUNCTION(imagefilltoborder)
3387 {
3388 	zval *IM;
3389 	zend_long x, y, border, col;
3390 	gdImagePtr im;
3391 
3392 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &IM, &x, &y, &border, &col) == FAILURE) {
3393 		return;
3394 	}
3395 
3396 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3397 		RETURN_FALSE;
3398 	}
3399 
3400 	gdImageFillToBorder(im, x, y, border, col);
3401 	RETURN_TRUE;
3402 }
3403 /* }}} */
3404 
3405 /* {{{ proto bool imagefill(resource im, int x, int y, int col)
3406    Flood fill */
PHP_FUNCTION(imagefill)3407 PHP_FUNCTION(imagefill)
3408 {
3409 	zval *IM;
3410 	zend_long x, y, col;
3411 	gdImagePtr im;
3412 
3413 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll", &IM, &x, &y, &col) == FAILURE) {
3414 		return;
3415 	}
3416 
3417 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3418 		RETURN_FALSE;
3419 	}
3420 
3421 	gdImageFill(im, x, y, col);
3422 	RETURN_TRUE;
3423 }
3424 /* }}} */
3425 
3426 /* {{{ proto int imagecolorstotal(resource im)
3427    Find out the number of colors in an image's palette */
PHP_FUNCTION(imagecolorstotal)3428 PHP_FUNCTION(imagecolorstotal)
3429 {
3430 	zval *IM;
3431 	gdImagePtr im;
3432 
3433 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) {
3434 		return;
3435 	}
3436 
3437 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3438 		RETURN_FALSE;
3439 	}
3440 
3441 	RETURN_LONG(gdImageColorsTotal(im));
3442 }
3443 /* }}} */
3444 
3445 /* {{{ proto int imagecolortransparent(resource im [, int col])
3446    Define a color as transparent */
PHP_FUNCTION(imagecolortransparent)3447 PHP_FUNCTION(imagecolortransparent)
3448 {
3449 	zval *IM;
3450 	zend_long COL = 0;
3451 	gdImagePtr im;
3452 	int argc = ZEND_NUM_ARGS();
3453 
3454 	if (zend_parse_parameters(argc, "r|l", &IM, &COL) == FAILURE) {
3455 		return;
3456 	}
3457 
3458 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3459 		RETURN_FALSE;
3460 	}
3461 
3462 	if (argc > 1) {
3463 		gdImageColorTransparent(im, COL);
3464 	}
3465 
3466 	RETURN_LONG(gdImageGetTransparent(im));
3467 }
3468 /* }}} */
3469 
3470 /* {{{ proto int imageinterlace(resource im [, int interlace])
3471    Enable or disable interlace */
PHP_FUNCTION(imageinterlace)3472 PHP_FUNCTION(imageinterlace)
3473 {
3474 	zval *IM;
3475 	int argc = ZEND_NUM_ARGS();
3476 	zend_long INT = 0;
3477 	gdImagePtr im;
3478 
3479 	if (zend_parse_parameters(argc, "r|l", &IM, &INT) == FAILURE) {
3480 		return;
3481 	}
3482 
3483 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3484 		RETURN_FALSE;
3485 	}
3486 
3487 	if (argc > 1) {
3488 		gdImageInterlace(im, INT);
3489 	}
3490 
3491 	RETURN_LONG(gdImageGetInterlaced(im));
3492 }
3493 /* }}} */
3494 
3495 /* {{{ php_imagepolygon
3496    arg = -1 open polygon
3497    arg = 0  normal polygon
3498    arg = 1  filled polygon */
3499 /* im, points, num_points, col */
php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS,int filled)3500 static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled)
3501 {
3502 	zval *IM, *POINTS;
3503 	zend_long NPOINTS, COL;
3504 	zval *var = NULL;
3505 	gdImagePtr im;
3506 	gdPointPtr points;
3507 	int npoints, col, nelem, i;
3508 
3509 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rall", &IM, &POINTS, &NPOINTS, &COL) == FAILURE) {
3510 		return;
3511 	}
3512 
3513 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3514 		RETURN_FALSE;
3515 	}
3516 
3517 	npoints = NPOINTS;
3518 	col = COL;
3519 
3520 	nelem = zend_hash_num_elements(Z_ARRVAL_P(POINTS));
3521 	if (nelem < 6) {
3522 		php_error_docref(NULL, E_WARNING, "You must have at least 3 points in your array");
3523 		RETURN_FALSE;
3524 	}
3525 	if (npoints <= 0) {
3526 		php_error_docref(NULL, E_WARNING, "You must give a positive number of points");
3527 		RETURN_FALSE;
3528 	}
3529 	if (nelem < npoints * 2) {
3530 		php_error_docref(NULL, E_WARNING, "Trying to use %d points in array with only %d points", npoints, nelem/2);
3531 		RETURN_FALSE;
3532 	}
3533 
3534 	points = (gdPointPtr) safe_emalloc(npoints, sizeof(gdPoint), 0);
3535 
3536 	for (i = 0; i < npoints; i++) {
3537 		if ((var = zend_hash_index_find(Z_ARRVAL_P(POINTS), (i * 2))) != NULL) {
3538 			points[i].x = zval_get_long(var);
3539 		}
3540 		if ((var = zend_hash_index_find(Z_ARRVAL_P(POINTS), (i * 2) + 1)) != NULL) {
3541 			points[i].y = zval_get_long(var);
3542 		}
3543 	}
3544 
3545 	if (im->AA) {
3546 		gdImageSetAntiAliased(im, col);
3547 		col = gdAntiAliased;
3548 	}
3549 	switch (filled) {
3550 		case -1:
3551 			gdImageOpenPolygon(im, points, npoints, col);
3552 			break;
3553 		case 0:
3554 			gdImagePolygon(im, points, npoints, col);
3555 			break;
3556 		case 1:
3557 			gdImageFilledPolygon(im, points, npoints, col);
3558 			break;
3559 	}
3560 
3561 	efree(points);
3562 	RETURN_TRUE;
3563 }
3564 /* }}} */
3565 
3566 /* {{{ proto bool imagepolygon(resource im, array point, int num_points, int col)
3567    Draw a polygon */
PHP_FUNCTION(imagepolygon)3568 PHP_FUNCTION(imagepolygon)
3569 {
3570 	php_imagepolygon(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
3571 }
3572 /* }}} */
3573 
3574 /* {{{ proto bool imageopenpolygon(resource im, array point, int num_points, int col)
3575    Draw a polygon */
PHP_FUNCTION(imageopenpolygon)3576 PHP_FUNCTION(imageopenpolygon)
3577 {
3578 	php_imagepolygon(INTERNAL_FUNCTION_PARAM_PASSTHRU, -1);
3579 }
3580 /* }}} */
3581 
3582 /* {{{ proto bool imagefilledpolygon(resource im, array point, int num_points, int col)
3583    Draw a filled polygon */
PHP_FUNCTION(imagefilledpolygon)3584 PHP_FUNCTION(imagefilledpolygon)
3585 {
3586 	php_imagepolygon(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
3587 }
3588 /* }}} */
3589 
3590 /* {{{ php_find_gd_font
3591  */
php_find_gd_font(int size)3592 static gdFontPtr php_find_gd_font(int size)
3593 {
3594 	gdFontPtr font;
3595 
3596 	switch (size) {
3597 		case 1:
3598 			font = gdFontTiny;
3599 			break;
3600 		case 2:
3601 			font = gdFontSmall;
3602 			break;
3603 		case 3:
3604 			font = gdFontMediumBold;
3605 			break;
3606 		case 4:
3607 			font = gdFontLarge;
3608 			break;
3609 		case 5:
3610 			font = gdFontGiant;
3611 			break;
3612 		default: {
3613 			 zval *zv = zend_hash_index_find(&EG(regular_list), size - 5);
3614 			 if (!zv || (Z_RES_P(zv))->type != le_gd_font) {
3615 				 if (size < 1) {
3616 					 font = gdFontTiny;
3617 				 } else {
3618 					 font = gdFontGiant;
3619 				 }
3620 			 } else {
3621 				 font = (gdFontPtr)Z_RES_P(zv)->ptr;
3622 			 }
3623 		 }
3624 		 break;
3625 	}
3626 
3627 	return font;
3628 }
3629 /* }}} */
3630 
3631 /* {{{ php_imagefontsize
3632  * arg = 0  ImageFontWidth
3633  * arg = 1  ImageFontHeight
3634  */
php_imagefontsize(INTERNAL_FUNCTION_PARAMETERS,int arg)3635 static void php_imagefontsize(INTERNAL_FUNCTION_PARAMETERS, int arg)
3636 {
3637 	zend_long SIZE;
3638 	gdFontPtr font;
3639 
3640 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &SIZE) == FAILURE) {
3641 		return;
3642 	}
3643 
3644 	font = php_find_gd_font(SIZE);
3645 	RETURN_LONG(arg ? font->h : font->w);
3646 }
3647 /* }}} */
3648 
3649 /* {{{ proto int imagefontwidth(int font)
3650    Get font width */
PHP_FUNCTION(imagefontwidth)3651 PHP_FUNCTION(imagefontwidth)
3652 {
3653 	php_imagefontsize(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
3654 }
3655 /* }}} */
3656 
3657 /* {{{ proto int imagefontheight(int font)
3658    Get font height */
PHP_FUNCTION(imagefontheight)3659 PHP_FUNCTION(imagefontheight)
3660 {
3661 	php_imagefontsize(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
3662 }
3663 /* }}} */
3664 
3665 /* {{{ php_gdimagecharup
3666  * workaround for a bug in gd 1.2 */
php_gdimagecharup(gdImagePtr im,gdFontPtr f,int x,int y,int c,int color)3667 static void php_gdimagecharup(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color)
3668 {
3669 	int cx, cy, px, py, fline;
3670 	cx = 0;
3671 	cy = 0;
3672 
3673 	if ((c < f->offset) || (c >= (f->offset + f->nchars))) {
3674 		return;
3675 	}
3676 
3677 	fline = (c - f->offset) * f->h * f->w;
3678 	for (py = y; (py > (y - f->w)); py--) {
3679 		for (px = x; (px < (x + f->h)); px++) {
3680 			if (f->data[fline + cy * f->w + cx]) {
3681 				gdImageSetPixel(im, px, py, color);
3682 			}
3683 			cy++;
3684 		}
3685 		cy = 0;
3686 		cx++;
3687 	}
3688 }
3689 /* }}} */
3690 
3691 /* {{{ php_imagechar
3692  * arg = 0  ImageChar
3693  * arg = 1  ImageCharUp
3694  * arg = 2  ImageString
3695  * arg = 3  ImageStringUp
3696  */
php_imagechar(INTERNAL_FUNCTION_PARAMETERS,int mode)3697 static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode)
3698 {
3699 	zval *IM;
3700 	zend_long SIZE, X, Y, COL;
3701 	char *C;
3702 	size_t C_len;
3703 	gdImagePtr im;
3704 	int ch = 0, col, x, y, size, i, l = 0;
3705 	unsigned char *str = NULL;
3706 	gdFontPtr font;
3707 
3708 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlllsl", &IM, &SIZE, &X, &Y, &C, &C_len, &COL) == FAILURE) {
3709 		return;
3710 	}
3711 
3712 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3713 		RETURN_FALSE;
3714 	}
3715 
3716 	col = COL;
3717 
3718 	if (mode < 2) {
3719 		ch = (int)((unsigned char)*C);
3720 	} else {
3721 		str = (unsigned char *) estrndup(C, C_len);
3722 		l = strlen((char *)str);
3723 	}
3724 
3725 	y = Y;
3726 	x = X;
3727 	size = SIZE;
3728 
3729 	font = php_find_gd_font(size);
3730 
3731 	switch (mode) {
3732 		case 0:
3733 			gdImageChar(im, font, x, y, ch, col);
3734 			break;
3735 		case 1:
3736 			php_gdimagecharup(im, font, x, y, ch, col);
3737 			break;
3738 		case 2:
3739 			for (i = 0; (i < l); i++) {
3740 				gdImageChar(im, font, x, y, (int) ((unsigned char) str[i]), col);
3741 				x += font->w;
3742 			}
3743 			break;
3744 		case 3: {
3745 			for (i = 0; (i < l); i++) {
3746 				/* php_gdimagecharup(im, font, x, y, (int) str[i], col); */
3747 				gdImageCharUp(im, font, x, y, (int) str[i], col);
3748 				y -= font->w;
3749 			}
3750 			break;
3751 		}
3752 	}
3753 	if (str) {
3754 		efree(str);
3755 	}
3756 	RETURN_TRUE;
3757 }
3758 /* }}} */
3759 
3760 /* {{{ proto bool imagechar(resource im, int font, int x, int y, string c, int col)
3761    Draw a character */
PHP_FUNCTION(imagechar)3762 PHP_FUNCTION(imagechar)
3763 {
3764 	php_imagechar(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
3765 }
3766 /* }}} */
3767 
3768 /* {{{ proto bool imagecharup(resource im, int font, int x, int y, string c, int col)
3769    Draw a character rotated 90 degrees counter-clockwise */
PHP_FUNCTION(imagecharup)3770 PHP_FUNCTION(imagecharup)
3771 {
3772 	php_imagechar(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
3773 }
3774 /* }}} */
3775 
3776 /* {{{ proto bool imagestring(resource im, int font, int x, int y, string str, int col)
3777    Draw a string horizontally */
PHP_FUNCTION(imagestring)3778 PHP_FUNCTION(imagestring)
3779 {
3780 	php_imagechar(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
3781 }
3782 /* }}} */
3783 
3784 /* {{{ proto bool imagestringup(resource im, int font, int x, int y, string str, int col)
3785    Draw a string vertically - rotated 90 degrees counter-clockwise */
PHP_FUNCTION(imagestringup)3786 PHP_FUNCTION(imagestringup)
3787 {
3788 	php_imagechar(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3);
3789 }
3790 /* }}} */
3791 
3792 /* {{{ proto bool imagecopy(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h)
3793    Copy part of an image */
PHP_FUNCTION(imagecopy)3794 PHP_FUNCTION(imagecopy)
3795 {
3796 	zval *SIM, *DIM;
3797 	zend_long SX, SY, SW, SH, DX, DY;
3798 	gdImagePtr im_dst, im_src;
3799 	int srcH, srcW, srcY, srcX, dstY, dstX;
3800 
3801 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &SW, &SH) == FAILURE) {
3802 		return;
3803 	}
3804 
3805 	if ((im_dst = (gdImagePtr)zend_fetch_resource(Z_RES_P(DIM), "Image", le_gd)) == NULL) {
3806 		RETURN_FALSE;
3807 	}
3808 
3809 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
3810 		RETURN_FALSE;
3811 	}
3812 
3813 	srcX = SX;
3814 	srcY = SY;
3815 	srcH = SH;
3816 	srcW = SW;
3817 	dstX = DX;
3818 	dstY = DY;
3819 
3820 	gdImageCopy(im_dst, im_src, dstX, dstY, srcX, srcY, srcW, srcH);
3821 	RETURN_TRUE;
3822 }
3823 /* }}} */
3824 
3825 /* {{{ proto bool imagecopymerge(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct)
3826    Merge one part of an image with another */
PHP_FUNCTION(imagecopymerge)3827 PHP_FUNCTION(imagecopymerge)
3828 {
3829 	zval *SIM, *DIM;
3830 	zend_long SX, SY, SW, SH, DX, DY, PCT;
3831 	gdImagePtr im_dst, im_src;
3832 	int srcH, srcW, srcY, srcX, dstY, dstX, pct;
3833 
3834 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrlllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &SW, &SH, &PCT) == FAILURE) {
3835 		return;
3836 	}
3837 
3838 	if ((im_dst = (gdImagePtr)zend_fetch_resource(Z_RES_P(DIM), "Image", le_gd)) == NULL) {
3839 		RETURN_FALSE;
3840 	}
3841 
3842 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
3843 		RETURN_FALSE;
3844 	}
3845 
3846 	srcX = SX;
3847 	srcY = SY;
3848 	srcH = SH;
3849 	srcW = SW;
3850 	dstX = DX;
3851 	dstY = DY;
3852 	pct  = PCT;
3853 
3854 	gdImageCopyMerge(im_dst, im_src, dstX, dstY, srcX, srcY, srcW, srcH, pct);
3855 	RETURN_TRUE;
3856 }
3857 /* }}} */
3858 
3859 /* {{{ proto bool imagecopymergegray(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct)
3860    Merge one part of an image with another */
PHP_FUNCTION(imagecopymergegray)3861 PHP_FUNCTION(imagecopymergegray)
3862 {
3863 	zval *SIM, *DIM;
3864 	zend_long SX, SY, SW, SH, DX, DY, PCT;
3865 	gdImagePtr im_dst, im_src;
3866 	int srcH, srcW, srcY, srcX, dstY, dstX, pct;
3867 
3868 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrlllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &SW, &SH, &PCT) == FAILURE) {
3869 		return;
3870 	}
3871 
3872 	if ((im_dst = (gdImagePtr)zend_fetch_resource(Z_RES_P(DIM), "Image", le_gd)) == NULL) {
3873 		RETURN_FALSE;
3874 	}
3875 
3876 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
3877 		RETURN_FALSE;
3878 	}
3879 
3880 	srcX = SX;
3881 	srcY = SY;
3882 	srcH = SH;
3883 	srcW = SW;
3884 	dstX = DX;
3885 	dstY = DY;
3886 	pct  = PCT;
3887 
3888 	gdImageCopyMergeGray(im_dst, im_src, dstX, dstY, srcX, srcY, srcW, srcH, pct);
3889 	RETURN_TRUE;
3890 }
3891 /* }}} */
3892 
3893 /* {{{ proto bool imagecopyresized(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)
3894    Copy and resize part of an image */
PHP_FUNCTION(imagecopyresized)3895 PHP_FUNCTION(imagecopyresized)
3896 {
3897 	zval *SIM, *DIM;
3898 	zend_long SX, SY, SW, SH, DX, DY, DW, DH;
3899 	gdImagePtr im_dst, im_src;
3900 	int srcH, srcW, dstH, dstW, srcY, srcX, dstY, dstX;
3901 
3902 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rrllllllll", &DIM, &SIM, &DX, &DY, &SX, &SY, &DW, &DH, &SW, &SH) == FAILURE) {
3903 		return;
3904 	}
3905 
3906 	if ((im_dst = (gdImagePtr)zend_fetch_resource(Z_RES_P(DIM), "Image", le_gd)) == NULL) {
3907 		RETURN_FALSE;
3908 	}
3909 
3910 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
3911 		RETURN_FALSE;
3912 	}
3913 
3914 	srcX = SX;
3915 	srcY = SY;
3916 	srcH = SH;
3917 	srcW = SW;
3918 	dstX = DX;
3919 	dstY = DY;
3920 	dstH = DH;
3921 	dstW = DW;
3922 
3923 	if (dstW <= 0 || dstH <= 0 || srcW <= 0 || srcH <= 0) {
3924 		php_error_docref(NULL, E_WARNING, "Invalid image dimensions");
3925 		RETURN_FALSE;
3926 	}
3927 
3928 	gdImageCopyResized(im_dst, im_src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH);
3929 	RETURN_TRUE;
3930 }
3931 /* }}} */
3932 
3933 /* {{{ proto int imagesx(resource im)
3934    Get image width */
PHP_FUNCTION(imagesx)3935 PHP_FUNCTION(imagesx)
3936 {
3937 	zval *IM;
3938 	gdImagePtr im;
3939 
3940 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) {
3941 		return;
3942 	}
3943 
3944 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3945 		RETURN_FALSE;
3946 	}
3947 
3948 	RETURN_LONG(gdImageSX(im));
3949 }
3950 /* }}} */
3951 
3952 /* {{{ proto int imagesy(resource im)
3953    Get image height */
PHP_FUNCTION(imagesy)3954 PHP_FUNCTION(imagesy)
3955 {
3956 	zval *IM;
3957 	gdImagePtr im;
3958 
3959 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) {
3960 		return;
3961 	}
3962 
3963 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
3964 		RETURN_FALSE;
3965 	}
3966 
3967 	RETURN_LONG(gdImageSY(im));
3968 }
3969 /* }}} */
3970 
3971 /* {{{ proto bool imagesetclip(resource im, int x1, int y1, int x2, int y2)
3972    Set the clipping rectangle. */
PHP_FUNCTION(imagesetclip)3973 PHP_FUNCTION(imagesetclip)
3974 {
3975 	zval *im_zval;
3976 	gdImagePtr im;
3977 	zend_long x1, y1, x2, y2;
3978 
3979 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll", &im_zval, &x1, &y1, &x2, &y2) == FAILURE) {
3980 		return;
3981 	}
3982 
3983 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(im_zval), "Image", le_gd)) == NULL) {
3984 		RETURN_FALSE;
3985 	}
3986 
3987 	gdImageSetClip(im, x1, y1, x2, y2);
3988 	RETURN_TRUE;
3989 }
3990 /* }}} */
3991 
3992 /* {{{ proto array imagegetclip(resource im)
3993    Get the clipping rectangle. */
PHP_FUNCTION(imagegetclip)3994 PHP_FUNCTION(imagegetclip)
3995 {
3996 	zval *im_zval;
3997 	gdImagePtr im;
3998 	int x1, y1, x2, y2;
3999 
4000 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &im_zval) == FAILURE) {
4001 		return;
4002 	}
4003 
4004 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(im_zval), "Image", le_gd)) == NULL) {
4005 		RETURN_FALSE;
4006 	}
4007 
4008 	gdImageGetClip(im, &x1, &y1, &x2, &y2);
4009 
4010 	array_init(return_value);
4011 	add_next_index_long(return_value, x1);
4012 	add_next_index_long(return_value, y1);
4013 	add_next_index_long(return_value, x2);
4014 	add_next_index_long(return_value, y2);
4015 }
4016 /* }}} */
4017 
4018 #define TTFTEXT_DRAW 0
4019 #define TTFTEXT_BBOX 1
4020 
4021 #ifdef HAVE_GD_FREETYPE
4022 /* {{{ proto array imageftbbox(float size, float angle, string font_file, string text [, array extrainfo])
4023    Give the bounding box of a text using fonts via freetype2 */
PHP_FUNCTION(imageftbbox)4024 PHP_FUNCTION(imageftbbox)
4025 {
4026 	php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_BBOX, 1);
4027 }
4028 /* }}} */
4029 
4030 /* {{{ proto array imagefttext(resource im, float size, float angle, int x, int y, int col, string font_file, string text [, array extrainfo])
4031    Write text to the image using fonts via freetype2 */
PHP_FUNCTION(imagefttext)4032 PHP_FUNCTION(imagefttext)
4033 {
4034 	php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_DRAW, 1);
4035 }
4036 /* }}} */
4037 
4038 /* {{{ proto array imagettfbbox(float size, float angle, string font_file, string text)
4039    Give the bounding box of a text using TrueType fonts */
PHP_FUNCTION(imagettfbbox)4040 PHP_FUNCTION(imagettfbbox)
4041 {
4042 	php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_BBOX, 0);
4043 }
4044 /* }}} */
4045 
4046 /* {{{ proto array imagettftext(resource im, float size, float angle, int x, int y, int col, string font_file, string text)
4047    Write text to the image using a TrueType font */
PHP_FUNCTION(imagettftext)4048 PHP_FUNCTION(imagettftext)
4049 {
4050 	php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_DRAW, 0);
4051 }
4052 /* }}} */
4053 
4054 /* {{{ php_imagettftext_common
4055  */
php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS,int mode,int extended)4056 static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int extended)
4057 {
4058 	zval *IM, *EXT = NULL;
4059 	gdImagePtr im=NULL;
4060 	zend_long col = -1, x = 0, y = 0;
4061 	size_t str_len, fontname_len;
4062 	int i, brect[8];
4063 	double ptsize, angle;
4064 	char *str = NULL, *fontname = NULL;
4065 	char *error = NULL;
4066 	int argc = ZEND_NUM_ARGS();
4067 	gdFTStringExtra strex = {0};
4068 
4069 	if (mode == TTFTEXT_BBOX) {
4070 		if (argc < 4 || argc > ((extended) ? 5 : 4)) {
4071 			ZEND_WRONG_PARAM_COUNT();
4072 		} else if (zend_parse_parameters(argc, "ddss|a", &ptsize, &angle, &fontname, &fontname_len, &str, &str_len, &EXT) == FAILURE) {
4073 			RETURN_FALSE;
4074 		}
4075 	} else {
4076 		if (argc < 8 || argc > ((extended) ? 9 : 8)) {
4077 			ZEND_WRONG_PARAM_COUNT();
4078 		} else if (zend_parse_parameters(argc, "rddlllss|a", &IM, &ptsize, &angle, &x, &y, &col, &fontname, &fontname_len, &str, &str_len, &EXT) == FAILURE) {
4079 			RETURN_FALSE;
4080 		}
4081 		if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4082 			RETURN_FALSE;
4083 		}
4084 	}
4085 
4086 	/* convert angle to radians */
4087 	angle = angle * (M_PI/180);
4088 
4089 	if (extended && EXT) {	/* parse extended info */
4090 		zval *item;
4091 		zend_string *key;
4092 
4093 		/* walk the assoc array */
4094 		ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(EXT), key, item) {
4095 			if (key == NULL) {
4096 				continue;
4097 			}
4098 			if (strcmp("linespacing", ZSTR_VAL(key)) == 0) {
4099 				strex.flags |= gdFTEX_LINESPACE;
4100 				strex.linespacing = zval_get_double(item);
4101 			}
4102 		} ZEND_HASH_FOREACH_END();
4103 	}
4104 
4105 #ifdef VIRTUAL_DIR
4106 	{
4107 		char tmp_font_path[MAXPATHLEN];
4108 
4109 		if (!VCWD_REALPATH(fontname, tmp_font_path)) {
4110 			fontname = NULL;
4111 		}
4112 	}
4113 #endif /* VIRTUAL_DIR */
4114 
4115 	PHP_GD_CHECK_OPEN_BASEDIR(fontname, "Invalid font filename");
4116 
4117 	if (extended) {
4118 		error = gdImageStringFTEx(im, brect, col, fontname, ptsize, angle, x, y, str, &strex);
4119 	} else {
4120 		error = gdImageStringFT(im, brect, col, fontname, ptsize, angle, x, y, str);
4121 	}
4122 
4123 	if (error) {
4124 		php_error_docref(NULL, E_WARNING, "%s", error);
4125 		RETURN_FALSE;
4126 	}
4127 
4128 	array_init(return_value);
4129 
4130 	/* return array with the text's bounding box */
4131 	for (i = 0; i < 8; i++) {
4132 		add_next_index_long(return_value, brect[i]);
4133 	}
4134 }
4135 /* }}} */
4136 #endif /* HAVE_GD_FREETYPE */
4137 
4138 /* {{{ proto bool image2wbmp(resource im [, string filename [, int foreground]])
4139    Output WBMP image to browser or file */
PHP_FUNCTION(image2wbmp)4140 PHP_FUNCTION(image2wbmp)
4141 {
4142 	_php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_CONVERT_WBM, "WBMP", NULL);
4143 }
4144 /* }}} */
4145 
4146 #if defined(HAVE_GD_JPG)
4147 /* {{{ proto bool jpeg2wbmp(string f_org, string f_dest, int d_height, int d_width, int threshold)
4148    Convert JPEG image to WBMP image */
PHP_FUNCTION(jpeg2wbmp)4149 PHP_FUNCTION(jpeg2wbmp)
4150 {
4151 	_php_image_convert(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG);
4152 }
4153 /* }}} */
4154 #endif
4155 
4156 #if defined(HAVE_GD_PNG)
4157 /* {{{ proto bool png2wbmp(string f_org, string f_dest, int d_height, int d_width, int threshold)
4158    Convert PNG image to WBMP image */
PHP_FUNCTION(png2wbmp)4159 PHP_FUNCTION(png2wbmp)
4160 {
4161 	_php_image_convert(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG);
4162 }
4163 /* }}} */
4164 #endif
4165 
4166 /* {{{ _php_image_convert
4167  * _php_image_convert converts jpeg/png images to wbmp and resizes them as needed  */
_php_image_convert(INTERNAL_FUNCTION_PARAMETERS,int image_type)4168 static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
4169 {
4170 	char *f_org, *f_dest;
4171 	size_t f_org_len, f_dest_len;
4172 	zend_long height, width, threshold;
4173 	gdImagePtr im_org, im_dest, im_tmp;
4174 	char *fn_org = NULL;
4175 	char *fn_dest = NULL;
4176 	FILE *org, *dest;
4177 	int dest_height = -1;
4178 	int dest_width = -1;
4179 	int org_height, org_width;
4180 	int white, black;
4181 	int color, color_org, median;
4182 	int int_threshold;
4183 	int x, y;
4184 	float x_ratio, y_ratio;
4185 #ifdef HAVE_GD_JPG
4186     zend_long ignore_warning;
4187 #endif
4188 
4189 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "pplll", &f_org, &f_org_len, &f_dest, &f_dest_len, &height, &width, &threshold) == FAILURE) {
4190 		return;
4191 	}
4192 
4193 	fn_org  = f_org;
4194 	fn_dest = f_dest;
4195 	dest_height = height;
4196 	dest_width = width;
4197 	int_threshold = threshold;
4198 
4199 	/* Check threshold value */
4200 	if (int_threshold < 0 || int_threshold > 8) {
4201 		php_error_docref(NULL, E_WARNING, "Invalid threshold value '%d'", int_threshold);
4202 		RETURN_FALSE;
4203 	}
4204 
4205 	/* Check origin file */
4206 	PHP_GD_CHECK_OPEN_BASEDIR(fn_org, "Invalid origin filename");
4207 
4208 	/* Check destination file */
4209 	PHP_GD_CHECK_OPEN_BASEDIR(fn_dest, "Invalid destination filename");
4210 
4211 	/* Open origin file */
4212 	org = VCWD_FOPEN(fn_org, "rb");
4213 	if (!org) {
4214 		php_error_docref(NULL, E_WARNING, "Unable to open '%s' for reading", fn_org);
4215 		RETURN_FALSE;
4216 	}
4217 
4218 	/* Open destination file */
4219 	dest = VCWD_FOPEN(fn_dest, "wb");
4220 	if (!dest) {
4221 		php_error_docref(NULL, E_WARNING, "Unable to open '%s' for writing", fn_dest);
4222         fclose(org);
4223 		RETURN_FALSE;
4224 	}
4225 
4226 	switch (image_type) {
4227 
4228 #ifdef HAVE_GD_JPG
4229 		case PHP_GDIMG_TYPE_JPG:
4230 			ignore_warning = INI_INT("gd.jpeg_ignore_warning");
4231 			im_org = gdImageCreateFromJpegEx(org, ignore_warning);
4232 			if (im_org == NULL) {
4233 				php_error_docref(NULL, E_WARNING, "Unable to open '%s' Not a valid JPEG file", fn_dest);
4234                 fclose(org);
4235                 fclose(dest);
4236 				RETURN_FALSE;
4237 			}
4238 			break;
4239 #endif /* HAVE_GD_JPG */
4240 
4241 #ifdef HAVE_GD_PNG
4242 		case PHP_GDIMG_TYPE_PNG:
4243 			im_org = gdImageCreateFromPng(org);
4244 			if (im_org == NULL) {
4245 				php_error_docref(NULL, E_WARNING, "Unable to open '%s' Not a valid PNG file", fn_dest);
4246                 fclose(org);
4247                 fclose(dest);
4248 				RETURN_FALSE;
4249 			}
4250 			break;
4251 #endif /* HAVE_GD_PNG */
4252 
4253 		default:
4254 			php_error_docref(NULL, E_WARNING, "Format not supported");
4255             fclose(org);
4256             fclose(dest);
4257 			RETURN_FALSE;
4258 			break;
4259 	}
4260 
4261 	fclose(org);
4262 
4263 	org_width  = gdImageSX (im_org);
4264 	org_height = gdImageSY (im_org);
4265 
4266 	x_ratio = (float) org_width / (float) dest_width;
4267 	y_ratio = (float) org_height / (float) dest_height;
4268 
4269 	if (x_ratio > 1 && y_ratio > 1) {
4270 		if (y_ratio > x_ratio) {
4271 			x_ratio = y_ratio;
4272 		} else {
4273 			y_ratio = x_ratio;
4274 		}
4275 		dest_width = (int) (org_width / x_ratio);
4276 		dest_height = (int) (org_height / y_ratio);
4277 	} else {
4278 		x_ratio = (float) dest_width / (float) org_width;
4279 		y_ratio = (float) dest_height / (float) org_height;
4280 
4281 		if (y_ratio < x_ratio) {
4282 			x_ratio = y_ratio;
4283 		} else {
4284 			y_ratio = x_ratio;
4285 		}
4286 		dest_width = (int) (org_width * x_ratio);
4287 		dest_height = (int) (org_height * y_ratio);
4288 	}
4289 
4290 	im_tmp = gdImageCreate (dest_width, dest_height);
4291 	if (im_tmp == NULL ) {
4292 		php_error_docref(NULL, E_WARNING, "Unable to allocate temporary buffer");
4293         fclose(dest);
4294         gdImageDestroy(im_org);
4295 		RETURN_FALSE;
4296 	}
4297 
4298 	gdImageCopyResized (im_tmp, im_org, 0, 0, 0, 0, dest_width, dest_height, org_width, org_height);
4299 
4300 	gdImageDestroy(im_org);
4301 
4302 	im_dest = gdImageCreate(dest_width, dest_height);
4303 	if (im_dest == NULL) {
4304 		php_error_docref(NULL, E_WARNING, "Unable to allocate destination buffer");
4305         fclose(dest);
4306         gdImageDestroy(im_tmp);
4307 		RETURN_FALSE;
4308 	}
4309 
4310 	white = gdImageColorAllocate(im_dest, 255, 255, 255);
4311 	if (white == -1) {
4312 		php_error_docref(NULL, E_WARNING, "Unable to allocate the colors for the destination buffer");
4313         fclose(dest);
4314         gdImageDestroy(im_tmp);
4315         gdImageDestroy(im_dest);
4316 		RETURN_FALSE;
4317 	}
4318 
4319 	black = gdImageColorAllocate(im_dest, 0, 0, 0);
4320 	if (black == -1) {
4321 		php_error_docref(NULL, E_WARNING, "Unable to allocate the colors for the destination buffer");
4322         fclose(dest);
4323         gdImageDestroy(im_tmp);
4324         gdImageDestroy(im_dest);
4325 		RETURN_FALSE;
4326 	}
4327 
4328 	int_threshold = int_threshold * 32;
4329 
4330 	for (y = 0; y < dest_height; y++) {
4331 		for (x = 0; x < dest_width; x++) {
4332 			color_org = gdImageGetPixel (im_tmp, x, y);
4333 			median = (im_tmp->red[color_org] + im_tmp->green[color_org] + im_tmp->blue[color_org]) / 3;
4334 			if (median < int_threshold) {
4335 				color = black;
4336 			} else {
4337 				color = white;
4338 			}
4339 			gdImageSetPixel (im_dest, x, y, color);
4340 		}
4341 	}
4342 
4343 	gdImageDestroy (im_tmp );
4344 
4345 	gdImageWBMP(im_dest, black , dest);
4346 
4347 	fflush(dest);
4348 	fclose(dest);
4349 
4350 	gdImageDestroy(im_dest);
4351 
4352 	RETURN_TRUE;
4353 }
4354 /* }}} */
4355 
4356 /* Section Filters */
4357 #define PHP_GD_SINGLE_RES	\
4358 	zval *SIM;	\
4359 	gdImagePtr im_src;	\
4360 	if (zend_parse_parameters(1, "r", &SIM) == FAILURE) {	\
4361 		RETURN_FALSE;	\
4362 	}	\
4363 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {	\
4364 		RETURN_FALSE;	\
4365 	}
4366 
php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS)4367 static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS)
4368 {
4369 	PHP_GD_SINGLE_RES
4370 
4371 	if (gdImageNegate(im_src) == 1) {
4372 		RETURN_TRUE;
4373 	}
4374 
4375 	RETURN_FALSE;
4376 }
4377 
php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS)4378 static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS)
4379 {
4380 	PHP_GD_SINGLE_RES
4381 
4382 	if (gdImageGrayScale(im_src) == 1) {
4383 		RETURN_TRUE;
4384 	}
4385 
4386 	RETURN_FALSE;
4387 }
4388 
php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS)4389 static void php_image_filter_brightness(INTERNAL_FUNCTION_PARAMETERS)
4390 {
4391 	zval *SIM;
4392 	gdImagePtr im_src;
4393 	zend_long brightness, tmp;
4394 
4395 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "zll", &SIM, &tmp, &brightness) == FAILURE) {
4396 		RETURN_FALSE;
4397 	}
4398 
4399 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
4400 		RETURN_FALSE;
4401 	}
4402 
4403 	if (gdImageBrightness(im_src, (int)brightness) == 1) {
4404 		RETURN_TRUE;
4405 	}
4406 
4407 	RETURN_FALSE;
4408 }
4409 
php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS)4410 static void php_image_filter_contrast(INTERNAL_FUNCTION_PARAMETERS)
4411 {
4412 	zval *SIM;
4413 	gdImagePtr im_src;
4414 	zend_long contrast, tmp;
4415 
4416 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rll", &SIM, &tmp, &contrast) == FAILURE) {
4417 		RETURN_FALSE;
4418 	}
4419 
4420 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
4421 		RETURN_FALSE;
4422 	}
4423 
4424 	if (gdImageContrast(im_src, (int)contrast) == 1) {
4425 		RETURN_TRUE;
4426 	}
4427 
4428 	RETURN_FALSE;
4429 }
4430 
php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS)4431 static void php_image_filter_colorize(INTERNAL_FUNCTION_PARAMETERS)
4432 {
4433 	zval *SIM;
4434 	gdImagePtr im_src;
4435 	zend_long r,g,b,tmp;
4436 	zend_long a = 0;
4437 
4438 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rllll|l", &SIM, &tmp, &r, &g, &b, &a) == FAILURE) {
4439 		RETURN_FALSE;
4440 	}
4441 
4442 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
4443 		RETURN_FALSE;
4444 	}
4445 
4446 	if (gdImageColor(im_src, (int) r, (int) g, (int) b, (int) a) == 1) {
4447 		RETURN_TRUE;
4448 	}
4449 
4450 	RETURN_FALSE;
4451 }
4452 
php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS)4453 static void php_image_filter_edgedetect(INTERNAL_FUNCTION_PARAMETERS)
4454 {
4455 	PHP_GD_SINGLE_RES
4456 
4457 	if (gdImageEdgeDetectQuick(im_src) == 1) {
4458 		RETURN_TRUE;
4459 	}
4460 
4461 	RETURN_FALSE;
4462 }
4463 
php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS)4464 static void php_image_filter_emboss(INTERNAL_FUNCTION_PARAMETERS)
4465 {
4466 	PHP_GD_SINGLE_RES
4467 
4468 	if (gdImageEmboss(im_src) == 1) {
4469 		RETURN_TRUE;
4470 	}
4471 
4472 	RETURN_FALSE;
4473 }
4474 
php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS)4475 static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS)
4476 {
4477 	PHP_GD_SINGLE_RES
4478 
4479 	if (gdImageGaussianBlur(im_src) == 1) {
4480 		RETURN_TRUE;
4481 	}
4482 
4483 	RETURN_FALSE;
4484 }
4485 
php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS)4486 static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS)
4487 {
4488 	PHP_GD_SINGLE_RES
4489 
4490 	if (gdImageSelectiveBlur(im_src) == 1) {
4491 		RETURN_TRUE;
4492 	}
4493 
4494 	RETURN_FALSE;
4495 }
4496 
php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS)4497 static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS)
4498 {
4499 	PHP_GD_SINGLE_RES
4500 
4501 	if (gdImageMeanRemoval(im_src) == 1) {
4502 		RETURN_TRUE;
4503 	}
4504 
4505 	RETURN_FALSE;
4506 }
4507 
php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS)4508 static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS)
4509 {
4510 	zval *SIM;
4511 	zend_long tmp;
4512 	gdImagePtr im_src;
4513 	double weight;
4514 
4515 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rld", &SIM, &tmp, &weight) == FAILURE) {
4516 		RETURN_FALSE;
4517 	}
4518 
4519 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
4520 		RETURN_FALSE;
4521 	}
4522 
4523 	if (gdImageSmooth(im_src, (float)weight)==1) {
4524 		RETURN_TRUE;
4525 	}
4526 
4527 	RETURN_FALSE;
4528 }
4529 
php_image_filter_pixelate(INTERNAL_FUNCTION_PARAMETERS)4530 static void php_image_filter_pixelate(INTERNAL_FUNCTION_PARAMETERS)
4531 {
4532 	zval *IM;
4533 	gdImagePtr im;
4534 	zend_long tmp, blocksize;
4535 	zend_bool mode = 0;
4536 
4537 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rll|b", &IM, &tmp, &blocksize, &mode) == FAILURE) {
4538 		RETURN_FALSE;
4539 	}
4540 
4541 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4542 		RETURN_FALSE;
4543 	}
4544 
4545 	if (gdImagePixelate(im, (int) blocksize, (const unsigned int) mode)) {
4546 		RETURN_TRUE;
4547 	}
4548 
4549 	RETURN_FALSE;
4550 }
4551 
php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS)4552 static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS)
4553 {
4554 	zval *IM;
4555 	zval *hash_colors = NULL;
4556 	gdImagePtr im;
4557 	zend_long tmp;
4558 	zend_long scatter_sub, scatter_plus;
4559 
4560 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rlll|a", &IM, &tmp, &scatter_sub, &scatter_plus, &hash_colors) == FAILURE) {
4561 		RETURN_FALSE;
4562 	}
4563 
4564 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4565 		RETURN_FALSE;
4566 	}
4567 
4568 	if (hash_colors) {
4569 		uint32_t i = 0;
4570 		uint32_t num_colors = zend_hash_num_elements(Z_ARRVAL_P(hash_colors));
4571 		zval *color;
4572 		int *colors;
4573 
4574 		if (num_colors == 0) {
4575 			RETURN_BOOL(gdImageScatter(im, (int)scatter_sub, (int)scatter_plus));
4576 		}
4577 
4578 		colors = emalloc(num_colors * sizeof(int));
4579 
4580 		ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(hash_colors), color) {
4581 			*(colors + i++) = (int) zval_get_long(color);
4582 		} ZEND_HASH_FOREACH_END();
4583 
4584 		RETVAL_BOOL(gdImageScatterColor(im, (int)scatter_sub, (int)scatter_plus, colors, num_colors));
4585 
4586 		efree(colors);
4587 	} else {
4588 		RETURN_BOOL(gdImageScatter(im, (int) scatter_sub, (int) scatter_plus))
4589 	}
4590 }
4591 
4592 /* {{{ proto bool imagefilter(resource src_im, int filtertype[, int arg1 [, int arg2 [, int arg3 [, int arg4 ]]]] )
4593    Applies Filter an image using a custom angle */
PHP_FUNCTION(imagefilter)4594 PHP_FUNCTION(imagefilter)
4595 {
4596 	zval *tmp;
4597 
4598 	typedef void (*image_filter)(INTERNAL_FUNCTION_PARAMETERS);
4599 	zend_long filtertype;
4600 	image_filter filters[] =
4601 	{
4602 		php_image_filter_negate ,
4603 		php_image_filter_grayscale,
4604 		php_image_filter_brightness,
4605 		php_image_filter_contrast,
4606 		php_image_filter_colorize,
4607 		php_image_filter_edgedetect,
4608 		php_image_filter_emboss,
4609 		php_image_filter_gaussian_blur,
4610 		php_image_filter_selective_blur,
4611 		php_image_filter_mean_removal,
4612 		php_image_filter_smooth,
4613 		php_image_filter_pixelate,
4614 		php_image_filter_scatter
4615 	};
4616 
4617 	if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > IMAGE_FILTER_MAX_ARGS) {
4618 		WRONG_PARAM_COUNT;
4619 	} else if (zend_parse_parameters(2, "rl", &tmp, &filtertype) == FAILURE) {
4620 		return;
4621 	}
4622 
4623 	if (filtertype >= 0 && filtertype <= IMAGE_FILTER_MAX) {
4624 		filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU);
4625 	}
4626 }
4627 /* }}} */
4628 
4629 /* {{{ proto resource imageconvolution(resource src_im, array matrix3x3, double div, double offset)
4630    Apply a 3x3 convolution matrix, using coefficient div and offset */
PHP_FUNCTION(imageconvolution)4631 PHP_FUNCTION(imageconvolution)
4632 {
4633 	zval *SIM, *hash_matrix;
4634 	zval *var = NULL, *var2 = NULL;
4635 	gdImagePtr im_src = NULL;
4636 	double div, offset;
4637 	int nelem, i, j, res;
4638 	float matrix[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};
4639 
4640 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "radd", &SIM, &hash_matrix, &div, &offset) == FAILURE) {
4641 		RETURN_FALSE;
4642 	}
4643 
4644 	if ((im_src = (gdImagePtr)zend_fetch_resource(Z_RES_P(SIM), "Image", le_gd)) == NULL) {
4645 		RETURN_FALSE;
4646 	}
4647 
4648 	nelem = zend_hash_num_elements(Z_ARRVAL_P(hash_matrix));
4649 	if (nelem != 3) {
4650 		php_error_docref(NULL, E_WARNING, "You must have 3x3 array");
4651 		RETURN_FALSE;
4652 	}
4653 
4654 	for (i=0; i<3; i++) {
4655 		if ((var = zend_hash_index_find(Z_ARRVAL_P(hash_matrix), (i))) != NULL && Z_TYPE_P(var) == IS_ARRAY) {
4656 			if (zend_hash_num_elements(Z_ARRVAL_P(var)) != 3 ) {
4657 				php_error_docref(NULL, E_WARNING, "You must have 3x3 array");
4658 				RETURN_FALSE;
4659 			}
4660 
4661 			for (j=0; j<3; j++) {
4662 				if ((var2 = zend_hash_index_find(Z_ARRVAL_P(var), j)) != NULL) {
4663 					matrix[i][j] = (float) zval_get_double(var2);
4664 				} else {
4665 					php_error_docref(NULL, E_WARNING, "You must have a 3x3 matrix");
4666 					RETURN_FALSE;
4667 				}
4668 			}
4669 		}
4670 	}
4671 	res = gdImageConvolution(im_src, matrix, (float)div, (float)offset);
4672 
4673 	if (res) {
4674 		RETURN_TRUE;
4675 	} else {
4676 		RETURN_FALSE;
4677 	}
4678 }
4679 /* }}} */
4680 /* End section: Filters */
4681 
4682 /* {{{ proto bool imageflip(resource im, int mode)
4683    Flip an image (in place) horizontally, vertically or both directions. */
PHP_FUNCTION(imageflip)4684 PHP_FUNCTION(imageflip)
4685 {
4686 	zval *IM;
4687 	zend_long mode;
4688 	gdImagePtr im;
4689 
4690 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &IM, &mode) == FAILURE)  {
4691 		return;
4692 	}
4693 
4694 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4695 		RETURN_FALSE;
4696 	}
4697 
4698 	switch (mode) {
4699 		case GD_FLIP_VERTICAL:
4700 			gdImageFlipVertical(im);
4701 			break;
4702 
4703 		case GD_FLIP_HORINZONTAL:
4704 			gdImageFlipHorizontal(im);
4705 			break;
4706 
4707 		case GD_FLIP_BOTH:
4708 			gdImageFlipBoth(im);
4709 			break;
4710 
4711 		default:
4712 			php_error_docref(NULL, E_WARNING, "Unknown flip mode");
4713 			RETURN_FALSE;
4714 	}
4715 
4716 	RETURN_TRUE;
4717 }
4718 /* }}} */
4719 
4720 /* {{{ proto bool imageantialias(resource im, bool on)
4721    Should antialiased functions used or not*/
PHP_FUNCTION(imageantialias)4722 PHP_FUNCTION(imageantialias)
4723 {
4724 	zval *IM;
4725 	zend_bool alias;
4726 	gdImagePtr im;
4727 
4728 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rb", &IM, &alias) == FAILURE) {
4729 		return;
4730 	}
4731 
4732 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4733 		RETURN_FALSE;
4734 	}
4735 
4736 	if (im->trueColor) {
4737 		im->AA = alias;
4738 	}
4739 
4740 	RETURN_TRUE;
4741 }
4742 /* }}} */
4743 
4744 /* {{{ proto resource imagecrop(resource im, array rect)
4745    Crop an image using the given coordinates and size, x, y, width and height. */
PHP_FUNCTION(imagecrop)4746 PHP_FUNCTION(imagecrop)
4747 {
4748 	zval *IM;
4749 	gdImagePtr im;
4750 	gdImagePtr im_crop;
4751 	gdRect rect;
4752 	zval *z_rect;
4753 	zval *tmp;
4754 
4755 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra", &IM, &z_rect) == FAILURE)  {
4756 		return;
4757 	}
4758 
4759 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4760 		RETURN_FALSE;
4761 	}
4762 
4763 	if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "x", sizeof("x") -1)) != NULL) {
4764 		rect.x = zval_get_long(tmp);
4765 	} else {
4766 		php_error_docref(NULL, E_WARNING, "Missing x position");
4767 		RETURN_FALSE;
4768 	}
4769 
4770 	if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "y", sizeof("y") - 1)) != NULL) {
4771 		rect.y = zval_get_long(tmp);
4772 	} else {
4773 		php_error_docref(NULL, E_WARNING, "Missing y position");
4774 		RETURN_FALSE;
4775 	}
4776 
4777 	if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "width", sizeof("width") - 1)) != NULL) {
4778 		rect.width = zval_get_long(tmp);
4779 	} else {
4780 		php_error_docref(NULL, E_WARNING, "Missing width");
4781 		RETURN_FALSE;
4782 	}
4783 
4784 	if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "height", sizeof("height") - 1)) != NULL) {
4785 		rect.height = zval_get_long(tmp);
4786 	} else {
4787 		php_error_docref(NULL, E_WARNING, "Missing height");
4788 		RETURN_FALSE;
4789 	}
4790 
4791 	im_crop = gdImageCrop(im, &rect);
4792 
4793 	if (im_crop == NULL) {
4794 		RETURN_FALSE;
4795 	} else {
4796 		RETURN_RES(zend_register_resource(im_crop, le_gd));
4797 	}
4798 }
4799 /* }}} */
4800 
4801 /* {{{ proto resource imagecropauto(resource im [, int mode = GD_CROP_DEFAULT [, float threshold [, int color]]])
4802    Crop an image automatically using one of the available modes. */
PHP_FUNCTION(imagecropauto)4803 PHP_FUNCTION(imagecropauto)
4804 {
4805 	zval *IM;
4806 	zend_long mode = GD_CROP_DEFAULT;
4807 	zend_long color = -1;
4808 	double threshold = 0.5f;
4809 	gdImagePtr im;
4810 	gdImagePtr im_crop;
4811 
4812 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|ldl", &IM, &mode, &threshold, &color) == FAILURE)  {
4813 		return;
4814 	}
4815 
4816 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4817 		RETURN_FALSE;
4818 	}
4819 
4820 	switch (mode) {
4821 		case -1:
4822 			php_error_docref(NULL, E_DEPRECATED, "Crop mode -1 is deprecated. Use IMG_CROP_DEFAULT instead.");
4823 			mode = GD_CROP_DEFAULT;
4824 			/* FALLTHRU */
4825 		case GD_CROP_DEFAULT:
4826 		case GD_CROP_TRANSPARENT:
4827 		case GD_CROP_BLACK:
4828 		case GD_CROP_WHITE:
4829 		case GD_CROP_SIDES:
4830 			im_crop = gdImageCropAuto(im, mode);
4831 			break;
4832 
4833 		case GD_CROP_THRESHOLD:
4834 			if (color < 0 || (!gdImageTrueColor(im) && color >= gdImageColorsTotal(im))) {
4835 				php_error_docref(NULL, E_WARNING, "Color argument missing with threshold mode");
4836 				RETURN_FALSE;
4837 			}
4838 			im_crop = gdImageCropThreshold(im, color, (float) threshold);
4839 			break;
4840 
4841 		default:
4842 			php_error_docref(NULL, E_WARNING, "Unknown crop mode");
4843 			RETURN_FALSE;
4844 	}
4845 	if (im_crop == NULL) {
4846 		RETURN_FALSE;
4847 	} else {
4848 		RETURN_RES(zend_register_resource(im_crop, le_gd));
4849 	}
4850 }
4851 /* }}} */
4852 
4853 /* {{{ proto resource imagescale(resource im, int new_width[, int new_height[, int method]])
4854    Scale an image using the given new width and height. */
PHP_FUNCTION(imagescale)4855 PHP_FUNCTION(imagescale)
4856 {
4857 	zval *IM;
4858 	gdImagePtr im;
4859 	gdImagePtr im_scaled = NULL;
4860 	int new_width, new_height;
4861 	zend_long tmp_w, tmp_h=-1, tmp_m = GD_BILINEAR_FIXED;
4862 	gdInterpolationMethod method, old_method;
4863 
4864 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl|ll", &IM, &tmp_w, &tmp_h, &tmp_m) == FAILURE)  {
4865 		return;
4866 	}
4867 	method = tmp_m;
4868 
4869 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4870 		RETURN_FALSE;
4871 	}
4872 
4873 	if (tmp_h < 0 || tmp_w < 0) {
4874 		/* preserve ratio */
4875 		long src_x, src_y;
4876 
4877 		src_x = gdImageSX(im);
4878 		src_y = gdImageSY(im);
4879 
4880 		if (src_x && tmp_h < 0) {
4881 			tmp_h = tmp_w * src_y / src_x;
4882 		}
4883 		if (src_y && tmp_w < 0) {
4884 			tmp_w = tmp_h * src_x / src_y;
4885 		}
4886 	}
4887 
4888 	if (tmp_h <= 0 || tmp_h > INT_MAX || tmp_w <= 0 || tmp_w > INT_MAX) {
4889 		RETURN_FALSE;
4890 	}
4891 
4892 	new_width = tmp_w;
4893 	new_height = tmp_h;
4894 
4895 	/* gdImageGetInterpolationMethod() is only available as of GD 2.1.1 */
4896 	old_method = im->interpolation_id;
4897 	if (gdImageSetInterpolationMethod(im, method)) {
4898 		im_scaled = gdImageScale(im, new_width, new_height);
4899 	}
4900 	gdImageSetInterpolationMethod(im, old_method);
4901 
4902 	if (im_scaled == NULL) {
4903 		RETURN_FALSE;
4904 	} else {
4905 		RETURN_RES(zend_register_resource(im_scaled, le_gd));
4906 	}
4907 }
4908 /* }}} */
4909 
4910 /* {{{ proto resource imageaffine(resource src, array affine[, array clip])
4911    Return an image containing the affine tramsformed src image, using an optional clipping area */
PHP_FUNCTION(imageaffine)4912 PHP_FUNCTION(imageaffine)
4913 {
4914 	zval *IM;
4915 	gdImagePtr src;
4916 	gdImagePtr dst;
4917 	gdRect rect;
4918 	gdRectPtr pRect = NULL;
4919 	zval *z_rect = NULL;
4920 	zval *z_affine;
4921 	zval *tmp;
4922 	double affine[6];
4923 	int i, nelems;
4924 	zval *zval_affine_elem = NULL;
4925 
4926 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra|a", &IM, &z_affine, &z_rect) == FAILURE)  {
4927 		return;
4928 	}
4929 
4930 	if ((src = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
4931 		RETURN_FALSE;
4932 	}
4933 
4934 	if ((nelems = zend_hash_num_elements(Z_ARRVAL_P(z_affine))) != 6) {
4935 		php_error_docref(NULL, E_WARNING, "Affine array must have six elements");
4936 		RETURN_FALSE;
4937 	}
4938 
4939 	for (i = 0; i < nelems; i++) {
4940 		if ((zval_affine_elem = zend_hash_index_find(Z_ARRVAL_P(z_affine), i)) != NULL) {
4941 			switch (Z_TYPE_P(zval_affine_elem)) {
4942 				case IS_LONG:
4943 					affine[i]  = Z_LVAL_P(zval_affine_elem);
4944 					break;
4945 				case IS_DOUBLE:
4946 					affine[i] = Z_DVAL_P(zval_affine_elem);
4947 					break;
4948 				case IS_STRING:
4949 					affine[i] = zval_get_double(zval_affine_elem);
4950 					break;
4951 				default:
4952 					php_error_docref(NULL, E_WARNING, "Invalid type for element %i", i);
4953 					RETURN_FALSE;
4954 			}
4955 		}
4956 	}
4957 
4958 	if (z_rect != NULL) {
4959 		if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "x", sizeof("x") - 1)) != NULL) {
4960 			rect.x = zval_get_long(tmp);
4961 		} else {
4962 			php_error_docref(NULL, E_WARNING, "Missing x position");
4963 			RETURN_FALSE;
4964 		}
4965 
4966 		if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "y", sizeof("y") - 1)) != NULL) {
4967 			rect.y = zval_get_long(tmp);
4968 		} else {
4969 			php_error_docref(NULL, E_WARNING, "Missing y position");
4970 			RETURN_FALSE;
4971 		}
4972 
4973 		if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "width", sizeof("width") - 1)) != NULL) {
4974 			rect.width = zval_get_long(tmp);
4975 		} else {
4976 			php_error_docref(NULL, E_WARNING, "Missing width");
4977 			RETURN_FALSE;
4978 		}
4979 
4980 		if ((tmp = zend_hash_str_find(Z_ARRVAL_P(z_rect), "height", sizeof("height") - 1)) != NULL) {
4981 			rect.height = zval_get_long(tmp);
4982 		} else {
4983 			php_error_docref(NULL, E_WARNING, "Missing height");
4984 			RETURN_FALSE;
4985 		}
4986 		pRect = &rect;
4987 	} else {
4988 		rect.x = -1;
4989 		rect.y = -1;
4990 		rect.width = gdImageSX(src);
4991 		rect.height = gdImageSY(src);
4992 		pRect = NULL;
4993 	}
4994 
4995 	if (gdTransformAffineGetImage(&dst, src, pRect, affine) != GD_TRUE) {
4996 		RETURN_FALSE;
4997 	}
4998 
4999 	if (dst == NULL) {
5000 		RETURN_FALSE;
5001 	} else {
5002 		RETURN_RES(zend_register_resource(dst, le_gd));
5003 	}
5004 }
5005 /* }}} */
5006 
5007 /* {{{ proto array imageaffinematrixget(int type[, array options])
5008    Return an image containing the affine tramsformed src image, using an optional clipping area */
PHP_FUNCTION(imageaffinematrixget)5009 PHP_FUNCTION(imageaffinematrixget)
5010 {
5011 	double affine[6];
5012 	zend_long type;
5013 	zval *options = NULL;
5014 	zval *tmp;
5015 	int res = GD_FALSE, i;
5016 
5017 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|z", &type, &options) == FAILURE)  {
5018 		return;
5019 	}
5020 
5021 	switch((gdAffineStandardMatrix)type) {
5022 		case GD_AFFINE_TRANSLATE:
5023 		case GD_AFFINE_SCALE: {
5024 			double x, y;
5025 			if (!options || Z_TYPE_P(options) != IS_ARRAY) {
5026 				php_error_docref(NULL, E_WARNING, "Array expected as options");
5027 				RETURN_FALSE;
5028 			}
5029 			if ((tmp = zend_hash_str_find(Z_ARRVAL_P(options), "x", sizeof("x") - 1)) != NULL) {
5030 				x = zval_get_double(tmp);
5031 			} else {
5032 				php_error_docref(NULL, E_WARNING, "Missing x position");
5033 				RETURN_FALSE;
5034 			}
5035 
5036 			if ((tmp = zend_hash_str_find(Z_ARRVAL_P(options), "y", sizeof("y") - 1)) != NULL) {
5037 				y = zval_get_double(tmp);
5038 			} else {
5039 				php_error_docref(NULL, E_WARNING, "Missing y position");
5040 				RETURN_FALSE;
5041 			}
5042 
5043 			if (type == GD_AFFINE_TRANSLATE) {
5044 				res = gdAffineTranslate(affine, x, y);
5045 			} else {
5046 				res = gdAffineScale(affine, x, y);
5047 			}
5048 			break;
5049 		}
5050 
5051 		case GD_AFFINE_ROTATE:
5052 		case GD_AFFINE_SHEAR_HORIZONTAL:
5053 		case GD_AFFINE_SHEAR_VERTICAL: {
5054 			double angle;
5055 
5056 			if (!options) {
5057 				php_error_docref(NULL, E_WARNING, "Number is expected as option");
5058 				RETURN_FALSE;
5059 			}
5060 
5061 			angle = zval_get_double(options);
5062 
5063 			if (type == GD_AFFINE_SHEAR_HORIZONTAL) {
5064 				res = gdAffineShearHorizontal(affine, angle);
5065 			} else if (type == GD_AFFINE_SHEAR_VERTICAL) {
5066 				res = gdAffineShearVertical(affine, angle);
5067 			} else {
5068 				res = gdAffineRotate(affine, angle);
5069 			}
5070 			break;
5071 		}
5072 
5073 		default:
5074 			php_error_docref(NULL, E_WARNING, "Invalid type for element " ZEND_LONG_FMT, type);
5075 			RETURN_FALSE;
5076 	}
5077 
5078 	if (res == GD_FALSE) {
5079 		RETURN_FALSE;
5080 	} else {
5081 		array_init(return_value);
5082 		for (i = 0; i < 6; i++) {
5083 			add_index_double(return_value, i, affine[i]);
5084 		}
5085 	}
5086 } /* }}} */
5087 
5088 /* {{{ proto array imageaffineconcat(array m1, array m2)
5089    Concat two matrices (as in doing many ops in one go) */
PHP_FUNCTION(imageaffinematrixconcat)5090 PHP_FUNCTION(imageaffinematrixconcat)
5091 {
5092 	double m1[6];
5093 	double m2[6];
5094 	double mr[6];
5095 
5096 	zval *tmp;
5097 	zval *z_m1;
5098 	zval *z_m2;
5099 	int i, nelems;
5100 
5101 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "aa", &z_m1, &z_m2) == FAILURE)  {
5102 		return;
5103 	}
5104 
5105 	if (((nelems = zend_hash_num_elements(Z_ARRVAL_P(z_m1))) != 6) || (nelems = zend_hash_num_elements(Z_ARRVAL_P(z_m2))) != 6) {
5106 		php_error_docref(NULL, E_WARNING, "Affine arrays must have six elements");
5107 		RETURN_FALSE;
5108 	}
5109 
5110 	for (i = 0; i < 6; i++) {
5111 		if ((tmp = zend_hash_index_find(Z_ARRVAL_P(z_m1), i)) != NULL) {
5112 			switch (Z_TYPE_P(tmp)) {
5113 				case IS_LONG:
5114 					m1[i]  = Z_LVAL_P(tmp);
5115 					break;
5116 				case IS_DOUBLE:
5117 					m1[i] = Z_DVAL_P(tmp);
5118 					break;
5119 				case IS_STRING:
5120 					m1[i] = zval_get_double(tmp);
5121 					break;
5122 				default:
5123 					php_error_docref(NULL, E_WARNING, "Invalid type for element %i", i);
5124 					RETURN_FALSE;
5125 			}
5126 		}
5127 		if ((tmp = zend_hash_index_find(Z_ARRVAL_P(z_m2), i)) != NULL) {
5128 			switch (Z_TYPE_P(tmp)) {
5129 				case IS_LONG:
5130 					m2[i]  = Z_LVAL_P(tmp);
5131 					break;
5132 				case IS_DOUBLE:
5133 					m2[i] = Z_DVAL_P(tmp);
5134 					break;
5135 				case IS_STRING:
5136 					m2[i] = zval_get_double(tmp);
5137 					break;
5138 				default:
5139 					php_error_docref(NULL, E_WARNING, "Invalid type for element %i", i);
5140 					RETURN_FALSE;
5141 			}
5142 		}
5143 	}
5144 
5145 	if (gdAffineConcat (mr, m1, m2) != GD_TRUE) {
5146 		RETURN_FALSE;
5147 	}
5148 
5149 	array_init(return_value);
5150 	for (i = 0; i < 6; i++) {
5151 		add_index_double(return_value, i, mr[i]);
5152 	}
5153 } /* }}} */
5154 
5155 /* {{{ proto resource imagesetinterpolation(resource im [, int method]])
5156    Set the default interpolation method, passing -1 or 0 sets it to the libgd default (bilinear). */
PHP_FUNCTION(imagesetinterpolation)5157 PHP_FUNCTION(imagesetinterpolation)
5158 {
5159 	zval *IM;
5160 	gdImagePtr im;
5161 	zend_long method = GD_BILINEAR_FIXED;
5162 
5163 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &IM, &method) == FAILURE)  {
5164 		return;
5165 	}
5166 
5167 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
5168 		RETURN_FALSE;
5169 	}
5170 
5171 	if (method == -1) {
5172 		 method = GD_BILINEAR_FIXED;
5173 	}
5174 	RETURN_BOOL(gdImageSetInterpolationMethod(im, (gdInterpolationMethod) method));
5175 }
5176 /* }}} */
5177 
5178 /* {{{ proto array imageresolution(resource im [, res_x, [res_y]])
5179    Get or set the resolution of the image in DPI. */
PHP_FUNCTION(imageresolution)5180 PHP_FUNCTION(imageresolution)
5181 {
5182 	zval *IM;
5183 	gdImagePtr im;
5184 	zend_long res_x = GD_RESOLUTION, res_y = GD_RESOLUTION;
5185 
5186 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|ll", &IM, &res_x, &res_y) == FAILURE)  {
5187 		return;
5188 	}
5189 
5190 	if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
5191 		RETURN_FALSE;
5192 	}
5193 
5194 	switch (ZEND_NUM_ARGS()) {
5195 		case 3:
5196 			gdImageSetResolution(im, res_x, res_y);
5197 			RETURN_TRUE;
5198 		case 2:
5199 			gdImageSetResolution(im, res_x, res_x);
5200 			RETURN_TRUE;
5201 		default:
5202 			array_init(return_value);
5203 			add_next_index_long(return_value, gdImageResolutionX(im));
5204 			add_next_index_long(return_value, gdImageResolutionY(im));
5205 	}
5206 }
5207 /* }}} */
5208