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
|