[ 
https://issues.apache.org/jira/browse/IMAGING-69?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13286668#comment-13286668
 ] 

Damjan Jovanovic commented on IMAGING-69:
-----------------------------------------

Thank you, but please reattach, this time clicking "Grant license to ASF for 
inclusion in ASF works". I can't use it otherwise.

                
> Streamlined TIFF strip reader reduces load time by a factor of 5
> ----------------------------------------------------------------
>
>                 Key: IMAGING-69
>                 URL: https://issues.apache.org/jira/browse/IMAGING-69
>             Project: Apache Commons Imaging
>          Issue Type: Improvement
>            Reporter: Gary Lucas
>         Attachments: ApacheImagingTrackerItem69_May_30_2012.patch, 
> ApacheImagingTrackerItem69_May_9_2012.patch, 
> Sanselan-58-TiffStripReaderSpeed.patch, Tracker_Item_58_22_Apr_2012.patch
>
>   Original Estimate: 1h
>  Remaining Estimate: 1h
>
> Testing reveals that streamlining the DataReaderStrip.java operations for 8 
> and 24 bit-per-pixel TIFF images reduces the TIFF file load time by a factor 
> of 5.  
> For each pixel in images of these types, the interpretStrip() method of 
> DataReaderStrip makes calls to a generic bit extractor using its 
> getSamplesAsBytes() method.  Internally, this method simply copies the 
> requisite number of bytes (8 or 24), but it executes a lot of conditional 
> statements to do so.  Under most architectures, conditionals tend to take 2 
> to 3 times as long to execute as simple arithmetic statements, so this 
> approach is expensive (especially since an image may contain millions of 
> pixels).  While the implementation is very generic, the majority of TIFF 
> files out there appear to fall into two simple categories.  By implementing 
> specialized code for these two cases, the loading time for TIFF images is 
> dramatically reduced.
> The following snippet shows the code I used for testing.  It was added right 
> at the beginning of the interpretStrip() method.
>  // Oct 2011 changes.
>         //  The general case decoder is based on the idea of using a 
>         //  generic bit-reader to unpack the number of bytes that are
>         //  needed.  Although it is efficiently implemented, it does
>         //  require performing at least three conditional branches per sample
>         //  extracted (and often more).   This change attempts to bypass that
>         //  overhead by implementing specialized blocks of extraction code
>         //  for commonly used 8 bitsPerPixel and 24 bitsPerPixel cases.
>         //  In other cases, it will simply fall through to the original code.
>         //    note that when promoting a byte to an integer, it is necessary
>         //    to mask it with 0xff because the Java byte type is signed
>         //    an this implementation requires an unsigned value
>         if(x>=width)
>         {
>             // this may not be required.  it was coded based on the 
>             // original implementation.  But looking at the TIFF 6.0 spec,
>             // it looks like the rows always evenly fill out the strip,
>             // so there should never be a partial row in a strip and x
>             // should not be anything except zero.
>             x = 0;
>             y++;
>         }
>         if(y>=height)
>         {
>             // we check it once before starting, so that we don't have
>             // to check it redundantly for each pixel
>             return;
>         }
>         
>         if(predictor==-1 && this.bitsPerPixel==8)
>         {
>             int [] samples = new int[1];
>             for(int i=0; i<pixels_per_strip; i++)
>             {
>                 samples[0] = bytes[i]&0x000000ff;
>                 photometricInterpreter.interpretPixel(bi, samples, x, y);
>                 x++;
>                 if(x>=width)
>                 {
>                     x = 0;
>                     y++;
>                     if(y>=height)
>                         return; // any remaining bytes are not needed
>                 }
>             } 
>             return;    
>         }
>         else if(predictor==-1 && this.bitsPerPixel==24)
>         {
>             int [] samples = new int[3];
>             int k = 0;
>             for(int i=0; i<pixels_per_strip; i++)
>             {
>                 samples[0] = bytes[k++]&0x000000ff;
>                 samples[1] = bytes[k++]&0x000000ff;
>                 samples[2] = bytes[k++]&0x000000ff;
>                 photometricInterpreter.interpretPixel(bi, samples, x, y);
>                 x++;
>                 if(x>=width)
>                 {
>                     x = 0;
>                     y++;
>                     if(y>=height)
>                         return; // any remaining bytes are not needed
>                 }
>             }   
>             return;
>         }
>         
>         // original code before Oct 2011 modification
>         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
>         BitInputStream bis = new BitInputStream(bais);
> etc.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to