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

Reply via email to