Source Code Cross Referenced for IndexColorModel.java in  » 6.0-JDK-Core » AWT » java » awt » image » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » AWT » java.awt.image 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1995-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package java.awt.image;
0027
0028        import java.awt.Transparency;
0029        import java.awt.color.ColorSpace;
0030        import java.math.BigInteger;
0031
0032        /**
0033         * The <code>IndexColorModel</code> class is a <code>ColorModel</code>
0034         * class that works with pixel values consisting of a
0035         * single sample that is an index into a fixed colormap in the default
0036         * sRGB color space.  The colormap specifies red, green, blue, and
0037         * optional alpha components corresponding to each index.  All components
0038         * are represented in the colormap as 8-bit unsigned integral values.
0039         * Some constructors allow the caller to specify "holes" in the colormap
0040         * by indicating which colormap entries are valid and which represent
0041         * unusable colors via the bits set in a <code>BigInteger</code> object.
0042         * This color model is similar to an X11 PseudoColor visual.
0043         * <p>
0044         * Some constructors provide a means to specify an alpha component
0045         * for each pixel in the colormap, while others either provide no
0046         * such means or, in some cases, a flag to indicate whether the
0047         * colormap data contains alpha values.  If no alpha is supplied to
0048         * the constructor, an opaque alpha component (alpha = 1.0) is
0049         * assumed for each entry.
0050         * An optional transparent pixel value can be supplied that indicates a
0051         * pixel to be made completely transparent, regardless of any alpha
0052         * component supplied or assumed for that pixel value.
0053         * Note that the color components in the colormap of an
0054         * <code>IndexColorModel</code> objects are never pre-multiplied with
0055         * the alpha components.
0056         * <p>
0057         * <a name="transparency">
0058         * The transparency of an <code>IndexColorModel</code> object is
0059         * determined by examining the alpha components of the colors in the
0060         * colormap and choosing the most specific value after considering
0061         * the optional alpha values and any transparent index specified.
0062         * The transparency value is <code>Transparency.OPAQUE</code>
0063         * only if all valid colors in
0064         * the colormap are opaque and there is no valid transparent pixel.
0065         * If all valid colors
0066         * in the colormap are either completely opaque (alpha = 1.0) or
0067         * completely transparent (alpha = 0.0), which typically occurs when
0068         * a valid transparent pixel is specified,
0069         * the value is <code>Transparency.BITMASK</code>.
0070         * Otherwise, the value is <code>Transparency.TRANSLUCENT</code>, indicating
0071         * that some valid color has an alpha component that is
0072         * neither completely transparent nor completely opaque
0073         * (0.0 &lt; alpha &lt; 1.0).
0074         * </a>
0075         *
0076         * <p>
0077         * If an <code>IndexColorModel</code> object has 
0078         * a transparency value of <code>Transparency.OPAQUE</code>,
0079         * then the <code>hasAlpha</code> 
0080         * and <code>getNumComponents</code> methods
0081         * (both inherited from <code>ColorModel</code>) 
0082         * return false and 3, respectively.
0083         * For any other transparency value,
0084         * <code>hasAlpha</code> returns true
0085         * and <code>getNumComponents</code> returns 4.
0086         *
0087         * <p>
0088         * <a name="index_values">
0089         * The values used to index into the colormap are taken from the least
0090         * significant <em>n</em> bits of pixel representations where
0091         * <em>n</em> is based on the pixel size specified in the constructor.
0092         * For pixel sizes smaller than 8 bits, <em>n</em> is rounded up to a
0093         * power of two (3 becomes 4 and 5,6,7 become 8).
0094         * For pixel sizes between 8 and 16 bits, <em>n</em> is equal to the
0095         * pixel size.
0096         * Pixel sizes larger than 16 bits are not supported by this class.
0097         * Higher order bits beyond <em>n</em> are ignored in pixel representations.
0098         * Index values greater than or equal to the map size, but less than
0099         * 2<sup><em>n</em></sup>, are undefined and return 0 for all color and
0100         * alpha components.
0101         * <p>
0102         * For those methods that use a primitive array pixel representation of
0103         * type <code>transferType</code>, the array length is always one.  
0104         * The transfer types supported are <code>DataBuffer.TYPE_BYTE</code> and 
0105         * <code>DataBuffer.TYPE_USHORT</code>.  A single int pixel 
0106         * representation is valid for all objects of this class, since it is 
0107         * always possible to represent pixel values used with this class in a 
0108         * single int.  Therefore, methods that use this representation do 
0109         * not throw an <code>IllegalArgumentException</code> due to an invalid 
0110         * pixel value.
0111         * <p>
0112         * Many of the methods in this class are final.  The reason for
0113         * this is that the underlying native graphics code makes assumptions
0114         * about the layout and operation of this class and those assumptions
0115         * are reflected in the implementations of the methods here that are
0116         * marked final.  You can subclass this class for other reasons, but
0117         * you cannot override or modify the behaviour of those methods.
0118         *
0119         * @see ColorModel
0120         * @see ColorSpace
0121         * @see DataBuffer
0122         *
0123         * @version 10 Feb 1997
0124         */
0125        public class IndexColorModel extends ColorModel {
0126            private int rgb[];
0127            private int map_size;
0128            private int pixel_mask;
0129            private int transparent_index = -1;
0130            private boolean allgrayopaque;
0131            private BigInteger validBits;
0132
0133            private static int[] opaqueBits = { 8, 8, 8 };
0134            private static int[] alphaBits = { 8, 8, 8, 8 };
0135
0136            static private native void initIDs();
0137
0138            static {
0139                ColorModel.loadLibraries();
0140                initIDs();
0141            }
0142
0143            /**
0144             * Constructs an <code>IndexColorModel</code> from the specified 
0145             * arrays of red, green, and blue components.  Pixels described 
0146             * by this color model all have alpha components of 255 
0147             * unnormalized (1.0&nbsp;normalized), which means they
0148             * are fully opaque.  All of the arrays specifying the color 
0149             * components must have at least the specified number of entries.  
0150             * The <code>ColorSpace</code> is the default sRGB space.
0151             * Since there is no alpha information in any of the arguments
0152             * to this constructor, the transparency value is always 
0153             * <code>Transparency.OPAQUE</code>.
0154             * The transfer type is the smallest of <code>DataBuffer.TYPE_BYTE</code>
0155             * or <code>DataBuffer.TYPE_USHORT</code> that can hold a single pixel.
0156             * @param bits	the number of bits each pixel occupies
0157             * @param size	the size of the color component arrays
0158             * @param r		the array of red color components
0159             * @param g		the array of green color components
0160             * @param b		the array of blue color components
0161             * @throws IllegalArgumentException if <code>bits</code> is less
0162             *         than 1 or greater than 16
0163             * @throws IllegalArgumentException if <code>size</code> is less
0164             *         than 1
0165             */
0166            public IndexColorModel(int bits, int size, byte r[], byte g[],
0167                    byte b[]) {
0168                super (bits, opaqueBits, ColorSpace
0169                        .getInstance(ColorSpace.CS_sRGB), false, false, OPAQUE,
0170                        ColorModel.getDefaultTransferType(bits));
0171                if (bits < 1 || bits > 16) {
0172                    throw new IllegalArgumentException(
0173                            "Number of bits must be between" + " 1 and 16.");
0174                }
0175                setRGBs(size, r, g, b, null);
0176                calculatePixelMask();
0177            }
0178
0179            /**
0180             * Constructs an <code>IndexColorModel</code> from the given arrays 
0181             * of red, green, and blue components.  Pixels described by this color
0182             * model all have alpha components of 255 unnormalized 
0183             * (1.0&nbsp;normalized), which means they are fully opaque, except 
0184             * for the indicated pixel to be made transparent.  All of the arrays
0185             * specifying the color components must have at least the specified
0186             * number of entries.
0187             * The <code>ColorSpace</code> is the default sRGB space.
0188             * The transparency value may be <code>Transparency.OPAQUE</code> or
0189             * <code>Transparency.BITMASK</code> depending on the arguments, as
0190             * specified in the <a href="#transparency">class description</a> above.
0191             * The transfer type is the smallest of <code>DataBuffer.TYPE_BYTE</code>
0192             * or <code>DataBuffer.TYPE_USHORT</code> that can hold a
0193             * single pixel.
0194             * @param bits	the number of bits each pixel occupies
0195             * @param size	the size of the color component arrays
0196             * @param r		the array of red color components
0197             * @param g		the array of green color components
0198             * @param b		the array of blue color components
0199             * @param trans	the index of the transparent pixel
0200             * @throws IllegalArgumentException if <code>bits</code> is less than
0201             *          1 or greater than 16
0202             * @throws IllegalArgumentException if <code>size</code> is less than
0203             *          1
0204             */
0205            public IndexColorModel(int bits, int size, byte r[], byte g[],
0206                    byte b[], int trans) {
0207                super (bits, opaqueBits, ColorSpace
0208                        .getInstance(ColorSpace.CS_sRGB), false, false, OPAQUE,
0209                        ColorModel.getDefaultTransferType(bits));
0210                if (bits < 1 || bits > 16) {
0211                    throw new IllegalArgumentException(
0212                            "Number of bits must be between" + " 1 and 16.");
0213                }
0214                setRGBs(size, r, g, b, null);
0215                setTransparentPixel(trans);
0216                calculatePixelMask();
0217            }
0218
0219            /**
0220             * Constructs an <code>IndexColorModel</code> from the given 
0221             * arrays of red, green, blue and alpha components.  All of the 
0222             * arrays specifying the components must have at least the specified 
0223             * number of entries.
0224             * The <code>ColorSpace</code> is the default sRGB space.
0225             * The transparency value may be any of <code>Transparency.OPAQUE</code>,
0226             * <code>Transparency.BITMASK</code>,
0227             * or <code>Transparency.TRANSLUCENT</code>
0228             * depending on the arguments, as specified
0229             * in the <a href="#transparency">class description</a> above.
0230             * The transfer type is the smallest of <code>DataBuffer.TYPE_BYTE</code>
0231             * or <code>DataBuffer.TYPE_USHORT</code> that can hold a single pixel.
0232             * @param bits	the number of bits each pixel occupies
0233             * @param size	the size of the color component arrays
0234             * @param r		the array of red color components
0235             * @param g		the array of green color components
0236             * @param b		the array of blue color components
0237             * @param a		the array of alpha value components
0238             * @throws IllegalArgumentException if <code>bits</code> is less
0239             *           than 1 or greater than 16
0240             * @throws IllegalArgumentException if <code>size</code> is less
0241             *           than 1
0242             */
0243            public IndexColorModel(int bits, int size, byte r[], byte g[],
0244                    byte b[], byte a[]) {
0245                super (bits, alphaBits, ColorSpace
0246                        .getInstance(ColorSpace.CS_sRGB), true, false,
0247                        TRANSLUCENT, ColorModel.getDefaultTransferType(bits));
0248                if (bits < 1 || bits > 16) {
0249                    throw new IllegalArgumentException(
0250                            "Number of bits must be between" + " 1 and 16.");
0251                }
0252                setRGBs(size, r, g, b, a);
0253                calculatePixelMask();
0254            }
0255
0256            /**
0257             * Constructs an <code>IndexColorModel</code> from a single 
0258             * array of interleaved red, green, blue and optional alpha 
0259             * components.  The array must have enough values in it to 
0260             * fill all of the needed component arrays of the specified 
0261             * size.  The <code>ColorSpace</code> is the default sRGB space.
0262             * The transparency value may be any of <code>Transparency.OPAQUE</code>,
0263             * <code>Transparency.BITMASK</code>,
0264             * or <code>Transparency.TRANSLUCENT</code>
0265             * depending on the arguments, as specified
0266             * in the <a href="#transparency">class description</a> above.
0267             * The transfer type is the smallest of
0268             * <code>DataBuffer.TYPE_BYTE</code> or <code>DataBuffer.TYPE_USHORT</code> 
0269             * that can hold a single pixel.
0270             * 
0271             * @param bits	the number of bits each pixel occupies
0272             * @param size	the size of the color component arrays
0273             * @param cmap	the array of color components
0274             * @param start	the starting offset of the first color component
0275             * @param hasalpha	indicates whether alpha values are contained in
0276             *			the <code>cmap</code> array
0277             * @throws IllegalArgumentException if <code>bits</code> is less
0278             *           than 1 or greater than 16
0279             * @throws IllegalArgumentException if <code>size</code> is less
0280             *           than 1
0281             */
0282            public IndexColorModel(int bits, int size, byte cmap[], int start,
0283                    boolean hasalpha) {
0284                this (bits, size, cmap, start, hasalpha, -1);
0285                if (bits < 1 || bits > 16) {
0286                    throw new IllegalArgumentException(
0287                            "Number of bits must be between" + " 1 and 16.");
0288                }
0289            }
0290
0291            /**
0292             * Constructs an <code>IndexColorModel</code> from a single array of 
0293             * interleaved red, green, blue and optional alpha components.  The 
0294             * specified transparent index represents a pixel that is made
0295             * entirely transparent regardless of any alpha value specified
0296             * for it.  The array must have enough values in it to fill all
0297             * of the needed component arrays of the specified size.
0298             * The <code>ColorSpace</code> is the default sRGB space.
0299             * The transparency value may be any of <code>Transparency.OPAQUE</code>,
0300             * <code>Transparency.BITMASK</code>,
0301             * or <code>Transparency.TRANSLUCENT</code>
0302             * depending on the arguments, as specified
0303             * in the <a href="#transparency">class description</a> above.
0304             * The transfer type is the smallest of
0305             * <code>DataBuffer.TYPE_BYTE</code> or <code>DataBuffer.TYPE_USHORT</code>
0306             * that can hold a single pixel.
0307             * @param bits	the number of bits each pixel occupies
0308             * @param size	the size of the color component arrays
0309             * @param cmap	the array of color components
0310             * @param start	the starting offset of the first color component
0311             * @param hasalpha	indicates whether alpha values are contained in
0312             *			the <code>cmap</code> array
0313             * @param trans	the index of the fully transparent pixel
0314             * @throws IllegalArgumentException if <code>bits</code> is less than
0315             *               1 or greater than 16
0316             * @throws IllegalArgumentException if <code>size</code> is less than
0317             *               1
0318             */
0319            public IndexColorModel(int bits, int size, byte cmap[], int start,
0320                    boolean hasalpha, int trans) {
0321                // REMIND: This assumes the ordering: RGB[A]
0322                super (bits, opaqueBits, ColorSpace
0323                        .getInstance(ColorSpace.CS_sRGB), false, false, OPAQUE,
0324                        ColorModel.getDefaultTransferType(bits));
0325
0326                if (bits < 1 || bits > 16) {
0327                    throw new IllegalArgumentException(
0328                            "Number of bits must be between" + " 1 and 16.");
0329                }
0330                if (size < 1) {
0331                    throw new IllegalArgumentException("Map size (" + size
0332                            + ") must be >= 1");
0333                }
0334                map_size = size;
0335                rgb = new int[calcRealMapSize(bits, size)];
0336                int j = start;
0337                int alpha = 0xff;
0338                boolean allgray = true;
0339                int transparency = OPAQUE;
0340                for (int i = 0; i < size; i++) {
0341                    int r = cmap[j++] & 0xff;
0342                    int g = cmap[j++] & 0xff;
0343                    int b = cmap[j++] & 0xff;
0344                    allgray = allgray && (r == g) && (g == b);
0345                    if (hasalpha) {
0346                        alpha = cmap[j++] & 0xff;
0347                        if (alpha != 0xff) {
0348                            if (alpha == 0x00) {
0349                                if (transparency == OPAQUE) {
0350                                    transparency = BITMASK;
0351                                }
0352                                if (transparent_index < 0) {
0353                                    transparent_index = i;
0354                                }
0355                            } else {
0356                                transparency = TRANSLUCENT;
0357                            }
0358                            allgray = false;
0359                        }
0360                    }
0361                    rgb[i] = (alpha << 24) | (r << 16) | (g << 8) | b;
0362                }
0363                this .allgrayopaque = allgray;
0364                setTransparency(transparency);
0365                setTransparentPixel(trans);
0366                calculatePixelMask();
0367            }
0368
0369            /**
0370             * Constructs an <code>IndexColorModel</code> from an array of 
0371             * ints where each int is comprised of red, green, blue, and 
0372             * optional alpha components in the default RGB color model format.  
0373             * The specified transparent index represents a pixel that is made
0374             * entirely transparent regardless of any alpha value specified
0375             * for it.  The array must have enough values in it to fill all
0376             * of the needed component arrays of the specified size.
0377             * The <code>ColorSpace</code> is the default sRGB space.
0378             * The transparency value may be any of <code>Transparency.OPAQUE</code>,
0379             * <code>Transparency.BITMASK</code>,
0380             * or <code>Transparency.TRANSLUCENT</code>
0381             * depending on the arguments, as specified
0382             * in the <a href="#transparency">class description</a> above.
0383             * @param bits	the number of bits each pixel occupies
0384             * @param size	the size of the color component arrays
0385             * @param cmap	the array of color components
0386             * @param start	the starting offset of the first color component
0387             * @param hasalpha	indicates whether alpha values are contained in
0388             *			the <code>cmap</code> array
0389             * @param trans	the index of the fully transparent pixel
0390             * @param transferType the data type of the array used to represent
0391             *           pixel values.  The data type must be either 
0392             *           <code>DataBuffer.TYPE_BYTE</code> or
0393             *           <code>DataBuffer.TYPE_USHORT</code>.
0394             * @throws IllegalArgumentException if <code>bits</code> is less
0395             *           than 1 or greater than 16
0396             * @throws IllegalArgumentException if <code>size</code> is less
0397             *           than 1
0398             * @throws IllegalArgumentException if <code>transferType</code> is not
0399             *           one of <code>DataBuffer.TYPE_BYTE</code> or
0400             *           <code>DataBuffer.TYPE_USHORT</code>
0401             */
0402            public IndexColorModel(int bits, int size, int cmap[], int start,
0403                    boolean hasalpha, int trans, int transferType) {
0404                // REMIND: This assumes the ordering: RGB[A]
0405                super (bits, opaqueBits, ColorSpace
0406                        .getInstance(ColorSpace.CS_sRGB), false, false, OPAQUE,
0407                        transferType);
0408
0409                if (bits < 1 || bits > 16) {
0410                    throw new IllegalArgumentException(
0411                            "Number of bits must be between" + " 1 and 16.");
0412                }
0413                if (size < 1) {
0414                    throw new IllegalArgumentException("Map size (" + size
0415                            + ") must be >= 1");
0416                }
0417                if ((transferType != DataBuffer.TYPE_BYTE)
0418                        && (transferType != DataBuffer.TYPE_USHORT)) {
0419                    throw new IllegalArgumentException(
0420                            "transferType must be either"
0421                                    + "DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT");
0422                }
0423
0424                setRGBs(size, cmap, start, hasalpha);
0425                setTransparentPixel(trans);
0426                calculatePixelMask();
0427            }
0428
0429            /**
0430             * Constructs an <code>IndexColorModel</code> from an 
0431             * <code>int</code> array where each <code>int</code> is 
0432             * comprised of red, green, blue, and alpha            
0433             * components in the default RGB color model format.  
0434             * The array must have enough values in it to fill all
0435             * of the needed component arrays of the specified size.
0436             * The <code>ColorSpace</code> is the default sRGB space.  
0437             * The transparency value may be any of <code>Transparency.OPAQUE</code>,
0438             * <code>Transparency.BITMASK</code>,
0439             * or <code>Transparency.TRANSLUCENT</code>
0440             * depending on the arguments, as specified
0441             * in the <a href="#transparency">class description</a> above.
0442             * The transfer type must be one of <code>DataBuffer.TYPE_BYTE</code>
0443             * <code>DataBuffer.TYPE_USHORT</code>.
0444             * The <code>BigInteger</code> object specifies the valid/invalid pixels
0445             * in the <code>cmap</code> array.  A pixel is valid if the 
0446             * <code>BigInteger</code> value at that index is set, and is invalid
0447             * if the <code>BigInteger</code> bit  at that index is not set.
0448             * @param bits the number of bits each pixel occupies
0449             * @param size the size of the color component array
0450             * @param cmap the array of color components
0451             * @param start the starting offset of the first color component
0452             * @param transferType the specified data type
0453             * @param validBits a <code>BigInteger</code> object.  If a bit is
0454             *    set in the BigInteger, the pixel at that index is valid.
0455             *    If a bit is not set, the pixel at that index
0456             *    is considered invalid.  If null, all pixels are valid.
0457             *    Only bits from 0 to the map size are considered.
0458             * @throws IllegalArgumentException if <code>bits</code> is less
0459             *           than 1 or greater than 16
0460             * @throws IllegalArgumentException if <code>size</code> is less
0461             *           than 1
0462             * @throws IllegalArgumentException if <code>transferType</code> is not
0463             *           one of <code>DataBuffer.TYPE_BYTE</code> or
0464             *           <code>DataBuffer.TYPE_USHORT</code>
0465             *    
0466             * @since 1.3
0467             */
0468            public IndexColorModel(int bits, int size, int cmap[], int start,
0469                    int transferType, BigInteger validBits) {
0470                super (bits, alphaBits, ColorSpace
0471                        .getInstance(ColorSpace.CS_sRGB), true, false,
0472                        TRANSLUCENT, transferType);
0473
0474                if (bits < 1 || bits > 16) {
0475                    throw new IllegalArgumentException(
0476                            "Number of bits must be between" + " 1 and 16.");
0477                }
0478                if (size < 1) {
0479                    throw new IllegalArgumentException("Map size (" + size
0480                            + ") must be >= 1");
0481                }
0482                if ((transferType != DataBuffer.TYPE_BYTE)
0483                        && (transferType != DataBuffer.TYPE_USHORT)) {
0484                    throw new IllegalArgumentException(
0485                            "transferType must be either"
0486                                    + "DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT");
0487                }
0488
0489                if (validBits != null) {
0490                    // Check to see if it is all valid
0491                    for (int i = 0; i < size; i++) {
0492                        if (!validBits.testBit(i)) {
0493                            this .validBits = validBits;
0494                            break;
0495                        }
0496                    }
0497                }
0498
0499                setRGBs(size, cmap, start, true);
0500                calculatePixelMask();
0501            }
0502
0503            private void setRGBs(int size, byte r[], byte g[], byte b[],
0504                    byte a[]) {
0505                if (size < 1) {
0506                    throw new IllegalArgumentException("Map size (" + size
0507                            + ") must be >= 1");
0508                }
0509                map_size = size;
0510                rgb = new int[calcRealMapSize(pixel_bits, size)];
0511                int alpha = 0xff;
0512                int transparency = OPAQUE;
0513                boolean allgray = true;
0514                for (int i = 0; i < size; i++) {
0515                    int rc = r[i] & 0xff;
0516                    int gc = g[i] & 0xff;
0517                    int bc = b[i] & 0xff;
0518                    allgray = allgray && (rc == gc) && (gc == bc);
0519                    if (a != null) {
0520                        alpha = a[i] & 0xff;
0521                        if (alpha != 0xff) {
0522                            if (alpha == 0x00) {
0523                                if (transparency == OPAQUE) {
0524                                    transparency = BITMASK;
0525                                }
0526                                if (transparent_index < 0) {
0527                                    transparent_index = i;
0528                                }
0529                            } else {
0530                                transparency = TRANSLUCENT;
0531                            }
0532                            allgray = false;
0533                        }
0534                    }
0535                    rgb[i] = (alpha << 24) | (rc << 16) | (gc << 8) | bc;
0536                }
0537                this .allgrayopaque = allgray;
0538                setTransparency(transparency);
0539            }
0540
0541            private void setRGBs(int size, int cmap[], int start,
0542                    boolean hasalpha) {
0543                map_size = size;
0544                rgb = new int[calcRealMapSize(pixel_bits, size)];
0545                int j = start;
0546                int transparency = OPAQUE;
0547                boolean allgray = true;
0548                BigInteger validBits = this .validBits;
0549                for (int i = 0; i < size; i++, j++) {
0550                    if (validBits != null && !validBits.testBit(i)) {
0551                        continue;
0552                    }
0553                    int cmaprgb = cmap[j];
0554                    int r = (cmaprgb >> 16) & 0xff;
0555                    int g = (cmaprgb >> 8) & 0xff;
0556                    int b = (cmaprgb) & 0xff;
0557                    allgray = allgray && (r == g) && (g == b);
0558                    if (hasalpha) {
0559                        int alpha = cmaprgb >>> 24;
0560                        if (alpha != 0xff) {
0561                            if (alpha == 0x00) {
0562                                if (transparency == OPAQUE) {
0563                                    transparency = BITMASK;
0564                                }
0565                                if (transparent_index < 0) {
0566                                    transparent_index = i;
0567                                }
0568                            } else {
0569                                transparency = TRANSLUCENT;
0570                            }
0571                            allgray = false;
0572                        }
0573                    } else {
0574                        cmaprgb |= 0xff000000;
0575                    }
0576                    rgb[i] = cmaprgb;
0577                }
0578                this .allgrayopaque = allgray;
0579                setTransparency(transparency);
0580            }
0581
0582            private int calcRealMapSize(int bits, int size) {
0583                int newSize = Math.max(1 << bits, size);
0584                return Math.max(newSize, 256);
0585            }
0586
0587            private BigInteger getAllValid() {
0588                int numbytes = (map_size + 7) / 8;
0589                byte[] valid = new byte[numbytes];
0590                java.util.Arrays.fill(valid, (byte) 0xff);
0591                valid[0] = (byte) (0xff >>> (numbytes * 8 - map_size));
0592
0593                return new BigInteger(1, valid);
0594            }
0595
0596            /**
0597             * Returns the transparency.  Returns either OPAQUE, BITMASK,
0598             * or TRANSLUCENT
0599             * @return the transparency of this <code>IndexColorModel</code> 
0600             * @see Transparency#OPAQUE
0601             * @see Transparency#BITMASK
0602             * @see Transparency#TRANSLUCENT
0603             */
0604            public int getTransparency() {
0605                return transparency;
0606            }
0607
0608            /**
0609             * Returns an array of the number of bits for each color/alpha component.
0610             * The array contains the color components in the order red, green,
0611             * blue, followed by the alpha component, if present.
0612             * @return an array containing the number of bits of each color 
0613             *         and alpha component of this <code>IndexColorModel</code>
0614             */
0615            public int[] getComponentSize() {
0616                if (nBits == null) {
0617                    if (supportsAlpha) {
0618                        nBits = new int[4];
0619                        nBits[3] = 8;
0620                    } else {
0621                        nBits = new int[3];
0622                    }
0623                    nBits[0] = nBits[1] = nBits[2] = 8;
0624                }
0625                return nBits;
0626            }
0627
0628            /**
0629             * Returns the size of the color/alpha component arrays in this
0630             * <code>IndexColorModel</code>.
0631             * @return the size of the color and alpha component arrays.
0632             */
0633            final public int getMapSize() {
0634                return map_size;
0635            }
0636
0637            /**
0638             * Returns the index of a transparent pixel in this
0639             * <code>IndexColorModel</code> or -1 if there is no pixel
0640             * with an alpha value of 0.  If a transparent pixel was
0641             * explicitly specified in one of the constructors by its
0642             * index, then that index will be preferred, otherwise,
0643             * the index of any pixel which happens to be fully transparent
0644             * may be returned.
0645             * @return the index of a transparent pixel in this
0646             *         <code>IndexColorModel</code> object, or -1 if there
0647             *         is no such pixel
0648             */
0649            final public int getTransparentPixel() {
0650                return transparent_index;
0651            }
0652
0653            /**
0654             * Copies the array of red color components into the specified array.  
0655             * Only the initial entries of the array as specified by 
0656             * {@link #getMapSize() getMapSize} are written.
0657             * @param r the specified array into which the elements of the 
0658             *      array of red color components are copied 
0659             */
0660            final public void getReds(byte r[]) {
0661                for (int i = 0; i < map_size; i++) {
0662                    r[i] = (byte) (rgb[i] >> 16);
0663                }
0664            }
0665
0666            /**
0667             * Copies the array of green color components into the specified array.  
0668             * Only the initial entries of the array as specified by 
0669             * <code>getMapSize</code> are written.
0670             * @param g the specified array into which the elements of the 
0671             *      array of green color components are copied 
0672             */
0673            final public void getGreens(byte g[]) {
0674                for (int i = 0; i < map_size; i++) {
0675                    g[i] = (byte) (rgb[i] >> 8);
0676                }
0677            }
0678
0679            /**
0680             * Copies the array of blue color components into the specified array.  
0681             * Only the initial entries of the array as specified by 
0682             * <code>getMapSize</code> are written.
0683             * @param b the specified array into which the elements of the 
0684             *      array of blue color components are copied 
0685             */
0686            final public void getBlues(byte b[]) {
0687                for (int i = 0; i < map_size; i++) {
0688                    b[i] = (byte) rgb[i];
0689                }
0690            }
0691
0692            /**
0693             * Copies the array of alpha transparency components into the 
0694             * specified array.  Only the initial entries of the array as specified 
0695             * by <code>getMapSize</code> are written.
0696             * @param a the specified array into which the elements of the 
0697             *      array of alpha components are copied 
0698             */
0699            final public void getAlphas(byte a[]) {
0700                for (int i = 0; i < map_size; i++) {
0701                    a[i] = (byte) (rgb[i] >> 24);
0702                }
0703            }
0704
0705            /**
0706             * Converts data for each index from the color and alpha component
0707             * arrays to an int in the default RGB ColorModel format and copies
0708             * the resulting 32-bit ARGB values into the specified array.  Only
0709             * the initial entries of the array as specified by 
0710             * <code>getMapSize</code> are
0711             * written.
0712             * @param rgb the specified array into which the converted ARGB 
0713             *        values from this array of color and alpha components
0714             *        are copied.
0715             */
0716            final public void getRGBs(int rgb[]) {
0717                System.arraycopy(this .rgb, 0, rgb, 0, map_size);
0718            }
0719
0720            private void setTransparentPixel(int trans) {
0721                if (trans >= 0 && trans < map_size) {
0722                    rgb[trans] &= 0x00ffffff;
0723                    transparent_index = trans;
0724                    allgrayopaque = false;
0725                    if (this .transparency == OPAQUE) {
0726                        setTransparency(BITMASK);
0727                    }
0728                }
0729            }
0730
0731            private void setTransparency(int transparency) {
0732                if (this .transparency != transparency) {
0733                    this .transparency = transparency;
0734                    if (transparency == OPAQUE) {
0735                        supportsAlpha = false;
0736                        numComponents = 3;
0737                        nBits = opaqueBits;
0738                    } else {
0739                        supportsAlpha = true;
0740                        numComponents = 4;
0741                        nBits = alphaBits;
0742                    }
0743                }
0744            }
0745
0746            /**
0747             * This method is called from the constructors to set the pixel_mask
0748             * value, which is based on the value of pixel_bits.  The pixel_mask
0749             * value is used to mask off the pixel parameters for methods such
0750             * as getRed(), getGreen(), getBlue(), getAlpha(), and getRGB().
0751             */
0752            private final void calculatePixelMask() {
0753                // Note that we adjust the mask so that our masking behavior here
0754                // is consistent with that of our native rendering loops.
0755                int maskbits = pixel_bits;
0756                if (maskbits == 3) {
0757                    maskbits = 4;
0758                } else if (maskbits > 4 && maskbits < 8) {
0759                    maskbits = 8;
0760                }
0761                pixel_mask = (1 << maskbits) - 1;
0762            }
0763
0764            /**
0765             * Returns the red color component for the specified pixel, scaled
0766             * from 0 to 255 in the default RGB ColorSpace, sRGB.  The pixel value
0767             * is specified as an int.
0768             * Only the lower <em>n</em> bits of the pixel value, as specified in the
0769             * <a href="#index_values">class description</a> above, are used to
0770             * calculate the returned value.
0771             * The returned value is a non pre-multiplied value.
0772             * @param pixel the specified pixel 
0773             * @return the value of the red color component for the specified pixel
0774             */
0775            final public int getRed(int pixel) {
0776                return (rgb[pixel & pixel_mask] >> 16) & 0xff;
0777            }
0778
0779            /**
0780             * Returns the green color component for the specified pixel, scaled
0781             * from 0 to 255 in the default RGB ColorSpace, sRGB.  The pixel value
0782             * is specified as an int.
0783             * Only the lower <em>n</em> bits of the pixel value, as specified in the
0784             * <a href="#index_values">class description</a> above, are used to
0785             * calculate the returned value.
0786             * The returned value is a non pre-multiplied value.
0787             * @param pixel the specified pixel 
0788             * @return the value of the green color component for the specified pixel
0789             */
0790            final public int getGreen(int pixel) {
0791                return (rgb[pixel & pixel_mask] >> 8) & 0xff;
0792            }
0793
0794            /**
0795             * Returns the blue color component for the specified pixel, scaled
0796             * from 0 to 255 in the default RGB ColorSpace, sRGB.  The pixel value
0797             * is specified as an int.
0798             * Only the lower <em>n</em> bits of the pixel value, as specified in the
0799             * <a href="#index_values">class description</a> above, are used to
0800             * calculate the returned value.
0801             * The returned value is a non pre-multiplied value.
0802             * @param pixel the specified pixel 
0803             * @return the value of the blue color component for the specified pixel
0804             */
0805            final public int getBlue(int pixel) {
0806                return rgb[pixel & pixel_mask] & 0xff;
0807            }
0808
0809            /**
0810             * Returns the alpha component for the specified pixel, scaled
0811             * from 0 to 255.  The pixel value is specified as an int.
0812             * Only the lower <em>n</em> bits of the pixel value, as specified in the
0813             * <a href="#index_values">class description</a> above, are used to
0814             * calculate the returned value.
0815             * @param pixel the specified pixel 
0816             * @return the value of the alpha component for the specified pixel
0817             */
0818            final public int getAlpha(int pixel) {
0819                return (rgb[pixel & pixel_mask] >> 24) & 0xff;
0820            }
0821
0822            /**
0823             * Returns the color/alpha components of the pixel in the default
0824             * RGB color model format.  The pixel value is specified as an int.
0825             * Only the lower <em>n</em> bits of the pixel value, as specified in the
0826             * <a href="#index_values">class description</a> above, are used to
0827             * calculate the returned value.
0828             * The returned value is in a non pre-multiplied format.
0829             * @param pixel the specified pixel 
0830             * @return the color and alpha components of the specified pixel
0831             * @see ColorModel#getRGBdefault
0832             */
0833            final public int getRGB(int pixel) {
0834                return rgb[pixel & pixel_mask];
0835            }
0836
0837            private static final int CACHESIZE = 40;
0838            private int lookupcache[] = new int[CACHESIZE];
0839
0840            /**
0841             * Returns a data element array representation of a pixel in this
0842             * ColorModel, given an integer pixel representation in the
0843             * default RGB color model.  This array can then be passed to the 
0844             * {@link WritableRaster#setDataElements(int, int, java.lang.Object) setDataElements}
0845             * method of a {@link WritableRaster} object.  If the pixel variable is 
0846             * <code>null</code>, a new array is allocated.  If <code>pixel</code>
0847             * is not <code>null</code>, it must be
0848             * a primitive array of type <code>transferType</code>; otherwise, a
0849             * <code>ClassCastException</code> is thrown.  An 
0850             * <code>ArrayIndexOutOfBoundsException</code> is
0851             * thrown if <code>pixel</code> is not large enough to hold a pixel 
0852             * value for this <code>ColorModel</code>.  The pixel array is returned.
0853             * <p>
0854             * Since <code>IndexColorModel</code> can be subclassed, subclasses 
0855             * inherit the implementation of this method and if they don't 
0856             * override it then they throw an exception if they use an 
0857             * unsupported <code>transferType</code>.
0858             *
0859             * @param rgb the integer pixel representation in the default RGB
0860             * color model
0861             * @param pixel the specified pixel
0862             * @return an array representation of the specified pixel in this
0863             *  <code>IndexColorModel</code>.
0864             * @throws ClassCastException if <code>pixel</code>
0865             *  is not a primitive array of type <code>transferType</code>
0866             * @throws ArrayIndexOutOfBoundsException if
0867             *  <code>pixel</code> is not large enough to hold a pixel value
0868             *  for this <code>ColorModel</code>
0869             * @throws UnsupportedOperationException if <code>transferType</code>
0870             *         is invalid
0871             * @see WritableRaster#setDataElements
0872             * @see SampleModel#setDataElements
0873             */
0874            public synchronized Object getDataElements(int rgb, Object pixel) {
0875                int red = (rgb >> 16) & 0xff;
0876                int green = (rgb >> 8) & 0xff;
0877                int blue = rgb & 0xff;
0878                int alpha = (rgb >>> 24);
0879                int pix = 0;
0880
0881                // Note that pixels are stored at lookupcache[2*i]
0882                // and the rgb that was searched is stored at
0883                // lookupcache[2*i+1].  Also, the pixel is first
0884                // inverted using the unary complement operator
0885                // before storing in the cache so it can never be 0.
0886                for (int i = CACHESIZE - 2; i >= 0; i -= 2) {
0887                    if ((pix = lookupcache[i]) == 0) {
0888                        break;
0889                    }
0890                    if (rgb == lookupcache[i + 1]) {
0891                        return installpixel(pixel, ~pix);
0892                    }
0893                }
0894
0895                if (allgrayopaque) {
0896                    // IndexColorModel objects are all tagged as
0897                    // non-premultiplied so ignore the alpha value
0898                    // of the incoming color, convert the
0899                    // non-premultiplied color components to a
0900                    // grayscale value and search for the closest
0901                    // gray value in the palette.  Since all colors
0902                    // in the palette are gray, we only need compare
0903                    // to one of the color components for a match
0904                    // using a simple linear distance formula.
0905
0906                    int minDist = 256;
0907                    int d;
0908                    int gray = (int) (red * 77 + green * 150 + blue * 29 + 128) / 256;
0909
0910                    for (int i = 0; i < map_size; i++) {
0911                        if (this .rgb[i] == 0x0) {
0912                            // For allgrayopaque colormaps, entries are 0
0913                            // iff they are an invalid color and should be
0914                            // ignored during color searches.
0915                            continue;
0916                        }
0917                        d = (this .rgb[i] & 0xff) - gray;
0918                        if (d < 0)
0919                            d = -d;
0920                        if (d < minDist) {
0921                            pix = i;
0922                            if (d == 0) {
0923                                break;
0924                            }
0925                            minDist = d;
0926                        }
0927                    }
0928                } else if (transparency == OPAQUE) {
0929                    // IndexColorModel objects are all tagged as
0930                    // non-premultiplied so ignore the alpha value
0931                    // of the incoming color and search for closest
0932                    // color match independently using a 3 component
0933                    // Euclidean distance formula.
0934                    // For opaque colormaps, palette entries are 0
0935                    // iff they are an invalid color and should be
0936                    // ignored during color searches.
0937                    // As an optimization, exact color searches are
0938                    // likely to be fairly common in opaque colormaps
0939                    // so first we will do a quick search for an
0940                    // exact match.
0941
0942                    int smallestError = Integer.MAX_VALUE;
0943                    int lut[] = this .rgb;
0944                    int lutrgb;
0945                    for (int i = 0; i < map_size; i++) {
0946                        lutrgb = lut[i];
0947                        if (lutrgb == rgb && lutrgb != 0) {
0948                            pix = i;
0949                            smallestError = 0;
0950                            break;
0951                        }
0952                    }
0953
0954                    if (smallestError != 0) {
0955                        for (int i = 0; i < map_size; i++) {
0956                            lutrgb = lut[i];
0957                            if (lutrgb == 0) {
0958                                continue;
0959                            }
0960
0961                            int tmp = ((lutrgb >> 16) & 0xff) - red;
0962                            int currentError = tmp * tmp;
0963                            if (currentError < smallestError) {
0964                                tmp = ((lutrgb >> 8) & 0xff) - green;
0965                                currentError += tmp * tmp;
0966                                if (currentError < smallestError) {
0967                                    tmp = (lutrgb & 0xff) - blue;
0968                                    currentError += tmp * tmp;
0969                                    if (currentError < smallestError) {
0970                                        pix = i;
0971                                        smallestError = currentError;
0972                                    }
0973                                }
0974                            }
0975                        }
0976                    }
0977                } else if (alpha == 0 && transparent_index >= 0) {
0978                    // Special case - transparent color maps to the
0979                    // specified transparent pixel, if there is one
0980
0981                    pix = transparent_index;
0982                } else {
0983                    // IndexColorModel objects are all tagged as
0984                    // non-premultiplied so use non-premultiplied
0985                    // color components in the distance calculations.
0986                    // Look for closest match using a 4 component
0987                    // Euclidean distance formula.
0988
0989                    int smallestError = Integer.MAX_VALUE;
0990                    int lut[] = this .rgb;
0991                    for (int i = 0; i < map_size; i++) {
0992                        int lutrgb = lut[i];
0993                        if (lutrgb == rgb) {
0994                            if (validBits != null && !validBits.testBit(i)) {
0995                                continue;
0996                            }
0997                            pix = i;
0998                            break;
0999                        }
1000
1001                        int tmp = ((lutrgb >> 16) & 0xff) - red;
1002                        int currentError = tmp * tmp;
1003                        if (currentError < smallestError) {
1004                            tmp = ((lutrgb >> 8) & 0xff) - green;
1005                            currentError += tmp * tmp;
1006                            if (currentError < smallestError) {
1007                                tmp = (lutrgb & 0xff) - blue;
1008                                currentError += tmp * tmp;
1009                                if (currentError < smallestError) {
1010                                    tmp = (lutrgb >>> 24) - alpha;
1011                                    currentError += tmp * tmp;
1012                                    if (currentError < smallestError
1013                                            && (validBits == null || validBits
1014                                                    .testBit(i))) {
1015                                        pix = i;
1016                                        smallestError = currentError;
1017                                    }
1018                                }
1019                            }
1020                        }
1021                    }
1022                }
1023                System.arraycopy(lookupcache, 2, lookupcache, 0, CACHESIZE - 2);
1024                lookupcache[CACHESIZE - 1] = rgb;
1025                lookupcache[CACHESIZE - 2] = ~pix;
1026                return installpixel(pixel, pix);
1027            }
1028
1029            private Object installpixel(Object pixel, int pix) {
1030                switch (transferType) {
1031                case DataBuffer.TYPE_INT:
1032                    int[] intObj;
1033                    if (pixel == null) {
1034                        pixel = intObj = new int[1];
1035                    } else {
1036                        intObj = (int[]) pixel;
1037                    }
1038                    intObj[0] = pix;
1039                    break;
1040                case DataBuffer.TYPE_BYTE:
1041                    byte[] byteObj;
1042                    if (pixel == null) {
1043                        pixel = byteObj = new byte[1];
1044                    } else {
1045                        byteObj = (byte[]) pixel;
1046                    }
1047                    byteObj[0] = (byte) pix;
1048                    break;
1049                case DataBuffer.TYPE_USHORT:
1050                    short[] shortObj;
1051                    if (pixel == null) {
1052                        pixel = shortObj = new short[1];
1053                    } else {
1054                        shortObj = (short[]) pixel;
1055                    }
1056                    shortObj[0] = (short) pix;
1057                    break;
1058                default:
1059                    throw new UnsupportedOperationException(
1060                            "This method has not been "
1061                                    + "implemented for transferType "
1062                                    + transferType);
1063                }
1064                return pixel;
1065            }
1066
1067            /**
1068             * Returns an array of unnormalized color/alpha components for a 
1069             * specified pixel in this <code>ColorModel</code>.  The pixel value 
1070             * is specified as an int.  If the <code>components</code> array is <code>null</code>, 
1071             * a new array is allocated that contains 
1072             * <code>offset + getNumComponents()</code> elements. 
1073             * The <code>components</code> array is returned, 
1074             * with the alpha component included 
1075             * only if <code>hasAlpha</code> returns true.  
1076             * Color/alpha components are stored in the <code>components</code> array starting 
1077             * at <code>offset</code> even if the array is allocated by this method.  
1078             * An <code>ArrayIndexOutOfBoundsException</code>
1079             * is thrown if  the <code>components</code> array is not <code>null</code> and is 
1080             * not large enough to hold all the color and alpha components 
1081             * starting at <code>offset</code>.
1082             * @param pixel the specified pixel
1083             * @param components the array to receive the color and alpha
1084             * components of the specified pixel
1085             * @param offset the offset into the <code>components</code> array at
1086             * which to start storing the color and alpha components
1087             * @return an array containing the color and alpha components of the
1088             * specified pixel starting at the specified offset.
1089             * @see ColorModel#hasAlpha
1090             * @see ColorModel#getNumComponents
1091             */
1092            public int[] getComponents(int pixel, int[] components, int offset) {
1093                if (components == null) {
1094                    components = new int[offset + numComponents];
1095                }
1096
1097                // REMIND: Needs to change if different color space
1098                components[offset + 0] = getRed(pixel);
1099                components[offset + 1] = getGreen(pixel);
1100                components[offset + 2] = getBlue(pixel);
1101                if (supportsAlpha && (components.length - offset) > 3) {
1102                    components[offset + 3] = getAlpha(pixel);
1103                }
1104
1105                return components;
1106            }
1107
1108            /**
1109             * Returns an array of unnormalized color/alpha components for
1110             * a specified pixel in this <code>ColorModel</code>.  The pixel 
1111             * value is specified by an array of data elements of type 
1112             * <code>transferType</code> passed in as an object reference.
1113             * If <code>pixel</code> is not a primitive array of type 
1114             * <code>transferType</code>, a <code>ClassCastException</code>
1115             * is thrown.  An <code>ArrayIndexOutOfBoundsException</code>
1116             * is thrown if <code>pixel</code> is not large enough to hold 
1117             * a pixel value for this <code>ColorModel</code>.  If the 
1118             * <code>components</code> array is <code>null</code>, a new array 
1119             * is allocated that contains 
1120             * <code>offset + getNumComponents()</code> elements. 
1121             * The <code>components</code> array is returned, 
1122             * with the alpha component included 
1123             * only if <code>hasAlpha</code> returns true.  
1124             * Color/alpha components are stored in the <code>components</code> 
1125             * array starting at <code>offset</code> even if the array is
1126             * allocated by this method.  An 
1127             * <code>ArrayIndexOutOfBoundsException</code> is also
1128             * thrown if  the <code>components</code> array is not 
1129             * <code>null</code> and is not large enough to hold all the color 
1130             * and alpha components starting at <code>offset</code>.  
1131             * <p>
1132             * Since <code>IndexColorModel</code> can be subclassed, subclasses 
1133             * inherit the implementation of this method and if they don't
1134             * override it then they throw an exception if they use an 
1135             * unsupported <code>transferType</code>.
1136             *
1137             * @param pixel the specified pixel
1138             * @param components an array that receives the color and alpha  
1139             * components of the specified pixel
1140             * @param offset the index into the <code>components</code> array at
1141             * which to begin storing the color and alpha components of the
1142             * specified pixel
1143             * @return an array containing the color and alpha components of the
1144             * specified pixel starting at the specified offset.
1145             * @throws ArrayIndexOutOfBoundsException if <code>pixel</code>
1146             *            is not large enough to hold a pixel value for this
1147             *            <code>ColorModel</code> or if the 
1148             *            <code>components</code> array is not <code>null</code> 
1149             *            and is not large enough to hold all the color 
1150             *            and alpha components starting at <code>offset</code>
1151             * @throws ClassCastException if <code>pixel</code> is not a 
1152             *            primitive array of type <code>transferType</code>
1153             * @throws UnsupportedOperationException if <code>transferType</code>
1154             *         is not one of the supported transer types
1155             * @see ColorModel#hasAlpha
1156             * @see ColorModel#getNumComponents
1157             */
1158            public int[] getComponents(Object pixel, int[] components,
1159                    int offset) {
1160                int intpixel;
1161                switch (transferType) {
1162                case DataBuffer.TYPE_BYTE:
1163                    byte bdata[] = (byte[]) pixel;
1164                    intpixel = bdata[0] & 0xff;
1165                    break;
1166                case DataBuffer.TYPE_USHORT:
1167                    short sdata[] = (short[]) pixel;
1168                    intpixel = sdata[0] & 0xffff;
1169                    break;
1170                case DataBuffer.TYPE_INT:
1171                    int idata[] = (int[]) pixel;
1172                    intpixel = idata[0];
1173                    break;
1174                default:
1175                    throw new UnsupportedOperationException(
1176                            "This method has not been "
1177                                    + "implemented for transferType "
1178                                    + transferType);
1179                }
1180                return getComponents(intpixel, components, offset);
1181            }
1182
1183            /**
1184             * Returns a pixel value represented as an int in this 
1185             * <code>ColorModel</code> given an array of unnormalized 
1186             * color/alpha components.  An 
1187             * <code>ArrayIndexOutOfBoundsException</code> 
1188             * is thrown if the <code>components</code> array is not large 
1189             * enough to hold all of the color and alpha components starting
1190             * at <code>offset</code>.  Since
1191             * <code>ColorModel</code> can be subclassed, subclasses inherit the
1192             * implementation of this method and if they don't override it then
1193             * they throw an exception if they use an unsupported transferType.
1194             * @param components an array of unnormalized color and alpha
1195             * components
1196             * @param offset the index into <code>components</code> at which to
1197             * begin retrieving the color and alpha components
1198             * @return an <code>int</code> pixel value in this
1199             * <code>ColorModel</code> corresponding to the specified components.
1200             * @throws ArrayIndexOutOfBoundsException if
1201             *  the <code>components</code> array is not large enough to
1202             *  hold all of the color and alpha components starting at
1203             *  <code>offset</code>
1204             * @throws UnsupportedOperationException if <code>transferType</code>
1205             *         is invalid
1206             */
1207            public int getDataElement(int[] components, int offset) {
1208                int rgb = (components[offset + 0] << 16)
1209                        | (components[offset + 1] << 8)
1210                        | (components[offset + 2]);
1211                if (supportsAlpha) {
1212                    rgb |= (components[offset + 3] << 24);
1213                } else {
1214                    rgb |= 0xff000000;
1215                }
1216                Object inData = getDataElements(rgb, null);
1217                int pixel;
1218                switch (transferType) {
1219                case DataBuffer.TYPE_BYTE:
1220                    byte bdata[] = (byte[]) inData;
1221                    pixel = bdata[0] & 0xff;
1222                    break;
1223                case DataBuffer.TYPE_USHORT:
1224                    short sdata[] = (short[]) inData;
1225                    pixel = sdata[0];
1226                    break;
1227                case DataBuffer.TYPE_INT:
1228                    int idata[] = (int[]) inData;
1229                    pixel = idata[0];
1230                    break;
1231                default:
1232                    throw new UnsupportedOperationException(
1233                            "This method has not been "
1234                                    + "implemented for transferType "
1235                                    + transferType);
1236                }
1237                return pixel;
1238            }
1239
1240            /**
1241             * Returns a data element array representation of a pixel in this
1242             * <code>ColorModel</code> given an array of unnormalized color/alpha 
1243             * components.  This array can then be passed to the 
1244             * <code>setDataElements</code> method of a <code>WritableRaster</code> 
1245             * object.  An <code>ArrayIndexOutOfBoundsException</code> is 
1246             * thrown if the 
1247             * <code>components</code> array is not large enough to hold all of the 
1248             * color and alpha components starting at <code>offset</code>.  
1249             * If the pixel variable is <code>null</code>, a new array
1250             * is allocated.  If <code>pixel</code> is not <code>null</code>, 
1251             * it must be a primitive array of type <code>transferType</code>; 
1252             * otherwise, a <code>ClassCastException</code> is thrown.
1253             * An <code>ArrayIndexOutOfBoundsException</code> is thrown if pixel 
1254             * is not large enough to hold a pixel value for this
1255             * <code>ColorModel</code>.
1256             * <p>
1257             * Since <code>IndexColorModel</code> can be subclassed, subclasses
1258             * inherit the implementation of this method and if they don't
1259             * override it then they throw an exception if they use an
1260             * unsupported <code>transferType</code>
1261             *
1262             * @param components an array of unnormalized color and alpha
1263             * components
1264             * @param offset the index into <code>components</code> at which to
1265             * begin retrieving color and alpha components
1266             * @param pixel the <code>Object</code> representing an array of color
1267             * and alpha components
1268             * @return an <code>Object</code> representing an array of color and
1269             * alpha components.
1270             * @throws ClassCastException if <code>pixel</code>
1271             *  is not a primitive array of type <code>transferType</code>
1272             * @throws ArrayIndexOutOfBoundsException if 
1273             *  <code>pixel</code> is not large enough to hold a pixel value
1274             *  for this <code>ColorModel</code> or the <code>components</code>
1275             *  array is not large enough to hold all of the color and alpha
1276             *  components starting at <code>offset</code>
1277             * @throws UnsupportedOperationException if <code>transferType</code>
1278             *         is not one of the supported transer types
1279             * @see WritableRaster#setDataElements
1280             * @see SampleModel#setDataElements
1281             */
1282            public Object getDataElements(int[] components, int offset,
1283                    Object pixel) {
1284                int rgb = (components[offset + 0] << 16)
1285                        | (components[offset + 1] << 8)
1286                        | (components[offset + 2]);
1287                if (supportsAlpha) {
1288                    rgb |= (components[offset + 3] << 24);
1289                } else {
1290                    rgb &= 0xff000000;
1291                }
1292                return getDataElements(rgb, pixel);
1293            }
1294
1295            /**
1296             * Creates a <code>WritableRaster</code> with the specified width 
1297             * and height that has a data layout (<code>SampleModel</code>) 
1298             * compatible with this <code>ColorModel</code>.  This method
1299             * only works for color models with 16 or fewer bits per pixel.
1300             * <p>
1301             * Since <code>IndexColorModel</code> can be subclassed, any 
1302             * subclass that supports greater than 16 bits per pixel must
1303             * override this method.
1304             *
1305             * @param w the width to apply to the new <code>WritableRaster</code>
1306             * @param h the height to apply to the new <code>WritableRaster</code>
1307             * @return a <code>WritableRaster</code> object with the specified
1308             * width and height.
1309             * @throws UnsupportedOperationException if the number of bits in a
1310             *         pixel is greater than 16
1311             * @see WritableRaster
1312             * @see SampleModel
1313             */
1314            public WritableRaster createCompatibleWritableRaster(int w, int h) {
1315                WritableRaster raster;
1316
1317                if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
1318                    // TYPE_BINARY
1319                    raster = Raster.createPackedRaster(DataBuffer.TYPE_BYTE, w,
1320                            h, 1, pixel_bits, null);
1321                } else if (pixel_bits <= 8) {
1322                    raster = Raster.createInterleavedRaster(
1323                            DataBuffer.TYPE_BYTE, w, h, 1, null);
1324                } else if (pixel_bits <= 16) {
1325                    raster = Raster.createInterleavedRaster(
1326                            DataBuffer.TYPE_USHORT, w, h, 1, null);
1327                } else {
1328                    throw new UnsupportedOperationException(
1329                            "This method is not supported "
1330                                    + " for pixel bits > 16.");
1331                }
1332                return raster;
1333            }
1334
1335            /**
1336             * Returns <code>true</code> if <code>raster</code> is compatible 
1337             * with this <code>ColorModel</code> or <code>false</code> if it 
1338             * is not compatible with this <code>ColorModel</code>.
1339             * @param raster the {@link Raster} object to test for compatibility
1340             * @return <code>true</code> if <code>raster</code> is compatible
1341             * with this <code>ColorModel</code>; <code>false</code> otherwise.
1342             * 
1343             */
1344            public boolean isCompatibleRaster(Raster raster) {
1345
1346                int size = raster.getSampleModel().getSampleSize(0);
1347                return ((raster.getTransferType() == transferType)
1348                        && (raster.getNumBands() == 1) && ((1 << size) >= map_size));
1349            }
1350
1351            /**
1352             * Creates a <code>SampleModel</code> with the specified 
1353             * width and height that has a data layout compatible with 
1354             * this <code>ColorModel</code>.  
1355             * @param w the width to apply to the new <code>SampleModel</code>
1356             * @param h the height to apply to the new <code>SampleModel</code> 
1357             * @return a <code>SampleModel</code> object with the specified
1358             * width and height.
1359             * @throws IllegalArgumentException if <code>w</code> or
1360             *         <code>h</code> is not greater than 0
1361             * @see SampleModel
1362             */
1363            public SampleModel createCompatibleSampleModel(int w, int h) {
1364                int[] off = new int[1];
1365                off[0] = 0;
1366                if (pixel_bits == 1 || pixel_bits == 2 || pixel_bits == 4) {
1367                    return new MultiPixelPackedSampleModel(transferType, w, h,
1368                            pixel_bits);
1369                } else {
1370                    return new ComponentSampleModel(transferType, w, h, 1, w,
1371                            off);
1372                }
1373            }
1374
1375            /** 
1376             * Checks if the specified <code>SampleModel</code> is compatible 
1377             * with this <code>ColorModel</code>.  If <code>sm</code> is
1378             * <code>null</code>, this method returns <code>false</code>.  
1379             * @param sm the specified <code>SampleModel</code>, 
1380             *           or <code>null</code>
1381             * @return <code>true</code> if the specified <code>SampleModel</code>
1382             * is compatible with this <code>ColorModel</code>; <code>false</code>
1383             * otherwise.
1384             * @see SampleModel 
1385             */
1386            public boolean isCompatibleSampleModel(SampleModel sm) {
1387                // fix 4238629
1388                if (!(sm instanceof  ComponentSampleModel)
1389                        && !(sm instanceof  MultiPixelPackedSampleModel)) {
1390                    return false;
1391                }
1392
1393                // Transfer type must be the same
1394                if (sm.getTransferType() != transferType) {
1395                    return false;
1396                }
1397
1398                if (sm.getNumBands() != 1) {
1399                    return false;
1400                }
1401
1402                return true;
1403            }
1404
1405            /**
1406             * Returns a new <code>BufferedImage</code> of TYPE_INT_ARGB or 
1407             * TYPE_INT_RGB that has a <code>Raster</code> with pixel data 
1408             * computed by expanding the indices in the source <code>Raster</code>
1409             * using the color/alpha component arrays of this <code>ColorModel</code>.
1410             * Only the lower <em>n</em> bits of each index value in the source
1411             * <code>Raster</code>, as specified in the
1412             * <a href="#index_values">class description</a> above, are used to
1413             * compute the color/alpha values in the returned image.
1414             * If <code>forceARGB</code> is <code>true</code>, a TYPE_INT_ARGB image is
1415             * returned regardless of whether or not this <code>ColorModel</code>
1416             * has an alpha component array or a transparent pixel.
1417             * @param raster the specified <code>Raster</code>
1418             * @param forceARGB if <code>true</code>, the returned 
1419             *     <code>BufferedImage</code> is TYPE_INT_ARGB; otherwise it is
1420             *     TYPE_INT_RGB
1421             * @return a <code>BufferedImage</code> created with the specified
1422             *     <code>Raster</code>
1423             * @throws IllegalArgumentException if the raster argument is not
1424             *           compatible with this IndexColorModel
1425             */
1426            public BufferedImage convertToIntDiscrete(Raster raster,
1427                    boolean forceARGB) {
1428                ColorModel cm;
1429
1430                if (!isCompatibleRaster(raster)) {
1431                    throw new IllegalArgumentException(
1432                            "This raster is not compatible"
1433                                    + "with this IndexColorModel.");
1434                }
1435                if (forceARGB || transparency == TRANSLUCENT) {
1436                    cm = ColorModel.getRGBdefault();
1437                } else if (transparency == BITMASK) {
1438                    cm = new DirectColorModel(25, 0xff0000, 0x00ff00, 0x0000ff,
1439                            0x1000000);
1440                } else {
1441                    cm = new DirectColorModel(24, 0xff0000, 0x00ff00, 0x0000ff);
1442                }
1443
1444                int w = raster.getWidth();
1445                int h = raster.getHeight();
1446                WritableRaster discreteRaster = cm
1447                        .createCompatibleWritableRaster(w, h);
1448                Object obj = null;
1449                int[] data = null;
1450
1451                int rX = raster.getMinX();
1452                int rY = raster.getMinY();
1453
1454                for (int y = 0; y < h; y++, rY++) {
1455                    obj = raster.getDataElements(rX, rY, w, 1, obj);
1456                    if (obj instanceof  int[]) {
1457                        data = (int[]) obj;
1458                    } else {
1459                        data = DataBuffer.toIntArray(obj);
1460                    }
1461                    for (int x = 0; x < w; x++) {
1462                        data[x] = rgb[data[x] & pixel_mask];
1463                    }
1464                    discreteRaster.setDataElements(0, y, w, 1, data);
1465                }
1466
1467                return new BufferedImage(cm, discreteRaster, false, null);
1468            }
1469
1470            /**
1471             * Returns whether or not the pixel is valid.  
1472             * @param pixel the specified pixel value
1473             * @return <code>true</code> if <code>pixel</code>
1474             * is valid; <code>false</code> otherwise.
1475             * @since 1.3
1476             */
1477            public boolean isValid(int pixel) {
1478                return ((pixel >= 0 && pixel < map_size) && (validBits == null || validBits
1479                        .testBit(pixel)));
1480            }
1481
1482            /**
1483             * Returns whether or not all of the pixels are valid.
1484             * @return <code>true</code> if all pixels are valid;
1485             * <code>false</code> otherwise.
1486             * @since 1.3
1487             */
1488            public boolean isValid() {
1489                return (validBits == null);
1490            }
1491
1492            /**
1493             * Returns a <code>BigInteger</code> that indicates the valid/invalid
1494             * pixels in the colormap.  A bit is valid if the 
1495             * <code>BigInteger</code> value at that index is set, and is invalid
1496             * if the <code>BigInteger</code> value at that index is not set.
1497             * The only valid ranges to query in the <code>BigInteger</code> are
1498             * between 0 and the map size.
1499             * @return a <code>BigInteger</code> indicating the valid/invalid pixels.
1500             * @since 1.3
1501             */
1502            public BigInteger getValidPixels() {
1503                if (validBits == null) {
1504                    return getAllValid();
1505                } else {
1506                    return validBits;
1507                }
1508            }
1509
1510            /**
1511             * Disposes of system resources associated with this
1512             * <code>ColorModel</code> once this <code>ColorModel</code> is no
1513             * longer referenced.
1514             */
1515            public void finalize() {
1516                sun.awt.image.BufImgSurfaceData.freeNativeICMData(this );
1517            }
1518
1519            /**
1520             * Returns the <code>String</code> representation of the contents of
1521             * this <code>ColorModel</code>object.
1522             * @return a <code>String</code> representing the contents of this
1523             * <code>ColorModel</code> object.
1524             */
1525            public String toString() {
1526                return new String("IndexColorModel: #pixelBits = " + pixel_bits
1527                        + " numComponents = " + numComponents
1528                        + " color space = " + colorSpace + " transparency = "
1529                        + transparency + " transIndex   = " + transparent_index
1530                        + " has alpha = " + supportsAlpha + " isAlphaPre = "
1531                        + isAlphaPremultiplied);
1532            }
1533        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.