~ubuntu-branches/ubuntu/breezy/php5/breezy-security

« back to all changes in this revision

Viewing changes to ext/gd/gd.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-10-09 03:14:32 UTC
  • Revision ID: james.westby@ubuntu.com-20051009031432-kspik3lobxstafv9
Tags: upstream-5.0.5
ImportĀ upstreamĀ versionĀ 5.0.5

Show diffs side-by-side

added added

removed removed

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