1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Stanislav Malyshev <stas@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: gd_ctx.c 272374 2008-12-31 11:17:49Z sebastian $ */
20 :
21 : #include "php_gd.h"
22 :
23 : #define CTX_PUTC(c,ctx) ctx->putC(ctx, c)
24 :
25 : static void _php_image_output_putc(struct gdIOCtx *ctx, int c)
26 27 : {
27 : /* without the following downcast, the write will fail
28 : * (i.e., will write a zero byte) for all
29 : * big endian architectures:
30 : */
31 27 : unsigned char ch = (unsigned char) c;
32 : TSRMLS_FETCH();
33 27 : php_write(&ch, 1 TSRMLS_CC);
34 27 : }
35 :
36 : static int _php_image_output_putbuf(struct gdIOCtx *ctx, const void* buf, int l)
37 316 : {
38 : TSRMLS_FETCH();
39 316 : return php_write((void *)buf, l TSRMLS_CC);
40 : }
41 :
42 : static void _php_image_output_ctxfree(struct gdIOCtx *ctx)
43 27 : {
44 27 : if(ctx) {
45 27 : efree(ctx);
46 : }
47 27 : }
48 :
49 : /* {{{ _php_image_output_ctx */
50 : static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
51 79 : {
52 : zval **imgind, **file, **quality, **basefilter;
53 : gdImagePtr im;
54 79 : char *fn = NULL;
55 79 : FILE *fp = NULL;
56 79 : int argc = ZEND_NUM_ARGS();
57 79 : int q = -1, i;
58 79 : int f = -1;
59 : gdIOCtx *ctx;
60 :
61 : /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp().
62 : * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called
63 : * from imagey<type>().
64 : */
65 :
66 79 : if (argc < 2 && image_type == PHP_GDIMG_TYPE_XBM) {
67 0 : WRONG_PARAM_COUNT;
68 : }
69 :
70 79 : if (argc < 1 || argc > 4 || zend_get_parameters_ex(argc, &imgind, &file, &quality, &basefilter) == FAILURE)
71 : {
72 0 : WRONG_PARAM_COUNT;
73 : }
74 :
75 79 : ZEND_FETCH_RESOURCE(im, gdImagePtr, imgind, -1, "Image", phpi_get_le_gd());
76 :
77 79 : if (argc > 1) {
78 69 : if (argc >= 2 && Z_TYPE_PP(file) != IS_NULL) {
79 52 : convert_to_string_ex(file);
80 : }
81 69 : fn = Z_STRVAL_PP(file);
82 69 : if (argc >= 3) {
83 18 : convert_to_long_ex(quality);
84 18 : q = Z_LVAL_PP(quality);/* or colorindex for foreground of BW images (defaults to black) */
85 18 : if (argc == 4) {
86 0 : convert_to_long_ex(basefilter);
87 0 : f = Z_LVAL_PP(basefilter);
88 : }
89 : }
90 : }
91 :
92 131 : if (argc > 1 && (Z_TYPE_PP(file) != IS_NULL && ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))))) {
93 :
94 52 : PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
95 :
96 52 : fp = VCWD_FOPEN(fn, "wb");
97 52 : if (!fp) {
98 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", fn, strerror(errno));
99 0 : RETURN_FALSE;
100 : }
101 :
102 52 : ctx = gdNewFileCtx(fp);
103 : } else {
104 27 : ctx = emalloc(sizeof(gdIOCtx));
105 27 : ctx->putC = _php_image_output_putc;
106 27 : ctx->putBuf = _php_image_output_putbuf;
107 : #if HAVE_LIBGD204
108 27 : ctx->gd_free = _php_image_output_ctxfree;
109 : #else
110 : ctx->free = _php_image_output_ctxfree;
111 : #endif
112 :
113 : #if APACHE && defined(CHARSET_EBCDIC)
114 : /* XXX this is unlikely to work any more thies@thieso.net */
115 : /* This is a binary file already: avoid EBCDIC->ASCII conversion */
116 : ap_bsetflag(php3_rqst->connection->client, B_EBCDIC2ASCII, 0);
117 : #endif
118 : }
119 :
120 79 : switch(image_type) {
121 : case PHP_GDIMG_CONVERT_WBM:
122 0 : if(q<0||q>255) {
123 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q);
124 : }
125 : case PHP_GDIMG_TYPE_JPG:
126 8 : (*func_p)(im, ctx, q);
127 8 : break;
128 : case PHP_GDIMG_TYPE_PNG:
129 59 : (*func_p)(im, ctx, q, f);
130 59 : break;
131 : case PHP_GDIMG_TYPE_XBM:
132 : case PHP_GDIMG_TYPE_WBM:
133 1 : if (argc < 3) {
134 1 : for(i=0; i < gdImageColorsTotal(im); i++) {
135 0 : if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break;
136 : }
137 1 : q = i;
138 : }
139 1 : if (image_type == PHP_GDIMG_TYPE_XBM) {
140 0 : (*func_p)(im, fn, q, ctx);
141 : } else {
142 1 : (*func_p)(im, q, ctx);
143 : }
144 1 : break;
145 : default:
146 11 : (*func_p)(im, ctx);
147 : break;
148 : }
149 :
150 : #if HAVE_LIBGD204
151 79 : ctx->gd_free(ctx);
152 : #else
153 : ctx->free(ctx);
154 : #endif
155 :
156 79 : if(fp) {
157 52 : fflush(fp);
158 52 : fclose(fp);
159 : }
160 :
161 79 : RETURN_TRUE;
162 : }
163 : /* }}} */
164 :
165 : /*
166 : * Local variables:
167 : * tab-width: 4
168 : * c-basic-offset: 4
169 : * End:
170 : * vim600: sw=4 ts=4 fdm=marker
171 : * vim<600: sw=4 ts=4
172 : */
|