root/ext/gd/gd_ctx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _php_image_output_putc
  2. _php_image_output_putbuf
  3. _php_image_output_ctxfree
  4. _php_image_stream_putc
  5. _php_image_stream_putbuf
  6. _php_image_stream_ctxfree
  7. _php_image_output_ctx

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 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$ */
  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         /* without the following downcast, the write will fail
  28          * (i.e., will write a zero byte) for all
  29          * big endian architectures:
  30          */
  31         unsigned char ch = (unsigned char) c;
  32         TSRMLS_FETCH();
  33         php_write(&ch, 1 TSRMLS_CC);
  34 }
  35 
  36 static int _php_image_output_putbuf(struct gdIOCtx *ctx, const void* buf, int l)
  37 {
  38         TSRMLS_FETCH();
  39         return php_write((void *)buf, l TSRMLS_CC);
  40 }
  41 
  42 static void _php_image_output_ctxfree(struct gdIOCtx *ctx)
  43 {
  44         if(ctx) {
  45                 efree(ctx);
  46         }
  47 }
  48 
  49 static void _php_image_stream_putc(struct gdIOCtx *ctx, int c)  {
  50         char ch = (char) c;
  51         php_stream * stream = (php_stream *)ctx->data;
  52         TSRMLS_FETCH();
  53         php_stream_write(stream, &ch, 1);
  54 }
  55 
  56 static int _php_image_stream_putbuf(struct gdIOCtx *ctx, const void* buf, int l)
  57 {
  58         php_stream * stream = (php_stream *)ctx->data;
  59         TSRMLS_FETCH();
  60         return php_stream_write(stream, (void *)buf, l);
  61 }
  62 
  63 static void _php_image_stream_ctxfree(struct gdIOCtx *ctx)
  64 {
  65         TSRMLS_FETCH();
  66 
  67         if(ctx->data) {
  68                 php_stream_close((php_stream *) ctx->data);
  69                 ctx->data = NULL;
  70         }
  71         if(ctx) {
  72                 efree(ctx);
  73         }
  74 }
  75 
  76 /* {{{ _php_image_output_ctx */
  77 static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
  78 {
  79         zval *imgind;
  80         char *file = NULL;
  81         int file_len = 0;
  82         long quality, basefilter;
  83         gdImagePtr im;
  84         int argc = ZEND_NUM_ARGS();
  85         int q = -1, i;
  86         int f = -1;
  87         gdIOCtx *ctx = NULL;
  88         zval *to_zval = NULL;
  89         php_stream *stream;
  90 
  91         /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp().
  92          * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called
  93          * from imagey<type>().
  94          */
  95         if (image_type == PHP_GDIMG_TYPE_XBM) {
  96                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) {
  97                         return;
  98                 }
  99         } else {
 100                 /* PHP_GDIMG_TYPE_GIF
 101                  * PHP_GDIMG_TYPE_PNG 
 102                  * PHP_GDIMG_TYPE_JPG 
 103                  * PHP_GDIMG_TYPE_WBM 
 104                  * PHP_GDIMG_TYPE_WEBP 
 105                  * */
 106                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z/!ll", &imgind, &to_zval, &quality, &basefilter) == FAILURE) {
 107                         return;
 108                 }
 109         }
 110 
 111         ZEND_FETCH_RESOURCE(im, gdImagePtr, &imgind, -1, "Image", phpi_get_le_gd());
 112 
 113         if (argc >= 3) {
 114                 q = quality; /* or colorindex for foreground of BW images (defaults to black) */
 115                 if (argc == 4) {
 116                         f = basefilter;
 117                 }
 118         }
 119 
 120         if (argc > 1 && to_zval != NULL) {
 121                 if (Z_TYPE_P(to_zval) == IS_RESOURCE) {
 122                         php_stream_from_zval_no_verify(stream, &to_zval);
 123                         if (stream == NULL) {
 124                                 RETURN_FALSE;
 125                         }
 126                 } else if (Z_TYPE_P(to_zval) == IS_STRING) {
 127                         if (CHECK_ZVAL_NULL_PATH(to_zval)) {
 128                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid 2nd parameter, filename must not contain null bytes");
 129                                 RETURN_FALSE;
 130                         }
 131 
 132                         stream = php_stream_open_wrapper(Z_STRVAL_P(to_zval), "wb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL);
 133                         if (stream == NULL) {
 134                                 RETURN_FALSE;
 135                         }
 136                 } else {
 137                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid 2nd parameter, it must a filename or a stream");
 138                         RETURN_FALSE;
 139                 }
 140         } else if (argc > 1 && file != NULL) {
 141                 stream = php_stream_open_wrapper(file, "wb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL);
 142                 if (stream == NULL) {
 143                         RETURN_FALSE;
 144                 }
 145         } else {
 146                 ctx = emalloc(sizeof(gdIOCtx));
 147                 ctx->putC = _php_image_output_putc;
 148                 ctx->putBuf = _php_image_output_putbuf;
 149                 ctx->gd_free = _php_image_output_ctxfree;
 150 
 151 #if APACHE && defined(CHARSET_EBCDIC)
 152                 /* XXX this is unlikely to work any more thies@thieso.net */
 153                 /* This is a binary file already: avoid EBCDIC->ASCII conversion */
 154                 ap_bsetflag(php3_rqst->connection->client, B_EBCDIC2ASCII, 0);
 155 #endif
 156         }
 157 
 158         if (!ctx)       {
 159                 ctx = emalloc(sizeof(gdIOCtx));
 160                 ctx->putC = _php_image_stream_putc;
 161                 ctx->putBuf = _php_image_stream_putbuf;
 162                 ctx->gd_free = _php_image_stream_ctxfree;
 163                 ctx->data = (void *)stream;
 164         }
 165 
 166         switch(image_type) {
 167                 case PHP_GDIMG_CONVERT_WBM:
 168                         if(q<0||q>255) {
 169                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid threshold value '%d'. It must be between 0 and 255", q);
 170                         }
 171                 case PHP_GDIMG_TYPE_JPG:
 172                         (*func_p)(im, ctx, q);
 173                         break;
 174                 case PHP_GDIMG_TYPE_WEBP:
 175                         if (q == -1) {
 176                                 q = 80;
 177                         }
 178                         (*func_p)(im, ctx, q);
 179                         break;
 180                 case PHP_GDIMG_TYPE_PNG:
 181                         (*func_p)(im, ctx, q, f);
 182                         break;
 183                 case PHP_GDIMG_TYPE_XBM:
 184                 case PHP_GDIMG_TYPE_WBM:
 185                         if (argc < 3) {
 186                                 for(i=0; i < gdImageColorsTotal(im); i++) {
 187                                         if(!gdImageRed(im, i) && !gdImageGreen(im, i) && !gdImageBlue(im, i)) break;
 188                                 }
 189                                 q = i;
 190                         }
 191                         if (image_type == PHP_GDIMG_TYPE_XBM) {
 192                                 (*func_p)(im, file ? file : "", q, ctx);
 193                         } else {
 194                                 (*func_p)(im, q, ctx);
 195                         }
 196                         break;
 197                 default:
 198                         (*func_p)(im, ctx);
 199                         break;
 200         }
 201 
 202         ctx->gd_free(ctx);
 203 
 204         RETURN_TRUE;
 205 }
 206 /* }}} */
 207 
 208 /*
 209  * Local variables:
 210  * tab-width: 4
 211  * c-basic-offset: 4
 212  * End:
 213  * vim600: sw=4 ts=4 fdm=marker
 214  * vim<600: sw=4 ts=4
 215  */

/* [<][>][^][v][top][bottom][index][help] */