1 // Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
5 import org.ibex.util.*;
6 import org.ibex.translators.*;
9 * The in-memory representation of a PNG or GIF image. It is
10 * read-only. It is usually passed to PixelBuffer.drawPicture()
12 * Implementations of the Platform class should return objects
13 * supporting this interface from the createPicture() method. These
14 * implementations may choose to implement caching strategies (for
15 * example, using a Pixmap on X11).
17 public class Picture {
19 private final static boolean NANOGOAT_KEEP_ALL_METHODS = true;
21 public Picture() { this.stream = null; }
22 public Picture(JS r) { this.stream = r; }
23 private static Cache cache = new Cache(100); ///< Picture, keyed by the Stream that loaded them
25 public JS stream = null; ///< the stream we were loaded from
26 public int width = -1; ///< the width of the image
27 public int height = -1; ///< the height of the image
28 public int[] data = null; ///< argb samples
29 public boolean isLoaded = false; ///< true iff the image is fully loaded
31 /** invoked when an image is fully loaded; subclasses can use this to initialize platform-specific constructs */
32 protected void loaded() { isLoaded = true; }
34 /** turns a stream into a Picture.Source and passes it to the callback */
35 public static Picture load(final JS stream, final Scheduler.Task callback) {
36 Picture ret = (Picture)cache.get(stream);
37 if (ret == null) cache.put(stream, ret = Platform.createPicture(stream));
38 final Picture p = ret;
39 if (!ret.isLoaded && callback != null) {
40 final Ibex.Blessing b = Ibex.Blessing.getBlessing(stream);
41 new java.lang.Thread() { public void run() {
42 InputStream in = null;
44 in = b == null ? Stream.getInputStream(stream) : b.getImage();
45 } catch (IOException e) { Log.error(Picture.class, e);
46 } catch (JSExn e) { Log.error(Picture.class, e);
48 if (in == null) { Log.warn(Picture.class, "couldn't load image for stream " + stream); return; }
50 PushbackInputStream pbis = new PushbackInputStream(in);
51 int firstByte = pbis.read();
52 if (firstByte == -1) throw new JSExn("empty stream reading image");
53 pbis.unread(firstByte);
54 if ((firstByte & 0xff) == 'G') GIF.load(pbis, p);
55 else if ((firstByte & 0xff) == 137) PNG.load(pbis, p);
56 else if ((firstByte & 0xff) == 0xff) Platform.decodeJPEG(pbis, p);
57 else throw new JSExn("couldn't figure out image type from first byte");
59 Scheduler.add(callback);
60 } catch (Exception e) {
61 Log.info(this, "exception while loading image");