United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6354056 JPEGImageReader could be optimized
JDK-6354056 : JPEGImageReader could be optimized

Details
Type:
Bug
Submit Date:
2005-11-22
Status:
Resolved
Updated Date:
2008-02-05
Project Name:
JDK
Resolved Date:
2005-12-05
Component:
client-libs
OS:
solaris_9
Sub-Component:
javax.imageio
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:

Related Reports

Sub Tasks

Description
In imageioJPEG.c, we read one scanline at a time, then copy the decoded data into
a temporary buffer before stuffing it into the destination raster.  That intermediate
copy step is currently not as efficient as possible since it copies one byte at a
time, but in the common case (where jpeg_read_scanlines() produces 3ByteRgb data)
the component data is already ordered, so we could simply use memcpy() instead.

                                    

Comments
SUGGESTED FIX

*** /tmp/geta1993	Mon Nov 21 19:19:19 2005
--- imageioJPEG.c	Thu Nov 10 15:49:37 2005
***************
*** 1764,1769 ****
--- 1764,1770 ----
      int maxBandValue, halfMaxBandValue;
      boolean mustScale = FALSE;
      boolean progressive = FALSE;
+     boolean orderedBands = TRUE;
      imageIODataPtr data = (imageIODataPtr) ptr;
      j_decompress_ptr cinfo;
  
***************
*** 1812,1817 ****
--- 1813,1821 ----
  
      for (i = 0; i < numBands; i++) {
          bands[i] = body[i];
+         if (orderedBands && (bands[i] != i)) {
+             orderedBands = FALSE;
+         }
      }
  
      (*env)->ReleaseIntArrayElements(env, srcBands, body, JNI_ABORT);
***************
*** 1974,1979 ****
--- 1978,1991 ----
                          *out++ = data->scale[i][*(in+bands[i])];
                      }
                  }
+             } else if (orderedBands && (pixelStride == numBands)) {
+                 // Optimization: The component bands are ordered sequentially,
+                 // so we can simply use memcpy() to copy the intermediate
+                 // scanline buffer into the raster.
+                 in = scanLinePtr + (sourceXStart * cinfo->num_components);
+                 if (pixelLimit > in) {
+                     memcpy(out, in, pixelLimit - in);
+                 }
              } else {
                  for (in = scanLinePtr+sourceXStart*cinfo->num_components;
                       in < pixelLimit;
                                     
2005-11-22
EVALUATION

See suggested fix.  This change is especially beneficial on solaris-sparc (results
taken on SB2000, 900 MHz USIII, 1GB RAM, -client, -Xms256M -Xmx512M, "base" is the
2005-11-19.mustang 2D nightly build, "test" is similar but contains the changes
described here):

Options common across all tests:
  testname=imageio.input.image.imageio.reader.tests.read
  imageio.input.image.imageio.reader.opts.ignoreMetadata=true
  imageio.input.opts.general.source=file
  imageio.input.image.imageio.opts.format=core-jpg
  imageio.input.image.imageio.reader.opts.installListener=false
  imageio.input.image.imageio.reader.opts.seekForwardOnly=true
  imageio.input.opts.imageio.useCache=false
  imageio.opts.content=photo
imageio.opts.size=1000:
base: 3874.603733 (var=0.51%) (100.0%)
test: 5756.207674 (var=29.19%) (148.56%)
imageio.opts.size=250:
base: 3591.873386 (var=5.87%) (100.0%)
test: 5702.289632 (var=2.83%) (158.76%)
imageio.opts.size=4000:
base: 1893.939393 (var=4.89%) (100.0%)
test: 4356.112169 (var=11.39%) (230.0%)

This fix has less dramatic results on other platforms, such as solaris-i586 (results
taken on W2100z, 2x 2.0 GHz Opteron, 2GB RAM, same options as above):
imageio.opts.size=1000:
base: 13322.61398 (var=0.35%) (100.0%)
test: 14672.16872 (var=0.16%) (110.13%)
imageio.opts.size=250:
base: 12019.48888 (var=0.72%) (100.0%)
test: 13075.79003 (var=0.6%) (108.79%)
imageio.opts.size=4000:
base: 11624.52775 (var=0.25%) (100.0%)
test: 12779.55271 (var=0.19%) (109.94%)

And on windows-i586 (results taken on 2x 2.8 GHz P4, 1GB RAM, same options as above):
imageio.opts.size=1000:
base: 16494.39190 (var=0.0%) (100.0%)
test: 17877.92235 (var=0.17%) (108.39%)
imageio.opts.size=250:
base: 13722.69184 (var=0.69%) (100.0%)
test: 14741.27557 (var=0.16%) (107.42%)
imageio.opts.size=4000:
base: 15581.52476 (var=0.43%) (100.0%)
test: 17467.24890 (var=0.42%) (112.1%)
                                     
2005-11-22



Hardware and Software, Engineered to Work Together