/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *******************************************************************************/
package org.eclipse.swt.graphics;


import java.io.*;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.cairo.*;
import org.eclipse.swt.internal.gtk.*;

/**
 * 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.bmp");
 * </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.bmp");
 *    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>
 * Applications which require even greater control over the image
 * loading process should use the support provided in class
 * <code>ImageLoader</code>.
 * </p><p>
 * Application code must explicitly 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
 * @see ImageLoader
 * @see <a href="http://www.eclipse.org/swt/snippets/#image">Image snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: GraphicsExample, ImageAnalyzer</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 */
public final class Image extends Resource implements Drawable {

	/**
	 * specifies whether the receiver is a bitmap or an icon
	 * (one of <code>SWT.BITMAP</code>, <code>SWT.ICON</code>)
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. 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 accessed from application code.
	 * </p>
	 *
	 * @noreference This field is not intended to be referenced by clients.
	 */
	public int type;

	/**
	 * The handle to the OS pixmap resource.
	 * (Warning: This field is platform dependent)
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. 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 accessed from application code.
	 * </p>
	 *
	 * @noreference This field is not intended to be referenced by clients.
	 */
	public long /*int*/ pixmap;

	/**
	 * The handle to the OS mask resource.
	 * (Warning: This field is platform dependent)
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. 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 accessed from application code.
	 * </p>
	 *
	 * @noreference This field is not intended to be referenced by clients.
	 */
	public long /*int*/ mask;

	/**
	 * The handle to the OS cairo surface resource.
	 * (Warning: This field is platform dependent)
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. 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 accessed from application code.
	 * </p>
	 *
	 * @noreference This field is not intended to be referenced by clients.
	 */
	public long /*int*/ surface;

	/**
	 * specifies the transparent pixel
	 */
	int transparentPixel = -1;

	/**
	 * The GC the image is currently selected in.
	 */
	GC memGC;

	/**
	 * The alpha data of the image.
	 */
	byte[] alphaData;

	/**
	 * The global alpha value to be used for every pixel.
	 */
	int alpha = -1;

	/**
	 * The width of the image.
	 */
	int width = -1;

	/**
	 * The height of the image.
	 */
	int height = -1;

	/**
	 * Specifies the default scanline padding.
	 */
	static final int DEFAULT_SCANLINE_PAD = 4;

	/**
	 * ImageFileNameProvider to provide file names at various Zoom levels
	 */
	ImageFileNameProvider imageFileNameProvider;

	/**
	 * ImageDataProvider to provide ImageData at various Zoom levels
	 */
	ImageDataProvider imageDataProvider;

	/**
	 * Attribute to cache current device zoom level
	 */
	int currentDeviceZoom = 100;

Image(Device device) {
	super(device);
}

/**
 * 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) {
	super(device);
	init(width, height);
	init();
}

/**
 * Constructs a new instance of this class based on the
 * provided image, with an appearance that varies depending
 * on the value of the flag. The possible flag values are:
 * <dl>
 * <dt><b>{@link SWT#IMAGE_COPY}</b></dt>
 * <dd>the result is an identical copy of srcImage</dd>
 * <dt><b>{@link SWT#IMAGE_DISABLE}</b></dt>
 * <dd>the result is a copy of srcImage which has a <em>disabled</em> look</dd>
 * <dt><b>{@link SWT#IMAGE_GRAY}</b></dt>
 * <dd>the result is a copy of srcImage which has a <em>gray scale</em> look</dd>
 * </dl>
 *
 * @param device the device on which to create the image
 * @param srcImage the image to use as the source
 * @param flag the style, either <code>IMAGE_COPY</code>, <code>IMAGE_DISABLE</code> or <code>IMAGE_GRAY</code>
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
 *    <li>ERROR_NULL_ARGUMENT - if srcImage is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the flag is not one of <code>IMAGE_COPY</code>, <code>IMAGE_DISABLE</code> or <code>IMAGE_GRAY</code></li>
 *    <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon, or is otherwise in an invalid state</li>
 *    <li>ERROR_UNSUPPORTED_DEPTH - if the depth of the image 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, Image srcImage, int flag) {
	super(device);
	if (srcImage == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (srcImage.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	switch (flag) {
		case SWT.IMAGE_COPY:
		case SWT.IMAGE_DISABLE:
		case SWT.IMAGE_GRAY:
			break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	device = this.device;
	this.type = srcImage.type;

	if (OS.USE_CAIRO) {
		if (flag != SWT.IMAGE_DISABLE) transparentPixel = srcImage.transparentPixel;
		alpha = srcImage.alpha;
		if (srcImage.alphaData != null) {
			alphaData = new byte[srcImage.alphaData.length];
			System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length);
		}

		long /*int*/ imageSurface = srcImage.surface;
		int width = this.width = srcImage.width;
		int height = this.height = srcImage.height;
		int format = Cairo.cairo_surface_get_content(imageSurface) == Cairo.CAIRO_CONTENT_COLOR ? Cairo.CAIRO_FORMAT_RGB24 : Cairo.CAIRO_FORMAT_ARGB32;
		boolean hasAlpha = format == Cairo.CAIRO_FORMAT_ARGB32;
		surface = Cairo.cairo_image_surface_create(format, width, height);
		if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		long /*int*/ cairo = Cairo.cairo_create(surface);
		if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_SOURCE);
		Cairo.cairo_set_source_surface (cairo, imageSurface, 0, 0);
		Cairo.cairo_paint (cairo);
		Cairo.cairo_destroy(cairo);
		if (flag != SWT.IMAGE_COPY) {
			int stride = Cairo.cairo_image_surface_get_stride(surface);
			long /*int*/ data = Cairo.cairo_image_surface_get_data(surface);
			int oa, or, og, ob;
			if (OS.BIG_ENDIAN) {
				oa = 0; or = 1; og = 2; ob = 3;
			} else {
				oa = 3; or = 2; og = 1; ob = 0;
			}
			switch (flag) {
				case SWT.IMAGE_DISABLE: {
					Color zeroColor = device.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
					RGB zeroRGB = zeroColor.getRGB();
					int zeroRed = zeroRGB.red;
					int zeroGreen = zeroRGB.green;
					int zeroBlue = zeroRGB.blue;
					Color oneColor = device.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
					RGB oneRGB = oneColor.getRGB();
					int oneRed = oneRGB.red;
					int oneGreen = oneRGB.green;
					int oneBlue = oneRGB.blue;
					byte[] line = new byte[stride];
					for (int y=0; y<height; y++) {
						OS.memmove(line, data + (y * stride), stride);
						for (int x=0, offset=0; x<width; x++, offset += 4) {
							int a = line[offset + oa] & 0xFF;
							int r = line[offset + or] & 0xFF;
							int g = line[offset + og] & 0xFF;
							int b = line[offset + ob] & 0xFF;
							if (hasAlpha && a != 0) {
								r = ((r * 0xFF) + a / 2) / a;
								g = ((g * 0xFF) + a / 2) / a;
								b = ((b * 0xFF) + a / 2) / a;
							}
							int intensity = r * r + g * g + b * b;
							if (intensity < 98304) {
								r = zeroRed;
								g = zeroGreen;
								b = zeroBlue;
							} else {
								r = oneRed;
								g = oneGreen;
								b = oneBlue;
							}
							if (hasAlpha) {
								/* pre-multiplied alpha */
								r = (r * a) + 128;
								r = (r + (r >> 8)) >> 8;
								g = (g * a) + 128;
								g = (g + (g >> 8)) >> 8;
								b = (b * a) + 128;
								b = (b + (b >> 8)) >> 8;
							}
							line[offset + or] = (byte)r;
							line[offset + og] = (byte)g;
							line[offset + ob] = (byte)b;
						}
						OS.memmove(data + (y * stride), line, stride);
					}
					break;
				}
				case SWT.IMAGE_GRAY: {
					byte[] line = new byte[stride];
					for (int y=0; y<height; y++) {
						OS.memmove(line, data + (y * stride), stride);
						for (int x=0, offset = 0; x<width; x++, offset += 4) {
							int a = line[offset + oa] & 0xFF;
							int r = line[offset + or] & 0xFF;
							int g = line[offset + og] & 0xFF;
							int b = line[offset + ob] & 0xFF;
							if (hasAlpha && a != 0) {
								r = ((r * 0xFF) + a / 2) / a;
								g = ((g * 0xFF) + a / 2) / a;
								b = ((b * 0xFF) + a / 2) / a;
							}
							int intensity = (r+r+g+g+g+g+g+b) >> 3;
							if (hasAlpha) {
								/* pre-multiplied alpha */
								intensity = (intensity * a) + 128;
								intensity = (intensity + (intensity >> 8)) >> 8;
							}
							line[offset+or] = line[offset+og] = line[offset+ob] = (byte)intensity;
						}
						OS.memmove(data + (y * stride), line, stride);
					}
					break;
				}
			}
		}
		init();
		return;
	}

	/* Get source image size */
	int[] w = new int[1], h = new int[1];
	if (OS.GTK_VERSION >= OS.VERSION(2, 24, 0)) {
		OS.gdk_pixmap_get_size(srcImage.pixmap, w, h);
	} else {
		OS.gdk_drawable_get_size(srcImage.pixmap, w, h);
	}
 	int width = w[0];
 	int height = h[0];

 	/* Copy the mask */
	if ((srcImage.type == SWT.ICON && srcImage.mask != 0) || srcImage.transparentPixel != -1) {
		/* Generate the mask if necessary. */
		if (srcImage.transparentPixel != -1) srcImage.createMask();
		long /*int*/ mask = OS.gdk_pixmap_new(0, width, height, 1);
		if (mask == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		long /*int*/ gdkGC = OS.gdk_gc_new(mask);
		if (gdkGC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		OS.gdk_draw_drawable(mask, gdkGC, srcImage.mask, 0, 0, 0, 0, width, height);
		OS.g_object_unref(gdkGC);
		this.mask = mask;
		/* Destroy the image mask if the there is a GC created on the image */
		if (srcImage.transparentPixel != -1 && srcImage.memGC != null) srcImage.destroyMask();
	}

	/* Copy transparent pixel and alpha data */
	if (flag != SWT.IMAGE_DISABLE) transparentPixel = srcImage.transparentPixel;
	alpha = srcImage.alpha;
	if (srcImage.alphaData != null) {
		alphaData = new byte[srcImage.alphaData.length];
		System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length);
	}
	createAlphaMask(width, height);

	/* Create the new pixmap */
	long /*int*/ pixmap = OS.gdk_pixmap_new (OS.gdk_get_default_root_window(), width, height, -1);
	if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	long /*int*/ gdkGC = OS.gdk_gc_new(pixmap);
	if (gdkGC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	this.pixmap = pixmap;

	if (flag == SWT.IMAGE_COPY) {
		OS.gdk_draw_drawable(pixmap, gdkGC, srcImage.pixmap, 0, 0, 0, 0, width, height);
		OS.g_object_unref(gdkGC);
	} else {

		/* Retrieve the source pixmap data */
		long /*int*/ pixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, false, 8, width, height);
		if (pixbuf == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		long /*int*/ colormap = OS.gdk_colormap_get_system();
		OS.gdk_pixbuf_get_from_drawable(pixbuf, srcImage.pixmap, colormap, 0, 0, 0, 0, width, height);
		int stride = OS.gdk_pixbuf_get_rowstride(pixbuf);
		long /*int*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf);

		/* Apply transformation */
		switch (flag) {
			case SWT.IMAGE_DISABLE: {
				Color zeroColor = device.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
				RGB zeroRGB = zeroColor.getRGB();
				byte zeroRed = (byte)zeroRGB.red;
				byte zeroGreen = (byte)zeroRGB.green;
				byte zeroBlue = (byte)zeroRGB.blue;
				Color oneColor = device.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
				RGB oneRGB = oneColor.getRGB();
				byte oneRed = (byte)oneRGB.red;
				byte oneGreen = (byte)oneRGB.green;
				byte oneBlue = (byte)oneRGB.blue;
				byte[] line = new byte[stride];
				for (int y=0; y<height; y++) {
					OS.memmove(line, pixels + (y * stride), stride);
					for (int x=0; x<width; x++) {
						int offset = x*3;
						int red = line[offset] & 0xFF;
						int green = line[offset+1] & 0xFF;
						int blue = line[offset+2] & 0xFF;
						int intensity = red * red + green * green + blue * blue;
						if (intensity < 98304) {
							line[offset] = zeroRed;
							line[offset+1] = zeroGreen;
							line[offset+2] = zeroBlue;
						} else {
							line[offset] = oneRed;
							line[offset+1] = oneGreen;
							line[offset+2] = oneBlue;
						}
					}
					OS.memmove(pixels + (y * stride), line, stride);
				}
				break;
			}
			case SWT.IMAGE_GRAY: {
				byte[] line = new byte[stride];
				for (int y=0; y<height; y++) {
					OS.memmove(line, pixels + (y * stride), stride);
					for (int x=0; x<width; x++) {
						int offset = x*3;
						int red = line[offset] & 0xFF;
						int green = line[offset+1] & 0xFF;
						int blue = line[offset+2] & 0xFF;
						byte intensity = (byte)((red+red+green+green+green+green+green+blue) >> 3);
						line[offset] = line[offset+1] = line[offset+2] = intensity;
					}
					OS.memmove(pixels + (y * stride), line, stride);
				}
				break;
			}
		}

		/* Copy data back to destination pixmap */
		OS.gdk_pixbuf_render_to_drawable(pixbuf, pixmap, gdkGC, 0, 0, 0, 0, width, height, OS.GDK_RGB_DITHER_NORMAL, 0, 0);

		/* Free resources */
		OS.g_object_unref(pixbuf);
		OS.g_object_unref(gdkGC);
	}
	init();
}

/**
 * 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) {
	super(device);
	if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	init(bounds.width, bounds.height);
	init();
}

/**
 * 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) {
	super(device);
	init(data);
	init();
}

/**
 * Constructs an instance of this class, whose type is
 * <code>SWT.ICON</code>, from the two given <code>ImageData</code>
 * objects. The two images must be the same size. Pixel transparency
 * in either image will be ignored.
 * <p>
 * The mask image should contain white wherever the icon is to be visible,
 * and black wherever the icon is to be transparent. In addition,
 * the source image should contain black wherever the icon is to be
 * transparent.
 * </p>
 *
 * @param device the device on which to create the icon
 * @param source the color data for the icon
 * @param mask the mask data for the icon
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
 *    <li>ERROR_NULL_ARGUMENT - if either the source or mask is null </li>
 *    <li>ERROR_INVALID_ARGUMENT - if source and mask are different sizes</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 source, ImageData mask) {
	super(device);
	if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (mask == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (source.width != mask.width || source.height != mask.height) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	mask = ImageData.convertMask (mask);
	ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data);
	image.maskPad = mask.scanlinePad;
	image.maskData = mask.data;
	init(image);
	init();
}

/**
 * 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 is provided for convenience when loading a single
 * image only. If the stream contains multiple images, only the first
 * one will be loaded. To load multiple images, use
 * <code>ImageLoader.load()</code>.
 * </p><p>
 * This constructor may be used to load a resource as follows:
 * </p>
 * <pre>
 *     static Image loadImage (Display display, Class clazz, String string) {
 *          InputStream stream = clazz.getResourceAsStream (string);
 *          if (stream == null) return null;
 *          Image image = null;
 *          try {
 *               image = new Image (display, stream);
 *          } catch (SWTException ex) {
 *          } finally {
 *               try {
 *                    stream.close ();
 *               } catch (IOException ex) {}
 *          }
 *          return image;
 *     }
 * </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_IO - if an IO error occurs while reading from the stream</li>
 *    <li>ERROR_INVALID_IMAGE - if the image stream contains invalid data </li>
 *    <li>ERROR_UNSUPPORTED_DEPTH - if the image stream describes an image with an unsupported depth</li>
 *    <li>ERROR_UNSUPPORTED_FORMAT - if the image stream 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, InputStream stream) {
	super(device);
	init(new ImageData(stream));
	init();
}

/**
 * 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_IO - if an IO error occurs while reading from the file</li>
 *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li>
 *    <li>ERROR_UNSUPPORTED_DEPTH - if the image file describes an image with 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) {
	super(device);
	if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	initNative(filename);
	if (this.pixmap == 0 && this.surface == 0) init(new ImageData(filename));
	init();
}

/**
 * Constructs an instance of this class by loading its representation
 * from the file retrieved from the ImageFileNameProvider. 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 for loading image as
 * per DPI level.
 *
 * @param device the device on which to create the image
 * @param imageFileNameProvider the ImageFileNameProvider object that is
 * to be used to get the file name
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
 *    <li>ERROR_NULL_ARGUMENT - if the ImageFileNameProvider is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the fileName provided by ImageFileNameProvider is null at 100% zoom</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_IO - if an IO error occurs while reading from the file</li>
 *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li>
 *    <li>ERROR_UNSUPPORTED_DEPTH - if the image file describes an image with 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>
 * @since 3.104
 */
public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
	super(device);
	this.imageFileNameProvider = imageFileNameProvider;
	currentDeviceZoom = getDeviceZoom ();
	String filename = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, currentDeviceZoom, new boolean[1]);
	initNative (filename);
	if (this.pixmap == 0 && this.surface == 0) init(new ImageData(filename));
	init ();
}

/**
 * Constructs an instance of this class by loading its representation
 * from the ImageData retrieved from the ImageDataProvider. 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 for loading image as
 * per DPI level.
 *
 * @param device the device on which to create the image
 * @param imageDataProvider the ImageDataProvider object that is
 * to be used to get the ImageData
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
 *    <li>ERROR_NULL_ARGUMENT - if the ImageDataProvider is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the ImageData provided by ImageDataProvider is null at 100% zoom</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_IO - if an IO error occurs while reading from the file</li>
 *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li>
 *    <li>ERROR_UNSUPPORTED_DEPTH - if the image file describes an image with 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>
 * @since 3.104
 */
public Image(Device device, ImageDataProvider imageDataProvider) {
	super(device);
	this.imageDataProvider = imageDataProvider;
	currentDeviceZoom = getDeviceZoom ();
	ImageData data =  DPIUtil.validateAndGetImageDataAtZoom(imageDataProvider, currentDeviceZoom, new boolean[1]);
	init (data);
	init ();
}

int getDeviceZoom () {
	return DPIUtil.mapDPIToZoom (device._getDPIx ());
}

/**
 * Refresh the Image based on the zoom level, if required.
 *
 * @return true if image is refreshed
 */
boolean refreshImageForZoom () {
	boolean refreshed = false;
	if (imageFileNameProvider != null) {
		int deviceZoomLevel = getDeviceZoom();
		if (deviceZoomLevel != currentDeviceZoom) {
			boolean[] found = new boolean[1];
			String filename = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, deviceZoomLevel, found);
			/* Avoid re-creating the fall-back image, when current zoom is already 100% */
			if (found[0] || currentDeviceZoom != 100) {
				/* Release current native resources */
				destroy ();
				initNative(filename);
				if (this.pixmap == 0 && this.surface == 0) init(new ImageData(filename));
				init ();
				refreshed = true;
			}
			currentDeviceZoom = deviceZoomLevel;
		}
	} else if (imageDataProvider != null) {
		int deviceZoomLevel = getDeviceZoom();
		if (deviceZoomLevel != currentDeviceZoom) {
			boolean[] found = new boolean[1];
			ImageData data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, deviceZoomLevel, found);
			/* Avoid re-creating the fall-back image, when current zoom is already 100% */
			if (found[0] || currentDeviceZoom != 100) {
				/* Release current native resources */
				destroy ();
				init(data);
				init();
				refreshed = true;
			}
			currentDeviceZoom = deviceZoomLevel;
		}
	}
	return refreshed;
}

void initNative(String filename) {
	try {
		int length = filename.length ();
		char [] chars = new char [length];
		filename.getChars (0, length, chars, 0);
		byte [] buffer = Converter.wcsToMbcs(null, chars, true);
		long /*int*/ pixbuf = OS.gdk_pixbuf_new_from_file(buffer, null);
		if (pixbuf != 0) {
			try {
				createFromPixbuf (SWT.BITMAP, pixbuf);
			} finally {
				if (pixbuf != 0) OS.g_object_unref (pixbuf);
			}
		}
	} catch (SWTException e) {}
}

void createAlphaMask (int width, int height) {
	if (device.useXRender && (alpha != -1 || alphaData != null)) {
		mask = OS.gdk_pixmap_new(0, alpha != -1 ? 1 : width, alpha != -1 ? 1 : height, 8);
		if (mask == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		long /*int*/ gc = OS.gdk_gc_new(mask);
		if (alpha != -1) {
			GdkColor color = new GdkColor();
			color.pixel = (alpha & 0xFF) << 8 | (alpha & 0xFF);
			OS.gdk_gc_set_foreground(gc, color);
			OS.gdk_draw_rectangle(mask, gc, 1, 0, 0, 1, 1);
		} else {
			long /*int*/ imagePtr = OS.gdk_drawable_get_image(mask, 0, 0, width, height);
			if (imagePtr == 0) SWT.error(SWT.ERROR_NO_HANDLES);
			GdkImage gdkImage = new GdkImage();
			OS.memmove(gdkImage, imagePtr);
			if (gdkImage.bpl == width) {
				OS.memmove(gdkImage.mem, alphaData, alphaData.length);
			} else {
				byte[] line = new byte[gdkImage.bpl];
				for (int y = 0; y < height; y++) {
					System.arraycopy(alphaData, width * y, line, 0, width);
					OS.memmove(gdkImage.mem + (gdkImage.bpl * y), line, gdkImage.bpl);
				}
			}
			OS.gdk_draw_image(mask, gc, imagePtr, 0, 0, 0, 0, width, height);
			OS.g_object_unref(imagePtr);
		}
		OS.g_object_unref(gc);
	}
}

void createFromPixbuf(int type, long /*int*/ pixbuf) {
	this.type = type;
	boolean hasAlpha = OS.gdk_pixbuf_get_has_alpha(pixbuf);
	if (OS.USE_CAIRO) {
		int width = this.width = OS.gdk_pixbuf_get_width(pixbuf);
		int height = this.height = OS.gdk_pixbuf_get_height(pixbuf);
		int stride = OS.gdk_pixbuf_get_rowstride(pixbuf);
		long /*int*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf);
		int format = hasAlpha ? Cairo.CAIRO_FORMAT_ARGB32 : Cairo.CAIRO_FORMAT_RGB24;
		surface = Cairo.cairo_image_surface_create(format, width, height);
		if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		long /*int*/ data = Cairo.cairo_image_surface_get_data(surface);
		int cairoStride = Cairo.cairo_image_surface_get_stride(surface);
		int oa = 0, or = 0, og = 0, ob = 0;
		if (OS.BIG_ENDIAN) {
			oa = 0; or = 1; og = 2; ob = 3;
		} else {
			oa = 3; or = 2; og = 1; ob = 0;
		}
		byte[] line = new byte[stride];
		if (hasAlpha) {
			alphaData = new byte[width * height];
			for (int y = 0, alphaOffset = 0; y < height; y++) {
				OS.memmove(line, pixels + (y * stride), stride);
				for (int x = 0, offset = 0; x < width; x++, offset += 4) {
					int a = line[offset + 3] & 0xFF;
					int r = ((line[offset + 0] & 0xFF) * a) + 128;
					r = (r + (r >> 8)) >> 8;
					int g = ((line[offset + 1] & 0xFF) * a) + 128;
					g = (g + (g >> 8)) >> 8;
					int b = ((line[offset + 2] & 0xFF) * a) + 128;
					b = (b + (b >> 8)) >> 8;
					line[offset + oa] = (byte)a;
					line[offset + or] = (byte)r;
					line[offset + og] = (byte)g;
					line[offset + ob] = (byte)b;
					alphaData[alphaOffset++] = (byte)a;
				}
				OS.memmove(data + (y * stride), line, stride);
			}
		} else {
			byte[] cairoLine = new byte[cairoStride];
			for (int y = 0; y < height; y++) {
				OS.memmove(line, pixels + (y * stride), stride);
				for (int x = 0, offset = 0, cairoOffset = 0; x < width; x++, offset += 3, cairoOffset += 4) {
					int r = line[offset + 0] & 0xFF;
					int g = line[offset + 1] & 0xFF;
					int b = line[offset + 2] & 0xFF;
					cairoLine[cairoOffset + or] = (byte)r;
					cairoLine[cairoOffset + og] = (byte)g;
					cairoLine[cairoOffset + ob] = (byte)b;
				}
				OS.memmove(data + (y * cairoStride), cairoLine, cairoStride);
			}
		}
		Cairo.cairo_surface_mark_dirty(surface);
	} else {
		if (hasAlpha) {
			/*
			* Bug in GTK. Depending on the image (seems to affect images that have
			* some degree of transparency all over the image), gdk_pixbuff_render_pixmap_and_mask()
			* will return a corrupt pixmap. To avoid this, read in and store the alpha channel data
			* for the image and then set it to 0xFF to prevent any possible corruption from
			* gdk_pixbuff_render_pixmap_and_mask().
			*/
			int width = OS.gdk_pixbuf_get_width(pixbuf);
			int height = OS.gdk_pixbuf_get_height(pixbuf);
			int stride = OS.gdk_pixbuf_get_rowstride(pixbuf);
			long /*int*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf);
			byte[] line = new byte[stride];
			alphaData = new byte[width * height];
			for (int y = 0; y < height; y++) {
				OS.memmove(line, pixels + (y * stride), stride);
				for (int x = 0; x < width; x++) {
					alphaData[y*width+x] = line[x*4 + 3];
					line[x*4 + 3] = (byte) 0xFF;
				}
				OS.memmove(pixels + (y * stride), line, stride);
			}
			createAlphaMask(width, height);
		}
		long /*int*/ [] pixmap_return = new long /*int*/ [1];
		OS.gdk_pixbuf_render_pixmap_and_mask(pixbuf, pixmap_return, null, 0);
		this.pixmap = pixmap_return[0];
		if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	}
}

/**
 * Create the receiver's mask if necessary.
 */
void createMask() {
	if (OS.USE_CAIRO) {
		int width = this.width;
		int height = this.height;
		int stride = Cairo.cairo_image_surface_get_stride(surface);
		long /*int*/ surfaceData = Cairo.cairo_image_surface_get_data(surface);
		int oa, or, og, ob, tr, tg, tb;
		if (OS.BIG_ENDIAN) {
			oa = 0; or = 1; og = 2; ob = 3;
			tr = (transparentPixel >> 24) & 0xFF;
			tg = (transparentPixel >> 16) & 0xFF;
			tb = (transparentPixel >> 8) & 0xFF;
		} else {
			oa = 3; or = 2; og = 1; ob = 0;
			tr = (transparentPixel >> 16) & 0xFF;
			tg = (transparentPixel >> 8) & 0xFF;
			tb = (transparentPixel >> 0) & 0xFF;
		}
		byte[] srcData = new byte[stride * height];
		OS.memmove(srcData, surfaceData, srcData.length);
		int offset = 0;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++, offset += 4) {
				int a = srcData[offset + oa] & 0xFF;
				int r = srcData[offset + or] & 0xFF;
				int g = srcData[offset + og] & 0xFF;
				int b = srcData[offset + ob] & 0xFF;
				if (r == tr && g == tg && b == tb) {
					a = r = g = b = 0;
				} else {
					a = 0xff;
				}
				srcData[offset + oa] = (byte)a;
				srcData[offset + or] = (byte)r;
				srcData[offset + og] = (byte)g;
				srcData[offset + ob] = (byte)b;
			}
		}
		OS.memmove(surfaceData, srcData, srcData.length);
		return;
	}
	if (mask != 0) return;
	mask = createMask(getImageData(), false);
	if (mask == 0) SWT.error(SWT.ERROR_NO_HANDLES);
}

long /*int*/ createMask(ImageData image, boolean copy) {
	ImageData mask = image.getTransparencyMask();
	byte[] data = mask.data;
	byte[] maskData = copy ? new byte[data.length] : data;
	for (int i = 0; i < maskData.length; i++) {
		byte s = data[i];
		maskData[i] = (byte)(((s & 0x80) >> 7) | ((s & 0x40) >> 5) |
			((s & 0x20) >> 3) | ((s & 0x10) >> 1) | ((s & 0x08) << 1) |
			((s & 0x04) << 3) | ((s & 0x02) << 5) |	((s & 0x01) << 7));
	}
	maskData = ImageData.convertPad(maskData, mask.width, mask.height, mask.depth, mask.scanlinePad, 1);
	return OS.gdk_bitmap_create_from_data(0, maskData, mask.width, mask.height);
}

void createSurface() {
	if (surface != 0) return;
	/* There is no pixmaps in GTK 3. */
	if (OS.GTK3) return;
	/* Generate the mask if necessary. */
	if (transparentPixel != -1) createMask();
	int[] w = new int[1], h = new int[1];
	if (OS.GTK_VERSION >= OS.VERSION(2, 24, 0)) {
		OS.gdk_pixmap_get_size(pixmap, w, h);
	} else {
		OS.gdk_drawable_get_size(pixmap, w, h);
	}
	int width = w[0], height = h[0];
	this.width = width;
	this.height = height;
	if (mask != 0 || alpha != -1 || alphaData != null) {
	 	long /*int*/ pixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, true, 8, width, height);
		if (pixbuf == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		long /*int*/ colormap = OS.gdk_colormap_get_system();
		OS.gdk_pixbuf_get_from_drawable(pixbuf, pixmap, colormap, 0, 0, 0, 0, width, height);
		int stride = OS.gdk_pixbuf_get_rowstride(pixbuf);
		long /*int*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf);
		byte[] line = new byte[stride];
		int oa, or, og, ob;
		if (OS.BIG_ENDIAN) {
			oa = 0; or = 1; og = 2; ob = 3;
		} else {
			oa = 3; or = 2; og = 1; ob = 0;
		}
		if (mask != 0 && OS.gdk_drawable_get_depth(mask) == 1) {
			long /*int*/ maskPixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, false, 8, width, height);
			if (maskPixbuf == 0) SWT.error(SWT.ERROR_NO_HANDLES);
			OS.gdk_pixbuf_get_from_drawable(maskPixbuf, mask, 0, 0, 0, 0, 0, width, height);
			int maskStride = OS.gdk_pixbuf_get_rowstride(maskPixbuf);
			long /*int*/ maskPixels = OS.gdk_pixbuf_get_pixels(maskPixbuf);
			byte[] maskLine = new byte[maskStride];
			long /*int*/ offset = pixels, maskOffset = maskPixels;
			for (int y=0; y<height; y++) {
				OS.memmove(line, offset, stride);
				OS.memmove(maskLine, maskOffset, maskStride);
				for (int x=0, offset1=0; x<width; x++, offset1 += 4) {
					if (maskLine[x * 3] == 0) {
						line[offset1 + 0] = line[offset1 + 1] = line[offset1 + 2] = line[offset1 + 3] = 0;
					} else {
						byte r = line[offset1 + 0];
						byte g = line[offset1 + 1];
						byte b = line[offset1 + 2];
						line[offset1 + oa] = (byte)0xFF;
						line[offset1 + or] = r;
						line[offset1 + og] = g;
						line[offset1 + ob] = b;
					}
				}
				OS.memmove(offset, line, stride);
				offset += stride;
				maskOffset += maskStride;
			}
			OS.g_object_unref(maskPixbuf);
		} else if (alpha != -1) {
			long /*int*/ offset = pixels;
			for (int y=0; y<height; y++) {
				OS.memmove(line, offset, stride);
				for (int x=0, offset1=0; x<width; x++, offset1 += 4) {
					/* pre-multiplied alpha */
					int r = ((line[offset1 + 0] & 0xFF) * alpha) + 128;
					r = (r + (r >> 8)) >> 8;
					int g = ((line[offset1 + 1] & 0xFF) * alpha) + 128;
					g = (g + (g >> 8)) >> 8;
					int b = ((line[offset1 + 2] & 0xFF) * alpha) + 128;
					b = (b + (b >> 8)) >> 8;
					line[offset1 + oa] = (byte)alpha;
					line[offset1 + or] = (byte)r;
					line[offset1 + og] = (byte)g;
					line[offset1 + ob] = (byte)b;
				}
				OS.memmove(offset, line, stride);
				offset += stride;
			}
		} else if (alphaData != null) {
			long /*int*/ offset = pixels;
			for (int y = 0; y < h [0]; y++) {
				OS.memmove (line, offset, stride);
				for (int x=0, offset1=0; x<width; x++, offset1 += 4) {
					int alpha = alphaData [y*w [0]+x] & 0xFF;
					/* pre-multiplied alpha */
					int r = ((line[offset1 + 0] & 0xFF) * alpha) + 128;
					r = (r + (r >> 8)) >> 8;
					int g = ((line[offset1 + 1] & 0xFF) * alpha) + 128;
					g = (g + (g >> 8)) >> 8;
					int b = ((line[offset1 + 2] & 0xFF) * alpha) + 128;
					b = (b + (b >> 8)) >> 8;
					line[offset1 + oa] = (byte)alpha;
					line[offset1 + or] = (byte)r;
					line[offset1 + og] = (byte)g;
					line[offset1 + ob] = (byte)b;
				}
				OS.memmove (offset, line, stride);
				offset += stride;
			}
		} else {
			long /*int*/ offset = pixels;
			for (int y = 0; y < h [0]; y++) {
				OS.memmove (line, offset, stride);
				for (int x=0, offset1=0; x<width; x++, offset1 += 4) {
					byte r = line[offset1 + 0];
					byte g = line[offset1 + 1];
					byte b = line[offset1 + 2];
					line[offset1 + oa] = (byte)0xFF;
					line[offset1 + or] = r;
					line[offset1 + og] = g;
					line[offset1 + ob] = b;
				}
				OS.memmove (offset, line, stride);
				offset += stride;
			}
		}
		surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_ARGB32, width, height);
		long /*int*/ data = Cairo.cairo_image_surface_get_data(surface);
		OS.memmove(data, pixels, stride * height);
		Cairo.cairo_surface_mark_dirty(surface);
		OS.g_object_unref(pixbuf);
	} else {
		long /*int*/ xDisplay = OS.gdk_x11_display_get_xdisplay(OS.gdk_display_get_default());
		long /*int*/ xDrawable = OS.GDK_PIXMAP_XID(pixmap);
		long /*int*/ xVisual = OS.gdk_x11_visual_get_xvisual(OS.gdk_visual_get_system());
		surface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, width, height);
	}
	/* Destroy the image mask if the there is a GC created on the image */
	if (transparentPixel != -1 && memGC != null) destroyMask();
}

/**
 * Destroy the receiver's mask if it exists.
 */
void destroyMask() {
	if (mask == 0) return;
	OS.g_object_unref(mask);
	mask = 0;
}

@Override
void destroy() {
	if (memGC != null) memGC.dispose();
	if (pixmap != 0) OS.g_object_unref(pixmap);
	if (mask != 0) OS.g_object_unref(mask);
	if (surface != 0) Cairo.cairo_surface_destroy(surface);
	surface = pixmap = mask = 0;
	memGC = 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
 */
@Override
public boolean equals (Object object) {
	if (object == this) return true;
	if (!(object instanceof Image)) return false;
	Image image = (Image)object;
	if (device != image.device || transparentPixel != image.transparentPixel) return false;
	if (imageDataProvider != null && image.imageDataProvider != null) {
		return imageDataProvider.equals (image.imageDataProvider);
	} else if (imageFileNameProvider != null && image.imageFileNameProvider != null) {
		return imageFileNameProvider.equals (image.imageFileNameProvider);
	} else if (OS.USE_CAIRO) {
		return surface == image.surface;
	} else {
		return pixmap == image.pixmap;
	}
}

/**
 * Returns the color to which to map the transparent pixel, or null if
 * the receiver has no transparent pixel.
 * <p>
 * There are certain uses of Images that do not support transparency
 * (for example, setting an image into a button or label). In these cases,
 * it may be desired to simulate transparency by using the background
 * color of the widget to paint the transparent pixels of the image.
 * Use this method to check which color will be used in these cases
 * in place of transparency. This value may be set with setBackground().
 * <p>
 *
 * @return the background color of the image, or null if there is no transparency in the image
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Color getBackground() {
	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (transparentPixel == -1) return null;
	//NOT DONE
	return null;
}

/**
 * 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);
	if (width != -1 && height != -1) {
		return new Rectangle(0, 0, width, height);
	}
	int[] w = new int[1]; int[] h = new int[1];
	if (OS.GTK_VERSION >= OS.VERSION(2, 24, 0)) {
		OS.gdk_pixmap_get_size(pixmap, w, h);
	} else {
		OS.gdk_drawable_get_size(pixmap, w, h);
	}
	return new Rectangle(0, 0, width = w[0], height = h[0]);
}

/**
 * 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);

	if (OS.USE_CAIRO) {
		long /*int*/ surface = ImageList.convertSurface(this);
		int format = Cairo.cairo_image_surface_get_format(surface);
		int width = Cairo.cairo_image_surface_get_width(surface);
		int height = Cairo.cairo_image_surface_get_height(surface);
		int stride = Cairo.cairo_image_surface_get_stride(surface);
		long /*int*/ surfaceData = Cairo.cairo_image_surface_get_data(surface);
		boolean hasAlpha = format == Cairo.CAIRO_FORMAT_ARGB32;
		int oa, or, og, ob;
		if (OS.BIG_ENDIAN) {
			oa = 0; or = 1; og = 2; ob = 3;
		} else {
			oa = 3; or = 2; og = 1; ob = 0;
		}
		byte[] srcData = new byte[stride * height];
		OS.memmove(srcData, surfaceData, srcData.length);
		PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF);
		ImageData data = new ImageData(width, height, 32, palette, 4, srcData);
		if (hasAlpha) {
			byte[] alphaData = data.alphaData = new byte[width * height];
			for (int y = 0, offset = 0, alphaOffset = 0; y < height; y++) {
				for (int x = 0; x < width; x++, offset += 4) {
					int a = srcData[offset + oa] & 0xFF;
					int r = srcData[offset + or] & 0xFF;
					int g = srcData[offset + og] & 0xFF;
					int b = srcData[offset + ob] & 0xFF;
					srcData[offset + 0] = 0;
					alphaData[alphaOffset++] = (byte)a;
					if (a != 0) {
						srcData[offset + 1] = (byte)(((r * 0xFF) + a / 2) / a);
						srcData[offset + 2] = (byte)(((g * 0xFF) + a / 2) / a);
						srcData[offset + 3] = (byte)(((b * 0xFF) + a / 2) / a);
					}
				}
			}
		} else {
			for (int y = 0, offset = 0; y < height; y++) {
				for (int x = 0; x < width; x++, offset += 4) {
					byte r = srcData[offset + or];
					byte g = srcData[offset + og];
					byte b = srcData[offset + ob];
					srcData[offset + 0] = 0;
					srcData[offset + 1] = r;
					srcData[offset + 2] = g;
					srcData[offset + 3] = b;
				}
			}
		}
		Cairo.cairo_surface_destroy(surface);
		return data;
	}
	int[] w = new int[1], h = new int[1];
	if (OS.GTK_VERSION >= OS.VERSION(2, 24, 0)) {
		OS.gdk_pixmap_get_size(pixmap, w, h);
	} else {
		OS.gdk_drawable_get_size(pixmap, w, h);
	}
 	int width = w[0], height = h[0];
 	long /*int*/ pixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, false, 8, width, height);
	if (pixbuf == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	long /*int*/ colormap = OS.gdk_colormap_get_system();
	OS.gdk_pixbuf_get_from_drawable(pixbuf, pixmap, colormap, 0, 0, 0, 0, width, height);
	int stride = OS.gdk_pixbuf_get_rowstride(pixbuf);
	long /*int*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf);
	byte[] srcData = new byte[stride * height];
	OS.memmove(srcData, pixels, srcData.length);
	OS.g_object_unref(pixbuf);

	PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF);
	ImageData data = new ImageData(width, height, 24, palette, 4, srcData);
	data.bytesPerLine = stride;

	if (transparentPixel == -1 && type == SWT.ICON && mask != 0) {
		/* Get the icon mask data */
		long /*int*/ gdkImagePtr = OS.gdk_drawable_get_image(mask, 0, 0, width, height);
		if (gdkImagePtr == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		GdkImage gdkImage = new GdkImage();
		OS.memmove(gdkImage, gdkImagePtr);
		byte[] maskData = new byte[gdkImage.bpl * gdkImage.height];
		OS.memmove(maskData, gdkImage.mem, maskData.length);
		OS.g_object_unref(gdkImagePtr);
		int maskPad;
		for (maskPad = 1; maskPad < 128; maskPad++) {
			int bpl = (((width + 7) / 8) + (maskPad - 1)) / maskPad * maskPad;
			if (gdkImage.bpl == bpl) break;
		}
		/* Make mask scanline pad equals to 2 */
		data.maskPad = 2;
		maskData = ImageData.convertPad(maskData, width, height, 1, maskPad, data.maskPad);
		/* Bit swap the mask data if necessary */
		if (gdkImage.byte_order == OS.GDK_LSB_FIRST) {
			for (int i = 0; i < maskData.length; i++) {
				byte b = maskData[i];
				maskData[i] = (byte)(((b & 0x01) << 7) | ((b & 0x02) << 5) |
					((b & 0x04) << 3) |	((b & 0x08) << 1) | ((b & 0x10) >> 1) |
					((b & 0x20) >> 3) |	((b & 0x40) >> 5) | ((b & 0x80) >> 7));
			}
		}
		data.maskData = maskData;
	}
	data.transparentPixel = transparentPixel;
	data.alpha = alpha;
	if (alpha == -1 && alphaData != null) {
		data.alphaData = new byte[alphaData.length];
		System.arraycopy(alphaData, 0, data.alphaData, 0, alphaData.length);
	}
	return data;
}

/**
 * Invokes platform specific functionality to allocate a new image.
 * <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 device the device on which to allocate the color
 * @param type the type of the image (<code>SWT.BITMAP</code> or <code>SWT.ICON</code>)
 * @param imageHandle the OS handle for the image
 * @param mask the OS handle for the image mask
 *
 * @noreference This method is not intended to be referenced by clients.
 */
public static Image gtk_new(Device device, int type, long /*int*/ imageHandle, long /*int*/ mask) {
	Image image = new Image(device);
	image.type = type;
	if (OS.GTK3) {
		image.surface = imageHandle;
	} else {
		image.pixmap = imageHandle;
		if (OS.USE_CAIRO) image.createSurface();
	}
	image.mask = mask;
	return image;
}

/**
 * Invokes platform specific functionality to allocate a new image.
 * <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 device the device on which to allocate the color
 * @param type the type of the image (<code>SWT.BITMAP</code> or <code>SWT.ICON</code>)
 * @param pixbuf an GdkPixbuf
 *
 * @noreference This method is not intended to be referenced by clients.
 */
public static Image gtk_new_from_pixbuf(Device device, int type, long /*int*/ pixbuf) {
	Image image = new Image(device);
	image.createFromPixbuf(type, pixbuf);
	image.type = type;
	return image;
}

/**
 * Returns an integer hash code for the receiver. Any two
 * objects that 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
 */
@Override
public int hashCode () {
	if (imageDataProvider != null) {
		return imageDataProvider.hashCode();
	} else if (imageFileNameProvider != null) {
		 return imageFileNameProvider.hashCode();
	} else if (OS.USE_CAIRO) {
		return (int)/*64*/surface;
	} else {
		return (int)/*64*/pixmap;
	}
}

void init(int width, int height) {
	if (width <= 0 || height <= 0) {
		SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	}
	this.type = SWT.BITMAP;

	/* Create the pixmap */
	if (OS.USE_CAIRO) {
		if (OS.GTK_VERSION >= OS.VERSION(2, 22, 0)) {
			surface = OS.gdk_window_create_similar_surface(OS.gdk_get_default_root_window(), Cairo.CAIRO_CONTENT_COLOR, width, height);
		} else {
			long /*int*/ xDisplay = OS.gdk_x11_display_get_xdisplay(OS.gdk_display_get_default());
			long /*int*/ xDrawable = OS.gdk_x11_drawable_get_xid(OS.gdk_get_default_root_window());
			long /*int*/ xVisual = OS.gdk_x11_visual_get_xvisual(OS.gdk_visual_get_system());
			long /*int*/ rootSurface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, 1, 1);
			if (rootSurface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
			surface = Cairo.cairo_surface_create_similar(rootSurface, Cairo.CAIRO_CONTENT_COLOR, width, height);
			Cairo.cairo_surface_destroy(rootSurface);
		}
		if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		long /*int*/ cairo = Cairo.cairo_create(surface);
		if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		Cairo.cairo_set_source_rgb(cairo, 1, 1, 1);
		Cairo.cairo_rectangle(cairo, 0, 0, width, height);
		Cairo.cairo_fill(cairo);
		Cairo.cairo_destroy(cairo);
		this.width = width;
		this.height = height;
		return;
	}
	this.pixmap = OS.gdk_pixmap_new(OS.gdk_get_default_root_window(), width, height, -1);
	if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	/* Fill the bitmap with white */
	GdkColor white = new GdkColor();
	white.red = (short)0xFFFF;
	white.green = (short)0xFFFF;
	white.blue = (short)0xFFFF;
	long /*int*/ colormap = OS.gdk_colormap_get_system();
	OS.gdk_colormap_alloc_color(colormap, white, true, true);
	long /*int*/ gdkGC = OS.gdk_gc_new(pixmap);
	OS.gdk_gc_set_foreground(gdkGC, white);
	OS.gdk_draw_rectangle(pixmap, gdkGC, 1, 0, 0, width, height);
	OS.g_object_unref(gdkGC);
	OS.gdk_colormap_free_colors(colormap, white, 1);
}

void init(ImageData image) {
	if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	int width = this.width = image.width;
	int height = this.height = image.height;
	PaletteData palette = image.palette;
	if (!(((image.depth == 1 || image.depth == 2 || image.depth == 4 || image.depth == 8) && !palette.isDirect) ||
		((image.depth == 8) || (image.depth == 16 || image.depth == 24 || image.depth == 32) && palette.isDirect)))
			SWT.error (SWT.ERROR_UNSUPPORTED_DEPTH);
	if (OS.USE_CAIRO) {
		boolean hasAlpha = image.transparentPixel != -1 || image.alpha != -1 || image.maskData != null || image.alphaData != null;
		int format = hasAlpha ? Cairo.CAIRO_FORMAT_ARGB32 : Cairo.CAIRO_FORMAT_RGB24;
		surface = Cairo.cairo_image_surface_create(format, width, height);
		if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		int stride = Cairo.cairo_image_surface_get_stride(surface);
		long /*int*/ data = Cairo.cairo_image_surface_get_data(surface);
		int oa = 0, or = 0, og = 0, ob = 0;
		int redMask, greenMask, blueMask, destDepth = 32, destOrder;
		if (OS.BIG_ENDIAN) {
			oa = 0; or = 1; og = 2; ob = 3;
			redMask = 0xFF00;
			greenMask = 0xFF0000;
			blueMask = 0xFF000000;
			destOrder = ImageData.MSB_FIRST;
		} else {
			oa = 3; or = 2; og = 1; ob = 0;
			redMask = 0xFF0000;
			greenMask = 0xFF00;
			blueMask = 0xFF;
			destOrder = ImageData.LSB_FIRST;
		}
		byte[] buffer = image.data;
		if (!palette.isDirect || image.depth != destDepth || stride != image.bytesPerLine || palette.redMask != redMask || palette.greenMask != greenMask || palette.blueMask != blueMask || destOrder != image.getByteOrder()) {
			buffer = new byte[stride * height];
			if (palette.isDirect) {
				ImageData.blit(ImageData.BLIT_SRC,
					image.data, image.depth, image.bytesPerLine, image.getByteOrder(), 0, 0, width, height, palette.redMask, palette.greenMask, palette.blueMask,
					ImageData.ALPHA_OPAQUE, null, 0, 0, 0,
					buffer, destDepth, stride, destOrder, 0, 0, width, height, redMask, greenMask, blueMask,
					false, false);
			} else {
				RGB[] rgbs = palette.getRGBs();
				int length = rgbs.length;
				byte[] srcReds = new byte[length];
				byte[] srcGreens = new byte[length];
				byte[] srcBlues = new byte[length];
				for (int i = 0; i < rgbs.length; i++) {
					RGB rgb = rgbs[i];
					if (rgb == null) continue;
					srcReds[i] = (byte)rgb.red;
					srcGreens[i] = (byte)rgb.green;
					srcBlues[i] = (byte)rgb.blue;
				}
				ImageData.blit(ImageData.BLIT_SRC,
					image.data, image.depth, image.bytesPerLine, image.getByteOrder(), 0, 0, width, height, srcReds, srcGreens, srcBlues,
					ImageData.ALPHA_OPAQUE, null, 0, 0, 0,
					buffer, destDepth, stride, destOrder, 0, 0, width, height, redMask, greenMask, blueMask,
					false, false);
			}
		}
		boolean isIcon = image.getTransparencyType() == SWT.TRANSPARENCY_MASK;
		this.type = isIcon ? SWT.ICON : SWT.BITMAP;
		if (isIcon || image.transparentPixel != -1) {
			if (image.transparentPixel != -1) {
				RGB rgb = null;
				if (palette.isDirect) {
					rgb = palette.getRGB(image.transparentPixel);
				} else {
					if (image.transparentPixel < palette.colors.length) {
						rgb = palette.getRGB(image.transparentPixel);
					}
				}
				if (rgb != null) {
					transparentPixel = rgb.red << 16 | rgb.green << 8 | rgb.blue;
				}
			}
			ImageData mask = image.getTransparencyMask();
			for (int y = 0, offset = 0; y < height; y++) {
				for (int x=0; x<width; x++, offset += 4) {
					int alpha = mask.getPixel(x, y) == 0 ? 0 : 0xff;
					/* pre-multiplied alpha */
					int r = ((buffer[offset + or] & 0xFF) * alpha) + 128;
					r = (r + (r >> 8)) >> 8;
					int g = ((buffer[offset + og] & 0xFF) * alpha) + 128;
					g = (g + (g >> 8)) >> 8;
					int b = ((buffer[offset + ob] & 0xFF) * alpha) + 128;
					b = (b + (b >> 8)) >> 8;
					buffer[offset + oa] = (byte)alpha;
					buffer[offset + or] = (byte)r;
					buffer[offset + og] = (byte)g;
					buffer[offset + ob] = (byte)b;
				}
			}
		} else {
			this.alpha = image.alpha;
			if (image.alpha == -1 && image.alphaData != null) {
				this.alphaData = new byte[image.alphaData.length];
				System.arraycopy(image.alphaData, 0, this.alphaData, 0, alphaData.length);
			}
			if (this.alpha != -1) {
				for (int y = 0, offset = 0; y < height; y++) {
					for (int x=0; x<width; x++, offset += 4) {
						int alpha = this.alpha;
						/* pre-multiplied alpha */
						int r = ((buffer[offset + or] & 0xFF) * alpha) + 128;
						r = (r + (r >> 8)) >> 8;
						int g = ((buffer[offset + og] & 0xFF) * alpha) + 128;
						g = (g + (g >> 8)) >> 8;
						int b = ((buffer[offset + ob] & 0xFF) * alpha) + 128;
						b = (b + (b >> 8)) >> 8;
						buffer[offset + oa] = (byte)alpha;
						buffer[offset + or] = (byte)r;
						buffer[offset + og] = (byte)g;
						buffer[offset + ob] = (byte)b;
					}
				}
			} else if (this.alphaData != null) {
				for (int y = 0, offset = 0; y < height; y++) {
					for (int x=0; x<width; x++, offset += 4) {
						int alpha = alphaData [y*width+x] & 0xFF;
						/* pre-multiplied alpha */
						int r = ((buffer[offset + or] & 0xFF) * alpha) + 128;
						r = (r + (r >> 8)) >> 8;
						int g = ((buffer[offset + og] & 0xFF) * alpha) + 128;
						g = (g + (g >> 8)) >> 8;
						int b = ((buffer[offset + ob] & 0xFF) * alpha) + 128;
						b = (b + (b >> 8)) >> 8;
						buffer[offset + oa] = (byte)alpha;
						buffer[offset + or] = (byte)r;
						buffer[offset + og] = (byte)g;
						buffer[offset + ob] = (byte)b;
					}
				}
			}
		}
		OS.memmove(data, buffer, stride * height);
		Cairo.cairo_surface_mark_dirty(surface);
		//TODO convert to XLIB surface if opaque for better performance
		return;
	}
	long /*int*/ pixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, false, 8, width, height);
	if (pixbuf == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	int stride = OS.gdk_pixbuf_get_rowstride(pixbuf);
	long /*int*/ data = OS.gdk_pixbuf_get_pixels(pixbuf);
	byte[] buffer = image.data;
	if (!palette.isDirect || image.depth != 24 || stride != image.bytesPerLine || palette.redMask != 0xFF0000 || palette.greenMask != 0xFF00 || palette.blueMask != 0xFF) {
		buffer = new byte[stride * height];
		if (palette.isDirect) {
			ImageData.blit(ImageData.BLIT_SRC,
				image.data, image.depth, image.bytesPerLine, image.getByteOrder(), 0, 0, width, height, palette.redMask, palette.greenMask, palette.blueMask,
				ImageData.ALPHA_OPAQUE, null, 0, 0, 0,
				buffer, 24, stride, ImageData.MSB_FIRST, 0, 0, width, height, 0xFF0000, 0xFF00, 0xFF,
				false, false);
		} else {
			RGB[] rgbs = palette.getRGBs();
			int length = rgbs.length;
			byte[] srcReds = new byte[length];
			byte[] srcGreens = new byte[length];
			byte[] srcBlues = new byte[length];
			for (int i = 0; i < rgbs.length; i++) {
				RGB rgb = rgbs[i];
				if (rgb == null) continue;
				srcReds[i] = (byte)rgb.red;
				srcGreens[i] = (byte)rgb.green;
				srcBlues[i] = (byte)rgb.blue;
			}
			ImageData.blit(ImageData.BLIT_SRC,
				image.data, image.depth, image.bytesPerLine, image.getByteOrder(), 0, 0, width, height, srcReds, srcGreens, srcBlues,
				ImageData.ALPHA_OPAQUE, null, 0, 0, 0,
				buffer, 24, stride, ImageData.MSB_FIRST, 0, 0, width, height, 0xFF0000, 0xFF00, 0xFF,
				false, false);
		}
	}
	OS.memmove(data, buffer, stride * height);
	long /*int*/ pixmap = OS.gdk_pixmap_new (OS.gdk_get_default_root_window(), width, height, -1);
	if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	long /*int*/ gdkGC = OS.gdk_gc_new(pixmap);
	if (gdkGC == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	OS.gdk_pixbuf_render_to_drawable(pixbuf, pixmap, gdkGC, 0, 0, 0, 0, width, height, OS.GDK_RGB_DITHER_NORMAL, 0, 0);
	OS.g_object_unref(gdkGC);
	OS.g_object_unref(pixbuf);

	boolean isIcon = image.getTransparencyType() == SWT.TRANSPARENCY_MASK;
	if (isIcon || image.transparentPixel != -1) {
		if (image.transparentPixel != -1) {
			RGB rgb = null;
			if (palette.isDirect) {
				rgb = palette.getRGB(image.transparentPixel);
			} else {
				if (image.transparentPixel < palette.colors.length) {
					rgb = palette.getRGB(image.transparentPixel);
				}
			}
			if (rgb != null) {
				transparentPixel = rgb.red << 16 | rgb.green << 8 | rgb.blue;
			}
		}
		long /*int*/ mask = createMask(image, isIcon);
		if (mask == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		this.mask = mask;
		if (isIcon) {
			this.type = SWT.ICON;
		} else {
			this.type = SWT.BITMAP;
		}
	} else {
		this.type = SWT.BITMAP;
		this.mask = 0;
		this.alpha = image.alpha;
		if (image.alpha == -1 && image.alphaData != null) {
			this.alphaData = new byte[image.alphaData.length];
			System.arraycopy(image.alphaData, 0, this.alphaData, 0, alphaData.length);
		}
		createAlphaMask(width, height);
	}
	this.pixmap = pixmap;
}

/**
 * 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
 *
 * @noreference This method is not intended to be referenced by clients.
 */
public long /*int*/ internal_new_GC (GCData data) {
	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (type != SWT.BITMAP || memGC != null) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	long /*int*/ gc;
	if (OS.USE_CAIRO) {
		gc = Cairo.cairo_create(surface);
	} else {
		gc = OS.gdk_gc_new(pixmap);
	}
	if (data != null) {
		int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
		if ((data.style & mask) == 0) {
			data.style |= SWT.LEFT_TO_RIGHT;
		} else {
			if ((data.style & SWT.RIGHT_TO_LEFT) != 0) {
				data.style |= SWT.MIRRORED;
			}
		}
		data.device = device;
		data.drawable = pixmap;
		data.background = device.COLOR_WHITE.handle;
		data.foreground = device.COLOR_BLACK.handle;
		data.font = device.systemFont;
		data.image = this;
	}
	return gc;
}

/**
 * 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
 *
 * @noreference This method is not intended to be referenced by clients.
 */
public void internal_dispose_GC (long /*int*/ hDC, GCData data) {
	long /*int*/ gc = hDC;
	if (OS.USE_CAIRO) {
		Cairo.cairo_destroy(gc);
	} else {
		OS.g_object_unref(gc);
	}
}

/**
 * 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 (except {@link #dispose()}) using the image.
 *
 * @return <code>true</code> when the image is disposed and <code>false</code> otherwise
 */
@Override
public boolean isDisposed() {
	if (OS.USE_CAIRO) {
		return surface == 0;
	} else {
		return pixmap == 0;
	}
}

/**
 * Sets the color to which to map the transparent pixel.
 * <p>
 * There are certain uses of <code>Images</code> that do not support
 * transparency (for example, setting an image into a button or label).
 * In these cases, it may be desired to simulate transparency by using
 * the background color of the widget to paint the transparent pixels
 * of the image. This method specifies the color that will be used in
 * these cases. For example:
 * <pre>
 *    Button b = new Button();
 *    image.setBackground(b.getBackground());
 *    b.setImage(image);
 * </pre>
 * </p><p>
 * The image may be modified by this operation (in effect, the
 * transparent regions may be filled with the supplied color).  Hence
 * this operation is not reversible and it is not legal to call
 * this function twice or with a null argument.
 * </p><p>
 * This method has no effect if the receiver does not have a transparent
 * pixel value.
 * </p>
 *
 * @param color the color to use when a transparent pixel is specified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the color is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setBackground(Color color) {
	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (color == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	if (transparentPixel == -1) return;
	//NOT DONE
}

/**
 * Returns a string containing a concise, human-readable
 * description of the receiver.
 *
 * @return a string representation of the receiver
 */
@Override
public String toString () {
	if (isDisposed()) return "Image {*DISPOSED*}";
	if (OS.USE_CAIRO) {
		return "Image {" + surface + "}";
	} else {
		return "Image {" + pixmap + "}";
	}
}

}
