/*******************************************************************************
 * Copyright (c) 2000, 2003 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.opengl;

import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;


public class ImageDataUtil {
	/**
	 * 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
		
	/**
	 * 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;
		
	/**
	 * Byte and bit order constants.
	 */
	static final int LSB_FIRST = 0;
	static final int MSB_FIRST = 1;
	
	/**
	 * 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
		
	/**
	 * 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);
		}
	}

	/**
	 * Blits a direct palette image into a direct palette image.
	 * <p>
	 * Note: When the source and destination depth, order and masks
	 * are pairwise equal and the blitter operation is BLIT_SRC,
	 * the masks are ignored.  Hence when not changing the image
	 * data format, 0 may be specified for the masks.
	 * </p>
	 * 
	 * @param op the blitter operation: a combination of BLIT_xxx flags
	 *        (see BLIT_xxx constants)
	 * @param srcData the source byte array containing image data
	 * @param srcDepth the source depth: one of 8, 16, 24, 32
	 * @param srcStride the source number of bytes per line
	 * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
	 *        ignored if srcDepth is not 16 or 32
	 * @param srcX the top-left x-coord of the source blit region
	 * @param srcY the top-left y-coord of the source blit region
	 * @param srcWidth the width of the source blit region
	 * @param srcHeight the height of the source blit region
	 * @param srcRedMask the source red channel mask
	 * @param srcGreenMask the source green channel mask
	 * @param srcBlueMask the source blue channel mask
	 * @param alphaMode the alpha blending or mask mode, may be
	 *        an integer 0-255 for global alpha; ignored if BLIT_ALPHA
	 *        not specified in the blitter operations
	 *        (see ALPHA_MODE_xxx constants)
	 * @param alphaData the alpha blending or mask data, varies depending
	 *        on the value of alphaMode and sometimes ignored
	 * @param alphaStride the alpha data number of bytes per line
	 * @param alphaX the top-left x-coord of the alpha blit region
	 * @param alphaY the top-left y-coord of the alpha blit region
	 * @param destData the destination byte array containing image data
	 * @param destDepth the destination depth: one of 8, 16, 24, 32
	 * @param destStride the destination number of bytes per line
	 * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
	 *        ignored if destDepth is not 16 or 32
	 * @param destX the top-left x-coord of the destination blit region
	 * @param destY the top-left y-coord of the destination blit region
	 * @param destWidth the width of the destination blit region
	 * @param destHeight the height of the destination blit region
	 * @param destRedMask the destination red channel mask
	 * @param destGreenMask the destination green channel mask
	 * @param destBlueMask the destination blue channel mask
	 * @param flipX if true the resulting image is flipped along the vertical axis
	 * @param flipY if true the resulting image is flipped along the horizontal axis
	 */
	static void blit(int op,
		byte[] srcData, int srcDepth, int srcStride, int srcOrder,
		int srcX, int srcY, int srcWidth, int srcHeight,
		int srcRedMask, int srcGreenMask, int srcBlueMask,
		int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
		byte[] destData, int destDepth, int destStride, int destOrder,
		int destX, int destY, int destWidth, int destHeight,
		int destRedMask, int destGreenMask, int destBlueMask,
		boolean flipX, boolean flipY) {
		if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;

		// these should be supplied as params later
		final int srcAlphaMask = 0, destAlphaMask = 0;

		/*** Prepare scaling data ***/
		final int dwm1 = destWidth - 1;
		final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
		final int dhm1 = destHeight - 1;
		final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;

		/*** Prepare source-related data ***/
		final int sbpp, stype;
		switch (srcDepth) {
			case 8:
				sbpp = 1;
				stype = TYPE_GENERIC_8;
				break;
			case 16:
				sbpp = 2;
				stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
				break;
			case 24:
				sbpp = 3;
				stype = TYPE_GENERIC_24;
				break;
			case 32:
				sbpp = 4;
				stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
				break;
			default:
				//throw new IllegalArgumentException("Invalid source type");
				return;
		}			
		int spr = srcY * srcStride + srcX * sbpp;

		/*** Prepare destination-related data ***/
		final int dbpp, dtype;
		switch (destDepth) {
			case 8:
				dbpp = 1;
				dtype = TYPE_GENERIC_8;
				break;
			case 16:
				dbpp = 2;
				dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
				break;
			case 24:
				dbpp = 3;
				dtype = TYPE_GENERIC_24;
				break;
			case 32:
				dbpp = 4;
				dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
				break;
			default:
				//throw new IllegalArgumentException("Invalid destination type");
				return;
		}			
		int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp;
		final int dprxi = (flipX) ? -dbpp : dbpp;
		final int dpryi = (flipY) ? -destStride : destStride;

		/*** Prepare special processing data ***/
		int apr;
		if ((op & BLIT_ALPHA) != 0) {
			switch (alphaMode) {
				case ALPHA_MASK_UNPACKED:
				case ALPHA_CHANNEL_SEPARATE:
					if (alphaData == null) alphaMode = 0x10000;
					apr = alphaY * alphaStride + alphaX;
					break;
				case ALPHA_MASK_PACKED:
					if (alphaData == null) alphaMode = 0x10000;
					alphaStride <<= 3;
					apr = alphaY * alphaStride + alphaX;
					break;
				case ALPHA_MASK_INDEX:
					//throw new IllegalArgumentException("Invalid alpha type");
					return;
				case ALPHA_MASK_RGB:
					if (alphaData == null) alphaMode = 0x10000;
					apr = 0;
					break;
				default:
					alphaMode = (alphaMode << 16) / 255; // prescale
				case ALPHA_CHANNEL_SOURCE:
					apr = 0;
					break;
			}
		} else {
			alphaMode = 0x10000;
			apr = 0;
		}

		/*** Blit ***/
		int dp = dpr;
		int sp = spr;
		if ((alphaMode == 0x10000) && (stype == dtype) &&
			(srcRedMask == destRedMask) && (srcGreenMask == destGreenMask) &&
			(srcBlueMask == destBlueMask) && (srcAlphaMask == destAlphaMask)) {
			/*** Fast blit (straight copy) ***/
			switch (sbpp) {
				case 1:
					for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
						for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
							destData[dp] = srcData[sp];
							sp += (sfx >>> 16);
						}
					}
					break;					
				case 2:
					for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
						for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
							destData[dp] = srcData[sp];
							destData[dp + 1] = srcData[sp + 1];
							sp += (sfx >>> 16) * 2;
						}
					}
					break;
				case 3:
					for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
						for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
							destData[dp] = srcData[sp];
							destData[dp + 1] = srcData[sp + 1];
							destData[dp + 2] = srcData[sp + 2];
							sp += (sfx >>> 16) * 3;
						}
					}
					break;
				case 4:
					for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
						for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
							destData[dp] = srcData[sp];
							destData[dp + 1] = srcData[sp + 1];
							destData[dp + 2] = srcData[sp + 2];
							destData[dp + 3] = srcData[sp + 3];
							sp += (sfx >>> 16) * 4;
						}
					}
					break;
			}
			return;
		}
		/*** Comprehensive blit (apply transformations) ***/
		final int srcRedShift = getChannelShift(srcRedMask);
		final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)];
		final int srcGreenShift = getChannelShift(srcGreenMask);
		final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)];
		final int srcBlueShift = getChannelShift(srcBlueMask);
		final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)];
		final int srcAlphaShift = getChannelShift(srcAlphaMask);
		final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)];

		final int destRedShift = getChannelShift(destRedMask);
		final int destRedWidth = getChannelWidth(destRedMask, destRedShift);
		final byte[] destReds = ANY_TO_EIGHT[destRedWidth];
		final int destRedPreShift = 8 - destRedWidth;
		final int destGreenShift = getChannelShift(destGreenMask);
		final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift);
		final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth];
		final int destGreenPreShift = 8 - destGreenWidth;
		final int destBlueShift = getChannelShift(destBlueMask);
		final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift);
		final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth];
		final int destBluePreShift = 8 - destBlueWidth;
		final int destAlphaShift = getChannelShift(destAlphaMask);
		final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift);
		final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth];
		final int destAlphaPreShift = 8 - destAlphaWidth;

		int ap = apr, alpha = alphaMode;
		int r = 0, g = 0, b = 0, a = 0;
		int rq = 0, gq = 0, bq = 0, aq = 0;
		for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
				sp = spr += (sfy >>> 16) * srcStride,
				ap = apr += (sfy >>> 16) * alphaStride,
				sfy = (sfy & 0xffff) + sfyi,
				dp = dpr += dpryi) {
			for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
					dp += dprxi,
					sfx = (sfx & 0xffff) + sfxi) {
				/*** READ NEXT PIXEL ***/
				switch (stype) {
					case TYPE_GENERIC_8: {
						final int data = srcData[sp] & 0xff;
						sp += (sfx >>> 16);
						r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
						g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
						b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
						a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
					} break;
					case TYPE_GENERIC_16_MSB: {
						final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff);
						sp += (sfx >>> 16) * 2;
						r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
						g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
						b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
						a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
					} break;
					case TYPE_GENERIC_16_LSB: {
						final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff);
						sp += (sfx >>> 16) * 2;
						r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
						g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
						b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
						a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
					} break;
					case TYPE_GENERIC_24: {
						final int data = (( ((srcData[sp] & 0xff) << 8) |
							(srcData[sp + 1] & 0xff)) << 8) |
							(srcData[sp + 2] & 0xff);
						sp += (sfx >>> 16) * 3;
						r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
						g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
						b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
						a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
					} break;
					case TYPE_GENERIC_32_MSB: {
						final int data = (( (( ((srcData[sp] & 0xff) << 8) |
							(srcData[sp + 1] & 0xff)) << 8) |
							(srcData[sp + 2] & 0xff)) << 8) |
							(srcData[sp + 3] & 0xff);
						sp += (sfx >>> 16) * 4;
						r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
						g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
						b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
						a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
					} break;
					case TYPE_GENERIC_32_LSB: {
						final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) |
							(srcData[sp + 2] & 0xff)) << 8) |
							(srcData[sp + 1] & 0xff)) << 8) |
							(srcData[sp] & 0xff);
						sp += (sfx >>> 16) * 4;
						r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
						g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
						b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
						a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
					} break;
				}

				/*** DO SPECIAL PROCESSING IF REQUIRED ***/
				switch (alphaMode) {
					case ALPHA_CHANNEL_SEPARATE:
						alpha = ((alphaData[ap] & 0xff) << 16) / 255;
						ap += (sfx >> 16);
						break;
					case ALPHA_CHANNEL_SOURCE:
						alpha = (a << 16) / 255;
						break;
					case ALPHA_MASK_UNPACKED:
						alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
						ap += (sfx >> 16);
						break;						
					case ALPHA_MASK_PACKED:
						alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
						ap += (sfx >> 16);
						break;
					case ALPHA_MASK_RGB:
						alpha = 0x10000;
						for (int i = 0; i < alphaData.length; i += 3) {
							if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) {
								alpha = 0x0000;
								break;
							}
						}
						break;
				}
				if (alpha != 0x10000) {
					if (alpha == 0x0000) continue;
					switch (dtype) {
						case TYPE_GENERIC_8: {
							final int data = destData[dp] & 0xff;
							rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
							gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
							bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
							aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
						} break;
						case TYPE_GENERIC_16_MSB: {
							final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff);
							rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
							gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
							bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
							aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
						} break;
						case TYPE_GENERIC_16_LSB: {
							final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff);
							rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
							gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
							bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
							aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
						} break;
						case TYPE_GENERIC_24: {
							final int data = (( ((destData[dp] & 0xff) << 8) |
								(destData[dp + 1] & 0xff)) << 8) |
								(destData[dp + 2] & 0xff);
							rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
							gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
							bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
							aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
						} break;
						case TYPE_GENERIC_32_MSB: {
							final int data = (( (( ((destData[dp] & 0xff) << 8) |
								(destData[dp + 1] & 0xff)) << 8) |
								(destData[dp + 2] & 0xff)) << 8) |
								(destData[dp + 3] & 0xff);
							rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
							gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
							bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
							aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
						} break;
						case TYPE_GENERIC_32_LSB: {
							final int data = (( (( ((destData[dp + 3] & 0xff) << 8) |
								(destData[dp + 2] & 0xff)) << 8) |
								(destData[dp + 1] & 0xff)) << 8) |
								(destData[dp] & 0xff);
							rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
							gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
							bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
							aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
						} break;
					}
					// Perform alpha blending
					a = aq + ((a - aq) * alpha >> 16);
					r = rq + ((r - rq) * alpha >> 16);
					g = gq + ((g - gq) * alpha >> 16);
					b = bq + ((b - bq) * alpha >> 16);
				}

				/*** WRITE NEXT PIXEL ***/
				final int data = 
					(r >>> destRedPreShift << destRedShift) |
					(g >>> destGreenPreShift << destGreenShift) |
					(b >>> destBluePreShift << destBlueShift) |
					(a >>> destAlphaPreShift << destAlphaShift);
				switch (dtype) {
					case TYPE_GENERIC_8: {
						destData[dp] = (byte) data;
					} break;
					case TYPE_GENERIC_16_MSB: {
						destData[dp] = (byte) (data >>> 8);
						destData[dp + 1] = (byte) (data & 0xff);
					} break;
					case TYPE_GENERIC_16_LSB: {
						destData[dp] = (byte) (data & 0xff);
						destData[dp + 1] = (byte) (data >>> 8);
					} break;
					case TYPE_GENERIC_24: {
						destData[dp] = (byte) (data >>> 16);
						destData[dp + 1] = (byte) (data >>> 8);
						destData[dp + 2] = (byte) (data & 0xff);
					} break;
					case TYPE_GENERIC_32_MSB: {
						destData[dp] = (byte) (data >>> 24);
						destData[dp + 1] = (byte) (data >>> 16);
						destData[dp + 2] = (byte) (data >>> 8);
						destData[dp + 3] = (byte) (data & 0xff);
					} break;
					case TYPE_GENERIC_32_LSB: {
						destData[dp] = (byte) (data & 0xff);
						destData[dp + 1] = (byte) (data >>> 8);
						destData[dp + 2] = (byte) (data >>> 16);
						destData[dp + 3] = (byte) (data >>> 24);
					} break;
				}
			}
		}			
	}

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

	public static ImageData convertImageData (ImageData source) {
		PaletteData palette = new PaletteData (0xff0000, 0xff00, 0xff);
		ImageData newSource = new ImageData (source.width, source.height, 24, palette);

		ImageDataUtil.blit (
			1,
			source.data,
			source.depth,
			source.bytesPerLine,
			(source.depth != 16) ? MSB_FIRST : LSB_FIRST,
			0,
			0,
			source.width,
			source.height,
			source.palette.redMask,
			source.palette.greenMask,
			source.palette.blueMask,
			255,
			null,
			0,
			0,
			0,
			newSource.data,
			newSource.depth,
			newSource.bytesPerLine,
			(newSource.depth != 16) ? MSB_FIRST : LSB_FIRST,
			0,
			0,
			newSource.width,
			newSource.height,
			newSource.palette.redMask,
			newSource.palette.greenMask,
			newSource.palette.blueMask,
			false,
			true);

		return newSource;
	}
}
