summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java')
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java107
1 files changed, 103 insertions, 4 deletions
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
index 4e6181f0e58..cd047f26715 100644
--- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
@@ -103,8 +103,15 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
native void pumpBytes (byte[] bytes, int len) throws IOException;
native void pumpDone () throws IOException;
native void finish (boolean needsClose);
- static native void streamImage(int[] bytes, String format, int width, int height, boolean hasAlpha, DataOutput sink);
-
+
+ /**
+ * Converts given image to bytes.
+ * Will call the GdkPixbufWriter for each chunk.
+ */
+ static native void streamImage(int[] bytes, String format,
+ int width, int height,
+ boolean hasAlpha, GdkPixbufWriter writer);
+
// gdk-pixbuf provids data in RGBA format
static final ColorModel cm = new DirectColorModel (32, 0xff000000,
0x00ff0000,
@@ -461,7 +468,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
}
private static class GdkPixbufWriter
- extends ImageWriter
+ extends ImageWriter implements Runnable
{
String ext;
public GdkPixbufWriter(GdkPixbufWriterSpi ownerSpi, Object ext)
@@ -519,14 +526,106 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
model = img.getColorModel();
}
+ Thread workerThread = new Thread(this, "GdkPixbufWriter");
+ workerThread.start();
processImageStarted(1);
synchronized(pixbufLock)
{
streamImage(pixels, this.ext, width, height, model.hasAlpha(),
- (DataOutput) this.getOutput());
+ this);
}
+ synchronized(data)
+ {
+ data.add(DATADONE);
+ data.notifyAll();
+ }
+
+ while (workerThread.isAlive())
+ {
+ try
+ {
+ workerThread.join();
+ }
+ catch (InterruptedException ioe)
+ {
+ // Ignored.
+ }
+ }
+
+ if (exception != null)
+ throw exception;
+
processImageComplete();
}
+
+ /**
+ * Object marking end of data from native streamImage code.
+ */
+ private static final Object DATADONE = new Object();
+
+ /**
+ * Holds the data gotten from the native streamImage code.
+ * A worker thread will pull data out.
+ * Needs to be synchronized for access.
+ * The special object DATADONE is added when all data has been delivered.
+ */
+ private ArrayList data = new ArrayList();
+
+ /**
+ * Holds any IOException thrown by the run method that needs
+ * to be rethrown by the write method.
+ */
+ private IOException exception;
+
+ /** Callback for streamImage native code. **/
+ private void write(byte[] bs)
+ {
+ synchronized(data)
+ {
+ data.add(bs);
+ data.notifyAll();
+ }
+ }
+
+ public void run()
+ {
+ boolean done = false;
+ while (!done)
+ {
+ synchronized(data)
+ {
+ while (data.isEmpty())
+ {
+ try
+ {
+ data.wait();
+ }
+ catch (InterruptedException ie)
+ {
+ /* ignore */
+ }
+ }
+
+ Object o = data.remove(0);
+ if (o == DATADONE)
+ done = true;
+ else
+ {
+ DataOutput out = (DataOutput) getOutput();
+ try
+ {
+ out.write((byte[]) o);
+ }
+ catch (IOException ioe)
+ {
+ // We are only interested in the first exception.
+ if (exception == null)
+ exception = ioe;
+ }
+ }
+ }
+ }
+ }
}
private static class GdkPixbufReader