blob: e8aaf581f4df07b0e8e1a7477fd2a2f8c00c678d [file] [log] [blame]
package org.eclipse.swt.graphics;
/*
* Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
* This file is made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*/
import org.eclipse.swt.*;
/**
* 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 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>.
*
* @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.
*
* @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;
}
}