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