< prev index next >

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

Print this page

        

@@ -29,14 +29,15 @@
 import java.awt.color.ColorSpace;
 import java.awt.color.ICC_ColorSpace;
 import sun.java2d.cmm.CMSManager;
 import sun.java2d.cmm.ColorTransform;
 import sun.java2d.cmm.PCMM;
-import java.awt.Toolkit;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
 import java.util.WeakHashMap;
+import java.util.Objects;
 
 /**
  * The {@code ColorModel} abstract class encapsulates the
  * methods for translating a pixel value to color components
  * (for example, red, green, and blue) and an alpha component.

@@ -168,10 +169,11 @@
     int numColorComponents = -1;
     ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
     int colorSpaceType = ColorSpace.TYPE_RGB;
     int maxBits;
     boolean is_sRGB = true;
+    private volatile int hashCode;
 
     /**
      * Data type of the array used to represent pixel values.
      */
     protected int transferType;

@@ -360,11 +362,18 @@
         else {
             this.isAlphaPremultiplied = isAlphaPremultiplied;
             this.transparency         = transparency;
         }
 
-        nBits = bits.clone();
+        /*
+         * We need significant bits value only for the length
+         * of number of components, so we truncate remaining part.
+         * It also helps in hashCode calculation since bits[] can contain
+         * different values after the length of number of components between
+         * two ColorModels.
+         */
+        nBits = Arrays.copyOf(bits, numComponents);
         this.pixel_bits = pixel_bits;
         if (pixel_bits <= 0) {
             throw new IllegalArgumentException("Number of pixel bits must "+
                                                "be > 0");
         }

@@ -1439,32 +1448,51 @@
         return getNormalizedComponents(components, 0,
                                        normComponents, normOffset);
     }
 
     /**
-     * Tests if the specified {@code Object} is an instance of
-     * {@code ColorModel} and if it equals this
+     * Tests if the specified {@code Object} equals this
      * {@code ColorModel}.
+     * In order to protect the symmetry property of
+     * {@code (a.equals(b) == b.equals(a))},
+     * the target object must be the same class(and not a subclass)
+     * as this object to evaluate as {equals}.
+     * <p>
+     * To verify equality we also check following properties:
+     *
+     * <ul>
+     * <li>Support for alpha component.
+     * <li>Is alpha premultiplied.
+     * <li>Number of bits per pixel.
+     * <li>Type of transparency like Opaque, Bitmask or Translucent.
+     * <li>Number of components in a pixel.
+     * <li>{@code ColorSpace} type.
+     * <li>Type of the array used to represent pixel values.
+     * <li>Number of significant bits per color and alpha component.
+     * </ul>
+     * <p>
      * @param obj the {@code Object} to test for equality
      * @return {@code true} if the specified {@code Object}
-     * is an instance of {@code ColorModel} and equals this
-     * {@code ColorModel}; {@code false} otherwise.
+     * equals this {@code ColorModel}; {@code false} otherwise.
      */
+    @Override
     public boolean equals(Object obj) {
-        if (!(obj instanceof ColorModel)) {
+        if (this == obj) {
+            return true;
+        }
+        if ((obj == null) || (obj.getClass() !=  getClass())) {
             return false;
         }
-        ColorModel cm = (ColorModel) obj;
 
-        if (this == cm) {
-            return true;
-        }
+        ColorModel cm = (ColorModel) obj;
         if (supportsAlpha != cm.hasAlpha() ||
             isAlphaPremultiplied != cm.isAlphaPremultiplied() ||
             pixel_bits != cm.getPixelSize() ||
             transparency != cm.getTransparency() ||
-            numComponents != cm.getNumComponents())
+            numComponents != cm.getNumComponents() ||
+            (!(colorSpace.equals(cm.colorSpace))) ||
+            transferType != cm.transferType)
         {
             return false;
         }
 
         int[] nb = cm.getComponentSize();

@@ -1485,26 +1513,25 @@
     /**
      * Returns the hash code for this ColorModel.
      *
      * @return    a hash code for this ColorModel.
      */
+    @Override
     public int hashCode() {
-
-        int result = 0;
-
-        result = (supportsAlpha ? 2 : 3) +
-                 (isAlphaPremultiplied ? 4 : 5) +
-                 pixel_bits * 6 +
-                 transparency * 7 +
-                 numComponents * 8;
-
-        if (nBits != null) {
-            for (int i = 0; i < numComponents; i++) {
-                result = result + nBits[i] * (i + 9);
+        int result = hashCode;
+        if (result == 0) {
+            result = 7;
+            result = 89 * result + this.pixel_bits;
+            result = 89 * result + Arrays.hashCode(this.nBits);
+            result = 89 * result + this.transparency;
+            result = 89 * result + (this.supportsAlpha ? 1 : 0);
+            result = 89 * result + (this.isAlphaPremultiplied ? 1 : 0);
+            result = 89 * result + this.numComponents;
+            result = 89 * result + Objects.hashCode(this.colorSpace);
+            result = 89 * result + this.transferType;
+            hashCode = result;
             }
-        }
-
         return result;
     }
 
     /**
      * Returns the {@code ColorSpace} associated with this
< prev index next >