1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/13 moduleorg.eclipse.swt.graphics.ImageLoader;
14 15 importjava.lang.all;
16 importjava.util.Vector;
17 18 19 publicimportorg.eclipse.swt.graphics.ImageLoaderListener;
20 publicimportorg.eclipse.swt.graphics.ImageLoaderEvent;
21 publicimportorg.eclipse.swt.graphics.ImageData;
22 23 importorg.eclipse.swt.SWT;
24 importorg.eclipse.swt.internal.Compatibility;
25 importorg.eclipse.swt.internal.image.FileFormat;
26 27 version(Tango){
28 importtango.core.Array;
29 } else { // Phobos30 }
31 32 33 /**
34 * Instances of this class are used to load images from,
35 * and save images to, a file or stream.
36 * <p>
37 * Currently supported image formats are:
38 * </p><ul>
39 * <li>BMP (Windows or OS/2 Bitmap)</li>
40 * <li>ICO (Windows Icon)</li>
41 * <li>JPEG</li>
42 * <li>GIF</li>
43 * <li>PNG</li>
44 * <li>TIFF</li>
45 * </ul>
46 * <code>ImageLoaders</code> can be used to:
47 * <ul>
48 * <li>load/save single images in all formats</li>
49 * <li>load/save multiple images (GIF/ICO/TIFF)</li>
50 * <li>load/save animated GIF images</li>
51 * <li>load interlaced GIF/PNG images</li>
52 * <li>load progressive JPEG images</li>
53 * </ul>
54 *
55 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ImageAnalyzer</a>
56 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
57 */58 59 publicclassImageLoader {
60 61 /**
62 * the array of ImageData objects in this ImageLoader.
63 * This array is read in when the load method is called,
64 * and it is written out when the save method is called
65 */66 publicImageData[] data;
67 68 /**
69 * the width of the logical screen on which the images
70 * reside, in pixels (this corresponds to the GIF89a
71 * Logical Screen Width value)
72 */73 publicintlogicalScreenWidth;
74 75 /**
76 * the height of the logical screen on which the images
77 * reside, in pixels (this corresponds to the GIF89a
78 * Logical Screen Height value)
79 */80 publicintlogicalScreenHeight;
81 82 /**
83 * the background pixel for the logical screen (this
84 * corresponds to the GIF89a Background Color Index value).
85 * The default is -1 which means 'unspecified background'
86 *
87 */88 publicintbackgroundPixel;
89 90 /**
91 * the number of times to repeat the display of a sequence
92 * of animated images (this corresponds to the commonly-used
93 * GIF application extension for "NETSCAPE 2.0 01").
94 * The default is 1. A value of 0 means 'display repeatedly'
95 */96 publicintrepeatCount;
97 98 /*
99 * the set of ImageLoader event listeners, created on demand
100 */101 VectorimageLoaderListeners;
102 103 /**
104 * Construct a new empty ImageLoader.
105 */106 publicthis() {
107 imageLoaderListeners = newVector();
108 reset();
109 }
110 111 /**
112 * Resets the fields of the ImageLoader, except for the
113 * <code>imageLoaderListeners</code> field.
114 */115 voidreset() {
116 data = null;
117 logicalScreenWidth = 0;
118 logicalScreenHeight = 0;
119 backgroundPixel = -1;
120 repeatCount = 1;
121 }
122 123 /**
124 * Loads an array of <code>ImageData</code> objects from the
125 * specified input stream. Throws an error if either an error
126 * occurs while loading the images, or if the images are not
127 * of a supported type. Returns the loaded image data array.
128 *
129 * @param stream the input stream to load the images from
130 * @return an array of <code>ImageData</code> objects loaded from the specified input stream
131 *
132 * @exception IllegalArgumentException <ul>
133 * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
134 * </ul>
135 * @exception SWTException <ul>
136 * <li>ERROR_IO - if an IO error occurs while reading from the stream</li>
137 * <li>ERROR_INVALID_IMAGE - if the image stream contains invalid data</li>
138 * <li>ERROR_UNSUPPORTED_FORMAT - if the image stream contains an unrecognized format</li>
139 * </ul>
140 */141 publicImageData[] load(InputStreamstream) {
142 if (streamisnull) SWT.error(SWT.ERROR_NULL_ARGUMENT);
143 reset();
144 data = FileFormat.load(stream, this);
145 returndata;
146 }
147 148 /**
149 * Loads an array of <code>ImageData</code> objects from the
150 * file with the specified name. Throws an error if either
151 * an error occurs while loading the images, or if the images are
152 * not of a supported type. Returns the loaded image data array.
153 *
154 * @param filename the name of the file to load the images from
155 * @return an array of <code>ImageData</code> objects loaded from the specified file
156 *
157 * @exception IllegalArgumentException <ul>
158 * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
159 * </ul>
160 * @exception SWTException <ul>
161 * <li>ERROR_IO - if an IO error occurs while reading from the file</li>
162 * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
163 * <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
164 * </ul>
165 */166 publicImageData[] load(Stringfilename) {
167 if (filenameisnull) SWT.error(SWT.ERROR_NULL_ARGUMENT);
168 InputStreamstream = null;
169 voidclose(){
170 try {
171 if( stream !isnull ) stream.close();
172 } catch (IOExceptione) {
173 // Ignore error174 }
175 }
176 try {
177 stream = Compatibility.newFileInputStream(filename);
178 scope(exit) close();
179 180 returnload(stream);
181 } catch (IOExceptione) {
182 SWT.error(SWT.ERROR_IO, e);
183 }
184 returnnull;
185 }
186 187 /**
188 * Saves the image data in this ImageLoader to the specified stream.
189 * The format parameter can have one of the following values:
190 * <dl>
191 * <dt><code>IMAGE_BMP</code></dt>
192 * <dd>Windows BMP file format, no compression</dd>
193 * <dt><code>IMAGE_BMP_RLE</code></dt>
194 * <dd>Windows BMP file format, RLE compression if appropriate</dd>
195 * <dt><code>IMAGE_GIF</code></dt>
196 * <dd>GIF file format</dd>
197 * <dt><code>IMAGE_ICO</code></dt>
198 * <dd>Windows ICO file format</dd>
199 * <dt><code>IMAGE_JPEG</code></dt>
200 * <dd>JPEG file format</dd>
201 * <dt><code>IMAGE_PNG</code></dt>
202 * <dd>PNG file format</dd>
203 * </dl>
204 *
205 * @param stream the output stream to write the images to
206 * @param format the format to write the images in
207 *
208 * @exception IllegalArgumentException <ul>
209 * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
210 * </ul>
211 * @exception SWTException <ul>
212 * <li>ERROR_IO - if an IO error occurs while writing to the stream</li>
213 * <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
214 * <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
215 * </ul>
216 */217 publicvoidsave(OutputStreamstream, intformat) {
218 if (streamisnull) SWT.error(SWT.ERROR_NULL_ARGUMENT);
219 FileFormat.save(stream, format, this);
220 }
221 222 /**
223 * Saves the image data in this ImageLoader to a file with the specified name.
224 * The format parameter can have one of the following values:
225 * <dl>
226 * <dt><code>IMAGE_BMP</code></dt>
227 * <dd>Windows BMP file format, no compression</dd>
228 * <dt><code>IMAGE_BMP_RLE</code></dt>
229 * <dd>Windows BMP file format, RLE compression if appropriate</dd>
230 * <dt><code>IMAGE_GIF</code></dt>
231 * <dd>GIF file format</dd>
232 * <dt><code>IMAGE_ICO</code></dt>
233 * <dd>Windows ICO file format</dd>
234 * <dt><code>IMAGE_JPEG</code></dt>
235 * <dd>JPEG file format</dd>
236 * <dt><code>IMAGE_PNG</code></dt>
237 * <dd>PNG file format</dd>
238 * </dl>
239 *
240 * @param filename the name of the file to write the images to
241 * @param format the format to write the images in
242 *
243 * @exception IllegalArgumentException <ul>
244 * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
245 * </ul>
246 * @exception SWTException <ul>
247 * <li>ERROR_IO - if an IO error occurs while writing to the file</li>
248 * <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
249 * <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
250 * </ul>
251 */252 publicvoidsave(Stringfilename, intformat) {
253 if (filenameisnull) SWT.error(SWT.ERROR_NULL_ARGUMENT);
254 OutputStreamstream = null;
255 try {
256 stream = Compatibility.newFileOutputStream(filename);
257 } catch (IOExceptione) {
258 SWT.error(SWT.ERROR_IO, e);
259 }
260 save(stream, format);
261 try {
262 stream.close();
263 } catch (IOExceptione) {
264 }
265 }
266 267 /**
268 * Adds the listener to the collection of listeners who will be
269 * notified when image data is either partially or completely loaded.
270 * <p>
271 * An ImageLoaderListener should be added before invoking
272 * one of the receiver's load methods. The listener's
273 * <code>imageDataLoaded</code> method is called when image
274 * data has been partially loaded, as is supported by interlaced
275 * GIF/PNG or progressive JPEG images.
276 *
277 * @param listener the listener which should be notified
278 *
279 * @exception IllegalArgumentException <ul>
280 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
281 * </ul>
282 *
283 * @see ImageLoaderListener
284 * @see ImageLoaderEvent
285 */286 publicvoidaddImageLoaderListener(ImageLoaderListenerlistener) {
287 if (listenerisnull) SWT.error (SWT.ERROR_NULL_ARGUMENT);
288 imageLoaderListeners.addElement(cast(Object)listener);
289 }
290 291 /**
292 * Removes the listener from the collection of listeners who will be
293 * notified when image data is either partially or completely loaded.
294 *
295 * @param listener the listener which should no longer be notified
296 *
297 * @exception IllegalArgumentException <ul>
298 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
299 * </ul>
300 *
301 * @see #addImageLoaderListener(ImageLoaderListener)
302 */303 publicvoidremoveImageLoaderListener(ImageLoaderListenerlistener) {
304 if (listenerisnull) SWT.error (SWT.ERROR_NULL_ARGUMENT);
305 if (imageLoaderListenersisnull ) return;
306 imageLoaderListeners.removeElement( cast(Object)listener );
307 }
308 309 /**
310 * Returns <code>true</code> if the receiver has image loader
311 * listeners, and <code>false</code> otherwise.
312 *
313 * @return <code>true</code> if there are <code>ImageLoaderListener</code>s, and <code>false</code> otherwise
314 *
315 * @see #addImageLoaderListener(ImageLoaderListener)
316 * @see #removeImageLoaderListener(ImageLoaderListener)
317 */318 publicboolhasListeners() {
319 if( imageLoaderListenersisnull ) returnfalse;
320 returnimageLoaderListeners.size() > 0;
321 }
322 323 /**
324 * Notifies all image loader listeners that an image loader event
325 * has occurred. Pass the specified event object to each listener.
326 *
327 * @param event the <code>ImageLoaderEvent</code> to send to each <code>ImageLoaderListener</code>
328 */329 publicvoidnotifyListeners(ImageLoaderEventevent) {
330 if (!hasListeners()) return;
331 autosize = imageLoaderListeners.size();
332 for (inti = 0; i < size; i++) {
333 ImageLoaderListenerlistener = cast(ImageLoaderListener) imageLoaderListeners.elementAt(i);
334 listener.imageDataLoaded(event);
335 }
336 }
337 338 }