Back to index

php5  5.3.10
gd_ctx.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Stanislav Malyshev <stas@php.net>                           |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: gd_ctx.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #include "php_gd.h"
00022 
00023 #define CTX_PUTC(c,ctx) ctx->putC(ctx, c)
00024 
00025 static void _php_image_output_putc(struct gdIOCtx *ctx, int c)
00026 {
00027        /* without the following downcast, the write will fail
00028         * (i.e., will write a zero byte) for all
00029         * big endian architectures:
00030         */
00031        unsigned char ch = (unsigned char) c;
00032        TSRMLS_FETCH();
00033        php_write(&ch, 1 TSRMLS_CC);
00034 }
00035 
00036 static int _php_image_output_putbuf(struct gdIOCtx *ctx, const void* buf, int l)
00037 {
00038        TSRMLS_FETCH();
00039        return php_write((void *)buf, l TSRMLS_CC);
00040 }
00041 
00042 static void _php_image_output_ctxfree(struct gdIOCtx *ctx)
00043 {
00044        if(ctx) {
00045               efree(ctx);
00046        }
00047 }
00048 
00049 /* {{{ _php_image_output_ctx */
00050 static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
00051 {
00052        zval *imgind;
00053        char *file = NULL;
00054        int file_len = 0;
00055        long quality, basefilter;
00056        gdImagePtr im;
00057        FILE *fp = NULL;
00058        int argc = ZEND_NUM_ARGS();
00059        int q = -1, i;
00060        int f = -1;
00061        gdIOCtx *ctx;
00062 
00063        /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp().
00064         * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called
00065         * from imagey<type>().
00066         */
00067 
00068        if (image_type == PHP_GDIMG_TYPE_XBM) {
00069               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) {
00070                      return;
00071               }
00072        } else {
00073               /* PHP_GDIMG_TYPE_GIF
00074                * PHP_GDIMG_TYPE_PNG 
00075                * PHP_GDIMG_TYPE_JPG 
00076                * PHP_GDIMG_TYPE_WBM */
00077               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) {
00078                      return;
00079               }
00080        }
00081 
00082        ZEND_FETCH_RESOURCE(im, gdImagePtr, &imgind, -1, "Image", phpi_get_le_gd());
00083 
00084        if (argc > 1) {
00085               if (argc >= 3) {
00086                      q = quality; /* or colorindex for foreground of BW images (defaults to black) */
00087                      if (argc == 4) {
00088                             f = basefilter;
00089                      }
00090               }
00091        }
00092 
00093        if (argc > 1 && file_len) {
00094               if (strlen(file) != file_len) {
00095                      RETURN_FALSE;
00096               }
00097               PHP_GD_CHECK_OPEN_BASEDIR(file, "Invalid filename");
00098 
00099               fp = VCWD_FOPEN(file, "wb");
00100               if (!fp) {
00101                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", file, strerror(errno));
00102                      RETURN_FALSE;
00103               }
00104 
00105               ctx = gdNewFileCtx(fp);
00106        } else {
00107               ctx = emalloc(sizeof(gdIOCtx));
00108               ctx->putC = _php_image_output_putc;
00109               ctx->putBuf = _php_image_output_putbuf;
00110 #if HAVE_LIBGD204
00111               ctx->gd_free = _php_image_output_ctxfree;
00112 #else
00113               ctx->free = _php_image_output_ctxfree;
00114 #endif
00115 
00116 #if APACHE && defined(CHARSET_EBCDIC)
00117               /* XXX this is unlikely to work any more thies@thieso.net */
00118               /* This is a binary file already: avoid EBCDIC->ASCII conversion */
00119               ap_bsetflag(php3_rqst->connection->client, B_EBCDIC2ASCII, 0);
00120 #endif
00121        }
00122 
00123        switch(image_type) {
00124               case PHP_GDIMG_CONVERT_WBM:
00125                      if(q<0||q>255) {
00126                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q);
00127                      }
00128               case PHP_GDIMG_TYPE_JPG:
00129                      (*func_p)(im, ctx, q);
00130                      break;
00131               case PHP_GDIMG_TYPE_PNG:
00132                      (*func_p)(im, ctx, q, f);
00133                      break;
00134               case PHP_GDIMG_TYPE_XBM:
00135               case PHP_GDIMG_TYPE_WBM:
00136                      if (argc < 3) {
00137                             for(i=0; i < gdImageColorsTotal(im); i++) {
00138                                    if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break;
00139                             }
00140                             q = i;
00141                      }
00142                      if (image_type == PHP_GDIMG_TYPE_XBM) {
00143                             (*func_p)(im, file, q, ctx);
00144                      } else {
00145                             (*func_p)(im, q, ctx);
00146                      }
00147                      break;
00148               default:
00149                      (*func_p)(im, ctx);
00150                      break;
00151        }
00152 
00153 #if HAVE_LIBGD204
00154        ctx->gd_free(ctx);
00155 #else
00156        ctx->free(ctx);
00157 #endif
00158 
00159        if(fp) {
00160               fflush(fp);
00161               fclose(fp);
00162        }
00163 
00164     RETURN_TRUE;
00165 }
00166 /* }}} */
00167 
00168 /*
00169  * Local variables:
00170  * tab-width: 4
00171  * c-basic-offset: 4
00172  * End:
00173  * vim600: sw=4 ts=4 fdm=marker
00174  * vim<600: sw=4 ts=4
00175  */