Mercurial > projects > dwt-win
changeset 9:9f69ba7a0546
PaletteData
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 25 Jan 2008 14:05:07 +0100 |
parents | 4287bcee9960 |
children | a04f5735069f |
files | dwt/graphics/PaletteData.d |
diffstat | 1 files changed, 216 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/graphics/PaletteData.d Fri Jan 25 14:05:07 2008 +0100 @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwt.graphics.PaletteData; + + +import dwt.DWT; +import dwt.graphics.RGB; + +/** + * Instances of this class describe the color data used by an image. + * <p> + * Depending on the depth of the image, the PaletteData can take one + * of two forms, indicated by the isDirect field: + * </p> + * <dl> + * <dt> + * <em>isDirect is false</em> + * </dt> + * <dd> + * If isDirect is <code>false</code>, this palette is an indexed + * palette which maps pixel values to RGBs. The actual RGB values + * may be retrieved by using the getRGBs() method. + * </dd> + * <dt> + * <em>isDirect is true</em> + * </dt> + * <dd> + * If isDirect is <code>true</code>, this palette is a direct color + * palette. Instead of containing RGB values, it contains red, + * green and blue mask and shift information which indicates how + * the color components may be extracted from a given pixel. + * This means that the RGB value is actually encoded in the pixel value. + * <p> + * In this case, the shift data is the number of bits required to shift + * the RGB value to the left in order to align the high bit of the + * corresponding mask with the high bit of the first byte. This number + * may be negative, so care must be taken when shifting. For example, + * with a red mask of 0xFF0000, the red shift would be -16. With a red + * mask of 0x1F, the red shift would be 3. + * </p> + * </dd> + * </dl> + * + * @see Image + * @see RGB + */ + +public final class PaletteData { + + /** + * true if the receiver is a direct palette, + * and false otherwise + */ + public bool 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 this(RGB[] colors) { + if (colors is null) DWT.error(DWT.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 this(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>RGB</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 is null) DWT.error(DWT.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] is rgb ) return i; + } + /* The RGB did not exist in the palette */ + DWT.error(DWT.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) { + DWT.error(DWT.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) !is 0) return 7 - i; + } + return 32; +} + +}