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