ComponentColorModel.java [plain text]
package java.awt.image;
import gnu.java.awt.Buffers;
import java.awt.Point;
import java.awt.color.ColorSpace;
public class ComponentColorModel extends ColorModel
{
private static int sum(int[] values)
{
int sum = 0;
for (int i=0; i<values.length; i++)
sum += values[i];
return sum;
}
public ComponentColorModel(ColorSpace colorSpace, int[] bits,
boolean hasAlpha,
boolean isAlphaPremultiplied,
int transparency, int transferType)
{
super(sum(bits), bits, colorSpace, hasAlpha, isAlphaPremultiplied,
transparency, transferType);
}
public ComponentColorModel(ColorSpace colorSpace,
boolean hasAlpha,
boolean isAlphaPremultiplied,
int transparency, int transferType)
{
this(colorSpace, null, hasAlpha, isAlphaPremultiplied,
transparency, transferType);
}
public int getRed(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
return (int) getRGBFloat(pixel)[0];
}
public int getGreen(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
return (int) getRGBFloat(pixel)[0];
}
public int getBlue(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
return (int) getRGBFloat(pixel)[0];
}
public int getAlpha(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
int shift = 8 - getComponentSize(getNumColorComponents());
if (shift >= 0) return pixel << shift;
return pixel >> (-shift);
}
public int getRGB(int pixel)
{
float[] rgb = getRGBFloat(pixel);
int ret = getRGB(rgb);
if (hasAlpha()) ret |= getAlpha(pixel) << 24;
return ret;
}
private float[] getRGBFloat(int pixel)
{
float[] data = { pixel };
return cspace.toRGB(data);
}
private float[] getRGBFloat(Object inData)
{
DataBuffer buffer =
Buffers.createBufferFromData(transferType, inData,
getNumComponents());
int colors = getNumColorComponents();
float[] data = new float[colors];
for (int i=0; i<colors; i++)
{
float maxValue = (1<<getComponentSize(i))-1;
data[i] = buffer.getElemFloat(i)/maxValue;
}
float[] rgb = cspace.toRGB(data);
return rgb;
}
public int getRed(Object inData)
{
return (int) getRGBFloat(inData)[0]*255;
}
public int getGreen(Object inData)
{
return (int) getRGBFloat(inData)[1]*255;
}
public int getBlue(Object inData)
{
return (int) getRGBFloat(inData)[2]*255;
}
public int getAlpha(Object inData)
{
DataBuffer buffer =
Buffers.createBufferFromData(transferType, inData,
getNumComponents());
int shift = 8 - getComponentSize(getNumColorComponents());
int alpha = buffer.getElem(getNumColorComponents());
if (shift >= 0) return alpha << shift;
return alpha >> (-shift);
}
private int getRGB(float[] rgb)
{
int ret =
(((int) (rgb[0]*255F)) << 16) |
(((int) (rgb[1]*255F)) << 8) |
(((int) (rgb[2]*255F)) << 0);
return ret;
}
public int getRGB(Object inData)
{
float[] rgb = getRGBFloat(inData);
int ret = getRGB(rgb);
if (hasAlpha()) ret |= getAlpha(inData) << 24;
return ret;
}
public Object getDataElements(int rgb, Object pixel)
{
float[] rgbFloats = {
((rgb >> 16)&0xff)/255.0F,
((rgb >> 8)&0xff)/255.0F,
((rgb >> 0)&0xff)/255.0F
};
float[] data = cspace.fromRGB(rgbFloats);
DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
getNumComponents());
int numColors = getNumColorComponents();
if (hasAlpha())
{
float alpha = ((rgb >> 24)&0xff)/255.0F;
if (isAlphaPremultiplied()) {
for (int i=0; i<numColors; i++)
data[i] *= alpha;
}
alpha *= (1<<(bits[numColors]-1));
buffer.setElemFloat(numColors, alpha);
}
for (int i=0; i<numColors; i++)
{
float value = data[i]*(1<<(bits[i]-1));
buffer.setElemFloat(i, value);
}
return Buffers.getData(buffer);
}
public int[] getComponents(int pixel, int[] components, int offset)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
if (components == null)
components = new int[getNumComponents() + offset];
components[offset] = pixel;
return components;
}
public int[] getComponents(Object pixel, int[] components, int offset)
{
DataBuffer buffer = Buffers.createBuffer(transferType, pixel,
getNumComponents());
int numComponents = getNumComponents();
if (components == null)
components = new int[numComponents + offset];
for (int i=0; i<numComponents; i++)
components[offset++] = buffer.getElem(i);
return components;
}
public int getDataElement(int[] components, int offset)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
return components[offset];
}
public Object getDataElements(int[] components, int offset, Object obj)
{
DataBuffer buffer = Buffers.createBuffer(transferType, obj,
getNumComponents());
int numComponents = getNumComponents();
for (int i=0; i<numComponents; i++)
buffer.setElem(i, components[offset++]);
return Buffers.getData(buffer);
}
public ColorModel coerceData(WritableRaster raster,
boolean isAlphaPremultiplied) {
if (this.isAlphaPremultiplied == isAlphaPremultiplied)
return this;
super.coerceData(raster, isAlphaPremultiplied);
return new ComponentColorModel(cspace, bits, hasAlpha(),
isAlphaPremultiplied, transparency, transferType);
}
public boolean isCompatibleRaster(Raster raster)
{
return super.isCompatibleRaster(raster);
}
public WritableRaster createCompatibleWritableRaster(int w, int h)
{
SampleModel sm = createCompatibleSampleModel(w, h);
Point origin = new Point(0, 0);
return Raster.createWritableRaster(sm, origin);
}
public SampleModel createCompatibleSampleModel(int w, int h)
{
int pixelStride, scanlineStride;
int[] bandOffsets;
pixelStride = getNumComponents();
scanlineStride = pixelStride * w;
bandOffsets = new int[pixelStride];
for (int i = 0; i < pixelStride; i++)
bandOffsets[i] = i;
switch (transferType)
{
case DataBuffer.TYPE_BYTE:
case DataBuffer.TYPE_USHORT:
return new PixelInterleavedSampleModel(transferType, w, h,
pixelStride,
scanlineStride,
bandOffsets);
default:
return new ComponentSampleModel(transferType, w, h,
pixelStride,
scanlineStride,
bandOffsets);
}
}
public boolean isCompatibleSampleModel(SampleModel sm)
{
return
(sm instanceof ComponentSampleModel) &&
super.isCompatibleSampleModel(sm);
}
public WritableRaster getAlphaRaster(WritableRaster raster)
{
if (!hasAlpha()) return null;
SampleModel sm = raster.getSampleModel();
int[] alphaBand = { sm.getNumBands() - 1 };
SampleModel alphaModel = sm.createSubsetSampleModel(alphaBand);
DataBuffer buffer = raster.getDataBuffer();
Point origin = new Point(0, 0);
return Raster.createWritableRaster(alphaModel, buffer, origin);
}
public boolean equals(Object obj)
{
if (!(obj instanceof ComponentColorModel)) return false;
return super.equals(obj);
}
}