comparison dwt/graphics/ImageLoader.d @ 22:5f2e72114476

Image in work, this revision does not compile
author Frank Benoit <benoit@tionex.de>
date Sat, 26 Jan 2008 19:05:32 +0100
parents
children ab60f3309436
comparison
equal deleted inserted replaced
21:d2e87572b721 22:5f2e72114476
1 /*******************************************************************************
2 * Copyright (c) 2000, 2006 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 module dwt.graphics.ImageLoader;
14
15
16 public import dwt.graphics.ImageLoaderListener;
17 public import dwt.graphics.ImageLoaderEvent;
18 public import dwt.graphics.ImageData;
19
20 import dwt.DWT;
21 import dwt.internal.Compatibility;
22 import dwt.internal.image.FileFormat;
23
24 import tango.core.Exception;
25 import tango.core.Array;
26
27
28 /**
29 * Instances of this class are used to load images from,
30 * and save images to, a file or stream.
31 * <p>
32 * Currently supported image formats are:
33 * </p><ul>
34 * <li>BMP (Windows or OS/2 Bitmap)</li>
35 * <li>ICO (Windows Icon)</li>
36 * <li>JPEG</li>
37 * <li>GIF</li>
38 * <li>PNG</li>
39 * <li>TIFF</li>
40 * </ul>
41 * <code>ImageLoaders</code> can be used to:
42 * <ul>
43 * <li>load/save single images in all formats</li>
44 * <li>load/save multiple images (GIF/ICO/TIFF)</li>
45 * <li>load/save animated GIF images</li>
46 * <li>load interlaced GIF/PNG images</li>
47 * <li>load progressive JPEG images</li>
48 * </ul>
49 */
50
51 public class ImageLoader {
52
53 /**
54 * the array of ImageData objects in this ImageLoader.
55 * This array is read in when the load method is called,
56 * and it is written out when the save method is called
57 */
58 public ImageData[] data;
59
60 /**
61 * the width of the logical screen on which the images
62 * reside, in pixels (this corresponds to the GIF89a
63 * Logical Screen Width value)
64 */
65 public int logicalScreenWidth;
66
67 /**
68 * the height of the logical screen on which the images
69 * reside, in pixels (this corresponds to the GIF89a
70 * Logical Screen Height value)
71 */
72 public int logicalScreenHeight;
73
74 /**
75 * the background pixel for the logical screen (this
76 * corresponds to the GIF89a Background Color Index value).
77 * The default is -1 which means 'unspecified background'
78 *
79 */
80 public int backgroundPixel;
81
82 /**
83 * the number of times to repeat the display of a sequence
84 * of animated images (this corresponds to the commonly-used
85 * GIF application extension for "NETSCAPE 2.0 01").
86 * The default is 1. A value of 0 means 'display repeatedly'
87 */
88 public int repeatCount;
89
90 /*
91 * the set of ImageLoader event listeners, created on demand
92 */
93 ImageLoaderListener[] imageLoaderListeners;
94
95 /**
96 * Construct a new empty ImageLoader.
97 */
98 public this() {
99 reset();
100 }
101
102 /**
103 * Resets the fields of the ImageLoader, except for the
104 * <code>imageLoaderListeners</code> field.
105 */
106 void reset() {
107 data = null;
108 logicalScreenWidth = 0;
109 logicalScreenHeight = 0;
110 backgroundPixel = -1;
111 repeatCount = 1;
112 }
113
114 /**
115 * Loads an array of <code>ImageData</code> objects from the
116 * specified input stream. Throws an error if either an error
117 * occurs while loading the images, or if the images are not
118 * of a supported type. Returns the loaded image data array.
119 *
120 * @param stream the input stream to load the images from
121 * @return an array of <code>ImageData</code> objects loaded from the specified input stream
122 *
123 * @exception IllegalArgumentException <ul>
124 * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
125 * </ul>
126 * @exception DWTException <ul>
127 * <li>ERROR_IO - if an IO error occurs while reading from the stream</li>
128 * <li>ERROR_INVALID_IMAGE - if the image stream contains invalid data</li>
129 * <li>ERROR_UNSUPPORTED_FORMAT - if the image stream contains an unrecognized format</li>
130 * </ul>
131 */
132 public ImageData[] load(InputStream stream) {
133 if (stream is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
134 reset();
135 data = FileFormat.load(stream, this);
136 return data;
137 }
138
139 /**
140 * Loads an array of <code>ImageData</code> objects from the
141 * file with the specified name. Throws an error if either
142 * an error occurs while loading the images, or if the images are
143 * not of a supported type. Returns the loaded image data array.
144 *
145 * @param filename the name of the file to load the images from
146 * @return an array of <code>ImageData</code> objects loaded from the specified file
147 *
148 * @exception IllegalArgumentException <ul>
149 * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
150 * </ul>
151 * @exception DWTException <ul>
152 * <li>ERROR_IO - if an IO error occurs while reading from the file</li>
153 * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
154 * <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
155 * </ul>
156 */
157 public ImageData[] load(char[] filename) {
158 if (filename is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
159 InputStream stream = null;
160 void close(){
161 try {
162 if( stream !is null ) stream.close();
163 } catch (IOException e) {
164 // Ignore error
165 }
166 }
167 try {
168 stream = Compatibility.newFileInputStream(filename);
169 scope(exit) close();
170
171 return load(stream);
172 } catch (IOException e) {
173 DWT.error(DWT.ERROR_IO, e);
174 }
175 return null;
176 }
177
178 /**
179 * Saves the image data in this ImageLoader to the specified stream.
180 * The format parameter can have one of the following values:
181 * <dl>
182 * <dt><code>IMAGE_BMP</code></dt>
183 * <dd>Windows BMP file format, no compression</dd>
184 * <dt><code>IMAGE_BMP_RLE</code></dt>
185 * <dd>Windows BMP file format, RLE compression if appropriate</dd>
186 * <dt><code>IMAGE_GIF</code></dt>
187 * <dd>GIF file format</dd>
188 * <dt><code>IMAGE_ICO</code></dt>
189 * <dd>Windows ICO file format</dd>
190 * <dt><code>IMAGE_JPEG</code></dt>
191 * <dd>JPEG file format</dd>
192 * <dt><code>IMAGE_PNG</code></dt>
193 * <dd>PNG file format</dd>
194 * </dl>
195 *
196 * @param stream the output stream to write the images to
197 * @param format the format to write the images in
198 *
199 * @exception IllegalArgumentException <ul>
200 * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
201 * </ul>
202 * @exception DWTException <ul>
203 * <li>ERROR_IO - if an IO error occurs while writing to the stream</li>
204 * <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
205 * <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
206 * </ul>
207 */
208 public void save(OutputStream stream, int format) {
209 if (stream is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
210 FileFormat.save(stream, format, this);
211 }
212
213 /**
214 * Saves the image data in this ImageLoader to a file with the specified name.
215 * The format parameter can have one of the following values:
216 * <dl>
217 * <dt><code>IMAGE_BMP</code></dt>
218 * <dd>Windows BMP file format, no compression</dd>
219 * <dt><code>IMAGE_BMP_RLE</code></dt>
220 * <dd>Windows BMP file format, RLE compression if appropriate</dd>
221 * <dt><code>IMAGE_GIF</code></dt>
222 * <dd>GIF file format</dd>
223 * <dt><code>IMAGE_ICO</code></dt>
224 * <dd>Windows ICO file format</dd>
225 * <dt><code>IMAGE_JPEG</code></dt>
226 * <dd>JPEG file format</dd>
227 * <dt><code>IMAGE_PNG</code></dt>
228 * <dd>PNG file format</dd>
229 * </dl>
230 *
231 * @param filename the name of the file to write the images to
232 * @param format the format to write the images in
233 *
234 * @exception IllegalArgumentException <ul>
235 * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
236 * </ul>
237 * @exception DWTException <ul>
238 * <li>ERROR_IO - if an IO error occurs while writing to the file</li>
239 * <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
240 * <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
241 * </ul>
242 */
243 public void save(char[] filename, int format) {
244 if (filename is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
245 OutputStream stream = null;
246 try {
247 stream = Compatibility.newFileOutputStream(filename);
248 } catch (IOException e) {
249 DWT.error(DWT.ERROR_IO, e);
250 }
251 save(stream, format);
252 try {
253 stream.close();
254 } catch (IOException e) {
255 }
256 }
257
258 /**
259 * Adds the listener to the collection of listeners who will be
260 * notified when image data is either partially or completely loaded.
261 * <p>
262 * An ImageLoaderListener should be added before invoking
263 * one of the receiver's load methods. The listener's
264 * <code>imageDataLoaded</code> method is called when image
265 * data has been partially loaded, as is supported by interlaced
266 * GIF/PNG or progressive JPEG images.
267 *
268 * @param listener the listener which should be notified
269 *
270 * @exception IllegalArgumentException <ul>
271 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
272 * </ul>
273 *
274 * @see ImageLoaderListener
275 * @see ImageLoaderEvent
276 */
277 public void addImageLoaderListener(ImageLoaderListener listener) {
278 if (listener is null) DWT.error (DWT.ERROR_NULL_ARGUMENT);
279 imageLoaderListeners ~= listener;
280 }
281
282 /**
283 * Removes the listener from the collection of listeners who will be
284 * notified when image data is either partially or completely loaded.
285 *
286 * @param listener the listener which should no longer be notified
287 *
288 * @exception IllegalArgumentException <ul>
289 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
290 * </ul>
291 *
292 * @see #addImageLoaderListener(ImageLoaderListener)
293 */
294 public void removeImageLoaderListener(ImageLoaderListener listener) {
295 if (listener is null) DWT.error (DWT.ERROR_NULL_ARGUMENT);
296 if (imageLoaderListeners.length == 0 ) return;
297 tango.core.Array.remove( imageLoaderListeners, listener, delegate bool(ImageLoaderListener l1, ImageLoaderListener l2 ){ return l1 is l2; });
298 }
299
300 /**
301 * Returns <code>true</code> if the receiver has image loader
302 * listeners, and <code>false</code> otherwise.
303 *
304 * @return <code>true</code> if there are <code>ImageLoaderListener</code>s, and <code>false</code> otherwise
305 *
306 * @see #addImageLoaderListener(ImageLoaderListener)
307 * @see #removeImageLoaderListener(ImageLoaderListener)
308 */
309 public bool hasListeners() {
310 return imageLoaderListeners.length > 0;
311 }
312
313 /**
314 * Notifies all image loader listeners that an image loader event
315 * has occurred. Pass the specified event object to each listener.
316 *
317 * @param event the <code>ImageLoaderEvent</code> to send to each <code>ImageLoaderListener</code>
318 */
319 public void notifyListeners(ImageLoaderEvent event) {
320 if (!hasListeners()) return;
321 foreach( listener; imageLoaderListeners ){
322 listener.imageDataLoaded(event);
323 }
324 }
325
326 }