< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  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 
  31 /**
  32  * The {@code PackedColorModel} class is an abstract
  33  * {@link ColorModel} class that works with pixel values which represent
  34  * color and alpha information as separate samples and which pack all
  35  * samples for a single pixel into a single int, short, or byte quantity.
  36  * This class can be used with an arbitrary {@link ColorSpace}.  The number of
  37  * color samples in the pixel values must be the same as the number of color
  38  * components in the {@code ColorSpace}.  There can be a single alpha
  39  * sample.  The array length is always 1 for those methods that use a
  40  * primitive array pixel representation of type {@code transferType}.
  41  * The transfer types supported are DataBuffer.TYPE_BYTE,
  42  * DataBuffer.TYPE_USHORT, and DataBuffer.TYPE_INT.
  43  * Color and alpha samples are stored in the single element of the array
  44  * in bits indicated by bit masks.  Each bit mask must be contiguous and
  45  * masks must not overlap.  The same masks apply to the single int
  46  * pixel representation used by other methods.  The correspondence of
  47  * masks and color/alpha samples is as follows:
  48  * <ul>
  49  * <li> Masks are identified by indices running from 0 through


  71  * done according to the masks of the {@code ColorModel}.
  72  * <p>
  73  * A single {@code int} pixel representation is valid for all objects
  74  * of this class since it is always possible to represent pixel values
  75  * used with this class in a single {@code int}.  Therefore, methods
  76  * that use this representation do not throw an
  77  * {@code IllegalArgumentException} due to an invalid pixel value.
  78  * <p>
  79  * A subclass of {@code PackedColorModel} is {@link DirectColorModel},
  80  * which is similar to an X11 TrueColor visual.
  81  *
  82  * @see DirectColorModel
  83  * @see SinglePixelPackedSampleModel
  84  * @see BufferedImage
  85  */
  86 
  87 public abstract class PackedColorModel extends ColorModel {
  88     int[] maskArray;
  89     int[] maskOffsets;
  90     float[] scaleFactors;

  91 
  92     /**
  93      * Constructs a {@code PackedColorModel} from a color mask array,
  94      * which specifies which bits in an {@code int} pixel representation
  95      * contain each of the color samples, and an alpha mask.  Color
  96      * components are in the specified {@code ColorSpace}.  The length of
  97      * {@code colorMaskArray} should be the number of components in
  98      * the {@code ColorSpace}.  All of the bits in each mask
  99      * must be contiguous and fit in the specified number of least significant
 100      * bits of an {@code int} pixel representation.  If the
 101      * {@code alphaMask} is 0, there is no alpha.  If there is alpha,
 102      * the {@code boolean isAlphaPremultiplied} specifies
 103      * how to interpret color and alpha samples in pixel values.  If the
 104      * {@code boolean} is {@code true}, color samples are assumed
 105      * to have been multiplied by the alpha sample.  The transparency,
 106      * {@code trans}, specifies what alpha values can be represented
 107      * by this color model.  The transfer type is the type of primitive
 108      * array used to represent pixel values.
 109      * @param space the specified {@code ColorSpace}
 110      * @param bits the number of bits in the pixel values


 376         }
 377 
 378         int x = raster.getMinX();
 379         int y = raster.getMinY();
 380         int[] band = new int[1];
 381         band[0] = raster.getNumBands() - 1;
 382         return raster.createWritableChild(x, y, raster.getWidth(),
 383                                           raster.getHeight(), x, y,
 384                                           band);
 385     }
 386 
 387     /**
 388      * Tests if the specified {@code Object} is an instance
 389      * of {@code PackedColorModel} and equals this
 390      * {@code PackedColorModel}.
 391      * @param obj the {@code Object} to test for equality
 392      * @return {@code true} if the specified {@code Object}
 393      * is an instance of {@code PackedColorModel} and equals this
 394      * {@code PackedColorModel}; {@code false} otherwise.
 395      */

 396     public boolean equals(Object obj) {
 397         if (!(obj instanceof PackedColorModel)) {
 398             return false;
 399         }
 400 
 401         if (!super.equals(obj)) {









 402             return false;
 403         }
 404 
 405         PackedColorModel cm = (PackedColorModel) obj;
 406         int numC = cm.getNumComponents();
 407         for(int i=0; i < numC; i++) {
 408             if (maskArray[i] != cm.getMask(i)) {
 409                 return false;
 410             }
 411         }











 412         return true;
























 413     }
 414 
 415     private static final int[] createBitsArray(int[]colorMaskArray,
 416                                                int alphaMask) {
 417         int numColors = colorMaskArray.length;
 418         int numAlpha = (alphaMask == 0 ? 0 : 1);
 419         int[] arr = new int[numColors+numAlpha];
 420         for (int i=0; i < numColors; i++) {
 421             arr[i] = countBits(colorMaskArray[i]);
 422             if (arr[i] < 0) {
 423                 throw new IllegalArgumentException("Noncontiguous color mask ("
 424                                      + Integer.toHexString(colorMaskArray[i])+
 425                                      "at index "+i);
 426             }
 427         }
 428         if (alphaMask != 0) {
 429             arr[numColors] = countBits(alphaMask);
 430             if (arr[numColors] < 0) {
 431                 throw new IllegalArgumentException("Noncontiguous alpha mask ("
 432                                      + Integer.toHexString(alphaMask));


   1 /*
   2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  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.util.Arrays;
  31 import java.util.Objects;
  32 
  33 /**
  34  * The {@code PackedColorModel} class is an abstract
  35  * {@link ColorModel} class that works with pixel values which represent
  36  * color and alpha information as separate samples and which pack all
  37  * samples for a single pixel into a single int, short, or byte quantity.
  38  * This class can be used with an arbitrary {@link ColorSpace}.  The number of
  39  * color samples in the pixel values must be the same as the number of color
  40  * components in the {@code ColorSpace}.  There can be a single alpha
  41  * sample.  The array length is always 1 for those methods that use a
  42  * primitive array pixel representation of type {@code transferType}.
  43  * The transfer types supported are DataBuffer.TYPE_BYTE,
  44  * DataBuffer.TYPE_USHORT, and DataBuffer.TYPE_INT.
  45  * Color and alpha samples are stored in the single element of the array
  46  * in bits indicated by bit masks.  Each bit mask must be contiguous and
  47  * masks must not overlap.  The same masks apply to the single int
  48  * pixel representation used by other methods.  The correspondence of
  49  * masks and color/alpha samples is as follows:
  50  * <ul>
  51  * <li> Masks are identified by indices running from 0 through


  73  * done according to the masks of the {@code ColorModel}.
  74  * <p>
  75  * A single {@code int} pixel representation is valid for all objects
  76  * of this class since it is always possible to represent pixel values
  77  * used with this class in a single {@code int}.  Therefore, methods
  78  * that use this representation do not throw an
  79  * {@code IllegalArgumentException} due to an invalid pixel value.
  80  * <p>
  81  * A subclass of {@code PackedColorModel} is {@link DirectColorModel},
  82  * which is similar to an X11 TrueColor visual.
  83  *
  84  * @see DirectColorModel
  85  * @see SinglePixelPackedSampleModel
  86  * @see BufferedImage
  87  */
  88 
  89 public abstract class PackedColorModel extends ColorModel {
  90     int[] maskArray;
  91     int[] maskOffsets;
  92     float[] scaleFactors;
  93     private volatile int hashCode;
  94 
  95     /**
  96      * Constructs a {@code PackedColorModel} from a color mask array,
  97      * which specifies which bits in an {@code int} pixel representation
  98      * contain each of the color samples, and an alpha mask.  Color
  99      * components are in the specified {@code ColorSpace}.  The length of
 100      * {@code colorMaskArray} should be the number of components in
 101      * the {@code ColorSpace}.  All of the bits in each mask
 102      * must be contiguous and fit in the specified number of least significant
 103      * bits of an {@code int} pixel representation.  If the
 104      * {@code alphaMask} is 0, there is no alpha.  If there is alpha,
 105      * the {@code boolean isAlphaPremultiplied} specifies
 106      * how to interpret color and alpha samples in pixel values.  If the
 107      * {@code boolean} is {@code true}, color samples are assumed
 108      * to have been multiplied by the alpha sample.  The transparency,
 109      * {@code trans}, specifies what alpha values can be represented
 110      * by this color model.  The transfer type is the type of primitive
 111      * array used to represent pixel values.
 112      * @param space the specified {@code ColorSpace}
 113      * @param bits the number of bits in the pixel values


 379         }
 380 
 381         int x = raster.getMinX();
 382         int y = raster.getMinY();
 383         int[] band = new int[1];
 384         band[0] = raster.getNumBands() - 1;
 385         return raster.createWritableChild(x, y, raster.getWidth(),
 386                                           raster.getHeight(), x, y,
 387                                           band);
 388     }
 389 
 390     /**
 391      * Tests if the specified {@code Object} is an instance
 392      * of {@code PackedColorModel} and equals this
 393      * {@code PackedColorModel}.
 394      * @param obj the {@code Object} to test for equality
 395      * @return {@code true} if the specified {@code Object}
 396      * is an instance of {@code PackedColorModel} and equals this
 397      * {@code PackedColorModel}; {@code false} otherwise.
 398      */
 399     @Override
 400     public boolean equals(Object obj) {
 401         if (!(obj instanceof PackedColorModel)) {
 402             return false;
 403         }
 404 
 405         PackedColorModel cm = (PackedColorModel) obj;
 406 
 407         if (supportsAlpha != cm.hasAlpha() ||
 408             isAlphaPremultiplied != cm.isAlphaPremultiplied() ||
 409             pixel_bits != cm.getPixelSize() ||
 410             transparency != cm.getTransparency() ||
 411             numComponents != cm.getNumComponents() ||
 412             (!(colorSpace.equals(cm.colorSpace))) ||
 413             transferType != cm.transferType)
 414         {
 415             return false;
 416         }
 417 

 418         int numC = cm.getNumComponents();
 419         for(int i=0; i < numC; i++) {
 420             if (maskArray[i] != cm.getMask(i)) {
 421                 return false;
 422             }
 423         }
 424 
 425         int[] nb = cm.getComponentSize();
 426         if ((nBits != null) && (nb != null)) {
 427             for (int i = 0; i < numComponents; i++) {
 428                 if (nBits[i] != nb[i]) {
 429                     return false;
 430                 }
 431             }
 432         } else {
 433             return ((nBits == null) && (nb == null));
 434         }
 435         return true;
 436     }
 437 
 438     /**
 439      * Returns the hash code for this PackedColorModel.
 440      *
 441      * @return    a hash code for this PackedColorModel.
 442      */
 443     @Override
 444     public int hashCode() {
 445         int result = hashCode;
 446         if (result == 0) {
 447             result = 7;
 448             result = 89 * result + this.pixel_bits;
 449             result = 89 * result + Arrays.hashCode(this.nBits);
 450             result = 89 * result + this.transparency;
 451             result = 89 * result + (this.supportsAlpha ? 1 : 0);
 452             result = 89 * result + (this.isAlphaPremultiplied ? 1 : 0);
 453             result = 89 * result + this.numComponents;
 454             result = 89 * result + Objects.hashCode(this.colorSpace);
 455             result = 89 * result + this.transferType;
 456             result = 89 * result + Arrays.hashCode(this.maskArray);
 457             hashCode = result;
 458         }
 459         return result;
 460     }
 461 
 462     private static final int[] createBitsArray(int[]colorMaskArray,
 463                                                int alphaMask) {
 464         int numColors = colorMaskArray.length;
 465         int numAlpha = (alphaMask == 0 ? 0 : 1);
 466         int[] arr = new int[numColors+numAlpha];
 467         for (int i=0; i < numColors; i++) {
 468             arr[i] = countBits(colorMaskArray[i]);
 469             if (arr[i] < 0) {
 470                 throw new IllegalArgumentException("Noncontiguous color mask ("
 471                                      + Integer.toHexString(colorMaskArray[i])+
 472                                      "at index "+i);
 473             }
 474         }
 475         if (alphaMask != 0) {
 476             arr[numColors] = countBits(alphaMask);
 477             if (arr[numColors] < 0) {
 478                 throw new IllegalArgumentException("Noncontiguous alpha mask ("
 479                                      + Integer.toHexString(alphaMask));


< prev index next >