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

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