1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
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 276986 2009-03-10 23:40:06Z helly $ */
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 80 : {
52 : zval *imgind;
53 80 : char *file = NULL;
54 80 : int file_len = 0;
55 : long quality, basefilter;
56 : gdImagePtr im;
57 80 : FILE *fp = NULL;
58 80 : int argc = ZEND_NUM_ARGS();
59 80 : int q = -1, i;
60 80 : int f = -1;
61 : gdIOCtx *ctx;
62 :
63 : /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp().
64 : * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called
65 : * from imagey<type>().
66 : */
67 :
68 80 : if (image_type == PHP_GDIMG_TYPE_XBM) {
69 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) {
70 0 : return;
71 : }
72 : } else {
73 : /* PHP_GDIMG_TYPE_GIF
74 : * PHP_GDIMG_TYPE_PNG
75 : * PHP_GDIMG_TYPE_JPG
76 : * PHP_GDIMG_TYPE_WBM */
77 80 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) {
78 0 : return;
79 : }
80 : }
81 :
82 80 : ZEND_FETCH_RESOURCE(im, gdImagePtr, &imgind, -1, "Image", phpi_get_le_gd());
83 :
84 80 : if (argc > 1) {
85 70 : if (argc >= 3) {
86 18 : q = quality; /* or colorindex for foreground of BW images (defaults to black) */
87 18 : if (argc == 4) {
88 0 : f = basefilter;
89 : }
90 : }
91 : }
92 :
93 133 : if (argc > 1 && file_len) {
94 53 : PHP_GD_CHECK_OPEN_BASEDIR(file, "Invalid filename");
95 :
96 53 : fp = VCWD_FOPEN(file, "wb");
97 53 : if (!fp) {
98 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", file, strerror(errno));
99 0 : RETURN_FALSE;
100 : }
101 :
102 53 : 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 27 : ctx->gd_free = _php_image_output_ctxfree;
108 : }
109 :
110 80 : switch(image_type) {
111 : case PHP_GDIMG_CONVERT_WBM:
112 0 : if(q<0||q>255) {
113 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q);
114 : }
115 : case PHP_GDIMG_TYPE_JPG:
116 8 : (*func_p)(im, ctx, q);
117 8 : break;
118 : case PHP_GDIMG_TYPE_PNG:
119 60 : (*func_p)(im, ctx, q, f);
120 60 : break;
121 : case PHP_GDIMG_TYPE_XBM:
122 : case PHP_GDIMG_TYPE_WBM:
123 1 : if (argc < 3) {
124 1 : for(i=0; i < gdImageColorsTotal(im); i++) {
125 0 : if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break;
126 : }
127 1 : q = i;
128 : }
129 1 : if (image_type == PHP_GDIMG_TYPE_XBM) {
130 0 : (*func_p)(im, file, q, ctx);
131 : } else {
132 1 : (*func_p)(im, q, ctx);
133 : }
134 1 : break;
135 : default:
136 11 : (*func_p)(im, ctx);
137 : break;
138 : }
139 :
140 80 : ctx->gd_free(ctx);
141 :
142 80 : if(fp) {
143 53 : fflush(fp);
144 53 : fclose(fp);
145 : }
146 :
147 80 : RETURN_TRUE;
148 : }
149 : /* }}} */
150 :
151 : /*
152 : * Local variables:
153 : * tab-width: 4
154 : * c-basic-offset: 4
155 : * End:
156 : * vim600: sw=4 ts=4 fdm=marker
157 : * vim<600: sw=4 ts=4
158 : */
|