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