package org.eclipse.swt.graphics;

/*
 * Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
 * This file is made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 */

import org.eclipse.swt.internal.carbon.*;
import org.eclipse.swt.*;
import java.io.*;

/**
 * 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 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
 * @see ImageLoader
 */
public final class Image implements Drawable {

    static class XImage {
        int byte_order= OS.MSBFirst;
		int bitmap_bit_order= OS.MSBFirst;
        int depth;
        int width;
        int height;
        int bits_per_pixel;
        int bytes_per_line;
		int red_mask;
		int green_mask;
		int blue_mask;
		
        XImage(int w, int h, int d) {
			width= w;
			height= h;
			depth= d;
			bits_per_pixel= d;
			bytes_per_line= (((width*depth-1)/(8*DEFAULT_SCANLINE_PAD))+1)*DEFAULT_SCANLINE_PAD;
			switch (d) {
			case 16:
				red_mask= 0x7C00;
				green_mask= 0x03E0;
				blue_mask= 0x001F;
				break;
			case 24:
			case 32:
				red_mask= 0xff0000;
				green_mask= 0x00ff00;
				blue_mask= 0x0000ff;
				break;
			default:
				break;
			}
        }
    }
	
	static class XColor {
		short red;
		short green;
		short blue;
	}
	
	/**
	 * 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 pixmap resource.
	 * Warning: This field is platform dependent.
	 */
	public int pixmap;

	/**
	 * The handle to the OS mask resource.
	 * Warning: This field is platform dependent.
	 */
	public int mask;

	/**
	 * The device where this image was created.
	 */
	Device device;

	/**
	 * specifies the transparent pixel
	 * (Warning: This field is platform dependent)
	 */
	int transparentPixel = -1;

	/**
	 * The GC the image is currently selected in.
	 * Warning: This field is platform dependent.
	 */
	GC memGC;

	/**
	 * The alpha data of the image.
	 * Warning: This field is platform dependent.
	 */
	byte[] alphaData;

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

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) {
	init(device, width, height);
}
/**
 * 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>IMAGE_COPY</b></dt>
 * <dd>the result is an identical copy of srcImage</dd>
 * <dt><b>IMAGE_DISABLE</b></dt>
 * <dd>the result is a copy of srcImage which has a <em>disabled</em> look</dd>
 * <dt><b>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>
 * </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) {
	if (device == null) device = Device.getDevice();
	if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	this.device = device;
	if (srcImage == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (srcImage.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	
	// AW
	//if (flag == SWT.IMAGE_DISABLE)
		flag= SWT.IMAGE_COPY;
	// AW
		
	int xDisplay = device.xDisplay;
	this.type = srcImage.type;
	this.mask = 0;
	MacRect bounds= new MacRect();
	OS.GetPixBounds(srcImage.pixmap, bounds.getData());
 	int width = bounds.getWidth();
 	int height = bounds.getHeight();

	/* Don't create the mask here if flag is SWT.IMAGE_GRAY. See below.*/
	if (flag != SWT.IMAGE_GRAY && srcImage.mask != 0) {
		/* Generate the mask if necessary. */
		if (srcImage.transparentPixel != -1) srcImage.createMask();
        /* AW
		int mask = OS.XCreatePixmap(xDisplay, drawable, width, height, 1);
		int gc = OS.XCreateGC(xDisplay, mask, 0, null);
		OS.XCopyArea(xDisplay, srcImage.mask, mask, gc, 0, 0, width, height, 0, 0);
		OS.XFreeGC(xDisplay, gc);
		*/
		this.mask = OS.duplicatePixMap(srcImage.mask);
		/* Destroy the image mask if the there is a GC created on the image */
		if (srcImage.transparentPixel != -1 && srcImage.memGC != null) srcImage.destroyMask();
	}
	switch (flag) {
		case SWT.IMAGE_COPY:
            /* AW
			int[] depth = new int[1];
			OS.XGetGeometry(xDisplay, srcImage.pixmap, unused, unused, unused, unused, unused, unused, depth);
			int pixmap = OS.XCreatePixmap(xDisplay, drawable, width, height, depth[0]);
			int gc = OS.XCreateGC(xDisplay, pixmap, 0, null);
			OS.XCopyArea(xDisplay, srcImage.pixmap, pixmap, gc, 0, 0, width, height, 0, 0);
			OS.XFreeGC(xDisplay, gc);
			*/
			this.pixmap = OS.duplicatePixMap(srcImage.pixmap);
			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);
			}
			return;
		case SWT.IMAGE_DISABLE:
			/* Get src image data */
			XImage srcXImage = new XImage(width, height, OS.GetPixDepth(srcImage.pixmap));
            /* AW
			int srcXImagePtr = OS.XGetImage(xDisplay, srcImage.pixmap, 0, 0, width, height, OS.AllPlanes, OS.ZPixmap);
			OS.memmove(srcXImage, srcXImagePtr, XImage.sizeof);
			*/
			byte[] srcData = new byte[srcXImage.bytes_per_line * srcXImage.height];
			/* AW
			OS.memmove(srcData, srcXImage.data, srcData.length);
            */
			/* Create destination image */
            /* AW
			int destPixmap = OS.XCreatePixmap(xDisplay, drawable, width, height, srcXImage.depth);
			*/
			int destPixmap = OS.NewPixMap((short)width, (short)height, (short)srcXImage.depth, (short)4, null, null, null);			
			XImage destXImage = new XImage(width, height, srcXImage.depth);
			/* AW
			int destXImagePtr = OS.XGetImage(xDisplay, drawable, 0, 0, width, height, OS.AllPlanes, OS.ZPixmap);
			OS.memmove(destXImage, destXImagePtr, XImage.sizeof);
			*/
			byte[] destData = new byte[destXImage.bytes_per_line * destXImage.height];
			/* Find the colors to map to */
			Color zeroColor = device.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
			Color oneColor = device.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
			/* AW
			int zeroPixel = zeroColor.handle.pixel;
			int onePixel = oneColor.handle.pixel;
			*/
			int zeroPixel = 0;
			int onePixel = 1;

			switch (srcXImage.bits_per_pixel) {
				case 1:
					/*
					 * Nothing we can reasonably do here except copy
					 * the bitmap; we can't make it a higher color depth.
					 * Short-circuit the rest of the code and return.
					 */
                    /* AW
					gc = OS.XCreateGC(xDisplay, drawable, 0, null);
					pixmap = OS.XCreatePixmap(xDisplay, drawable, width, height, 1);
					OS.XCopyArea(xDisplay, srcImage.pixmap, pixmap, gc, 0, 0, width, height, 0, 0);
					*/
					pixmap = OS.duplicatePixMap(srcImage.pixmap);
					/* AW
					OS.XDestroyImage(srcXImagePtr);
					OS.XDestroyImage(destXImagePtr);
					OS.XFreeGC(xDisplay, gc);
                    */
					return;
				case 4:
					SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
					break;
				case 8:
					int index = 0;
					int srcPixel, r, g, b;
                    /* AW
					XColor[] colors = new XColor[256];
					int colormap = OS.XDefaultColormap(xDisplay, OS.XDefaultScreen(xDisplay));
					for (int y = 0; y < srcXImage.height; y++) {
						for (int x = 0; x < srcXImage.bytes_per_line; x++) {
							srcPixel = srcData[index + x] & 0xFF;
                            */
							/* Get the RGB values of srcPixel */
                            /* AW
							if (colors[srcPixel] == null) {
								XColor color = new XColor();
								color.pixel = srcPixel;
								OS.XQueryColor(xDisplay, colormap, color);
								colors[srcPixel] = color;
							}
							XColor xColor = colors[srcPixel];
							r = (xColor.red >> 8) & 0xFF;
							g = (xColor.green >> 8) & 0xFF;
							b = (xColor.blue >> 8) & 0xFF;
                            */
							/* See if the rgb maps to 0 or 1 */
                            /* AW
							if ((r * r + g * g + b * b) < 98304) {
                            */
								/* Map down to 0 */
                                /* AW
								destData[index + x] = (byte)zeroPixel;
							} else {
                            */
								/* Map up to 1 */
                                /* AW
								destData[index + x] = (byte)onePixel;
							}
						}
						index += srcXImage.bytes_per_line;
					}
                    */
					System.out.println("Image.Image(4): nyi");
					break;
				case 16:
					index = 0;
					/* Get masks */
                    /* AW
					Visual visual = new Visual();
					int screenNum = OS.XDefaultScreen(xDisplay);
					int visualPtr = OS.XDefaultVisual(xDisplay, screenNum);
					OS.memmove(visual, visualPtr, Visual.sizeof);
					int redMask = visual.red_mask;
					int greenMask = visual.green_mask;
					int blueMask = visual.blue_mask;
                    */
					int redMask = 0x7C00;
					int greenMask = 0x03E0;
					int blueMask = 0x001F;					
					/* Calculate mask shifts */
					int[] shift = new int[1];
					getOffsetForMask(16, redMask, srcXImage.byte_order, shift);
					int rShift = 24 - shift[0];
					getOffsetForMask(16, greenMask, srcXImage.byte_order, shift);
					int gShift = 24 - shift[0];
					getOffsetForMask(16, blueMask, srcXImage.byte_order, shift);
					int bShift = 24 - shift[0];
					byte zeroLow = (byte)(zeroPixel & 0xFF);
					byte zeroHigh = (byte)((zeroPixel >> 8) & 0xFF);
					byte oneLow = (byte)(onePixel & 0xFF);
					byte oneHigh = (byte)((onePixel >> 8) & 0xFF);
					for (int y = 0; y < srcXImage.height; y++) {
						int xIndex = 0;
						for (int x = 0; x < srcXImage.bytes_per_line; x += 2) {
							srcPixel = ((srcData[index + xIndex + 1] & 0xFF) << 8) | (srcData[index + xIndex] & 0xFF);
							r = (srcPixel & redMask) << rShift >> 16;
							g = (srcPixel & greenMask) << gShift >> 16;
							b = (srcPixel & blueMask) << bShift >> 16;
							/* See if the rgb maps to 0 or 1 */
							if ((r * r + g * g + b * b) < 98304) {
								/* Map down to 0 */
								destData[index + xIndex] = zeroLow;
								destData[index + xIndex + 1] = zeroHigh;
							} else {
								/* Map up to 1 */
								destData[index + xIndex] = oneLow;
								destData[index + xIndex + 1] = oneHigh;
							}
							xIndex += srcXImage.bits_per_pixel / 8;
						}
						index += srcXImage.bytes_per_line;
					}
					break;
				case 24:
				case 32:
					index = 0;
					/* Get masks */
                    /* AW
					visual = new Visual();
					screenNum = OS.XDefaultScreen(xDisplay);
					visualPtr = OS.XDefaultVisual(xDisplay, screenNum);
					OS.memmove(visual, visualPtr, Visual.sizeof);
					redMask = visual.red_mask;
					greenMask = visual.green_mask;
					blueMask = visual.blue_mask;
                    */
					redMask = 0xff0000;
					greenMask = 0x00ff00;
					blueMask = 0x0000ff;					
					/* Calculate mask shifts */
					shift = new int[1];
					getOffsetForMask(srcXImage.bits_per_pixel, redMask, srcXImage.byte_order, shift);
					rShift = shift[0];
					getOffsetForMask(srcXImage.bits_per_pixel, greenMask, srcXImage.byte_order, shift);
					gShift = shift[0];
					getOffsetForMask(srcXImage.bits_per_pixel, blueMask, srcXImage.byte_order, shift);
					bShift = shift[0];
					byte zeroR = (byte)zeroColor.getRed();
					byte zeroG = (byte)zeroColor.getGreen();
					byte zeroB = (byte)zeroColor.getBlue();
					byte oneR = (byte)oneColor.getRed();
					byte oneG = (byte)oneColor.getGreen();
					byte oneB = (byte)oneColor.getBlue();
					for (int y = 0; y < srcXImage.height; y++) {
						int xIndex = 0;
						for (int x = 0; x < srcXImage.width; x++) {
							r = srcData[index + xIndex + rShift] & 0xFF;
							g = srcData[index + xIndex + gShift] & 0xFF;
							b = srcData[index + xIndex + bShift] & 0xFF;
							/* See if the rgb maps to 0 or 1 */
							if ((r * r + g * g + b * b) < 98304) {
								/* Map down to 0 */
								destData[index + xIndex + rShift] = zeroR;
								destData[index + xIndex + gShift] = zeroG;
								destData[index + xIndex + bShift] = zeroB;
							} else {
								/* Map up to 1 */
								destData[index + xIndex + rShift] = oneR;
								destData[index + xIndex + gShift] = oneG;
								destData[index + xIndex + bShift] = oneB;
							}
							xIndex += destXImage.bits_per_pixel / 8;
						}
						index += srcXImage.bytes_per_line;
					}
					break;
				default:
					SWT.error(SWT.ERROR_INVALID_IMAGE);
			}
            /* AW
			OS.memmove(destXImage.data, destData, destData.length);
			gc = OS.XCreateGC(xDisplay, destPixmap, 0, null);
			OS.XPutImage(xDisplay, destPixmap, gc, destXImagePtr, 0, 0, 0, 0, width, height);
			*/
			
			System.out.println("Image.Image(5): nyi");
			/* AW
			OS.XDestroyImage(destXImagePtr);
			OS.XDestroyImage(srcXImagePtr);
			OS.XFreeGC(xDisplay, gc);
			*/
			this.pixmap = destPixmap;
			return;

		case SWT.IMAGE_GRAY:
			ImageData data = srcImage.getImageData();
			PaletteData palette = data.palette;
			ImageData newData = data;
			if (!palette.isDirect) {
				/* Convert the palette entries to gray. */
				RGB [] rgbs = palette.getRGBs();
				for (int i=0; i<rgbs.length; i++) {
					if (data.transparentPixel != i) {
						RGB color = rgbs [i];
						int red = color.red;
						int green = color.green;
						int blue = color.blue;
						int intensity = (red+red+green+green+green+green+green+blue) >> 3;
						color.red = color.green = color.blue = intensity;
					}
				}
				newData.palette = new PaletteData(rgbs);
			} else {
				/* Create a 8 bit depth image data with a gray palette. */
				RGB[] rgbs = new RGB[256];
				for (int i=0; i<rgbs.length; i++) {
					rgbs[i] = new RGB(i, i, i);
				}
				newData = new ImageData(width, height, 8, new PaletteData(rgbs));
				newData.maskData = data.maskData;
				newData.maskPad = data.maskPad;
				/* Convert the pixels. */
				int[] scanline = new int[width];
				int redMask = palette.redMask;
				int greenMask = palette.greenMask;
				int blueMask = palette.blueMask;
				int redShift = palette.redShift;
				int greenShift = palette.greenShift;
				int blueShift = palette.blueShift;
				for (int y=0; y<height; y++) {
					int offset = y * newData.bytesPerLine;
					data.getPixels(0, y, width, scanline, 0);
					for (int x=0; x<width; x++) {
						int pixel = scanline[x];
						int red = pixel & redMask;
						red = (redShift < 0) ? red >>> -redShift : red << redShift;
						int green = pixel & greenMask;
						green = (greenShift < 0) ? green >>> -greenShift : green << greenShift;
						int blue = pixel & blueMask;
						blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift;
						newData.data[offset++] =
							(byte)((red+red+green+green+green+green+green+blue) >> 3);
					}
				}
			}
			init (device, newData);
			break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
}
/**
 * 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 (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 SWTError <ul>
 *    <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li>
 * </ul>
 */
public Image(Device device, ImageData image) {
	init(device, image);
}
/**
 * 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, and the mask image
 * must have a color depth of 1. Pixel transparency in either image
 * will be ignored. If either image is an icon to begin with, an
 * exception is thrown.
 * <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 or
 *          if the mask is not monochrome, or if either the source or mask
 *          is already an icon</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) {
	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);
	}
	if (mask.depth != 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	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(device, image);
}
/**
 * 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.
 * <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>
 *     new Image(device, clazz.getResourceAsStream("file.gif"));
 * </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>
 * </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) {
	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>
 * </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) {
	init(device, new ImageData(filename));
}
/**
 * Create the receiver's mask if necessary.
 */
void createMask() {
	if (mask != 0) return;
    /* AW
	int xDisplay = device.xDisplay;
	int drawable = OS.XDefaultRootWindow(xDisplay);
	int screenDepth = OS.XDefaultDepthOfScreen(OS.XDefaultScreenOfDisplay(xDisplay));
	*/
	int screenDepth = 32;
	/* AW
	int visual = OS.XDefaultVisual(xDisplay, OS.XDefaultScreen(xDisplay));
	*/
	ImageData maskImage = getImageData().getTransparencyMask();
	/* AW
	int maskPixmap = OS.XCreatePixmap(xDisplay, drawable, maskImage.width, maskImage.height, 1);
	*/
	int maskPixmap = OS.NewPixMap((short)maskImage.width, (short)maskImage.height, (short)1, (short)4, null, null, null);
	/* AW
	XColor[] xcolors = device.xcolors;
	*/
	XColor[] xcolors = null;
	int error = Image.putImage(maskImage, 0, 0, maskImage.width, maskImage.height, 0, 0, maskImage.width, maskImage.height, screenDepth, xcolors, null, true, maskPixmap);
	this.mask = maskPixmap;
}
/**
 * Disposes of the operating system resources associated with
 * the image. Applications must dispose of all images which
 * they allocate.
 */
public void dispose () {
	if (pixmap == 0) return;
	if (device.isDisposed()) return;
    /* AW
	int xDisplay = device.xDisplay;
	if (pixmap != 0) OS.XFreePixmap (xDisplay, pixmap);
	*/
	if (pixmap != 0) OS.DisposePixMap(pixmap);
	/* AW
	if (mask != 0) OS.XFreePixmap (xDisplay, mask);
	*/
	if (mask != 0) OS.DisposePixMap(mask);
	device = null;
	memGC = null;
	pixmap = mask = 0;
}
/**
 * Destroy the receiver's mask if it exists.
 */
void destroyMask() {
	if (mask == 0) return;
    /* AW
	OS.XFreePixmap (device.xDisplay, mask);
    */
	OS.DisposePixMap(mask);
	mask = 0;
}
/**
 * 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 && pixmap == image.pixmap &&
		transparentPixel == image.transparentPixel &&
		mask == image.mask;
}
/**
 * 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;
    /* AW
	XColor xColor = new XColor();
	xColor.pixel = transparentPixel;
	int xDisplay = device.xDisplay;
	int colormap = OS.XDefaultColormap(xDisplay, OS.XDefaultScreen(xDisplay));
	OS.XQueryColor(xDisplay, colormap, xColor);
	return Color.motif_new(device, xColor);
    */
    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);
    /* AW
	int [] unused = new int [1];  int [] width = new int [1];  int [] height = new int [1];
 	OS.XGetGeometry (device.xDisplay, pixmap, unused, unused, unused, width, height, unused, unused);
    */
	MacRect bounds= new MacRect();		
	OS.GetPixBounds(pixmap, bounds.getData());
	return bounds.toRectangle();
}
/**
 * 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);
	Rectangle srcBounds = getBounds();
	int width = srcBounds.width;
	int height = srcBounds.height;
	int xDisplay = device.xDisplay;
    /* AW
	int xSrcImagePtr = OS.XGetImage(xDisplay, pixmap, 0, 0, width, height, OS.AllPlanes, OS.ZPixmap);
	if (xSrcImagePtr == 0) SWT.error(SWT.ERROR_NO_HANDLES);
    */
	XImage xSrcImage = new XImage((short)width, (short)height, OS.GetPixDepth(pixmap));
    /* AW
	OS.memmove(xSrcImage, xSrcImagePtr, XImage.sizeof);
    */
	/* Calculate the palette depending on the display attributes */
	PaletteData palette = null;

	/* Get the data for the source image. */
	int length = xSrcImage.bytes_per_line * xSrcImage.height;
	byte[] srcData = new byte[length];
    /* AW
	OS.memmove(srcData, xSrcImage.data, length);
    */
	OS.copyPixmpaData(srcData, pixmap, length);
	
	switch (xSrcImage.depth) {
		case 1:
			palette = new PaletteData(new RGB[] {
				new RGB(0, 0, 0),
				new RGB(255, 255, 255)
			});
			break;
		case 4:
			/*
			 * We currently don't run on a 4-bit server, so 4-bit images
			 * should not exist.
			 */
			SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
		case 8:
			/* Normalize the pixels in the source image data (by making the
			 * pixel values sequential starting at pixel 0). Reserve normalized
			 * pixel 0 so that it maps to real pixel 0. This assumes pixel 0 is
			 * always used in the image.
			 */
			byte[] normPixel = new byte[ 256 ];
			for (int index = 0; index < normPixel.length; index++) {
				normPixel[ index ] = 0;
			}
			int numPixels = 1;
			int index = 0;
			for (int y = 0; y < xSrcImage.height; y++) {
				for (int x = 0; x < xSrcImage.bytes_per_line; x++) {
					int srcPixel = srcData[ index + x ] & 0xFF;
					if (srcPixel != 0 && normPixel[ srcPixel ] == 0) {
						normPixel[ srcPixel ] = (byte)numPixels++;
					}
					srcData[ index + x ] = normPixel[ srcPixel ];
				}
				index += xSrcImage.bytes_per_line;
			}

			/* Create a palette with only the RGB values used in the image. */
            /* AW
			int colormap = OS.XDefaultColormap(xDisplay, OS.XDefaultScreen(xDisplay));
			*/
			RGB[] rgbs = new RGB[ numPixels ];
			/* AW
			XColor color = new XColor();
			for (int srcPixel = 0; srcPixel < normPixel.length; srcPixel++) {
				// If the pixel value was used in the image, get its RGB values.
				if (srcPixel == 0 || normPixel[ srcPixel ] != 0) {
					color.pixel = srcPixel;
					OS.XQueryColor(xDisplay, colormap, color);
					int rgbIndex = normPixel[ srcPixel ] & 0xFF;
					rgbs[ rgbIndex ] = new RGB((color.red >> 8) & 0xFF, (color.green >> 8) & 0xFF, (color.blue >> 8) & 0xFF);
				}
			}
			*/
			palette = new PaletteData(rgbs);
			break;
		case 16:
			/*
			 * For some reason, the XImage does not have the mask information.
			 * We must get it from the visual.
			 */
            /* AW
			int visual = OS.XDefaultVisual(xDisplay, OS.XDefaultScreen(xDisplay));
			Visual v = new Visual();
			OS.memmove(v, visual, Visual.sizeof);
			palette = new PaletteData(v.red_mask, v.green_mask, v.blue_mask);
            */
			// AW assumes Mac
			palette = new PaletteData(0x7C00, 0x03E0, 0x001F);
			break;
		case 24:
		// AW
		case 32:
		// AW
			/* We always create 24-bit ImageData with the following palette */
			/* AW
			palette = new PaletteData(0xFF, 0xFF00, 0xFF0000);
			*/
			// AW assumes Mac
			palette = new PaletteData(0xFF0000, 0xFF00, 0xFF);
			break;
		default:
			System.out.println("unsupported depth: " + xSrcImage.depth);
			SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
	}
	ImageData data = new ImageData(width, height, xSrcImage.depth, palette);
	data.data = srcData;
	if (xSrcImage.bits_per_pixel == 32) {
		/*
		 * If bits per pixel is 32, scale the data down to 24, since we do not
		 * support 32-bit images
		 */
		byte[] oldData = data.data;
		int bytesPerLine = (xSrcImage.width * xSrcImage.depth + 7) / 8;
		bytesPerLine = (bytesPerLine + 3) / 4 * 4;
		byte[] newData = new byte[bytesPerLine * xSrcImage.height];
		int destIndex = 0;
		int srcIndex = 0;
		int rOffset = 0, gOffset = 1, bOffset = 2;
		if (xSrcImage.byte_order == OS.MSBFirst) {
			rOffset = 3; gOffset = 2; bOffset = 1;
		}
		for (int y = 0; y < height; y++) {
			destIndex = y * bytesPerLine;
			srcIndex = y * xSrcImage.bytes_per_line;
			for (int x = 0; x < width; x++) {
				newData[destIndex] = oldData[srcIndex + rOffset];
				newData[destIndex + 1] = oldData[srcIndex + gOffset];
				newData[destIndex + 2] = oldData[srcIndex + bOffset];
				srcIndex += 4;
				destIndex += 3;
			}
		}
		data.data = newData;
	}
	if (transparentPixel == -1 && type == SWT.ICON && mask != 0) {
		/* Get the icon data */
		data.maskPad = 4;
        /* AW
		int xMaskPtr = OS.XGetImage(xDisplay, mask, 0, 0, width, height, OS.AllPlanes, OS.ZPixmap);
		if (xMaskPtr == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		*/
		XImage xMask = new XImage((short)width, (short)height, OS.GetPixDepth(mask));
		/* AW
		OS.memmove(xMask, xMaskPtr, XImage.sizeof);
		*/
		data.maskData = new byte[xMask.bytes_per_line * xMask.height];
		/* AW
		OS.memmove(data.maskData, xMask.data, data.maskData.length);
		OS.XDestroyImage(xMaskPtr);
        */
		/* Bit swap the mask data if necessary */
		if (xMask.bitmap_bit_order == OS.LSBFirst) {
			byte[] maskData = data.maskData;
			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.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);
	}
    /* AW
	OS.XDestroyImage(xSrcImagePtr);
    */
	return data;
}
/**
 * Get the offset for the given mask.
 *
 * For 24 and 32-bit masks, the offset indicates which byte holds the
 *  data for the given mask (indexed from 0).
 *  For example, in 0x0000FF00, the byte offset is 1.
 *
 * For 16-bit masks, the offset indicates which bit holds the most significant
 *  data for the given mask (indexed from 1).
 *  For example, in 0x7E0, the bit offset is 11.
 *
 * The different semantics are necessary because 24- and 32-bit images
 * have their color components aligned on byte boundaries, and 16-bit images
 * do not.
 */
static boolean getOffsetForMask(int bitspp, int mask, int byteOrder, int[] poff) {
	if (bitspp % 8 != 0) {
		return false;
	}
	switch (mask) {
		/* 24-bit and 32-bit masks */
		case 0x000000FF:
			poff[0] = 0;
			break;
		case 0x0000FF00:
			poff[0] = 1;
			break;
		case 0x00FF0000:
			poff[0] = 2;
			break;
		case 0xFF000000:
			poff[0] = 3;
			break;
		/* 16-bit masks */
		case 0x001F:
			poff[0] = 5;
			break;
		case 0x03E0:
			poff[0] = 10;
			break;
		case 0x07E0:
			poff[0] = 11;
			break;
		case 0x7C00:
			poff[0] = 15;
			break;
		case 0xF800:
			poff[0] = 16;
			break;
		default:
			return false;
	}
	if (bitspp == 16) {
		return true;
	}
	if (poff[0] >= bitspp / 8) {
		return false;
	}
	if (byteOrder == OS.MSBFirst) {
		poff[0] = (bitspp/8 - 1) - poff[0];
	}
	return true;
}
/**
 * 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 pixmap;
}
void init(Device device, int width, int height) {
	if (device == null) device = Device.getDevice();
	if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	this.device = device;
	/* Create the pixmap */
	if (width <= 0 | height <= 0) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}

	this.type = SWT.BITMAP;
    /* AW
	int xDisplay = device.xDisplay;
	int screen = OS.XDefaultScreenOfDisplay(xDisplay);
	int depth = OS.XDefaultDepthOfScreen(screen);
	*/
	int depth= 32;
	/* AW
	int screenNum = OS.XDefaultScreen(xDisplay);
	int drawable = OS.XDefaultRootWindow(xDisplay);
	int pixmap = OS.XCreatePixmap(xDisplay, drawable, width, height, depth);
	*/
	int pixmap = OS.NewPixMap((short)width, (short)height, (short)depth, (short)4, null, null, null);
	if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);

	/* Fill the bitmap with white */
    /* AW
	int xGC = OS.XCreateGC(xDisplay, drawable, 0, null);
	OS.XSetForeground(xDisplay, xGC, OS.XWhitePixel(xDisplay, screenNum));
	OS.XFillRectangle(xDisplay, pixmap, xGC, 0, 0, width, height);
	OS.XFreeGC(xDisplay, xGC);
    */
	// AW
	/*
	// FIXME: we set the pixmap to black or white in NewPixMap for now
	int[] savePort= new int[1];
	int[] saveGWorld= new int[1];
	OS.GetGWorld(savePort, saveGWorld);
	OS.SetGWorld(xGC, 0);
	MacRect mr= new MacRect();
	OS.GetPixBounds(pixmap, mr.getData());
	OS.EraseRect(mr.getData());
	OS.FrameRect(mr.getData());
	OS.SetGWorld(savePort[0], saveGWorld[0]);
	*/
	// AW
	this.pixmap = pixmap;
}
void init(Device device, ImageData image) {
	if (device == null) device = Device.getDevice();
	if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	this.device = device;
	if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	/* AW
	int xDisplay = device.xDisplay;
	int drawable = OS.XDefaultRootWindow(xDisplay);
	int screenDepth = OS.XDefaultDepthOfScreen(OS.XDefaultScreenOfDisplay(xDisplay));
	*/
	int screenDepth = 32;
	/* AW
	int visual = OS.XDefaultVisual(xDisplay, OS.XDefaultScreen(xDisplay));
	int pixmap = OS.XCreatePixmap(xDisplay, drawable, image.width, image.height, screenDepth);
	*/
	int pixmap = OS.NewPixMap((short)image.width, (short)image.height, (short)screenDepth, (short)4, null, null, null);
	if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	/* AW
	int gc = OS.XCreateGC(xDisplay, pixmap, 0, null);
	*/
	int[] transPixel = null;
	if (image.transparentPixel != -1) transPixel = new int[]{image.transparentPixel};
	int error = putImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height, screenDepth, null /* AW device.xcolors */, transPixel, false, pixmap);
	/* AW
	OS.XFreeGC(xDisplay, gc);
	*/
	if (error != 0) {
		/* AW
		OS.XFreePixmap (xDisplay, pixmap);
		*/
		OS.DisposePixMap(pixmap);
		SWT.error(error);
	}
	if (image.getTransparencyType() == SWT.TRANSPARENCY_MASK || image.transparentPixel != -1) {
		if (image.transparentPixel != -1) transparentPixel = transPixel[0];
		ImageData maskImage = image.getTransparencyMask();
		/* AW
		int mask = OS.XCreatePixmap(xDisplay, drawable, image.width, image.height, 1);
		*/
		int mask = OS.NewPixMap((short)image.width, (short)image.height, (short)1, (short)4, null, null, null);
		/* AW
		gc = OS.XCreateGC(xDisplay, mask, 0, null);
		*/
		error = putImage(maskImage, 0, 0, maskImage.width, maskImage.height, 0, 0, maskImage.width, maskImage.height, screenDepth, null /* AW device.xcolors */, null, true, mask);
		/* AW
		OS.XFreeGC(xDisplay, gc);
		*/
		if (error != 0) {
			/* AW
			OS.XFreePixmap (xDisplay, pixmap);
			OS.XFreePixmap (xDisplay, mask);
			*/
			OS.DisposePixMap(pixmap);
			OS.DisposePixMap(mask);
			SWT.error(error);
		}
		this.mask = mask;
		if (image.getTransparencyType() == SWT.TRANSPARENCY_MASK) {
			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);
		}
	}
	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
 *
 * @private
 */
public int internal_new_GC (GCData data) {
	if (pixmap == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (type != SWT.BITMAP || memGC != null) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	int[] offscreenGWorld = new int[1];
	OS.NewGWorldFromPtr(offscreenGWorld, pixmap);
	int xGC = offscreenGWorld[0];
	if (xGC == 0) SWT.error (SWT.ERROR_NO_HANDLES);
	if (data != null) {
		data.device = device;
		/* AW
		data.display = xDisplay;
		data.drawable = pixmap;
		data.fontList = device.systemFont;
		data.colormap = OS.XDefaultColormap (xDisplay, OS.XDefaultScreen (xDisplay));
		*/
		data.image = this;
		
		// AW
		data.font = device.systemFont;
		data.foreground = 0x00000000;	// black
		data.background = 0x00ffffff;	// white
		// AW
	}
		
	return xGC;
}
/**	 
 * 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 handle the platform specific GC handle
 * @param data the platform specific GC data 
 *
 * @private
 */
public void internal_dispose_GC (int gc, GCData data) {
    /* AW
	int xDisplay = 0;
	if (data != null) xDisplay = data.display;
	if (xDisplay == 0 && device != null) xDisplay = device.xDisplay;
	if (xDisplay == 0) SWT.error (SWT.ERROR_NO_HANDLES);;
	OS.XFreeGC(xDisplay, gc);
    */
	if (gc != 0)
		OS.DisposeGWorld(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 using the image.
 *
 * @return <code>true</code> when the image is disposed and <code>false</code> otherwise
 */
public boolean isDisposed() {
	return pixmap == 0;
}
public static Image macosx_new(Device device, int type, int pixmap, int mask) {
	if (device == null) device = Device.getDevice();
	Image image = new Image();
	image.device = device;
	image.type = type;
	image.pixmap = pixmap;
	image.mask = mask;
	return image;
}
/**
 * Put a device-independent image of any depth into a drawable of any depth,
 * stretching if necessary.
 */
static int putImage(ImageData image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, int screenDepth, XColor[] xcolors, int[] transparentPixel, boolean isMask, int drawable) {
	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)))
			return SWT.ERROR_UNSUPPORTED_DEPTH;

	boolean flipX = destWidth < 0;
	boolean flipY = destHeight < 0;
	if (flipX) {
		destWidth = -destWidth;
		destX = destX - destWidth;
	}
	if (flipY) {
		destHeight = -destHeight;
		destY = destY - destHeight;
	}
	byte[] srcReds = null, srcGreens = null, srcBlues = null;
	if (!palette.isDirect) {
		RGB[] rgbs = palette.getRGBs();
		int length = rgbs.length;
		srcReds = new byte[length];
		srcGreens = new byte[length];
		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;
		}
	}
	byte[] destReds = null, destGreens = null, destBlues = null;
	int destRedMask = 0, destGreenMask = 0, destBlueMask = 0;
	final boolean screenDirect;
	if (screenDepth <= 8) {
		if (xcolors == null) return SWT.ERROR_UNSUPPORTED_DEPTH;
		destReds = new byte[xcolors.length];
		destGreens = new byte[xcolors.length];
		destBlues = new byte[xcolors.length];
		for (int i = 0; i < xcolors.length; i++) {
			XColor color = xcolors[i];
			if (color == null) continue;
			destReds[i] = (byte)((color.red >> 8) & 0xFF);
			destGreens[i] = (byte)((color.green >> 8) & 0xFF);
			destBlues[i] = (byte)((color.blue >> 8) & 0xFF);
		}
		screenDirect = false;
	} else {
		/* AW
		Visual xVisual = new Visual();
		OS.memmove(xVisual, visual, Visual.sizeof);
		destRedMask = xVisual.red_mask;
		destGreenMask = xVisual.green_mask;
		destBlueMask = xVisual.blue_mask;
		*/
		// AW
		destRedMask = 0xff0000;
		destGreenMask = 0x00ff00;
		destBlueMask = 0x0000ff;
		screenDirect = true;
	}
	if (transparentPixel != null) {
		int transRed = 0, transGreen = 0, transBlue = 0;
		if (palette.isDirect) {
			RGB rgb = palette.getRGB(transparentPixel[0]);
			transRed = rgb.red;
			transGreen = rgb.green;
			transBlue = rgb.blue;
		} else {
			RGB[] rgbs = palette.getRGBs();
			if (transparentPixel[0] < rgbs.length) {
				RGB rgb = rgbs[transparentPixel[0]];
				transRed = rgb.red;
				transGreen = rgb.green;
				transBlue = rgb.blue;
			}
		}
		transparentPixel[0] = ImageData.closestMatch(screenDepth, (byte)transRed, (byte)transGreen, (byte)transBlue,
			destRedMask, destGreenMask, destBlueMask, destReds, destGreens, destBlues);
	}

	/* Depth 1 */
	if (image.depth == 1 && isMask) {
		int bplX = ((destWidth + 7) / 8 + 3) & 0xFFFC;
		int bufSize = bplX * destHeight;
		byte[] buf = new byte[bufSize];
		/* AW
		int bufPtr = OS.XtMalloc(bufSize);
		int xImagePtr = OS.XCreateImage(display, visual, 1, OS.XYBitmap, 0, bufPtr, destWidth, destHeight, 32, bplX);
		if (xImagePtr == 0) {
			OS.XtFree(bufPtr);
			return SWT.ERROR_NO_HANDLES;
		}
		*/
		int foreground = 1, background = 0;
		if (!isMask) {
			foreground = 0;
			if (srcReds.length > 1) {
				foreground = ImageData.closestMatch(screenDepth, srcReds[1], srcGreens[1], srcBlues[1],
					destRedMask, destGreenMask, destBlueMask, destReds, destGreens, destBlues);
			}
			if (srcReds.length > 0) {
				background = ImageData.closestMatch(screenDepth, srcReds[0], srcGreens[0], srcBlues[0],
					destRedMask, destGreenMask, destBlueMask, destReds, destGreens, destBlues);
			}
		}
		/* AW
		XImage xImage = new XImage();
		OS.memmove(xImage, xImagePtr, XImage.sizeof);
		xImage.byte_order = OS.MSBFirst;
		xImage.bitmap_unit = 8;
		xImage.bitmap_bit_order = OS.MSBFirst;
		OS.memmove(xImagePtr, xImage, XImage.sizeof);
		*/
		int destOrder = ImageData.MSB_FIRST;
		ImageData.blit(ImageData.BLIT_SRC,
			image.data, 1, image.bytesPerLine, image.getByteOrder(), srcX, srcY, srcWidth, srcHeight, null, null, null,
			ImageData.ALPHA_OPAQUE, null, 0,
			buf, 1, bplX, destOrder, 0, 0, destWidth, destHeight, null, null, null,
			flipX, flipY);
		
		/* AW
		OS.memmove(xImage.data, buf, bufSize);
		XGCValues values = new XGCValues();
		OS.XGetGCValues(display, gc, OS.GCForeground | OS.GCBackground, values);
		OS.XSetForeground(display, gc, foreground);
		OS.XSetBackground(display, gc, background);
		OS.XPutImage(display, drawable, gc, xImagePtr, 0, 0, destX, destY, destWidth, destHeight);
		OS.XSetForeground(display, gc, values.foreground);
		OS.XSetBackground(display, gc, values.background);
		OS.XDestroyImage(xImagePtr);
		*/
		OS.setPixMapData(drawable, buf);
		return 0;
	}
	
	/* Depths other than 1 */
	/* AW
	int xImagePtr = OS.XCreateImage(display, visual, screenDepth, OS.ZPixmap, 0, 0, destWidth, destHeight, 32, 0);
	if (xImagePtr == 0) return SWT.ERROR_NO_HANDLES;
	*/
	XImage xImage = new XImage(destWidth, destHeight, 32);
	/* AW
	OS.memmove(xImage, xImagePtr, XImage.sizeof);
	*/
	int bufSize = xImage.bytes_per_line * destHeight;	
	byte[] buf = new byte[bufSize];
	/*
	int bufPtr = OS.XtMalloc(bufSize);
	xImage.data = bufPtr;
	OS.memmove(xImagePtr, xImage, XImage.sizeof);
	*/
	int srcOrder = image.getByteOrder();
	int destOrder = xImage.byte_order == OS.MSBFirst ? ImageData.MSB_FIRST : ImageData.LSB_FIRST;
	
	if (palette.isDirect) {
		if (screenDirect) {
			ImageData.blit(ImageData.BLIT_SRC,
				image.data, image.depth, image.bytesPerLine, srcOrder, srcX, srcY, srcWidth, srcHeight, palette.redMask, palette.greenMask, palette.blueMask,
				ImageData.ALPHA_OPAQUE, null, 0,
				buf, xImage.bits_per_pixel, xImage.bytes_per_line, destOrder, 0, 0, destWidth, destHeight, xImage.red_mask, xImage.green_mask, xImage.blue_mask,
				flipX, flipY);
		} else {
			ImageData.blit(ImageData.BLIT_SRC,
				image.data, image.depth, image.bytesPerLine, srcOrder, srcX, srcY, srcWidth, srcHeight, palette.redMask, palette.greenMask, palette.blueMask,
				ImageData.ALPHA_OPAQUE, null, 0,
				buf, xImage.bits_per_pixel, xImage.bytes_per_line, destOrder, 0, 0, destWidth, destHeight, destReds, destGreens, destBlues,
				flipX, flipY);
		}
	} else {
		if (screenDirect) {
			ImageData.blit(ImageData.BLIT_SRC,
				image.data, image.depth, image.bytesPerLine, srcOrder, srcX, srcY, srcWidth, srcHeight, srcReds, srcGreens, srcBlues,
				ImageData.ALPHA_OPAQUE, null, 0,
				buf, xImage.bits_per_pixel, xImage.bytes_per_line, destOrder, 0, 0, destWidth, destHeight, xImage.red_mask, xImage.green_mask, xImage.blue_mask,
				flipX, flipY);
		} else {
			ImageData.blit(ImageData.BLIT_SRC,
				image.data, image.depth, image.bytesPerLine, srcOrder, srcX, srcY, srcWidth, srcHeight, srcReds, srcGreens, srcBlues,
				ImageData.ALPHA_OPAQUE, null, 0,
				buf, xImage.bits_per_pixel, xImage.bytes_per_line, destOrder, 0, 0, destWidth, destHeight, destReds, destGreens, destBlues,
				flipX, flipY);
		}
	}
	/* AW
	OS.memmove(xImage.data, buf, bufSize);
	OS.XPutImage(display, drawable, gc, xImagePtr, 0, 0, destX, destY, destWidth, destHeight);
	OS.XDestroyImage(xImagePtr);
	*/
	OS.setPixMapData(drawable, buf);
	return 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;
	/* Generate the mask if necessary. */
	if (mask == 0) createMask();
	Rectangle bounds = getBounds();
	int[] unused = new int[1];
	int[] depth = new int[1];
    /* AW
	int xDisplay = device.xDisplay;
 	OS.XGetGeometry(xDisplay, pixmap, unused, unused, unused, unused, unused, unused, depth);
	int drawable = OS.XDefaultRootWindow(xDisplay);
	int tempPixmap = OS.XCreatePixmap(xDisplay, drawable, bounds.width, bounds.height, depth[0]);
	int xGC = OS.XCreateGC(xDisplay, tempPixmap, 0, null);
	OS.XSetForeground(xDisplay, xGC, color.handle.pixel);
	OS.XFillRectangle(xDisplay, tempPixmap, xGC, 0, 0, bounds.width, bounds.height);
	OS.XSetClipMask(xDisplay, xGC, mask);
	OS.XCopyArea(xDisplay, pixmap, tempPixmap, xGC, 0, 0, bounds.width, bounds.height, 0, 0);
	OS.XSetClipMask(xDisplay, xGC, OS.None);
	OS.XCopyArea(xDisplay, tempPixmap, pixmap, xGC, 0, 0, bounds.width, bounds.height, 0, 0);
	OS.XFreePixmap(xDisplay, tempPixmap);
	OS.XFreeGC(xDisplay, xGC);
    */
	/* Destroy the receiver's mask if the there is a GC created on it */
	if (memGC != null) destroyMask();
}
/**
 * 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 {" + pixmap + "}";
}
}
