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:
oh, i missed your earlier post that you do have a patch. and your points on jpeg 6 is very true. i was just working on the test script. i guess, i will get back to my work :-) Previous Comments: ------------------------------------------------------------------------ [2009-10-01 18:56:27] paj...@php.net Sorry, my last comment has been submitted too quickly. I won't use this patch as it breaks API and ABI backward compatibility. It is also better to provide more user friendly functions to get a resized image without worrying about which scale can actually be used. The patch is also missing the tests if libjpeg7 is actually used. I won't support patched jpeg6 as there are dozen versions out there. ------------------------------------------------------------------------ [2009-10-01 18:54:04] paj...@php.net Thanks for the patch. However you seemed to have missed my answer where I said that I have a patch already. ------------------------------------------------------------------------ [2009-10-01 18:52:21] sriram dot natarajan at gmail dot com 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) { ------------------------------------------------------------------------ [2009-09-28 08:36:29] paj...@php.net 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