/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.tools.internal;

import java.io.*;
import java.util.Vector;

/**
 * Customize the icon of a Windows exe
 * 
 * WARNING! This class is not part of SWT API. It is NOT API. It is an internal
 * tool that may be changed or removed at anytime.
 * 
 * Based on MSDN "An In-Depth Look into the Win32 Portable Executable File Format"
 */
public class IconExe {
	
	 /**
	 * Replace the Desktop icons provided in the Windows executable program
	 * with matching icons provided by the user.
	 *
 	 * Takes 2 arguments
	 * argument 0: the Windows executable e.g c:/eclipse/eclipse.exe
	 * argument 1: The .ico file to write to the given executable e.g. c:/myApp.ico
	 *
	 * Note 1. Write access to the executable program is required. As a result, that
	 * program must not be currently running or edited elsewhere.
	 * 
	 * Note 2.  The Eclipse 3.1 launcher requires a .ico file with the following 6 images
	 * 1. 32x32, 4 bit (Windows 16 colors palette)
	 * 2. 16x16, 4 bit (Windows 16 colors palette)
	 * 3. 16x16, 8 bit (256 colors)
	 * 4. 32x32, 8 bit (256 colors)
	 * 5. 48x48, 4 bit (Windows 16 colors palette)
	 * 6. 48x48, 8 bit (256 colors)
	 * A user icon matching exactly the width/height/depth of an executable icon will be written
	 * to the executable and will replace that executable icon. If an executable icon
	 * does not match a user icon, it is silently left as is.
	 * 
	 * Note 3. This function modifies the content of the executable program and may cause
	 * its corruption.
	 */
	public static void main(String[] args) {
		if (args.length < 2) {
			System.err.println("Usage: IconExe <windows executable> <ico file>");
			return;
		}
		ImageLoader loader = new ImageLoader();
		try {
			ImageData[] data = null;
			
			if (args.length == 2) {
				/* ICO case */
				data = loader.load(args[1]);
			} else {
				/* BMP case - each following argument is a single BMP file
				 * BMP is handled for testing purpose only. The ICO file is the
				 * official Microsoft format for image resources.
				 */
				data = new ImageData[args.length - 1];
				for (int i = 1; i < args.length; i++) {
					ImageData[] current = loader.load(args[i]);
					data[i - 1] = current[0];
				}
			}
			int nMissing = unloadIcons(args[0], data);
			if (nMissing != 0) System.err.println("Error - "+nMissing+" icon(s) not replaced in "+args[0]+" using "+args[1]);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/* Implementation */

	/** 
	 * Retrieve the Desktop icons provided in the Windows executable program.
	 * These icons are typically shown in various places of the Windows desktop.
	 * 
	 * Note.  The Eclipse 3.1 launcher returns the following 6 images
	 * 1. 32x32, 4 bit (Windows 16 colors palette)
	 * 2. 16x16, 4 bit (Windows 16 colors palette)
	 * 3. 16x16, 8 bit (256 colors)
	 * 4. 32x32, 8 bit (256 colors)
	 * 5. 48x48, 4 bit (Windows 16 colors palette)
	 * 6. 48x48, 8 bit (256 colors)
	 * 
	 * @param program the Windows executable e.g c:/eclipse/eclipse.exe
	 */	
	static ImageData[] loadIcons(String program) throws FileNotFoundException, IOException {
		RandomAccessFile raf = new RandomAccessFile(program, "r");
		IconExe iconExe = new IconExe();
		IconResInfo[] iconInfo = iconExe.getIcons(raf);
		ImageData[] data = new ImageData[iconInfo.length];
		for (int i = 0; i < data.length; i++) data[i] = iconInfo[i].data;
		raf.close();
		return data;
	}
	
	/** 
	 * Replace the Desktop icons provided in the Windows executable program
	 * with icons provided by the user.
	 * 
	 * Note 1. Write access to the executable program is required. As a result, that
	 * program must not be currently running or edited elsewhere.
	 * 
	 * Note 2. Use loadIcons to determine which set of icons (width, height, depth)
	 * is required to replace the icons in the executable program. A user icon
	 * matching exactly the width/height/depth of an executable icon will be written
	 * to the executable and will replace that executable icon. If an executable icon
	 * does not match a user icon, it is left as is. Verify the return value matches
	 * the number of icons to write. Finally, use loadIcons after this operation
	 * to verify the icons have changed as expected.
	 * 
	 * Note 3. The Eclipse 3.1 launcher requires the following 6 images (in any order).
	 * 1. 32x32, 4 bit (Windows 16 colors palette)
	 * 2. 16x16, 4 bit (Windows 16 colors palette)
	 * 3. 16x16, 8 bit (256 colors)
	 * 4. 32x32, 8 bit (256 colors)
	 * 5. 48x48, 4 bit (Windows 16 colors palette)
	 * 6. 48x48, 8 bit (256 colors)
	 * 
	 * Note 4. This function modifies the content of the executable program and may cause
	 * its corruption. 
	 * 
	 * @param program the Windows executable e.g c:/eclipse/eclipse.exe
	 * @param icons to write to the given executable
	 * @return the number of icons from the original program that were not successfully replaced (0 if success)
	 */	
	static int unloadIcons(String program, ImageData[] icons) throws FileNotFoundException, IOException {
		RandomAccessFile raf = new RandomAccessFile(program, "rw");
		IconExe iconExe = new IconExe();
		IconResInfo[] iconInfo = iconExe.getIcons(raf);
		int cnt = 0;
		for (int i = 0; i < iconInfo.length; i++) {
			for (int j = 0; j < icons.length; j++)
			if (iconInfo[i].data.width == icons[j].width && 
				iconInfo[i].data.height == icons[j].height && 
				iconInfo[i].data.depth == icons[j].depth) {
				raf.seek(iconInfo[i].offset);
				unloadIcon(raf, icons[j]);
				cnt++;
			}
		}
		raf.close();
		return iconInfo.length - cnt;
	}
	
	public static final String VERSION = "20050124";
	
	static final boolean DEBUG = false;
	public static class IconResInfo {
		ImageData data;
		int offset;
		int size;
	}
	
	IconResInfo[] iconInfo = null;
	int iconCnt;
	
	IconResInfo[] getIcons(RandomAccessFile raf) throws IOException {
		iconInfo = new IconResInfo[4];
		iconCnt = 0;
		IMAGE_DOS_HEADER imageDosHeader = new IMAGE_DOS_HEADER();
		read(raf, imageDosHeader);
		if (imageDosHeader.e_magic != IMAGE_DOS_SIGNATURE) return null;
		int imageNtHeadersOffset = imageDosHeader.e_lfanew;
		raf.seek(imageNtHeadersOffset);
		IMAGE_NT_HEADERS imageNtHeaders = new IMAGE_NT_HEADERS();
		read(raf, imageNtHeaders);
		if (imageNtHeaders.Signature != IMAGE_NT_SIGNATURE) return null;
		
		// DumpResources
		int resourcesRVA = imageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
		if (resourcesRVA == 0) return null;
		if (DEBUG) System.out.println("* Resources (RVA= "+resourcesRVA+")");
		IMAGE_SECTION_HEADER imageSectionHeader = new IMAGE_SECTION_HEADER();
		int firstSectionOffset = imageNtHeadersOffset + IMAGE_NT_HEADERS.FIELD_OFFSET_OptionalHeader + imageNtHeaders.FileHeader.SizeOfOptionalHeader;
		raf.seek(firstSectionOffset);
		boolean found = false;
		for (int i = 0; i < imageNtHeaders.FileHeader.NumberOfSections; i++) {
			read(raf, imageSectionHeader);
			if (resourcesRVA >= imageSectionHeader.VirtualAddress && resourcesRVA < imageSectionHeader.VirtualAddress + imageSectionHeader.Misc_VirtualSize) {
				// could check the imageSectionHeader name is .rsrc
				found = true;
				break;
			}
		}
		if (!found) return null;
		int delta = imageSectionHeader.VirtualAddress - imageSectionHeader.PointerToRawData;
		int imageResourceDirectoryOffset = resourcesRVA - delta;
		dumpResourceDirectory(raf, imageResourceDirectoryOffset, imageResourceDirectoryOffset, delta, 0, 0, false);
		if (iconCnt < iconInfo.length) {
			IconResInfo[] newArray = new IconResInfo[iconCnt];
			System.arraycopy(iconInfo, 0, newArray, 0, iconCnt);
			iconInfo = newArray;
		}
		return iconInfo;
	}

void dumpResourceDirectory(RandomAccessFile raf, int imageResourceDirectoryOffset, int resourceBase, int delta, int type, int level, boolean rt_icon_root) throws IOException {
	if (DEBUG) System.out.println("** LEVEL "+level);

	IMAGE_RESOURCE_DIRECTORY imageResourceDirectory = new IMAGE_RESOURCE_DIRECTORY();
	raf.seek(imageResourceDirectoryOffset);
	read(raf, imageResourceDirectory);

	if (DEBUG) {
		String sType = ""+type;
		// level 1 resources are resource types
		if (level == 1) {
			System.out.println("___________________________");
			if (type == RT_ICON) sType = "RT_ICON";
			if (type == RT_GROUP_ICON) sType = "RT_GROUP_ICON";
		}
		System.out.println("Resource Directory ["+sType+"]"+" (Named "+imageResourceDirectory.NumberOfNamedEntries+", ID "+imageResourceDirectory.NumberOfIdEntries+")");
	}
//	int IRDE_StartOffset = imageResourceDirectoryOffset + IMAGE_RESOURCE_DIRECTORY.SIZEOF;	
	IMAGE_RESOURCE_DIRECTORY_ENTRY[] imageResourceDirectoryEntries = new IMAGE_RESOURCE_DIRECTORY_ENTRY[imageResourceDirectory.NumberOfIdEntries];
	for (int i = 0; i < imageResourceDirectoryEntries.length; i++) {
		imageResourceDirectoryEntries[i] = new IMAGE_RESOURCE_DIRECTORY_ENTRY();
		read(raf, imageResourceDirectoryEntries[i]);
	}
	for (int i = 0; i < imageResourceDirectoryEntries.length; i++) {
		if (imageResourceDirectoryEntries[i].DataIsDirectory) {
			dumpResourceDirectory(raf, imageResourceDirectoryEntries[i].OffsetToDirectory + resourceBase, resourceBase, delta, imageResourceDirectoryEntries[i].Id, level + 1, rt_icon_root ? true : type == RT_ICON);
		} else {
			// Resource found
			/// pResDirEntry->Name
			IMAGE_RESOURCE_DIRECTORY_ENTRY irde = imageResourceDirectoryEntries[i];
			IMAGE_RESOURCE_DATA_ENTRY data = new IMAGE_RESOURCE_DATA_ENTRY();
			raf.seek(imageResourceDirectoryEntries[i].OffsetToData + resourceBase);
			read(raf, data);
			if (DEBUG) System.out.println("Resource Id "+irde.Id+" Data Offset RVA "+data.OffsetToData+", Size "+data.Size);
			if (rt_icon_root) {
				if (DEBUG) System.out.println("iconcnt "+iconCnt+" |"+iconInfo.length);
				iconInfo[iconCnt] = new IconResInfo();
				iconInfo[iconCnt].data = parseIcon(raf, data.OffsetToData - delta, data.Size);
				iconInfo[iconCnt].offset = data.OffsetToData - delta;
				iconInfo[iconCnt].size = data.Size;	
				iconCnt++;
				if (iconCnt == iconInfo.length) {
					IconResInfo[] newArray = new IconResInfo[iconInfo.length + 4];
					System.arraycopy(iconInfo, 0, newArray, 0, iconInfo.length);
					iconInfo = newArray;
				}
			}
		}
 	}
}

static ImageData parseIcon(RandomAccessFile raf, int offset, int size) throws IOException {
	raf.seek(offset);
	BITMAPINFO bitmapInfo = new BITMAPINFO();
	read(raf, bitmapInfo);
	bitmapInfo.bmiHeader.biHeight /= 2;
	int width = bitmapInfo.bmiHeader.biWidth;
	int height = bitmapInfo.bmiHeader.biHeight;
	int depth = bitmapInfo.bmiHeader.biBitCount;

	PaletteData palette = loadPalette(bitmapInfo.bmiHeader, raf);
	byte[] shapeData = loadData(bitmapInfo.bmiHeader, raf);
	bitmapInfo.bmiHeader.biBitCount = 1;
	byte[] maskData = loadData(bitmapInfo.bmiHeader, raf);
	maskData = convertPad(maskData, width, height, 1, 4, 2);
	bitInvertData(maskData, 0, maskData.length);
	return ImageData.internal_new(
		width,
		height,
		depth,
		palette,
		4,
		shapeData,
		2,
		maskData,
		null,
		-1,
		-1,
		SWT.IMAGE_ICO,
		0,
		0,
		0,
		0);
}

static byte[] bitInvertData(byte[] data, int startIndex, int endIndex) {
	// Destructively bit invert data in the given byte array.
	for (int i = startIndex; i < endIndex; i++) {
		data[i] = (byte)(255 - data[i - startIndex]);
	}
	return data;
}

static final byte[] convertPad(byte[] data, int width, int height, int depth, int pad, int newPad) {
	if (pad == newPad) return data;
	int stride = (width * depth + 7) / 8;
	int bpl = (stride + (pad - 1)) / pad * pad;
	int newBpl = (stride + (newPad - 1)) / newPad * newPad;
	byte[] newData = new byte[height * newBpl];
	int srcIndex = 0, destIndex = 0;
	for (int y = 0; y < height; y++) {
		System.arraycopy(data, srcIndex, newData, destIndex, newBpl);
		srcIndex += bpl;
		destIndex += newBpl;
	}
	return newData;
}
static PaletteData loadPalette(BITMAPINFOHEADER bih, RandomAccessFile raf) throws IOException {
	int depth = bih.biBitCount;
	if (depth <= 8) {
		int numColors = bih.biClrUsed;
		if (numColors == 0) {
			numColors = 1 << depth;
		} else {
			if (numColors > 256)
				numColors = 256;
		}
		byte[] buf = new byte[numColors * 4];
		raf.read(buf);
		return paletteFromBytes(buf, numColors);
	}
	if (depth == 16) return new PaletteData(0x7C00, 0x3E0, 0x1F);
	if (depth == 24) return new PaletteData(0xFF, 0xFF00, 0xFF0000);
	return new PaletteData(0xFF00, 0xFF0000, 0xFF000000);
}
static PaletteData paletteFromBytes(byte[] bytes, int numColors) {
	int bytesOffset = 0;
	RGB[] colors = new RGB[numColors];
	for (int i = 0; i < numColors; i++) {
		colors[i] = new RGB(bytes[bytesOffset + 2] & 0xFF,
			bytes[bytesOffset + 1] & 0xFF,
			bytes[bytesOffset] & 0xFF);
		bytesOffset += 4;
	}
	return new PaletteData(colors);
}
static byte[] loadData(BITMAPINFOHEADER bih, RandomAccessFile raf) throws IOException {
	int stride = (bih.biWidth * bih.biBitCount + 7) / 8;
	stride = (stride + 3) / 4 * 4; // Round up to 4 byte multiple
	byte[] data = loadData(bih, raf, stride);
	flipScanLines(data, stride, bih.biHeight);
	return data;
}
static void flipScanLines(byte[] data, int stride, int height) {
	int i1 = 0;
	int i2 = (height - 1) * stride;
	for (int i = 0; i < height / 2; i++) {
		for (int index = 0; index < stride; index++) {
			byte b = data[index + i1];
			data[index + i1] = data[index + i2];
			data[index + i2] = b;
		}
		i1 += stride;
		i2 -= stride;
	}
}
static byte[] loadData(BITMAPINFOHEADER bih, RandomAccessFile raf, int stride) throws IOException {
	int dataSize = bih.biHeight * stride;
	byte[] data = new byte[dataSize];
	int cmp = bih.biCompression;
	if (cmp == 0) { // BMP_NO_COMPRESSION
		raf.read(data);
	} else {
		if (DEBUG) System.out.println("ICO cannot be compressed?");
	}
	return data;
}

static void unloadIcon(RandomAccessFile raf, ImageData icon) throws IOException {
	int sizeImage = (((icon.width * icon.depth + 31) / 32 * 4) +
		((icon.width + 31) / 32 * 4)) * icon.height;
	write4(raf, BMPHeaderFixedSize);
	write4(raf, icon.width);
	write4(raf, icon.height * 2);
	writeU2(raf, 1);
	writeU2(raf, icon.depth);
	write4(raf, 0);
	write4(raf, sizeImage);
	write4(raf, 0);
	write4(raf, 0);
	write4(raf, icon.palette.colors != null ? icon.palette.colors.length : 0);
	write4(raf, 0);
	
	byte[] rgbs = paletteToBytes(icon.palette);
	raf.write(rgbs);
	unloadShapeData(raf, icon);
	unloadMaskData(raf, icon);
}
static byte[] paletteToBytes(PaletteData pal) {
	int n = pal.colors == null ? 0 : (pal.colors.length < 256 ? pal.colors.length : 256);
	byte[] bytes = new byte[n * 4];
	int offset = 0;
	for (int i = 0; i < n; i++) {
		RGB col = pal.colors[i];
		bytes[offset] = (byte)col.blue;
		bytes[offset + 1] = (byte)col.green;
		bytes[offset + 2] = (byte)col.red;
		offset += 4;
	}
	return bytes;
}
static void unloadMaskData(RandomAccessFile raf, ImageData icon) {
	ImageData mask = icon.getTransparencyMask();
	int bpl = (icon.width + 7) / 8;
	int pad = mask.scanlinePad;
	int srcBpl = (bpl + pad - 1) / pad * pad;
	int destBpl = (bpl + 3) / 4 * 4;
	byte[] buf = new byte[destBpl];
	int offset = (icon.height - 1) * srcBpl;
	byte[] data = mask.data;
	try {
		for (int i = 0; i < icon.height; i++) {
			System.arraycopy(data, offset, buf, 0, bpl);
			bitInvertData(buf, 0, bpl);
			raf.write(buf, 0, destBpl);
			offset -= srcBpl;
		}
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
}
static void unloadShapeData(RandomAccessFile raf, ImageData icon) {
	int bpl = (icon.width * icon.depth + 7) / 8;
	int pad = icon.scanlinePad;
	int srcBpl = (bpl + pad - 1) / pad * pad;
	int destBpl = (bpl + 3) / 4 * 4;
	byte[] buf = new byte[destBpl];
	int offset = (icon.height - 1) * srcBpl;
	byte[] data = icon.data;
	try {
		for (int i = 0; i < icon.height; i++) {
			System.arraycopy(data, offset, buf, 0, bpl);
			raf.write(buf, 0, destBpl);
			offset -= srcBpl;
		}
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
}
static boolean readIconGroup(RandomAccessFile raf, int offset, int size) throws IOException {
	raf.seek(offset);
	NEWHEADER newHeader = new NEWHEADER();
	read(raf, newHeader);
	if (newHeader.ResType != RES_ICON) return false;
	RESDIR[] resDir = new RESDIR[newHeader.ResCount];
	for (int i = 0; i < newHeader.ResCount; i++) {
		resDir[i] = new RESDIR();
		read(raf, resDir[i]);
	}
	return true;
}

static void copyFile(String src, String dst) throws FileNotFoundException, IOException {
	File srcFile = new File(src);
	File dstFile = new File(dst);
	FileInputStream in = new FileInputStream(srcFile);
	FileOutputStream out = new FileOutputStream(dstFile);
	int c;
	while ((c = in.read()) != -1) out.write(c); 
	in.close();
	out.close();
}

/* IO utilities to parse Windows executable */
static final int IMAGE_DOS_SIGNATURE = 0x5a4d;
static final int IMAGE_NT_SIGNATURE = 0x00004550;
static final int IMAGE_DIRECTORY_ENTRY_RESOURCE = 2;
static final int RES_ICON = 1;
static final int RT_ICON = 3;
static final int RT_GROUP_ICON = 14;
static final int BMPHeaderFixedSize = 40;
	
public static class IMAGE_DOS_HEADER {
	int e_magic; // WORD
	int e_cblp; // WORD
	int e_cp; // WORD
	int e_crlc; // WORD
	int e_cparhdr; // WORD
	int e_minalloc; // WORD
	int e_maxalloc; // WORD
	int e_ss; // WORD
	int e_sp; // WORD
	int e_csum; // WORD
	int e_ip; // WORD
	int e_cs; // WORD
	int e_lfarlc; // WORD
	int e_ovno; // WORD
	int[] e_res = new int[4]; // WORD[4]
	int e_oemid; // WORD
	int e_oeminfo; // WORD
	int[] e_res2 = new int[10]; // WORD[10]
	int e_lfanew; // LONG
}

public static class IMAGE_FILE_HEADER {
	int Machine; // WORD
	int NumberOfSections; // WORD
	int TimeDateStamp; // DWORD
	int PointerToSymbolTable; // DWORD
	int NumberOfSymbols; // DWORD
	int SizeOfOptionalHeader; // WORD
	int Characteristics; // WORD
}

public static class IMAGE_DATA_DIRECTORY {
	int VirtualAddress; // DWORD
	int Size; // DWORD
}

public static class IMAGE_OPTIONAL_HEADER {
	int Magic; // WORD
	int MajorLinkerVersion; // BYTE
	int MinorLinkerVersion; // BYTE
	int SizeOfCode; // DWORD
	int SizeOfInitializedData; // DWORD
	int SizeOfUninitializedData; // DWORD
	int AddressOfEntryPoint; // DWORD
	int BaseOfCode; // DWORD
	int BaseOfData; // DWORD
	int ImageBase; // DWORD
	int SectionAlignment; // DWORD
	int FileAlignment; // DWORD
	int MajorOperatingSystemVersion; // WORD
	int MinorOperatingSystemVersion; // WORD
	int MajorImageVersion; // WORD
	int MinorImageVersion; // WORD
	int MajorSubsystemVersion; // WORD
	int MinorSubsystemVersion; // WORD
	int Win32VersionValue; // DWORD
	int SizeOfImage; // DWORD
	int SizeOfHeaders; // DWORD
	int CheckSum; // DWORD
	int Subsystem; // WORD
	int DllCharacteristics; // WORD
	int SizeOfStackReserve; // DWORD
	int SizeOfStackCommit; // DWORD
	int SizeOfHeapReserve; // DWORD
	int SizeOfHeapCommit; // DWORD
	int LoaderFlags; // DWORD
	int NumberOfRvaAndSizes; // DWORD
	IMAGE_DATA_DIRECTORY[] DataDirectory = new IMAGE_DATA_DIRECTORY[16];
}
public static class IMAGE_NT_HEADERS {
	int Signature; // DWORD
	IMAGE_FILE_HEADER FileHeader = new IMAGE_FILE_HEADER();
	IMAGE_OPTIONAL_HEADER OptionalHeader = new IMAGE_OPTIONAL_HEADER();
	final static int FIELD_OFFSET_OptionalHeader = 24;  
}
	
public static class IMAGE_SECTION_HEADER {
	int[] Name = new int[8]; // BYTE[8]
	int Misc_VirtualSize; // DWORD (union Misc { DWORD PhysicalAddress; DWORD VirtualSize }
	int VirtualAddress; // DWORD
	int SizeOfRawData; // DWORD
	int PointerToRawData; // DWORD
	int PointerToRelocations; // DWORD
	int PointerToLinenumbers; // DWORD
	int NumberOfRelocations; // WORD
	int NumberOfLinenumbers; // WORD
	int Characteristics; // DWORD
}

public static class IMAGE_RESOURCE_DIRECTORY {
	int Characteristics; // DWORD
	int TimeDateStamp; // DWORD
	int MajorVersion; // WORD
	int MinorVersion; // WORD
	int NumberOfNamedEntries; // WORD - used
	int NumberOfIdEntries; // WORD - used
	final static int SIZEOF = 16;
}

public static class IMAGE_RESOURCE_DIRECTORY_ENTRY {
	// union
	int NameOffset; // DWORD 31 bits
	boolean NameIsString; // DWORD 1 bit
	int Name; // DWORD
	int Id; // WORD
	// union
	int OffsetToData; // DWORD
	int OffsetToDirectory; // DWORD 31 bits
	boolean DataIsDirectory; // DWORD 1 bit
}

public static class IMAGE_RESOURCE_DATA_ENTRY {
	int OffsetToData; // DWORD
	int Size; // DWORD
	int CodePage; // DWORD
	int Reserved; // DWORD
}

public static class NEWHEADER {
	int Reserved; // WORD
	int ResType; // WORD
	int ResCount; // WORD
}

public static class ICONRESDIR {
	int Width; // BYTE
	int Height; // BYTE
	int ColorCount; // BYTE
	int reserved; // BYTE
}

public static class CURSORDIR {
	int Width; // WORD
	int Height; // WORD
}

public static class RESDIR {
	// union
	ICONRESDIR Icon = new ICONRESDIR();
	CURSORDIR Cursor = new CURSORDIR();
	int Planes; // WORD
	int BitCount; // WORD
	int BytesInRes; // DWORD
	int IconCursorId; // WORD
}

public static class BITMAPINFOHEADER {
	int biSize; // DWORD
	int biWidth; // LONG
	int biHeight; // LONG
	int biPlanes; // WORD
	int biBitCount; // WORD
	int biCompression; // DWORD
	int biSizeImage; // DWORD
	int biXPelsPerMeter; // LONG
	int biYPelsPerMeter; // LONG
	int biClrUsed; // DWORD
	int biClrImportant; // DWORD
}

static class RGBQUAD {
	int rgBlue; // BYTE
	int rgbGreen; // BYTE
	int rgbRed; // BYTE
	int rgbReserved; // BYTE
}
static class BITMAPINFO {
	BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER();
	RGBQUAD[] bmiColors = null;
}
static void read(RandomAccessFile raf, BITMAPINFOHEADER bih) throws IOException {
	bih.biSize = read4(raf);
	bih.biWidth = read4(raf);
	bih.biHeight = read4(raf);
	bih.biPlanes = readU2(raf);
	bih.biBitCount = readU2(raf);
	bih.biCompression = read4(raf);
	bih.biSizeImage = read4(raf);
	bih.biXPelsPerMeter = read4(raf);
	bih.biYPelsPerMeter = read4(raf);
	bih.biClrUsed = read4(raf);
	bih.biClrImportant = read4(raf);
}
static void read(RandomAccessFile raf, BITMAPINFO bi) throws IOException {
	read(raf, bi.bmiHeader);
}
/* Little Endian helpers */
static int readU2(RandomAccessFile raf) throws IOException {
	int b0 = raf.readByte() & 0xFF;
	int b1 = raf.readByte() & 0xFF;
	return (b1 << 8 | b0);
}
static int read4(RandomAccessFile raf) throws IOException {
	int b0 = raf.readByte() & 0xFF;
	int b1 = raf.readByte() & 0xFF;
	int b2 = raf.readByte() & 0xFF;
	int b3 = raf.readByte() & 0xFF;
	return b3 << 24 | b2 << 16 | b1 << 8 | b0;
}
static void write4(RandomAccessFile raf, int value) throws IOException {
	raf.write(value & 0xFF);
	raf.write((value >> 8) & 0xFF);
	raf.write((value >> 16) & 0xFF);
	raf.write((value >> 24) & 0xFF);
}
static void writeU2(RandomAccessFile raf, int value) throws IOException {
	raf.write(value & 0xFF);
	raf.write((value >> 8) & 0xFF);
}
static void read(RandomAccessFile raf, IMAGE_DOS_HEADER idh) throws IOException {
	idh.e_magic = readU2(raf);
	idh.e_cblp = readU2(raf);
	idh.e_cp = readU2(raf);
	idh.e_crlc = readU2(raf);
	idh.e_cparhdr = readU2(raf);
	idh.e_minalloc = readU2(raf);
	idh.e_maxalloc = readU2(raf);
	idh.e_ss = readU2(raf);
	idh.e_sp = readU2(raf);
	idh.e_csum = readU2(raf);
	idh.e_ip = readU2(raf);
	idh.e_cs = readU2(raf);
	idh.e_lfarlc = readU2(raf);
	idh.e_ovno = readU2(raf);
	for (int i = 0; i < idh.e_res.length; i++) idh.e_res[i] = readU2(raf);
	idh.e_oemid = readU2(raf);
	idh.e_oeminfo = readU2(raf);
	for (int i = 0; i < idh.e_res2.length; i++) idh.e_res2[i] = readU2(raf);
	idh.e_lfanew = read4(raf);
}
static void read(RandomAccessFile raf, IMAGE_FILE_HEADER ifh) throws IOException {
	ifh.Machine = readU2(raf);
	ifh.NumberOfSections = readU2(raf);
	ifh.TimeDateStamp = read4(raf);
	ifh.PointerToSymbolTable = read4(raf);
	ifh.NumberOfSymbols = read4(raf);
	ifh.SizeOfOptionalHeader = readU2(raf);
	ifh.Characteristics  = readU2(raf);
}
static void read(RandomAccessFile raf, IMAGE_DATA_DIRECTORY idd) throws IOException {
	idd.VirtualAddress = read4(raf);
	idd.Size = read4(raf);
}
static void read(RandomAccessFile raf, IMAGE_OPTIONAL_HEADER ioh) throws IOException {
	ioh.Magic = readU2(raf);
	ioh.MajorLinkerVersion = raf.read();
	ioh.MinorLinkerVersion = raf.read();
	ioh.SizeOfCode = read4(raf);
	ioh.SizeOfInitializedData = read4(raf);
	ioh.SizeOfUninitializedData = read4(raf);
	ioh.AddressOfEntryPoint = read4(raf);
	ioh.BaseOfCode = read4(raf);
	ioh.BaseOfData = read4(raf);
	ioh.ImageBase = read4(raf);
	ioh.SectionAlignment = read4(raf);
	ioh.FileAlignment = read4(raf);
	ioh.MajorOperatingSystemVersion = readU2(raf);
	ioh.MinorOperatingSystemVersion = readU2(raf);
	ioh.MajorImageVersion = readU2(raf);
	ioh.MinorImageVersion = readU2(raf);
	ioh.MajorSubsystemVersion = readU2(raf);
	ioh.MinorSubsystemVersion = readU2(raf);
	ioh.Win32VersionValue = read4(raf);
	ioh.SizeOfImage = read4(raf);
	ioh.SizeOfHeaders = read4(raf);
	ioh.CheckSum = read4(raf);
	ioh.Subsystem = readU2(raf);
	ioh.DllCharacteristics = readU2(raf);
	ioh.SizeOfStackReserve = read4(raf);
	ioh.SizeOfStackCommit = read4(raf);
	ioh.SizeOfHeapReserve = read4(raf);
	ioh.SizeOfHeapCommit = read4(raf);
	ioh.LoaderFlags = read4(raf);
	ioh.NumberOfRvaAndSizes = read4(raf);
	for (int i = 0 ; i < ioh.DataDirectory.length; i++) {
		ioh.DataDirectory[i] = new IMAGE_DATA_DIRECTORY();
		read(raf, ioh.DataDirectory[i]);
	}
}
static void read(RandomAccessFile raf, IMAGE_NT_HEADERS inh) throws IOException {
	inh.Signature = read4(raf);
	read(raf, inh.FileHeader);
	read(raf, inh.OptionalHeader);
}
static void read(RandomAccessFile raf, IMAGE_SECTION_HEADER ish) throws IOException {
	for (int i = 0 ; i < ish.Name.length; i++) ish.Name[i] = raf.read();
	ish.Misc_VirtualSize = read4(raf);
	ish.VirtualAddress = read4(raf);
	ish.SizeOfRawData = read4(raf);
	ish.PointerToRawData = read4(raf);
	ish.PointerToRelocations = read4(raf);
	ish.PointerToLinenumbers = read4(raf);
	ish.NumberOfRelocations = readU2(raf);
	ish.NumberOfLinenumbers = readU2(raf);
	ish.Characteristics = read4(raf);
}
static void read(RandomAccessFile raf, IMAGE_RESOURCE_DIRECTORY ird) throws IOException {
	ird.Characteristics = read4(raf);
	ird.TimeDateStamp = read4(raf);
	ird.MajorVersion = readU2(raf);
	ird.MinorVersion = readU2(raf);
	ird.NumberOfNamedEntries = readU2(raf);
	ird.NumberOfIdEntries = readU2(raf);
}
static void read(RandomAccessFile raf, IMAGE_RESOURCE_DIRECTORY_ENTRY irde) throws IOException {
	irde.Name = read4(raf);
	irde.OffsetToData = read4(raf);
	// construct other union members
	irde.NameOffset = irde.Name & ~ (1 << 31);
	irde.NameIsString = (irde.Name & (1 << 31)) != 0;
	irde.Id = irde.Name & 0xFFFF;
	irde.OffsetToDirectory = irde.OffsetToData & ~ (1 << 31);
	irde.DataIsDirectory = (irde.OffsetToData & (1 << 31)) != 0;
}
static void read(RandomAccessFile raf, IMAGE_RESOURCE_DATA_ENTRY irde) throws IOException {
	irde.OffsetToData = read4(raf);
	irde.Size = read4(raf);
	irde.CodePage = read4(raf);
	irde.Reserved = read4(raf);
}
static void read(RandomAccessFile raf, NEWHEADER nh) throws IOException {
	nh.Reserved = readU2(raf);
	nh.ResType = readU2(raf);
	nh.ResCount = readU2(raf);
}
static void read(RandomAccessFile raf, ICONRESDIR i) throws IOException {
	i.Width = raf.read();
	i.Height = raf.read();
	i.ColorCount = raf.read();
	i.reserved = raf.read();
}
static void read(RandomAccessFile raf, CURSORDIR c) throws IOException {
	c.Width = readU2(raf);
	c.Height = readU2(raf);
}
static void read(RandomAccessFile raf, RESDIR rs) throws IOException {
	long start = raf.getFilePointer();
	read(raf, rs.Icon);
	raf.seek(start);
	read(raf, rs.Cursor);
	rs.Planes = readU2(raf);
	rs.BitCount = readU2(raf);
	rs.BytesInRes = read4(raf);
	rs.IconCursorId = readU2(raf);
}

/* ImageData and Image Decoder inlining to avoid dependency on SWT 
 * The following section can be entirely removed if SWT can be used.
 */

static class RGB {
	
	/**
	 * the red component of the RGB
	 */
	public int red;
	
	/**
	 * the green component of the RGB
	 */
	public int green;
	
	/**
	 * the blue component of the RGB
	 */
	public int blue;
	
	static final long serialVersionUID = 3258415023461249074L;
	
/**
 * Constructs an instance of this class with the given
 * red, green and blue values.
 *
 * @param red the red component of the new instance
 * @param green the green component of the new instance
 * @param blue the blue component of the new instance
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li>
 * </ul>
 */
public RGB(int red, int green, int blue) {
	if ((red > 255) || (red < 0) ||
		(green > 255) || (green < 0) ||
		(blue > 255) || (blue < 0))
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	this.red = red;
	this.green = green;
	this.blue = blue;
}

/**
 * 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 RGB)) return false;
	RGB rgb = (RGB)object;
	return (rgb.red == this.red) && (rgb.green == this.green) && (rgb.blue == this.blue);
}

/**
 * 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(Object)
 */
public int hashCode () {
	return (blue << 16) | (green << 8) | red;
}

/**
 * Returns a string containing a concise, human-readable
 * description of the receiver.
 *
 * @return a string representation of the <code>RGB</code>
 */
public String toString () {
	return "RGB {" + red + ", " + green + ", " + blue + "}"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ 

//$NON-NLS-4$
}

}
static class PaletteData {
	
	/**
	 * true if the receiver is a direct palette, 
	 * and false otherwise
	 */
	public boolean isDirect;
	
	/**
	 * the RGB values for an indexed palette, where the
	 * indices of the array correspond to pixel values
	 */
	public RGB[] colors;
	
	/**
	 * the red mask for a direct palette
	 */
	public int redMask;
	
	/**
	 * the green mask for a direct palette
	 */
	public int greenMask;
	
	/**
	 * the blue mask for a direct palette
	 */
	public int blueMask;
	
	/**
	 * the red shift for a direct palette
	 */
	public int redShift;
	
	/**
	 * the green shift for a direct palette
	 */
	public int greenShift;
	
	/**
	 * the blue shift for a direct palette
	 */
	public int blueShift;

/**
 * Constructs a new indexed palette given an array of RGB values.
 *
 * @param colors the array of <code>RGB</code>s for the palette
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public PaletteData(RGB[] colors) {
	if (colors == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	this.colors = colors;
	this.isDirect = false;
}

/**
 * Constructs a new direct palette given the red, green and blue masks.
 *
 * @param redMask the red mask
 * @param greenMask the green mask
 * @param blueMask the blue mask
 */
public PaletteData(int redMask, int greenMask, int blueMask) {
	this.redMask = redMask;
	this.greenMask = greenMask;
	this.blueMask = blueMask;
	this.isDirect = true;
	this.redShift = shiftForMask(redMask);
	this.greenShift = shiftForMask(greenMask);
	this.blueShift = shiftForMask(blueMask);
}

/**
 * Returns the pixel value corresponding to the given <code>RBG</code>.
 *
 * @param rgb the RGB to get the pixel value for
 * @return the pixel value for the given RGB
 * 
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the RGB is not found in the palette</li>
 * </ul>
 */
public int getPixel(RGB rgb) {
	if (rgb == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (isDirect) {
		int pixel = 0;
		pixel |= (redShift < 0 ? rgb.red << -redShift : rgb.red >>> redShift) & redMask;
		pixel |= (greenShift < 0 ? rgb.green << -greenShift : rgb.green >>> greenShift) & greenMask;
		pixel |= (blueShift < 0 ? rgb.blue << -blueShift : rgb.blue >>> blueShift) & blueMask;
		return pixel;
	} else {
		for (int i = 0; i < colors.length; i++) {
			if (colors[i].equals(rgb)) return i;
		}
		/* The RGB did not exist in the palette */
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		return 0;
	}
}

/**
 * Returns an <code>RGB</code> corresponding to the given pixel value.
 *
 * @param pixel the pixel to get the RGB value for
 * @return the RGB value for the given pixel
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the pixel does not exist in the palette</li>
 * </ul>
 */
public RGB getRGB(int pixel) {
	if (isDirect) {
		int r = pixel & redMask;
		r = (redShift < 0) ? r >>> -redShift : r << redShift;
		int g = pixel & greenMask;
		g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
		int b = pixel & blueMask;
		b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
		return new RGB(r, g, b);
	} else {
		if (pixel < 0 || pixel >= colors.length) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		return colors[pixel];
	}
}

/**
 * Returns all the RGB values in the receiver if it is an
 * indexed palette, or null if it is a direct palette.
 *
 * @return the <code>RGB</code>s for the receiver or null
 */
public RGB[] getRGBs() {
	return colors;
}

/**
 * Computes the shift value for a given mask.
 *
 * @param mask the mask to compute the shift for
 * @return the shift amount
 *
 * @see PaletteData
 */
int shiftForMask(int mask) {
	for (int i = 31; i >= 0; i--) { 
		if (((mask >> i) & 0x1) != 0) return 7 - i;
	}
	return 32;
}

}
static class ImageLoader {
	
	/**
	 * the array of ImageData objects in this ImageLoader.
	 * This array is read in when the load method is called,
	 * and it is written out when the save method is called
	 */
	public ImageData[] data;
	
	/**
	 * the width of the logical screen on which the images
	 * reside, in pixels (this corresponds to the GIF89a
	 * Logical Screen Width value)
	 */
	public int logicalScreenWidth;

	/**
	 * the height of the logical screen on which the images
	 * reside, in pixels (this corresponds to the GIF89a
	 * Logical Screen Height value)
	 */
	public int logicalScreenHeight;

	/**
	 * the background pixel for the logical screen (this 
	 * corresponds to the GIF89a Background Color Index value).
	 * The default is -1 which means 'unspecified background'
	 * 
	 */
	public int backgroundPixel;

	/**
	 * the number of times to repeat the display of a sequence
	 * of animated images (this corresponds to the commonly-used
	 * GIF application extension for "NETSCAPE 2.0 01")
	 */
	public int repeatCount;
		
	/*
	 * the set of ImageLoader event listeners, created on demand
	 */
	Vector imageLoaderListeners;

/**
 * Construct a new empty ImageLoader.
 */
public ImageLoader() {
	reset();
}

/**
 * Resets the fields of the ImageLoader, except for the
 * <code>imageLoaderListeners</code> field.
 */
void reset() {
	data = null;
	logicalScreenWidth = 0;
	logicalScreenHeight = 0;
	backgroundPixel = -1;
	repeatCount = 1;
}

/**
 * Loads an array of <code>ImageData</code> objects from the
 * specified input stream. Throws an error if either an error
 * occurs while loading the images, or if the images are not
 * of a supported type. Returns the loaded image data array.
 *
 * @param stream the input stream to load the images from
 * @return an array of <code>ImageData</code> objects loaded from the specified input stream
 *
 * @exception IllegalArgumentException <ul>
 *    <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 input/output error occurs while reading data</li>
 *    <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
 * </ul>
 */
public ImageData[] load(InputStream stream) {
	if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	reset();
	data = FileFormat.load(stream, this);
	return data;
}

/**
 * Loads an array of <code>ImageData</code> objects from the
 * file with the specified name. Throws an error if either
 * an error occurs while loading the images, or if the images are
 * not of a supported type. Returns the loaded image data array.
 *
 * @param filename the name of the file to load the images from
 * @return an array of <code>ImageData</code> objects loaded from the specified file
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
 *    <li>ERROR_IO - if an IO error occurs while reading data</li>
 *    <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
 * </ul>
 */
public ImageData[] load(String filename) {
	if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	InputStream stream = null;
	try {
		stream = new FileInputStream(filename);
		return load(stream);
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	} finally {
		try {
			if (stream != null) stream.close();
		} catch (IOException e) {
			// Ignore error
		}
	}
	return null;
}
}
static class ImageData {
	
	/**
	 * The width of the image, in pixels.
	 */
	public int width;

	/**
	 * The height of the image, in pixels.
	 */
	public int height;

	/**
	 * The color depth of the image, in bits per pixel.
	 * <p>
	 * Note that a depth of 8 or less does not necessarily
	 * mean that the image is palette indexed, or
	 * conversely that a depth greater than 8 means that
	 * the image is direct color.  Check the associated
	 * PaletteData's isDirect field for such determinations.
	 */
	public int depth;

	/**
	 * The scanline padding.
	 * <p>
	 * If one scanline of the image is not a multiple of
	 * this number, it will be padded with zeros until it is.
	 * </p>
	 */
	public int scanlinePad;

	/**
	 * The number of bytes per scanline.
	 * <p>
	 * This is a multiple of the scanline padding.
	 * </p>
	 */
	public int bytesPerLine;

	/**
	 * The pixel data of the image.
	 * <p>
	 * Note that for 16 bit depth images the pixel data is stored
	 * in least significant byte order; however, for 24bit and
	 * 32bit depth images the pixel data is stored in most
	 * significant byte order.
	 * </p>
	 */
	public byte[] data;

	/**
	 * The color table for the image.
	 */
	public PaletteData palette;

	/**
	 * The transparent pixel.
	 * <p>
	 * Pixels with this value are transparent.
	 * </p><p>
	 * The default is -1 which means 'no transparent pixel'.
	 * </p>
	 */
	public int transparentPixel;

	/**
	 * An icon-specific field containing the data from the icon mask.
	 * <p>
	 * This is a 1 bit bitmap stored with the most significant
	 * bit first.  The number of bytes per scanline is
	 * '((width + 7) / 8 + (maskPad - 1)) / maskPad * maskPad'.
	 * </p><p>
	 * The default is null which means 'no transparency mask'.
	 * </p>
	 */
	public byte[] maskData;

	/**
	 * An icon-specific field containing the scanline pad of the mask.
	 * <p>
	 * If one scanline of the transparency mask is not a
	 * multiple of this number, it will be padded with zeros until
	 * it is.
	 * </p>
	 */
	public int maskPad;
	
	/**
	 * The alpha data of the image.
	 * <p>
	 * Every pixel can have an <em>alpha blending</em> value that
	 * varies from 0, meaning fully transparent, to 255 meaning
	 * fully opaque.  The number of bytes per scanline is
	 * 'width'.
	 * </p>
	 */
	public byte[] alphaData;
	
	/**
	 * The global alpha value to be used for every pixel.
	 * <p>
	 * If this value is set, the <code>alphaData</code> field
	 * is ignored and when the image is rendered each pixel
	 * will be blended with the background an amount
	 * proportional to this value.
	 * </p><p>
	 * The default is -1 which means 'no global alpha value'
	 * </p>
	 */
	public int alpha;

	/**
	 * The type of file from which the image was read.
	 * 
	 * It is expressed as one of the following values:
	 * <dl>
	 * <dt><code>IMAGE_BMP</code></dt>
	 * <dd>Windows BMP file format, no compression</dd>
	 * <dt><code>IMAGE_BMP_RLE</code></dt>
	 * <dd>Windows BMP file format, RLE compression if appropriate</dd>
	 * <dt><code>IMAGE_GIF</code></dt>
	 * <dd>GIF file format</dd>
	 * <dt><code>IMAGE_ICO</code></dt>
	 * <dd>Windows ICO file format</dd>
	 * <dt><code>IMAGE_JPEG</code></dt>
	 * <dd>JPEG file format</dd>
	 * <dt><code>IMAGE_PNG</code></dt>
	 * <dd>PNG file format</dd>
	 * </dl>
	 */
	public int type;

	/**
	 * The x coordinate of the top left corner of the image
	 * within the logical screen (this field corresponds to
	 * the GIF89a Image Left Position value).
	 */
	public int x;

	/**
	 * The y coordinate of the top left corner of the image
	 * within the logical screen (this field corresponds to
	 * the GIF89a Image Top Position value).
	 */
	public int y;

	/**
	 * A description of how to dispose of the current image
	 * before displaying the next.
	 * 
	 * It is expressed as one of the following values:
	 * <dl>
	 * <dt><code>DM_UNSPECIFIED</code></dt>
	 * <dd>disposal method not specified</dd>
	 * <dt><code>DM_FILL_NONE</code></dt>
	 * <dd>do nothing - leave the image in place</dd>
	 * <dt><code>DM_FILL_BACKGROUND</code></dt>
	 * <dd>fill with the background color</dd>
	 * <dt><code>DM_FILL_PREVIOUS</code></dt>
	 * <dd>restore the previous picture</dd>
	 * </dl>
	 * (this field corresponds to the GIF89a Disposal Method value)
	 */
	public int disposalMethod;

	/**
	 * The time to delay before displaying the next image
	 * in an animation (this field corresponds to the GIF89a
	 * Delay Time value).
	 */
	public int delayTime;

	/**
	 * Arbitrary channel width data to 8-bit conversion table.
	 */
	static final byte[][] ANY_TO_EIGHT = new byte[9][];
	static {
		for (int b = 0; b < 9; ++b) {
			byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b];
			if (b == 0) continue;
			int inc = 0;
			for (int bit = 0x10000; (bit >>= b) != 0;) inc |= bit;
			for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = (byte)(v >> 8);
		}
	}
	static final byte[] ONE_TO_ONE_MAPPING = ANY_TO_EIGHT[8];

	/**
	 * Scaled 8x8 Bayer dither matrix.
	 */
	static final int[][] DITHER_MATRIX = {
		{ 0xfc0000, 0x7c0000, 0xdc0000, 0x5c0000, 0xf40000, 0x740000, 0xd40000, 0x540000 },
		{ 0x3c0000, 0xbc0000, 0x1c0000, 0x9c0000, 0x340000, 0xb40000, 0x140000, 0x940000 },
		{ 0xcc0000, 0x4c0000, 0xec0000, 0x6c0000, 0xc40000, 0x440000, 0xe40000, 0x640000 },
		{ 0x0c0000, 0x8c0000, 0x2c0000, 0xac0000, 0x040000, 0x840000, 0x240000, 0xa40000 },
		{ 0xf00000, 0x700000, 0xd00000, 0x500000, 0xf80000, 0x780000, 0xd80000, 0x580000 },
		{ 0x300000, 0xb00000, 0x100000, 0x900000, 0x380000, 0xb80000, 0x180000, 0x980000 },
		{ 0xc00000, 0x400000, 0xe00000, 0x600000, 0xc80000, 0x480000, 0xe80000, 0x680000 },
		{ 0x000000, 0x800000, 0x200000, 0xa00000, 0x080000, 0x880000, 0x280000, 0xa80000 }
	};

/**
 * Constructs a new, empty ImageData with the given width, height,
 * depth and palette. The data will be initialized to an (all zero)
 * array of the appropriate size.
 *
 * @param width the width of the image
 * @param height the height of the image
 * @param depth the depth of the image
 * @param palette the palette of the image (must not be null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the width or height is negative, or if the depth is not
 *        	one of 1, 2, 4, 8, 16, 24 or 32</li>
 *    <li>ERROR_NULL_ARGUMENT - if the palette is null</li>
 * </ul>
 */
public ImageData(int width, int height, int depth, PaletteData palette) {
	this(width, height, depth, palette,
		4, null, 0, null,
		null, -1, -1, SWT.IMAGE_UNDEFINED,
		0, 0, 0, 0);
}

/**
 * Constructs a new, empty ImageData with the given width, height,
 * depth, palette, scanlinePad and data.
 *
 * @param width the width of the image
 * @param height the height of the image
 * @param depth the depth of the image
 * @param palette the palette of the image
 * @param scanlinePad the padding of each line, in bytes
 * @param data the data of the image
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the width or height is negative, or if the depth is not
 *        	one of 1, 2, 4, 8, 16, 24 or 32</li>
 *    <li>ERROR_NULL_ARGUMENT - if the palette or data is null</li>
 *    <li>ERROR_CANNOT_BE_ZERO - if the scanlinePad is zero</li>
 * </ul>
 */
public ImageData(int width, int height, int depth, PaletteData palette, int scanlinePad, byte[] data) {
	this(width, height, depth, palette,
		scanlinePad, checkData(data), 0, null,
		null, -1, -1, SWT.IMAGE_UNDEFINED,
		0, 0, 0, 0);
}

/**
 * Constructs an <code>ImageData</code> loaded from a file with the
 * specified name. Throws an error if an error occurs loading the
 * image, or if the image has an unsupported type.
 * <p>
 * This constructor is provided for convenience when loading a single
 * image only. If the file contains multiple images, only the first
 * one will be loaded. To load multiple images, use 
 * <code>ImageLoader.load()</code>.
 * </p>
 *
 * @param filename the name of the file to load the image from (must not be null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
 *    <li>ERROR_IO if an IO error occurs while reading data</li>
 *    <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li>
 * </ul>
 */
public ImageData(String filename) {
	ImageData[] data = new ImageLoader().load(filename);
	if (data.length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE);
	ImageData i = data[0];
	setAllFields(
		i.width,
		i.height,
		i.depth,
		i.scanlinePad,
		i.bytesPerLine,
		i.data,
		i.palette,
		i.transparentPixel,
		i.maskData,
		i.maskPad,
		i.alphaData,
		i.alpha,
		i.type,
		i.x,
		i.y,
		i.disposalMethod,
		i.delayTime);
}

/**
 * Prevents uninitialized instances from being created outside the package.
 */
ImageData() {
}

/**
 * Constructs an image data by giving values for all non-computable fields.
 * <p>
 * This method is for internal use, and is not described further.
 * </p>
 */
ImageData(
	int width, int height, int depth, PaletteData palette,
	int scanlinePad, byte[] data, int maskPad, byte[] maskData,
	byte[] alphaData, int alpha, int transparentPixel, int type,
	int x, int y, int disposalMethod, int delayTime)
{

	if (palette == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (!(depth == 1 || depth == 2 || depth == 4 || depth == 8
		|| depth == 16 || depth == 24 || depth == 32)) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (width <= 0 || height <= 0) {
		SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	if (scanlinePad == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO);

	int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1))
		/ scanlinePad * scanlinePad;
	setAllFields(
		width,
		height,
		depth,
		scanlinePad,
		bytesPerLine,
		data != null ? data : new byte[bytesPerLine * height],
		palette,
		transparentPixel,
		maskData,
		maskPad,
		alphaData,
		alpha,
		type,
		x,
		y,
		disposalMethod,
		delayTime);
}

/**
 * Initializes all fields in the receiver. This method must be called
 * by all public constructors to ensure that all fields are initialized
 * for a new ImageData object. If a new field is added to the class,
 * then it must be added to this method.
 * <p>
 * This method is for internal use, and is not described further.
 * </p>
 */
void setAllFields(int width, int height, int depth, int scanlinePad,
	int bytesPerLine, byte[] data, PaletteData palette, int transparentPixel,
	byte[] maskData, int maskPad, byte[] alphaData, int alpha,
	int type, int x, int y, int disposalMethod, int delayTime) {

	this.width = width;
	this.height = height;
	this.depth = depth;
	this.scanlinePad = scanlinePad;
	this.bytesPerLine = bytesPerLine;
	this.data = data;
	this.palette = palette;
	this.transparentPixel = transparentPixel;
	this.maskData = maskData;
	this.maskPad = maskPad;
	this.alphaData = alphaData;
	this.alpha = alpha;
	this.type = type;
	this.x = x;
	this.y = y;
	this.disposalMethod = disposalMethod;
	this.delayTime = delayTime;
}

/**	 
 * Invokes internal SWT functionality to create a new instance of
 * this class.
 * <p>
 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
 * API for <code>ImageData</code>. It is marked public only so that it
 * can be shared within the packages provided by SWT. It is subject
 * to change without notice, and should never be called from
 * application code.
 * </p>
 * <p>
 * This method is for internal use, and is not described further.
 * </p>
 */
public static ImageData internal_new(
	int width, int height, int depth, PaletteData palette,
	int scanlinePad, byte[] data, int maskPad, byte[] maskData,
	byte[] alphaData, int alpha, int transparentPixel, int type,
	int x, int y, int disposalMethod, int delayTime)
{
	return new ImageData(
		width, height, depth, palette, scanlinePad, data, maskPad, maskData,
		alphaData, alpha, transparentPixel, type, x, y, disposalMethod, delayTime);
}

ImageData colorMaskImage(int pixel) {
	ImageData mask = new ImageData(width, height, 1, bwPalette(),
		2, null, 0, null, null, -1, -1, SWT.IMAGE_UNDEFINED,
		0, 0, 0, 0);
	int[] row = new int[width];
	for (int y = 0; y < height; y++) {
		getPixels(0, y, width, row, 0);
		for (int i = 0; i < width; i++) {
			if (pixel != -1 && row[i] == pixel) {
				row[i] = 0;
			} else {
				row[i] = 1;
			}
		}
		mask.setPixels(0, y, width, row, 0);
	}
	return mask;
}

static byte[] checkData(byte [] data) {
	if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	return data;
}

/**
 * Returns <code>getWidth</code> pixel values starting at offset
 * <code>x</code> in scanline <code>y</code> in the receiver's
 * data starting at <code>startIndex</code>.
 *
 * @param x the x position of the first pixel to get
 * @param y the y position of the first pixel to get
 * @param getWidth the width of the data to get
 * @param pixels the buffer in which to put the pixels
 * @param startIndex the offset into the byte array to begin storing pixels
 *
 * @exception IndexOutOfBoundsException if getWidth is too large
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
 *    <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4 or 8
 *        (For higher depths, use the int[] version of this method.)</li>
 * </ul>
 */
public void getPixels(int x, int y, int getWidth, byte[] pixels, int startIndex) {
	if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error

(SWT.ERROR_INVALID_ARGUMENT);
	if (getWidth == 0) return;
	int index;
	int theByte;
	int mask = 0;
	int n = getWidth;
	int i = startIndex;
	int srcX = x, srcY = y;
	if (depth == 1) {
		index = (y * bytesPerLine) + (x >> 3);
		theByte = data[index] & 0xFF;
		while (n > 0) {
			mask = 1 << (7 - (srcX & 0x7));
			if ((theByte & mask) == 0) {
				pixels[i] = 0;
			} else {
				pixels[i] = 1;
			}
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				if (n > 0) theByte = data[index] & 0xFF;
				srcX = 0;
			} else {
				if (mask == 1) {
					index++;
					if (n > 0) theByte = data[index] & 0xFF;
				}
			}
		}
		return;
	}
	if (depth == 2) {
		index = (y * bytesPerLine) + (x >> 2);
		theByte = data[index] & 0xFF;
		int offset;
		while (n > 0) {
			offset = 3 - (srcX % 4);
			mask = 3 << (offset * 2);
			pixels[i] = (byte)((theByte & mask) >> (offset * 2));
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				if (n > 0) theByte = data[index] & 0xFF;
				srcX = 0;
			} else {
				if (offset == 0) {
					index++;
					theByte = data[index] & 0xFF;
				}
			}
		}
		return;
	}
	if (depth == 4) {
		index = (y * bytesPerLine) + (x >> 1);
		if ((x & 0x1) == 1) {
			theByte = data[index] & 0xFF;
			pixels[i] = (byte)(theByte & 0x0F);
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index++;
			}
		}
		while (n > 1) {
			theByte = data[index] & 0xFF;
			pixels[i] = (byte)(theByte >> 4);
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				pixels[i] = (byte)(theByte & 0x0F);
				i++;
				n--;
				srcX++;
				if (srcX >= width) {
					srcY++;
					index = srcY * bytesPerLine;
					srcX = 0;
				} else {
					index++;
				}
			}
		}
		if (n > 0) {
			theByte = data[index] & 0xFF;
			pixels[i] = (byte)(theByte >> 4);
		}
		return;
	}
	if (depth == 8) {
		index = (y * bytesPerLine) + x;
		for (int j = 0; j < getWidth; j++) {
			pixels[i] = data[index];
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index++;
			}
		}
		return;
	}
	SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
}

/**
 * Returns <code>getWidth</code> pixel values starting at offset
 * <code>x</code> in scanline <code>y</code> in the receiver's
 * data starting at <code>startIndex</code>.
 *
 * @param x the x position of the first pixel to get
 * @param y the y position of the first pixel to get
 * @param getWidth the width of the data to get
 * @param pixels the buffer in which to put the pixels
 * @param startIndex the offset into the buffer to begin storing pixels
 *
 * @exception IndexOutOfBoundsException if getWidth is too large
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
 *    <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
 * </ul>
 */
public void getPixels(int x, int y, int getWidth, int[] pixels, int startIndex) {
	if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error

(SWT.ERROR_INVALID_ARGUMENT);
	if (getWidth == 0) return;
	int index;
	int theByte;
	int mask;
	int n = getWidth;
	int i = startIndex;
	int srcX = x, srcY = y;
	if (depth == 1) {
		index = (y * bytesPerLine) + (x >> 3);
		theByte = data[index] & 0xFF;
		while (n > 0) {
			mask = 1 << (7 - (srcX & 0x7));
			if ((theByte & mask) == 0) {
				pixels[i] = 0;
			} else {
				pixels[i] = 1;
			}
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				if (n > 0) theByte = data[index] & 0xFF;
				srcX = 0;
			} else {
				if (mask == 1) {
					index++;
					if (n > 0) theByte = data[index] & 0xFF;
				}
			}
		}
		return;
	}		
	if (depth == 2) {
		index = (y * bytesPerLine) + (x >> 2);
		theByte = data[index] & 0xFF;
		int offset;
		while (n > 0) {
			offset = 3 - (srcX % 4);
			mask = 3 << (offset * 2);
			pixels[i] = (byte)((theByte & mask) >> (offset * 2));
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				if (n > 0) theByte = data[index] & 0xFF;
				srcX = 0;
			} else {
				if (offset == 0) {
					index++;
					theByte = data[index] & 0xFF;
				}
			}
		}
		return;
	}
	if (depth == 4) {
		index = (y * bytesPerLine) + (x >> 1);
		if ((x & 0x1) == 1) {
			theByte = data[index] & 0xFF;
			pixels[i] = theByte & 0x0F;
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index++;
			}
		}
		while (n > 1) {
			theByte = data[index] & 0xFF;
			pixels[i] = theByte >> 4;
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				pixels[i] = theByte & 0x0F;
				i++;
				n--;
				srcX++;
				if (srcX >= width) {
					srcY++;
					index = srcY * bytesPerLine;
					srcX = 0;
				} else {
					index++;
				}
			}
		}
		if (n > 0) {
			theByte = data[index] & 0xFF;
			pixels[i] = theByte >> 4;
		}
		return;
	}
	if (depth == 8) {
		index = (y * bytesPerLine) + x;
		for (int j = 0; j < getWidth; j++) {
			pixels[i] = data[index] & 0xFF;
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index++;
			}
		}
		return;
	}
	if (depth == 16) {
		index = (y * bytesPerLine) + (x * 2);
		for (int j = 0; j < getWidth; j++) {
			pixels[i] = ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF);
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index += 2;
			}
		}
		return;
	}
	if (depth == 24) {
		index = (y * bytesPerLine) + (x * 3);
		for (int j = 0; j < getWidth; j++) {
			pixels[i] = ((data[index] & 0xFF) << 16) | ((data[index+1] & 0xFF) << 8)
				| (data[index+2] & 0xFF);
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index += 3;
			}
		}
		return;
	}
	if (depth == 32) {
		index = (y * bytesPerLine) + (x * 4);
		i = startIndex;
		for (int j = 0; j < getWidth; j++) {
			pixels[i] = ((data[index] & 0xFF) << 24) | ((data[index+1] & 0xFF) << 16)
				| ((data[index+2] & 0xFF) << 8) | (data[index+3] & 0xFF);
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index += 4;
			}
		}
		return;
	}
	SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
}

/**
 * Returns an array of <code>RGB</code>s which comprise the
 * indexed color table of the receiver, or null if the receiver
 * has a direct color model.
 *
 * @return the RGB values for the image or null if direct color
 *
 * @see PaletteData#getRGBs()
 */
public RGB[] getRGBs() {
	return palette.getRGBs();
}

/**
 * Returns an <code>ImageData</code> which specifies the
 * transparency mask information for the receiver, or null if the
 * receiver has no transparency and is not an icon.
 *
 * @return the transparency mask or null if none exists
 */
public ImageData getTransparencyMask() {
	if (getTransparencyType() == SWT.TRANSPARENCY_MASK) {
		return new ImageData(width, height, 1, bwPalette(), maskPad, maskData);
	} else {
		return colorMaskImage(transparentPixel);
	}
}

/**
 * Returns the image transparency type.
 *
 * @return the receiver's transparency type
 */
public int getTransparencyType() {
	if (maskData != null) return SWT.TRANSPARENCY_MASK;
	if (transparentPixel != -1) return SWT.TRANSPARENCY_PIXEL;
	if (alphaData != null) return SWT.TRANSPARENCY_ALPHA;
	return SWT.TRANSPARENCY_NONE;
}

/**
 * Returns the byte order of the receiver.
 * 
 * @return MSB_FIRST or LSB_FIRST
 */
int getByteOrder() {
	return depth != 16 ? MSB_FIRST : LSB_FIRST;
}

/**
 * Sets the pixel values starting at offset <code>x</code> in
 * scanline <code>y</code> in the receiver's data to the
 * values from the array <code>pixels</code> starting at
 * <code>startIndex</code>.
 *
 * @param x the x position of the pixel to set
 * @param y the y position of the pixel to set
 * @param putWidth the width of the pixels to set
 * @param pixels the pixels to set
 * @param startIndex the index at which to begin setting
 *
 * @exception IndexOutOfBoundsException if putWidth is too large
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
 *    <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8
 *        (For higher depths, use the int[] version of this method.)</li>
 * </ul>
 */
public void setPixels(int x, int y, int putWidth, byte[] pixels, int startIndex) {
	if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	if (putWidth == 0) return;
	int index;
	int theByte;
	int mask;
	int n = putWidth;
	int i = startIndex;
	int srcX = x, srcY = y;
	if (depth == 1) {
		index = (y * bytesPerLine) + (x >> 3);
		while (n > 0) {
			mask = 1 << (7 - (srcX & 0x7));
			if ((pixels[i] & 0x1) == 1) {
				data[index] = (byte)((data[index] & 0xFF) | mask);
			} else {
				data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1));
			}
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				if (mask == 1) {
					index++;
				}
			}
		}
		return;
	}
	if (depth == 2) {
		byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F };
		index = (y * bytesPerLine) + (x >> 2);
		int offset = 3 - (x % 4);
		while (n > 0) {
			theByte = pixels[i] & 0x3;
			data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2)));
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				offset = 0;
				srcX = 0;
			} else {
				if (offset == 0) {
					index++;
					offset = 3;
				} else {
					offset--;
				}
			}
		}
		return;
	}
	if (depth == 4) {
		index = (y * bytesPerLine) + (x >> 1);
		boolean high = (x & 0x1) == 0;
		while (n > 0) {
			theByte = pixels[i] & 0x0F;
			if (high) {
				data[index] = (byte)((data[index] & 0x0F) | (theByte << 4));
			} else {
				data[index] = (byte)((data[index] & 0xF0) | theByte);
			}
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				high = true;
				srcX = 0;
			} else {
				if (!high) index++;
				high = !high;
			}
		}
		return;
	}
	if (depth == 8) {
		index = (y * bytesPerLine) + x;
		for (int j = 0; j < putWidth; j++) {
			data[index] = (byte)(pixels[i] & 0xFF);
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index++;
			}
		}
		return;
	}
	SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
}

/**
 * Sets the pixel values starting at offset <code>x</code> in
 * scanline <code>y</code> in the receiver's data to the
 * values from the array <code>pixels</code> starting at
 * <code>startIndex</code>.
 *
 * @param x the x position of the pixel to set
 * @param y the y position of the pixel to set
 * @param putWidth the width of the pixels to set
 * @param pixels the pixels to set
 * @param startIndex the index at which to begin setting
 *
 * @exception IndexOutOfBoundsException if putWidth is too large
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
 *    <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
 * </ul>
 */
public void setPixels(int x, int y, int putWidth, int[] pixels, int startIndex) {
	if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	if (putWidth == 0) return;
	int index;
	int theByte;
	int mask;
	int n = putWidth;
	int i = startIndex;
	int pixel;
	int srcX = x, srcY = y;
	if (depth == 1) {
		index = (y * bytesPerLine) + (x >> 3);
		while (n > 0) {
			mask = 1 << (7 - (srcX & 0x7));
			if ((pixels[i] & 0x1) == 1) {
				data[index] = (byte)((data[index] & 0xFF) | mask);
			} else {
				data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1));
			}
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				if (mask == 1) {
					index++;
				}
			}
		}
		return;
	}
	if (depth == 2) {
		byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F };
		index = (y * bytesPerLine) + (x >> 2);
		int offset = 3 - (x % 4);
		while (n > 0) {
			theByte = pixels[i] & 0x3;
			data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2)));
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				offset = 3;
				srcX = 0;
			} else {
				if (offset == 0) {
					index++;
					offset = 3;
				} else {
					offset--;
				}
			}
		}
		return;
	}
	if (depth == 4) {
		index = (y * bytesPerLine) + (x >> 1);
		boolean high = (x & 0x1) == 0;
		while (n > 0) {
			theByte = pixels[i] & 0x0F;
			if (high) {
				data[index] = (byte)((data[index] & 0x0F) | (theByte << 4));
			} else {
				data[index] = (byte)((data[index] & 0xF0) | theByte);
			}
			i++;
			n--;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				high = true;
				srcX = 0;
			} else {
				if (!high) index++;
				high = !high;
			}
		}
		return;
	}
	if (depth == 8) {
		index = (y * bytesPerLine) + x;
		for (int j = 0; j < putWidth; j++) {
			data[index] = (byte)(pixels[i] & 0xFF);
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index++;
			}
		}
		return;

	}
	if (depth == 16) {
		index = (y * bytesPerLine) + (x * 2);
		for (int j = 0; j < putWidth; j++) {
			pixel = pixels[i];
			data[index] = (byte)(pixel & 0xFF);
			data[index + 1] = (byte)((pixel >> 8) & 0xFF);
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index += 2;
			}
		}
		return;
	}
	if (depth == 24) {
		index = (y * bytesPerLine) + (x * 3);
		for (int j = 0; j < putWidth; j++) {
			pixel = pixels[i];
			data[index] = (byte)((pixel >> 16) & 0xFF);
			data[index + 1] = (byte)((pixel >> 8) & 0xFF);
			data[index + 2] = (byte)(pixel & 0xFF);
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index += 3;
			}
		}
		return;
	}
	if (depth == 32) {
		index = (y * bytesPerLine) + (x * 4);
		for (int j = 0; j < putWidth; j++) {
			pixel = pixels[i];
			data[index] = (byte)((pixel >> 24) & 0xFF);
			data[index + 1] = (byte)((pixel >> 16) & 0xFF);
			data[index + 2] = (byte)((pixel >> 8) & 0xFF);
			data[index + 3] = (byte)(pixel & 0xFF);
			i++;
			srcX++;
			if (srcX >= width) {
				srcY++;
				index = srcY * bytesPerLine;
				srcX = 0;
			} else {
				index += 4;
			}
		}
		return;
	}
	SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
}

/**
 * Returns a palette with 2 colors: black & white.
 */
static PaletteData bwPalette() {
	return new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255, 255, 255)});
}

/**
 * Gets the offset of the most significant bit for
 * the given mask.
 */
static int getMSBOffset(int mask) {
	for (int i = 31; i >= 0; i--) {
		if (((mask >> i) & 0x1) != 0) return i + 1;
	}
	return 0;
}

/**
 * Finds the closest match.
 */
static int closestMatch(int depth, byte red, byte green, byte blue, int redMask, int greenMask, int blueMask, byte[] reds, byte[] greens, byte[] blues) {
	if (depth > 8) {
		int rshift = 32 - getMSBOffset(redMask);
		int gshift = 32 - getMSBOffset(greenMask);
		int bshift = 32 - getMSBOffset(blueMask);
		return (((red << 24) >>> rshift) & redMask) |
			(((green << 24) >>> gshift) & greenMask) |
			(((blue << 24) >>> bshift) & blueMask);
	}
	int r, g, b;
	int minDistance = 0x7fffffff;
	int nearestPixel = 0;
	int n = reds.length;
	for (int j = 0; j < n; j++) {
		r = (reds[j] & 0xFF) - (red & 0xFF);
		g = (greens[j] & 0xFF) - (green & 0xFF);
		b = (blues[j] & 0xFF) - (blue & 0xFF);
		int distance = r*r + g*g + b*b;
		if (distance < minDistance) {
			nearestPixel = j;
			if (distance == 0) break;
			minDistance = distance;
		}
	}
	return nearestPixel;
}

static final ImageData convertMask(ImageData mask) {
	if (mask.depth == 1) return mask;
	PaletteData palette = new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255,255,255)});
	ImageData newMask = new ImageData(mask.width, mask.height, 1, palette);
	/* Find index of black in mask palette */
	int blackIndex = 0;
	RGB[] rgbs = mask.getRGBs();
	if (rgbs != null) {
		while (blackIndex < rgbs.length) {
			if (rgbs[blackIndex].equals(palette.colors[0])) break;
			blackIndex++;
		}
	}
	int[] pixels = new int[mask.width];
	for (int y = 0; y < mask.height; y++) {
		mask.getPixels(0, y, mask.width, pixels, 0);
		for (int i = 0; i < pixels.length; i++) {
			if (pixels[i] == blackIndex) {
				pixels[i] = 0;
			} else {
				pixels[i] = 1;
			}
		}
		newMask.setPixels(0, y, mask.width, pixels, 0);
	}
	return newMask;
}

static final byte[] convertPad(byte[] data, int width, int height, int depth, int pad, int newPad) {
	if (pad == newPad) return data;
	int stride = (width * depth + 7) / 8;
	int bpl = (stride + (pad - 1)) / pad * pad;	
	int newBpl = (stride + (newPad - 1)) / newPad * newPad;
	byte[] newData = new byte[height * newBpl];
	int srcIndex = 0, destIndex = 0;
	for (int y = 0; y < height; y++) {
		System.arraycopy(data, srcIndex, newData, destIndex, stride);
		srcIndex += bpl;
		destIndex += newBpl;
	}
	return newData;
}

/**
 * Blit operation bits to be OR'ed together to specify the desired operation.
 */
static final int
	BLIT_SRC = 1,     // copy source directly, else applies logic operations
	BLIT_ALPHA = 2,   // enable alpha blending
	BLIT_DITHER = 4;  // enable dithering in low color modes

/**
 * Alpha mode, values 0 - 255 specify global alpha level
 */
static final int
	ALPHA_OPAQUE = 255,           // Fully opaque (ignores any alpha data)
	ALPHA_TRANSPARENT = 0,        // Fully transparent (ignores any alpha data)
	ALPHA_CHANNEL_SEPARATE = -1,  // Use alpha channel from separate alphaData
	ALPHA_CHANNEL_SOURCE = -2,    // Use alpha channel embedded in sourceData
	ALPHA_MASK_UNPACKED = -3,     // Use transparency mask formed by bytes in alphaData (non-zero is opaque)
	ALPHA_MASK_PACKED = -4,       // Use transparency mask formed by packed bits in alphaData
	ALPHA_MASK_INDEX = -5,        // Consider source palette indices transparent if in alphaData array
	ALPHA_MASK_RGB = -6;          // Consider source RGBs transparent if in RGB888 format alphaData array

/**
 * Byte and bit order constants.
 */
static final int LSB_FIRST = 0;
static final int MSB_FIRST = 1;

/**
 * Data types (internal)
 */
//private static final int
//	// direct / true color formats with arbitrary masks & shifts
//	TYPE_GENERIC_8 = 0,
//	TYPE_GENERIC_16_MSB = 1,
//	TYPE_GENERIC_16_LSB = 2,
//	TYPE_GENERIC_24 = 3,
//	TYPE_GENERIC_32_MSB = 4,
//	TYPE_GENERIC_32_LSB = 5,
//	// palette indexed color formats
//	TYPE_INDEX_8 = 6,
//	TYPE_INDEX_4 = 7,
//	TYPE_INDEX_2 = 8,
//	TYPE_INDEX_1_MSB = 9,
//	TYPE_INDEX_1_LSB = 10;

/**
 * Computes the required channel shift from a mask.
 */
static int getChannelShift(int mask) {
	if (mask == 0) return 0;
	int i;
	for (i = 0; ((mask & 1) == 0) && (i < 32); ++i) {
		mask >>>= 1;
	}
	return i;
}

/**
 * Computes the required channel width (depth) from a mask.
 */
static int getChannelWidth(int mask, int shift) {
	if (mask == 0) return 0;
	int i;
	mask >>>= shift;
	for (i = shift; ((mask & 1) != 0) && (i < 32); ++i) {
		mask >>>= 1;
	}
	return i - shift;
}

/**
 * Extracts a field from packed RGB data given a mask for that field.
 */
static byte getChannelField(int data, int mask) {
	final int shift = getChannelShift(mask);
	return ANY_TO_EIGHT[getChannelWidth(mask, shift)][(data & mask) >>> shift];
}

/* 
 * Fill in dithered gradated values for a color channel
 */
static final void buildDitheredGradientChannel(int from, int to, int steps,
	int bandWidth, int bandHeight, boolean vertical,
	byte[] bitmapData, int dp, int bytesPerLine, int bits) {
	final int mask = 0xff00 >>> bits;
	int val = from << 16;
	final int inc = ((to << 16) - val) / steps + 1;
	if (vertical) {
		for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) {
			for (int dx = 0, dptr = dp; dx < bandWidth; ++dx, dptr += 4) {
				final int thresh = DITHER_MATRIX[dy & 7][dx] >>> bits;
				int temp = val + thresh;
				if (temp > 0xffffff) bitmapData[dptr] = -1;
				else bitmapData[dptr] = (byte)((temp >>> 16) & mask);
			}
			val += inc;
		}
	} else {
		for (int dx = 0; dx < bandWidth; ++dx, dp += 4) {
			for (int dy = 0, dptr = dp; dy < bandHeight; ++dy, dptr += bytesPerLine) {
				final int thresh = DITHER_MATRIX[dy][dx & 7] >>> bits;
				int temp = val + thresh;
				if (temp > 0xffffff) bitmapData[dptr] = -1;
				else bitmapData[dptr] = (byte)((temp >>> 16) & mask);
			}
			val += inc;
		}
	}
}
}

static class LEDataInputStream extends InputStream {
	int position;
	InputStream in;

	/**
	 * The byte array containing the bytes to read.
	 */
	protected byte[] buf;
	
	/**
	 * The current position within the byte array <code>buf</code>. A value
	 * equal to buf.length indicates no bytes available.  A value of
	 * 0 indicates the buffer is full.
	 */
	protected int pos;
	

	public LEDataInputStream(InputStream input) {
		this(input, 512);
	}
	
	public LEDataInputStream(InputStream input, int bufferSize) {
		this.in = input;
		if (bufferSize > 0) {
			buf = new byte[bufferSize];
			pos = bufferSize;
		} 
		else throw new IllegalArgumentException();
	}
	
	public void close() throws IOException {
		buf = null;
		if (in != null) {
			in.close();
			in = null;
		}
	}
	
	/**
	 * Answer how many bytes were read.
	 */
	public int getPosition() {
		return position;
	}
	
	/**
	 * Answers how many bytes are available for reading without blocking
	 */
	public int available() throws IOException {
		if (buf == null) throw new IOException();
		return (buf.length - pos) + in.available();
	}
	
	/**
	 * Answer the next byte of the input stream.
	 */
	public int read() throws IOException {
		if (buf == null) throw new IOException();
		position++;
		if (pos < buf.length) return (buf[pos++] & 0xFF);
		return in.read();
	}
	
	/**
	 * Don't imitate the JDK behaviour of reading a random number
	 * of bytes when you can actually read them all.
	 */
	public int read(byte b[], int off, int len) throws IOException {
		int result;
		int left = len;
		result = readData(b, off, len);
		while (true) {
			if (result == -1) return -1;
			position += result;
			if (result == left) return len;
			left -= result;
			off += result;
			result = readData(b, off, left);
		}
	}
	
	/**
 	 * Reads at most <code>length</code> bytes from this LEDataInputStream and 
 	 * stores them in byte array <code>buffer</code> starting at <code>offset</code>.
 	 * <p>
 	 * Answer the number of bytes actually read or -1 if no bytes were read and 
 	 * end of stream was encountered.  This implementation reads bytes from 
 	 * the pushback buffer first, then the target stream if more bytes are required
 	 * to satisfy <code>count</code>.
	 * </p>
	 * @param buffer the byte array in which to store the read bytes.
	 * @param offset the offset in <code>buffer</code> to store the read bytes.
	 * @param length the maximum number of bytes to store in <code>buffer</code>.
	 *
	 * @return int the number of bytes actually read or -1 if end of stream.
	 *
	 * @exception java.io.IOException if an IOException occurs.
	 */
	private int readData(byte[] buffer, int offset, int length) throws IOException {
		if (buf == null) throw new IOException();
		if (offset < 0 || offset > buffer.length ||
  		 	length < 0 || (length > buffer.length - offset)) {
	 		throw new ArrayIndexOutOfBoundsException();
		 	}
				
		int cacheCopied = 0;
		int newOffset = offset;
	
		// Are there pushback bytes available?
		int available = buf.length - pos;
		if (available > 0) {
			cacheCopied = (available >= length) ? length : available;
			System.arraycopy(buf, pos, buffer, newOffset, cacheCopied);
			newOffset += cacheCopied;
			pos += cacheCopied;
		}
	
		// Have we copied enough?
		if (cacheCopied == length) return length;

		int inCopied = in.read(buffer, newOffset, length - cacheCopied);

		if (inCopied > 0) return inCopied + cacheCopied;
		if (cacheCopied == 0) return inCopied;
		return cacheCopied;
	}
	
	/**
	 * Answer an integer comprised of the next
	 * four bytes of the input stream.
	 */
	public int readInt() throws IOException {
		byte[] buf = new byte[4];
		read(buf);
		return ((((((buf[3] & 0xFF) << 8) | 
			(buf[2] & 0xFF)) << 8) | 
			(buf[1] & 0xFF)) << 8) | 
			(buf[0] & 0xFF);
	}
	
	/**
	 * Answer a short comprised of the next
	 * two bytes of the input stream.
	 */
	public short readShort() throws IOException {
		byte[] buf = new byte[2];
		read(buf);
		return (short)(((buf[1] & 0xFF) << 8) | (buf[0] & 0xFF));
	}
	
	/**
	 * Push back the entire content of the given buffer <code>b</code>.
	 * <p>
	 * The bytes are pushed so that they would be read back b[0], b[1], etc. 
	 * If the push back buffer cannot handle the bytes copied from <code>b</code>, 
	 * an IOException will be thrown and no byte will be pushed back.
	 * </p>
	 * 
	 * @param b the byte array containing bytes to push back into the stream
	 *
	 * @exception 	java.io.IOException if the pushback buffer is too small
	 */
	public void unread(byte[] b) throws IOException {
		int length = b.length;
		if (length > pos) throw new IOException();
		position -= length;
		pos -= length;
		System.arraycopy(b, 0, buf, pos, length);
	}
}
public static abstract class FileFormat {	
	LEDataInputStream inputStream;
	ImageLoader loader;
	int compression;

byte[] bitInvertData(byte[] data, int startIndex, int endIndex) {
	// Destructively bit invert data in the given byte array.
	for (int i = startIndex; i < endIndex; i++) {
		data[i] = (byte)(255 - data[i - startIndex]);
	}
	return data;
}

/**
 * Return whether or not the specified input stream
 * represents a supported file format.
 */
abstract boolean isFileFormat(LEDataInputStream stream);

abstract ImageData[] loadFromByteStream();

public ImageData[] loadFromStream(LEDataInputStream stream) {
	try {
		inputStream = stream;
		return loadFromByteStream();
	} catch (Exception e) {
		SWT.error(SWT.ERROR_IO, e);
		return null;
	}
}

public static ImageData[] load(InputStream is, ImageLoader loader) {
	LEDataInputStream stream = new LEDataInputStream(is);
	boolean isSupported = false;	
	FileFormat fileFormat = new WinICOFileFormat();
	if (fileFormat.isFileFormat(stream)) isSupported = true;
	else {
		fileFormat = new WinBMPFileFormat();
		if (fileFormat.isFileFormat(stream)) isSupported = true;
	}
	if (!isSupported) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
	fileFormat.loader = loader;
	return fileFormat.loadFromStream(stream);
}
}
static class WinBMPFileFormat extends FileFormat {
	static final int BMPFileHeaderSize = 14;
	static final int BMPHeaderFixedSize = 40;
	int importantColors;

void decompressData(byte[] src, byte[] dest, int stride, int cmp) {
	if (cmp == 1) { // BMP_RLE8_COMPRESSION
		if (decompressRLE8Data(src, src.length, stride, dest, dest.length) <= 0)
			SWT.error(SWT.ERROR_INVALID_IMAGE);
		return;
	}
	if (cmp == 2) { // BMP_RLE4_COMPRESSION
		if (decompressRLE4Data(src, src.length, stride, dest, dest.length) <= 0)
			SWT.error(SWT.ERROR_INVALID_IMAGE);
		return;
	}
	SWT.error(SWT.ERROR_INVALID_IMAGE);
}
int decompressRLE4Data(byte[] src, int numBytes, int stride, byte[] dest, int destSize) {
	int sp = 0;
	int se = numBytes;
	int dp = 0;
	int de = destSize;
	int x = 0, y = 0;
	while (sp < se) {
		int len = src[sp] & 0xFF;
		sp++;
		if (len == 0) {
			len = src[sp] & 0xFF;
			sp++;
			switch (len) {
				case 0: /* end of line */
					y++;
					x = 0;
					dp = y * stride;
					if (dp >= de)
						return -1;
					break;
				case 1: /* end of bitmap */
					return 1;
				case 2: /* delta */
					x += src[sp] & 0xFF;
					sp++;
					y += src[sp] & 0xFF;
					sp++;
					dp = y * stride + x / 2;
					if (dp >= de)
						return -1;
					break;
				default: /* absolute mode run */
					if ((len & 1) != 0) /* odd run lengths not currently supported */
						return -1;
					x += len;
					len = len / 2;
					if (len > (se - sp))
						return -1;
					if (len > (de - dp))
						return -1;
					for (int i = 0; i < len; i++) {
						dest[dp] = src[sp];
						dp++;
						sp++;
					}
					if ((sp & 1) != 0)
						sp++; /* word align sp? */
					break;
			}
		} else {
			if ((len & 1) != 0)
				return -1;
			x += len;
			len = len / 2;
			byte theByte = src[sp];
			sp++;
			if (len > (de - dp))
				return -1;
			for (int i = 0; i < len; i++) {
				dest[dp] = theByte;
				dp++;
			}
		}
	}
	return 1;
}
int decompressRLE8Data(byte[] src, int numBytes, int stride, byte[] dest, int destSize) {
	int sp = 0;
	int se = numBytes;
	int dp = 0;
	int de = destSize;
	int x = 0, y = 0;
	while (sp < se) {
		int len = src[sp] & 0xFF;
		sp++;
		if (len == 0) {
			len = src[sp] & 0xFF;
			sp++;
			switch (len) {
				case 0: /* end of line */
					y++;
					x = 0;
					dp = y * stride;
					if (dp >= de)
						return -1;
					break;
				case 1: /* end of bitmap */
					return 1;
				case 2: /* delta */
					x += src[sp] & 0xFF;
					sp++;
					y += src[sp] & 0xFF;
					sp++;
					dp = y * stride + x;
					if (dp >= de)
						return -1;
					break;
				default: /* absolute mode run */
					if (len > (se - sp))
						return -1;
					if (len > (de - dp))
						return -1;
					for (int i = 0; i < len; i++) {
						dest[dp] = src[sp];
						dp++;
						sp++;
					}
					if ((sp & 1) != 0)
						sp++; /* word align sp? */
					x += len;
					break;
			}
		} else {
			byte theByte = src[sp];
			sp++;
			if (len > (de - dp))
				return -1;
			for (int i = 0; i < len; i++) {
				dest[dp] = theByte;
				dp++;
			}
			x += len;
		}
	}
	return 1;
}
boolean isFileFormat(LEDataInputStream stream) {
	try {
		byte[] header = new byte[18];
		stream.read(header);
		stream.unread(header);
		int infoHeaderSize = (header[14] & 0xFF) | ((header[15] & 0xFF) << 8) | ((header[16] & 0xFF) << 16) | ((header[17] & 0xFF) << 24);
		return header[0] == 0x42 && header[1] == 0x4D && infoHeaderSize >= BMPHeaderFixedSize;
	} catch (Exception e) {
		return false;
	}
}
byte[] loadData(byte[] infoHeader) {
	int width = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
	int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
	int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
	int stride = (width * bitCount + 7) / 8;
	stride = (stride + 3) / 4 * 4; // Round up to 4 byte multiple
	byte[] data = loadData(infoHeader, stride);
	flipScanLines(data, stride, height);
	return data;
}
byte[] loadData(byte[] infoHeader, int stride) {
	int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
	int dataSize = height * stride;
	byte[] data = new byte[dataSize];
	int cmp = (infoHeader[16] & 0xFF) | ((infoHeader[17] & 0xFF) << 8) | ((infoHeader[18] & 0xFF) << 16) | ((infoHeader[19] & 0xFF) << 24);
	if (cmp == 0) { // BMP_NO_COMPRESSION
		try {
			if (inputStream.read(data) != dataSize)
				SWT.error(SWT.ERROR_INVALID_IMAGE);
		} catch (IOException e) {
			SWT.error(SWT.ERROR_IO, e);
		}
	} else {
		int compressedSize = (infoHeader[20] & 0xFF) | ((infoHeader[21] & 0xFF) << 8) | ((infoHeader[22] & 0xFF) << 16) | ((infoHeader[23] & 0xFF) << 24);
		byte[] compressed = new byte[compressedSize];
		try {
			if (inputStream.read(compressed) != compressedSize)
				SWT.error(SWT.ERROR_INVALID_IMAGE);
		} catch (IOException e) {
			SWT.error(SWT.ERROR_IO, e);
		}
		decompressData(compressed, data, stride, cmp);
	}
	return data;
}
int[] loadFileHeader() {
	int[] header = new int[5];
	try {
		header[0] = inputStream.readShort();
		header[1] = inputStream.readInt();
		header[2] = inputStream.readShort();
		header[3] = inputStream.readShort();
		header[4] = inputStream.readInt();
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	if (header[0] != 0x4D42)
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	return header;
}
ImageData[] loadFromByteStream() {
	int[] fileHeader = loadFileHeader();
	byte[] infoHeader = new byte[BMPHeaderFixedSize];
	try {
		inputStream.read(infoHeader);
	} catch (Exception e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	int width = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
	int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
	int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
	PaletteData palette = loadPalette(infoHeader);
	if (inputStream.getPosition() < fileHeader[4]) {
		// Seek to the specified offset
		try {
			inputStream.skip(fileHeader[4] - inputStream.getPosition());
		} catch (IOException e) {
			SWT.error(SWT.ERROR_IO, e);
		}
	}
	byte[] data = loadData(infoHeader);
	this.compression = (infoHeader[16] & 0xFF) | ((infoHeader[17] & 0xFF) << 8) | ((infoHeader[18] & 0xFF) << 16) | ((infoHeader[19] & 0xFF) << 24);
	this.importantColors = (infoHeader[36] & 0xFF) | ((infoHeader[37] & 0xFF) << 8) | ((infoHeader[38] & 0xFF) << 16) | ((infoHeader[39] & 0xFF) << 24);
//	int xPelsPerMeter = (infoHeader[24] & 0xFF) | ((infoHeader[25] & 0xFF) << 8) | ((infoHeader[26] & 0xFF) << 16) | ((infoHeader[27] & 0xFF) << 24);
//	int yPelsPerMeter = (infoHeader[28] & 0xFF) | ((infoHeader[29] & 0xFF) << 8) | ((infoHeader[30] & 0xFF) << 16) | ((infoHeader[31] & 0xFF) << 24);
	int type = (this.compression == 1 /*BMP_RLE8_COMPRESSION*/) || (this.compression == 2 

/*BMP_RLE4_COMPRESSION*/) ? SWT.IMAGE_BMP_RLE : SWT.IMAGE_BMP;
	return new ImageData[] {
		ImageData.internal_new(
			width,
			height,
			bitCount,
			palette,
			4,
			data,
			0,
			null,
			null,
			-1,
			-1,
			type,
			0,
			0,
			0,
			0)
	};
}
PaletteData loadPalette(byte[] infoHeader) {
	int depth = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
	if (depth <= 8) {
		int numColors = (infoHeader[32] & 0xFF) | ((infoHeader[33] & 0xFF) << 8) | ((infoHeader[34] & 0xFF) << 16) | ((infoHeader[35] & 0xFF) << 24);
		if (numColors == 0) {
			numColors = 1 << depth;
		} else {
			if (numColors > 256)
				numColors = 256;
		}
		byte[] buf = new byte[numColors * 4];
		try {
			if (inputStream.read(buf) != buf.length)
				SWT.error(SWT.ERROR_INVALID_IMAGE);
		} catch (IOException e) {
			SWT.error(SWT.ERROR_IO, e);
		}
		return paletteFromBytes(buf, numColors);
	}
	if (depth == 16) return new PaletteData(0x7C00, 0x3E0, 0x1F);
	if (depth == 24) return new PaletteData(0xFF, 0xFF00, 0xFF0000);
	return new PaletteData(0xFF00, 0xFF0000, 0xFF000000);
}
PaletteData paletteFromBytes(byte[] bytes, int numColors) {
	int bytesOffset = 0;
	RGB[] colors = new RGB[numColors];
	for (int i = 0; i < numColors; i++) {
		colors[i] = new RGB(bytes[bytesOffset + 2] & 0xFF,
			bytes[bytesOffset + 1] & 0xFF,
			bytes[bytesOffset] & 0xFF);
		bytesOffset += 4;
	}
	return new PaletteData(colors);
}
/**
 * Answer a byte array containing the BMP representation of
 * the given device independent palette.
 */
static byte[] paletteToBytes(PaletteData pal) {
	int n = pal.colors == null ? 0 : (pal.colors.length < 256 ? pal.colors.length : 256);
	byte[] bytes = new byte[n * 4];
	int offset = 0;
	for (int i = 0; i < n; i++) {
		RGB col = pal.colors[i];
		bytes[offset] = (byte)col.blue;
		bytes[offset + 1] = (byte)col.green;
		bytes[offset + 2] = (byte)col.red;
		offset += 4;
	}
	return bytes;
}

void flipScanLines(byte[] data, int stride, int height) {
	int i1 = 0;
	int i2 = (height - 1) * stride;
	for (int i = 0; i < height / 2; i++) {
		for (int index = 0; index < stride; index++) {
			byte b = data[index + i1];
			data[index + i1] = data[index + i2];
			data[index + i2] = b;
		}
		i1 += stride;
		i2 -= stride;
	}
}

}

static class WinICOFileFormat extends FileFormat {
	
static final byte[] convertPad(byte[] data, int width, int height, int depth, int pad, int newPad) {
	if (pad == newPad) return data;
	int stride = (width * depth + 7) / 8;
	int bpl = (stride + (pad - 1)) / pad * pad;
	int newBpl = (stride + (newPad - 1)) / newPad * newPad;
	byte[] newData = new byte[height * newBpl];
	int srcIndex = 0, destIndex = 0;
	for (int y = 0; y < height; y++) {
		System.arraycopy(data, srcIndex, newData, destIndex, newBpl);
		srcIndex += bpl;
		destIndex += newBpl;
	}
	return newData;
}
/**
 * Answer the size in bytes of the file representation of the given
 * icon
 */
int iconSize(ImageData i) {
	int shapeDataStride = (i.width * i.depth + 31) / 32 * 4;
	int maskDataStride = (i.width + 31) / 32 * 4;
	int dataSize = (shapeDataStride + maskDataStride) * i.height;
	int paletteSize = i.palette.colors != null ? i.palette.colors.length * 4 : 0;
	return WinBMPFileFormat.BMPHeaderFixedSize + paletteSize + dataSize;
}
boolean isFileFormat(LEDataInputStream stream) {
	try {
		byte[] header = new byte[4];
		stream.read(header);
		stream.unread(header);
		return header[0] == 0 && header[1] == 0 && header[2] == 1 && header[3] == 0;
	} catch (Exception e) {
		return false;
	}
}
boolean isValidIcon(ImageData i) {
	switch (i.depth) {
		case 1:
		case 4:
		case 8:
			if (i.palette.isDirect) return false;
			int size = i.palette.colors.length;
			return size == 2 || size == 16 || size == 32 || size == 256;
		case 24:
		case 32:
			return i.palette.isDirect;
	}
	return false;
}
int loadFileHeader(LEDataInputStream byteStream) {
	int[] fileHeader = new int[3];
	try {
		fileHeader[0] = byteStream.readShort();
		fileHeader[1] = byteStream.readShort();
		fileHeader[2] = byteStream.readShort();
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	if ((fileHeader[0] != 0) || (fileHeader[1] != 1))
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	int numIcons = fileHeader[2];
	if (numIcons <= 0)
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	return numIcons;
}
int loadFileHeader(LEDataInputStream byteStream, boolean hasHeader) {
	int[] fileHeader = new int[3];
	try {
		if (hasHeader) {
			fileHeader[0] = byteStream.readShort();
			fileHeader[1] = byteStream.readShort();
		} else {
			fileHeader[0] = 0;
			fileHeader[1] = 1;
		}
		fileHeader[2] = byteStream.readShort();
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	if ((fileHeader[0] != 0) || (fileHeader[1] != 1))
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	int numIcons = fileHeader[2];
	if (numIcons <= 0)
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	return numIcons;
}
ImageData[] loadFromByteStream() {
	int numIcons = loadFileHeader(inputStream);
	int[][] headers = loadIconHeaders(numIcons);
	ImageData[] icons = new ImageData[headers.length];
	for (int i = 0; i < icons.length; i++) {
		icons[i] = loadIcon(headers[i]);
	}
	return icons;
}
/**
 * Load one icon from the byte stream.
 */
ImageData loadIcon(int[] iconHeader) {
	byte[] infoHeader = loadInfoHeader(iconHeader);
	WinBMPFileFormat bmpFormat = new WinBMPFileFormat();
	bmpFormat.inputStream = inputStream;
	PaletteData palette = bmpFormat.loadPalette(infoHeader);
	byte[] shapeData = bmpFormat.loadData(infoHeader);
	int width = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
	int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
	int depth = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
	infoHeader[14] = 1;
	infoHeader[15] = 0;
	byte[] maskData = bmpFormat.loadData(infoHeader);
	maskData = convertPad(maskData, width, height, 1, 4, 2);
	bitInvertData(maskData, 0, maskData.length);
	return ImageData.internal_new(
		width,
		height,
		depth,
		palette,
		4,
		shapeData,
		2,
		maskData,
		null,
		-1,
		-1,
		SWT.IMAGE_ICO,
		0,
		0,
		0,
		0);
}
int[][] loadIconHeaders(int numIcons) {
	int[][] headers = new int[numIcons][7];
	try {
		for (int i = 0; i < numIcons; i++) {
			headers[i][0] = inputStream.read();
			headers[i][1] = inputStream.read();
			headers[i][2] = inputStream.readShort();
			headers[i][3] = inputStream.readShort();
			headers[i][4] = inputStream.readShort();
			headers[i][5] = inputStream.readInt();
			headers[i][6] = inputStream.readInt();
		}
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	return headers;
}
byte[] loadInfoHeader(int[] iconHeader) {
	int width = iconHeader[0];
	int height = iconHeader[1];
	int numColors = iconHeader[2]; // the number of colors is in the low byte, but the high byte must be 0
	if (numColors == 0) numColors = 256; // this is specified: '00' represents '256' (0x100) colors
	if ((numColors != 2) && (numColors != 8) && (numColors != 16) &&
		(numColors != 32) && (numColors != 256))
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	if (inputStream.getPosition() < iconHeader[6]) {
		// Seek to the specified offset
		try {
			inputStream.skip(iconHeader[6] - inputStream.getPosition());
		} catch (IOException e) {
			SWT.error(SWT.ERROR_IO, e);
			return null;
		}
	}
	byte[] infoHeader = new byte[WinBMPFileFormat.BMPHeaderFixedSize];
	try {
		inputStream.read(infoHeader);
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	if (((infoHeader[12] & 0xFF) | ((infoHeader[13] & 0xFF) << 8)) != 1)
		SWT.error(SWT.ERROR_INVALID_IMAGE);
	int infoWidth = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
	int infoHeight = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
	int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
	if (height == infoHeight && bitCount == 1) height /= 2;
	if (!((width == infoWidth) && (height * 2 == infoHeight) &&
		(bitCount == 1 || bitCount == 4 || bitCount == 8 || bitCount == 24 || bitCount == 32)))
			SWT.error(SWT.ERROR_INVALID_IMAGE);
	infoHeader[8] = (byte)(height & 0xFF);
	infoHeader[9] = (byte)((height >> 8) & 0xFF);
	infoHeader[10] = (byte)((height >> 16) & 0xFF);
	infoHeader[11] = (byte)((height >> 24) & 0xFF);
	return infoHeader;
}
}
static class SWT {
	public static final int IMAGE_ICO = 3;
	public static final int ERROR_IO = 39;
	public static final int ERROR_INVALID_IMAGE = 40;
	public static final int ERROR_NULL_ARGUMENT = 4;
	public static final int ERROR_INVALID_ARGUMENT = 5;
	public static final int ERROR_CANNOT_BE_ZERO = 7;
	public static final int IMAGE_UNDEFINED = -1;
	public static final int ERROR_UNSUPPORTED_DEPTH = 38;
	public static final int TRANSPARENCY_MASK = 1 << 1;
	public static final int ERROR_UNSUPPORTED_FORMAT = 42;
	public static final int TRANSPARENCY_ALPHA = 1 << 0;
	public static final int TRANSPARENCY_NONE = 0x0;
	public static final int TRANSPARENCY_PIXEL = 1 << 2;
	public static final int IMAGE_BMP = 0;
	public static final int IMAGE_BMP_RLE = 1;
	
	public static void error(int code) {
		throw new RuntimeException("Error "+code);
	}
	public static void error(int code, Throwable t) {
		throw new RuntimeException(t);
	}
}
}
