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