1 7 8 17 18 package java.awt.image; 19 20 import java.awt.Point ; 21 import java.awt.Graphics2D ; 22 import java.awt.color.*; 23 import sun.awt.color.ICC_Transform; 24 import sun.awt.color.ProfileDeferralMgr; 25 import java.awt.geom.Rectangle2D ; 26 import java.awt.geom.Point2D ; 27 import java.awt.RenderingHints ; 28 29 51 public class ColorConvertOp implements BufferedImageOp , RasterOp { 52 ICC_Profile[] profileList; 53 ColorSpace[] CSList; 54 ICC_Transform thisTransform, thisRasterTransform; 55 ICC_Profile thisSrcProfile, thisDestProfile; 56 RenderingHints hints; 57 boolean gotProfiles; 58 float[] srcMinVals, srcMaxVals, dstMinVals, dstMaxVals; 59 60 61 static { 62 if (ProfileDeferralMgr.deferring) { 63 ProfileDeferralMgr.activateProfiles(); 64 } 65 } 66 67 78 public ColorConvertOp (RenderingHints hints) 79 { 80 profileList = new ICC_Profile [0]; 81 this.hints = hints; 82 } 83 84 100 public ColorConvertOp (ColorSpace cspace, RenderingHints hints) 101 { 102 if (cspace == null) { 103 throw new NullPointerException ("ColorSpace cannot be null"); 104 } 105 if (cspace instanceof ICC_ColorSpace) { 106 profileList = new ICC_Profile [1]; 107 108 profileList [0] = ((ICC_ColorSpace) cspace).getProfile(); 109 } 110 else { 111 CSList = new ColorSpace[1]; 112 CSList[0] = cspace; 113 } 114 this.hints = hints; 115 } 116 117 118 135 public ColorConvertOp(ColorSpace srcCspace, ColorSpace dstCspace, 136 RenderingHints hints) 137 { 138 if ((srcCspace == null) || (dstCspace == null)) { 139 throw new NullPointerException ("ColorSpaces cannot be null"); 140 } 141 if ((srcCspace instanceof ICC_ColorSpace) && 142 (dstCspace instanceof ICC_ColorSpace)) { 143 profileList = new ICC_Profile [2]; 144 145 profileList [0] = ((ICC_ColorSpace) srcCspace).getProfile(); 146 profileList [1] = ((ICC_ColorSpace) dstCspace).getProfile(); 147 148 getMinMaxValsFromColorSpaces(srcCspace, dstCspace); 149 } else { 150 151 CSList = new ColorSpace[2]; 152 CSList[0] = srcCspace; 153 CSList[1] = dstCspace; 154 } 155 this.hints = hints; 156 } 157 158 159 186 public ColorConvertOp (ICC_Profile[] profiles, RenderingHints hints) 187 { 188 if (profiles == null) { 189 throw new NullPointerException ("Profiles cannot be null"); 190 } 191 gotProfiles = true; 192 profileList = new ICC_Profile[profiles.length]; 193 for (int i1 = 0; i1 < profiles.length; i1++) { 194 profileList[i1] = profiles[i1]; 195 } 196 this.hints = hints; 197 } 198 199 200 209 public final ICC_Profile[] getICC_Profiles() { 210 if (gotProfiles) { 211 ICC_Profile[] profiles = new ICC_Profile[profileList.length]; 212 for (int i1 = 0; i1 < profileList.length; i1++) { 213 profiles[i1] = profileList[i1]; 214 } 215 return profiles; 216 } 217 return null; 218 } 219 220 234 public final BufferedImage filter(BufferedImage src, BufferedImage dest) { 235 ColorSpace srcColorSpace, destColorSpace; 236 BufferedImage savdest = null; 237 238 if (src.getColorModel() instanceof IndexColorModel ) { 239 IndexColorModel icm = (IndexColorModel ) src.getColorModel(); 240 src = icm.convertToIntDiscrete(src.getRaster(), true); 241 } 242 srcColorSpace = src.getColorModel().getColorSpace(); 243 if (dest != null) { 244 if (dest.getColorModel() instanceof IndexColorModel ) { 245 savdest = dest; 246 dest = null; 247 destColorSpace = null; 248 } else { 249 destColorSpace = dest.getColorModel().getColorSpace(); 250 } 251 } else { 252 destColorSpace = null; 253 } 254 255 if ((CSList != null) || 256 (!(srcColorSpace instanceof ICC_ColorSpace)) || 257 ((dest != null) && 258 (!(destColorSpace instanceof ICC_ColorSpace)))) { 259 260 dest = nonICCBIFilter(src, srcColorSpace, dest, destColorSpace); 261 } else { 262 dest = ICCBIFilter(src, srcColorSpace, dest, destColorSpace); 263 } 264 265 if (savdest != null) { 266 Graphics2D big = savdest.createGraphics(); 267 try { 268 big.drawImage(dest, 0, 0, null); 269 } finally { 270 big.dispose(); 271 } 272 return savdest; 273 } else { 274 return dest; 275 } 276 } 277 278 private final BufferedImage ICCBIFilter(BufferedImage src, 279 ColorSpace srcColorSpace, 280 BufferedImage dest, 281 ColorSpace destColorSpace) { 282 int nProfiles = profileList.length; 283 ICC_Profile srcProfile = null, destProfile = null; 284 285 srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile(); 286 287 if (dest == null) { 289 if (nProfiles == 0) { 290 throw new IllegalArgumentException ( 291 "Destination ColorSpace is undefined"); 292 } 293 destProfile = profileList [nProfiles - 1]; 294 dest = createCompatibleDestImage(src, null); 295 } 296 else { 297 if (src.getHeight() != dest.getHeight() || 298 src.getWidth() != dest.getWidth()) { 299 throw new IllegalArgumentException ( 300 "Width or height of BufferedImages do not match"); 301 } 302 destProfile = ((ICC_ColorSpace) destColorSpace).getProfile(); 303 } 304 305 306 if ((thisTransform == null) || (thisSrcProfile != srcProfile) || 307 (thisDestProfile != destProfile) ) { 308 updateBITransform(srcProfile, destProfile); 309 } 310 311 312 thisTransform.colorConvert(src, dest); 313 314 return dest; 315 } 316 317 private void updateBITransform(ICC_Profile srcProfile, 318 ICC_Profile destProfile) { 319 ICC_Profile[] theProfiles; 320 int i1, nProfiles, nTransforms, whichTrans, renderState; 321 ICC_Transform[] theTransforms; 322 boolean useSrc = false, useDest = false; 323 324 nProfiles = profileList.length; 325 nTransforms = nProfiles; 326 if ((nProfiles == 0) || (srcProfile != profileList[0])) { 327 nTransforms += 1; 328 useSrc = true; 329 } 330 if ((nProfiles == 0) || (destProfile != profileList[nProfiles - 1]) || 331 (nTransforms < 2)) { 332 nTransforms += 1; 333 useDest = true; 334 } 335 336 337 theProfiles = new ICC_Profile[nTransforms]; 339 340 int idx = 0; 341 if (useSrc) { 342 343 theProfiles[idx++] = srcProfile; 344 } 345 346 for (i1 = 0; i1 < nProfiles; i1++) { 347 348 theProfiles[idx++] = profileList [i1]; 349 } 350 351 if (useDest) { 352 353 theProfiles[idx] = destProfile; 354 } 355 356 357 theTransforms = new ICC_Transform [nTransforms]; 358 359 360 if (theProfiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) { 361 363 renderState = ICC_Profile.icRelativeColorimetric; 364 } 365 else { 366 renderState = ICC_Profile.icPerceptual; 368 } 369 370 whichTrans = ICC_Transform.In; 371 372 373 for (i1 = 0; i1 < nTransforms; i1++) { 374 if (i1 == nTransforms -1) { 375 whichTrans = ICC_Transform.Out; 376 } 377 else { 378 if ((whichTrans == ICC_Transform.Simulation) && 379 (theProfiles[i1].getProfileClass () == 380 ICC_Profile.CLASS_ABSTRACT)) { 381 renderState = ICC_Profile.icPerceptual; 382 whichTrans = ICC_Transform.In; 383 } 384 } 385 386 theTransforms[i1] = new ICC_Transform (theProfiles[i1], 387 renderState, whichTrans); 388 389 391 renderState = getRenderingIntent(theProfiles[i1]); 392 393 394 whichTrans = ICC_Transform.Simulation; 395 } 396 397 398 thisTransform = new ICC_Transform (theTransforms); 399 400 401 thisSrcProfile = srcProfile; 402 thisDestProfile = destProfile; 403 } 404 405 425 public final WritableRaster filter (Raster src, WritableRaster dest) { 426 427 if (CSList != null) { 428 429 return nonICCRasterFilter(src, dest); 430 } 431 int nProfiles = profileList.length; 432 if (nProfiles < 2) { 433 throw new IllegalArgumentException ( 434 "Source or Destination ColorSpace is undefined"); 435 } 436 if (src.getNumBands() != profileList[0].getNumComponents()) { 437 throw new IllegalArgumentException ( 438 "Numbers of source Raster bands and source color space " + 439 "components do not match"); 440 } 441 if (dest == null) { 442 dest = createCompatibleDestRaster(src); 443 } 444 else { 445 if (src.getHeight() != dest.getHeight() || 446 src.getWidth() != dest.getWidth()) { 447 throw new IllegalArgumentException ( 448 "Width or height of Rasters do not match"); 449 } 450 if (dest.getNumBands() != 451 profileList[nProfiles-1].getNumComponents()) { 452 throw new IllegalArgumentException ( 453 "Numbers of destination Raster bands and destination " + 454 "color space components do not match"); 455 } 456 } 457 458 459 if (thisRasterTransform == null) { 460 int i1, whichTrans, renderState; 461 ICC_Transform[] theTransforms; 462 463 464 theTransforms = new ICC_Transform [nProfiles]; 465 466 467 if (profileList[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) { 468 470 renderState = ICC_Profile.icRelativeColorimetric; 471 } 472 else { 473 renderState = ICC_Profile.icPerceptual; 475 } 476 477 whichTrans = ICC_Transform.In; 478 479 480 for (i1 = 0; i1 < nProfiles; i1++) { 481 if (i1 == nProfiles -1) { 482 whichTrans = ICC_Transform.Out; 483 } 484 else { 485 if ((whichTrans == ICC_Transform.Simulation) && 486 (profileList[i1].getProfileClass () == 487 ICC_Profile.CLASS_ABSTRACT)) { 488 renderState = ICC_Profile.icPerceptual; 489 whichTrans = ICC_Transform.In; 490 } 491 } 492 493 theTransforms[i1] = new ICC_Transform (profileList[i1], 494 renderState, whichTrans); 495 496 498 renderState = getRenderingIntent(profileList[i1]); 499 500 501 whichTrans = ICC_Transform.Simulation; 502 } 503 504 505 thisRasterTransform = new ICC_Transform (theTransforms); 506 } 507 508 int srcTransferType = src.getTransferType(); 509 int dstTransferType = dest.getTransferType(); 510 if ((srcTransferType == DataBuffer.TYPE_FLOAT) || 511 (srcTransferType == DataBuffer.TYPE_DOUBLE) || 512 (dstTransferType == DataBuffer.TYPE_FLOAT) || 513 (dstTransferType == DataBuffer.TYPE_DOUBLE)) { 514 if (srcMinVals == null) { 515 getMinMaxValsFromProfiles(profileList[0], 516 profileList[nProfiles-1]); 517 } 518 519 thisRasterTransform.colorConvert(src, dest, 520 srcMinVals, srcMaxVals, 521 dstMinVals, dstMaxVals); 522 } else { 523 524 thisRasterTransform.colorConvert(src, dest); 525 } 526 527 528 return dest; 529 } 530 531 539 public final Rectangle2D getBounds2D (BufferedImage src) { 540 return getBounds2D(src.getRaster()); 541 } 542 543 551 public final Rectangle2D getBounds2D (Raster src) { 552 555 return src.getBounds(); 556 } 557 558 571 public BufferedImage createCompatibleDestImage (BufferedImage src, 572 ColorModel destCM) { 573 ColorSpace cs = null;; 574 if (destCM == null) { 575 if (CSList == null) { 576 577 int nProfiles = profileList.length; 578 if (nProfiles == 0) { 579 throw new IllegalArgumentException ( 580 "Destination ColorSpace is undefined"); 581 } 582 ICC_Profile destProfile = profileList[nProfiles - 1]; 583 cs = new ICC_ColorSpace(destProfile); 584 } else { 585 586 int nSpaces = CSList.length; 587 cs = CSList[nSpaces - 1]; 588 } 589 } 590 return createCompatibleDestImage(src, destCM, cs); 591 } 592 593 private BufferedImage createCompatibleDestImage(BufferedImage src, 594 ColorModel destCM, 595 ColorSpace destCS) { 596 BufferedImage image; 597 if (destCM == null) { 598 ColorModel srcCM = src.getColorModel(); 599 int nbands = destCS.getNumComponents(); 600 boolean hasAlpha = srcCM.hasAlpha(); 601 if (hasAlpha) { 602 nbands += 1; 603 } 604 int[] nbits = new int[nbands]; 605 for (int i = 0; i < nbands; i++) { 606 nbits[i] = 8; 607 } 608 destCM = new ComponentColorModel (destCS, nbits, hasAlpha, 609 srcCM.isAlphaPremultiplied(), 610 srcCM.getTransparency(), 611 DataBuffer.TYPE_BYTE); 612 } 613 int w = src.getWidth(); 614 int h = src.getHeight(); 615 image = new BufferedImage (destCM, 616 destCM.createCompatibleWritableRaster(w, h), 617 destCM.isAlphaPremultiplied(), null); 618 return image; 619 } 620 621 622 632 public WritableRaster createCompatibleDestRaster (Raster src) { 633 int ncomponents; 634 635 if (CSList != null) { 636 637 if (CSList.length != 2) { 638 throw new IllegalArgumentException ( 639 "Destination ColorSpace is undefined"); 640 } 641 ncomponents = CSList[1].getNumComponents(); 642 } else { 643 644 int nProfiles = profileList.length; 645 if (nProfiles < 2) { 646 throw new IllegalArgumentException ( 647 "Destination ColorSpace is undefined"); 648 } 649 ncomponents = profileList[nProfiles-1].getNumComponents(); 650 } 651 652 WritableRaster dest = 653 Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, 654 src.getWidth(), 655 src.getHeight(), 656 ncomponents, 657 new Point (src.getMinX(), src.getMinY())); 658 return dest; 659 } 660 661 672 public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) { 673 if (dstPt == null) { 674 dstPt = new Point2D.Float (); 675 } 676 dstPt.setLocation(srcPt.getX(), srcPt.getY()); 677 678 return dstPt; 679 } 680 681 682 685 private int getRenderingIntent (ICC_Profile profile) { 686 byte[] header = profile.getData(ICC_Profile.icSigHead); 687 int index = ICC_Profile.icHdrRenderingIntent; 688 return (((header[index] & 0xff) << 24) | 689 ((header[index+1] & 0xff) << 16) | 690 ((header[index+2] & 0xff) << 8) | 691 (header[index+3] & 0xff)); 692 } 693 694 699 public final RenderingHints getRenderingHints() { 700 return hints; 701 } 702 703 private final BufferedImage nonICCBIFilter(BufferedImage src, 704 ColorSpace srcColorSpace, 705 BufferedImage dst, 706 ColorSpace dstColorSpace) { 707 708 int w = src.getWidth(); 709 int h = src.getHeight(); 710 ICC_ColorSpace ciespace = 711 (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_CIEXYZ); 712 if (dst == null) { 713 dst = createCompatibleDestImage(src, null); 714 dstColorSpace = dst.getColorModel().getColorSpace(); 715 } else { 716 if ((h != dst.getHeight()) || (w != dst.getWidth())) { 717 throw new IllegalArgumentException ( 718 "Width or height of BufferedImages do not match"); 719 } 720 } 721 Raster srcRas = src.getRaster(); 722 WritableRaster dstRas = dst.getRaster(); 723 ColorModel srcCM = src.getColorModel(); 724 ColorModel dstCM = dst.getColorModel(); 725 int srcNumComp = srcCM.getNumColorComponents(); 726 int dstNumComp = dstCM.getNumColorComponents(); 727 boolean dstHasAlpha = dstCM.hasAlpha(); 728 boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha; 729 ColorSpace[] list; 730 if ((CSList == null) && (profileList.length != 0)) { 731 732 boolean nonICCSrc, nonICCDst; 733 ICC_Profile srcProfile, dstProfile; 734 if (!(srcColorSpace instanceof ICC_ColorSpace)) { 735 nonICCSrc = true; 736 srcProfile = ciespace.getProfile(); 737 } else { 738 nonICCSrc = false; 739 srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile(); 740 } 741 if (!(dstColorSpace instanceof ICC_ColorSpace)) { 742 nonICCDst = true; 743 dstProfile = ciespace.getProfile(); 744 } else { 745 nonICCDst = false; 746 dstProfile = ((ICC_ColorSpace) dstColorSpace).getProfile(); 747 } 748 749 if ((thisTransform == null) || (thisSrcProfile != srcProfile) || 750 (thisDestProfile != dstProfile) ) { 751 updateBITransform(srcProfile, dstProfile); 752 } 753 float maxNum = 65535.0f; ColorSpace cs; 756 int iccSrcNumComp; 757 if (nonICCSrc) { 758 cs = ciespace; 759 iccSrcNumComp = 3; 760 } else { 761 cs = srcColorSpace; 762 iccSrcNumComp = srcNumComp; 763 } 764 float[] srcMinVal = new float[iccSrcNumComp]; 765 float[] srcInvDiffMinMax = new float[iccSrcNumComp]; 766 for (int i = 0; i < srcNumComp; i++) { 767 srcMinVal[i] = cs.getMinValue(i); 768 srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]); 769 } 770 int iccDstNumComp; 771 if (nonICCDst) { 772 cs = ciespace; 773 iccDstNumComp = 3; 774 } else { 775 cs = dstColorSpace; 776 iccDstNumComp = dstNumComp; 777 } 778 float[] dstMinVal = new float[iccDstNumComp]; 779 float[] dstDiffMinMax = new float[iccDstNumComp]; 780 for (int i = 0; i < dstNumComp; i++) { 781 dstMinVal[i] = cs.getMinValue(i); 782 dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum; 783 } 784 float[] dstColor; 785 if (dstHasAlpha) { 786 int size = ((dstNumComp + 1) > 3) ? (dstNumComp + 1) : 3; 787 dstColor = new float[size]; 788 } else { 789 int size = (dstNumComp > 3) ? dstNumComp : 3; 790 dstColor = new float[size]; 791 } 792 short[] srcLine = new short[w * iccSrcNumComp]; 793 short[] dstLine = new short[w * iccDstNumComp]; 794 Object pixel; 795 float[] color; 796 float[] alpha = null; 797 if (needSrcAlpha) { 798 alpha = new float[w]; 799 } 800 int idx; 801 for (int y = 0; y < h; y++) { 803 pixel = null; 805 color = null; 806 idx = 0; 807 for (int x = 0; x < w; x++) { 808 pixel = srcRas.getDataElements(x, y, pixel); 809 color = srcCM.getNormalizedComponents(pixel, color, 0); 810 if (needSrcAlpha) { 811 alpha[x] = color[srcNumComp]; 812 } 813 if (nonICCSrc) { 814 color = srcColorSpace.toCIEXYZ(color); 815 } 816 for (int i = 0; i < iccSrcNumComp; i++) { 817 srcLine[idx++] = (short) 818 ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] + 819 0.5f); 820 } 821 } 822 thisTransform.colorConvert(srcLine, dstLine); 824 pixel = null; 826 idx = 0; 827 for (int x = 0; x < w; x++) { 828 for (int i = 0; i < iccDstNumComp; i++) { 829 dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) * 830 dstDiffMinMax[i] + dstMinVal[i]; 831 } 832 if (nonICCDst) { 833 color = srcColorSpace.fromCIEXYZ(dstColor); 834 for (int i = 0; i < dstNumComp; i++) { 835 dstColor[i] = color[i]; 836 } 837 } 838 if (needSrcAlpha) { 839 dstColor[dstNumComp] = alpha[x]; 840 } else if (dstHasAlpha) { 841 dstColor[dstNumComp] = 1.0f; 842 } 843 pixel = dstCM.getDataElements(dstColor, 0, pixel); 844 dstRas.setDataElements(x, y, pixel); 845 } 846 } 847 } else { 848 849 int numCS; 851 if (CSList == null) { 852 numCS = 0; 853 } else { 854 numCS = CSList.length; 855 } 856 float[] dstColor; 857 if (dstHasAlpha) { 858 dstColor = new float[dstNumComp + 1]; 859 } else { 860 dstColor = new float[dstNumComp]; 861 } 862 Object spixel = null; 863 Object dpixel = null; 864 float[] color = null; 865 float[] tmpColor; 866 for (int y = 0; y < h; y++) { 868 for (int x = 0; x < w; x++) { 869 spixel = srcRas.getDataElements(x, y, spixel); 870 color = srcCM.getNormalizedComponents(spixel, color, 0); 871 tmpColor = srcColorSpace.toCIEXYZ(color); 872 for (int i = 0; i < numCS; i++) { 873 tmpColor = CSList[i].fromCIEXYZ(tmpColor); 874 tmpColor = CSList[i].toCIEXYZ(tmpColor); 875 } 876 tmpColor = dstColorSpace.fromCIEXYZ(tmpColor); 877 for (int i = 0; i < dstNumComp; i++) { 878 dstColor[i] = tmpColor[i]; 879 } 880 if (needSrcAlpha) { 881 dstColor[dstNumComp] = color[srcNumComp]; 882 } else if (dstHasAlpha) { 883 dstColor[dstNumComp] = 1.0f; 884 } 885 dpixel = dstCM.getDataElements(dstColor, 0, dpixel); 886 dstRas.setDataElements(x, y, dpixel); 887 888 } 889 } 890 } 891 892 return dst; 893 } 894 895 897 private final WritableRaster nonICCRasterFilter(Raster src, 898 WritableRaster dst) { 899 900 if (CSList.length != 2) { 901 throw new IllegalArgumentException ( 902 "Destination ColorSpace is undefined"); 903 } 904 if (src.getNumBands() != CSList[0].getNumComponents()) { 905 throw new IllegalArgumentException ( 906 "Numbers of source Raster bands and source color space " + 907 "components do not match"); 908 } 909 if (dst == null) { 910 dst = createCompatibleDestRaster(src); 911 } else { 912 if (src.getHeight() != dst.getHeight() || 913 src.getWidth() != dst.getWidth()) { 914 throw new IllegalArgumentException ( 915 "Width or height of Rasters do not match"); 916 } 917 if (dst.getNumBands() != CSList[1].getNumComponents()) { 918 throw new IllegalArgumentException ( 919 "Numbers of destination Raster bands and destination " + 920 "color space components do not match"); 921 } 922 } 923 924 if (srcMinVals == null) { 925 getMinMaxValsFromColorSpaces(CSList[0], CSList[1]); 926 } 927 928 SampleModel srcSM = src.getSampleModel(); 929 SampleModel dstSM = dst.getSampleModel(); 930 boolean srcIsFloat, dstIsFloat; 931 int srcTransferType = src.getTransferType(); 932 int dstTransferType = dst.getTransferType(); 933 if ((srcTransferType == DataBuffer.TYPE_FLOAT) || 934 (srcTransferType == DataBuffer.TYPE_DOUBLE)) { 935 srcIsFloat = true; 936 } else { 937 srcIsFloat = false; 938 } 939 if ((dstTransferType == DataBuffer.TYPE_FLOAT) || 940 (dstTransferType == DataBuffer.TYPE_DOUBLE)) { 941 dstIsFloat = true; 942 } else { 943 dstIsFloat = false; 944 } 945 int w = src.getWidth(); 946 int h = src.getHeight(); 947 int srcNumBands = src.getNumBands(); 948 int dstNumBands = dst.getNumBands(); 949 float[] srcScaleFactor = null; 950 float[] dstScaleFactor = null; 951 if (!srcIsFloat) { 952 srcScaleFactor = new float[srcNumBands]; 953 for (int i = 0; i < srcNumBands; i++) { 954 if (srcTransferType == DataBuffer.TYPE_SHORT) { 955 srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) / 956 32767.0f; 957 } else { 958 srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) / 959 ((float) ((1 << srcSM.getSampleSize(i)) - 1)); 960 } 961 } 962 } 963 if (!dstIsFloat) { 964 dstScaleFactor = new float[dstNumBands]; 965 for (int i = 0; i < dstNumBands; i++) { 966 if (dstTransferType == DataBuffer.TYPE_SHORT) { 967 dstScaleFactor[i] = 32767.0f / 968 (dstMaxVals[i] - dstMinVals[i]); 969 } else { 970 dstScaleFactor[i] = 971 ((float) ((1 << dstSM.getSampleSize(i)) - 1)) / 972 (dstMaxVals[i] - dstMinVals[i]); 973 } 974 } 975 } 976 int ys = src.getMinY(); 977 int yd = dst.getMinY(); 978 int xs, xd; 979 float sample; 980 float[] color = new float[srcNumBands]; 981 float[] tmpColor; 982 ColorSpace srcColorSpace = CSList[0]; 983 ColorSpace dstColorSpace = CSList[1]; 984 for (int y = 0; y < h; y++, ys++, yd++) { 986 xs = src.getMinX(); 988 xd = dst.getMinX(); 989 for (int x = 0; x < w; x++, xs++, xd++) { 990 for (int i = 0; i < srcNumBands; i++) { 991 sample = src.getSampleFloat(xs, ys, i); 992 if (!srcIsFloat) { 993 sample = sample * srcScaleFactor[i] + srcMinVals[i]; 994 } 995 color[i] = sample; 996 } 997 tmpColor = srcColorSpace.toCIEXYZ(color); 998 tmpColor = dstColorSpace.fromCIEXYZ(tmpColor); 999 for (int i = 0; i < dstNumBands; i++) { 1000 sample = tmpColor[i]; 1001 if (!dstIsFloat) { 1002 sample = (sample - dstMinVals[i]) * dstScaleFactor[i]; 1003 } 1004 dst.setSample(xd, yd, i, sample); 1005 } 1006 } 1007 } 1008 return dst; 1009 } 1010 1011 private void getMinMaxValsFromProfiles(ICC_Profile srcProfile, 1012 ICC_Profile dstProfile) { 1013 int type = srcProfile.getColorSpaceType(); 1014 int nc = srcProfile.getNumComponents(); 1015 srcMinVals = new float[nc]; 1016 srcMaxVals = new float[nc]; 1017 setMinMax(type, nc, srcMinVals, srcMaxVals); 1018 type = dstProfile.getColorSpaceType(); 1019 nc = dstProfile.getNumComponents(); 1020 dstMinVals = new float[nc]; 1021 dstMaxVals = new float[nc]; 1022 setMinMax(type, nc, dstMinVals, dstMaxVals); 1023 } 1024 1025 private void setMinMax(int type, int nc, float[] minVals, float[] maxVals) { 1026 if (type == ColorSpace.TYPE_Lab) { 1027 minVals[0] = 0.0f; maxVals[0] = 100.0f; 1029 minVals[1] = -128.0f; maxVals[1] = 127.0f; 1031 minVals[2] = -128.0f; maxVals[2] = 127.0f; 1033 } else if (type == ColorSpace.TYPE_XYZ) { 1034 minVals[0] = minVals[1] = minVals[2] = 0.0f; maxVals[0] = maxVals[1] = maxVals[2] = 1.0f + (32767.0f/ 32768.0f); 1036 } else { 1037 for (int i = 0; i < nc; i++) { 1038 minVals[i] = 0.0f; 1039 maxVals[i] = 1.0f; 1040 } 1041 } 1042 } 1043 1044 private void getMinMaxValsFromColorSpaces(ColorSpace srcCspace, 1045 ColorSpace dstCspace) { 1046 int nc = srcCspace.getNumComponents(); 1047 srcMinVals = new float[nc]; 1048 srcMaxVals = new float[nc]; 1049 for (int i = 0; i < nc; i++) { 1050 srcMinVals[i] = srcCspace.getMinValue(i); 1051 srcMaxVals[i] = srcCspace.getMaxValue(i); 1052 } 1053 nc = dstCspace.getNumComponents(); 1054 dstMinVals = new float[nc]; 1055 dstMaxVals = new float[nc]; 1056 for (int i = 0; i < nc; i++) { 1057 dstMinVals[i] = dstCspace.getMinValue(i); 1058 dstMaxVals[i] = dstCspace.getMaxValue(i); 1059 } 1060 } 1061 1062} 1063 | Popular Tags |