X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FPicture.java;h=44565d571a0b76872f8800143a691326e22a6cec;hb=16c24a73c1c1b2955db0bbbaf5a940215329bca1;hp=a4cc602a6b4e4e017ccb6d7b66e08a6f9fea4b0e;hpb=6a96430e10e27fc1de5754cb5add705f929dd109;p=org.ibex.core.git diff --git a/src/org/xwt/Picture.java b/src/org/xwt/Picture.java index a4cc602..44565d5 100644 --- a/src/org/xwt/Picture.java +++ b/src/org/xwt/Picture.java @@ -1,4 +1,4 @@ -// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] +// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; import java.io.*; import org.xwt.js.*; @@ -6,55 +6,61 @@ import org.xwt.util.*; import org.xwt.translators.*; /** - *

* The in-memory representation of a PNG or GIF image. It is * read-only. It is usually passed to PixelBuffer.drawPicture() - *

* - *

* Implementations of the Platform class should return objects * supporting this interface from the createPicture() method. These * implementations may choose to implement caching strategies (for * example, using a Pixmap on X11). - *

*/ -public abstract class Picture { +public class Picture { - /** the resource that created this Picture */ - public Res res = null; + public Picture() { this.stream = null; } + public Picture(JS r) { this.stream = r; } + private static Cache cache = new Cache(100); ///< Picture, keyed by the Stream that loaded them - /** the height of the picture */ - public abstract int getHeight(); - - /** the width of the picture */ - public abstract int getWidth(); + public JS stream = null; ///< the stream we were loaded from + public int width = -1; ///< the width of the image + public int height = -1; ///< the height of the image + public int[] data = null; ///< argb samples + public boolean isLoaded = false; ///< true iff the image is fully loaded - /** Pictures, cache keyed by Res instance */ - private static Cache cache = new Cache(); - private static GIF gif = new GIF(); - - /** turns a resource into a Picture.Source and passes it to the callback */ - public static void fromRes(final Res r, final Callback callback) { - Picture ret = (Picture)cache.get(r); - if (ret != null) { - callback.call(ret); - return; - } + /** invoked when an image is fully loaded; subclasses can use this to initialize platform-specific constructs */ + protected void loaded() { isLoaded = true; } - try { - // FIXME: put self in background - PushbackInputStream pbis = new PushbackInputStream(r.getInputStream()); - int c = pbis.read(); - pbis.unread(c); - if (c == 'G') ret = gif.fromInputStream(pbis, r.getDescriptiveName()); - else if (c == 137) ret = new PNG().fromInputStream(pbis, r.getDescriptiveName()); - else if (c == 0xff) ret = Platform.decodeJPEG(pbis, r.getDescriptiveName()); - else throw new JS.Exn("couldn't figure out image type from first byte"); - cache.put(r, ret); - ret.res = r; - callback.call(ret); - } catch (Exception e) { - Log.log(Picture.class, e); + /** turns a stream into a Picture.Source and passes it to the callback */ + public static Picture load(final JS stream, final Scheduler.Task callback) { + Picture ret = (Picture)cache.get(stream); + if (ret == null) cache.put(stream, ret = Platform.createPicture(stream)); + final Picture p = ret; + if (!ret.isLoaded && callback != null) { + final XWT.Blessing b = XWT.Blessing.getBlessing(stream); + new java.lang.Thread() { public void run() { + InputStream in = null; + try { + in = b == null ? Stream.getInputStream(stream) : b.getImage(); + } catch (IOException e) { Log.error(Picture.class, stream); + } catch (JSExn e) { Log.error(Picture.class, stream); + } + if (in == null) { Log.warn(Picture.class, "couldn't load image for stream " + stream); return; } + try { + PushbackInputStream pbis = new PushbackInputStream(in); + int firstByte = pbis.read(); + if (firstByte == -1) throw new JSExn("empty stream reading image"); + pbis.unread(firstByte); + if ((firstByte & 0xff) == 'G') GIF.load(pbis, p); + else if ((firstByte & 0xff) == 137) PNG.load(pbis, p); + else if ((firstByte & 0xff) == 0xff) Platform.decodeJPEG(pbis, p); + else throw new JSExn("couldn't figure out image type from first byte"); + p.loaded(); + Scheduler.add(callback); + } catch (Exception e) { + Log.info(this, "exception while loading image"); + Log.info(this, e); + } + } }.start(); } + return ret; } }