United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4705399 : drawImage can be extremely slow for drawing scaled instances

Details
Type:
Bug
Submit Date:
2002-06-20
Status:
Resolved
Updated Date:
2006-03-22
Project Name:
JDK
Resolved Date:
2006-03-22
Component:
client-libs
OS:
linux,solaris_10
Sub-Component:
2d
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.2,6
Fixed Versions:

Related Reports
Backport:
Backport:
Duplicate:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
Name: jk109818			Date: 06/20/2002


FULL PRODUCT VERSION :
[mcmahan@gs164 test]$ java -version
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

FULL OPERATING SYSTEM VERSION :
Linux gs164.sp.cs.cmu.edu 2.4.16 #1-i686-001 Tue Dec 4
01:39:05 EST 2001 i686 unknown

ADDITIONAL OPERATING SYSTEMS :

glibc-2.2.2-10
Red Hat Linux release 7.1 (Seawolf)

A DESCRIPTION OF THE PROBLEM :
WHen running the code attached, a simple program to scale
an image and save it to a new file, some large images take
several orders of magnitude longer to scale than expected.

The images scale in about the same amount of time when
using the ImageMagick convert command.

The extremely long time taken to convert slow.jpg occurs
when both the SCALE_SMOOTH and SCALE_FAST hints are given.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Download slow.jpg and fast.jpg
http://www-2.cs.cmu.edu/~mcmahan/slow.jpg
http://www-2.cs.cmu.edu/~mcmahan/fast.jpg
(Both files are about 8M)

2. run java Convert fast.jpg foo.jpg and observe running
times

EXPECTED VERSUS ACTUAL BEHAVIOR :
Here are results for convert on slow.jpg after over a
minute of processing:

[mcmahan@gs164 test]$ java Convert slow.jpg foo.jpg
Loading ...  11.303s
Input image is size 2443x3535
Scaling... Warning: Cannot convert string
"MetaCtrl<Key>Insert" to type VirtualBinding
0.374s
Drawing...  0  1  2  3 4 5  6  7  8  9  10  11  12  13  14
 15  16  17  18

Results for fast.jpg:
[mcmahan@gs164 test]$ java Convert fast.jpg foo.jpg
Loading ...  7.918s
Input image is size 3557x2345
Scaling... Warning: Cannot convert string
"MetaCtrl<Key>Insert" to type VirtualBinding
0.416s
Drawing...  0  1  2  3  4  5  6  7  8  9  10  11  12  13
14  15  16  17  18  19  20  21  22  23  24  25  26  27  28
 29  30  31  32  33  34  35  36  37  38  39  40  41  42
43  44  45  46  47  48  49  50  51  52  53  54  55  56  57
 58  59  60  61  62  63  64  65  66  67  68  69  70  71
72  73  74  75  76  77  78  79  80  81  82  83  84  85
86  87  88  89  90  91  92  93  94  95  96  97  98  99
100  101  102  103  104  105  106  107  108  109  110  111
 112  113  114  115  116  117  118  119  120  121  122
123  124  125  126  127  128  129  130  131  132  133  134
 135  136  137  138  139  140  141  142  143  144  145
146  147  148  149  150  151  152  153  154  155  156  157
158  159  160  161  162  163  164  165  166  167  168  169
 170  171  172  173  174  175  176  177  178  179  180
181  182  183  184  185  186  187  188  189  190  191  192
 193  194  195  196  197  198  199  200  201  202  203
204  205  206  207  208  209  210  211  212  213  214  215
 216  217  218  219  220  221  222  223  224  225  226
227  228  229  230  231  232  233  234  235  236  237  238
 239  240  241  242  243  244  245  246  247  248  249
250  251  252  253  254  255  256  257  258  259  260  261
 262  263  264  265  266  267  268  269  270  271  272
273  274  275  276  277  278  279  280  281  282  283  284
 285  286  287  288  289  290  291  292  293  294  295
296  297  298  299 5.976s

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Dimension;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.JPanel;
import javax.swing.JFrame;


import javax.imageio.*;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.ImageInputStream;

public class Convert{

    public static void main(String[] args){
 int w = 300;
 int h = 300;

 File in = new File(args[0]);
 File out = new File(args[1]);
 if(! in.isFile()){
     usage();
 }
 

 System.out.print("Loading ...  ");
 long lt = System.currentTimeMillis();
 BufferedImage image = null;
 //load image
 try{
     image = ImageIO.read(in);
 }catch(IOException e){
     System.out.println("Error reading imageFile " + in);
     System.exit(1);
 }
 lt = System.currentTimeMillis() - lt;
 System.out.println(  (lt/1000.0) + "s");
 
 
 if(image == null){ System.exit(1); }

 System.out.println("Input image is size " + image.getWidth() + "x" +
image.getHeight());

 System.out.print("Scaling... ");
 lt = System.currentTimeMillis();
 //Image scaled = image.getScaledInstance(w, h,
Image.SCALE_FAST);
 Image scaled = image.getScaledInstance(w, h,
Image.SCALE_SMOOTH);
 lt = System.currentTimeMillis() - lt;
 System.out.println(  (lt/1000.0) + "s");

 System.out.print("Drawing... ");
 lt = System.currentTimeMillis();
 BufferedImage buffered;
 if(image instanceof BufferedImage){
     int type = ((BufferedImage)image).getType();
     buffered = new BufferedImage(w, h, type);
 }else{
     buffered = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
 }
 Graphics2D g2 = buffered.createGraphics();
 g2.drawImage(scaled,0,0, new MyImageObserver());
 lt = System.currentTimeMillis() - lt;
 System.out.println(  (lt/1000.0) + "s");

 //get a writer
 Iterator writers = ImageIO.getImageWritersByFormatName("jpeg");
 javax.imageio.ImageWriter writer =
(javax.imageio.ImageWriter)writers.next();
 
 try{
     // set output
     ImageOutputStream ios = ImageIO.createImageOutputStream(out);
     writer.setOutput(ios);
     
     //set params
     ImageWriteParam param = writer.getDefaultWriteParam();
     param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
     param.setCompressionQuality(0.75f);
     
     //write
     writer.write(null, new IIOImage(buffered,null,null), param);
 }catch(IOException e){
     System.out.println("Error saving " + e);
     e.printStackTrace();
 }

    }
    
    private static void usage(){
 System.out.println("Usage: convert inputfile outputfile");
    }
}

 class MyImageObserver implements ImageObserver{

 public boolean imageUpdate(Image img, int infoflags, int x, int y, int
width, int height){
     if ((infoflags & SOMEBITS) != 0) {
  System.out.print( " " + y + " ");
     }
     return true;
 }

    }
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
No work around known.
(Review ID: 144809) 
======================================================================

                                    

Comments
EVALUATION

The reason of the slow drawing operation is that we are using
 embedded color profile to get RGB color values.

 As possible solution (or workaround) I suggest to create images
 with sRGB color space  by default even embedded color profile is
 present in the jpeg file.
                                     
2006-03-03
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mustang


                                     
2004-09-18
EVALUATION

It appears that the RenderedImage produced by reading slow.jpg using Image I/O
has a non-sRGB color space.  When the scaled instance is rendered, it goes
through general loops that convert each pixel into the sRGB color space, which
is not as optimal as if the image was originally in the sRGB color space (like
fast.jpg).  The old com.sun.image.codec.jpeg.JPEGDecoder produces an sRGB
BufferedImage for slow.jpg, so I'll need to investigate to determine which
behavior is correct.
###@###.### 2002-09-27

Should investigate this for Mustang, since it is one of the more problematic
issues for people migrating over to the IIO framework.
###@###.### 2004-09-17
                                     
2002-09-27
WORK AROUND

Avoid using JPEG images with non-standard color spaces.  You can use the
com.sun.image.codec.jpeg.JPEGDecoder since it doesn't cause the slow rendering
behavior, but keep in mind that this decoder is unsupported by Sun, and is not
guaranteed to be available in other JDKs or in future releases.
###@###.### 2002-09-27
                                     
2002-09-27



Hardware and Software, Engineered to Work Together