📄 indexcolormodel.java
字号:
} /** * Returns the red color component for the specified pixel, scaled * from 0 to 255 in the default RGB ColorSpace, sRGB. The pixel value * is specified as an int. The returned value is a * non pre-multiplied value. * @param pixel the specified pixel * @return the value of the red color component for the specified pixel */ final public int getRed(int pixel) { return (rgb[pixel] >> 16) & 0xff; } /** * Returns the green color component for the specified pixel, scaled * from 0 to 255 in the default RGB ColorSpace, sRGB. The pixel value * is specified as an int. The returned value is a * non pre-multiplied value. * @param pixel the specified pixel * @return the value of the green color component for the specified pixel */ final public int getGreen(int pixel) { return (rgb[pixel] >> 8) & 0xff; } /** * Returns the blue color component for the specified pixel, scaled * from 0 to 255 in the default RGB ColorSpace, sRGB. The pixel value * is specified as an int. The returned value is a * non pre-multiplied value. * @param pixel the specified pixel * @return the value of the blue color component for the specified pixel */ final public int getBlue(int pixel) { return rgb[pixel] & 0xff; } /** * Returns the alpha component for the specified pixel, scaled * from 0 to 255. The pixel value is specified as an int. * @param pixel the specified pixel * @return the value of the alpha component for the specified pixel */ final public int getAlpha(int pixel) { return (rgb[pixel] >> 24) & 0xff; } /** * Returns the color/alpha components of the pixel in the default * RGB color model format. The pixel value is specified as an int. * The returned value is in a non pre-multiplied format. * @param pixel the specified pixel * @return the color and alpha components of the specified pixel * @see ColorModel#getRGBdefault */ final public int getRGB(int pixel) { return rgb[pixel]; } private static final int CACHESIZE = 40; private int lookupcache[] = new int[CACHESIZE]; /** * Returns a data element array representation of a pixel in this * ColorModel, given an integer pixel representation in the * default RGB color model. This array can then be passed to the * {@link WritableRaster#setDataElements(int, int, java.lang.Object) setDataElements} * method of a {@link WritableRaster} object. If the pixel variable is * <code>null</code>, a new array is allocated. If <code>pixel</code> * is not <code>null</code>, it must be * a primitive array of type <code>transferType</code>; otherwise, a * <code>ClassCastException</code> is thrown. An * <code>ArrayIndexOutOfBoundsException</code> is * thrown if <code>pixel</code> is not large enough to hold a pixel * value for this <code>ColorModel</code>. The pixel array is returned. * <p> * Since <code>IndexColorModel</code> can be subclassed, subclasses * inherit the implementation of this method and if they don't * override it then they throw an exception if they use an * unsupported <code>transferType</code>. * * @param rgb the integer pixel representation in the default RGB * color model * @param pixel the specified pixel * @return an array representation of the specified pixel in this * <code>IndexColorModel</code>. * @throws ClassCastException if <code>pixel</code> * is not a primitive array of type <code>transferType</code> * @throws ArrayIndexOutOfBoundsException if * <code>pixel</code> is not large enough to hold a pixel value * for this <code>ColorModel</code> * @throws UnsupportedOperationException if <code>transferType</code> * is invalid * @see WritableRaster#setDataElements * @see SampleModel#setDataElements */ public synchronized Object getDataElements(int rgb, Object pixel) { int red = (rgb>>16) & 0xff; int green = (rgb>>8) & 0xff; int blue = rgb & 0xff; int alpha = (rgb>>>24); int pix = 0; for (int i = CACHESIZE - 2; i >= 0; i -= 2) { if ((pix = lookupcache[i]) == 0) { break; } if (rgb == lookupcache[i+1]) { return installpixel(pixel, ~pix); } } if (allgrayopaque) { int minDist = 256; int d; int gray = (int) (red*77 + green*150 + blue*29 + 128)/256; for (int i = 0; i < map_size; i++) { if (this.rgb[i] == 0x0) { // For allgrayopaque colormaps, entries are 0 // iff they are an invalid color and should be // ignored during color searches. continue; } d = (this.rgb[i] & 0xff) - gray; if (d < 0) d = -d; if (d < minDist) { pix = i; if (d == 0) { break; } minDist = d; } } } else if (alpha == 0) { // Return transparent pixel if we have one if (transparent_index >= 0) { pix = transparent_index; } else { // Search for smallest alpha int smallestAlpha = 256; for (int i = 0; i < map_size; i++) { int a = this.rgb[i] >>> 24; if (smallestAlpha > alpha && (validBits == null || validBits.testBit(i))) { smallestAlpha = alpha; pix = i; } } } } else { // a heuristic which says find the closest color, // after finding the closest alpha // if user wants different behavior, they can derive // a class and override this method // SLOW --- but accurate // REMIND - need a native implementation, and inverse color-map int smallestError = 255 * 255 * 255; // largest possible int smallestAlphaError = 255; if (false && red == green && green == blue) { // Grayscale } for (int i=0; i < map_size; i++) { int lutrgb = this.rgb[i]; if (lutrgb == rgb) { pix = i; break; } int tmp = (lutrgb>>>24) - alpha; if (tmp < 0) { tmp = -tmp; } if (tmp <= smallestAlphaError) { smallestAlphaError = tmp; tmp = ((lutrgb>>16) & 0xff) - red; int currentError = tmp * tmp; if (currentError < smallestError) { tmp = ((lutrgb>>8) & 0xff) - green; currentError += tmp * tmp; if (currentError < smallestError) { tmp = (lutrgb & 0xff) - blue; currentError += tmp * tmp; if (currentError < smallestError && (validBits == null || validBits.testBit(i))) { pix = i; smallestError = currentError; } } } } } } System.arraycopy(lookupcache, 2, lookupcache, 0, CACHESIZE - 2); lookupcache[CACHESIZE - 1] = rgb; lookupcache[CACHESIZE - 2] = ~pix; return installpixel(pixel, pix); } private Object installpixel(Object pixel, int pix) { switch (transferType) { case DataBuffer.TYPE_INT: int[] intObj; if (pixel == null) { pixel = intObj = new int[1]; } else { intObj = (int[]) pixel; } intObj[0] = pix; break; case DataBuffer.TYPE_BYTE: byte[] byteObj; if (pixel == null) { pixel = byteObj = new byte[1]; } else { byteObj = (byte[]) pixel; } byteObj[0] = (byte) pix; break; case DataBuffer.TYPE_USHORT: short[] shortObj; if (pixel == null) { pixel = shortObj = new short[1]; } else { shortObj = (short[]) pixel; } shortObj[0] = (short) pix; break; default: throw new UnsupportedOperationException("This method has not been "+ "implemented for transferType " + transferType); } return pixel; } /** * Returns an array of unnormalized color/alpha components for a * specified pixel in this <code>ColorModel</code>. The pixel value * is specified as an int. If the components array is <code>null</code>, * a new array is allocated. The components array is returned. * Color/alpha components are stored in the components array starting * at <code>offset</code> even if the array is allocated by this method. * An <code>ArrayIndexOutOfBoundsException</code> * is thrown if the components array is not <code>null</code> and is * not large enough to hold all the color and alpha components * starting at <code>offset</code>. * @param pixel the specified pixel * @param components the array to receive the color and alpha * components of the specified pixel * @param offset the offset into the <code>components</code> array at * which to start storing the color and alpha components * @return an array containing the color and alpha components of the * specified pixel starting at the specified offset. */ public int[] getComponents(int pixel, int[] components, int offset) { if (components == null) { components = new int[offset+numComponents]; } // REMIND: Needs to change if different color space components[offset+0] = getRed(pixel); components[offset+1] = getGreen(pixel); components[offset+2] = getBlue(pixel); if (supportsAlpha && (components.length-offset) > 3) { components[offset+3] = getAlpha(pixel); } return components; } /** * Returns an array of unnormalized color/alpha components for * a specified pixel in this <code>ColorModel</code>. The pixel * value is specified by an array of data elements of type * <code>transferType</code> passed in as an object reference. * If <code>pixel</code> is not a primitive array of type * <code>transferType</code>, a <code>ClassCastException</code> * is thrown. An <code>ArrayIndexOutOfBoundsException</code> * is thrown if <code>pixel</code> is not large enough to hold * a pixel value for this <code>ColorModel</code>. If the * <code>components</code> array is <code>null</code>, a new array * is allocated. The <code>components</code> array is returned. * Color/alpha components are stored in the <code>components</code> * array starting at <code>offset</code> even if the array is * allocated by this method. An * <code>ArrayIndexOutOfBoundsException</code> is also * thrown if the <code>components</code> array is not * <code>null</code> and is not large enough to hold all the color * and alpha components starting at <code>offset</code>. * <p> * Since <code>IndexColorModel</code> can be subclassed, subclasses * inherit the implementation of this method and if they don't * override it then they throw an exception if they use an * unsupported <code>transferType</code>. * * @param pixel the specified pixel * @param components an array that receives the color and alpha * components of the specified pixel * @param offset the index into the <code>components</code> array at * which to begin storing the color and alpha components of the * specified pixel * @return an array containing the color and alpha components of the * specified pixel starting at the specified offset. * @throws ArrayIndexOutOfBoundsException if <code>pixel</code> * is not large enough to hold a pixel value for this * <code>ColorModel</code> or if the * <code>components</code> array is not <code>null</code> * and is not large enough to hold all the color * and alpha components starting at <code>offset</code> * @throws ClassCastException if <code>pixel</code> is not a * primitive array of type <code>transferType</code> * @throws UnsupportedOperationException if <code>transferType</code> * is not one of the supported transer types */ public int[] getComponents(Object pixel, int[] components, int offset) { int intpixel; switch (transferType) { case DataBuffer.TYPE_BYTE: byte bdata[] = (byte[])pixel; intpixel = bdata[0] & 0xff; break; case DataBuffer.TYPE_USHORT: short sdata[] = (short[])pixel; intpixel = sdata[0] & 0xffff; break; case DataBuffer.TYPE_INT: int idata[] = (int[])pixel; intpixel = idata[0]; break; default: throw new UnsupportedOperationException("This method has not been "+ "implemented for transferType " + transferType); } return getComponents(intpixel, components, offset); } /** * Returns a pixel value represented as an int in this * <code>ColorModel</code> given an array of unnormalized * color/alpha components. An * <code>ArrayIndexOutOfBoundsException</code>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -