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