javauis/eswt_akn/org.eclipse.ercp.swt.s60/src/org/eclipse/swt/graphics/Image.java
branchRCL_3
changeset 19 04becd199f91
child 60 6c158198356e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/eswt_akn/org.eclipse.ercp.swt.s60/src/org/eclipse/swt/graphics/Image.java	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,775 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 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
+ *     Lynne Kues (IBM Corp) - modified to reflect eSWT API subset
+ *     Nokia Corporation - S60 implementation
+ *******************************************************************************/
+package org.eclipse.swt.graphics;
+
+
+import java.io.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.internal.symbian.*;
+import org.eclipse.swt.internal.FileCompatibility;
+
+
+/**
+ * Instances of this class are graphics which have been prepared
+ * for display on a specific device. That is, they are ready
+ * to paint using methods such as <code>GC.drawImage()</code>
+ * and display on widgets with, for example, <code>Button.setImage()</code>.
+ * <p>
+ * If loaded from a file format that supports it, an
+ * <code>Image</code> may have transparency, meaning that certain
+ * pixels are specified as being transparent when drawn. Examples
+ * of file formats that support transparency are GIF and PNG.
+ * </p><p>
+ * There are two primary ways to use <code>Images</code>.
+ * The first is to load a graphic file from disk and create an
+ * <code>Image</code> from it. This is done using an <code>Image</code>
+ * constructor, for example:
+ * <pre>
+ *    Image i = new Image(device, "C:\\graphic.png");
+ * </pre>
+ * A graphic file may contain a color table specifying which
+ * colors the image was intended to possess. In the above example,
+ * these colors will be mapped to the closest available color in
+ * SWT. It is possible to get more control over the mapping of
+ * colors as the image is being created, using code of the form:
+ * <pre>
+ *    ImageData data = new ImageData("C:\\graphic.png");
+ *    RGB[] rgbs = data.getRGBs();
+ *    // At this point, rgbs contains specifications of all
+ *    // the colors contained within this image. You may
+ *    // allocate as many of these colors as you wish by
+ *    // using the Color constructor Color(RGB), then
+ *    // create the image:
+ *    Image i = new Image(device, data);
+ * </pre>
+ * <p>
+ * Application code must explicitely invoke the <code>Image.dispose()</code>
+ * method to release the operating system resources managed by each instance
+ * when those instances are no longer required.
+ * </p>
+ *
+ * @see Color
+ * @see ImageData
+ */
+
+public final class Image implements Drawable
+{
+
+    /**
+     * specifies whether the receiver is a bitmap or an icon
+     * (one of <code>SWT.BITMAP</code>, <code>SWT.ICON</code>)
+     */
+    public int type;
+
+    /**
+     * the handle to the OS image resource
+     * (Warning: This field is platform dependent)
+     */
+    public int handle;
+
+    /**
+     * the device where this image was created
+     */
+    Device device;
+
+    /**
+     * specifies the transparent pixel
+     * (Warning: This field is platform dependent)
+     */
+    Color transparentPixel;
+
+    /**
+     * Whether this image is currently selected in a GC
+     * (Warning: This field is platform dependent)
+     */
+    boolean owningGc = false;
+
+    /**
+     * the global alpha value to be used for every pixel
+     * (Warning: This field is platform dependent)
+     */
+    int alpha = -1;
+
+    /**
+     * specifies the default scanline padding
+     * (Warning: This field is platform dependent)
+     */
+    static final int DEFAULT_SCANLINE_PAD = 4;
+
+    /**
+     * Prevents uninitialized instances from being created outside the package.
+     */
+    Image()
+    {
+    }
+
+    /**
+     * Constructs an empty instance of this class with the
+     * specified width and height. The result may be drawn upon
+     * by creating a GC and using any of its drawing operations,
+     * as shown in the following example:
+     * <pre>
+     *    Image i = new Image(device, width, height);
+     *    GC gc = new GC(i);
+     *    gc.drawRectangle(0, 0, 50, 50);
+     *    gc.dispose();
+     * </pre>
+     * <p>
+     * Note: Some platforms may have a limitation on the size
+     * of image that can be created (size depends on width, height,
+     * and depth). For example, Windows 95, 98, and ME do not allow
+     * images larger than 16M.
+     * </p>
+     *
+     * @param device the device on which to create the image
+     * @param width the width of the new image
+     * @param height the height of the new image
+     *
+     * @exception IllegalArgumentException <ul>
+     *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
+     *    <li>ERROR_INVALID_ARGUMENT - if either the width or height is negative or zero</li>
+     * </ul>
+     * @exception SWTError <ul>
+     *    <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li>
+     * </ul>
+     */
+    public Image(Device device, int width, int height)
+    {
+        if (device == null) device = Device.getDevice();
+        if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+        init(device, width, height);
+    }
+
+    /**
+     * Constructs an empty instance of this class with the
+     * width and height of the specified rectangle. The result
+     * may be drawn upon by creating a GC and using any of its
+     * drawing operations, as shown in the following example:
+     * <pre>
+     *    Image i = new Image(device, boundsRectangle);
+     *    GC gc = new GC(i);
+     *    gc.drawRectangle(0, 0, 50, 50);
+     *    gc.dispose();
+     * </pre>
+     * <p>
+     * Note: Some platforms may have a limitation on the size
+     * of image that can be created (size depends on width, height,
+     * and depth). For example, Windows 95, 98, and ME do not allow
+     * images larger than 16M.
+     * </p>
+     *
+     * @param device the device on which to create the image
+     * @param bounds a rectangle specifying the image's width and height (must not be null)
+     *
+     * @exception IllegalArgumentException <ul>
+     *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
+     *    <li>ERROR_NULL_ARGUMENT - if the bounds rectangle is null</li>
+     *    <li>ERROR_INVALID_ARGUMENT - if either the rectangle's width or height is negative</li>
+     * </ul>
+     * @exception SWTError <ul>
+     *    <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li>
+     * </ul>
+     */
+    public Image(Device device, Rectangle bounds)
+    {
+        if (device == null) device = Device.getDevice();
+        if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+        if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+        init(device, bounds.width, bounds.height);
+    }
+
+    /**
+     * Constructs an instance of this class from the given
+     * <code>ImageData</code>.
+     *
+     * @param device the device on which to create the image
+     * @param data the image data to create the image from (must not be null)
+     *
+     * @exception IllegalArgumentException <ul>
+     *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
+     *    <li>ERROR_NULL_ARGUMENT - if the image data is null</li>
+     * </ul>
+     * @exception SWTException <ul>
+     *    <li>ERROR_UNSUPPORTED_DEPTH - if the depth of the ImageData is not supported</li>
+     * </ul>
+     * @exception SWTError <ul>
+     *    <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li>
+     * </ul>
+     */
+    public Image(Device device, ImageData data)
+    {
+        if (device == null) device = Device.getDevice();
+        if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+        init(device, data);
+    }
+
+    /**
+     * Constructs an instance of this class by loading its representation
+     * from the specified input stream. Throws an error if an error
+     * occurs while loading the image, or if the result is an image
+     * of an unsupported type.  Application code is still responsible
+     * for closing the input stream.
+     * <p>
+     * This constructor may be used to load a resource as follows:
+     * </p>
+     * <pre>
+     *     new Image(device, clazz.getResourceAsStream("file.png"));
+     * </pre>
+     *
+     * @param device the device on which to create the image
+     * @param stream the input stream to load the image from
+     *
+     * @exception IllegalArgumentException <ul>
+     *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
+     *    <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
+     * </ul>
+     * @exception SWTException <ul>
+     *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li>
+     *    <li>ERROR_IO - if an IO error occurs while reading data</li>
+     *    <li>ERROR_UNSUPPORTED_DEPTH - if the InputStream describes an image with an unsupported depth</li>
+     *    <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
+     *  * </ul>
+     * </ul>
+     * @exception SWTError <ul>
+     *    <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li>
+     * </ul>
+     */
+    public Image(Device device, InputStream stream)
+    {
+        if (device == null) device = Device.getDevice();
+        if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+        init(device, new ImageData(stream));
+    }
+
+    /**
+     * Constructs an instance of this class by loading its representation
+     * from the file with the specified name. Throws an error if an error
+     * occurs while loading the image, or if the result is an image
+     * of an unsupported type.
+     * <p>
+     * This constructor is provided for convenience when loading
+     * a single image only. If the specified file contains
+     * multiple images, only the first one will be used.
+     *
+     * @param device the device on which to create the image
+     * @param filename the name of the file to load the image from
+     *
+     * @exception IllegalArgumentException <ul>
+     *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
+     *    <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
+     * </ul>
+     * @exception SWTException <ul>
+     *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li>
+     *    <li>ERROR_IO - if an IO error occurs while reading data</li>
+     *    <li>ERROR_UNSUPPORTED_DEPTH - if the image file has an unsupported depth</li>
+     *    <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
+     * </ul>
+     * @exception SWTError <ul>
+     *    <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li>
+     * </ul>
+     */
+    public Image(Device device, String filename)
+    {
+        if (device == null) device = Device.getDevice();
+        if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+        init(device, new ImageData(filename));
+    }
+
+    /**
+     * Disposes of the operating system resources associated with
+     * the image. Applications must dispose of all images which
+     * they allocate.
+     */
+    public void dispose()
+    {
+        if (handle == 0) return;
+        if (device.isDisposed()) return;
+        OS.Image_Dispose(device.handle, handle);
+        handle = 0;
+        if (transparentPixel != null) transparentPixel.dispose();
+        if (device.tracking) device.dispose_Object(this);
+        device = null;
+    }
+
+    /**
+     * Compares the argument to the receiver, and returns true
+     * if they represent the <em>same</em> object using a class
+     * specific comparison.
+     *
+     * @param object the object to compare with this object
+     * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
+     *
+     * @see #hashCode
+     */
+    public boolean equals(Object object)
+    {
+        if (object == this) return true;
+        if (!(object instanceof Image)) return false;
+        Image image = (Image) object;
+        return device == image.device && handle == image.handle;
+    }
+
+    /**
+     * Returns the bounds of the receiver. The rectangle will always
+     * have x and y values of 0, and the width and height of the
+     * image.
+     *
+     * @return a rectangle specifying the image's bounds
+     *
+     * @exception SWTException <ul>
+     *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+     *    <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon</li>
+     * </ul>
+     */
+    public Rectangle getBounds()
+    {
+        if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+        switch (type)
+        {
+        case SWT.BITMAP:
+        case SWT.ICON:
+            return OS.Image_GetBounds(handle);
+        default:
+            SWT.error(SWT.ERROR_INVALID_IMAGE);
+            return null;
+        }
+    }
+
+    /**
+     * Returns an <code>ImageData</code> based on the receiver
+     * Modifications made to this <code>ImageData</code> will not
+     * affect the Image.
+     *
+     * @return an <code>ImageData</code> containing the image's data and attributes
+     *
+     * @exception SWTException <ul>
+     *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+     *    <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon</li>
+     * </ul>
+     *
+     * @see ImageData
+     */
+    public ImageData getImageData()
+    {
+        if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+        switch (type)
+        {
+        case SWT.BITMAP:
+        case SWT.ICON:
+            return OS.Image_GetData(handle);
+        default:
+            SWT.error(SWT.ERROR_INVALID_IMAGE);
+            return null;
+        }
+    }
+
+    /**
+     * Returns an integer hash code for the receiver. Any two
+     * objects which return <code>true</code> when passed to
+     * <code>equals</code> must return the same value for this
+     * method.
+     *
+     * @return the receiver's hash
+     *
+     * @see #equals
+     */
+    public int hashCode()
+    {
+        return handle;
+    }
+
+    void init(Device device, int width, int height)
+    {
+        if (width <= 0 || height <= 0)
+        {
+            SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+        }
+        this.device = device;
+        type = SWT.BITMAP;
+        handle = OS.Image_New(device.handle, width, height);
+        if (handle == 0)
+        {
+            SWT.error(SWT.ERROR_NO_HANDLES, null, device.getLastError());
+        }
+        try
+        {
+            if (device.tracking) device.new_Object(this);
+        }
+        catch (Error e)
+        {
+            OS.Image_Dispose(device.handle, handle);
+            throw e;
+        }
+    }
+
+    static void init(Device device, Image image, ImageData i)
+    {
+        if (image != null) image.device = device;
+        image.handle = OS.Image_NewFromData(device.handle, i);
+        image.alpha = i.alpha;
+
+        try
+        {
+            if (i.transparentPixel != -1)
+            {
+                image.transparentPixel = new Color(device, i.palette.getRGB(i.transparentPixel));
+            }
+            if (device.tracking) device.new_Object(image);
+        }
+        catch (Error e)
+        {
+            OS.Image_Dispose(device.handle, image.handle);
+            throw e;
+        }
+    }
+
+    static void init(Device device, Image image, ImageData source, ImageData mask)
+    {
+        /* Create a temporary image and locate the black pixel */
+        ImageData imageData;
+        int blackIndex = 0;
+        if (source.palette.isDirect)
+        {
+            imageData = new ImageData(source.width, source.height, source.depth, source.palette);
+        }
+        else
+        {
+            RGB black = new RGB(0, 0, 0);
+            RGB[] rgbs = source.getRGBs();
+            if (source.transparentPixel != -1)
+            {
+                /*
+                 * The source had transparency, so we can use the transparent pixel
+                 * for black.
+                 */
+                RGB[] newRGBs = new RGB[rgbs.length];
+                System.arraycopy(rgbs, 0, newRGBs, 0, rgbs.length);
+                if (source.transparentPixel >= newRGBs.length)
+                {
+                    /* Grow the palette with black */
+                    rgbs = new RGB[source.transparentPixel + 1];
+                    System.arraycopy(newRGBs, 0, rgbs, 0, newRGBs.length);
+                    for (int i = newRGBs.length; i <= source.transparentPixel; i++)
+                    {
+                        rgbs[i] = new RGB(0, 0, 0);
+                    }
+                }
+                else
+                {
+                    newRGBs[source.transparentPixel] = black;
+                    rgbs = newRGBs;
+                }
+                blackIndex = source.transparentPixel;
+                imageData = new ImageData(source.width, source.height, source.depth, new PaletteData(rgbs));
+            }
+            else
+            {
+                while (blackIndex < rgbs.length)
+                {
+                    if (rgbs[blackIndex].equals(black)) break;
+                    blackIndex++;
+                }
+                if (blackIndex == rgbs.length)
+                {
+                    /*
+                     * We didn't find black in the palette, and there is no transparent
+                     * pixel we can use.
+                     */
+                    if ((1 << source.depth) > rgbs.length)
+                    {
+                        /* We can grow the palette and add black */
+                        RGB[] newRGBs = new RGB[rgbs.length + 1];
+                        System.arraycopy(rgbs, 0, newRGBs, 0, rgbs.length);
+                        newRGBs[rgbs.length] = black;
+                        rgbs = newRGBs;
+                    }
+                    else
+                    {
+                        /* No room to grow the palette */
+                        blackIndex = -1;
+                    }
+                }
+                imageData = new ImageData(source.width, source.height, source.depth, new PaletteData(rgbs));
+            }
+        }
+        if (blackIndex == -1)
+        {
+            /* There was no black in the palette, so just copy the data over */
+            System.arraycopy(source.data, 0, imageData.data, 0, imageData.data.length);
+        }
+        else
+        {
+            /* Modify the source image to contain black wherever the mask is 0 */
+            int[] imagePixels = new int[imageData.width];
+            int[] maskPixels = new int[mask.width];
+            for (int y = 0; y < imageData.height; y++)
+            {
+                source.getPixels(0, y, imageData.width, imagePixels, 0);
+                mask.getPixels(0, y, mask.width, maskPixels, 0);
+                for (int i = 0; i < imagePixels.length; i++)
+                {
+                    if (maskPixels[i] == 0) imagePixels[i] = blackIndex;
+                }
+                imageData.setPixels(0, y, source.width, imagePixels, 0);
+            }
+        }
+        imageData.maskPad = mask.scanlinePad;
+        imageData.maskData = mask.data;
+        init(device, image, imageData);
+    }
+
+    void init(Device device, ImageData i)
+    {
+        if (i == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+        init(device, this, i);
+    }
+
+    /**
+     * Invokes platform specific functionality to allocate a new GC handle.
+     * <p>
+     * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+     * API for <code>Image</code>. It is marked public only so that it
+     * can be shared within the packages provided by SWT. It is not
+     * available on all platforms, and should never be called from
+     * application code.
+     * </p>
+     *
+     * @param data the platform specific GC data
+     * @return the platform specific GC handle
+     */
+    public int internal_new_GC(GCData data)
+    {
+        synchronized (this)
+        {
+            if (owningGc)
+            {
+                SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+            }
+            owningGc = true;
+        }
+
+        if ((type != SWT.BITMAP) && (type != SWT.ICON))
+        {
+            SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+        }
+
+        return OS.Drawable_NewGc(handle);
+    }
+
+    /**
+     * Invokes platform specific functionality to dispose a GC handle.
+     * <p>
+     * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+     * API for <code>Image</code>. It is marked public only so that it
+     * can be shared within the packages provided by SWT. It is not
+     * available on all platforms, and should never be called from
+     * application code.
+     * </p>
+     *
+     * @param hDC the platform specific GC handle
+     * @param data the platform specific GC data
+     */
+    public void internal_dispose_GC(int gcHandle, GCData data)
+    {
+        OS.GC_Dispose(gcHandle);
+
+        synchronized (this)
+        {
+            owningGc = false;
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if the receiver is visible, and
+     * <code>false</code> otherwise.
+     * <p>
+     * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+     * API for <code>Drawable</code>. It is marked public only so that it
+     * can be shared within the packages provided by SWT. It is not
+     * available on all platforms, and should never be called from
+     * application code.
+     * </p>
+     *
+     * @return the receiver's visibility state
+     */
+    public boolean internal_isVisible()
+    {
+        return true;
+    }
+
+    /**
+     * Returns <code>true</code> if the receiver has been disposed,
+     * and <code>false</code> otherwise.
+     * <p>
+     * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+     * API for <code>Drawable</code>. It is marked public only so that it
+     * can be shared within the packages provided by SWT. It is not
+     * available on all platforms, and should never be called from
+     * application code.
+     * </p>
+     *
+     * @return <code>true</code> when the receiver is disposed and <code>false</code> otherwise
+     */
+    public boolean internal_isDisposed()
+    {
+        return isDisposed();
+    }
+
+    /**
+     * Returns <code>true</code> if the image has been disposed,
+     * and <code>false</code> otherwise.
+     * <p>
+     * This method gets the dispose state for the image.
+     * When an image has been disposed, it is an error to
+     * invoke any other method using the image.
+     *
+     * @return <code>true</code> when the image is disposed and <code>false</code> otherwise
+     */
+    public boolean isDisposed()
+    {
+        return handle == 0;
+    }
+
+    /**
+     * Returns a string containing a concise, human-readable
+     * description of the receiver.
+     *
+     * @return a string representation of the receiver
+     */
+    public String toString()
+    {
+        if (isDisposed()) return "Image {*DISPOSED*}";
+        return "Image {" + handle + "}";
+    }
+
+
+
+
+    /**
+     * The following functions are not part of the eSWT public api
+     * @param fileName
+     * @return
+     */
+    static int imageFormat(String fileName)
+    {
+        InputStream stream = null;
+        try
+        {
+            stream = FileCompatibility.getInputStreamFromFile(fileName);
+            byte[] buffer = new byte[32];
+            stream.read(buffer, 0, buffer.length);
+            stream.close();
+            return Image.imageFormat(buffer);
+        }
+        catch (IOException e)
+        {
+            SWT.error(SWT.ERROR_IO, e);
+        }
+        finally
+        {
+            try
+            {
+                if (stream != null) stream.close();
+            }
+            catch (IOException e)
+            {
+                // Ignore error
+            }
+        }
+        return SWT.IMAGE_UNDEFINED;
+    }
+    static int imageFormat(byte[] streamBytes)
+    {
+        if (isPNGFormat(streamBytes)) return SWT.IMAGE_PNG;
+        if (isGIFFormat(streamBytes)) return SWT.IMAGE_GIF;
+        if (isJPEGFormat(streamBytes)) return SWT.IMAGE_JPEG;
+        return SWT.IMAGE_UNDEFINED;
+    }
+    static boolean isPNGFormat(byte[] streamBytes)
+    {
+        if (streamBytes.length < 8) return false;
+        if ((streamBytes[0] & 0xFF) != 137) return false; //137
+        if ((streamBytes[1] & 0xFF) != 80) return false; //P
+        if ((streamBytes[2] & 0xFF) != 78) return false; //N
+        if ((streamBytes[3] & 0xFF) != 71) return false; //G
+        if ((streamBytes[4] & 0xFF) != 13) return false; //<RETURN>
+        if ((streamBytes[5] & 0xFF) != 10) return false; //<LINEFEED>
+        if ((streamBytes[6] & 0xFF) != 26) return false; //<CTRL/Z>
+        if ((streamBytes[7] & 0xFF) != 10) return false; //<LINEFEED>
+        return true;
+    }
+    static boolean isGIFFormat(byte[] streamBytes)
+    {
+        if (streamBytes.length < 3) return false;
+        if (streamBytes[0] != 'G') return false;
+        if (streamBytes[1]  != 'I') return false;
+        if (streamBytes[2]  != 'F') return false;
+        return true;
+    }
+    static boolean isJPEGFormat(byte[] streamBytes)
+    {
+        if (streamBytes.length < 2) return false;
+        if ((streamBytes[0] & 0xFF) != 0xFF) return false;
+        if ((streamBytes[1] & 0xFF) != 0xD8) return false;
+        return true;
+    }
+    /**
+     * Reads the specified stream and returns the contents as a byte
+     * array.
+     *
+     * @param stream the raw image data stream
+     * @return image data buffer
+     */
+    static byte[] readImageStream(InputStream stream)
+    {
+        byte[] buffer = new byte[512];
+        ByteArrayOutputStream baoStream = new ByteArrayOutputStream();
+        if (buffer == null || baoStream == null)
+        {
+            SWT.error(SWT.ERROR_IO);
+        }
+        try
+        {
+            boolean done = false;
+            while (!done)
+            {
+                int length = stream.read(buffer);
+                if (-1 == length)
+                {
+                    done = true;
+                }
+                else
+                {
+                    baoStream.write(buffer,0,length);
+                }
+            }
+        }
+        catch (IOException e)
+        {
+            SWT.error(SWT.ERROR_IO, e);
+        }
+        finally
+        {
+            try
+            {
+                baoStream.close();
+            }
+            catch (IOException e)
+            {
+                // ignore for the close
+            }
+        }
+
+        return baoStream.toByteArray();
+    }
+}