< prev index next >

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

Print this page


   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


 785         // an 8-bit value will be returned.
 786 
 787         // This method maps the input value corresponding to a
 788         // normalized ColorSpace component value of 0.0 to 0, and the
 789         // input value corresponding to a normalized ColorSpace
 790         // component value of 1.0 to 2^n - 1 (where n is 8 or 16), so
 791         // it is appropriate only for ColorSpaces with min/max component
 792         // values of 0.0/1.0.  This will be true for sRGB, the built-in
 793         // Linear RGB and Linear Gray spaces, and any other ICC grayscale
 794         // spaces for which we have precomputed LUTs.
 795 
 796         boolean needAlpha = (supportsAlpha && isAlphaPremultiplied);
 797         int alp = 0;
 798         int comp;
 799         int mask = (1 << nBits[idx]) - 1;
 800 
 801         switch (transferType) {
 802             // Note: we do no clamping of the pixel data here - we
 803             // assume that the data is scaled properly
 804             case DataBuffer.TYPE_SHORT: {
 805                 short sdata[] = (short[]) inData;
 806                 float scalefactor = (float) ((1 << precision) - 1);
 807                 if (needAlpha) {
 808                     short s = sdata[numColorComponents];
 809                     if (s != (short) 0) {
 810                         return (int) ((((float) sdata[idx]) /
 811                                        ((float) s)) * scalefactor + 0.5f);
 812                     } else {
 813                         return 0;
 814                     }
 815                 } else {
 816                     return (int) ((sdata[idx] / 32767.0f) * scalefactor + 0.5f);
 817                 }
 818             }
 819             case DataBuffer.TYPE_FLOAT: {
 820                 float fdata[] = (float[]) inData;
 821                 float scalefactor = (float) ((1 << precision) - 1);
 822                 if (needAlpha) {
 823                     float f = fdata[numColorComponents];
 824                     if (f != 0.0f) {
 825                         return (int) (((fdata[idx] / f) * scalefactor) + 0.5f);
 826                     } else {
 827                         return 0;
 828                     }
 829                 } else {
 830                     return (int) (fdata[idx] * scalefactor + 0.5f);
 831                 }
 832             }
 833             case DataBuffer.TYPE_DOUBLE: {
 834                 double ddata[] = (double[]) inData;
 835                 double scalefactor = (double) ((1 << precision) - 1);
 836                 if (needAlpha) {
 837                     double d = ddata[numColorComponents];
 838                     if (d != 0.0) {
 839                         return (int) (((ddata[idx] / d) * scalefactor) + 0.5);
 840                     } else {
 841                         return 0;
 842                     }
 843                 } else {
 844                     return (int) (ddata[idx] * scalefactor + 0.5);
 845                 }
 846             }
 847             case DataBuffer.TYPE_BYTE:
 848                byte bdata[] = (byte[])inData;
 849                comp = bdata[idx] & mask;
 850                precision = 8;
 851                if (needAlpha) {
 852                    alp = bdata[numColorComponents] & mask;
 853                }
 854             break;
 855             case DataBuffer.TYPE_USHORT:
 856                short usdata[] = (short[])inData;
 857                comp = usdata[idx] & mask;
 858                if (needAlpha) {
 859                    alp = usdata[numColorComponents] & mask;
 860                }
 861             break;
 862             case DataBuffer.TYPE_INT:
 863                int idata[] = (int[])inData;
 864                comp = idata[idx];
 865                if (needAlpha) {
 866                    alp = idata[numColorComponents];
 867                }
 868             break;
 869             default:
 870                throw new
 871                    UnsupportedOperationException("This method has not "+
 872                    "been implemented for transferType " + transferType);
 873         }
 874         if (needAlpha) {
 875             if (alp != 0) {
 876                 float scalefactor = (float) ((1 << precision) - 1);
 877                 float fcomp = ((float) comp) / ((float)mask);
 878                 float invalp = ((float) ((1<<nBits[numColorComponents]) - 1)) /
 879                                ((float) alp);
 880                 return (int) (fcomp * invalp * scalefactor + 0.5f);
 881             } else {
 882                 return 0;
 883             }


1037      * large enough to hold a pixel value for this
1038      * {@code ColorModel}.
1039      * @throws UnsupportedOperationException If the transfer type of
1040      * this {@code ComponentColorModel}
1041      * is not one of the supported transfer types:
1042      * {@code DataBuffer.TYPE_BYTE}, {@code DataBuffer.TYPE_USHORT},
1043      * {@code DataBuffer.TYPE_INT}, {@code DataBuffer.TYPE_SHORT},
1044      * {@code DataBuffer.TYPE_FLOAT}, or {@code DataBuffer.TYPE_DOUBLE}.
1045      */
1046     public int getAlpha(Object inData) {
1047         if (supportsAlpha == false) {
1048             return 255;
1049         }
1050 
1051         int alpha = 0;
1052         int aIdx = numColorComponents;
1053         int mask = (1 << nBits[aIdx]) - 1;
1054 
1055         switch (transferType) {
1056             case DataBuffer.TYPE_SHORT:
1057                 short sdata[] = (short[])inData;
1058                 alpha = (int) ((sdata[aIdx] / 32767.0f) * 255.0f + 0.5f);
1059                 return alpha;
1060             case DataBuffer.TYPE_FLOAT:
1061                 float fdata[] = (float[])inData;
1062                 alpha = (int) (fdata[aIdx] * 255.0f + 0.5f);
1063                 return alpha;
1064             case DataBuffer.TYPE_DOUBLE:
1065                 double ddata[] = (double[])inData;
1066                 alpha = (int) (ddata[aIdx] * 255.0 + 0.5);
1067                 return alpha;
1068             case DataBuffer.TYPE_BYTE:
1069                byte bdata[] = (byte[])inData;
1070                alpha = bdata[aIdx] & mask;
1071             break;
1072             case DataBuffer.TYPE_USHORT:
1073                short usdata[] = (short[])inData;
1074                alpha = usdata[aIdx] & mask;
1075             break;
1076             case DataBuffer.TYPE_INT:
1077                int idata[] = (int[])inData;
1078                alpha = idata[aIdx];
1079             break;
1080             default:
1081                throw new
1082                    UnsupportedOperationException("This method has not "+
1083                    "been implemented for transferType " + transferType);
1084         }
1085 
1086         if (nBits[aIdx] == 8) {
1087             return alpha;
1088         } else {
1089             return (int)
1090                 ((((float) alpha) / ((float) ((1 << nBits[aIdx]) - 1))) *
1091                  255.0f + 0.5f);
1092         }
1093     }
1094 
1095     /**
1096      * Returns the color/alpha components for the specified pixel in the
1097      * default RGB color model format.  A color conversion is done if


1184      * @see WritableRaster#setDataElements
1185      * @see SampleModel#setDataElements
1186      */
1187     public Object getDataElements(int rgb, Object pixel) {
1188         // REMIND: Use rendering hints?
1189 
1190         int red, grn, blu, alp;
1191         red = (rgb>>16) & 0xff;
1192         grn = (rgb>>8) & 0xff;
1193         blu = rgb & 0xff;
1194 
1195         if (needScaleInit) {
1196             initScale();
1197         }
1198         if (signed) {
1199             // Handle SHORT, FLOAT, & DOUBLE here
1200 
1201             switch(transferType) {
1202             case DataBuffer.TYPE_SHORT:
1203                 {
1204                     short sdata[];
1205                     if (pixel == null) {
1206                         sdata = new short[numComponents];
1207                     } else {
1208                         sdata = (short[])pixel;
1209                     }
1210                     float factor;
1211                     if (is_sRGB_stdScale || is_LinearRGB_stdScale) {
1212                         factor = 32767.0f / 255.0f;
1213                         if (is_LinearRGB_stdScale) {
1214                             red = fromsRGB8LUT16[red] & 0xffff;
1215                             grn = fromsRGB8LUT16[grn] & 0xffff;
1216                             blu = fromsRGB8LUT16[blu] & 0xffff;
1217                             factor = 32767.0f / 65535.0f;
1218                         }
1219                         if (supportsAlpha) {
1220                             alp = (rgb>>24) & 0xff;
1221                             sdata[3] =
1222                                 (short) (alp * (32767.0f / 255.0f) + 0.5f);
1223                             if (isAlphaPremultiplied) {
1224                                 factor = alp * factor * (1.0f / 255.0f);


1247                     } else if (is_ICCGray_stdScale) {
1248                         red = fromsRGB8LUT16[red] & 0xffff;
1249                         grn = fromsRGB8LUT16[grn] & 0xffff;
1250                         blu = fromsRGB8LUT16[blu] & 0xffff;
1251                         int gray = (int) ((0.2125f * red) +
1252                                           (0.7154f * grn) +
1253                                           (0.0721f * blu) + 0.5f);
1254                         gray = fromLinearGray16ToOtherGray16LUT[gray] & 0xffff;
1255                         factor = 32767.0f / 65535.0f;
1256                         if (supportsAlpha) {
1257                             alp = (rgb>>24) & 0xff;
1258                             sdata[1] =
1259                                 (short) (alp * (32767.0f / 255.0f) + 0.5f);
1260                             if (isAlphaPremultiplied) {
1261                                 factor = alp * factor * (1.0f / 255.0f);
1262                             }
1263                         }
1264                         sdata[0] = (short) (gray * factor + 0.5f);
1265                     } else {
1266                         factor = 1.0f / 255.0f;
1267                         float norm[] = new float[3];
1268                         norm[0] = red * factor;
1269                         norm[1] = grn * factor;
1270                         norm[2] = blu * factor;
1271                         norm = colorSpace.fromRGB(norm);
1272                         if (nonStdScale) {
1273                             for (int i = 0; i < numColorComponents; i++) {
1274                                 norm[i] = (norm[i] - compOffset[i]) *
1275                                           compScale[i];
1276                                 // REMIND: need to analyze whether this
1277                                 // clamping is necessary
1278                                 if (norm[i] < 0.0f) {
1279                                     norm[i] = 0.0f;
1280                                 }
1281                                 if (norm[i] > 1.0f) {
1282                                     norm[i] = 1.0f;
1283                                 }
1284                             }
1285                         }
1286                         factor = 32767.0f;
1287                         if (supportsAlpha) {
1288                             alp = (rgb>>24) & 0xff;
1289                             sdata[numColorComponents] =
1290                                 (short) (alp * (32767.0f / 255.0f) + 0.5f);
1291                             if (isAlphaPremultiplied) {
1292                                 factor *= alp * (1.0f / 255.0f);
1293                             }
1294                         }
1295                         for (int i = 0; i < numColorComponents; i++) {
1296                             sdata[i] = (short) (norm[i] * factor + 0.5f);
1297                         }
1298                     }
1299                     return sdata;
1300                 }
1301             case DataBuffer.TYPE_FLOAT:
1302                 {
1303                     float fdata[];
1304                     if (pixel == null) {
1305                         fdata = new float[numComponents];
1306                     } else {
1307                         fdata = (float[])pixel;
1308                     }
1309                     float factor;
1310                     if (is_sRGB_stdScale || is_LinearRGB_stdScale) {
1311                         if (is_LinearRGB_stdScale) {
1312                             red = fromsRGB8LUT16[red] & 0xffff;
1313                             grn = fromsRGB8LUT16[grn] & 0xffff;
1314                             blu = fromsRGB8LUT16[blu] & 0xffff;
1315                             factor = 1.0f / 65535.0f;
1316                         } else {
1317                             factor = 1.0f / 255.0f;
1318                         }
1319                         if (supportsAlpha) {
1320                             alp = (rgb>>24) & 0xff;
1321                             fdata[3] = alp * (1.0f / 255.0f);
1322                             if (isAlphaPremultiplied) {
1323                                 factor *= fdata[3];


1340                                 fdata[0] *= fdata[1];
1341                             }
1342                         }
1343                     } else if (is_ICCGray_stdScale) {
1344                         red = fromsRGB8LUT16[red] & 0xffff;
1345                         grn = fromsRGB8LUT16[grn] & 0xffff;
1346                         blu = fromsRGB8LUT16[blu] & 0xffff;
1347                         int gray = (int) ((0.2125f * red) +
1348                                           (0.7154f * grn) +
1349                                           (0.0721f * blu) + 0.5f);
1350                         fdata[0] = (fromLinearGray16ToOtherGray16LUT[gray] &
1351                                     0xffff) / 65535.0f;
1352                         if (supportsAlpha) {
1353                             alp = (rgb>>24) & 0xff;
1354                             fdata[1] = alp * (1.0f / 255.0f);
1355                             if (isAlphaPremultiplied) {
1356                                 fdata[0] *= fdata[1];
1357                             }
1358                         }
1359                     } else {
1360                         float norm[] = new float[3];
1361                         factor = 1.0f / 255.0f;
1362                         norm[0] = red * factor;
1363                         norm[1] = grn * factor;
1364                         norm[2] = blu * factor;
1365                         norm = colorSpace.fromRGB(norm);
1366                         if (supportsAlpha) {
1367                             alp = (rgb>>24) & 0xff;
1368                             fdata[numColorComponents] = alp * factor;
1369                             if (isAlphaPremultiplied) {
1370                                 factor *= alp;
1371                                 for (int i = 0; i < numColorComponents; i++) {
1372                                     norm[i] *= factor;
1373                                 }
1374                             }
1375                         }
1376                         for (int i = 0; i < numColorComponents; i++) {
1377                             fdata[i] = norm[i];
1378                         }
1379                     }
1380                     return fdata;
1381                 }
1382             case DataBuffer.TYPE_DOUBLE:
1383                 {
1384                     double ddata[];
1385                     if (pixel == null) {
1386                         ddata = new double[numComponents];
1387                     } else {
1388                         ddata = (double[])pixel;
1389                     }
1390                     if (is_sRGB_stdScale || is_LinearRGB_stdScale) {
1391                         double factor;
1392                         if (is_LinearRGB_stdScale) {
1393                             red = fromsRGB8LUT16[red] & 0xffff;
1394                             grn = fromsRGB8LUT16[grn] & 0xffff;
1395                             blu = fromsRGB8LUT16[blu] & 0xffff;
1396                             factor = 1.0 / 65535.0;
1397                         } else {
1398                             factor = 1.0 / 255.0;
1399                         }
1400                         if (supportsAlpha) {
1401                             alp = (rgb>>24) & 0xff;
1402                             ddata[3] = alp * (1.0 / 255.0);
1403                             if (isAlphaPremultiplied) {
1404                                 factor *= ddata[3];


1422                             }
1423                         }
1424                     } else if (is_ICCGray_stdScale) {
1425                         red = fromsRGB8LUT16[red] & 0xffff;
1426                         grn = fromsRGB8LUT16[grn] & 0xffff;
1427                         blu = fromsRGB8LUT16[blu] & 0xffff;
1428                         int gray = (int) ((0.2125f * red) +
1429                                           (0.7154f * grn) +
1430                                           (0.0721f * blu) + 0.5f);
1431                         ddata[0] = (fromLinearGray16ToOtherGray16LUT[gray] &
1432                                     0xffff) / 65535.0;
1433                         if (supportsAlpha) {
1434                             alp = (rgb>>24) & 0xff;
1435                             ddata[1] = alp * (1.0 / 255.0);
1436                             if (isAlphaPremultiplied) {
1437                                 ddata[0] *= ddata[1];
1438                             }
1439                         }
1440                     } else {
1441                         float factor = 1.0f / 255.0f;
1442                         float norm[] = new float[3];
1443                         norm[0] = red * factor;
1444                         norm[1] = grn * factor;
1445                         norm[2] = blu * factor;
1446                         norm = colorSpace.fromRGB(norm);
1447                         if (supportsAlpha) {
1448                             alp = (rgb>>24) & 0xff;
1449                             ddata[numColorComponents] = alp * (1.0 / 255.0);
1450                             if (isAlphaPremultiplied) {
1451                                 factor *= alp;
1452                                 for (int i = 0; i < numColorComponents; i++) {
1453                                     norm[i] *= factor;
1454                                 }
1455                             }
1456                         }
1457                         for (int i = 0; i < numColorComponents; i++) {
1458                             ddata[i] = norm[i];
1459                         }
1460                     }
1461                     return ddata;
1462                 }
1463             }
1464         }
1465 
1466         // Handle BYTE, USHORT, & INT here
1467         //REMIND: maybe more efficient not to use int array for
1468         //DataBuffer.TYPE_USHORT and DataBuffer.TYPE_INT
1469         int intpixel[];
1470         if (transferType == DataBuffer.TYPE_INT &&
1471             pixel != null) {
1472            intpixel = (int[])pixel;
1473         } else {
1474             intpixel = new int[numComponents];
1475         }
1476 
1477         if (is_sRGB_stdScale || is_LinearRGB_stdScale) {
1478             int precision;
1479             float factor;
1480             if (is_LinearRGB_stdScale) {
1481                 if (transferType == DataBuffer.TYPE_BYTE) {
1482                     red = fromsRGB8LUT8[red] & 0xff;
1483                     grn = fromsRGB8LUT8[grn] & 0xff;
1484                     blu = fromsRGB8LUT8[blu] & 0xff;
1485                     precision = 8;
1486                     factor = 1.0f / 255.0f;
1487                 } else {
1488                     red = fromsRGB8LUT16[red] & 0xffff;
1489                     grn = fromsRGB8LUT16[grn] & 0xffff;


1598                 }
1599                 else {
1600                     intpixel[numColorComponents] =
1601                         (int) (alp * factor *
1602                                ((1<<nBits[numColorComponents]) - 1) + 0.5f);
1603                 }
1604                 if (isAlphaPremultiplied) {
1605                     factor *= alp;
1606                     for (int i = 0; i < numColorComponents; i++) {
1607                         norm[i] *= factor;
1608                     }
1609                 }
1610             }
1611             for (int i = 0; i < numColorComponents; i++) {
1612                 intpixel[i] = (int) (norm[i] * ((1<<nBits[i]) - 1) + 0.5f);
1613             }
1614         }
1615 
1616         switch (transferType) {
1617             case DataBuffer.TYPE_BYTE: {
1618                byte bdata[];
1619                if (pixel == null) {
1620                    bdata = new byte[numComponents];
1621                } else {
1622                    bdata = (byte[])pixel;
1623                }
1624                for (int i = 0; i < numComponents; i++) {
1625                    bdata[i] = (byte)(0xff&intpixel[i]);
1626                }
1627                return bdata;
1628             }
1629             case DataBuffer.TYPE_USHORT:{
1630                short sdata[];
1631                if (pixel == null) {
1632                    sdata = new short[numComponents];
1633                } else {
1634                    sdata = (short[])pixel;
1635                }
1636                for (int i = 0; i < numComponents; i++) {
1637                    sdata[i] = (short)(intpixel[i]&0xffff);
1638                }
1639                return sdata;
1640             }
1641             case DataBuffer.TYPE_INT:
1642                 if (maxBits > 23) {
1643                     // fix 4412670 - for components of 24 or more bits
1644                     // some calculations done above with float precision
1645                     // may lose enough precision that the integer result
1646                     // overflows nBits, so we need to clamp.
1647                     for (int i = 0; i < numComponents; i++) {
1648                         if (intpixel[i] > ((1<<nBits[i]) - 1)) {
1649                             intpixel[i] = (1<<nBits[i]) - 1;
1650                         }


1724      * a new array is allocated.
1725      * @param offset An offset into the {@code components} array.
1726      *
1727      * @return The {@code components} array.
1728      *
1729      * @throws IllegalArgumentException If this
1730      * {@code ComponentColorModel} does not support the unnormalized form
1731      * @throws UnsupportedOperationException in some cases iff the
1732      * transfer type of this {@code ComponentColorModel}
1733      * is not one of the following transfer types:
1734      * {@code DataBuffer.TYPE_BYTE}, {@code DataBuffer.TYPE_USHORT},
1735      * or {@code DataBuffer.TYPE_INT}.
1736      * @throws ClassCastException If {@code pixel} is not a primitive
1737      * array of type {@code transferType}.
1738      * @throws IllegalArgumentException If the {@code components} array is
1739      * not null and is not large enough to hold all the color and alpha
1740      * components (starting at offset), or if {@code pixel} is not large
1741      * enough to hold a pixel value for this ColorModel.
1742      */
1743     public int[] getComponents(Object pixel, int[] components, int offset) {
1744         int intpixel[];
1745         if (needScaleInit) {
1746             initScale();
1747         }
1748         if (noUnnorm) {
1749             throw new
1750                 IllegalArgumentException(
1751                     "This ColorModel does not support the unnormalized form");
1752         }
1753         if (pixel instanceof int[]) {
1754             intpixel = (int[])pixel;
1755         } else {
1756             intpixel = DataBuffer.toIntArray(pixel);
1757             if (intpixel == null) {
1758                throw new UnsupportedOperationException("This method has not been "+
1759                    "implemented for transferType " + transferType);
1760             }
1761         }
1762         if (intpixel.length < numComponents) {
1763             throw new IllegalArgumentException
1764                 ("Length of pixel array < number of components in model");


2040      *  hold all of the color and alpha components starting at
2041      *  {@code normOffset}
2042      * @since 1.4
2043      */
2044     public int getDataElement(float[] normComponents, int normOffset) {
2045         if (numComponents > 1) {
2046             throw new
2047                 IllegalArgumentException("More than one component per pixel");
2048         }
2049         if (signed) {
2050             throw new
2051                 IllegalArgumentException("Component value is signed");
2052         }
2053         if (needScaleInit) {
2054             initScale();
2055         }
2056         Object pixel = getDataElements(normComponents, normOffset, null);
2057         switch (transferType) {
2058         case DataBuffer.TYPE_BYTE:
2059             {
2060                 byte bpixel[] = (byte[]) pixel;
2061                 return bpixel[0] & 0xff;
2062             }
2063         case DataBuffer.TYPE_USHORT:
2064             {
2065                 short[] uspixel = (short[]) pixel;
2066                 return uspixel[0] & 0xffff;
2067             }
2068         case DataBuffer.TYPE_INT:
2069             {
2070                 int[] ipixel = (int[]) pixel;
2071                 return ipixel[0];
2072             }
2073         default:
2074             throw new UnsupportedOperationException("This method has not been "
2075                 + "implemented for transferType " + transferType);
2076         }
2077     }
2078 
2079     /**
2080      * Returns a data element array representation of a pixel in this


2451      */
2452     public ColorModel coerceData (WritableRaster raster,
2453                                   boolean isAlphaPremultiplied) {
2454         if ((supportsAlpha == false) ||
2455             (this.isAlphaPremultiplied == isAlphaPremultiplied))
2456         {
2457             // Nothing to do
2458             return this;
2459         }
2460 
2461         int w = raster.getWidth();
2462         int h = raster.getHeight();
2463         int aIdx = raster.getNumBands() - 1;
2464         float normAlpha;
2465         int rminX = raster.getMinX();
2466         int rY = raster.getMinY();
2467         int rX;
2468         if (isAlphaPremultiplied) {
2469             switch (transferType) {
2470                 case DataBuffer.TYPE_BYTE: {
2471                     byte pixel[] = null;
2472                     byte zpixel[] = null;
2473                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2474                     for (int y = 0; y < h; y++, rY++) {
2475                         rX = rminX;
2476                         for (int x = 0; x < w; x++, rX++) {
2477                             pixel = (byte[])raster.getDataElements(rX, rY,
2478                                                                    pixel);
2479                             normAlpha = (pixel[aIdx] & 0xff) * alphaScale;
2480                             if (normAlpha != 0.0f) {
2481                                 for (int c=0; c < aIdx; c++) {
2482                                     pixel[c] = (byte)((pixel[c] & 0xff) *
2483                                                       normAlpha + 0.5f);
2484                                 }
2485                                 raster.setDataElements(rX, rY, pixel);
2486                             } else {
2487                                 if (zpixel == null) {
2488                                     zpixel = new byte[numComponents];
2489                                     java.util.Arrays.fill(zpixel, (byte) 0);
2490                                 }
2491                                 raster.setDataElements(rX, rY, zpixel);
2492                             }
2493                         }
2494                     }
2495                 }
2496                 break;
2497                 case DataBuffer.TYPE_USHORT: {
2498                     short pixel[] = null;
2499                     short zpixel[] = null;
2500                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2501                     for (int y = 0; y < h; y++, rY++) {
2502                         rX = rminX;
2503                         for (int x = 0; x < w; x++, rX++) {
2504                             pixel = (short[])raster.getDataElements(rX, rY,
2505                                                                     pixel);
2506                             normAlpha = (pixel[aIdx] & 0xffff) * alphaScale;
2507                             if (normAlpha != 0.0f) {
2508                                 for (int c=0; c < aIdx; c++) {
2509                                     pixel[c] = (short)
2510                                         ((pixel[c] & 0xffff) * normAlpha +
2511                                          0.5f);
2512                                 }
2513                                 raster.setDataElements(rX, rY, pixel);
2514                             } else {
2515                                 if (zpixel == null) {
2516                                     zpixel = new short[numComponents];
2517                                     java.util.Arrays.fill(zpixel, (short) 0);
2518                                 }
2519                                 raster.setDataElements(rX, rY, zpixel);
2520                             }
2521                         }
2522                     }
2523                 }
2524                 break;
2525                 case DataBuffer.TYPE_INT: {
2526                     int pixel[] = null;
2527                     int zpixel[] = null;
2528                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2529                     for (int y = 0; y < h; y++, rY++) {
2530                         rX = rminX;
2531                         for (int x = 0; x < w; x++, rX++) {
2532                             pixel = (int[])raster.getDataElements(rX, rY,
2533                                                                   pixel);
2534                             normAlpha = pixel[aIdx] * alphaScale;
2535                             if (normAlpha != 0.0f) {
2536                                 for (int c=0; c < aIdx; c++) {
2537                                     pixel[c] = (int) (pixel[c] * normAlpha +
2538                                                       0.5f);
2539                                 }
2540                                 raster.setDataElements(rX, rY, pixel);
2541                             } else {
2542                                 if (zpixel == null) {
2543                                     zpixel = new int[numComponents];
2544                                     java.util.Arrays.fill(zpixel, 0);
2545                                 }
2546                                 raster.setDataElements(rX, rY, zpixel);
2547                             }
2548                         }
2549                     }
2550                 }
2551                 break;
2552                 case DataBuffer.TYPE_SHORT: {
2553                     short pixel[] = null;
2554                     short zpixel[] = null;
2555                     float alphaScale = 1.0f / 32767.0f;
2556                     for (int y = 0; y < h; y++, rY++) {
2557                         rX = rminX;
2558                         for (int x = 0; x < w; x++, rX++) {
2559                             pixel = (short[]) raster.getDataElements(rX, rY,
2560                                                                      pixel);
2561                             normAlpha = pixel[aIdx] * alphaScale;
2562                             if (normAlpha != 0.0f) {
2563                                 for (int c=0; c < aIdx; c++) {
2564                                     pixel[c] = (short) (pixel[c] * normAlpha +
2565                                                         0.5f);
2566                                 }
2567                                 raster.setDataElements(rX, rY, pixel);
2568                             } else {
2569                                 if (zpixel == null) {
2570                                     zpixel = new short[numComponents];
2571                                     java.util.Arrays.fill(zpixel, (short) 0);
2572                                 }
2573                                 raster.setDataElements(rX, rY, zpixel);
2574                             }
2575                         }
2576                     }
2577                 }
2578                 break;
2579                 case DataBuffer.TYPE_FLOAT: {
2580                     float pixel[] = null;
2581                     float zpixel[] = null;
2582                     for (int y = 0; y < h; y++, rY++) {
2583                         rX = rminX;
2584                         for (int x = 0; x < w; x++, rX++) {
2585                             pixel = (float[]) raster.getDataElements(rX, rY,
2586                                                                      pixel);
2587                             normAlpha = pixel[aIdx];
2588                             if (normAlpha != 0.0f) {
2589                                 for (int c=0; c < aIdx; c++) {
2590                                     pixel[c] *= normAlpha;
2591                                 }
2592                                 raster.setDataElements(rX, rY, pixel);
2593                             } else {
2594                                 if (zpixel == null) {
2595                                     zpixel = new float[numComponents];
2596                                     java.util.Arrays.fill(zpixel, 0.0f);
2597                                 }
2598                                 raster.setDataElements(rX, rY, zpixel);
2599                             }
2600                         }
2601                     }
2602                 }
2603                 break;
2604                 case DataBuffer.TYPE_DOUBLE: {
2605                     double pixel[] = null;
2606                     double zpixel[] = null;
2607                     for (int y = 0; y < h; y++, rY++) {
2608                         rX = rminX;
2609                         for (int x = 0; x < w; x++, rX++) {
2610                             pixel = (double[]) raster.getDataElements(rX, rY,
2611                                                                       pixel);
2612                             double dnormAlpha = pixel[aIdx];
2613                             if (dnormAlpha != 0.0) {
2614                                 for (int c=0; c < aIdx; c++) {
2615                                     pixel[c] *= dnormAlpha;
2616                                 }
2617                                 raster.setDataElements(rX, rY, pixel);
2618                             } else {
2619                                 if (zpixel == null) {
2620                                     zpixel = new double[numComponents];
2621                                     java.util.Arrays.fill(zpixel, 0.0);
2622                                 }
2623                                 raster.setDataElements(rX, rY, zpixel);
2624                             }
2625                         }
2626                     }
2627                 }
2628                 break;
2629                 default:
2630                     throw new UnsupportedOperationException("This method has not been "+
2631                          "implemented for transferType " + transferType);
2632             }
2633         }
2634         else {
2635             // We are premultiplied and want to divide it out
2636             switch (transferType) {
2637                 case DataBuffer.TYPE_BYTE: {
2638                     byte pixel[] = null;
2639                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2640                     for (int y = 0; y < h; y++, rY++) {
2641                         rX = rminX;
2642                         for (int x = 0; x < w; x++, rX++) {
2643                             pixel = (byte[])raster.getDataElements(rX, rY,
2644                                                                    pixel);
2645                             normAlpha = (pixel[aIdx] & 0xff) * alphaScale;
2646                             if (normAlpha != 0.0f) {
2647                                 float invAlpha = 1.0f / normAlpha;
2648                                 for (int c=0; c < aIdx; c++) {
2649                                     pixel[c] = (byte)
2650                                         ((pixel[c] & 0xff) * invAlpha + 0.5f);
2651                                 }
2652                                 raster.setDataElements(rX, rY, pixel);
2653                             }
2654                         }
2655                     }
2656                 }
2657                 break;
2658                 case DataBuffer.TYPE_USHORT: {
2659                     short pixel[] = null;
2660                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2661                     for (int y = 0; y < h; y++, rY++) {
2662                         rX = rminX;
2663                         for (int x = 0; x < w; x++, rX++) {
2664                             pixel = (short[])raster.getDataElements(rX, rY,
2665                                                                     pixel);
2666                             normAlpha = (pixel[aIdx] & 0xffff) * alphaScale;
2667                             if (normAlpha != 0.0f) {
2668                                 float invAlpha = 1.0f / normAlpha;
2669                                 for (int c=0; c < aIdx; c++) {
2670                                     pixel[c] = (short)
2671                                         ((pixel[c] & 0xffff) * invAlpha + 0.5f);
2672                                 }
2673                                 raster.setDataElements(rX, rY, pixel);
2674                             }
2675                         }
2676                     }
2677                 }
2678                 break;
2679                 case DataBuffer.TYPE_INT: {
2680                     int pixel[] = null;
2681                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2682                     for (int y = 0; y < h; y++, rY++) {
2683                         rX = rminX;
2684                         for (int x = 0; x < w; x++, rX++) {
2685                             pixel = (int[])raster.getDataElements(rX, rY,
2686                                                                   pixel);
2687                             normAlpha = pixel[aIdx] * alphaScale;
2688                             if (normAlpha != 0.0f) {
2689                                 float invAlpha = 1.0f / normAlpha;
2690                                 for (int c=0; c < aIdx; c++) {
2691                                     pixel[c] = (int)
2692                                         (pixel[c] * invAlpha + 0.5f);
2693                                 }
2694                                 raster.setDataElements(rX, rY, pixel);
2695                             }
2696                         }
2697                     }
2698                 }
2699                 break;
2700                 case DataBuffer.TYPE_SHORT: {
2701                     short pixel[] = null;
2702                     float alphaScale = 1.0f / 32767.0f;
2703                     for (int y = 0; y < h; y++, rY++) {
2704                         rX = rminX;
2705                         for (int x = 0; x < w; x++, rX++) {
2706                             pixel = (short[])raster.getDataElements(rX, rY,
2707                                                                     pixel);
2708                             normAlpha = pixel[aIdx] * alphaScale;
2709                             if (normAlpha != 0.0f) {
2710                                 float invAlpha = 1.0f / normAlpha;
2711                                 for (int c=0; c < aIdx; c++) {
2712                                     pixel[c] = (short)
2713                                         (pixel[c] * invAlpha + 0.5f);
2714                                 }
2715                                 raster.setDataElements(rX, rY, pixel);
2716                             }
2717                         }
2718                     }
2719                 }
2720                 break;
2721                 case DataBuffer.TYPE_FLOAT: {
2722                     float pixel[] = null;
2723                     for (int y = 0; y < h; y++, rY++) {
2724                         rX = rminX;
2725                         for (int x = 0; x < w; x++, rX++) {
2726                             pixel = (float[])raster.getDataElements(rX, rY,
2727                                                                     pixel);
2728                             normAlpha = pixel[aIdx];
2729                             if (normAlpha != 0.0f) {
2730                                 float invAlpha = 1.0f / normAlpha;
2731                                 for (int c=0; c < aIdx; c++) {
2732                                     pixel[c] *= invAlpha;
2733                                 }
2734                                 raster.setDataElements(rX, rY, pixel);
2735                             }
2736                         }
2737                     }
2738                 }
2739                 break;
2740                 case DataBuffer.TYPE_DOUBLE: {
2741                     double pixel[] = null;
2742                     for (int y = 0; y < h; y++, rY++) {
2743                         rX = rminX;
2744                         for (int x = 0; x < w; x++, rX++) {
2745                             pixel = (double[])raster.getDataElements(rX, rY,
2746                                                                      pixel);
2747                             double dnormAlpha = pixel[aIdx];
2748                             if (dnormAlpha != 0.0) {
2749                                 double invAlpha = 1.0 / dnormAlpha;
2750                                 for (int c=0; c < aIdx; c++) {
2751                                     pixel[c] *= invAlpha;
2752                                 }
2753                                 raster.setDataElements(rX, rY, pixel);
2754                             }
2755                         }
2756                     }
2757                 }
2758                 break;
2759                 default:
2760                     throw new UnsupportedOperationException("This method has not been "+
2761                          "implemented for transferType " + transferType);


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


 785         // an 8-bit value will be returned.
 786 
 787         // This method maps the input value corresponding to a
 788         // normalized ColorSpace component value of 0.0 to 0, and the
 789         // input value corresponding to a normalized ColorSpace
 790         // component value of 1.0 to 2^n - 1 (where n is 8 or 16), so
 791         // it is appropriate only for ColorSpaces with min/max component
 792         // values of 0.0/1.0.  This will be true for sRGB, the built-in
 793         // Linear RGB and Linear Gray spaces, and any other ICC grayscale
 794         // spaces for which we have precomputed LUTs.
 795 
 796         boolean needAlpha = (supportsAlpha && isAlphaPremultiplied);
 797         int alp = 0;
 798         int comp;
 799         int mask = (1 << nBits[idx]) - 1;
 800 
 801         switch (transferType) {
 802             // Note: we do no clamping of the pixel data here - we
 803             // assume that the data is scaled properly
 804             case DataBuffer.TYPE_SHORT: {
 805                 short[] sdata = (short[]) inData;
 806                 float scalefactor = (float) ((1 << precision) - 1);
 807                 if (needAlpha) {
 808                     short s = sdata[numColorComponents];
 809                     if (s != (short) 0) {
 810                         return (int) ((((float) sdata[idx]) /
 811                                        ((float) s)) * scalefactor + 0.5f);
 812                     } else {
 813                         return 0;
 814                     }
 815                 } else {
 816                     return (int) ((sdata[idx] / 32767.0f) * scalefactor + 0.5f);
 817                 }
 818             }
 819             case DataBuffer.TYPE_FLOAT: {
 820                 float[] fdata = (float[]) inData;
 821                 float scalefactor = (float) ((1 << precision) - 1);
 822                 if (needAlpha) {
 823                     float f = fdata[numColorComponents];
 824                     if (f != 0.0f) {
 825                         return (int) (((fdata[idx] / f) * scalefactor) + 0.5f);
 826                     } else {
 827                         return 0;
 828                     }
 829                 } else {
 830                     return (int) (fdata[idx] * scalefactor + 0.5f);
 831                 }
 832             }
 833             case DataBuffer.TYPE_DOUBLE: {
 834                 double[] ddata = (double[]) inData;
 835                 double scalefactor = (double) ((1 << precision) - 1);
 836                 if (needAlpha) {
 837                     double d = ddata[numColorComponents];
 838                     if (d != 0.0) {
 839                         return (int) (((ddata[idx] / d) * scalefactor) + 0.5);
 840                     } else {
 841                         return 0;
 842                     }
 843                 } else {
 844                     return (int) (ddata[idx] * scalefactor + 0.5);
 845                 }
 846             }
 847             case DataBuffer.TYPE_BYTE:
 848                byte[] bdata = (byte[])inData;
 849                comp = bdata[idx] & mask;
 850                precision = 8;
 851                if (needAlpha) {
 852                    alp = bdata[numColorComponents] & mask;
 853                }
 854             break;
 855             case DataBuffer.TYPE_USHORT:
 856                short[] usdata = (short[])inData;
 857                comp = usdata[idx] & mask;
 858                if (needAlpha) {
 859                    alp = usdata[numColorComponents] & mask;
 860                }
 861             break;
 862             case DataBuffer.TYPE_INT:
 863                int[] idata = (int[])inData;
 864                comp = idata[idx];
 865                if (needAlpha) {
 866                    alp = idata[numColorComponents];
 867                }
 868             break;
 869             default:
 870                throw new
 871                    UnsupportedOperationException("This method has not "+
 872                    "been implemented for transferType " + transferType);
 873         }
 874         if (needAlpha) {
 875             if (alp != 0) {
 876                 float scalefactor = (float) ((1 << precision) - 1);
 877                 float fcomp = ((float) comp) / ((float)mask);
 878                 float invalp = ((float) ((1<<nBits[numColorComponents]) - 1)) /
 879                                ((float) alp);
 880                 return (int) (fcomp * invalp * scalefactor + 0.5f);
 881             } else {
 882                 return 0;
 883             }


1037      * large enough to hold a pixel value for this
1038      * {@code ColorModel}.
1039      * @throws UnsupportedOperationException If the transfer type of
1040      * this {@code ComponentColorModel}
1041      * is not one of the supported transfer types:
1042      * {@code DataBuffer.TYPE_BYTE}, {@code DataBuffer.TYPE_USHORT},
1043      * {@code DataBuffer.TYPE_INT}, {@code DataBuffer.TYPE_SHORT},
1044      * {@code DataBuffer.TYPE_FLOAT}, or {@code DataBuffer.TYPE_DOUBLE}.
1045      */
1046     public int getAlpha(Object inData) {
1047         if (supportsAlpha == false) {
1048             return 255;
1049         }
1050 
1051         int alpha = 0;
1052         int aIdx = numColorComponents;
1053         int mask = (1 << nBits[aIdx]) - 1;
1054 
1055         switch (transferType) {
1056             case DataBuffer.TYPE_SHORT:
1057                 short[] sdata = (short[])inData;
1058                 alpha = (int) ((sdata[aIdx] / 32767.0f) * 255.0f + 0.5f);
1059                 return alpha;
1060             case DataBuffer.TYPE_FLOAT:
1061                 float[] fdata = (float[])inData;
1062                 alpha = (int) (fdata[aIdx] * 255.0f + 0.5f);
1063                 return alpha;
1064             case DataBuffer.TYPE_DOUBLE:
1065                 double[] ddata = (double[])inData;
1066                 alpha = (int) (ddata[aIdx] * 255.0 + 0.5);
1067                 return alpha;
1068             case DataBuffer.TYPE_BYTE:
1069                byte[] bdata = (byte[])inData;
1070                alpha = bdata[aIdx] & mask;
1071             break;
1072             case DataBuffer.TYPE_USHORT:
1073                short[] usdata = (short[])inData;
1074                alpha = usdata[aIdx] & mask;
1075             break;
1076             case DataBuffer.TYPE_INT:
1077                int[] idata = (int[])inData;
1078                alpha = idata[aIdx];
1079             break;
1080             default:
1081                throw new
1082                    UnsupportedOperationException("This method has not "+
1083                    "been implemented for transferType " + transferType);
1084         }
1085 
1086         if (nBits[aIdx] == 8) {
1087             return alpha;
1088         } else {
1089             return (int)
1090                 ((((float) alpha) / ((float) ((1 << nBits[aIdx]) - 1))) *
1091                  255.0f + 0.5f);
1092         }
1093     }
1094 
1095     /**
1096      * Returns the color/alpha components for the specified pixel in the
1097      * default RGB color model format.  A color conversion is done if


1184      * @see WritableRaster#setDataElements
1185      * @see SampleModel#setDataElements
1186      */
1187     public Object getDataElements(int rgb, Object pixel) {
1188         // REMIND: Use rendering hints?
1189 
1190         int red, grn, blu, alp;
1191         red = (rgb>>16) & 0xff;
1192         grn = (rgb>>8) & 0xff;
1193         blu = rgb & 0xff;
1194 
1195         if (needScaleInit) {
1196             initScale();
1197         }
1198         if (signed) {
1199             // Handle SHORT, FLOAT, & DOUBLE here
1200 
1201             switch(transferType) {
1202             case DataBuffer.TYPE_SHORT:
1203                 {
1204                     short[] sdata;
1205                     if (pixel == null) {
1206                         sdata = new short[numComponents];
1207                     } else {
1208                         sdata = (short[])pixel;
1209                     }
1210                     float factor;
1211                     if (is_sRGB_stdScale || is_LinearRGB_stdScale) {
1212                         factor = 32767.0f / 255.0f;
1213                         if (is_LinearRGB_stdScale) {
1214                             red = fromsRGB8LUT16[red] & 0xffff;
1215                             grn = fromsRGB8LUT16[grn] & 0xffff;
1216                             blu = fromsRGB8LUT16[blu] & 0xffff;
1217                             factor = 32767.0f / 65535.0f;
1218                         }
1219                         if (supportsAlpha) {
1220                             alp = (rgb>>24) & 0xff;
1221                             sdata[3] =
1222                                 (short) (alp * (32767.0f / 255.0f) + 0.5f);
1223                             if (isAlphaPremultiplied) {
1224                                 factor = alp * factor * (1.0f / 255.0f);


1247                     } else if (is_ICCGray_stdScale) {
1248                         red = fromsRGB8LUT16[red] & 0xffff;
1249                         grn = fromsRGB8LUT16[grn] & 0xffff;
1250                         blu = fromsRGB8LUT16[blu] & 0xffff;
1251                         int gray = (int) ((0.2125f * red) +
1252                                           (0.7154f * grn) +
1253                                           (0.0721f * blu) + 0.5f);
1254                         gray = fromLinearGray16ToOtherGray16LUT[gray] & 0xffff;
1255                         factor = 32767.0f / 65535.0f;
1256                         if (supportsAlpha) {
1257                             alp = (rgb>>24) & 0xff;
1258                             sdata[1] =
1259                                 (short) (alp * (32767.0f / 255.0f) + 0.5f);
1260                             if (isAlphaPremultiplied) {
1261                                 factor = alp * factor * (1.0f / 255.0f);
1262                             }
1263                         }
1264                         sdata[0] = (short) (gray * factor + 0.5f);
1265                     } else {
1266                         factor = 1.0f / 255.0f;
1267                         float[] norm = new float[3];
1268                         norm[0] = red * factor;
1269                         norm[1] = grn * factor;
1270                         norm[2] = blu * factor;
1271                         norm = colorSpace.fromRGB(norm);
1272                         if (nonStdScale) {
1273                             for (int i = 0; i < numColorComponents; i++) {
1274                                 norm[i] = (norm[i] - compOffset[i]) *
1275                                           compScale[i];
1276                                 // REMIND: need to analyze whether this
1277                                 // clamping is necessary
1278                                 if (norm[i] < 0.0f) {
1279                                     norm[i] = 0.0f;
1280                                 }
1281                                 if (norm[i] > 1.0f) {
1282                                     norm[i] = 1.0f;
1283                                 }
1284                             }
1285                         }
1286                         factor = 32767.0f;
1287                         if (supportsAlpha) {
1288                             alp = (rgb>>24) & 0xff;
1289                             sdata[numColorComponents] =
1290                                 (short) (alp * (32767.0f / 255.0f) + 0.5f);
1291                             if (isAlphaPremultiplied) {
1292                                 factor *= alp * (1.0f / 255.0f);
1293                             }
1294                         }
1295                         for (int i = 0; i < numColorComponents; i++) {
1296                             sdata[i] = (short) (norm[i] * factor + 0.5f);
1297                         }
1298                     }
1299                     return sdata;
1300                 }
1301             case DataBuffer.TYPE_FLOAT:
1302                 {
1303                     float[] fdata;
1304                     if (pixel == null) {
1305                         fdata = new float[numComponents];
1306                     } else {
1307                         fdata = (float[])pixel;
1308                     }
1309                     float factor;
1310                     if (is_sRGB_stdScale || is_LinearRGB_stdScale) {
1311                         if (is_LinearRGB_stdScale) {
1312                             red = fromsRGB8LUT16[red] & 0xffff;
1313                             grn = fromsRGB8LUT16[grn] & 0xffff;
1314                             blu = fromsRGB8LUT16[blu] & 0xffff;
1315                             factor = 1.0f / 65535.0f;
1316                         } else {
1317                             factor = 1.0f / 255.0f;
1318                         }
1319                         if (supportsAlpha) {
1320                             alp = (rgb>>24) & 0xff;
1321                             fdata[3] = alp * (1.0f / 255.0f);
1322                             if (isAlphaPremultiplied) {
1323                                 factor *= fdata[3];


1340                                 fdata[0] *= fdata[1];
1341                             }
1342                         }
1343                     } else if (is_ICCGray_stdScale) {
1344                         red = fromsRGB8LUT16[red] & 0xffff;
1345                         grn = fromsRGB8LUT16[grn] & 0xffff;
1346                         blu = fromsRGB8LUT16[blu] & 0xffff;
1347                         int gray = (int) ((0.2125f * red) +
1348                                           (0.7154f * grn) +
1349                                           (0.0721f * blu) + 0.5f);
1350                         fdata[0] = (fromLinearGray16ToOtherGray16LUT[gray] &
1351                                     0xffff) / 65535.0f;
1352                         if (supportsAlpha) {
1353                             alp = (rgb>>24) & 0xff;
1354                             fdata[1] = alp * (1.0f / 255.0f);
1355                             if (isAlphaPremultiplied) {
1356                                 fdata[0] *= fdata[1];
1357                             }
1358                         }
1359                     } else {
1360                         float[] norm = new float[3];
1361                         factor = 1.0f / 255.0f;
1362                         norm[0] = red * factor;
1363                         norm[1] = grn * factor;
1364                         norm[2] = blu * factor;
1365                         norm = colorSpace.fromRGB(norm);
1366                         if (supportsAlpha) {
1367                             alp = (rgb>>24) & 0xff;
1368                             fdata[numColorComponents] = alp * factor;
1369                             if (isAlphaPremultiplied) {
1370                                 factor *= alp;
1371                                 for (int i = 0; i < numColorComponents; i++) {
1372                                     norm[i] *= factor;
1373                                 }
1374                             }
1375                         }
1376                         for (int i = 0; i < numColorComponents; i++) {
1377                             fdata[i] = norm[i];
1378                         }
1379                     }
1380                     return fdata;
1381                 }
1382             case DataBuffer.TYPE_DOUBLE:
1383                 {
1384                     double[] ddata;
1385                     if (pixel == null) {
1386                         ddata = new double[numComponents];
1387                     } else {
1388                         ddata = (double[])pixel;
1389                     }
1390                     if (is_sRGB_stdScale || is_LinearRGB_stdScale) {
1391                         double factor;
1392                         if (is_LinearRGB_stdScale) {
1393                             red = fromsRGB8LUT16[red] & 0xffff;
1394                             grn = fromsRGB8LUT16[grn] & 0xffff;
1395                             blu = fromsRGB8LUT16[blu] & 0xffff;
1396                             factor = 1.0 / 65535.0;
1397                         } else {
1398                             factor = 1.0 / 255.0;
1399                         }
1400                         if (supportsAlpha) {
1401                             alp = (rgb>>24) & 0xff;
1402                             ddata[3] = alp * (1.0 / 255.0);
1403                             if (isAlphaPremultiplied) {
1404                                 factor *= ddata[3];


1422                             }
1423                         }
1424                     } else if (is_ICCGray_stdScale) {
1425                         red = fromsRGB8LUT16[red] & 0xffff;
1426                         grn = fromsRGB8LUT16[grn] & 0xffff;
1427                         blu = fromsRGB8LUT16[blu] & 0xffff;
1428                         int gray = (int) ((0.2125f * red) +
1429                                           (0.7154f * grn) +
1430                                           (0.0721f * blu) + 0.5f);
1431                         ddata[0] = (fromLinearGray16ToOtherGray16LUT[gray] &
1432                                     0xffff) / 65535.0;
1433                         if (supportsAlpha) {
1434                             alp = (rgb>>24) & 0xff;
1435                             ddata[1] = alp * (1.0 / 255.0);
1436                             if (isAlphaPremultiplied) {
1437                                 ddata[0] *= ddata[1];
1438                             }
1439                         }
1440                     } else {
1441                         float factor = 1.0f / 255.0f;
1442                         float[] norm = new float[3];
1443                         norm[0] = red * factor;
1444                         norm[1] = grn * factor;
1445                         norm[2] = blu * factor;
1446                         norm = colorSpace.fromRGB(norm);
1447                         if (supportsAlpha) {
1448                             alp = (rgb>>24) & 0xff;
1449                             ddata[numColorComponents] = alp * (1.0 / 255.0);
1450                             if (isAlphaPremultiplied) {
1451                                 factor *= alp;
1452                                 for (int i = 0; i < numColorComponents; i++) {
1453                                     norm[i] *= factor;
1454                                 }
1455                             }
1456                         }
1457                         for (int i = 0; i < numColorComponents; i++) {
1458                             ddata[i] = norm[i];
1459                         }
1460                     }
1461                     return ddata;
1462                 }
1463             }
1464         }
1465 
1466         // Handle BYTE, USHORT, & INT here
1467         //REMIND: maybe more efficient not to use int array for
1468         //DataBuffer.TYPE_USHORT and DataBuffer.TYPE_INT
1469         int[] intpixel;
1470         if (transferType == DataBuffer.TYPE_INT &&
1471             pixel != null) {
1472            intpixel = (int[])pixel;
1473         } else {
1474             intpixel = new int[numComponents];
1475         }
1476 
1477         if (is_sRGB_stdScale || is_LinearRGB_stdScale) {
1478             int precision;
1479             float factor;
1480             if (is_LinearRGB_stdScale) {
1481                 if (transferType == DataBuffer.TYPE_BYTE) {
1482                     red = fromsRGB8LUT8[red] & 0xff;
1483                     grn = fromsRGB8LUT8[grn] & 0xff;
1484                     blu = fromsRGB8LUT8[blu] & 0xff;
1485                     precision = 8;
1486                     factor = 1.0f / 255.0f;
1487                 } else {
1488                     red = fromsRGB8LUT16[red] & 0xffff;
1489                     grn = fromsRGB8LUT16[grn] & 0xffff;


1598                 }
1599                 else {
1600                     intpixel[numColorComponents] =
1601                         (int) (alp * factor *
1602                                ((1<<nBits[numColorComponents]) - 1) + 0.5f);
1603                 }
1604                 if (isAlphaPremultiplied) {
1605                     factor *= alp;
1606                     for (int i = 0; i < numColorComponents; i++) {
1607                         norm[i] *= factor;
1608                     }
1609                 }
1610             }
1611             for (int i = 0; i < numColorComponents; i++) {
1612                 intpixel[i] = (int) (norm[i] * ((1<<nBits[i]) - 1) + 0.5f);
1613             }
1614         }
1615 
1616         switch (transferType) {
1617             case DataBuffer.TYPE_BYTE: {
1618                byte[] bdata;
1619                if (pixel == null) {
1620                    bdata = new byte[numComponents];
1621                } else {
1622                    bdata = (byte[])pixel;
1623                }
1624                for (int i = 0; i < numComponents; i++) {
1625                    bdata[i] = (byte)(0xff&intpixel[i]);
1626                }
1627                return bdata;
1628             }
1629             case DataBuffer.TYPE_USHORT:{
1630                short[] sdata;
1631                if (pixel == null) {
1632                    sdata = new short[numComponents];
1633                } else {
1634                    sdata = (short[])pixel;
1635                }
1636                for (int i = 0; i < numComponents; i++) {
1637                    sdata[i] = (short)(intpixel[i]&0xffff);
1638                }
1639                return sdata;
1640             }
1641             case DataBuffer.TYPE_INT:
1642                 if (maxBits > 23) {
1643                     // fix 4412670 - for components of 24 or more bits
1644                     // some calculations done above with float precision
1645                     // may lose enough precision that the integer result
1646                     // overflows nBits, so we need to clamp.
1647                     for (int i = 0; i < numComponents; i++) {
1648                         if (intpixel[i] > ((1<<nBits[i]) - 1)) {
1649                             intpixel[i] = (1<<nBits[i]) - 1;
1650                         }


1724      * a new array is allocated.
1725      * @param offset An offset into the {@code components} array.
1726      *
1727      * @return The {@code components} array.
1728      *
1729      * @throws IllegalArgumentException If this
1730      * {@code ComponentColorModel} does not support the unnormalized form
1731      * @throws UnsupportedOperationException in some cases iff the
1732      * transfer type of this {@code ComponentColorModel}
1733      * is not one of the following transfer types:
1734      * {@code DataBuffer.TYPE_BYTE}, {@code DataBuffer.TYPE_USHORT},
1735      * or {@code DataBuffer.TYPE_INT}.
1736      * @throws ClassCastException If {@code pixel} is not a primitive
1737      * array of type {@code transferType}.
1738      * @throws IllegalArgumentException If the {@code components} array is
1739      * not null and is not large enough to hold all the color and alpha
1740      * components (starting at offset), or if {@code pixel} is not large
1741      * enough to hold a pixel value for this ColorModel.
1742      */
1743     public int[] getComponents(Object pixel, int[] components, int offset) {
1744         int[] intpixel;
1745         if (needScaleInit) {
1746             initScale();
1747         }
1748         if (noUnnorm) {
1749             throw new
1750                 IllegalArgumentException(
1751                     "This ColorModel does not support the unnormalized form");
1752         }
1753         if (pixel instanceof int[]) {
1754             intpixel = (int[])pixel;
1755         } else {
1756             intpixel = DataBuffer.toIntArray(pixel);
1757             if (intpixel == null) {
1758                throw new UnsupportedOperationException("This method has not been "+
1759                    "implemented for transferType " + transferType);
1760             }
1761         }
1762         if (intpixel.length < numComponents) {
1763             throw new IllegalArgumentException
1764                 ("Length of pixel array < number of components in model");


2040      *  hold all of the color and alpha components starting at
2041      *  {@code normOffset}
2042      * @since 1.4
2043      */
2044     public int getDataElement(float[] normComponents, int normOffset) {
2045         if (numComponents > 1) {
2046             throw new
2047                 IllegalArgumentException("More than one component per pixel");
2048         }
2049         if (signed) {
2050             throw new
2051                 IllegalArgumentException("Component value is signed");
2052         }
2053         if (needScaleInit) {
2054             initScale();
2055         }
2056         Object pixel = getDataElements(normComponents, normOffset, null);
2057         switch (transferType) {
2058         case DataBuffer.TYPE_BYTE:
2059             {
2060                 byte[] bpixel = (byte[]) pixel;
2061                 return bpixel[0] & 0xff;
2062             }
2063         case DataBuffer.TYPE_USHORT:
2064             {
2065                 short[] uspixel = (short[]) pixel;
2066                 return uspixel[0] & 0xffff;
2067             }
2068         case DataBuffer.TYPE_INT:
2069             {
2070                 int[] ipixel = (int[]) pixel;
2071                 return ipixel[0];
2072             }
2073         default:
2074             throw new UnsupportedOperationException("This method has not been "
2075                 + "implemented for transferType " + transferType);
2076         }
2077     }
2078 
2079     /**
2080      * Returns a data element array representation of a pixel in this


2451      */
2452     public ColorModel coerceData (WritableRaster raster,
2453                                   boolean isAlphaPremultiplied) {
2454         if ((supportsAlpha == false) ||
2455             (this.isAlphaPremultiplied == isAlphaPremultiplied))
2456         {
2457             // Nothing to do
2458             return this;
2459         }
2460 
2461         int w = raster.getWidth();
2462         int h = raster.getHeight();
2463         int aIdx = raster.getNumBands() - 1;
2464         float normAlpha;
2465         int rminX = raster.getMinX();
2466         int rY = raster.getMinY();
2467         int rX;
2468         if (isAlphaPremultiplied) {
2469             switch (transferType) {
2470                 case DataBuffer.TYPE_BYTE: {
2471                     byte[] pixel = null;
2472                     byte[] zpixel = null;
2473                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2474                     for (int y = 0; y < h; y++, rY++) {
2475                         rX = rminX;
2476                         for (int x = 0; x < w; x++, rX++) {
2477                             pixel = (byte[])raster.getDataElements(rX, rY,
2478                                                                    pixel);
2479                             normAlpha = (pixel[aIdx] & 0xff) * alphaScale;
2480                             if (normAlpha != 0.0f) {
2481                                 for (int c=0; c < aIdx; c++) {
2482                                     pixel[c] = (byte)((pixel[c] & 0xff) *
2483                                                       normAlpha + 0.5f);
2484                                 }
2485                                 raster.setDataElements(rX, rY, pixel);
2486                             } else {
2487                                 if (zpixel == null) {
2488                                     zpixel = new byte[numComponents];
2489                                     java.util.Arrays.fill(zpixel, (byte) 0);
2490                                 }
2491                                 raster.setDataElements(rX, rY, zpixel);
2492                             }
2493                         }
2494                     }
2495                 }
2496                 break;
2497                 case DataBuffer.TYPE_USHORT: {
2498                     short[] pixel = null;
2499                     short[] zpixel = null;
2500                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2501                     for (int y = 0; y < h; y++, rY++) {
2502                         rX = rminX;
2503                         for (int x = 0; x < w; x++, rX++) {
2504                             pixel = (short[])raster.getDataElements(rX, rY,
2505                                                                     pixel);
2506                             normAlpha = (pixel[aIdx] & 0xffff) * alphaScale;
2507                             if (normAlpha != 0.0f) {
2508                                 for (int c=0; c < aIdx; c++) {
2509                                     pixel[c] = (short)
2510                                         ((pixel[c] & 0xffff) * normAlpha +
2511                                          0.5f);
2512                                 }
2513                                 raster.setDataElements(rX, rY, pixel);
2514                             } else {
2515                                 if (zpixel == null) {
2516                                     zpixel = new short[numComponents];
2517                                     java.util.Arrays.fill(zpixel, (short) 0);
2518                                 }
2519                                 raster.setDataElements(rX, rY, zpixel);
2520                             }
2521                         }
2522                     }
2523                 }
2524                 break;
2525                 case DataBuffer.TYPE_INT: {
2526                     int[] pixel = null;
2527                     int[] zpixel = null;
2528                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2529                     for (int y = 0; y < h; y++, rY++) {
2530                         rX = rminX;
2531                         for (int x = 0; x < w; x++, rX++) {
2532                             pixel = (int[])raster.getDataElements(rX, rY,
2533                                                                   pixel);
2534                             normAlpha = pixel[aIdx] * alphaScale;
2535                             if (normAlpha != 0.0f) {
2536                                 for (int c=0; c < aIdx; c++) {
2537                                     pixel[c] = (int) (pixel[c] * normAlpha +
2538                                                       0.5f);
2539                                 }
2540                                 raster.setDataElements(rX, rY, pixel);
2541                             } else {
2542                                 if (zpixel == null) {
2543                                     zpixel = new int[numComponents];
2544                                     java.util.Arrays.fill(zpixel, 0);
2545                                 }
2546                                 raster.setDataElements(rX, rY, zpixel);
2547                             }
2548                         }
2549                     }
2550                 }
2551                 break;
2552                 case DataBuffer.TYPE_SHORT: {
2553                     short[] pixel = null;
2554                     short[] zpixel = null;
2555                     float alphaScale = 1.0f / 32767.0f;
2556                     for (int y = 0; y < h; y++, rY++) {
2557                         rX = rminX;
2558                         for (int x = 0; x < w; x++, rX++) {
2559                             pixel = (short[]) raster.getDataElements(rX, rY,
2560                                                                      pixel);
2561                             normAlpha = pixel[aIdx] * alphaScale;
2562                             if (normAlpha != 0.0f) {
2563                                 for (int c=0; c < aIdx; c++) {
2564                                     pixel[c] = (short) (pixel[c] * normAlpha +
2565                                                         0.5f);
2566                                 }
2567                                 raster.setDataElements(rX, rY, pixel);
2568                             } else {
2569                                 if (zpixel == null) {
2570                                     zpixel = new short[numComponents];
2571                                     java.util.Arrays.fill(zpixel, (short) 0);
2572                                 }
2573                                 raster.setDataElements(rX, rY, zpixel);
2574                             }
2575                         }
2576                     }
2577                 }
2578                 break;
2579                 case DataBuffer.TYPE_FLOAT: {
2580                     float[] pixel = null;
2581                     float[] zpixel = null;
2582                     for (int y = 0; y < h; y++, rY++) {
2583                         rX = rminX;
2584                         for (int x = 0; x < w; x++, rX++) {
2585                             pixel = (float[]) raster.getDataElements(rX, rY,
2586                                                                      pixel);
2587                             normAlpha = pixel[aIdx];
2588                             if (normAlpha != 0.0f) {
2589                                 for (int c=0; c < aIdx; c++) {
2590                                     pixel[c] *= normAlpha;
2591                                 }
2592                                 raster.setDataElements(rX, rY, pixel);
2593                             } else {
2594                                 if (zpixel == null) {
2595                                     zpixel = new float[numComponents];
2596                                     java.util.Arrays.fill(zpixel, 0.0f);
2597                                 }
2598                                 raster.setDataElements(rX, rY, zpixel);
2599                             }
2600                         }
2601                     }
2602                 }
2603                 break;
2604                 case DataBuffer.TYPE_DOUBLE: {
2605                     double[] pixel = null;
2606                     double[] zpixel = null;
2607                     for (int y = 0; y < h; y++, rY++) {
2608                         rX = rminX;
2609                         for (int x = 0; x < w; x++, rX++) {
2610                             pixel = (double[]) raster.getDataElements(rX, rY,
2611                                                                       pixel);
2612                             double dnormAlpha = pixel[aIdx];
2613                             if (dnormAlpha != 0.0) {
2614                                 for (int c=0; c < aIdx; c++) {
2615                                     pixel[c] *= dnormAlpha;
2616                                 }
2617                                 raster.setDataElements(rX, rY, pixel);
2618                             } else {
2619                                 if (zpixel == null) {
2620                                     zpixel = new double[numComponents];
2621                                     java.util.Arrays.fill(zpixel, 0.0);
2622                                 }
2623                                 raster.setDataElements(rX, rY, zpixel);
2624                             }
2625                         }
2626                     }
2627                 }
2628                 break;
2629                 default:
2630                     throw new UnsupportedOperationException("This method has not been "+
2631                          "implemented for transferType " + transferType);
2632             }
2633         }
2634         else {
2635             // We are premultiplied and want to divide it out
2636             switch (transferType) {
2637                 case DataBuffer.TYPE_BYTE: {
2638                     byte[] pixel = null;
2639                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2640                     for (int y = 0; y < h; y++, rY++) {
2641                         rX = rminX;
2642                         for (int x = 0; x < w; x++, rX++) {
2643                             pixel = (byte[])raster.getDataElements(rX, rY,
2644                                                                    pixel);
2645                             normAlpha = (pixel[aIdx] & 0xff) * alphaScale;
2646                             if (normAlpha != 0.0f) {
2647                                 float invAlpha = 1.0f / normAlpha;
2648                                 for (int c=0; c < aIdx; c++) {
2649                                     pixel[c] = (byte)
2650                                         ((pixel[c] & 0xff) * invAlpha + 0.5f);
2651                                 }
2652                                 raster.setDataElements(rX, rY, pixel);
2653                             }
2654                         }
2655                     }
2656                 }
2657                 break;
2658                 case DataBuffer.TYPE_USHORT: {
2659                     short[] pixel = null;
2660                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2661                     for (int y = 0; y < h; y++, rY++) {
2662                         rX = rminX;
2663                         for (int x = 0; x < w; x++, rX++) {
2664                             pixel = (short[])raster.getDataElements(rX, rY,
2665                                                                     pixel);
2666                             normAlpha = (pixel[aIdx] & 0xffff) * alphaScale;
2667                             if (normAlpha != 0.0f) {
2668                                 float invAlpha = 1.0f / normAlpha;
2669                                 for (int c=0; c < aIdx; c++) {
2670                                     pixel[c] = (short)
2671                                         ((pixel[c] & 0xffff) * invAlpha + 0.5f);
2672                                 }
2673                                 raster.setDataElements(rX, rY, pixel);
2674                             }
2675                         }
2676                     }
2677                 }
2678                 break;
2679                 case DataBuffer.TYPE_INT: {
2680                     int[] pixel = null;
2681                     float alphaScale = 1.0f / ((float) ((1<<nBits[aIdx]) - 1));
2682                     for (int y = 0; y < h; y++, rY++) {
2683                         rX = rminX;
2684                         for (int x = 0; x < w; x++, rX++) {
2685                             pixel = (int[])raster.getDataElements(rX, rY,
2686                                                                   pixel);
2687                             normAlpha = pixel[aIdx] * alphaScale;
2688                             if (normAlpha != 0.0f) {
2689                                 float invAlpha = 1.0f / normAlpha;
2690                                 for (int c=0; c < aIdx; c++) {
2691                                     pixel[c] = (int)
2692                                         (pixel[c] * invAlpha + 0.5f);
2693                                 }
2694                                 raster.setDataElements(rX, rY, pixel);
2695                             }
2696                         }
2697                     }
2698                 }
2699                 break;
2700                 case DataBuffer.TYPE_SHORT: {
2701                     short[] pixel = null;
2702                     float alphaScale = 1.0f / 32767.0f;
2703                     for (int y = 0; y < h; y++, rY++) {
2704                         rX = rminX;
2705                         for (int x = 0; x < w; x++, rX++) {
2706                             pixel = (short[])raster.getDataElements(rX, rY,
2707                                                                     pixel);
2708                             normAlpha = pixel[aIdx] * alphaScale;
2709                             if (normAlpha != 0.0f) {
2710                                 float invAlpha = 1.0f / normAlpha;
2711                                 for (int c=0; c < aIdx; c++) {
2712                                     pixel[c] = (short)
2713                                         (pixel[c] * invAlpha + 0.5f);
2714                                 }
2715                                 raster.setDataElements(rX, rY, pixel);
2716                             }
2717                         }
2718                     }
2719                 }
2720                 break;
2721                 case DataBuffer.TYPE_FLOAT: {
2722                     float[] pixel = null;
2723                     for (int y = 0; y < h; y++, rY++) {
2724                         rX = rminX;
2725                         for (int x = 0; x < w; x++, rX++) {
2726                             pixel = (float[])raster.getDataElements(rX, rY,
2727                                                                     pixel);
2728                             normAlpha = pixel[aIdx];
2729                             if (normAlpha != 0.0f) {
2730                                 float invAlpha = 1.0f / normAlpha;
2731                                 for (int c=0; c < aIdx; c++) {
2732                                     pixel[c] *= invAlpha;
2733                                 }
2734                                 raster.setDataElements(rX, rY, pixel);
2735                             }
2736                         }
2737                     }
2738                 }
2739                 break;
2740                 case DataBuffer.TYPE_DOUBLE: {
2741                     double[] pixel = null;
2742                     for (int y = 0; y < h; y++, rY++) {
2743                         rX = rminX;
2744                         for (int x = 0; x < w; x++, rX++) {
2745                             pixel = (double[])raster.getDataElements(rX, rY,
2746                                                                      pixel);
2747                             double dnormAlpha = pixel[aIdx];
2748                             if (dnormAlpha != 0.0) {
2749                                 double invAlpha = 1.0 / dnormAlpha;
2750                                 for (int c=0; c < aIdx; c++) {
2751                                     pixel[c] *= invAlpha;
2752                                 }
2753                                 raster.setDataElements(rX, rY, pixel);
2754                             }
2755                         }
2756                     }
2757                 }
2758                 break;
2759                 default:
2760                     throw new UnsupportedOperationException("This method has not been "+
2761                          "implemented for transferType " + transferType);


< prev index next >