/* Copyright (C) 2000 Free Software Foundation This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ package java.awt.image; import java.awt.Transparency; import java.awt.color.ColorSpace; import gnu.java.awt.Buffers; /** * @author Rolf W. Rasmussen */ public class IndexColorModel extends ColorModel { private byte[] r; private byte[] g; private byte[] b; private byte[] a; private int[] argb; private byte[] cmap; private int start; private int transparent; private int size; public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b) { super(bits, nArray(bits, 3), ColorSpace.getInstance(ColorSpace.CS_sRGB), false, // no transparency false, // no premultiplied Transparency.OPAQUE, Buffers.smallestAppropriateTransferType(bits)); this.r = r; this.g = g; this.b = b; this.size = size; } public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b, int transparent) { super(bits, nArray(bits, 4), ColorSpace.getInstance(ColorSpace.CS_sRGB), true, // has transparency false, Transparency.BITMASK, Buffers.smallestAppropriateTransferType(bits)); this.r = r; this.g = g; this.b = b; this.transparent = transparent; this.size = size; } public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b, byte[] a) { super(bits, nArray(bits, 4), ColorSpace.getInstance(ColorSpace.CS_sRGB), true, // has transparency false, Transparency.BITMASK, Buffers.smallestAppropriateTransferType(bits)); this.r = r; this.g = g; this.b = b; this.a = a; this.size = size; } public IndexColorModel(int bits, int size, byte[] cmap, int start, boolean hasAlpha) { super(bits, nArray(bits, hasAlpha ? 4 : 3), ColorSpace.getInstance(ColorSpace.CS_sRGB), hasAlpha, false, hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE, Buffers.smallestAppropriateTransferType(bits)); this.cmap = cmap; this.start = start; this.size = size; } public IndexColorModel(int bits, int size, byte[] cmap, int start, boolean hasAlpha, int transparent, int transferType) { super(bits, nArray(bits, hasAlpha ? 4 : 3), ColorSpace.getInstance(ColorSpace.CS_sRGB), hasAlpha, false, hasAlpha ? Transparency.TRANSLUCENT : ((transparent < 0) ? Transparency.OPAQUE : Transparency.BITMASK), transferType); this.cmap = cmap; this.start = start; this.size = size; } public final int getMapSize() { return size; } public final int getTransparentPixel() { return transparent; } public final void getReds(byte r[]) { if (this.r == null) calcRGBArrays(); System.arraycopy(this.r, 0, r, 0, getMapSize()); } public final void getGreens(byte g[]) { if (this.g == null) calcRGBArrays(); System.arraycopy(this.g, 0, g, 0, getMapSize()); } public final void getBlues(byte b[]) { if (this.b == null) calcRGBArrays(); System.arraycopy(this.b, 0, b, 0, getMapSize()); } public final void getAlphas(byte a[]) { if (this.a == null) calcAlphaArray(); System.arraycopy(this.a, 0, a, 0, getMapSize()); } public final void getRGBs(int rgb[]) { if (this.argb == null) calcARGBArray(); System.arraycopy(this.argb, 0, rgb, 0, getMapSize()); } public int getRed(int pixel) { try { return r[pixel]; } catch (NullPointerException npe) { calcRGBArrays(); return r[pixel]; } } public int getGreen(int pixel) { try { return g[pixel]; } catch (NullPointerException npe) { calcRGBArrays(); return g[pixel]; } } public int getBlue(int pixel) { try { return b[pixel]; } catch (NullPointerException npe) { calcRGBArrays(); return b[pixel]; } } public int getAlpha(int pixel) { try { return a[pixel]; } catch (NullPointerException npe) { calcAlphaArray(); return a[pixel]; } } private void calcRGBArrays() { int j=0; boolean hasAlpha = hasAlpha(); r = new byte[size]; g = new byte[size]; b = new byte[size]; if (hasAlpha) a = new byte[size]; for (int i=0; i>> 24) & 0xff; rv = (rgb >>> 16) & 0xff; gv = (rgb >>> 8) & 0xff; bv = (rgb >>> 0) & 0xff; int pixelValue = getPixelValue(av, rv, gv, bv); /* In this color model, the whole pixel fits in the first element of the array. */ DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1); buffer.setElem(0, pixelValue); return Buffers.getData(buffer); } private int getPixelValue(int av, int rv, int gv, int bv) { if (r == null) calcRGBArrays(); if (a == null) calcAlphaArray(); int minDAlpha = 1<<8; int minDRGB = (1<<8)*(1<<8)*3; int pixelValue = -1; for (int i=0; i minDAlpha) continue; int dR = rv-(r[i]&0xff); int dG = gv-(g[i]&0xff); int dB = bv-(b[i]&0xff); int dRGB = dR*dR + dG*dG + dB*dB; if (dRGB >= minDRGB) continue; pixelValue = i; minDRGB = dRGB; } return pixelValue; } public int[] getComponents(int pixel, int[] components, int offset) { int numComponents = getNumComponents(); if (components == null) components = new int[offset + numComponents]; components[offset++] = (r[pixel]&0xff); components[offset++] = (g[pixel]&0xff); components[offset++] = (b[pixel]&0xff); if (hasAlpha()) components[offset++] = (a[pixel]&0xff); return components; } public final int[] getComponents(Object pixel, int[] components, int offset) { return getComponents(getPixelFromArray(pixel), components, offset); } public int getDataElement(int[] components, int offset) { int r = components[offset++]; int g = components[offset++]; int b = components[offset++]; int a = hasAlpha() ? components[offset++] : 255; return getPixelValue(a, r, g, b); } public Object getDataElements(int[] components, int offset, Object pixel) { int pixelValue = getDataElement(components, offset); /* In this color model, the whole pixel fits in the first element of the array. */ DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1); buffer.setElem(0, pixelValue); return Buffers.getData(buffer); } public SampleModel createCompatibleSampleModel(int w, int h) { int[] bandOffsets = {0}; return new ComponentSampleModel(transferType, w, h, 1, // pixel stride w, // scanline stride bandOffsets); } }