< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 1995, 2013, 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


 294      * Returns the mask indicating which bits in an {@code int} pixel
 295      * representation contain the alpha component.
 296      * @return the mask, which indicates which bits of the {@code int}
 297      *         pixel representation contain the alpha sample.
 298      */
 299     public final int getAlphaMask() {
 300         if (supportsAlpha) {
 301             return maskArray[3];
 302         } else {
 303             return 0;
 304         }
 305     }
 306 
 307 
 308     /*
 309      * Given an int pixel in this ColorModel's ColorSpace, converts
 310      * it to the default sRGB ColorSpace and returns the R, G, and B
 311      * components as float values between 0.0 and 1.0.
 312      */
 313     private float[] getDefaultRGBComponents(int pixel) {
 314         int components[] = getComponents(pixel, null, 0);
 315         float norm[] = getNormalizedComponents(components, 0, null, 0);
 316         // Note that getNormalizedComponents returns non-premultiplied values
 317         return colorSpace.toRGB(norm);
 318     }
 319 
 320 
 321     private int getsRGBComponentFromsRGB(int pixel, int idx) {
 322         int c = ((pixel & maskArray[idx]) >>> maskOffsets[idx]);
 323         if (isAlphaPremultiplied) {
 324             int a = ((pixel & maskArray[3]) >>> maskOffsets[3]);
 325             c = (a == 0) ? 0 :
 326                          (int) (((c * scaleFactors[idx]) * 255.0f /
 327                                  (a * scaleFactors[3])) + 0.5f);
 328         } else if (scaleFactors[idx] != 1.0f) {
 329             c = (int) ((c * scaleFactors[idx]) + 0.5f);
 330         }
 331         return c;
 332     }
 333 
 334 
 335     private int getsRGBComponentFromLinearRGB(int pixel, int idx) {


 354 
 355     /**
 356      * Returns the red color component for the specified pixel, scaled
 357      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 358      * color conversion is done if necessary.  The pixel value is specified
 359      * as an {@code int}.
 360      * The returned value is a non pre-multiplied value.  Thus, if the
 361      * alpha is premultiplied, this method divides it out before returning
 362      * the value.  If the alpha value is 0, for example, the red value
 363      * is 0.
 364      * @param pixel the specified pixel
 365      * @return the red color component for the specified pixel, from
 366      *         0 to 255 in the sRGB {@code ColorSpace}.
 367      */
 368     public final int getRed(int pixel) {
 369         if (is_sRGB) {
 370             return getsRGBComponentFromsRGB(pixel, 0);
 371         } else if (is_LinearRGB) {
 372             return getsRGBComponentFromLinearRGB(pixel, 0);
 373         }
 374         float rgb[] = getDefaultRGBComponents(pixel);
 375         return (int) (rgb[0] * 255.0f + 0.5f);
 376     }
 377 
 378     /**
 379      * Returns the green color component for the specified pixel, scaled
 380      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 381      * color conversion is done if necessary.  The pixel value is specified
 382      * as an {@code int}.
 383      * The returned value is a non pre-multiplied value.  Thus, if the
 384      * alpha is premultiplied, this method divides it out before returning
 385      * the value.  If the alpha value is 0, for example, the green value
 386      * is 0.
 387      * @param pixel the specified pixel
 388      * @return the green color component for the specified pixel, from
 389      *         0 to 255 in the sRGB {@code ColorSpace}.
 390      */
 391     public final int getGreen(int pixel) {
 392         if (is_sRGB) {
 393             return getsRGBComponentFromsRGB(pixel, 1);
 394         } else if (is_LinearRGB) {
 395             return getsRGBComponentFromLinearRGB(pixel, 1);
 396         }
 397         float rgb[] = getDefaultRGBComponents(pixel);
 398         return (int) (rgb[1] * 255.0f + 0.5f);
 399     }
 400 
 401     /**
 402      * Returns the blue color component for the specified pixel, scaled
 403      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 404      * color conversion is done if necessary.  The pixel value is specified
 405      * as an {@code int}.
 406      * The returned value is a non pre-multiplied value.  Thus, if the
 407      * alpha is premultiplied, this method divides it out before returning
 408      * the value.  If the alpha value is 0, for example, the blue value
 409      * is 0.
 410      * @param pixel the specified pixel
 411      * @return the blue color component for the specified pixel, from
 412      *         0 to 255 in the sRGB {@code ColorSpace}.
 413      */
 414     public final int getBlue(int pixel) {
 415         if (is_sRGB) {
 416             return getsRGBComponentFromsRGB(pixel, 2);
 417         } else if (is_LinearRGB) {
 418             return getsRGBComponentFromLinearRGB(pixel, 2);
 419         }
 420         float rgb[] = getDefaultRGBComponents(pixel);
 421         return (int) (rgb[2] * 255.0f + 0.5f);
 422     }
 423 
 424     /**
 425      * Returns the alpha component for the specified pixel, scaled
 426      * from 0 to 255.  The pixel value is specified as an {@code int}.
 427      * @param pixel the specified pixel
 428      * @return the value of the alpha component of {@code pixel}
 429      *         from 0 to 255.
 430      */
 431     public final int getAlpha(int pixel) {
 432         if (!supportsAlpha) return 255;
 433         int a = ((pixel & maskArray[3]) >>> maskOffsets[3]);
 434         if (scaleFactors[3] != 1.0f) {
 435             a = (int)(a * scaleFactors[3] + 0.5f);
 436         }
 437         return a;
 438     }
 439 
 440     /**
 441      * Returns the color/alpha components of the pixel in the default
 442      * RGB color model format.  A color conversion is done if necessary.
 443      * The pixel value is specified as an {@code int}.
 444      * The returned value is in a non pre-multiplied format.  Thus, if
 445      * the alpha is premultiplied, this method divides it out of the
 446      * color components.  If the alpha value is 0, for example, the color
 447      * values are each 0.
 448      * @param pixel the specified pixel
 449      * @return the RGB value of the color/alpha components of the specified
 450      *         pixel.
 451      * @see ColorModel#getRGBdefault
 452      */
 453     public final int getRGB(int pixel) {
 454         if (is_sRGB || is_LinearRGB) {
 455             return (getAlpha(pixel) << 24)
 456                 | (getRed(pixel) << 16)
 457                 | (getGreen(pixel) << 8)
 458                 | (getBlue(pixel) << 0);
 459         }
 460         float rgb[] = getDefaultRGBComponents(pixel);
 461         return (getAlpha(pixel) << 24)
 462             | (((int) (rgb[0] * 255.0f + 0.5f)) << 16)
 463             | (((int) (rgb[1] * 255.0f + 0.5f)) << 8)
 464             | (((int) (rgb[2] * 255.0f + 0.5f)) << 0);
 465     }
 466 
 467     /**
 468      * Returns the red color component for the specified pixel, scaled
 469      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 470      * color conversion is done if necessary.  The pixel value is specified
 471      * by an array of data elements of type {@code transferType} passed
 472      * in as an object reference.
 473      * The returned value is a non pre-multiplied value.  Thus, if the
 474      * alpha is premultiplied, this method divides it out before returning
 475      * the value.  If the alpha value is 0, for example, the red value
 476      * is 0.
 477      * If {@code inData} is not a primitive array of type
 478      * {@code transferType}, a {@code ClassCastException} is
 479      * thrown.  An {@code ArrayIndexOutOfBoundsException} is
 480      * thrown if {@code inData} is not large enough to hold a


 482      * {@code DirectColorModel} can be subclassed, subclasses inherit
 483      * the implementation of this method and if they don't override it
 484      * then they throw an exception if they use an unsupported
 485      * {@code transferType}.
 486      * An {@code UnsupportedOperationException} is thrown if this
 487      * {@code transferType} is not supported by this
 488      * {@code ColorModel}.
 489      * @param inData the array containing the pixel value
 490      * @return the value of the red component of the specified pixel.
 491      * @throws ArrayIndexOutOfBoundsException if {@code inData} is not
 492      *         large enough to hold a pixel value for this color model
 493      * @throws ClassCastException if {@code inData} is not a
 494      *         primitive array of type {@code transferType}
 495      * @throws UnsupportedOperationException if this {@code transferType}
 496      *         is not supported by this color model
 497      */
 498     public int getRed(Object inData) {
 499         int pixel=0;
 500         switch (transferType) {
 501             case DataBuffer.TYPE_BYTE:
 502                byte bdata[] = (byte[])inData;
 503                pixel = bdata[0] & 0xff;
 504             break;
 505             case DataBuffer.TYPE_USHORT:
 506                short sdata[] = (short[])inData;
 507                pixel = sdata[0] & 0xffff;
 508             break;
 509             case DataBuffer.TYPE_INT:
 510                int idata[] = (int[])inData;
 511                pixel = idata[0];
 512             break;
 513             default:
 514                throw new UnsupportedOperationException("This method has not been "+
 515                    "implemented for transferType " + transferType);
 516         }
 517         return getRed(pixel);
 518     }
 519 
 520 
 521     /**
 522      * Returns the green color component for the specified pixel, scaled
 523      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 524      * color conversion is done if necessary.  The pixel value is specified
 525      * by an array of data elements of type {@code transferType} passed
 526      * in as an object reference.
 527      * The returned value is a non pre-multiplied value.  Thus, if the
 528      * alpha is premultiplied, this method divides it out before returning
 529      * the value.  If the alpha value is 0, for example, the green value
 530      * is 0.  If {@code inData} is not a primitive array of type


 535      * {@code DirectColorModel} can be subclassed, subclasses inherit
 536      * the implementation of this method and if they don't override it
 537      * then they throw an exception if they use an unsupported
 538      * {@code transferType}.
 539      * An {@code UnsupportedOperationException} is
 540      * thrown if this {@code transferType} is not supported by this
 541      * {@code ColorModel}.
 542      * @param inData the array containing the pixel value
 543      * @return the value of the green component of the specified pixel.
 544      * @throws ArrayIndexOutOfBoundsException if {@code inData} is not
 545      *         large enough to hold a pixel value for this color model
 546      * @throws ClassCastException if {@code inData} is not a
 547      *         primitive array of type {@code transferType}
 548      * @throws UnsupportedOperationException if this {@code transferType}
 549      *         is not supported by this color model
 550      */
 551     public int getGreen(Object inData) {
 552         int pixel=0;
 553         switch (transferType) {
 554             case DataBuffer.TYPE_BYTE:
 555                byte bdata[] = (byte[])inData;
 556                pixel = bdata[0] & 0xff;
 557             break;
 558             case DataBuffer.TYPE_USHORT:
 559                short sdata[] = (short[])inData;
 560                pixel = sdata[0] & 0xffff;
 561             break;
 562             case DataBuffer.TYPE_INT:
 563                int idata[] = (int[])inData;
 564                pixel = idata[0];
 565             break;
 566             default:
 567                throw new UnsupportedOperationException("This method has not been "+
 568                    "implemented for transferType " + transferType);
 569         }
 570         return getGreen(pixel);
 571     }
 572 
 573 
 574     /**
 575      * Returns the blue color component for the specified pixel, scaled
 576      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 577      * color conversion is done if necessary.  The pixel value is specified
 578      * by an array of data elements of type {@code transferType} passed
 579      * in as an object reference.
 580      * The returned value is a non pre-multiplied value.  Thus, if the
 581      * alpha is premultiplied, this method divides it out before returning
 582      * the value.  If the alpha value is 0, for example, the blue value
 583      * is 0.  If {@code inData} is not a primitive array of type


 588      * {@code DirectColorModel} can be subclassed, subclasses inherit
 589      * the implementation of this method and if they don't override it
 590      * then they throw an exception if they use an unsupported
 591      * {@code transferType}.
 592      * An {@code UnsupportedOperationException} is
 593      * thrown if this {@code transferType} is not supported by this
 594      * {@code ColorModel}.
 595      * @param inData the array containing the pixel value
 596      * @return the value of the blue component of the specified pixel.
 597      * @throws ArrayIndexOutOfBoundsException if {@code inData} is not
 598      *         large enough to hold a pixel value for this color model
 599      * @throws ClassCastException if {@code inData} is not a
 600      *         primitive array of type {@code transferType}
 601      * @throws UnsupportedOperationException if this {@code transferType}
 602      *         is not supported by this color model
 603      */
 604     public int getBlue(Object inData) {
 605         int pixel=0;
 606         switch (transferType) {
 607             case DataBuffer.TYPE_BYTE:
 608                byte bdata[] = (byte[])inData;
 609                pixel = bdata[0] & 0xff;
 610             break;
 611             case DataBuffer.TYPE_USHORT:
 612                short sdata[] = (short[])inData;
 613                pixel = sdata[0] & 0xffff;
 614             break;
 615             case DataBuffer.TYPE_INT:
 616                int idata[] = (int[])inData;
 617                pixel = idata[0];
 618             break;
 619             default:
 620                throw new UnsupportedOperationException("This method has not been "+
 621                    "implemented for transferType " + transferType);
 622         }
 623         return getBlue(pixel);
 624     }
 625 
 626     /**
 627      * Returns the alpha component for the specified pixel, scaled
 628      * from 0 to 255.  The pixel value is specified by an array of data
 629      * elements of type {@code transferType} passed in as an object
 630      * reference.
 631      * If {@code inData} is not a primitive array of type
 632      * {@code transferType}, a {@code ClassCastException} is
 633      * thrown.  An {@code ArrayIndexOutOfBoundsException} is
 634      * thrown if {@code inData} is not large enough to hold a pixel
 635      * value for this {@code ColorModel}.  Since
 636      * {@code DirectColorModel} can be subclassed, subclasses inherit


 638      * then they throw an exception if they use an unsupported
 639      * {@code transferType}.
 640      * If this {@code transferType} is not supported, an
 641      * {@code UnsupportedOperationException} is thrown.
 642      * @param inData the specified pixel
 643      * @return the alpha component of the specified pixel, scaled from
 644      *         0 to 255.
 645      * @exception ClassCastException if {@code inData}
 646      *  is not a primitive array of type {@code transferType}
 647      * @exception ArrayIndexOutOfBoundsException if
 648      *  {@code inData} is not large enough to hold a pixel value
 649      *  for this {@code ColorModel}
 650      * @exception UnsupportedOperationException if this
 651      *  {@code tranferType} is not supported by this
 652      *  {@code ColorModel}
 653      */
 654     public int getAlpha(Object inData) {
 655         int pixel=0;
 656         switch (transferType) {
 657             case DataBuffer.TYPE_BYTE:
 658                byte bdata[] = (byte[])inData;
 659                pixel = bdata[0] & 0xff;
 660             break;
 661             case DataBuffer.TYPE_USHORT:
 662                short sdata[] = (short[])inData;
 663                pixel = sdata[0] & 0xffff;
 664             break;
 665             case DataBuffer.TYPE_INT:
 666                int idata[] = (int[])inData;
 667                pixel = idata[0];
 668             break;
 669             default:
 670                throw new UnsupportedOperationException("This method has not been "+
 671                    "implemented for transferType " + transferType);
 672         }
 673         return getAlpha(pixel);
 674     }
 675 
 676     /**
 677      * Returns the color/alpha components for the specified pixel in the
 678      * default RGB color model format.  A color conversion is done if
 679      * necessary.  The pixel value is specified by an array of data
 680      * elements of type {@code transferType} passed in as an object
 681      * reference.  If {@code inData} is not a primitive array of type
 682      * {@code transferType}, a {@code ClassCastException} is
 683      * thrown.  An {@code ArrayIndexOutOfBoundsException} is
 684      * thrown if {@code inData} is not large enough to hold a pixel
 685      * value for this {@code ColorModel}.
 686      * The returned value is in a non pre-multiplied format.  Thus, if
 687      * the alpha is premultiplied, this method divides it out of the
 688      * color components.  If the alpha value is 0, for example, the color
 689      * values is 0.  Since {@code DirectColorModel} can be
 690      * subclassed, subclasses inherit the implementation of this method
 691      * and if they don't override it then
 692      * they throw an exception if they use an unsupported
 693      * {@code transferType}.
 694      *
 695      * @param inData the specified pixel
 696      * @return the color and alpha components of the specified pixel.
 697      * @exception UnsupportedOperationException if this
 698      *            {@code transferType} is not supported by this
 699      *            {@code ColorModel}
 700      * @see ColorModel#getRGBdefault
 701      */
 702     public int getRGB(Object inData) {
 703         int pixel=0;
 704         switch (transferType) {
 705             case DataBuffer.TYPE_BYTE:
 706                byte bdata[] = (byte[])inData;
 707                pixel = bdata[0] & 0xff;
 708             break;
 709             case DataBuffer.TYPE_USHORT:
 710                short sdata[] = (short[])inData;
 711                pixel = sdata[0] & 0xffff;
 712             break;
 713             case DataBuffer.TYPE_INT:
 714                int idata[] = (int[])inData;
 715                pixel = idata[0];
 716             break;
 717             default:
 718                throw new UnsupportedOperationException("This method has not been "+
 719                    "implemented for transferType " + transferType);
 720         }
 721         return getRGB(pixel);
 722     }
 723 
 724     /**
 725      * Returns a data element array representation of a pixel in this
 726      * {@code ColorModel}, given an integer pixel representation in the
 727      * default RGB color model.
 728      * This array can then be passed to the {@code setDataElements}
 729      * method of a {@code WritableRaster} object.  If the pixel variable
 730      * is {@code null}, a new array is allocated.  If {@code pixel}
 731      * is not {@code null}, it must be a primitive array of type
 732      * {@code transferType}; otherwise, a
 733      * {@code ClassCastException} is thrown.  An
 734      * {@code ArrayIndexOutOfBoundsException} is


 741      *
 742      * @param rgb the integer pixel representation in the default RGB
 743      *            color model
 744      * @param pixel the specified pixel
 745      * @return an array representation of the specified pixel in this
 746      *         {@code ColorModel}
 747      * @exception ClassCastException if {@code pixel}
 748      *  is not a primitive array of type {@code transferType}
 749      * @exception ArrayIndexOutOfBoundsException if
 750      *  {@code pixel} is not large enough to hold a pixel value
 751      *  for this {@code ColorModel}
 752      * @exception UnsupportedOperationException if this
 753      *  {@code transferType} is not supported by this
 754      *  {@code ColorModel}
 755      * @see WritableRaster#setDataElements
 756      * @see SampleModel#setDataElements
 757      */
 758     public Object getDataElements(int rgb, Object pixel) {
 759         //REMIND: maybe more efficient not to use int array for
 760         //DataBuffer.TYPE_USHORT and DataBuffer.TYPE_INT
 761         int intpixel[] = null;
 762         if (transferType == DataBuffer.TYPE_INT &&
 763             pixel != null) {
 764             intpixel = (int[])pixel;
 765             intpixel[0] = 0;
 766         } else {
 767             intpixel = new int[1];
 768         }
 769 
 770         ColorModel defaultCM = ColorModel.getRGBdefault();
 771         if (this == defaultCM || equals(defaultCM)) {
 772             intpixel[0] = rgb;
 773             return intpixel;
 774         }
 775 
 776         int red, grn, blu, alp;
 777         red = (rgb>>16) & 0xff;
 778         grn = (rgb>>8) & 0xff;
 779         blu = rgb & 0xff;
 780         if (is_sRGB || is_LinearRGB) {
 781             int precision;


 859             // some calculations done above with float precision
 860             // may lose enough precision that the integer result
 861             // overflows nBits, so we need to clamp.
 862             if (red > ((1<<nBits[0]) - 1)) {
 863                 red = (1<<nBits[0]) - 1;
 864             }
 865             if (grn > ((1<<nBits[1]) - 1)) {
 866                 grn = (1<<nBits[1]) - 1;
 867             }
 868             if (blu > ((1<<nBits[2]) - 1)) {
 869                 blu = (1<<nBits[2]) - 1;
 870             }
 871         }
 872 
 873         intpixel[0] |= (red << maskOffsets[0]) |
 874                        (grn << maskOffsets[1]) |
 875                        (blu << maskOffsets[2]);
 876 
 877         switch (transferType) {
 878             case DataBuffer.TYPE_BYTE: {
 879                byte bdata[];
 880                if (pixel == null) {
 881                    bdata = new byte[1];
 882                } else {
 883                    bdata = (byte[])pixel;
 884                }
 885                bdata[0] = (byte)(0xff&intpixel[0]);
 886                return bdata;
 887             }
 888             case DataBuffer.TYPE_USHORT:{
 889                short sdata[];
 890                if (pixel == null) {
 891                    sdata = new short[1];
 892                } else {
 893                    sdata = (short[])pixel;
 894                }
 895                sdata[0] = (short)(intpixel[0]&0xffff);
 896                return sdata;
 897             }
 898             case DataBuffer.TYPE_INT:
 899                return intpixel;
 900         }
 901         throw new UnsupportedOperationException("This method has not been "+
 902                  "implemented for transferType " + transferType);
 903 
 904     }
 905 
 906     /**
 907      * Returns an array of unnormalized color/alpha components given a pixel
 908      * in this {@code ColorModel}.  The pixel value is specified as an
 909      * {@code int}.  If the {@code components} array is


 962      * @param offset the offset into the {@code components} array at
 963      *        which to start storing the color and alpha components
 964      * @return an array containing the color and alpha components of the
 965      * specified pixel starting at the specified offset.
 966      * @exception ClassCastException if {@code pixel}
 967      *  is not a primitive array of type {@code transferType}
 968      * @exception ArrayIndexOutOfBoundsException if
 969      *  {@code pixel} is not large enough to hold a pixel value
 970      *  for this {@code ColorModel}, or if {@code components}
 971      *  is not {@code null} and is not large enough to hold all the
 972      *  color and alpha components, starting at {@code offset}
 973      * @exception UnsupportedOperationException if this
 974      *            {@code transferType} is not supported by this
 975      *            color model
 976      */
 977     public final int[] getComponents(Object pixel, int[] components,
 978                                      int offset) {
 979         int intpixel=0;
 980         switch (transferType) {
 981             case DataBuffer.TYPE_BYTE:
 982                byte bdata[] = (byte[])pixel;
 983                intpixel = bdata[0] & 0xff;
 984             break;
 985             case DataBuffer.TYPE_USHORT:
 986                short sdata[] = (short[])pixel;
 987                intpixel = sdata[0] & 0xffff;
 988             break;
 989             case DataBuffer.TYPE_INT:
 990                int idata[] = (int[])pixel;
 991                intpixel = idata[0];
 992             break;
 993             default:
 994                throw new UnsupportedOperationException("This method has not been "+
 995                    "implemented for transferType " + transferType);
 996         }
 997         return getComponents(intpixel, components, offset);
 998     }
 999 
1000     /**
1001      * Creates a {@code WritableRaster} with the specified width and
1002      * height that has a data layout ({@code SampleModel}) compatible
1003      * with this {@code ColorModel}.
1004      * @param w the width to apply to the new {@code WritableRaster}
1005      * @param h the height to apply to the new {@code WritableRaster}
1006      * @return a {@code WritableRaster} object with the specified
1007      * width and height.
1008      * @throws IllegalArgumentException if {@code w} or {@code h}
1009      *         is less than or equal to zero
1010      * @see WritableRaster


1101      *  is not a primitive array of type {@code transferType}
1102      * @exception ArrayIndexOutOfBoundsException if
1103      *  {@code obj} is not large enough to hold a pixel value
1104      *  for this {@code ColorModel} or the {@code components}
1105      *  array is not large enough to hold all of the color and alpha
1106      *  components starting at {@code offset}
1107      * @exception UnsupportedOperationException if this
1108      *            {@code transferType} is not supported by this
1109      *            color model
1110      * @see WritableRaster#setDataElements
1111      * @see SampleModel#setDataElements
1112      */
1113     public Object getDataElements(int[] components, int offset, Object obj) {
1114         int pixel = 0;
1115         for (int i=0; i < numComponents; i++) {
1116             pixel |= ((components[offset+i]<<maskOffsets[i])&maskArray[i]);
1117         }
1118         switch (transferType) {
1119             case DataBuffer.TYPE_BYTE:
1120                if (obj instanceof byte[]) {
1121                    byte bdata[] = (byte[])obj;
1122                    bdata[0] = (byte)(pixel&0xff);
1123                    return bdata;
1124                } else {
1125                    byte bdata[] = {(byte)(pixel&0xff)};
1126                    return bdata;
1127                }
1128             case DataBuffer.TYPE_USHORT:
1129                if (obj instanceof short[]) {
1130                    short sdata[] = (short[])obj;
1131                    sdata[0] = (short)(pixel&0xffff);
1132                    return sdata;
1133                } else {
1134                    short sdata[] = {(short)(pixel&0xffff)};
1135                    return sdata;
1136                }
1137             case DataBuffer.TYPE_INT:
1138                if (obj instanceof int[]) {
1139                    int idata[] = (int[])obj;
1140                    idata[0] = pixel;
1141                    return idata;
1142                } else {
1143                    int idata[] = {pixel};
1144                    return idata;
1145                }
1146             default:
1147                throw new ClassCastException("This method has not been "+
1148                    "implemented for transferType " + transferType);
1149         }
1150     }
1151 
1152     /**
1153      * Forces the raster data to match the state specified in the
1154      * {@code isAlphaPremultiplied} variable, assuming the data is
1155      * currently correctly described by this {@code ColorModel}.  It
1156      * may multiply or divide the color raster data by alpha, or do
1157      * nothing if the data is in the correct state.  If the data needs to
1158      * be coerced, this method will also return an instance of this
1159      * {@code ColorModel} with the {@code isAlphaPremultiplied}
1160      * flag set appropriately.  This method will throw a
1161      * {@code UnsupportedOperationException} if this transferType is
1162      * not supported by this {@code ColorModel}.  Since
1163      * {@code ColorModel} can be subclassed, subclasses inherit the


1173      *            {@code transferType} is not supported by this
1174      *            color model
1175      */
1176     public final ColorModel coerceData (WritableRaster raster,
1177                                         boolean isAlphaPremultiplied)
1178     {
1179         if (!supportsAlpha ||
1180             this.isAlphaPremultiplied() == isAlphaPremultiplied) {
1181             return this;
1182         }
1183 
1184         int w = raster.getWidth();
1185         int h = raster.getHeight();
1186         int aIdx = numColorComponents;
1187         float normAlpha;
1188         float alphaScale = 1.0f / ((float) ((1 << nBits[aIdx]) - 1));
1189 
1190         int rminX = raster.getMinX();
1191         int rY = raster.getMinY();
1192         int rX;
1193         int pixel[] = null;
1194         int zpixel[] = null;
1195 
1196         if (isAlphaPremultiplied) {
1197             // Must mean that we are currently not premultiplied so
1198             // multiply by alpha
1199             switch (transferType) {
1200                 case DataBuffer.TYPE_BYTE: {
1201                     for (int y = 0; y < h; y++, rY++) {
1202                         rX = rminX;
1203                         for (int x = 0; x < w; x++, rX++) {
1204                             pixel = raster.getPixel(rX, rY, pixel);
1205                             normAlpha = pixel[aIdx] * alphaScale;
1206                             if (normAlpha != 0.f) {
1207                                 for (int c=0; c < aIdx; c++) {
1208                                     pixel[c] = (int) (pixel[c] * normAlpha +
1209                                                       0.5f);
1210                                 }
1211                                 raster.setPixel(rX, rY, pixel);
1212                             } else {
1213                                 if (zpixel == null) {
1214                                     zpixel = new int[numComponents];


   1 /*
   2  * Copyright (c) 1995, 2018, 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


 294      * Returns the mask indicating which bits in an {@code int} pixel
 295      * representation contain the alpha component.
 296      * @return the mask, which indicates which bits of the {@code int}
 297      *         pixel representation contain the alpha sample.
 298      */
 299     public final int getAlphaMask() {
 300         if (supportsAlpha) {
 301             return maskArray[3];
 302         } else {
 303             return 0;
 304         }
 305     }
 306 
 307 
 308     /*
 309      * Given an int pixel in this ColorModel's ColorSpace, converts
 310      * it to the default sRGB ColorSpace and returns the R, G, and B
 311      * components as float values between 0.0 and 1.0.
 312      */
 313     private float[] getDefaultRGBComponents(int pixel) {
 314         int[] components = getComponents(pixel, null, 0);
 315         float[] norm = getNormalizedComponents(components, 0, null, 0);
 316         // Note that getNormalizedComponents returns non-premultiplied values
 317         return colorSpace.toRGB(norm);
 318     }
 319 
 320 
 321     private int getsRGBComponentFromsRGB(int pixel, int idx) {
 322         int c = ((pixel & maskArray[idx]) >>> maskOffsets[idx]);
 323         if (isAlphaPremultiplied) {
 324             int a = ((pixel & maskArray[3]) >>> maskOffsets[3]);
 325             c = (a == 0) ? 0 :
 326                          (int) (((c * scaleFactors[idx]) * 255.0f /
 327                                  (a * scaleFactors[3])) + 0.5f);
 328         } else if (scaleFactors[idx] != 1.0f) {
 329             c = (int) ((c * scaleFactors[idx]) + 0.5f);
 330         }
 331         return c;
 332     }
 333 
 334 
 335     private int getsRGBComponentFromLinearRGB(int pixel, int idx) {


 354 
 355     /**
 356      * Returns the red color component for the specified pixel, scaled
 357      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 358      * color conversion is done if necessary.  The pixel value is specified
 359      * as an {@code int}.
 360      * The returned value is a non pre-multiplied value.  Thus, if the
 361      * alpha is premultiplied, this method divides it out before returning
 362      * the value.  If the alpha value is 0, for example, the red value
 363      * is 0.
 364      * @param pixel the specified pixel
 365      * @return the red color component for the specified pixel, from
 366      *         0 to 255 in the sRGB {@code ColorSpace}.
 367      */
 368     public final int getRed(int pixel) {
 369         if (is_sRGB) {
 370             return getsRGBComponentFromsRGB(pixel, 0);
 371         } else if (is_LinearRGB) {
 372             return getsRGBComponentFromLinearRGB(pixel, 0);
 373         }
 374         float[] rgb = getDefaultRGBComponents(pixel);
 375         return (int) (rgb[0] * 255.0f + 0.5f);
 376     }
 377 
 378     /**
 379      * Returns the green color component for the specified pixel, scaled
 380      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 381      * color conversion is done if necessary.  The pixel value is specified
 382      * as an {@code int}.
 383      * The returned value is a non pre-multiplied value.  Thus, if the
 384      * alpha is premultiplied, this method divides it out before returning
 385      * the value.  If the alpha value is 0, for example, the green value
 386      * is 0.
 387      * @param pixel the specified pixel
 388      * @return the green color component for the specified pixel, from
 389      *         0 to 255 in the sRGB {@code ColorSpace}.
 390      */
 391     public final int getGreen(int pixel) {
 392         if (is_sRGB) {
 393             return getsRGBComponentFromsRGB(pixel, 1);
 394         } else if (is_LinearRGB) {
 395             return getsRGBComponentFromLinearRGB(pixel, 1);
 396         }
 397         float[] rgb = getDefaultRGBComponents(pixel);
 398         return (int) (rgb[1] * 255.0f + 0.5f);
 399     }
 400 
 401     /**
 402      * Returns the blue color component for the specified pixel, scaled
 403      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 404      * color conversion is done if necessary.  The pixel value is specified
 405      * as an {@code int}.
 406      * The returned value is a non pre-multiplied value.  Thus, if the
 407      * alpha is premultiplied, this method divides it out before returning
 408      * the value.  If the alpha value is 0, for example, the blue value
 409      * is 0.
 410      * @param pixel the specified pixel
 411      * @return the blue color component for the specified pixel, from
 412      *         0 to 255 in the sRGB {@code ColorSpace}.
 413      */
 414     public final int getBlue(int pixel) {
 415         if (is_sRGB) {
 416             return getsRGBComponentFromsRGB(pixel, 2);
 417         } else if (is_LinearRGB) {
 418             return getsRGBComponentFromLinearRGB(pixel, 2);
 419         }
 420         float[] rgb = getDefaultRGBComponents(pixel);
 421         return (int) (rgb[2] * 255.0f + 0.5f);
 422     }
 423 
 424     /**
 425      * Returns the alpha component for the specified pixel, scaled
 426      * from 0 to 255.  The pixel value is specified as an {@code int}.
 427      * @param pixel the specified pixel
 428      * @return the value of the alpha component of {@code pixel}
 429      *         from 0 to 255.
 430      */
 431     public final int getAlpha(int pixel) {
 432         if (!supportsAlpha) return 255;
 433         int a = ((pixel & maskArray[3]) >>> maskOffsets[3]);
 434         if (scaleFactors[3] != 1.0f) {
 435             a = (int)(a * scaleFactors[3] + 0.5f);
 436         }
 437         return a;
 438     }
 439 
 440     /**
 441      * Returns the color/alpha components of the pixel in the default
 442      * RGB color model format.  A color conversion is done if necessary.
 443      * The pixel value is specified as an {@code int}.
 444      * The returned value is in a non pre-multiplied format.  Thus, if
 445      * the alpha is premultiplied, this method divides it out of the
 446      * color components.  If the alpha value is 0, for example, the color
 447      * values are each 0.
 448      * @param pixel the specified pixel
 449      * @return the RGB value of the color/alpha components of the specified
 450      *         pixel.
 451      * @see ColorModel#getRGBdefault
 452      */
 453     public final int getRGB(int pixel) {
 454         if (is_sRGB || is_LinearRGB) {
 455             return (getAlpha(pixel) << 24)
 456                 | (getRed(pixel) << 16)
 457                 | (getGreen(pixel) << 8)
 458                 | (getBlue(pixel) << 0);
 459         }
 460         float[] rgb = getDefaultRGBComponents(pixel);
 461         return (getAlpha(pixel) << 24)
 462             | (((int) (rgb[0] * 255.0f + 0.5f)) << 16)
 463             | (((int) (rgb[1] * 255.0f + 0.5f)) << 8)
 464             | (((int) (rgb[2] * 255.0f + 0.5f)) << 0);
 465     }
 466 
 467     /**
 468      * Returns the red color component for the specified pixel, scaled
 469      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 470      * color conversion is done if necessary.  The pixel value is specified
 471      * by an array of data elements of type {@code transferType} passed
 472      * in as an object reference.
 473      * The returned value is a non pre-multiplied value.  Thus, if the
 474      * alpha is premultiplied, this method divides it out before returning
 475      * the value.  If the alpha value is 0, for example, the red value
 476      * is 0.
 477      * If {@code inData} is not a primitive array of type
 478      * {@code transferType}, a {@code ClassCastException} is
 479      * thrown.  An {@code ArrayIndexOutOfBoundsException} is
 480      * thrown if {@code inData} is not large enough to hold a


 482      * {@code DirectColorModel} can be subclassed, subclasses inherit
 483      * the implementation of this method and if they don't override it
 484      * then they throw an exception if they use an unsupported
 485      * {@code transferType}.
 486      * An {@code UnsupportedOperationException} is thrown if this
 487      * {@code transferType} is not supported by this
 488      * {@code ColorModel}.
 489      * @param inData the array containing the pixel value
 490      * @return the value of the red component of the specified pixel.
 491      * @throws ArrayIndexOutOfBoundsException if {@code inData} is not
 492      *         large enough to hold a pixel value for this color model
 493      * @throws ClassCastException if {@code inData} is not a
 494      *         primitive array of type {@code transferType}
 495      * @throws UnsupportedOperationException if this {@code transferType}
 496      *         is not supported by this color model
 497      */
 498     public int getRed(Object inData) {
 499         int pixel=0;
 500         switch (transferType) {
 501             case DataBuffer.TYPE_BYTE:
 502                byte[] bdata = (byte[])inData;
 503                pixel = bdata[0] & 0xff;
 504             break;
 505             case DataBuffer.TYPE_USHORT:
 506                short[] sdata = (short[])inData;
 507                pixel = sdata[0] & 0xffff;
 508             break;
 509             case DataBuffer.TYPE_INT:
 510                int[] idata = (int[])inData;
 511                pixel = idata[0];
 512             break;
 513             default:
 514                throw new UnsupportedOperationException("This method has not been "+
 515                    "implemented for transferType " + transferType);
 516         }
 517         return getRed(pixel);
 518     }
 519 
 520 
 521     /**
 522      * Returns the green color component for the specified pixel, scaled
 523      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 524      * color conversion is done if necessary.  The pixel value is specified
 525      * by an array of data elements of type {@code transferType} passed
 526      * in as an object reference.
 527      * The returned value is a non pre-multiplied value.  Thus, if the
 528      * alpha is premultiplied, this method divides it out before returning
 529      * the value.  If the alpha value is 0, for example, the green value
 530      * is 0.  If {@code inData} is not a primitive array of type


 535      * {@code DirectColorModel} can be subclassed, subclasses inherit
 536      * the implementation of this method and if they don't override it
 537      * then they throw an exception if they use an unsupported
 538      * {@code transferType}.
 539      * An {@code UnsupportedOperationException} is
 540      * thrown if this {@code transferType} is not supported by this
 541      * {@code ColorModel}.
 542      * @param inData the array containing the pixel value
 543      * @return the value of the green component of the specified pixel.
 544      * @throws ArrayIndexOutOfBoundsException if {@code inData} is not
 545      *         large enough to hold a pixel value for this color model
 546      * @throws ClassCastException if {@code inData} is not a
 547      *         primitive array of type {@code transferType}
 548      * @throws UnsupportedOperationException if this {@code transferType}
 549      *         is not supported by this color model
 550      */
 551     public int getGreen(Object inData) {
 552         int pixel=0;
 553         switch (transferType) {
 554             case DataBuffer.TYPE_BYTE:
 555                byte[] bdata = (byte[])inData;
 556                pixel = bdata[0] & 0xff;
 557             break;
 558             case DataBuffer.TYPE_USHORT:
 559                short[] sdata = (short[])inData;
 560                pixel = sdata[0] & 0xffff;
 561             break;
 562             case DataBuffer.TYPE_INT:
 563                int[] idata = (int[])inData;
 564                pixel = idata[0];
 565             break;
 566             default:
 567                throw new UnsupportedOperationException("This method has not been "+
 568                    "implemented for transferType " + transferType);
 569         }
 570         return getGreen(pixel);
 571     }
 572 
 573 
 574     /**
 575      * Returns the blue color component for the specified pixel, scaled
 576      * from 0 to 255 in the default RGB {@code ColorSpace}, sRGB.  A
 577      * color conversion is done if necessary.  The pixel value is specified
 578      * by an array of data elements of type {@code transferType} passed
 579      * in as an object reference.
 580      * The returned value is a non pre-multiplied value.  Thus, if the
 581      * alpha is premultiplied, this method divides it out before returning
 582      * the value.  If the alpha value is 0, for example, the blue value
 583      * is 0.  If {@code inData} is not a primitive array of type


 588      * {@code DirectColorModel} can be subclassed, subclasses inherit
 589      * the implementation of this method and if they don't override it
 590      * then they throw an exception if they use an unsupported
 591      * {@code transferType}.
 592      * An {@code UnsupportedOperationException} is
 593      * thrown if this {@code transferType} is not supported by this
 594      * {@code ColorModel}.
 595      * @param inData the array containing the pixel value
 596      * @return the value of the blue component of the specified pixel.
 597      * @throws ArrayIndexOutOfBoundsException if {@code inData} is not
 598      *         large enough to hold a pixel value for this color model
 599      * @throws ClassCastException if {@code inData} is not a
 600      *         primitive array of type {@code transferType}
 601      * @throws UnsupportedOperationException if this {@code transferType}
 602      *         is not supported by this color model
 603      */
 604     public int getBlue(Object inData) {
 605         int pixel=0;
 606         switch (transferType) {
 607             case DataBuffer.TYPE_BYTE:
 608                byte[] bdata = (byte[])inData;
 609                pixel = bdata[0] & 0xff;
 610             break;
 611             case DataBuffer.TYPE_USHORT:
 612                short[] sdata = (short[])inData;
 613                pixel = sdata[0] & 0xffff;
 614             break;
 615             case DataBuffer.TYPE_INT:
 616                int[] idata = (int[])inData;
 617                pixel = idata[0];
 618             break;
 619             default:
 620                throw new UnsupportedOperationException("This method has not been "+
 621                    "implemented for transferType " + transferType);
 622         }
 623         return getBlue(pixel);
 624     }
 625 
 626     /**
 627      * Returns the alpha component for the specified pixel, scaled
 628      * from 0 to 255.  The pixel value is specified by an array of data
 629      * elements of type {@code transferType} passed in as an object
 630      * reference.
 631      * If {@code inData} is not a primitive array of type
 632      * {@code transferType}, a {@code ClassCastException} is
 633      * thrown.  An {@code ArrayIndexOutOfBoundsException} is
 634      * thrown if {@code inData} is not large enough to hold a pixel
 635      * value for this {@code ColorModel}.  Since
 636      * {@code DirectColorModel} can be subclassed, subclasses inherit


 638      * then they throw an exception if they use an unsupported
 639      * {@code transferType}.
 640      * If this {@code transferType} is not supported, an
 641      * {@code UnsupportedOperationException} is thrown.
 642      * @param inData the specified pixel
 643      * @return the alpha component of the specified pixel, scaled from
 644      *         0 to 255.
 645      * @exception ClassCastException if {@code inData}
 646      *  is not a primitive array of type {@code transferType}
 647      * @exception ArrayIndexOutOfBoundsException if
 648      *  {@code inData} is not large enough to hold a pixel value
 649      *  for this {@code ColorModel}
 650      * @exception UnsupportedOperationException if this
 651      *  {@code tranferType} is not supported by this
 652      *  {@code ColorModel}
 653      */
 654     public int getAlpha(Object inData) {
 655         int pixel=0;
 656         switch (transferType) {
 657             case DataBuffer.TYPE_BYTE:
 658                byte[] bdata = (byte[])inData;
 659                pixel = bdata[0] & 0xff;
 660             break;
 661             case DataBuffer.TYPE_USHORT:
 662                short[] sdata = (short[])inData;
 663                pixel = sdata[0] & 0xffff;
 664             break;
 665             case DataBuffer.TYPE_INT:
 666                int[] idata = (int[])inData;
 667                pixel = idata[0];
 668             break;
 669             default:
 670                throw new UnsupportedOperationException("This method has not been "+
 671                    "implemented for transferType " + transferType);
 672         }
 673         return getAlpha(pixel);
 674     }
 675 
 676     /**
 677      * Returns the color/alpha components for the specified pixel in the
 678      * default RGB color model format.  A color conversion is done if
 679      * necessary.  The pixel value is specified by an array of data
 680      * elements of type {@code transferType} passed in as an object
 681      * reference.  If {@code inData} is not a primitive array of type
 682      * {@code transferType}, a {@code ClassCastException} is
 683      * thrown.  An {@code ArrayIndexOutOfBoundsException} is
 684      * thrown if {@code inData} is not large enough to hold a pixel
 685      * value for this {@code ColorModel}.
 686      * The returned value is in a non pre-multiplied format.  Thus, if
 687      * the alpha is premultiplied, this method divides it out of the
 688      * color components.  If the alpha value is 0, for example, the color
 689      * values is 0.  Since {@code DirectColorModel} can be
 690      * subclassed, subclasses inherit the implementation of this method
 691      * and if they don't override it then
 692      * they throw an exception if they use an unsupported
 693      * {@code transferType}.
 694      *
 695      * @param inData the specified pixel
 696      * @return the color and alpha components of the specified pixel.
 697      * @exception UnsupportedOperationException if this
 698      *            {@code transferType} is not supported by this
 699      *            {@code ColorModel}
 700      * @see ColorModel#getRGBdefault
 701      */
 702     public int getRGB(Object inData) {
 703         int pixel=0;
 704         switch (transferType) {
 705             case DataBuffer.TYPE_BYTE:
 706                byte[] bdata = (byte[])inData;
 707                pixel = bdata[0] & 0xff;
 708             break;
 709             case DataBuffer.TYPE_USHORT:
 710                short[] sdata = (short[])inData;
 711                pixel = sdata[0] & 0xffff;
 712             break;
 713             case DataBuffer.TYPE_INT:
 714                int[] idata = (int[])inData;
 715                pixel = idata[0];
 716             break;
 717             default:
 718                throw new UnsupportedOperationException("This method has not been "+
 719                    "implemented for transferType " + transferType);
 720         }
 721         return getRGB(pixel);
 722     }
 723 
 724     /**
 725      * Returns a data element array representation of a pixel in this
 726      * {@code ColorModel}, given an integer pixel representation in the
 727      * default RGB color model.
 728      * This array can then be passed to the {@code setDataElements}
 729      * method of a {@code WritableRaster} object.  If the pixel variable
 730      * is {@code null}, a new array is allocated.  If {@code pixel}
 731      * is not {@code null}, it must be a primitive array of type
 732      * {@code transferType}; otherwise, a
 733      * {@code ClassCastException} is thrown.  An
 734      * {@code ArrayIndexOutOfBoundsException} is


 741      *
 742      * @param rgb the integer pixel representation in the default RGB
 743      *            color model
 744      * @param pixel the specified pixel
 745      * @return an array representation of the specified pixel in this
 746      *         {@code ColorModel}
 747      * @exception ClassCastException if {@code pixel}
 748      *  is not a primitive array of type {@code transferType}
 749      * @exception ArrayIndexOutOfBoundsException if
 750      *  {@code pixel} is not large enough to hold a pixel value
 751      *  for this {@code ColorModel}
 752      * @exception UnsupportedOperationException if this
 753      *  {@code transferType} is not supported by this
 754      *  {@code ColorModel}
 755      * @see WritableRaster#setDataElements
 756      * @see SampleModel#setDataElements
 757      */
 758     public Object getDataElements(int rgb, Object pixel) {
 759         //REMIND: maybe more efficient not to use int array for
 760         //DataBuffer.TYPE_USHORT and DataBuffer.TYPE_INT
 761         int[] intpixel = null;
 762         if (transferType == DataBuffer.TYPE_INT &&
 763             pixel != null) {
 764             intpixel = (int[])pixel;
 765             intpixel[0] = 0;
 766         } else {
 767             intpixel = new int[1];
 768         }
 769 
 770         ColorModel defaultCM = ColorModel.getRGBdefault();
 771         if (this == defaultCM || equals(defaultCM)) {
 772             intpixel[0] = rgb;
 773             return intpixel;
 774         }
 775 
 776         int red, grn, blu, alp;
 777         red = (rgb>>16) & 0xff;
 778         grn = (rgb>>8) & 0xff;
 779         blu = rgb & 0xff;
 780         if (is_sRGB || is_LinearRGB) {
 781             int precision;


 859             // some calculations done above with float precision
 860             // may lose enough precision that the integer result
 861             // overflows nBits, so we need to clamp.
 862             if (red > ((1<<nBits[0]) - 1)) {
 863                 red = (1<<nBits[0]) - 1;
 864             }
 865             if (grn > ((1<<nBits[1]) - 1)) {
 866                 grn = (1<<nBits[1]) - 1;
 867             }
 868             if (blu > ((1<<nBits[2]) - 1)) {
 869                 blu = (1<<nBits[2]) - 1;
 870             }
 871         }
 872 
 873         intpixel[0] |= (red << maskOffsets[0]) |
 874                        (grn << maskOffsets[1]) |
 875                        (blu << maskOffsets[2]);
 876 
 877         switch (transferType) {
 878             case DataBuffer.TYPE_BYTE: {
 879                byte[] bdata;
 880                if (pixel == null) {
 881                    bdata = new byte[1];
 882                } else {
 883                    bdata = (byte[])pixel;
 884                }
 885                bdata[0] = (byte)(0xff&intpixel[0]);
 886                return bdata;
 887             }
 888             case DataBuffer.TYPE_USHORT:{
 889                short[] sdata;
 890                if (pixel == null) {
 891                    sdata = new short[1];
 892                } else {
 893                    sdata = (short[])pixel;
 894                }
 895                sdata[0] = (short)(intpixel[0]&0xffff);
 896                return sdata;
 897             }
 898             case DataBuffer.TYPE_INT:
 899                return intpixel;
 900         }
 901         throw new UnsupportedOperationException("This method has not been "+
 902                  "implemented for transferType " + transferType);
 903 
 904     }
 905 
 906     /**
 907      * Returns an array of unnormalized color/alpha components given a pixel
 908      * in this {@code ColorModel}.  The pixel value is specified as an
 909      * {@code int}.  If the {@code components} array is


 962      * @param offset the offset into the {@code components} array at
 963      *        which to start storing the color and alpha components
 964      * @return an array containing the color and alpha components of the
 965      * specified pixel starting at the specified offset.
 966      * @exception ClassCastException if {@code pixel}
 967      *  is not a primitive array of type {@code transferType}
 968      * @exception ArrayIndexOutOfBoundsException if
 969      *  {@code pixel} is not large enough to hold a pixel value
 970      *  for this {@code ColorModel}, or if {@code components}
 971      *  is not {@code null} and is not large enough to hold all the
 972      *  color and alpha components, starting at {@code offset}
 973      * @exception UnsupportedOperationException if this
 974      *            {@code transferType} is not supported by this
 975      *            color model
 976      */
 977     public final int[] getComponents(Object pixel, int[] components,
 978                                      int offset) {
 979         int intpixel=0;
 980         switch (transferType) {
 981             case DataBuffer.TYPE_BYTE:
 982                byte[] bdata = (byte[])pixel;
 983                intpixel = bdata[0] & 0xff;
 984             break;
 985             case DataBuffer.TYPE_USHORT:
 986                short[] sdata = (short[])pixel;
 987                intpixel = sdata[0] & 0xffff;
 988             break;
 989             case DataBuffer.TYPE_INT:
 990                int[] idata = (int[])pixel;
 991                intpixel = idata[0];
 992             break;
 993             default:
 994                throw new UnsupportedOperationException("This method has not been "+
 995                    "implemented for transferType " + transferType);
 996         }
 997         return getComponents(intpixel, components, offset);
 998     }
 999 
1000     /**
1001      * Creates a {@code WritableRaster} with the specified width and
1002      * height that has a data layout ({@code SampleModel}) compatible
1003      * with this {@code ColorModel}.
1004      * @param w the width to apply to the new {@code WritableRaster}
1005      * @param h the height to apply to the new {@code WritableRaster}
1006      * @return a {@code WritableRaster} object with the specified
1007      * width and height.
1008      * @throws IllegalArgumentException if {@code w} or {@code h}
1009      *         is less than or equal to zero
1010      * @see WritableRaster


1101      *  is not a primitive array of type {@code transferType}
1102      * @exception ArrayIndexOutOfBoundsException if
1103      *  {@code obj} is not large enough to hold a pixel value
1104      *  for this {@code ColorModel} or the {@code components}
1105      *  array is not large enough to hold all of the color and alpha
1106      *  components starting at {@code offset}
1107      * @exception UnsupportedOperationException if this
1108      *            {@code transferType} is not supported by this
1109      *            color model
1110      * @see WritableRaster#setDataElements
1111      * @see SampleModel#setDataElements
1112      */
1113     public Object getDataElements(int[] components, int offset, Object obj) {
1114         int pixel = 0;
1115         for (int i=0; i < numComponents; i++) {
1116             pixel |= ((components[offset+i]<<maskOffsets[i])&maskArray[i]);
1117         }
1118         switch (transferType) {
1119             case DataBuffer.TYPE_BYTE:
1120                if (obj instanceof byte[]) {
1121                    byte[] bdata = (byte[])obj;
1122                    bdata[0] = (byte)(pixel&0xff);
1123                    return bdata;
1124                } else {
1125                    byte[] bdata = {(byte)(pixel&0xff)};
1126                    return bdata;
1127                }
1128             case DataBuffer.TYPE_USHORT:
1129                if (obj instanceof short[]) {
1130                    short[] sdata = (short[])obj;
1131                    sdata[0] = (short)(pixel&0xffff);
1132                    return sdata;
1133                } else {
1134                    short[] sdata = {(short)(pixel&0xffff)};
1135                    return sdata;
1136                }
1137             case DataBuffer.TYPE_INT:
1138                if (obj instanceof int[]) {
1139                    int[] idata = (int[])obj;
1140                    idata[0] = pixel;
1141                    return idata;
1142                } else {
1143                    int[] idata = {pixel};
1144                    return idata;
1145                }
1146             default:
1147                throw new ClassCastException("This method has not been "+
1148                    "implemented for transferType " + transferType);
1149         }
1150     }
1151 
1152     /**
1153      * Forces the raster data to match the state specified in the
1154      * {@code isAlphaPremultiplied} variable, assuming the data is
1155      * currently correctly described by this {@code ColorModel}.  It
1156      * may multiply or divide the color raster data by alpha, or do
1157      * nothing if the data is in the correct state.  If the data needs to
1158      * be coerced, this method will also return an instance of this
1159      * {@code ColorModel} with the {@code isAlphaPremultiplied}
1160      * flag set appropriately.  This method will throw a
1161      * {@code UnsupportedOperationException} if this transferType is
1162      * not supported by this {@code ColorModel}.  Since
1163      * {@code ColorModel} can be subclassed, subclasses inherit the


1173      *            {@code transferType} is not supported by this
1174      *            color model
1175      */
1176     public final ColorModel coerceData (WritableRaster raster,
1177                                         boolean isAlphaPremultiplied)
1178     {
1179         if (!supportsAlpha ||
1180             this.isAlphaPremultiplied() == isAlphaPremultiplied) {
1181             return this;
1182         }
1183 
1184         int w = raster.getWidth();
1185         int h = raster.getHeight();
1186         int aIdx = numColorComponents;
1187         float normAlpha;
1188         float alphaScale = 1.0f / ((float) ((1 << nBits[aIdx]) - 1));
1189 
1190         int rminX = raster.getMinX();
1191         int rY = raster.getMinY();
1192         int rX;
1193         int[] pixel = null;
1194         int[] zpixel = null;
1195 
1196         if (isAlphaPremultiplied) {
1197             // Must mean that we are currently not premultiplied so
1198             // multiply by alpha
1199             switch (transferType) {
1200                 case DataBuffer.TYPE_BYTE: {
1201                     for (int y = 0; y < h; y++, rY++) {
1202                         rX = rminX;
1203                         for (int x = 0; x < w; x++, rX++) {
1204                             pixel = raster.getPixel(rX, rY, pixel);
1205                             normAlpha = pixel[aIdx] * alphaScale;
1206                             if (normAlpha != 0.f) {
1207                                 for (int c=0; c < aIdx; c++) {
1208                                     pixel[c] = (int) (pixel[c] * normAlpha +
1209                                                       0.5f);
1210                                 }
1211                                 raster.setPixel(rX, rY, pixel);
1212                             } else {
1213                                 if (zpixel == null) {
1214                                     zpixel = new int[numComponents];


< prev index next >