diff options
Diffstat (limited to 'ext/gd/gd_ctx.c')
-rw-r--r-- | ext/gd/gd_ctx.c | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index a82220111..484eedf46 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -46,6 +46,33 @@ static void _php_image_output_ctxfree(struct gdIOCtx *ctx) } } +static void _php_image_stream_putc(struct gdIOCtx *ctx, int c) { + char ch = (char) c; + php_stream * stream = (php_stream *)ctx->data; + TSRMLS_FETCH(); + php_stream_write(stream, &ch, 1); +} + +static int _php_image_stream_putbuf(struct gdIOCtx *ctx, const void* buf, int l) +{ + php_stream * stream = (php_stream *)ctx->data; + TSRMLS_FETCH(); + return php_stream_write(stream, (void *)buf, l); +} + +static void _php_image_stream_ctxfree(struct gdIOCtx *ctx) +{ + TSRMLS_FETCH(); + + if(ctx->data) { + php_stream_close((php_stream *) ctx->data); + ctx->data = NULL; + } + if(ctx) { + efree(ctx); + } +} + /* {{{ _php_image_output_ctx */ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)()) { @@ -54,64 +81,62 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, int file_len = 0; long quality, basefilter; gdImagePtr im; - FILE *fp = NULL; int argc = ZEND_NUM_ARGS(); int q = -1, i; int f = -1; - gdIOCtx *ctx; + gdIOCtx *ctx = NULL; + zval *to_zval = NULL; + php_stream *stream; /* The third (quality) parameter for Wbmp stands for the threshold when called from image2wbmp(). * The third (quality) parameter for Wbmp and Xbm stands for the foreground color index when called * from imagey<type>(). */ - if (image_type == PHP_GDIMG_TYPE_XBM) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp!|ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { return; } } else { /* PHP_GDIMG_TYPE_GIF * PHP_GDIMG_TYPE_PNG * PHP_GDIMG_TYPE_JPG - * PHP_GDIMG_TYPE_WBM */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s!ll", &imgind, &file, &file_len, &quality, &basefilter) == FAILURE) { + * PHP_GDIMG_TYPE_WBM + * PHP_GDIMG_TYPE_WEBP + * */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|z/!ll", &imgind, &to_zval, &quality, &basefilter) == FAILURE) { return; } } ZEND_FETCH_RESOURCE(im, gdImagePtr, &imgind, -1, "Image", phpi_get_le_gd()); - if (argc > 1) { - if (argc >= 3) { - q = quality; /* or colorindex for foreground of BW images (defaults to black) */ - if (argc == 4) { - f = basefilter; - } + if (argc >= 3) { + q = quality; /* or colorindex for foreground of BW images (defaults to black) */ + if (argc == 4) { + f = basefilter; } } - if (argc > 1 && file_len) { - if (strlen(file) != file_len) { - RETURN_FALSE; - } - PHP_GD_CHECK_OPEN_BASEDIR(file, "Invalid filename"); - - fp = VCWD_FOPEN(file, "wb"); - if (!fp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing: %s", file, strerror(errno)); + if (argc > 1 && to_zval != NULL) { + if (Z_TYPE_P(to_zval) == IS_RESOURCE) { + php_stream_from_zval_no_verify(stream, &to_zval); + if (stream == NULL) { + RETURN_FALSE; + } + } else if (Z_TYPE_P(to_zval) == IS_STRING) { + stream = php_stream_open_wrapper(Z_STRVAL_P(to_zval), "wb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL); + if (stream == NULL) { + RETURN_FALSE; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid 2nd parameter, it must a filename or a stream"); RETURN_FALSE; } - - ctx = gdNewFileCtx(fp); } else { ctx = emalloc(sizeof(gdIOCtx)); ctx->putC = _php_image_output_putc; ctx->putBuf = _php_image_output_putbuf; -#if HAVE_LIBGD204 ctx->gd_free = _php_image_output_ctxfree; -#else - ctx->free = _php_image_output_ctxfree; -#endif #if APACHE && defined(CHARSET_EBCDIC) /* XXX this is unlikely to work any more thies@thieso.net */ @@ -120,6 +145,14 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, #endif } + if (!ctx) { + ctx = emalloc(sizeof(gdIOCtx)); + ctx->putC = _php_image_stream_putc; + ctx->putBuf = _php_image_stream_putbuf; + ctx->gd_free = _php_image_stream_ctxfree; + ctx->data = (void *)stream; + } + switch(image_type) { case PHP_GDIMG_CONVERT_WBM: if(q<0||q>255) { @@ -128,6 +161,12 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, case PHP_GDIMG_TYPE_JPG: (*func_p)(im, ctx, q); break; + case PHP_GDIMG_TYPE_WEBP: + if (q == -1) { + q = 80; + } + (*func_p)(im, ctx, q); + break; case PHP_GDIMG_TYPE_PNG: (*func_p)(im, ctx, q, f); break; @@ -156,12 +195,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, ctx->free(ctx); #endif - if(fp) { - fflush(fp); - fclose(fp); - } - - RETURN_TRUE; + RETURN_TRUE; } /* }}} */ |