ID: 49696
User updated by: sriram dot natarajan at gmail dot com
Reported By: sriram dot natarajan at gmail dot com
Status: Assigned
Bug Type: Feature/Change Request
Operating System: unix/linux
PHP Version: 5.3SVN-2009-09-28 (snap)
Assigned To: pajoye
New Comment:
here is a suggested patch (against 5.3). i have made this patch so that
it uses this prescale value only against bundled libgd. let me know , if
this makes sense to you.
Index: ext/gd/libgd/gd_jpeg.c
===================================================================
--- ext/gd/libgd/gd_jpeg.c (revision 289063)
+++ ext/gd/libgd/gd_jpeg.c (working copy)
@@ -260,21 +260,21 @@
gdFree (row);
}
-gdImagePtr gdImageCreateFromJpeg (FILE * inFile, int ignore_warning)
+gdImagePtr gdImageCreateFromJpeg (FILE * inFile, int ignore_warning,
int prescale)
{
gdImagePtr im;
gdIOCtx *in = gdNewFileCtx(inFile);
- im = gdImageCreateFromJpegCtx(in, ignore_warning);
+ im = gdImageCreateFromJpegCtx(in, ignore_warning, prescale);
in->gd_free (in);
return im;
}
-gdImagePtr gdImageCreateFromJpegPtr (int size, void *data, int
ignore_warning)
+gdImagePtr gdImageCreateFromJpegPtr (int size, void *data, int
ignore_warning, int prescale)
{
gdImagePtr im;
gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
- im = gdImageCreateFromJpegCtx(in, ignore_warning);
+ im = gdImageCreateFromJpegCtx(in, ignore_warning, prescale);
in->gd_free(in);
return im;
@@ -289,7 +289,7 @@
* Create a gd-format image from the JPEG-format INFILE. Returns the
* image, or NULL upon error.
*/
-gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile, int
ignore_warning)
+gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile, int
ignore_warning, int prescale)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
@@ -327,6 +327,8 @@
cinfo.err->error_exit = fatal_jpeg_error;
+ cinfo.scale_denom = prescale;
+
jpeg_create_decompress (&cinfo);
jpeg_gdIOCtx_src (&cinfo, infile);
Index: ext/gd/libgd/gd.h
===================================================================
--- ext/gd/libgd/gd.h (revision 289063)
+++ ext/gd/libgd/gd.h (working copy)
@@ -247,8 +247,8 @@
gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in);
gdImagePtr gdImageCreateFromWBMP(FILE *inFile);
gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile);
-gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning);
-gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int
ignore_warning);
+gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning, int
prescale);
+gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int
ignore_warning, int prescale);
int gdJpegGetVersionInt();
const char * gdPngGetVersionString();
Index: ext/gd/gd.c
===================================================================
--- ext/gd/gd.c (revision 289063)
+++ ext/gd/gd.c (working copy)
@@ -342,6 +342,7 @@
#ifdef HAVE_GD_JPG
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromjpeg, 0)
ZEND_ARG_INFO(0, filename)
+ ZEND_ARG_INFO(0, prescale)
ZEND_END_ARG_INFO()
#endif
@@ -2407,7 +2408,10 @@
FILE * fp = NULL;
#ifdef HAVE_GD_JPG
long ignore_warning;
+#if HAVE_GD_BUNDLED
+ long prescale = 0;
#endif
+#endif
if (image_type == PHP_GDIMG_TYPE_GD2PART) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sllll",
&file,
&file_len, &srcx, &srcy, &width, &height) == FAILURE) {
return;
@@ -2416,6 +2420,12 @@
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero width
or height
not allowed");
RETURN_FALSE;
}
+#if defined(HAVE_GD_JPG) && defined(HAVE_GD_BUNDLED)
+ } else if (image_type == PHP_GDIMG_TYPE_JPG) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l",
&file,
&file_len, &prescale) == FAILURE) {
+ return;
+ }
+#endif
} else {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file,
&file_len) == FAILURE) {
return;
@@ -2460,6 +2470,10 @@
if (image_type == PHP_GDIMG_TYPE_GD2PART) {
im = (*ioctx_func_p)(io_ctx, srcx, srcy, width, height);
+#if defined(HAVE_GD_JPG) && defined(HAVE_GD_BUNDLED)
+ } else if (image_type == PHP_GDIMG_TYPE_JPG) {
+ im = (*ioctx_func_p)(io_ctx, prescale);
+#endif
} else {
im = (*ioctx_func_p)(io_ctx);
}
@@ -2493,7 +2507,7 @@
case PHP_GDIMG_TYPE_JPG:
ignore_warning =
INI_INT("gd.jpeg_ignore_warning");
#ifdef HAVE_GD_BUNDLED
- im = gdImageCreateFromJpeg(fp, ignore_warning);
+ im = gdImageCreateFromJpeg(fp, ignore_warning,
prescale);
#else
im = gdImageCreateFromJpeg(fp);
#endif
@@ -2533,7 +2547,7 @@
#endif /* HAVE_GD_GIF_READ */
#ifdef HAVE_GD_JPG
-/* {{{ proto resource imagecreatefromjpeg(string filename)
+/* {{{ proto resource imagecreatefromjpeg(string filename[, int
prescale])
Create a new image from JPEG file or URL */
PHP_FUNCTION(imagecreatefromjpeg)
{
Previous Comments:
------------------------------------------------------------------------
[2009-09-28 08:36:29] [email protected]
I have a patch for libgd and jpeglib7 to allow exactly that. However a
manual scale is still necessary if you like to have a good result.
------------------------------------------------------------------------
[2009-09-28 05:03:53] sriram dot natarajan at gmail dot com
Description:
------------
GD library is commonly used in PHP5 applications for image processing.
When creating thumbnails from a large jpeg image, the original image
currently has to be decoded to a full-size copy before being resampled
or resized. This is a relatively expensive step. The underlying jpeg
library has a capability of prescaling an image when it is being
decoded, so for example the decoded image could be only 1/16 the size of
the fullsize image by prescaling by a factor of 4. This saves a
substantial amount of cpu time.
Expected result:
----------------
we can update php libgd library and our php gd extension to leverage
underlying jpeg's ability to prescale image at the time of creating jpeg
images.
for example, we can introduce new API or patch our existing
gdImageCreateFromJpeg API to have an extra argument for prescale size so
that we can set the value of 'prescale' value like below
cinfo.scale_denom = prescale;
before calling "jpeg_start_decompress (&cinfo)" function.
[credits: thanks to Richard Smith for coming up with this nice
suggestion]
af course, this will allow users to invoke our 'imagecreatefromjpeg'
with an optional argument which specifies the prescale size of this
jpeg.
$src_img=imagecreatefromjpeg($name, 4);
Actual result:
--------------
better performance while producing jpeg based thumbnails
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=49696&edit=1