001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.graphics;
011:
012: import java.io.*;
013: import java.util.Vector;
014: import org.eclipse.swt.*;
015: import org.eclipse.swt.internal.Compatibility;
016: import org.eclipse.swt.internal.image.*;
017:
018: /**
019: * Instances of this class are used to load images from,
020: * and save images to, a file or stream.
021: * <p>
022: * Currently supported image formats are:
023: * </p><ul>
024: * <li>BMP (Windows or OS/2 Bitmap)</li>
025: * <li>ICO (Windows Icon)</li>
026: * <li>JPEG</li>
027: * <li>GIF</li>
028: * <li>PNG</li>
029: * <li>TIFF</li>
030: * </ul>
031: * <code>ImageLoaders</code> can be used to:
032: * <ul>
033: * <li>load/save single images in all formats</li>
034: * <li>load/save multiple images (GIF/ICO/TIFF)</li>
035: * <li>load/save animated GIF images</li>
036: * <li>load interlaced GIF/PNG images</li>
037: * <li>load progressive JPEG images</li>
038: * </ul>
039: */
040:
041: public class ImageLoader {
042:
043: /**
044: * the array of ImageData objects in this ImageLoader.
045: * This array is read in when the load method is called,
046: * and it is written out when the save method is called
047: */
048: public ImageData[] data;
049:
050: /**
051: * the width of the logical screen on which the images
052: * reside, in pixels (this corresponds to the GIF89a
053: * Logical Screen Width value)
054: */
055: public int logicalScreenWidth;
056:
057: /**
058: * the height of the logical screen on which the images
059: * reside, in pixels (this corresponds to the GIF89a
060: * Logical Screen Height value)
061: */
062: public int logicalScreenHeight;
063:
064: /**
065: * the background pixel for the logical screen (this
066: * corresponds to the GIF89a Background Color Index value).
067: * The default is -1 which means 'unspecified background'
068: *
069: */
070: public int backgroundPixel;
071:
072: /**
073: * the number of times to repeat the display of a sequence
074: * of animated images (this corresponds to the commonly-used
075: * GIF application extension for "NETSCAPE 2.0 01").
076: * The default is 1. A value of 0 means 'display repeatedly'
077: */
078: public int repeatCount;
079:
080: /*
081: * the set of ImageLoader event listeners, created on demand
082: */
083: Vector imageLoaderListeners;
084:
085: /**
086: * Construct a new empty ImageLoader.
087: */
088: public ImageLoader() {
089: reset();
090: }
091:
092: /**
093: * Resets the fields of the ImageLoader, except for the
094: * <code>imageLoaderListeners</code> field.
095: */
096: void reset() {
097: data = null;
098: logicalScreenWidth = 0;
099: logicalScreenHeight = 0;
100: backgroundPixel = -1;
101: repeatCount = 1;
102: }
103:
104: /**
105: * Loads an array of <code>ImageData</code> objects from the
106: * specified input stream. Throws an error if either an error
107: * occurs while loading the images, or if the images are not
108: * of a supported type. Returns the loaded image data array.
109: *
110: * @param stream the input stream to load the images from
111: * @return an array of <code>ImageData</code> objects loaded from the specified input stream
112: *
113: * @exception IllegalArgumentException <ul>
114: * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
115: * </ul>
116: * @exception SWTException <ul>
117: * <li>ERROR_IO - if an IO error occurs while reading from the stream</li>
118: * <li>ERROR_INVALID_IMAGE - if the image stream contains invalid data</li>
119: * <li>ERROR_UNSUPPORTED_FORMAT - if the image stream contains an unrecognized format</li>
120: * </ul>
121: */
122: public ImageData[] load(InputStream stream) {
123: if (stream == null)
124: SWT.error(SWT.ERROR_NULL_ARGUMENT);
125: reset();
126: data = FileFormat.load(stream, this );
127: return data;
128: }
129:
130: /**
131: * Loads an array of <code>ImageData</code> objects from the
132: * file with the specified name. Throws an error if either
133: * an error occurs while loading the images, or if the images are
134: * not of a supported type. Returns the loaded image data array.
135: *
136: * @param filename the name of the file to load the images from
137: * @return an array of <code>ImageData</code> objects loaded from the specified file
138: *
139: * @exception IllegalArgumentException <ul>
140: * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
141: * </ul>
142: * @exception SWTException <ul>
143: * <li>ERROR_IO - if an IO error occurs while reading from the file</li>
144: * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
145: * <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
146: * </ul>
147: */
148: public ImageData[] load(String filename) {
149: if (filename == null)
150: SWT.error(SWT.ERROR_NULL_ARGUMENT);
151: InputStream stream = null;
152: try {
153: stream = Compatibility.newFileInputStream(filename);
154: return load(stream);
155: } catch (IOException e) {
156: SWT.error(SWT.ERROR_IO, e);
157: } finally {
158: try {
159: if (stream != null)
160: stream.close();
161: } catch (IOException e) {
162: // Ignore error
163: }
164: }
165: return null;
166: }
167:
168: /**
169: * Saves the image data in this ImageLoader to the specified stream.
170: * The format parameter can have one of the following values:
171: * <dl>
172: * <dt><code>IMAGE_BMP</code></dt>
173: * <dd>Windows BMP file format, no compression</dd>
174: * <dt><code>IMAGE_BMP_RLE</code></dt>
175: * <dd>Windows BMP file format, RLE compression if appropriate</dd>
176: * <dt><code>IMAGE_GIF</code></dt>
177: * <dd>GIF file format</dd>
178: * <dt><code>IMAGE_ICO</code></dt>
179: * <dd>Windows ICO file format</dd>
180: * <dt><code>IMAGE_JPEG</code></dt>
181: * <dd>JPEG file format</dd>
182: * <dt><code>IMAGE_PNG</code></dt>
183: * <dd>PNG file format</dd>
184: * </dl>
185: *
186: * @param stream the output stream to write the images to
187: * @param format the format to write the images in
188: *
189: * @exception IllegalArgumentException <ul>
190: * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
191: * </ul>
192: * @exception SWTException <ul>
193: * <li>ERROR_IO - if an IO error occurs while writing to the stream</li>
194: * <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
195: * <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
196: * </ul>
197: */
198: public void save(OutputStream stream, int format) {
199: if (stream == null)
200: SWT.error(SWT.ERROR_NULL_ARGUMENT);
201: FileFormat.save(stream, format, this );
202: }
203:
204: /**
205: * Saves the image data in this ImageLoader to a file with the specified name.
206: * The format parameter can have one of the following values:
207: * <dl>
208: * <dt><code>IMAGE_BMP</code></dt>
209: * <dd>Windows BMP file format, no compression</dd>
210: * <dt><code>IMAGE_BMP_RLE</code></dt>
211: * <dd>Windows BMP file format, RLE compression if appropriate</dd>
212: * <dt><code>IMAGE_GIF</code></dt>
213: * <dd>GIF file format</dd>
214: * <dt><code>IMAGE_ICO</code></dt>
215: * <dd>Windows ICO file format</dd>
216: * <dt><code>IMAGE_JPEG</code></dt>
217: * <dd>JPEG file format</dd>
218: * <dt><code>IMAGE_PNG</code></dt>
219: * <dd>PNG file format</dd>
220: * </dl>
221: *
222: * @param filename the name of the file to write the images to
223: * @param format the format to write the images in
224: *
225: * @exception IllegalArgumentException <ul>
226: * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
227: * </ul>
228: * @exception SWTException <ul>
229: * <li>ERROR_IO - if an IO error occurs while writing to the file</li>
230: * <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
231: * <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
232: * </ul>
233: */
234: public void save(String filename, int format) {
235: if (filename == null)
236: SWT.error(SWT.ERROR_NULL_ARGUMENT);
237: OutputStream stream = null;
238: try {
239: stream = Compatibility.newFileOutputStream(filename);
240: } catch (IOException e) {
241: SWT.error(SWT.ERROR_IO, e);
242: }
243: save(stream, format);
244: try {
245: stream.close();
246: } catch (IOException e) {
247: }
248: }
249:
250: /**
251: * Adds the listener to the collection of listeners who will be
252: * notified when image data is either partially or completely loaded.
253: * <p>
254: * An ImageLoaderListener should be added before invoking
255: * one of the receiver's load methods. The listener's
256: * <code>imageDataLoaded</code> method is called when image
257: * data has been partially loaded, as is supported by interlaced
258: * GIF/PNG or progressive JPEG images.
259: *
260: * @param listener the listener which should be notified
261: *
262: * @exception IllegalArgumentException <ul>
263: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
264: * </ul>
265: *
266: * @see ImageLoaderListener
267: * @see ImageLoaderEvent
268: */
269: public void addImageLoaderListener(ImageLoaderListener listener) {
270: if (listener == null)
271: SWT.error(SWT.ERROR_NULL_ARGUMENT);
272: if (imageLoaderListeners == null) {
273: imageLoaderListeners = new Vector();
274: }
275: imageLoaderListeners.addElement(listener);
276: }
277:
278: /**
279: * Removes the listener from the collection of listeners who will be
280: * notified when image data is either partially or completely loaded.
281: *
282: * @param listener the listener which should no longer be notified
283: *
284: * @exception IllegalArgumentException <ul>
285: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
286: * </ul>
287: *
288: * @see #addImageLoaderListener(ImageLoaderListener)
289: */
290: public void removeImageLoaderListener(ImageLoaderListener listener) {
291: if (listener == null)
292: SWT.error(SWT.ERROR_NULL_ARGUMENT);
293: if (imageLoaderListeners == null)
294: return;
295: imageLoaderListeners.removeElement(listener);
296: }
297:
298: /**
299: * Returns <code>true</code> if the receiver has image loader
300: * listeners, and <code>false</code> otherwise.
301: *
302: * @return <code>true</code> if there are <code>ImageLoaderListener</code>s, and <code>false</code> otherwise
303: *
304: * @see #addImageLoaderListener(ImageLoaderListener)
305: * @see #removeImageLoaderListener(ImageLoaderListener)
306: */
307: public boolean hasListeners() {
308: return imageLoaderListeners != null
309: && imageLoaderListeners.size() > 0;
310: }
311:
312: /**
313: * Notifies all image loader listeners that an image loader event
314: * has occurred. Pass the specified event object to each listener.
315: *
316: * @param event the <code>ImageLoaderEvent</code> to send to each <code>ImageLoaderListener</code>
317: */
318: public void notifyListeners(ImageLoaderEvent event) {
319: if (!hasListeners())
320: return;
321: int size = imageLoaderListeners.size();
322: for (int i = 0; i < size; i++) {
323: ImageLoaderListener listener = (ImageLoaderListener) imageLoaderListeners
324: .elementAt(i);
325: listener.imageDataLoaded(event);
326: }
327: }
328:
329: }
|