jdk/src/share/classes/java/awt/image/PackedColorModel.java
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 8750 50fec4bad1f7
child 22584 eed64ee05369
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 8750
diff changeset
     2
 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package java.awt.image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Transparency;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.color.ColorSpace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * The <code>PackedColorModel</code> class is an abstract
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * {@link ColorModel} class that works with pixel values which represent
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * color and alpha information as separate samples and which pack all
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * samples for a single pixel into a single int, short, or byte quantity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * This class can be used with an arbitrary {@link ColorSpace}.  The number of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * color samples in the pixel values must be the same as the number of color
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * components in the <code>ColorSpace</code>.  There can be a single alpha
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * sample.  The array length is always 1 for those methods that use a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * primitive array pixel representation of type <code>transferType</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * The transfer types supported are DataBuffer.TYPE_BYTE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * DataBuffer.TYPE_USHORT, and DataBuffer.TYPE_INT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * Color and alpha samples are stored in the single element of the array
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * in bits indicated by bit masks.  Each bit mask must be contiguous and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * masks must not overlap.  The same masks apply to the single int
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * pixel representation used by other methods.  The correspondence of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * masks and color/alpha samples is as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * <li> Masks are identified by indices running from 0 through
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * {@link ColorModel#getNumComponents() getNumComponents}&nbsp;-&nbsp;1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * <li> The first
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * {@link ColorModel#getNumColorComponents() getNumColorComponents}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * indices refer to color samples.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * <li> If an alpha sample is present, it corresponds the last index.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * <li> The order of the color indices is specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * by the <code>ColorSpace</code>.  Typically, this reflects the name of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * the color space type (for example, TYPE_RGB), index 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * corresponds to red, index 1 to green, and index 2 to blue.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * The translation from pixel values to color/alpha components for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * display or processing purposes is a one-to-one correspondence of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * samples to components.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * A <code>PackedColorModel</code> is typically used with image data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * that uses masks to define packed samples.  For example, a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * <code>PackedColorModel</code> can be used in conjunction with a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * {@link SinglePixelPackedSampleModel} to construct a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * {@link BufferedImage}.  Normally the masks used by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * {@link SampleModel} and the <code>ColorModel</code> would be the same.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * However, if they are different, the color interpretation of pixel data is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * done according to the masks of the <code>ColorModel</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * A single <code>int</code> pixel representation is valid for all objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * of this class since it is always possible to represent pixel values
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 * used with this class in a single <code>int</code>.  Therefore, methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * that use this representation do not throw an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * <code>IllegalArgumentException</code> due to an invalid pixel value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * A subclass of <code>PackedColorModel</code> is {@link DirectColorModel},
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * which is similar to an X11 TrueColor visual.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * @see DirectColorModel
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * @see SinglePixelPackedSampleModel
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 * @see BufferedImage
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
public abstract class PackedColorModel extends ColorModel {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    int[] maskArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    int[] maskOffsets;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    float[] scaleFactors;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * Constructs a <code>PackedColorModel</code> from a color mask array,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     * which specifies which bits in an <code>int</code> pixel representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * contain each of the color samples, and an alpha mask.  Color
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * components are in the specified <code>ColorSpace</code>.  The length of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     * <code>colorMaskArray</code> should be the number of components in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * the <code>ColorSpace</code>.  All of the bits in each mask
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * must be contiguous and fit in the specified number of least significant
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * bits of an <code>int</code> pixel representation.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * <code>alphaMask</code> is 0, there is no alpha.  If there is alpha,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * the <code>boolean</code> <code>isAlphaPremultiplied</code> specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * how to interpret color and alpha samples in pixel values.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * <code>boolean</code> is <code>true</code>, color samples are assumed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * to have been multiplied by the alpha sample.  The transparency,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     * <code>trans</code>, specifies what alpha values can be represented
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
     * by this color model.  The transfer type is the type of primitive
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * array used to represent pixel values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * @param space the specified <code>ColorSpace</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * @param bits the number of bits in the pixel values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * @param colorMaskArray array that specifies the masks representing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     *         the bits of the pixel values that represent the color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     *         components
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
     * @param alphaMask specifies the mask representing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     *         the bits of the pixel values that represent the alpha
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     *         component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * @param isAlphaPremultiplied <code>true</code> if color samples are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     *        premultiplied by the alpha sample; <code>false</code> otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * @param trans specifies the alpha value that can be represented by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     *        this color model
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * @param transferType the type of array used to represent pixel values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * @throws IllegalArgumentException if <code>bits</code> is less than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     *         1 or greater than 32
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    public PackedColorModel (ColorSpace space, int bits,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                             int[] colorMaskArray, int alphaMask,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                             boolean isAlphaPremultiplied,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                             int trans, int transferType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        super(bits, PackedColorModel.createBitsArray(colorMaskArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                                                     alphaMask),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
              space, (alphaMask == 0 ? false : true),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
              isAlphaPremultiplied, trans, transferType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        if (bits < 1 || bits > 32) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            throw new IllegalArgumentException("Number of bits must be between"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                                               +" 1 and 32.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        maskArray   = new int[numComponents];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        maskOffsets = new int[numComponents];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        scaleFactors = new float[numComponents];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        for (int i=0; i < numColorComponents; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
            // Get the mask offset and #bits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            DecomposeMask(colorMaskArray[i], i, space.getName(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        if (alphaMask != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            DecomposeMask(alphaMask, numColorComponents, "alpha");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            if (nBits[numComponents-1] == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                transparency = Transparency.BITMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
     * Constructs a <code>PackedColorModel</code> from the specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * masks which indicate which bits in an <code>int</code> pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     * representation contain the alpha, red, green and blue color samples.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     * Color components are in the specified <code>ColorSpace</code>, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * must be of type ColorSpace.TYPE_RGB.  All of the bits in each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * mask must be contiguous and fit in the specified number of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     * least significant bits of an <code>int</code> pixel representation.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * <code>amask</code> is 0, there is no alpha.  If there is alpha,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * the <code>boolean</code> <code>isAlphaPremultiplied</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * specifies how to interpret color and alpha samples
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * in pixel values.  If the <code>boolean</code> is <code>true</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * color samples are assumed to have been multiplied by the alpha sample.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * The transparency, <code>trans</code>, specifies what alpha values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * can be represented by this color model.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * The transfer type is the type of primitive array used to represent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * pixel values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * @param space the specified <code>ColorSpace</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * @param bits the number of bits in the pixel values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * @param rmask specifies the mask representing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     *         the bits of the pixel values that represent the red
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     *         color component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * @param gmask specifies the mask representing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     *         the bits of the pixel values that represent the green
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     *         color component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     * @param bmask specifies the mask representing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     *         the bits of the pixel values that represent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     *         the blue color component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * @param amask specifies the mask representing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     *         the bits of the pixel values that represent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     *         the alpha component
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * @param isAlphaPremultiplied <code>true</code> if color samples are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     *        premultiplied by the alpha sample; <code>false</code> otherwise
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * @param trans specifies the alpha value that can be represented by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     *        this color model
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * @param transferType the type of array used to represent pixel values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * @throws IllegalArgumentException if <code>space</code> is not a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     *         TYPE_RGB space
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * @see ColorSpace
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    public PackedColorModel(ColorSpace space, int bits, int rmask, int gmask,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                            int bmask, int amask,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                            boolean isAlphaPremultiplied,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                            int trans, int transferType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        super (bits, PackedColorModel.createBitsArray(rmask, gmask, bmask,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                                                      amask),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
               space, (amask == 0 ? false : true),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
               isAlphaPremultiplied, trans, transferType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        if (space.getType() != ColorSpace.TYPE_RGB) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            throw new IllegalArgumentException("ColorSpace must be TYPE_RGB.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        maskArray = new int[numComponents];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        maskOffsets = new int[numComponents];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        scaleFactors = new float[numComponents];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        DecomposeMask(rmask, 0, "red");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        DecomposeMask(gmask, 1, "green");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        DecomposeMask(bmask, 2, "blue");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        if (amask != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            DecomposeMask(amask, 3, "alpha");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            if (nBits[3] == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                transparency = Transparency.BITMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * Returns the mask indicating which bits in a pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * contain the specified color/alpha sample.  For color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * samples, <code>index</code> corresponds to the placement of color
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * sample names in the color space.  Thus, an <code>index</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * equal to 0 for a CMYK ColorSpace would correspond to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * Cyan and an <code>index</code> equal to 1 would correspond to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * Magenta.  If there is alpha, the alpha <code>index</code> would be:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     *      alphaIndex = numComponents() - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     * @param index the specified color or alpha sample
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     * @return the mask, which indicates which bits of the <code>int</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     *         pixel representation contain the color or alpha sample specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     *         by <code>index</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * @throws ArrayIndexOutOfBoundsException if <code>index</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     *         greater than the number of components minus 1 in this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     *         <code>PackedColorModel</code> or if <code>index</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     *         less than zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    final public int getMask(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        return maskArray[index];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * Returns a mask array indicating which bits in a pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * contain the color and alpha samples.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * @return the mask array , which indicates which bits of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     *         <code>int</code> pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     *         representation contain the color or alpha samples.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    final public int[] getMasks() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        return (int[]) maskArray.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * A utility function to compute the mask offset and scalefactor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * store these and the mask in instance arrays, and verify that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * the mask fits in the specified pixel size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    private void DecomposeMask(int mask,  int idx, String componentName) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        int off = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        int count = nBits[idx];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        // Store the mask
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        maskArray[idx]   = mask;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        // Now find the shift
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        if (mask != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            while ((mask & 1) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                mask >>>= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                off++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if (off + count > pixel_bits) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            throw new IllegalArgumentException(componentName + " mask "+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                                        Integer.toHexString(maskArray[idx])+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                                               " overflows pixel (expecting "+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                                               pixel_bits+" bits");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        maskOffsets[idx] = off;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        if (count == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            // High enough to scale any 0-ff value down to 0.0, but not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            // high enough to get Infinity when scaling back to pixel bits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            scaleFactors[idx] = 256.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            scaleFactors[idx] = 255.0f / ((1 << count) - 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     * Creates a <code>SampleModel</code> with the specified width and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * height that has a data layout compatible with this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * <code>ColorModel</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * @param w the width (in pixels) of the region of the image data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     *          described
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     * @param h the height (in pixels) of the region of the image data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     *          described
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * @return the newly created <code>SampleModel</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * @throws IllegalArgumentException if <code>w</code> or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     *         <code>h</code> is not greater than 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * @see SampleModel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    public SampleModel createCompatibleSampleModel(int w, int h) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        return new SinglePixelPackedSampleModel(transferType, w, h,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                                                maskArray);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * Checks if the specified <code>SampleModel</code> is compatible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * with this <code>ColorModel</code>.  If <code>sm</code> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * <code>null</code>, this method returns <code>false</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * @param sm the specified <code>SampleModel</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * or <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * @return <code>true</code> if the specified <code>SampleModel</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     *         is compatible with this <code>ColorModel</code>;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     *         <code>false</code> otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * @see SampleModel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    public boolean isCompatibleSampleModel(SampleModel sm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        if (! (sm instanceof SinglePixelPackedSampleModel)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        // Must have the same number of components
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        if (numComponents != sm.getNumBands()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        // Transfer type must be the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        if (sm.getTransferType() != transferType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        // Now compare the specific masks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        int[] bitMasks = sppsm.getBitMasks();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        if (bitMasks.length != maskArray.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        }
8750
50fec4bad1f7 7014528: ColorModel and SampleModel gotten from the same ImageTypeSpecifier instance can be not compatible
bae
parents: 5506
diff changeset
   346
50fec4bad1f7 7014528: ColorModel and SampleModel gotten from the same ImageTypeSpecifier instance can be not compatible
bae
parents: 5506
diff changeset
   347
        /* compare 'effective' masks only, i.e. only part of the mask
50fec4bad1f7 7014528: ColorModel and SampleModel gotten from the same ImageTypeSpecifier instance can be not compatible
bae
parents: 5506
diff changeset
   348
         * which fits the capacity of the transfer type.
50fec4bad1f7 7014528: ColorModel and SampleModel gotten from the same ImageTypeSpecifier instance can be not compatible
bae
parents: 5506
diff changeset
   349
         */
50fec4bad1f7 7014528: ColorModel and SampleModel gotten from the same ImageTypeSpecifier instance can be not compatible
bae
parents: 5506
diff changeset
   350
        int maxMask = (int)((1L << DataBuffer.getDataTypeSize(transferType)) - 1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        for (int i=0; i < bitMasks.length; i++) {
8750
50fec4bad1f7 7014528: ColorModel and SampleModel gotten from the same ImageTypeSpecifier instance can be not compatible
bae
parents: 5506
diff changeset
   352
            if ((maxMask & bitMasks[i]) != (maxMask & maskArray[i])) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     * Returns a {@link WritableRaster} representing the alpha channel of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * an image, extracted from the input <code>WritableRaster</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * This method assumes that <code>WritableRaster</code> objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * associated with this <code>ColorModel</code> store the alpha band,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * if present, as the last band of image data.  Returns <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     * if there is no separate spatial alpha channel associated with this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     * <code>ColorModel</code>.  This method creates a new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     * <code>WritableRaster</code>, but shares the data array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     * @param raster a <code>WritableRaster</code> containing an image
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * @return a <code>WritableRaster</code> that represents the alpha
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     *         channel of the image contained in <code>raster</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    public WritableRaster getAlphaRaster(WritableRaster raster) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        if (hasAlpha() == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        int x = raster.getMinX();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        int y = raster.getMinY();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        int[] band = new int[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        band[0] = raster.getNumBands() - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        return raster.createWritableChild(x, y, raster.getWidth(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                                          raster.getHeight(), x, y,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                                          band);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * Tests if the specified <code>Object</code> is an instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * of <code>PackedColorModel</code> and equals this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * <code>PackedColorModel</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * @param obj the <code>Object</code> to test for equality
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * @return <code>true</code> if the specified <code>Object</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * is an instance of <code>PackedColorModel</code> and equals this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * <code>PackedColorModel</code>; <code>false</code> otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    public boolean equals(Object obj) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        if (!(obj instanceof PackedColorModel)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        if (!super.equals(obj)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        PackedColorModel cm = (PackedColorModel) obj;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        int numC = cm.getNumComponents();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        if (numC != numComponents) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        for(int i=0; i < numC; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
            if (maskArray[i] != cm.getMask(i)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    private final static int[] createBitsArray(int[]colorMaskArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                                               int alphaMask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        int numColors = colorMaskArray.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        int numAlpha = (alphaMask == 0 ? 0 : 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        int[] arr = new int[numColors+numAlpha];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        for (int i=0; i < numColors; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            arr[i] = countBits(colorMaskArray[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            if (arr[i] < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                throw new IllegalArgumentException("Noncontiguous color mask ("
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                                     + Integer.toHexString(colorMaskArray[i])+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
                                     "at index "+i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        if (alphaMask != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            arr[numColors] = countBits(alphaMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            if (arr[numColors] < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                throw new IllegalArgumentException("Noncontiguous alpha mask ("
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                                     + Integer.toHexString(alphaMask));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        return arr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    private final static int[] createBitsArray(int rmask, int gmask, int bmask,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                                         int amask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        int[] arr = new int[3 + (amask == 0 ? 0 : 1)];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        arr[0] = countBits(rmask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        arr[1] = countBits(gmask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        arr[2] = countBits(bmask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        if (arr[0] < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            throw new IllegalArgumentException("Noncontiguous red mask ("
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                                     + Integer.toHexString(rmask));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        else if (arr[1] < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            throw new IllegalArgumentException("Noncontiguous green mask ("
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                                     + Integer.toHexString(gmask));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        else if (arr[2] < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            throw new IllegalArgumentException("Noncontiguous blue mask ("
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                                     + Integer.toHexString(bmask));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        if (amask != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            arr[3] = countBits(amask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            if (arr[3] < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                throw new IllegalArgumentException("Noncontiguous alpha mask ("
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                                     + Integer.toHexString(amask));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        return arr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    private final static int countBits(int mask) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        int count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        if (mask != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            while ((mask & 1) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                mask >>>= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            while ((mask & 1) == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                mask >>>= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                count++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        if (mask != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        return count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
}