View Javadoc

1   package com.atlassian.core.util.thumbnail;
2   
3   import java.awt.image.BufferedImage;
4   import java.awt.image.ColorModel;
5   import java.awt.image.ImageConsumer;
6   import java.awt.image.WritableRaster;
7   import java.util.Hashtable;
8   
9   public class SimpleImageConsumer implements ImageConsumer
10  {
11      private final Object holder;
12  
13      private ColorModel colorModel;
14      private WritableRaster raster;
15      private int width;
16      private int height;
17  
18      private BufferedImage image;
19      private int[] intBuffer;
20      private volatile boolean loadComplete;
21  
22      public SimpleImageConsumer()
23      {
24          holder = new Object();
25          width = -1;
26          height = -1;
27          loadComplete = false;
28      }
29  
30      public void imageComplete(int status)
31      {
32          synchronized(holder)
33          {
34              loadComplete = true;
35              holder.notify();
36          }
37      }
38  
39      public void setColorModel(ColorModel model)
40      {
41          colorModel = model;
42          createImage();
43      }
44  
45      /**
46       * Notification of the dimensions of the source image.
47       *
48       * @param w The width of the source image
49       * @param h The height of the source image
50       */
51      public void setDimensions(int w, int h)
52      {
53          width = w;
54          height = h;
55          createImage();
56      }
57  
58      /**
59       * Notification of load hints that may be useful. Not used in this
60       * implementation.
61       *
62       * @param flags The hints
63       */
64      public void setHints(int flags)
65      {
66      }
67  
68      /**
69       * Notification of a bunch of pixel values in byte form. Used for
70       * 256 color or less images (eg GIF, greyscale etc).
71       *
72       * @param x The starting x position of the pixels
73       * @param y The starting y position of the pixels
74       * @param w The number of pixels in the width
75       * @param h The number of pixels in the height
76       * @param model The color model used with these pixel values
77       * @param offset The offset into the source array to copy from
78       * @param scansize The number of pixel values between rows
79       */
80      public void setPixels(int x,
81                            int y,
82                            int w,
83                            int h,
84                            ColorModel model,
85                            byte[] pixels,
86                            int offset,
87                            int scansize)
88      {
89          if((intBuffer == null) || (pixels.length > intBuffer.length))
90              intBuffer = new int[pixels.length];
91  
92          for(int i = pixels.length; --i >= 0 ; )
93              intBuffer[i] = (int)pixels[i] & 0xFF;
94  
95          raster.setPixels(x, y, w, h, intBuffer);
96      }
97  
98      /**
99       * Notification of a bunch of pixel values as ints. These will be
100      * full 3 or 4 component images.
101      *
102      * @param x The starting x position of the pixels
103      * @param y The starting y position of the pixels
104      * @param w The number of pixels in the width
105      * @param h The number of pixels in the height
106      * @param model The color model used with these pixel values
107      * @param offset The offset into the source array to copy from
108      * @param scansize The number of pixel values between rows
109      */
110     public void setPixels(int x,
111                           int y,
112                           int w,
113                           int h,
114                           ColorModel model,
115                           int[] pixels,
116                           int offset,
117                           int scansize)
118     {
119         image.setRGB(x, y, w, h, pixels, offset, scansize);
120     }
121 
122     /**
123      * Notification of the properties of the image to use. Not used in this implementation.
124      *
125      * @param props The map of properties for this image
126      */
127     public void setProperties(Hashtable props)
128     {
129         createImage();
130     }
131 
132     //------------------------------------------------------------------------
133     // Local methods
134     //------------------------------------------------------------------------
135 
136     /**
137      * Fetch the image. This image is not necessarily completely rendered
138      * although we do try to guarantee it.
139      *
140      * Torsten Römer: Changed to public
141      *
142      * @return The image that has been created for the current input
143      */
144     public BufferedImage getImage()
145     {
146         if(!loadComplete)
147         {
148             synchronized(holder)
149             {
150                 try
151                 {
152                     holder.wait();
153                 }
154                 catch(InterruptedException ie)
155                 {
156                 }
157             }
158         }
159 
160         return image;
161     }
162 
163     /**
164      * Convenience method used to create the output image based on the data
165      * that has been given to us so far. Will not create the image until all
166      * the necessary information is given, and once created, will not overwrite
167      * the current image.
168      *
169      * Torsten Römer: Use another constructor of BufferedImage. With the one used
170      * here the resulting jpg was extremely blueish.
171      */
172     private void createImage()
173     {
174         // meet the preconditions first.
175         if((image != null) ||
176            (width == -1) ||
177            (colorModel == null))
178             return;
179 
180         image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
181     }
182 }