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