1 /**
2  * The utillib library.
3  * More information is available at http://www.jinchess.com/.
4  * Copyright (C) 2002 Alexander Maryanovsky.
5  * All rights reserved.
6  *
7  * The utillib library is free software; you can redistribute
8  * it and/or modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * The utillib library is distributed in the hope that it will
13  * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with utillib library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 
22 package free.util;
23 
24 import java.awt.Image;
25 import java.awt.Toolkit;
26 import java.awt.image.ImageObserver;
27 
28 
29 /**
30  * Various image related utilities.
31  */
32 
33 public class ImageUtilities{
34 
35 
36 
37   /**
38    * A constant indicating that the loading of the image completed.
39    */
40 
41   public static final int COMPLETE = 1;
42 
43 
44 
45   /**
46    * A constant indicating that the loading of the image errored.
47    */
48 
49   public static final int ERRORED = 2;
50 
51 
52 
53   /**
54    * A constant indicating that the loading of the image was aborted.
55    */
56 
57   public static final int ABORTED = 3;
58 
59 
60 
61   /**
62    * A constant indicating that the loading of the image was interrupted.
63    */
64 
65   public static final int INTERRUPTED = 4;
66 
67 
68 
69   /**
70    * Starts loading the given image, returns only when it's done loading.
71    * Note that it's much more efficient to preload a lot of images at once using
72    * the preload(Image []) method instead of this one.
73    *
74    * @return The result of the image loading, either {@link #COMPLETE},
75    * {@link #ERRORED}, {@link #ABORTED} or {@link #INTERRUPTED}.
76    *
77    * @see #preload(java.awt.Image [], int [])
78    */
79 
preload(Image image)80   public static int preload(Image image){
81     Toolkit toolkit = Toolkit.getDefaultToolkit();
82 
83     // Check if already loaded
84     if ((toolkit.checkImage(image, -1, -1, null) & ImageObserver.ALLBITS) != 0)
85       return COMPLETE;
86 
87     Object lock = new Object();
88     synchronized(lock){
89       while (true){
90         ImageLoadObserver observer = new ImageLoadObserver(lock);
91         toolkit.prepareImage(image, -1, -1, observer);
92         int result = toolkit.checkImage(image, -1, -1, null);
93         if ((result & ImageObserver.ALLBITS) != 0)
94           return COMPLETE;
95         if ((result & ImageObserver.ERROR) != 0)
96           return ERRORED;
97         if ((result & ImageObserver.ABORT) != 0)
98           return ABORTED;
99 
100         try{
101           lock.wait();
102           return observer.getResult();
103         } catch (InterruptedException e){
104             return INTERRUPTED;
105           }
106       }
107     }
108   }
109 
110 
111 
112   /**
113    * Starts loading the given images, returns only when all the images are done
114    * loading. If you just need to preload one Image, use the preload(Image) method
115    * instead.
116    *
117    * @return An array specifying the loading result of each image. Possible values
118    * are {@link #COMPLETE}, {@link #ERRORED} and {@link #ABORTED}.
119    *
120    * @see #preload(Image)
121    */
122 
preload(Image [] images, int [] results)123   public static int [] preload(Image [] images, int [] results){
124     Object [] locks = new Object[images.length];
125     ImageLoadObserver [] loadObservers = new ImageLoadObserver[images.length];
126     if ((results == null) || (results.length < images.length))
127       results = new int[images.length];
128     Toolkit toolkit = Toolkit.getDefaultToolkit();
129     for (int i = 0; i < images.length; i++){
130       locks[i] = new Object();
131       loadObservers[i] = new ImageLoadObserver(locks[i]);
132       toolkit.prepareImage(images[i], -1, -1, loadObservers[i]);
133     }
134 
135     for (int i = 0; i < images.length; i++){
136       synchronized(locks[i]){
137         int result = toolkit.checkImage(images[i], -1, -1, null);
138 
139         if ((result & ImageObserver.ALLBITS) != 0){
140           results[i] = COMPLETE;
141           continue;
142         }
143         if ((result & ImageObserver.ERROR) != 0){
144           results[i] = ERRORED;
145           continue;
146         }
147         if ((result & ImageObserver.ABORT) != 0){
148           results[i] = ABORTED;
149           continue;
150         }
151 
152         try{
153           locks[i].wait();
154           results[i] = loadObservers[i].getResult();
155         } catch (InterruptedException e){
156             results[i] = INTERRUPTED;
157           }
158       }
159     }
160 
161     return results;
162   }
163 
164 
165 
166   /**
167    * Returns whether the specified image is already fully loaded.
168    */
169 
isLoaded(Image image)170   public static boolean isLoaded(Image image){
171     return (Toolkit.getDefaultToolkit().checkImage(image, -1, -1, null) & ImageObserver.ALLBITS) != 0;
172   }
173 
174 
175 
176   /**
177    * This class is an implementation of ImageObserver which notifies a given
178    * lock when loading of the Image is done. This can be used to wait until a
179    * certain Image has finished loading.
180    */
181 
182   public static class ImageLoadObserver implements ImageObserver{
183 
184 
185     /**
186      * The lock.
187      */
188 
189     private final Object lock;
190 
191 
192 
193     /**
194      * The loading result.
195      */
196 
197     private int result = -1;
198 
199 
200 
201 
202     /**
203      * Creates a new ImageLoadObserver which will notify the given lock when
204      * the Image is done loading.
205      */
206 
ImageLoadObserver(Object lock)207     public ImageLoadObserver(Object lock){
208       this.lock = lock;
209     }
210 
211 
212 
213     /**
214      * If infoflags has the ALLBITS flag set, notifies the lock and returns
215      * false, otherwise simply returns true.
216      */
217 
imageUpdate(Image img, int infoflags, int x, int y, int width, int height)218     public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height){
219       synchronized(lock){
220         if ((infoflags & ALLBITS)!=0){
221           result = ImageUtilities.COMPLETE;
222           lock.notify();
223           return false;
224         }
225         if ((infoflags & ERROR)!=0){
226           result = ImageUtilities.ERRORED;
227           lock.notify();
228           return false;
229         }
230         if ((infoflags & ABORT)!=0){
231           result = ImageUtilities.ABORTED;
232           lock.notify();
233           return false;
234         }
235       }
236       return true;
237     }
238 
239 
240 
241 
242     /**
243      * Returns the result of the image loading process or -1 if loading hasn't finished yet.
244      * Possible values are {@link ImageUtilities#COMPLETE}, {@link ImageUtilities#ERRORED}
245      * and {@link ImageUtilities#ABORTED}
246      */
247 
getResult()248     public int getResult(){
249       return result;
250     }
251 
252   }
253 
254 
255 }
256