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);
|