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