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

import java.io.*;

/**
 * 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 {
		try (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;
			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 {
		try (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++;
					}
			}
			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);
	try (FileInputStream in = new FileInputStream(srcFile); FileOutputStream out = new FileOutputStream(dstFile)) {
		int c;
		while ((c = in.read()) != -1)
			out.write(c);
	}
}

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

/**
 * 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);
	try (InputStream stream = new FileInputStream(filename)) {
		return load(stream);
	} catch (IOException e) {
		SWT.error(SWT.ERROR_IO, e);
	}
	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();
	}
	
	@Override
	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
	 */
	@Override
	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.
	 */
	@Override
	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.
	 */
	@Override
	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;
}
@Override
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;
}
@Override
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;
}
@Override
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;
}
@Override
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);
	}
}
}
