changeset 12:0c78fa47d476

helper classes
author Frank Benoit <benoit@tionex.de>
date Sun, 06 Jan 2008 19:36:29 +0100
parents 5f725d09c076
children 3d9bbe0a83a0
files dwt/dwthelper/File.d dwt/dwthelper/FileInputStream.d dwt/dwthelper/FileOutputStream.d dwt/dwthelper/InflaterInputStream.d dwt/dwthelper/InputStream.d dwt/dwthelper/OutputStream.d dwt/dwthelper/utils.d dwt/graphics/ImageData.d dwt/graphics/ImageDataLoader.d dwt/graphics/ImageLoader.d dwt/internal/Compatibility.d dwt/internal/gtk/OS.d dwt/internal/image/FileFormat.d dwt/internal/image/LEDataInputStream.d dwt/internal/image/LEDataOutputStream.d todo.txt
diffstat 16 files changed, 1025 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/File.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,202 @@
+/**
+ * Authors: Frank Benoit <keinfarbton@googlemail.com>
+ */
+module dwt.dwthelper.File;
+
+import dwt.dwthelper.utils;
+
+static import tango.io.FileConst;
+static import tango.io.FilePath;
+static import tango.io.FileSystem;
+
+public class File {
+
+    public static char separatorChar;
+    public static char[] separator;
+    public static char pathSeparatorChar;
+    public static char[] pathSeparator;
+
+    private tango.io.FilePath.FilePath mFilePath;
+
+    public this ( char[] pathname ){
+        mFilePath = new tango.io.FilePath.FilePath( pathname );
+    }
+
+    public this ( char[] parent, char[] child ){
+        mFilePath = new tango.io.FilePath.FilePath( tango.io.FilePath.FilePath.join( parent, child ) );
+    }
+
+    public this ( dwt.dwthelper.File.File parent, char[] child ){
+        mFilePath = new tango.io.FilePath.FilePath( tango.io.FilePath.FilePath.join( parent.mFilePath.toString, child ) );
+    }
+
+    public int getPrefixLength(){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+
+    public char[] getName(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public char[] getParent(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public dwt.dwthelper.File.File getParentFile(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public char[] getPath(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public bool isAbsolute(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public char[] getAbsolutePath(){
+        return tango.io.FileSystem.FileSystem.toAbsolute( mFilePath ).toString;
+    }
+
+    public dwt.dwthelper.File.File getAbsoluteFile(){
+        return new File( getAbsolutePath() );
+    }
+
+    public char[] getCanonicalPath(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public dwt.dwthelper.File.File getCanonicalFile(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public bool canRead(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public bool canWrite(){
+        return mFilePath.isWritable;
+    }
+
+    public bool exists(){
+        return mFilePath.exists;
+    }
+
+    public bool isDirectory(){
+        return mFilePath.isFolder;
+    }
+
+    public bool isFile(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public bool isHidden(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public long lastModified(){
+        implMissing( __FILE__, __LINE__ );
+        return 0L;
+    }
+
+    public long length(){
+        implMissing( __FILE__, __LINE__ );
+        return 0L;
+    }
+
+    public bool createNewFile(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public bool delete_KEYWORDESCAPE(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public void deleteOnExit(){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public char[][] list(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public dwt.dwthelper.File.File[] listFiles(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public bool mkdir(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public bool mkdirs(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public bool renameTo( dwt.dwthelper.File.File dest ){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public bool setLastModified( long time ){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public bool setReadOnly(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public static dwt.dwthelper.File.File[] listRoots(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public static dwt.dwthelper.File.File createTempFile( char[] prefix, char[] suffix, dwt.dwthelper.File.File directory ){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public static dwt.dwthelper.File.File createTempFile( char[] prefix, char[] suffix ){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public int compareTo( dwt.dwthelper.File.File pathname ){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+
+    public char[] toString(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+
+    public static void static_this(){
+        separator = tango.io.FileConst.FileConst.PathSeparatorString;
+        separatorChar = tango.io.FileConst.FileConst.PathSeparatorChar;
+        pathSeparator = tango.io.FileConst.FileConst.SystemPathString;
+        pathSeparatorChar = tango.io.FileConst.FileConst.SystemPathChar;
+    }
+
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/FileInputStream.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,77 @@
+/**
+ * Authors: Frank Benoit <keinfarbton@googlemail.com>
+ */
+module dwt.dwthelper.FileInputStream;
+
+import dwt.dwthelper.utils;
+import dwt.dwthelper.File;
+import dwt.dwthelper.InputStream;
+
+import tango.io.FileConduit;
+import tango.io.protocol.Reader;
+import tango.core.Exception;
+import tango.text.convert.Format;
+
+public class FileInputStream : dwt.dwthelper.InputStream.InputStream {
+
+    alias dwt.dwthelper.InputStream.InputStream.read read;
+
+    private FileConduit conduit;
+    private ubyte[] buffer;
+    private int buf_pos;
+    private int buf_size;
+    private const int BUFFER_SIZE = 0x10000;
+    private bool eof;
+
+    public this ( char[] name ){
+        conduit = new FileConduit( name );
+        buffer = new ubyte[]( BUFFER_SIZE );
+    }
+
+    public this ( dwt.dwthelper.File.File file ){
+        implMissing( __FILE__, __LINE__ );
+        conduit = new FileConduit( file.getAbsolutePath(), FileConduit.ReadExisting );
+        buffer = new ubyte[]( BUFFER_SIZE );
+    }
+
+    public override int read(){
+        if( eof ){
+            return -1;
+        }
+        try{
+            if( buf_pos == buf_size ){
+                buf_pos = 0;
+                buf_size = conduit.input.read( buffer );
+            }
+            if( buf_size <= 0 ){
+                eof = true;
+                return -1;
+            }
+            assert( buf_pos < BUFFER_SIZE, Format( "{0} {1}", buf_pos, buf_size ) );
+            assert( buf_size <= BUFFER_SIZE );
+            int res = cast(int) buffer[ buf_pos ];
+            buf_pos++;
+            return res;
+        }
+        catch( IOException e ){
+            eof = true;
+            return -1;
+        }
+    }
+
+    public long skip( long n ){
+        implMissing( __FILE__, __LINE__ );
+        return 0L;
+    }
+
+    public int available(){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+
+    public override void close(){
+        conduit.close();
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/FileOutputStream.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,55 @@
+/**
+ * Authors: Frank Benoit <keinfarbton@googlemail.com>
+ */
+module dwt.dwthelper.FileOutputStream;
+
+public import dwt.dwthelper.File;
+public import dwt.dwthelper.OutputStream;
+
+import dwt.dwthelper.utils;
+
+public class FileOutputStream : dwt.dwthelper.OutputStream.OutputStream {
+
+    alias dwt.dwthelper.OutputStream.OutputStream.write write;
+    alias dwt.dwthelper.OutputStream.OutputStream.close close;
+
+    public this ( char[] name ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public this ( char[] name, bool append ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public this ( dwt.dwthelper.File.File file ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public this ( dwt.dwthelper.File.File file, bool append ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public void write( int b ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public void write( byte[] b ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public void write( byte[] b, int off, int len ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public void close(){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public void finalize(){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/InflaterInputStream.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,68 @@
+/**
+ * Authors: Frank Benoit <keinfarbton@googlemail.com>
+ */
+module dwt.dwthelper.InflaterInputStream;
+
+public import dwt.dwthelper.InputStream;
+import dwt.dwthelper.utils;
+
+public class InflaterInputStream : dwt.dwthelper.InputStream.InputStream {
+
+    alias dwt.dwthelper.InputStream.InputStream.read read;
+    alias dwt.dwthelper.InputStream.InputStream.skip skip;
+    alias dwt.dwthelper.InputStream.InputStream.available available;
+    alias dwt.dwthelper.InputStream.InputStream.close close;
+    alias dwt.dwthelper.InputStream.InputStream.mark mark;
+    alias dwt.dwthelper.InputStream.InputStream.reset reset;
+    alias dwt.dwthelper.InputStream.InputStream.markSupported markSupported;
+
+    protected byte[] buf;
+    protected int len;
+    package bool usesDefaultInflater = false;
+
+    public this ( dwt.dwthelper.InputStream.InputStream istr ){
+    }
+
+    public int read(){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+
+    public int read( byte[] b, int off, int len ){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+
+    public int available(){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+
+    public long skip( long n ){
+        implMissing( __FILE__, __LINE__ );
+        return 0L;
+    }
+
+    public void close(){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public void fill(){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public bool markSupported(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+    public synchronized void mark( int readlimit ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public synchronized void reset(){
+        implMissing( __FILE__, __LINE__ );
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/InputStream.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,61 @@
+/**
+ * Authors: Frank Benoit <keinfarbton@googlemail.com>
+ */
+
+module dwt.dwthelper.InputStream;
+
+import dwt.dwthelper.utils;
+
+public abstract class InputStream {
+
+
+    public this (){
+    }
+
+    public abstract int read();
+
+    public int read( byte[] b ){
+        foreach( uint idx, inout byte val; b ){
+            int c = read();
+            if( c == -1 ){
+                return idx;
+            }
+            b[ idx] = cast(byte)( c & 0xFF );
+        }
+        return b.length;
+    }
+
+    public int read( byte[] b, int off, int len ){
+        return read( b[ off .. off+len ] );
+    }
+
+    public long skip( long n ){
+        implMissing( __FILE__, __LINE__ );
+        return 0L;
+    }
+
+    public int available(){
+        return 0;
+    }
+
+    public void close(){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public synchronized void mark( int readlimit ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public synchronized void reset(){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public bool markSupported(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/OutputStream.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,50 @@
+/**
+ * Authors: Frank Benoit <keinfarbton@googlemail.com>
+ */
+module dwt.dwthelper.OutputStream;
+
+import dwt.dwthelper.utils;
+static import tango.io.model.IConduit;
+
+public abstract class OutputStream {
+
+    private tango.io.model.IConduit.OutputStream ostr;
+
+    public this(){
+    }
+
+    protected this( tango.io.model.IConduit.OutputStream aOutStream) {
+        this.ostr = aOutStream;
+    }
+
+    protected this(OutputStream rhs) {
+        ostr = rhs.ostr;
+    }
+
+    public abstract void write( int b );
+
+    public void write( byte[] b ){
+        ostr.write(b);
+    }
+
+    public void write(char[] c) {
+        ostr.write(c);
+    }
+
+    public void write( byte[] b, int off, int len ){
+        implMissing( __FILE__, __LINE__ );
+    }
+
+    public void flush(){
+        ostr.flush();
+    }
+
+    public void close(){
+        ostr.flush();
+        implMissing( __FILE__, __LINE__ );
+    }
+
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/dwthelper/utils.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,14 @@
+/**
+ * Authors: Frank Benoit <keinfarbton@googlemail.com>
+ */
+module dwt.dwthelper.utils;
+
+import tango.io.Stdout;
+import tango.stdc.stdlib : exit;
+
+void implMissing( char[] file, uint line ){
+    Stderr.formatln( "implementation missing in file {} line {}", file, line );
+    Stderr.formatln( "exiting ..." );
+    exit(1);
+}
+
--- a/dwt/graphics/ImageData.d	Sat Jan 05 15:13:44 2008 -0800
+++ b/dwt/graphics/ImageData.d	Sun Jan 06 19:36:29 2008 +0100
@@ -17,7 +17,7 @@
 import dwt.SWT;
 import dwt.internal.CloneableCompatibility;
 
-import tango.io.model.IConduit;
+public import dwt.dwthelper.InputStream;
 
 // PORTING_TYPE
 class GC{
--- a/dwt/graphics/ImageDataLoader.d	Sat Jan 05 15:13:44 2008 -0800
+++ b/dwt/graphics/ImageDataLoader.d	Sun Jan 06 19:36:29 2008 +0100
@@ -11,9 +11,9 @@
 module dwt.graphics.ImageDataLoader;
 
 public import dwt.graphics.ImageData;
+public import dwt.dwthelper.InputStream;
 
 import dwt.graphics.ImageLoader;
-import tango.io.model.IConduit;
 
 /**
  * Internal class that separates ImageData from ImageLoader
--- a/dwt/graphics/ImageLoader.d	Sat Jan 05 15:13:44 2008 -0800
+++ b/dwt/graphics/ImageLoader.d	Sun Jan 06 19:36:29 2008 +0100
@@ -14,19 +14,16 @@
 public import dwt.graphics.ImageLoaderListener;
 public import dwt.graphics.ImageLoaderEvent;
 public import dwt.graphics.ImageData;
+//public import dwt.dwthelper.InputStream;
+//public import dwt.dwthelper.OutputStream;
 
 import dwt.SWT;
 import dwt.internal.Compatibility;
-//import dwt.internal.image.*;
+import dwt.internal.image.FileFormat;
 
 import tango.core.Exception;
 import tango.core.Array;
-import tango.io.model.IConduit;
 
-class FileFormat{
-    static ImageData[] load( InputStream, ImageLoader ){ return null; }
-    static void save( OutputStream, int,  ImageLoader ){}
-}
 
 /**
  * Instances of this class are used to load images from,
--- a/dwt/internal/Compatibility.d	Sat Jan 05 15:13:44 2008 -0800
+++ b/dwt/internal/Compatibility.d	Sun Jan 06 19:36:29 2008 +0100
@@ -19,12 +19,13 @@
 +/
 
 import dwt.SWT;
+public import dwt.dwthelper.FileInputStream;
+public import dwt.dwthelper.FileOutputStream;
+public import dwt.dwthelper.InflaterInputStream;
 
 import Math = tango.math.Math;
 import Unicode = tango.text.Unicode;
 import tango.sys.Process;
-import tango.io.stream.FileStream;
-import tango.io.compress.ZlibStream;
 
 /**
  * This class is a placeholder for utility methods commonly
@@ -161,7 +162,7 @@
  * @exception IOException
  */
 public static InputStream newFileInputStream(char[] filename) {
-	return new FileInput(filename);
+	return new FileInputStream(filename);
 }
 
 /**
@@ -172,7 +173,7 @@
  * @exception IOException
  */
 public static OutputStream newFileOutputStream(char[] filename) {
-	return new FileOutput(filename);
+	return new FileOutputStream(filename);
 }
 
 /**
@@ -184,8 +185,8 @@
  *
  * @since 3.3
  */
-public static InputStream newInflaterInputStream(InputStream stream) {
-	return new ZlibInput(stream);
+public static InflaterInputStream newInflaterInputStream(InputStream stream) {
+	return new InflaterInputStream(stream);
 }
 
 /**
--- a/dwt/internal/gtk/OS.d	Sat Jan 05 15:13:44 2008 -0800
+++ b/dwt/internal/gtk/OS.d	Sun Jan 06 19:36:29 2008 +0100
@@ -32,6 +32,17 @@
         return cFunc(p);
     }");
 }
+/+
+// alternative template implementation, might be more stable
+template ForwardGtkOsCFunc(char[] name) {
+  alias typeof(mixin(name)) func;
+  alias ParameterTupleOf!(func) Params;
+  alias ReturnTypeOf!(func) Ret;
+  mixin("public static Ret "~name~"( Params p ) {
+    return ."~name~"(p);
+  }");
+}
++/
 
 //import dwt.internal.*;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/internal/image/FileFormat.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.internal.image.FileFormat;
+
+public import dwt.graphics.ImageLoader;
+public import dwt.graphics.ImageData;
+public import dwt.internal.image.LEDataInputStream;
+public import dwt.internal.image.LEDataOutputStream;
+
+import dwt.SWT;
+
+public import dwt.dwthelper.InputStream;
+public import dwt.dwthelper.OutputStream;
+
+/+
+import dwt.internal.image.WinBMPFileFormat;
+import dwt.internal.image.GIFFileFormat;
+import dwt.internal.image.WinICOFileFormat;
+import dwt.internal.image.JPEGFileFormat;
+import dwt.internal.image.PNGFileFormat;
+import dwt.internal.image.TIFFFileFormat;
+import dwt.internal.image.OS2BMPFileFormat;
++/
+
+import tango.core.Exception;
+import tango.core.Tuple;
+
+class Tmp : FileFormat{
+    bool isFileFormat(LEDataInputStream stream){
+        return false;
+    }
+    ImageData[] loadFromByteStream(){
+        return null;
+    }
+    void unloadIntoByteStream(ImageLoader loader){
+    }
+}
+class WinBMPFileFormat : Tmp{
+}
+class GIFFileFormat : Tmp{
+}
+class WinICOFileFormat : Tmp{
+}
+class JPEGFileFormat : Tmp{
+}
+class PNGFileFormat : Tmp{
+}
+class TIFFFileFormat : Tmp{
+}
+class OS2BMPFileFormat : Tmp{
+}
+
+/**
+ * Abstract factory class for loading/unloading images from files or streams
+ * in various image file formats.
+ *
+ */
+public abstract class FileFormat {
+	static const char[] FORMAT_PACKAGE = "dwt.internal.image"; //$NON-NLS-1$
+	static const char[] FORMAT_SUFFIX = "FileFormat"; //$NON-NLS-1$
+	static const char[][] FORMATS = [ "WinBMP"[], "WinBMP", "GIF", "WinICO", "JPEG", "PNG", "TIFF", "OS2BMP" ]; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$//$NON-NLS-5$ //$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$
+    alias Tuple!( WinBMPFileFormat, WinBMPFileFormat, GIFFileFormat, WinICOFileFormat, JPEGFileFormat, PNGFileFormat, TIFFFileFormat, OS2BMPFileFormat ) TFormats;
+	LEDataInputStream inputStream;
+	LEDataOutputStream outputStream;
+	ImageLoader loader;
+	int compression;
+
+/**
+ * Return whether or not the specified input stream
+ * represents a supported file format.
+ */
+abstract bool isFileFormat(LEDataInputStream stream);
+
+abstract ImageData[] loadFromByteStream();
+
+/**
+ * Read the specified input stream, and return the
+ * device independent image array represented by the stream.
+ */
+public ImageData[] loadFromStream(LEDataInputStream stream) {
+	try {
+		inputStream = stream;
+		return loadFromByteStream();
+    } catch (IOException e) {
+        SWT.error(SWT.ERROR_IO, e);
+        return null;
+    } catch (TracedException e) {
+        SWT.error(SWT.ERROR_INVALID_IMAGE, e);
+		return null;
+	}
+}
+
+/**
+ * Read the specified input stream using the specified loader, and
+ * return the device independent image array represented by the stream.
+ */
+public static ImageData[] load(InputStream istr, ImageLoader loader) {
+	FileFormat fileFormat = null;
+	LEDataInputStream stream = new LEDataInputStream(istr);
+	bool isSupported = false;
+    foreach( TFormat; TFormats ){
+        try{
+            fileFormat = new TFormat();
+            if (fileFormat.isFileFormat(stream)) {
+                isSupported = true;
+                break;
+            }
+        } catch (TracedException e) {
+        }
+    }
+	if (!isSupported) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
+	fileFormat.loader = loader;
+	return fileFormat.loadFromStream(stream);
+}
+
+/**
+ * Write the device independent image array stored in the specified loader
+ * to the specified output stream using the specified file format.
+ */
+public static void save(OutputStream os, int format, ImageLoader loader) {
+	if (format < 0 || format >= FORMATS.length) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
+	if (FORMATS[format] == null) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
+	if (loader.data == null || loader.data.length < 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+
+	LEDataOutputStream stream = new LEDataOutputStream(os);
+	FileFormat fileFormat = null;
+	try {
+        foreach( idx, TFormat; TFormats ){
+            if( idx == format ){
+                fileFormat = new TFormat();
+            }
+        }
+	} catch (TracedException e) {
+		SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
+	}
+	if (format == SWT.IMAGE_BMP_RLE) {
+		switch (loader.data[0].depth) {
+			case 8: fileFormat.compression = 1; break;
+			case 4: fileFormat.compression = 2; break;
+		}
+	}
+	fileFormat.unloadIntoStream(loader, stream);
+}
+
+abstract void unloadIntoByteStream(ImageLoader loader);
+
+/**
+ * Write the device independent image array stored in the specified loader
+ * to the specified output stream.
+ */
+public void unloadIntoStream(ImageLoader loader, LEDataOutputStream stream) {
+	try {
+		outputStream = stream;
+		unloadIntoByteStream(loader);
+		outputStream.flush();
+	} catch (TracedException e) {
+		try {outputStream.flush();} catch (Exception f) {}
+		SWT.error(SWT.ERROR_IO, e);
+	}
+}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/internal/image/LEDataInputStream.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.internal.image.LEDataInputStream;
+
+
+import dwt.dwthelper.InputStream;
+import tango.core.Exception;
+
+final class LEDataInputStream : InputStream{
+
+    InputStream host;
+
+	int position;
+
+	/**
+	 * The byte array containing the bytes to read.
+	 */
+	protected byte[] buf;
+
+	/**
+	 * The current position within the byte array <code>buf</code>. A value
+	 * equal to buf.length indicates no bytes available.  A value of
+	 * 0 indicates the buffer is full.
+	 */
+	protected int pos;
+
+
+	public this(InputStream input) {
+		this(input, 512);
+	}
+
+	public this(InputStream input, int bufferSize) {
+        host = input;
+		if (bufferSize > 0) {
+			buf = new byte[bufferSize];
+			pos = bufferSize;
+		}
+		else throw new IllegalArgumentException("bufferSize must be greater zero" );
+	}
+
+	public void close() {
+        buf = null;
+		if (host !is null) {
+			host.close();
+            host = null;
+		}
+	}
+
+	/**
+	 * Answer how many bytes were read.
+	 */
+	public int getPosition() {
+		return position;
+	}
+
+	/**
+	 * Answers how many bytes are available for reading without blocking
+	 */
+	public int available() {
+		if (buf is null) throw new IOException("buf is null");
+		return (buf.length - pos) + host.available();
+	}
+
+	/**
+	 * Answer the next byte of the input stream.
+	 */
+	public int read() {
+		if (buf is null) throw new IOException("buf is null");
+		if (pos < buf.length) {
+			position++;
+			return (buf[pos++] & 0xFF);
+		}
+        int c = host.read();
+		if (c != -1 ) position++;
+		return c;
+	}
+
+	/**
+	 * Don't imitate the JDK behaviour of reading a random number
+	 * of bytes when you can actually read them all.
+	 */
+	public int read(byte b[], int off, int len) {
+		int read = 0, count;
+		while (read != len && (count = readData(b, off, len - read)) != -1) {
+			off += count;
+			read += count;
+		}
+		position += read;
+		if (read == 0 && read != len) return -1;
+		return read;
+	}
+
+	/**
+ 	 * Reads at most <code>length</code> bytes from this LEDataInputStream and
+ 	 * stores them in byte array <code>buffer</code> starting at <code>offset</code>.
+ 	 * <p>
+ 	 * Answer the number of bytes actually read or -1 if no bytes were read and
+ 	 * end of stream was encountered.  This implementation reads bytes from
+ 	 * the pushback buffer first, then the target stream if more bytes are required
+ 	 * to satisfy <code>count</code>.
+	 * </p>
+	 * @param buffer the byte array in which to store the read bytes.
+	 * @param offset the offset in <code>buffer</code> to store the read bytes.
+	 * @param length the maximum number of bytes to store in <code>buffer</code>.
+	 *
+	 * @return int the number of bytes actually read or -1 if end of stream.
+	 *
+	 * @exception java.io.IOException if an IOException occurs.
+	 */
+	private int readData(byte[] buffer, int offset, int len) {
+		if (buf is null) throw new IOException("buf is null");
+		if (offset < 0 || offset > buffer.length ||
+  		 	len < 0 || (len > buffer.length - offset)) {
+	 		throw new ArrayBoundsException(__FILE__,__LINE__);
+		 	}
+
+		int cacheCopied = 0;
+		int newOffset = offset;
+
+		// Are there pushback bytes available?
+		int available = buf.length - pos;
+		if (available > 0) {
+			cacheCopied = (available >= len) ? len : available;
+            buffer[ newOffset .. newOffset + cacheCopied ] = buf[ pos .. pos + cacheCopied ];
+			newOffset += cacheCopied;
+			pos += cacheCopied;
+		}
+
+		// Have we copied enough?
+		if (cacheCopied == len) return len;
+
+		int inCopied = host.read( buffer, newOffset, len - cacheCopied );
+        if( inCopied == -1 ) inCopied = -1;
+		if (inCopied > 0 ) return inCopied + cacheCopied;
+		if (cacheCopied == 0) return inCopied;
+		return cacheCopied;
+	}
+
+	/**
+	 * Answer an integer comprised of the next
+	 * four bytes of the input stream.
+	 */
+	public int readInt() {
+		byte[4] buf = void;
+		host.read(buf);
+		return ((((((buf[3] & 0xFF) << 24) |
+			(buf[2] & 0xFF)) << 16) |
+			(buf[1] & 0xFF)) << 8) |
+			(buf[0] & 0xFF);
+	}
+
+	/**
+	 * Answer a short comprised of the next
+	 * two bytes of the input stream.
+	 */
+	public short readShort() {
+		byte[2] buf = void;
+		host.read(buf);
+		return cast(short)(((buf[1] & 0xFF) << 8) | (buf[0] & 0xFF));
+	}
+
+	/**
+	 * Push back the entire content of the given buffer <code>b</code>.
+	 * <p>
+	 * The bytes are pushed so that they would be read back b[0], b[1], etc.
+	 * If the push back buffer cannot handle the bytes copied from <code>b</code>,
+	 * an IOException will be thrown and no byte will be pushed back.
+	 * </p>
+	 *
+	 * @param b the byte array containing bytes to push back into the stream
+	 *
+	 * @exception 	java.io.IOException if the pushback buffer is too small
+	 */
+	public void unread(byte[] b) {
+		int l = b.length;
+		if (l > pos) throw new IOException("cannot unread");
+		position -= l;
+		pos -= l;
+        buf[ pos .. pos + l ] = b[];
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/internal/image/LEDataOutputStream.d	Sun Jan 06 19:36:29 2008 +0100
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.internal.image.LEDataOutputStream;
+
+
+import dwt.dwthelper.OutputStream;
+
+final class LEDataOutputStream : OutputStream {
+	OutputStream ostr;
+public this(OutputStream output) {
+	this.ostr = output;
+}
+/**
+ * Write the specified number of bytes of the given byte array,
+ * starting at the specified offset, to the output stream.
+ */
+public void write(byte b[], int off, int len) {
+	ostr.write(b, off, len);
+}
+/**
+ * Write the given byte to the output stream.
+ */
+public void write(int b)  {
+	ostr.write(b);
+}
+/**
+ * Write the given byte to the output stream.
+ */
+public void writeByte(byte b) {
+	ostr.write(b);
+}
+/**
+ * Write the four bytes of the given integer
+ * to the output stream.
+ */
+public void writeInt(int theInt) {
+	ostr.write(theInt & 0xFF);
+	ostr.write((theInt >> 8) & 0xFF);
+	ostr.write((theInt >> 16) & 0xFF);
+	ostr.write((theInt >> 24) & 0xFF);
+}
+/**
+ * Write the two bytes of the given short
+ * to the output stream.
+ */
+public void writeShort(int theShort) {
+	ostr.write(theShort & 0xFF);
+	ostr.write((theShort >> 8) & 0xFF);
+}
+}
--- a/todo.txt	Sat Jan 05 15:13:44 2008 -0800
+++ b/todo.txt	Sun Jan 06 19:36:29 2008 +0100
@@ -1,6 +1,11 @@
 next target is internal/images/FileFormat
-	dep: LEDataOutputStream
-	dep: LEDataInputStream
+    dep: LEDataOutputStream
+    dep: LEDataInputStream
+
+Questions:
+    What is the package: accessibility ?
+
+
 SWT                                    // left: getMessage -> Compatibility:ResourceBundle
 SWTError                               // OK
 SWTException                           // OK
@@ -22,7 +27,7 @@
 graphics/Color
 graphics/Cursor
 graphics/Device
-graphics/DeviceData		       // OK (fld: debug->debugging)
+graphics/DeviceData                    // OK (fld: debug->debugging)
 graphics/Drawable
 graphics/Font
 graphics/FontData                      // OK
@@ -243,56 +248,56 @@
 internal/gtk/GtkSelectionData
 internal/gtk/GtkFileSelection
 
-events/ShellAdapter   // OK
-events/SelectionListener   // OK
-events/TreeListener   // OK
-events/MenuDetectListener   // OK
-events/SelectionAdapter   // OK
-events/KeyAdapter   // OK
-events/TreeEvent   // OK
-events/ControlListener   // OK
-events/ArmEvent   // OK
-events/DragDetectEvent   // OK
-events/PaintListener   // OK
-events/MenuEvent   // OK
-events/DisposeEvent   // OK
-events/MouseEvent   // OK
-events/ShellListener   // OK
-events/SelectionEvent   // OK
-events/ControlAdapter   // OK
-events/ExpandListener   // OK
-events/MouseTrackListener   // OK
-events/FocusListener   // OK
-events/TreeAdapter   // OK
-events/MenuListener   // OK
-events/FocusEvent   // OK
-events/FocusAdapter   // OK
-events/MenuAdapter   // OK
-events/MouseWheelListener   // OK
-events/HelpListener   // OK
-events/ExpandAdapter   // OK
-events/TraverseEvent   // OK
-events/MouseListener   // OK
-events/ShellEvent   // OK
-events/KeyEvent   // OK
-events/ExpandEvent   // OK
-events/MenuDetectEvent   // OK
-events/VerifyEvent   // OK
-events/TraverseListener   // OK
-events/ArmListener   // OK
-events/ModifyListener   // OK
-events/MouseMoveListener   // OK
-events/ModifyEvent   // OK
-events/KeyListener   // OK
-events/VerifyListener   // OK
-events/PaintEvent   // OK
-events/HelpEvent   // OK
-events/DragDetectListener   // OK
-events/TypedEvent   // OK
-events/ControlEvent   // OK
-events/MouseTrackAdapter   // OK
-events/DisposeListener   // OK
-events/MouseAdapter   // OK
+events/ShellAdapter                    // OK
+events/SelectionListener               // OK
+events/TreeListener                    // OK
+events/MenuDetectListener              // OK
+events/SelectionAdapter                // OK
+events/KeyAdapter                      // OK
+events/TreeEvent                       // OK
+events/ControlListener                 // OK
+events/ArmEvent                        // OK
+events/DragDetectEvent                 // OK
+events/PaintListener                   // OK
+events/MenuEvent                       // OK
+events/DisposeEvent                    // OK
+events/MouseEvent                      // OK
+events/ShellListener                   // OK
+events/SelectionEvent                  // OK
+events/ControlAdapter                  // OK
+events/ExpandListener                  // OK
+events/MouseTrackListener              // OK
+events/FocusListener                   // OK
+events/TreeAdapter                     // OK
+events/MenuListener                    // OK
+events/FocusEvent                      // OK
+events/FocusAdapter                    // OK
+events/MenuAdapter                     // OK
+events/MouseWheelListener              // OK
+events/HelpListener                    // OK
+events/ExpandAdapter                   // OK
+events/TraverseEvent                   // OK
+events/MouseListener                   // OK
+events/ShellEvent                      // OK
+events/KeyEvent                        // OK
+events/ExpandEvent                     // OK
+events/MenuDetectEvent                 // OK
+events/VerifyEvent                     // OK
+events/TraverseListener                // OK
+events/ArmListener                     // OK
+events/ModifyListener                  // OK
+events/MouseMoveListener               // OK
+events/ModifyEvent                     // OK
+events/KeyListener                     // OK
+events/VerifyListener                  // OK
+events/PaintEvent                      // OK
+events/HelpEvent                       // OK
+events/DragDetectListener              // OK
+events/TypedEvent                      // OK
+events/ControlEvent                    // OK
+events/MouseTrackAdapter               // OK
+events/DisposeListener                 // OK
+events/MouseAdapter                    // OK
 
 
 // not sure what this is
@@ -394,7 +399,7 @@
 opengl/GLCanvas
 opengl/GLData
 
-dnd  // Drag and Drop 
+dnd  // Drag and Drop
 dnd/DragSourceAdapter
 dnd/TreeDragSourceEffect
 dnd/TreeDropTargetEffect