]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/graphics/ImageLoader.java
bbe5ac8d518a04b8a8c36cc74da6a82bf71bf117
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / graphics / ImageLoader.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2016 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.graphics;
15
16
17 import java.io.*;
18 import java.util.*;
19
20 import org.eclipse.swt.*;
21 import org.eclipse.swt.internal.image.*;
22
23 /**
24  * Instances of this class are used to load images from,
25  * and save images to, a file or stream.
26  * <p>
27  * Currently supported image formats are:
28  * </p><ul>
29  * <li>BMP (Windows or OS/2 Bitmap)</li>
30  * <li>ICO (Windows Icon)</li>
31  * <li>JPEG</li>
32  * <li>GIF</li>
33  * <li>PNG</li>
34  * <li>TIFF</li>
35  * </ul>
36  * <code>ImageLoaders</code> can be used to:
37  * <ul>
38  * <li>load/save single images in all formats</li>
39  * <li>load/save multiple images (GIF/ICO/TIFF)</li>
40  * <li>load/save animated GIF images</li>
41  * <li>load interlaced GIF/PNG images</li>
42  * <li>load progressive JPEG images</li>
43  * </ul>
44  *
45  * <p>
46  * NOTE: <code>ImageLoader</code> is implemented in Java on some platforms, which has
47  * certain performance implications. Performance and memory sensitive applications may
48  * benefit from using one of the constructors provided by <code>Image</code>, as these
49  * are implemented natively.</p>
50  *
51  * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ImageAnalyzer</a>
52  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
53  */
54 public class ImageLoader {
55
56         /**
57          * the array of ImageData objects in this ImageLoader.
58          * This array is read in when the load method is called,
59          * and it is written out when the save method is called
60          */
61         public ImageData[] data;
62
63         /**
64          * the width of the logical screen on which the images
65          * reside, in pixels (this corresponds to the GIF89a
66          * Logical Screen Width value)
67          */
68         public int logicalScreenWidth;
69
70         /**
71          * the height of the logical screen on which the images
72          * reside, in pixels (this corresponds to the GIF89a
73          * Logical Screen Height value)
74          */
75         public int logicalScreenHeight;
76
77         /**
78          * the background pixel for the logical screen (this
79          * corresponds to the GIF89a Background Color Index value).
80          * The default is -1 which means 'unspecified background'
81          *
82          */
83         public int backgroundPixel;
84
85         /**
86          * the number of times to repeat the display of a sequence
87          * of animated images (this corresponds to the commonly-used
88          * GIF application extension for "NETSCAPE 2.0 01").
89          * The default is 1. A value of 0 means 'display repeatedly'
90          */
91         public int repeatCount;
92
93         /**
94          * This is the compression used when saving jpeg and png files.
95          * <p>
96          * When saving jpeg files, the value is from 1 to 100,
97          * where 1 is very high compression but low quality, and 100 is
98          * no compression and high quality; default is 75.
99          * </p><p>
100          * When saving png files, the value is from 0 to 3, but they do not impact the quality
101          * because PNG is lossless compression. 0 is uncompressed, 1 is low compression and fast,
102          * 2 is default compression, and 3 is high compression but slow.
103          * </p>
104          *
105          * @since 3.8
106          */
107         public int compression;
108
109         /*
110          * the set of ImageLoader event listeners, created on demand
111          */
112         List<ImageLoaderListener> imageLoaderListeners;
113
114 /**
115  * Construct a new empty ImageLoader.
116  */
117 public ImageLoader() {
118         reset();
119 }
120
121 /**
122  * Resets the fields of the ImageLoader, except for the
123  * <code>imageLoaderListeners</code> field.
124  */
125 void reset() {
126         data = null;
127         logicalScreenWidth = 0;
128         logicalScreenHeight = 0;
129         backgroundPixel = -1;
130         repeatCount = 1;
131         compression = -1;
132 }
133
134 /**
135  * Loads an array of <code>ImageData</code> objects from the
136  * specified input stream. Throws an error if either an error
137  * occurs while loading the images, or if the images are not
138  * of a supported type. Returns the loaded image data array.
139  *
140  * @param stream the input stream to load the images from
141  * @return an array of <code>ImageData</code> objects loaded from the specified input stream
142  *
143  * @exception IllegalArgumentException <ul>
144  *    <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
145  * </ul>
146  * @exception SWTException <ul>
147  *    <li>ERROR_IO - if an IO error occurs while reading from the stream</li>
148  *    <li>ERROR_INVALID_IMAGE - if the image stream contains invalid data</li>
149  *    <li>ERROR_UNSUPPORTED_FORMAT - if the image stream contains an unrecognized format</li>
150  * </ul>
151  */
152 public ImageData[] load(InputStream stream) {
153         if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
154         reset();
155         data = FileFormat.load(stream, this);
156         return data;
157 }
158
159 /**
160  * Loads an array of <code>ImageData</code> objects from the
161  * file with the specified name. Throws an error if either
162  * an error occurs while loading the images, or if the images are
163  * not of a supported type. Returns the loaded image data array.
164  *
165  * @param filename the name of the file to load the images from
166  * @return an array of <code>ImageData</code> objects loaded from the specified file
167  *
168  * @exception IllegalArgumentException <ul>
169  *    <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
170  * </ul>
171  * @exception SWTException <ul>
172  *    <li>ERROR_IO - if an IO error occurs while reading from the file</li>
173  *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
174  *    <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
175  * </ul>
176  */
177 public ImageData[] load(String filename) {
178         if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
179         InputStream stream = null;
180         try {
181                 stream = new FileInputStream(filename);
182                 return load(stream);
183         } catch (IOException e) {
184                 SWT.error(SWT.ERROR_IO, e);
185         } finally {
186                 try {
187                         if (stream != null) stream.close();
188                 } catch (IOException e) {
189                         // Ignore error
190                 }
191         }
192         return null;
193 }
194
195 /**
196  * Saves the image data in this ImageLoader to the specified stream.
197  * The format parameter can have one of the following values:
198  * <dl>
199  * <dt><code>IMAGE_BMP</code></dt>
200  * <dd>Windows BMP file format, no compression</dd>
201  * <dt><code>IMAGE_BMP_RLE</code></dt>
202  * <dd>Windows BMP file format, RLE compression if appropriate</dd>
203  * <dt><code>IMAGE_GIF</code></dt>
204  * <dd>GIF file format</dd>
205  * <dt><code>IMAGE_ICO</code></dt>
206  * <dd>Windows ICO file format</dd>
207  * <dt><code>IMAGE_JPEG</code></dt>
208  * <dd>JPEG file format</dd>
209  * <dt><code>IMAGE_PNG</code></dt>
210  * <dd>PNG file format</dd>
211  * </dl>
212  *
213  * @param stream the output stream to write the images to
214  * @param format the format to write the images in
215  *
216  * @exception IllegalArgumentException <ul>
217  *    <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
218  * </ul>
219  * @exception SWTException <ul>
220  *    <li>ERROR_IO - if an IO error occurs while writing to the stream</li>
221  *    <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
222  *    <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
223  * </ul>
224  */
225 public void save(OutputStream stream, int format) {
226         if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
227         FileFormat.save(stream, format, this);
228 }
229
230 /**
231  * Saves the image data in this ImageLoader to a file with the specified name.
232  * The format parameter can have one of the following values:
233  * <dl>
234  * <dt><code>IMAGE_BMP</code></dt>
235  * <dd>Windows BMP file format, no compression</dd>
236  * <dt><code>IMAGE_BMP_RLE</code></dt>
237  * <dd>Windows BMP file format, RLE compression if appropriate</dd>
238  * <dt><code>IMAGE_GIF</code></dt>
239  * <dd>GIF file format</dd>
240  * <dt><code>IMAGE_ICO</code></dt>
241  * <dd>Windows ICO file format</dd>
242  * <dt><code>IMAGE_JPEG</code></dt>
243  * <dd>JPEG file format</dd>
244  * <dt><code>IMAGE_PNG</code></dt>
245  * <dd>PNG file format</dd>
246  * </dl>
247  *
248  * @param filename the name of the file to write the images to
249  * @param format the format to write the images in
250  *
251  * @exception IllegalArgumentException <ul>
252  *    <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
253  * </ul>
254  * @exception SWTException <ul>
255  *    <li>ERROR_IO - if an IO error occurs while writing to the file</li>
256  *    <li>ERROR_INVALID_IMAGE - if the image data contains invalid data</li>
257  *    <li>ERROR_UNSUPPORTED_FORMAT - if the image data cannot be saved to the requested format</li>
258  * </ul>
259  */
260 public void save(String filename, int format) {
261         if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
262         OutputStream stream = null;
263         try {
264                 stream = new FileOutputStream(filename);
265         } catch (IOException e) {
266                 SWT.error(SWT.ERROR_IO, e);
267         }
268         save(stream, format);
269         try {
270                 stream.close();
271         } catch (IOException e) {
272         }
273 }
274
275 /**
276  * Adds the listener to the collection of listeners who will be
277  * notified when image data is either partially or completely loaded.
278  * <p>
279  * An ImageLoaderListener should be added before invoking
280  * one of the receiver's load methods. The listener's
281  * <code>imageDataLoaded</code> method is called when image
282  * data has been partially loaded, as is supported by interlaced
283  * GIF/PNG or progressive JPEG images.
284  *
285  * @param listener the listener which should be notified
286  *
287  * @exception IllegalArgumentException <ul>
288  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
289  * </ul>
290  *
291  * @see ImageLoaderListener
292  * @see ImageLoaderEvent
293  */
294 public void addImageLoaderListener(ImageLoaderListener listener) {
295         if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
296         if (imageLoaderListeners == null) {
297                 imageLoaderListeners = new ArrayList<>();
298         }
299         imageLoaderListeners.add(listener);
300 }
301
302 /**
303  * Removes the listener from the collection of listeners who will be
304  * notified when image data is either partially or completely loaded.
305  *
306  * @param listener the listener which should no longer be notified
307  *
308  * @exception IllegalArgumentException <ul>
309  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
310  * </ul>
311  *
312  * @see #addImageLoaderListener(ImageLoaderListener)
313  */
314 public void removeImageLoaderListener(ImageLoaderListener listener) {
315         if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
316         if (imageLoaderListeners == null) return;
317         imageLoaderListeners.remove(listener);
318 }
319
320 /**
321  * Returns <code>true</code> if the receiver has image loader
322  * listeners, and <code>false</code> otherwise.
323  *
324  * @return <code>true</code> if there are <code>ImageLoaderListener</code>s, and <code>false</code> otherwise
325  *
326  * @see #addImageLoaderListener(ImageLoaderListener)
327  * @see #removeImageLoaderListener(ImageLoaderListener)
328  */
329 public boolean hasListeners() {
330         return imageLoaderListeners != null && imageLoaderListeners.size() > 0;
331 }
332
333 /**
334  * Notifies all image loader listeners that an image loader event
335  * has occurred. Pass the specified event object to each listener.
336  *
337  * @param event the <code>ImageLoaderEvent</code> to send to each <code>ImageLoaderListener</code>
338  */
339 public void notifyListeners(ImageLoaderEvent event) {
340         if (!hasListeners()) return;
341         int size = imageLoaderListeners.size();
342         for (int i = 0; i < size; i++) {
343                 ImageLoaderListener listener = imageLoaderListeners.get(i);
344                 listener.imageDataLoaded(event);
345         }
346 }
347
348 }