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