< prev index next >

src/java.desktop/share/classes/java/awt/image/ColorModel.java

Print this page




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.image;
  27 
  28 import java.awt.Transparency;
  29 import java.awt.color.ColorSpace;
  30 import java.awt.color.ICC_ColorSpace;
  31 import sun.java2d.cmm.CMSManager;
  32 import sun.java2d.cmm.ColorTransform;
  33 import sun.java2d.cmm.PCMM;
  34 import java.awt.Toolkit;
  35 import java.util.Collections;
  36 import java.util.Map;
  37 import java.util.WeakHashMap;

  38 
  39 /**
  40  * The {@code ColorModel} abstract class encapsulates the
  41  * methods for translating a pixel value to color components
  42  * (for example, red, green, and blue) and an alpha component.
  43  * In order to render an image to the screen, a printer, or another
  44  * image, pixel values must be converted to color and alpha components.
  45  * As arguments to or return values from methods of this class,
  46  * pixels are represented as 32-bit ints or as arrays of primitive types.
  47  * The number, order, and interpretation of color components for a
  48  * {@code ColorModel} is specified by its {@code ColorSpace}.
  49  * A {@code ColorModel} used with pixel data that does not include
  50  * alpha information treats all pixels as opaque, which is an alpha
  51  * value of 1.0.
  52  * <p>
  53  * This {@code ColorModel} class supports two representations of
  54  * pixel values.  A pixel value can be a single 32-bit int or an
  55  * array of primitive types.  The Java(tm) Platform 1.0 and 1.1 APIs
  56  * represented pixels as single {@code byte} or single
  57  * {@code int} values.  For purposes of the {@code ColorModel}


 153  * @see Raster
 154  * @see DataBuffer
 155  */
 156 public abstract class ColorModel implements Transparency{
 157     private long pData;         // Placeholder for data for native functions
 158 
 159     /**
 160      * The total number of bits in the pixel.
 161      */
 162     protected int pixel_bits;
 163     int nBits[];
 164     int transparency = Transparency.TRANSLUCENT;
 165     boolean supportsAlpha = true;
 166     boolean isAlphaPremultiplied = false;
 167     int numComponents = -1;
 168     int numColorComponents = -1;
 169     ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
 170     int colorSpaceType = ColorSpace.TYPE_RGB;
 171     int maxBits;
 172     boolean is_sRGB = true;

 173 
 174     /**
 175      * Data type of the array used to represent pixel values.
 176      */
 177     protected int transferType;
 178 
 179     /**
 180      * This is copied from java.awt.Toolkit since we need the library
 181      * loaded in java.awt.image also:
 182      *
 183      * WARNING: This is a temporary workaround for a problem in the
 184      * way the AWT loads native libraries. A number of classes in the
 185      * AWT package have a native method, initIDs(), which initializes
 186      * the JNI field and method ids used in the native portion of
 187      * their implementation.
 188      *
 189      * Since the use and storage of these ids is done by the
 190      * implementation libraries, the implementation of these method is
 191      * provided by the particular AWT implementations (for example,
 192      * "Toolkit"s/Peer), such as Motif, Microsoft Windows, or Tiny. The


 345                                                bits.length);
 346         }
 347 
 348         // 4186669
 349         if (transparency < Transparency.OPAQUE ||
 350             transparency > Transparency.TRANSLUCENT)
 351         {
 352             throw new IllegalArgumentException("Unknown transparency: "+
 353                                                transparency);
 354         }
 355 
 356         if (supportsAlpha == false) {
 357             this.isAlphaPremultiplied = false;
 358             this.transparency = Transparency.OPAQUE;
 359         }
 360         else {
 361             this.isAlphaPremultiplied = isAlphaPremultiplied;
 362             this.transparency         = transparency;
 363         }
 364 
 365         nBits = bits.clone();







 366         this.pixel_bits = pixel_bits;
 367         if (pixel_bits <= 0) {
 368             throw new IllegalArgumentException("Number of pixel bits must "+
 369                                                "be > 0");
 370         }
 371         // Check for bits < 0
 372         maxBits = 0;
 373         for (int i=0; i < bits.length; i++) {
 374             // bug 4304697
 375             if (bits[i] < 0) {
 376                 throw new
 377                     IllegalArgumentException("Number of bits must be >= 0");
 378             }
 379             if (maxBits < bits[i]) {
 380                 maxBits = bits[i];
 381             }
 382         }
 383 
 384         // Make sure that we don't have all 0-bit components
 385         if (maxBits == 0) {


1424      *          {@code pixel} is not large enough to hold a pixel
1425      *          value for this {@code ColorModel}.
1426      * @throws UnsupportedOperationException if the
1427      *          constructor of this {@code ColorModel} called the
1428      *          {@code super(bits)} constructor, but did not
1429      *          override this method.  See the constructor,
1430      *          {@link #ColorModel(int)}.
1431      * @throws UnsupportedOperationException if this method is unable
1432      *          to determine the number of bits per component
1433      * @since 1.4
1434      */
1435     public float[] getNormalizedComponents(Object pixel,
1436                                            float[] normComponents,
1437                                            int normOffset) {
1438         int components[] = getComponents(pixel, null, 0);
1439         return getNormalizedComponents(components, 0,
1440                                        normComponents, normOffset);
1441     }
1442 
1443     /**
1444      * Tests if the specified {@code Object} is an instance of
1445      * {@code ColorModel} and if it equals this
1446      * {@code ColorModel}.


















1447      * @param obj the {@code Object} to test for equality
1448      * @return {@code true} if the specified {@code Object}
1449      * is an instance of {@code ColorModel} and equals this
1450      * {@code ColorModel}; {@code false} otherwise.
1451      */

1452     public boolean equals(Object obj) {
1453         if (!(obj instanceof ColorModel)) {



1454             return false;
1455         }
1456         ColorModel cm = (ColorModel) obj;
1457 
1458         if (this == cm) {
1459             return true;
1460         }
1461         if (supportsAlpha != cm.hasAlpha() ||
1462             isAlphaPremultiplied != cm.isAlphaPremultiplied() ||
1463             pixel_bits != cm.getPixelSize() ||
1464             transparency != cm.getTransparency() ||
1465             numComponents != cm.getNumComponents())


1466         {
1467             return false;
1468         }
1469 
1470         int[] nb = cm.getComponentSize();
1471 
1472         if ((nBits != null) && (nb != null)) {
1473             for (int i = 0; i < numComponents; i++) {
1474                 if (nBits[i] != nb[i]) {
1475                     return false;
1476                 }
1477             }
1478         } else {
1479             return ((nBits == null) && (nb == null));
1480         }
1481 
1482         return true;
1483     }
1484 
1485     /**
1486      * Returns the hash code for this ColorModel.
1487      *
1488      * @return    a hash code for this ColorModel.
1489      */

1490     public int hashCode() {
1491 
1492         int result = 0;
1493 
1494         result = (supportsAlpha ? 2 : 3) +
1495                  (isAlphaPremultiplied ? 4 : 5) +
1496                  pixel_bits * 6 +
1497                  transparency * 7 +
1498                  numComponents * 8;
1499 
1500         if (nBits != null) {
1501             for (int i = 0; i < numComponents; i++) {
1502                 result = result + nBits[i] * (i + 9);
1503             }
1504         }
1505 
1506         return result;
1507     }
1508 
1509     /**
1510      * Returns the {@code ColorSpace} associated with this
1511      * {@code ColorModel}.
1512      * @return the {@code ColorSpace} of this
1513      * {@code ColorModel}.
1514      */
1515     public final ColorSpace getColorSpace() {
1516         return colorSpace;
1517     }
1518 
1519     /**
1520      * Forces the raster data to match the state specified in the
1521      * {@code isAlphaPremultiplied} variable, assuming the data is
1522      * currently correctly described by this {@code ColorModel}.  It
1523      * may multiply or divide the color raster data by alpha, or do
1524      * nothing if the data is in the correct state.  If the data needs to
1525      * be coerced, this method will also return an instance of this




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.image;
  27 
  28 import java.awt.Transparency;
  29 import java.awt.color.ColorSpace;
  30 import java.awt.color.ICC_ColorSpace;
  31 import sun.java2d.cmm.CMSManager;
  32 import sun.java2d.cmm.ColorTransform;
  33 import sun.java2d.cmm.PCMM;
  34 import java.util.Arrays;
  35 import java.util.Collections;
  36 import java.util.Map;
  37 import java.util.WeakHashMap;
  38 import java.util.Objects;
  39 
  40 /**
  41  * The {@code ColorModel} abstract class encapsulates the
  42  * methods for translating a pixel value to color components
  43  * (for example, red, green, and blue) and an alpha component.
  44  * In order to render an image to the screen, a printer, or another
  45  * image, pixel values must be converted to color and alpha components.
  46  * As arguments to or return values from methods of this class,
  47  * pixels are represented as 32-bit ints or as arrays of primitive types.
  48  * The number, order, and interpretation of color components for a
  49  * {@code ColorModel} is specified by its {@code ColorSpace}.
  50  * A {@code ColorModel} used with pixel data that does not include
  51  * alpha information treats all pixels as opaque, which is an alpha
  52  * value of 1.0.
  53  * <p>
  54  * This {@code ColorModel} class supports two representations of
  55  * pixel values.  A pixel value can be a single 32-bit int or an
  56  * array of primitive types.  The Java(tm) Platform 1.0 and 1.1 APIs
  57  * represented pixels as single {@code byte} or single
  58  * {@code int} values.  For purposes of the {@code ColorModel}


 154  * @see Raster
 155  * @see DataBuffer
 156  */
 157 public abstract class ColorModel implements Transparency{
 158     private long pData;         // Placeholder for data for native functions
 159 
 160     /**
 161      * The total number of bits in the pixel.
 162      */
 163     protected int pixel_bits;
 164     int nBits[];
 165     int transparency = Transparency.TRANSLUCENT;
 166     boolean supportsAlpha = true;
 167     boolean isAlphaPremultiplied = false;
 168     int numComponents = -1;
 169     int numColorComponents = -1;
 170     ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
 171     int colorSpaceType = ColorSpace.TYPE_RGB;
 172     int maxBits;
 173     boolean is_sRGB = true;
 174     private volatile int hashCode;
 175 
 176     /**
 177      * Data type of the array used to represent pixel values.
 178      */
 179     protected int transferType;
 180 
 181     /**
 182      * This is copied from java.awt.Toolkit since we need the library
 183      * loaded in java.awt.image also:
 184      *
 185      * WARNING: This is a temporary workaround for a problem in the
 186      * way the AWT loads native libraries. A number of classes in the
 187      * AWT package have a native method, initIDs(), which initializes
 188      * the JNI field and method ids used in the native portion of
 189      * their implementation.
 190      *
 191      * Since the use and storage of these ids is done by the
 192      * implementation libraries, the implementation of these method is
 193      * provided by the particular AWT implementations (for example,
 194      * "Toolkit"s/Peer), such as Motif, Microsoft Windows, or Tiny. The


 347                                                bits.length);
 348         }
 349 
 350         // 4186669
 351         if (transparency < Transparency.OPAQUE ||
 352             transparency > Transparency.TRANSLUCENT)
 353         {
 354             throw new IllegalArgumentException("Unknown transparency: "+
 355                                                transparency);
 356         }
 357 
 358         if (supportsAlpha == false) {
 359             this.isAlphaPremultiplied = false;
 360             this.transparency = Transparency.OPAQUE;
 361         }
 362         else {
 363             this.isAlphaPremultiplied = isAlphaPremultiplied;
 364             this.transparency         = transparency;
 365         }
 366 
 367         /*
 368          * We need significant bits value only for the length
 369          * of number of components, so we truncate remaining part.
 370          * It also helps in hashCode calculation since bits[] can contain
 371          * different values after the length of number of components between
 372          * two ColorModels.
 373          */
 374         nBits = Arrays.copyOf(bits, numComponents);
 375         this.pixel_bits = pixel_bits;
 376         if (pixel_bits <= 0) {
 377             throw new IllegalArgumentException("Number of pixel bits must "+
 378                                                "be > 0");
 379         }
 380         // Check for bits < 0
 381         maxBits = 0;
 382         for (int i=0; i < bits.length; i++) {
 383             // bug 4304697
 384             if (bits[i] < 0) {
 385                 throw new
 386                     IllegalArgumentException("Number of bits must be >= 0");
 387             }
 388             if (maxBits < bits[i]) {
 389                 maxBits = bits[i];
 390             }
 391         }
 392 
 393         // Make sure that we don't have all 0-bit components
 394         if (maxBits == 0) {


1433      *          {@code pixel} is not large enough to hold a pixel
1434      *          value for this {@code ColorModel}.
1435      * @throws UnsupportedOperationException if the
1436      *          constructor of this {@code ColorModel} called the
1437      *          {@code super(bits)} constructor, but did not
1438      *          override this method.  See the constructor,
1439      *          {@link #ColorModel(int)}.
1440      * @throws UnsupportedOperationException if this method is unable
1441      *          to determine the number of bits per component
1442      * @since 1.4
1443      */
1444     public float[] getNormalizedComponents(Object pixel,
1445                                            float[] normComponents,
1446                                            int normOffset) {
1447         int components[] = getComponents(pixel, null, 0);
1448         return getNormalizedComponents(components, 0,
1449                                        normComponents, normOffset);
1450     }
1451 
1452     /**
1453      * Tests if the specified {@code Object} equals this

1454      * {@code ColorModel}.
1455      * In order to protect the symmetry property of
1456      * {@code (a.equals(b) == b.equals(a))},
1457      * the target object must be the same class(and not a subclass)
1458      * as this object to evaluate as {equals}.
1459      * <p>
1460      * To verify equality we also check following properties:
1461      *
1462      * <ul>
1463      * <li>Support for alpha component.
1464      * <li>Is alpha premultiplied.
1465      * <li>Number of bits per pixel.
1466      * <li>Type of transparency like Opaque, Bitmask or Translucent.
1467      * <li>Number of components in a pixel.
1468      * <li>{@code ColorSpace} type.
1469      * <li>Type of the array used to represent pixel values.
1470      * <li>Number of significant bits per color and alpha component.
1471      * </ul>
1472      * <p>
1473      * @param obj the {@code Object} to test for equality
1474      * @return {@code true} if the specified {@code Object}
1475      * equals this {@code ColorModel}; {@code false} otherwise.

1476      */
1477     @Override
1478     public boolean equals(Object obj) {
1479         if (this == obj) {
1480             return true;
1481         }
1482         if ((obj == null) || (obj.getClass() !=  getClass())) {
1483             return false;
1484         }

1485 
1486         ColorModel cm = (ColorModel) obj;


1487         if (supportsAlpha != cm.hasAlpha() ||
1488             isAlphaPremultiplied != cm.isAlphaPremultiplied() ||
1489             pixel_bits != cm.getPixelSize() ||
1490             transparency != cm.getTransparency() ||
1491             numComponents != cm.getNumComponents() ||
1492             (!(colorSpace.equals(cm.colorSpace))) ||
1493             transferType != cm.transferType)
1494         {
1495             return false;
1496         }
1497 
1498         int[] nb = cm.getComponentSize();
1499 
1500         if ((nBits != null) && (nb != null)) {
1501             for (int i = 0; i < numComponents; i++) {
1502                 if (nBits[i] != nb[i]) {
1503                     return false;
1504                 }
1505             }
1506         } else {
1507             return ((nBits == null) && (nb == null));
1508         }
1509 
1510         return true;
1511     }
1512 
1513     /**
1514      * Returns the hash code for this ColorModel.
1515      *
1516      * @return    a hash code for this ColorModel.
1517      */
1518     @Override
1519     public int hashCode() {
1520         int result = hashCode;
1521         if (result == 0) {
1522             result = 7;
1523             result = 89 * result + this.pixel_bits;
1524             result = 89 * result + Arrays.hashCode(this.nBits);
1525             result = 89 * result + this.transparency;
1526             result = 89 * result + (this.supportsAlpha ? 1 : 0);
1527             result = 89 * result + (this.isAlphaPremultiplied ? 1 : 0);
1528             result = 89 * result + this.numComponents;
1529             result = 89 * result + Objects.hashCode(this.colorSpace);
1530             result = 89 * result + this.transferType;
1531             hashCode = result;
1532         }


1533         return result;
1534     }
1535 
1536     /**
1537      * Returns the {@code ColorSpace} associated with this
1538      * {@code ColorModel}.
1539      * @return the {@code ColorSpace} of this
1540      * {@code ColorModel}.
1541      */
1542     public final ColorSpace getColorSpace() {
1543         return colorSpace;
1544     }
1545 
1546     /**
1547      * Forces the raster data to match the state specified in the
1548      * {@code isAlphaPremultiplied} variable, assuming the data is
1549      * currently correctly described by this {@code ColorModel}.  It
1550      * may multiply or divide the color raster data by alpha, or do
1551      * nothing if the data is in the correct state.  If the data needs to
1552      * be coerced, this method will also return an instance of this


< prev index next >