1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /** 18 * @author Oleg V. Khaschansky 19 * @version $Revision$ 20 */ 21 22 package java.awt.color; 23 24 import java.io.File; 25 import java.io.FileInputStream; 26 import java.io.FileNotFoundException; 27 import java.io.FileOutputStream; 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.io.ObjectInputStream; 31 import java.io.ObjectOutputStream; 32 import java.io.ObjectStreamException; 33 import java.io.OutputStream; 34 import java.io.Serializable; 35 import java.security.AccessController; 36 import java.security.PrivilegedAction; 37 import java.util.StringTokenizer; 38 39 import org.apache.harmony.awt.gl.color.ICC_ProfileHelper; 40 import org.apache.harmony.awt.gl.color.NativeCMM; 41 import org.apache.harmony.awt.internal.nls.Messages; 42 43 /** 44 * The ICC_Profile class represents a color profile data for color spaces based 45 * on the International Color Consortium Specification ICC.1:2001-12, File 46 * Format for Color Profiles. 47 * 48 * @since Android 1.0 49 */ 50 public class ICC_Profile implements Serializable { 51 52 /** 53 * The Constant serialVersionUID. 54 */ 55 private static final long serialVersionUID = -3938515861990936766L; 56 57 // NOTE: Constant field values are noted in 1.5 specification. 58 59 /** 60 * The Constant CLASS_INPUT indicates that profile class is input. 61 */ 62 public static final int CLASS_INPUT = 0; 63 64 /** 65 * The Constant CLASS_DISPLAY indicates that profile class is display. 66 */ 67 public static final int CLASS_DISPLAY = 1; 68 69 /** 70 * The Constant CLASS_OUTPUT indicates that profile class is output. 71 */ 72 public static final int CLASS_OUTPUT = 2; 73 74 /** 75 * The Constant CLASS_DEVICELINK indicates that profile class is device 76 * link. 77 */ 78 public static final int CLASS_DEVICELINK = 3; 79 80 /** 81 * The Constant CLASS_COLORSPACECONVERSION indicates that profile class is 82 * color space conversion. 83 */ 84 public static final int CLASS_COLORSPACECONVERSION = 4; 85 86 /** 87 * The Constant CLASS_ABSTRACT indicates that profile class is abstract. 88 */ 89 public static final int CLASS_ABSTRACT = 5; 90 91 /** 92 * The Constant CLASS_NAMEDCOLOR indicates that profile class is named 93 * color. 94 */ 95 public static final int CLASS_NAMEDCOLOR = 6; 96 97 /** 98 * The Constant icSigXYZData - ICC Profile Color Space Type Signature. 99 */ 100 public static final int icSigXYZData = 1482250784; 101 102 /** 103 * The Constant icSigLabData - ICC Profile Color Space Type Signature. 104 */ 105 public static final int icSigLabData = 1281450528; 106 107 /** 108 * The Constant icSigLuvData - ICC Profile Color Space Type Signature. 109 */ 110 public static final int icSigLuvData = 1282766368; 111 112 /** 113 * The Constant icSigYCbCrData - ICC Profile Color Space Type Signature. 114 */ 115 public static final int icSigYCbCrData = 1497588338; 116 117 /** 118 * The Constant icSigYxyData - ICC Profile Color Space Type Signature. 119 */ 120 public static final int icSigYxyData = 1501067552; 121 122 /** 123 * The Constant icSigRgbData - ICC Profile Color Space Type Signature. 124 */ 125 public static final int icSigRgbData = 1380401696; 126 127 /** 128 * The Constant icSigGrayData - ICC Profile Color Space Type Signature. 129 */ 130 public static final int icSigGrayData = 1196573017; 131 132 /** 133 * The Constant icSigHsvData - ICC Profile Color Space Type Signature. 134 */ 135 public static final int icSigHsvData = 1213421088; 136 137 /** 138 * The Constant icSigHlsData - ICC Profile Color Space Type Signature. 139 */ 140 public static final int icSigHlsData = 1212961568; 141 142 /** 143 * The Constant icSigCmykData - ICC Profile Color Space Type Signature. 144 */ 145 public static final int icSigCmykData = 1129142603; 146 147 /** 148 * The Constant icSigCmyData - ICC Profile Color Space Type Signature. 149 */ 150 public static final int icSigCmyData = 1129142560; 151 152 /** 153 * The Constant icSigSpace2CLR - ICC Profile Color Space Type Signature. 154 */ 155 public static final int icSigSpace2CLR = 843271250; 156 157 /** 158 * The Constant icSigSpace3CLR - ICC Profile Color Space Type Signature. 159 */ 160 public static final int icSigSpace3CLR = 860048466; 161 162 /** 163 * The Constant icSigSpace4CLR - ICC Profile Color Space Type Signature. 164 */ 165 public static final int icSigSpace4CLR = 876825682; 166 167 /** 168 * The Constant icSigSpace5CLR - ICC Profile Color Space Type Signature. 169 */ 170 public static final int icSigSpace5CLR = 893602898; 171 172 /** 173 * The Constant icSigSpace6CLR - ICC Profile Color Space Type Signature. 174 */ 175 public static final int icSigSpace6CLR = 910380114; 176 177 /** 178 * The Constant icSigSpace7CLR - ICC Profile Color Space Type Signature. 179 */ 180 public static final int icSigSpace7CLR = 927157330; 181 182 /** 183 * The Constant icSigSpace8CLR - ICC Profile Color Space Type Signature. 184 */ 185 public static final int icSigSpace8CLR = 943934546; 186 187 /** 188 * The Constant icSigSpace9CLR - ICC Profile Color Space Type Signature. 189 */ 190 public static final int icSigSpace9CLR = 960711762; 191 192 /** 193 * The Constant icSigSpaceACLR - ICC Profile Color Space Type Signature. 194 */ 195 public static final int icSigSpaceACLR = 1094929490; 196 197 /** 198 * The Constant icSigSpaceBCLR - ICC Profile Color Space Type Signature. 199 */ 200 public static final int icSigSpaceBCLR = 1111706706; 201 202 /** 203 * The Constant icSigSpaceCCLR - ICC Profile Color Space Type Signature. 204 */ 205 public static final int icSigSpaceCCLR = 1128483922; 206 207 /** 208 * The Constant icSigSpaceDCLR - ICC Profile Color Space Type Signature. 209 */ 210 public static final int icSigSpaceDCLR = 1145261138; 211 212 /** 213 * The Constant icSigSpaceECLR - ICC Profile Color Space Type Signature. 214 */ 215 public static final int icSigSpaceECLR = 1162038354; 216 217 /** 218 * The Constant icSigSpaceFCLR - ICC Profile Color Space Type Signature. 219 */ 220 public static final int icSigSpaceFCLR = 1178815570; 221 222 /** 223 * The Constant icSigInputClass - ICC Profile Class Signature. 224 */ 225 public static final int icSigInputClass = 1935896178; 226 227 /** 228 * The Constant icSigDisplayClass - ICC Profile Class Signature. 229 */ 230 public static final int icSigDisplayClass = 1835955314; 231 232 /** 233 * The Constant icSigOutputClass - ICC Profile Class Signature. 234 */ 235 public static final int icSigOutputClass = 1886549106; 236 237 /** 238 * The Constant icSigLinkClass - ICC Profile Class Signature. 239 */ 240 public static final int icSigLinkClass = 1818848875; 241 242 /** 243 * The Constant icSigAbstractClass - ICC Profile Class Signature. 244 */ 245 public static final int icSigAbstractClass = 1633842036; 246 247 /** 248 * The Constant icSigColorantOrderTag - ICC Profile Tag Signature. 249 */ 250 public static final int icSigColorantOrderTag = 1668051567; 251 252 /** 253 * The Constant icSigColorantTableTag - ICC Profile Tag Signature. 254 */ 255 public static final int icSigColorantTableTag = 1668051572; 256 257 /** 258 * The Constant icSigColorSpaceClass - ICC Profile Tag Signature. 259 */ 260 public static final int icSigColorSpaceClass = 1936744803; 261 262 /** 263 * The Constant icSigNamedColorClass - ICC Profile Tag Signature. 264 */ 265 public static final int icSigNamedColorClass = 1852662636; 266 267 /** 268 * The Constant icPerceptual - ICC Profile Rendering Intent. 269 */ 270 public static final int icPerceptual = 0; 271 272 /** 273 * The Constant icRelativeColorimetric - ICC Profile Rendering Intent. 274 */ 275 public static final int icRelativeColorimetric = 1; 276 277 /** 278 * The Constant icSaturation - ICC Profile Rendering Intent. 279 */ 280 public static final int icSaturation = 2; 281 282 /** 283 * The Constant icAbsoluteColorimetric - ICC Profile Rendering Intent. 284 */ 285 public static final int icAbsoluteColorimetric = 3; 286 287 /** 288 * The Constant icSigHead - ICC Profile Tag Signature. 289 */ 290 public static final int icSigHead = 1751474532; 291 292 /** 293 * The Constant icSigAToB0Tag - ICC Profile Tag Signature. 294 */ 295 public static final int icSigAToB0Tag = 1093812784; 296 297 /** 298 * The Constant icSigAToB1Tag - ICC Profile Tag Signature. 299 */ 300 public static final int icSigAToB1Tag = 1093812785; 301 302 /** 303 * The Constant icSigAToB2Tag - ICC Profile Tag Signature. 304 */ 305 public static final int icSigAToB2Tag = 1093812786; 306 307 /** 308 * The Constant icSigBlueColorantTag - ICC Profile Tag Signature. 309 */ 310 public static final int icSigBlueColorantTag = 1649957210; 311 312 /** 313 * The Constant icSigBlueMatrixColumnTag - ICC Profile Tag Signature. 314 */ 315 public static final int icSigBlueMatrixColumnTag = 1649957210; 316 317 /** 318 * The Constant icSigBlueTRCTag - ICC Profile Tag Signature. 319 */ 320 public static final int icSigBlueTRCTag = 1649693251; 321 322 /** 323 * The Constant icSigBToA0Tag - ICC Profile Tag Signature. 324 */ 325 public static final int icSigBToA0Tag = 1110589744; 326 327 /** 328 * The Constant icSigBToA1Tag - ICC Profile Tag Signature. 329 */ 330 public static final int icSigBToA1Tag = 1110589745; 331 332 /** 333 * The Constant icSigBToA2Tag - ICC Profile Tag Signature. 334 */ 335 public static final int icSigBToA2Tag = 1110589746; 336 337 /** 338 * The Constant icSigCalibrationDateTimeTag - ICC Profile Tag Signature. 339 */ 340 public static final int icSigCalibrationDateTimeTag = 1667329140; 341 342 /** 343 * The Constant icSigCharTargetTag - ICC Profile Tag Signature. 344 */ 345 public static final int icSigCharTargetTag = 1952543335; 346 347 /** 348 * The Constant icSigCopyrightTag - ICC Profile Tag Signature. 349 */ 350 public static final int icSigCopyrightTag = 1668313716; 351 352 /** 353 * The Constant icSigCrdInfoTag - ICC Profile Tag Signature. 354 */ 355 public static final int icSigCrdInfoTag = 1668441193; 356 357 /** 358 * The Constant icSigDeviceMfgDescTag - ICC Profile Tag Signature. 359 */ 360 public static final int icSigDeviceMfgDescTag = 1684893284; 361 362 /** 363 * The Constant icSigDeviceModelDescTag - ICC Profile Tag Signature. 364 */ 365 public static final int icSigDeviceModelDescTag = 1684890724; 366 367 /** 368 * The Constant icSigDeviceSettingsTag - ICC Profile Tag Signature. 369 */ 370 public static final int icSigDeviceSettingsTag = 1684371059; 371 372 /** 373 * The Constant icSigGamutTag - ICC Profile Tag Signature. 374 */ 375 public static final int icSigGamutTag = 1734438260; 376 377 /** 378 * The Constant icSigGrayTRCTag - ICC Profile Tag Signature. 379 */ 380 public static final int icSigGrayTRCTag = 1800688195; 381 382 /** 383 * The Constant icSigGreenColorantTag - ICC Profile Tag Signature. 384 */ 385 public static final int icSigGreenColorantTag = 1733843290; 386 387 /** 388 * The Constant icSigGreenMatrixColumnTag - ICC Profile Tag Signature. 389 */ 390 public static final int icSigGreenMatrixColumnTag = 1733843290; 391 392 /** 393 * The Constant icSigGreenTRCTag - ICC Profile Tag Signature. 394 */ 395 public static final int icSigGreenTRCTag = 1733579331; 396 397 /** 398 * The Constant icSigLuminanceTag - ICC Profile Tag Signature. 399 */ 400 public static final int icSigLuminanceTag = 1819635049; 401 402 /** 403 * The Constant icSigMeasurementTag - ICC Profile Tag Signature. 404 */ 405 public static final int icSigMeasurementTag = 1835360627; 406 407 /** 408 * The Constant icSigMediaBlackPointTag - ICC Profile Tag Signature. 409 */ 410 public static final int icSigMediaBlackPointTag = 1651208308; 411 412 /** 413 * The Constant icSigMediaWhitePointTag - ICC Profile Tag Signature. 414 */ 415 public static final int icSigMediaWhitePointTag = 2004119668; 416 417 /** 418 * The Constant icSigNamedColor2Tag - ICC Profile Tag Signature. 419 */ 420 public static final int icSigNamedColor2Tag = 1852009522; 421 422 /** 423 * The Constant icSigOutputResponseTag - ICC Profile Tag Signature. 424 */ 425 public static final int icSigOutputResponseTag = 1919251312; 426 427 /** 428 * The Constant icSigPreview0Tag - ICC Profile Tag Signature. 429 */ 430 public static final int icSigPreview0Tag = 1886545200; 431 432 /** 433 * The Constant icSigPreview1Tag - ICC Profile Tag Signature. 434 */ 435 public static final int icSigPreview1Tag = 1886545201; 436 437 /** 438 * The Constant icSigPreview2Tag - ICC Profile Tag Signature. 439 */ 440 public static final int icSigPreview2Tag = 1886545202; 441 442 /** 443 * The Constant icSigProfileDescriptionTag - ICC Profile Tag Signature. 444 */ 445 public static final int icSigProfileDescriptionTag = 1684370275; 446 447 /** 448 * The Constant icSigProfileSequenceDescTag - ICC Profile Tag Signature. 449 */ 450 public static final int icSigProfileSequenceDescTag = 1886610801; 451 452 /** 453 * The Constant icSigPs2CRD0Tag - ICC Profile Tag Signature. 454 */ 455 public static final int icSigPs2CRD0Tag = 1886610480; 456 457 /** 458 * The Constant icSigPs2CRD1Tag - ICC Profile Tag Signature. 459 */ 460 public static final int icSigPs2CRD1Tag = 1886610481; 461 462 /** 463 * The Constant icSigPs2CRD2Tag - ICC Profile Tag Signature. 464 */ 465 public static final int icSigPs2CRD2Tag = 1886610482; 466 467 /** 468 * The Constant icSigPs2CRD3Tag - ICC Profile Tag Signature. 469 */ 470 public static final int icSigPs2CRD3Tag = 1886610483; 471 472 /** 473 * The Constant icSigPs2CSATag - ICC Profile Tag Signature. 474 */ 475 public static final int icSigPs2CSATag = 1886597747; 476 477 /** 478 * The Constant icSigPs2RenderingIntentTag - ICC Profile Tag Signature. 479 */ 480 public static final int icSigPs2RenderingIntentTag = 1886597737; 481 482 /** 483 * The Constant icSigRedColorantTag - ICC Profile Tag Signature. 484 */ 485 public static final int icSigRedColorantTag = 1918392666; 486 487 /** 488 * The Constant icSigRedMatrixColumnTag - ICC Profile Tag Signature. 489 */ 490 public static final int icSigRedMatrixColumnTag = 1918392666; 491 492 /** 493 * The Constant icSigRedTRCTag - ICC Profile Tag Signature. 494 */ 495 public static final int icSigRedTRCTag = 1918128707; 496 497 /** 498 * The Constant icSigScreeningDescTag - ICC Profile Tag Signature. 499 */ 500 public static final int icSigScreeningDescTag = 1935897188; 501 502 /** 503 * The Constant icSigScreeningTag - ICC Profile Tag Signature. 504 */ 505 public static final int icSigScreeningTag = 1935897198; 506 507 /** 508 * The Constant icSigTechnologyTag - ICC Profile Tag Signature. 509 */ 510 public static final int icSigTechnologyTag = 1952801640; 511 512 /** 513 * The Constant icSigUcrBgTag - ICC Profile Tag Signature. 514 */ 515 public static final int icSigUcrBgTag = 1650877472; 516 517 /** 518 * The Constant icSigViewingCondDescTag - ICC Profile Tag Signature. 519 */ 520 public static final int icSigViewingCondDescTag = 1987405156; 521 522 /** 523 * The Constant icSigViewingConditionsTag - ICC Profile Tag Signature. 524 */ 525 public static final int icSigViewingConditionsTag = 1986618743; 526 527 /** 528 * The Constant icSigChromaticAdaptationTag - ICC Profile Tag Signature. 529 */ 530 public static final int icSigChromaticAdaptationTag = 1667785060; 531 532 /** 533 * The Constant icSigChromaticityTag - ICC Profile Tag Signature. 534 */ 535 public static final int icSigChromaticityTag = 1667789421; 536 537 /** 538 * The Constant icHdrSize - ICC Profile Header Location. 539 */ 540 public static final int icHdrSize = 0; 541 542 /** 543 * The Constant icHdrCmmId - ICC Profile Header Location. 544 */ 545 public static final int icHdrCmmId = 4; 546 547 /** 548 * The Constant icHdrVersion - ICC Profile Header Location. 549 */ 550 public static final int icHdrVersion = 8; 551 552 /** 553 * The Constant icHdrDeviceClass - ICC Profile Header Location. 554 */ 555 public static final int icHdrDeviceClass = 12; 556 557 /** 558 * The Constant icHdrColorSpace - ICC Profile Header Location. 559 */ 560 public static final int icHdrColorSpace = 16; 561 562 /** 563 * The Constant icHdrPcs - ICC Profile Header Location. 564 */ 565 public static final int icHdrPcs = 20; 566 567 /** 568 * The Constant icHdrDate - ICC Profile Header Location. 569 */ 570 public static final int icHdrDate = 24; 571 572 /** 573 * The Constant icHdrMagic - ICC Profile Header Location. 574 */ 575 public static final int icHdrMagic = 36; 576 577 /** 578 * The Constant icHdrPlatform - ICC Profile Header Location. 579 */ 580 public static final int icHdrPlatform = 40; 581 582 /** 583 * The Constant icHdrProfileID - ICC Profile Header Location. 584 */ 585 public static final int icHdrProfileID = 84; 586 587 /** 588 * The Constant icHdrFlags - ICC Profile Header Location. 589 */ 590 public static final int icHdrFlags = 44; 591 592 /** 593 * The Constant icHdrManufacturer - ICC Profile Header Location. 594 */ 595 public static final int icHdrManufacturer = 48; 596 597 /** 598 * The Constant icHdrModel - ICC Profile Header Location. 599 */ 600 public static final int icHdrModel = 52; 601 602 /** 603 * The Constant icHdrAttributes - ICC Profile Header Location. 604 */ 605 public static final int icHdrAttributes = 56; 606 607 /** 608 * The Constant icHdrRenderingIntent - ICC Profile Header Location. 609 */ 610 public static final int icHdrRenderingIntent = 64; 611 612 /** 613 * The Constant icHdrIlluminant - ICC Profile Header Location. 614 */ 615 public static final int icHdrIlluminant = 68; 616 617 /** 618 * The Constant icHdrCreator - ICC Profile Header Location. 619 */ 620 public static final int icHdrCreator = 80; 621 622 /** 623 * The Constant icICCAbsoluteColorimetric - ICC Profile Rendering Intent. 624 */ 625 public static final int icICCAbsoluteColorimetric = 3; 626 627 /** 628 * The Constant icMediaRelativeColorimetric - ICC Profile Rendering Intent. 629 */ 630 public static final int icMediaRelativeColorimetric = 1; 631 632 /** 633 * The Constant icTagType - ICC Profile Constant. 634 */ 635 public static final int icTagType = 0; 636 637 /** 638 * The Constant icTagReserved - ICC Profile Constant. 639 */ 640 public static final int icTagReserved = 4; 641 642 /** 643 * The Constant icCurveCount - ICC Profile Constant. 644 */ 645 public static final int icCurveCount = 8; 646 647 /** 648 * The Constant icCurveData - ICC Profile Constant. 649 */ 650 public static final int icCurveData = 12; 651 652 /** 653 * The Constant icXYZNumberX - ICC Profile Constant. 654 */ 655 public static final int icXYZNumberX = 8; 656 657 /** 658 * Size of a profile header. 659 */ 660 private static final int headerSize = 128; 661 662 /** 663 * header magic number. 664 */ 665 private static final int headerMagicNumber = 0x61637370; 666 667 // Cache of predefined profiles 668 /** 669 * The s rgb profile. 670 */ 671 private static ICC_Profile sRGBProfile; 672 673 /** 674 * The xyz profile. 675 */ 676 private static ICC_Profile xyzProfile; 677 678 /** 679 * The gray profile. 680 */ 681 private static ICC_Profile grayProfile; 682 683 /** 684 * The pycc profile. 685 */ 686 private static ICC_Profile pyccProfile; 687 688 /** 689 * The linear rgb profile. 690 */ 691 private static ICC_Profile linearRGBProfile; 692 693 /** 694 * Handle to the current profile. 695 */ 696 private transient long profileHandle = 0; 697 698 /** 699 * If handle is used by another class this object is not responsible for 700 * closing profile. 701 */ 702 private transient boolean handleStolen = false; 703 704 /** 705 * Cached header data. 706 */ 707 private transient byte[] headerData = null; 708 709 /** 710 * Serialization support. 711 */ 712 private transient ICC_Profile openedProfileObject; 713 714 /** 715 * Instantiates a new ICC profile with the given data. 716 * 717 * @param data 718 * the data. 719 */ 720 private ICC_Profile(byte[] data) { 721 profileHandle = NativeCMM.cmmOpenProfile(data); 722 NativeCMM.addHandle(this, profileHandle); 723 } 724 725 /** 726 * Used to instantiate dummy ICC_ProfileStub objects. 727 */ 728 ICC_Profile() { 729 } 730 731 /** 732 * Used to instantiate subclasses (ICC_ProfileGrey and ICC_ProfileRGB). 733 * 734 * @param profileHandle 735 * - should be valid handle to opened color profile 736 */ 737 ICC_Profile(long profileHandle) { 738 this.profileHandle = profileHandle; 739 // A new object reference, need to add it. 740 NativeCMM.addHandle(this, profileHandle); 741 } 742 743 /** 744 * Writes the ICC_Profile to a file with the specified name. 745 * 746 * @param fileName 747 * the file name. 748 * @throws IOException 749 * if an I/O exception has occurred during writing or opening 750 * the file. 751 */ 752 public void write(String fileName) throws IOException { 753 FileOutputStream oStream = new FileOutputStream(fileName); 754 oStream.write(getData()); 755 oStream.close(); 756 } 757 758 /** 759 * Serializable implementation. 760 * 761 * @param s 762 * the s 763 * @throws IOException 764 * Signals that an I/O exception has occurred. 765 */ 766 private void writeObject(ObjectOutputStream s) throws IOException { 767 s.defaultWriteObject(); 768 s.writeObject(null); 769 s.writeObject(getData()); 770 } 771 772 /** 773 * Serializable implementation. 774 * 775 * @param s 776 * the s 777 * @throws IOException 778 * Signals that an I/O exception has occurred. 779 * @throws ClassNotFoundException 780 * the class not found exception 781 */ 782 private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { 783 s.defaultReadObject(); 784 String colorSpaceStr = (String)s.readObject(); 785 byte[] data = (byte[])s.readObject(); 786 787 if (colorSpaceStr != null) { 788 if (colorSpaceStr.equals("CS_sRGB")) { //$NON-NLS-1$ 789 openedProfileObject = getInstance(ColorSpace.CS_sRGB); 790 } else if (colorSpaceStr.equals("CS_GRAY")) { //$NON-NLS-1$ 791 openedProfileObject = getInstance(ColorSpace.CS_GRAY); 792 } else if (colorSpaceStr.equals("CS_LINEAR_RGB")) { //$NON-NLS-1$ 793 openedProfileObject = getInstance(ColorSpace.CS_LINEAR_RGB); 794 } else if (colorSpaceStr.equals("CS_CIEXYZ")) { //$NON-NLS-1$ 795 openedProfileObject = getInstance(ColorSpace.CS_CIEXYZ); 796 } else if (colorSpaceStr.equals("CS_PYCC")) { //$NON-NLS-1$ 797 openedProfileObject = getInstance(ColorSpace.CS_PYCC); 798 } else { 799 openedProfileObject = ICC_Profile.getInstance(data); 800 } 801 } else { 802 openedProfileObject = ICC_Profile.getInstance(data); 803 } 804 } 805 806 /** 807 * Resolves instances being deserialized into instances registered with CMM. 808 * 809 * @return ICC_Profile object for profile registered with CMM. 810 * @throws ObjectStreamException 811 * if there is an error in the serialized files or during the 812 * process of reading them. 813 */ 814 protected Object readResolve() throws ObjectStreamException { 815 return openedProfileObject; 816 } 817 818 /** 819 * Writes the ICC_Profile to an OutputStream. 820 * 821 * @param s 822 * the OutputStream. 823 * @throws IOException 824 * signals that an I/O exception has occurred during writing or 825 * opening OutputStream. 826 */ 827 public void write(OutputStream s) throws IOException { 828 s.write(getData()); 829 } 830 831 /** 832 * Sets a tagged data element in the profile from a byte array. 833 * 834 * @param tagSignature 835 * the ICC tag signature for the data element to be set. 836 * @param tagData 837 * the data to be set for the specified tag signature. 838 */ 839 public void setData(int tagSignature, byte[] tagData) { 840 NativeCMM.cmmSetProfileElement(profileHandle, tagSignature, tagData); 841 // Remove cached header data if header is modified 842 if (tagSignature == icSigHead) { 843 headerData = null; 844 } 845 } 846 847 /** 848 * Gets a tagged data element from the profile as a byte array. Elements are 849 * identified by tag signatures as defined in the ICC specification. 850 * 851 * @param tagSignature 852 * the ICC tag signature for the data element to get. 853 * @return a byte array that contains the tagged data element. 854 */ 855 public byte[] getData(int tagSignature) { 856 int tagSize = 0; 857 try { 858 tagSize = NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature); 859 } catch (CMMException e) { 860 // We'll get this exception if there's no element with 861 // the specified tag signature 862 return null; 863 } 864 865 byte[] data = new byte[tagSize]; 866 NativeCMM.cmmGetProfileElement(profileHandle, tagSignature, data); 867 return data; 868 } 869 870 /** 871 * Gets a data byte array of this ICC_Profile. 872 * 873 * @return a byte array that contains the ICC Profile data. 874 */ 875 public byte[] getData() { 876 int profileSize = NativeCMM.cmmGetProfileSize(profileHandle); 877 byte[] data = new byte[profileSize]; 878 NativeCMM.cmmGetProfile(profileHandle, data); 879 return data; 880 } 881 882 /** 883 * Frees the resources associated with an ICC_Profile object. 884 */ 885 @Override 886 protected void finalize() { 887 if (profileHandle != 0 && !handleStolen) { 888 NativeCMM.cmmCloseProfile(profileHandle); 889 } 890 891 // Always remove because key no more exist 892 // when object is destroyed 893 NativeCMM.removeHandle(this); 894 } 895 896 /** 897 * Gets the profile class. 898 * 899 * @return the profile class constant. 900 */ 901 public int getProfileClass() { 902 int deviceClassSignature = getIntFromHeader(icHdrDeviceClass); 903 904 switch (deviceClassSignature) { 905 case icSigColorSpaceClass: 906 return CLASS_COLORSPACECONVERSION; 907 case icSigDisplayClass: 908 return CLASS_DISPLAY; 909 case icSigOutputClass: 910 return CLASS_OUTPUT; 911 case icSigInputClass: 912 return CLASS_INPUT; 913 case icSigLinkClass: 914 return CLASS_DEVICELINK; 915 case icSigAbstractClass: 916 return CLASS_ABSTRACT; 917 case icSigNamedColorClass: 918 return CLASS_NAMEDCOLOR; 919 default: 920 } 921 922 // Not an ICC profile class 923 // awt.15F=Profile class does not comply with ICC specification 924 throw new IllegalArgumentException(Messages.getString("awt.15F")); //$NON-NLS-1$ 925 926 } 927 928 /** 929 * Gets the color space type of the Profile Connection Space (PCS). 930 * 931 * @return the PCS type. 932 */ 933 public int getPCSType() { 934 return csFromSignature(getIntFromHeader(icHdrPcs)); 935 } 936 937 /** 938 * Gets the number of components of this ICC Profile. 939 * 940 * @return the number of components of this ICC Profile. 941 */ 942 public int getNumComponents() { 943 switch (getIntFromHeader(icHdrColorSpace)) { 944 // The most common cases go first to increase speed 945 case icSigRgbData: 946 case icSigXYZData: 947 case icSigLabData: 948 return 3; 949 case icSigCmykData: 950 return 4; 951 // Then all other 952 case icSigGrayData: 953 return 1; 954 case icSigSpace2CLR: 955 return 2; 956 case icSigYCbCrData: 957 case icSigLuvData: 958 case icSigYxyData: 959 case icSigHlsData: 960 case icSigHsvData: 961 case icSigCmyData: 962 case icSigSpace3CLR: 963 return 3; 964 case icSigSpace4CLR: 965 return 4; 966 case icSigSpace5CLR: 967 return 5; 968 case icSigSpace6CLR: 969 return 6; 970 case icSigSpace7CLR: 971 return 7; 972 case icSigSpace8CLR: 973 return 8; 974 case icSigSpace9CLR: 975 return 9; 976 case icSigSpaceACLR: 977 return 10; 978 case icSigSpaceBCLR: 979 return 11; 980 case icSigSpaceCCLR: 981 return 12; 982 case icSigSpaceDCLR: 983 return 13; 984 case icSigSpaceECLR: 985 return 14; 986 case icSigSpaceFCLR: 987 return 15; 988 default: 989 } 990 991 // awt.160=Color space doesn't comply with ICC specification 992 throw new ProfileDataException(Messages.getString("awt.160") //$NON-NLS-1$ 993 ); 994 } 995 996 /** 997 * Gets the minor version of this ICC profile. 998 * 999 * @return the minor version of this ICC profile. 1000 */ 1001 public int getMinorVersion() { 1002 return getByteFromHeader(icHdrVersion + 1); 1003 } 1004 1005 /** 1006 * Gets the major version of this ICC profile. 1007 * 1008 * @return the major version of this ICC profile. 1009 */ 1010 public int getMajorVersion() { 1011 return getByteFromHeader(icHdrVersion); 1012 } 1013 1014 /** 1015 * Gets the color space type of this ICC_Profile. 1016 * 1017 * @return the color space type. 1018 */ 1019 public int getColorSpaceType() { 1020 return csFromSignature(getIntFromHeader(icHdrColorSpace)); 1021 } 1022 1023 /** 1024 * Tries to open the file at the specified path. Path entries can be divided 1025 * by a separator character. 1026 * 1027 * @param path 1028 * the path to the file. 1029 * @param fileName 1030 * the file name. 1031 * @return the input stream to read the file. 1032 */ 1033 private static FileInputStream tryPath(String path, String fileName) { 1034 FileInputStream fiStream = null; 1035 1036 if (path == null) { 1037 return null; 1038 } 1039 1040 StringTokenizer st = new StringTokenizer(path, File.pathSeparator); 1041 1042 while (st.hasMoreTokens()) { 1043 String pathEntry = st.nextToken(); 1044 try { 1045 fiStream = new FileInputStream(pathEntry + File.separatorChar + fileName); 1046 if (fiStream != null) { 1047 return fiStream; 1048 } 1049 } catch (FileNotFoundException e) { 1050 } 1051 } 1052 1053 return fiStream; 1054 } 1055 1056 /** 1057 * Gets the single instance of ICC_Profile from data in the specified file. 1058 * 1059 * @param fileName 1060 * the specified name of file with ICC profile data. 1061 * @return single instance of ICC_Profile. 1062 * @throws IOException 1063 * signals that an I/O error occurred while reading the file or 1064 * the file does not exist. 1065 */ 1066 public static ICC_Profile getInstance(String fileName) throws IOException { 1067 final String fName = fileName; // to use in the privileged block 1068 1069 FileInputStream fiStream = (FileInputStream)AccessController 1070 .doPrivileged(new PrivilegedAction<FileInputStream>() { 1071 public FileInputStream run() { 1072 FileInputStream fiStream = null; 1073 1074 // Open absolute path 1075 try { 1076 fiStream = new FileInputStream(fName); 1077 if (fiStream != null) { 1078 return fiStream; 1079 } 1080 } catch (FileNotFoundException e) { 1081 } 1082 1083 // Check java.iccprofile.path entries 1084 fiStream = tryPath(System.getProperty("java.iccprofile.path"), fName); //$NON-NLS-1$ 1085 if (fiStream != null) { 1086 return fiStream; 1087 } 1088 1089 // Check java.class.path entries 1090 fiStream = tryPath(System.getProperty("java.class.path"), fName); //$NON-NLS-1$ 1091 if (fiStream != null) { 1092 return fiStream; 1093 } 1094 1095 // Check directory with java sample profiles 1096 String home = System.getProperty("java.home"); //$NON-NLS-1$ 1097 if (home != null) { 1098 fiStream = tryPath(home + File.separatorChar 1099 + "lib" + File.separatorChar + "cmm", fName //$NON-NLS-1$ //$NON-NLS-2$ 1100 ); 1101 } 1102 1103 return fiStream; 1104 } 1105 }); 1106 1107 if (fiStream == null) { 1108 // awt.161=Unable to open file {0} 1109 throw new IOException(Messages.getString("awt.161", fileName)); //$NON-NLS-1$ 1110 } 1111 1112 ICC_Profile pf = getInstance(fiStream); 1113 fiStream.close(); 1114 return pf; 1115 } 1116 1117 /** 1118 * Gets the single instance of ICC_Profile with data in the specified 1119 * InputStream. 1120 * 1121 * @param s 1122 * the InputStream with ICC profile data. 1123 * @return single instance of ICC_Profile. 1124 * @throws IOException 1125 * if an I/O exception has occurred during reading from 1126 * InputStream. 1127 * @throws IllegalArgumentException 1128 * if the file does not contain valid ICC Profile data. 1129 */ 1130 public static ICC_Profile getInstance(InputStream s) throws IOException { 1131 byte[] header = new byte[headerSize]; 1132 // awt.162=Invalid ICC Profile Data 1133 String invalidDataMessage = Messages.getString("awt.162"); //$NON-NLS-1$ 1134 1135 // Get header from the input stream 1136 if (s.read(header) != headerSize) { 1137 throw new IllegalArgumentException(invalidDataMessage); 1138 } 1139 1140 // Check the profile data for consistency 1141 if (ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrMagic) != headerMagicNumber) { 1142 throw new IllegalArgumentException(invalidDataMessage); 1143 } 1144 1145 // Get profile size from header, create an array for profile data 1146 int profileSize = ICC_ProfileHelper.getBigEndianFromByteArray(header, icHdrSize); 1147 byte[] profileData = new byte[profileSize]; 1148 1149 // Copy header into it 1150 System.arraycopy(header, 0, profileData, 0, headerSize); 1151 1152 // Read the profile itself 1153 if (s.read(profileData, headerSize, profileSize - headerSize) != profileSize - headerSize) { 1154 throw new IllegalArgumentException(invalidDataMessage); 1155 } 1156 1157 return getInstance(profileData); 1158 } 1159 1160 /** 1161 * Gets the single instance of ICC_Profile from the specified data in a byte 1162 * array. 1163 * 1164 * @param data 1165 * the byte array of ICC profile. 1166 * @return single instance of ICC_Profile from the specified data in a byte 1167 * array. 1168 * @throws IllegalArgumentException 1169 * if the file does not contain valid ICC Profile data. 1170 */ 1171 public static ICC_Profile getInstance(byte[] data) { 1172 ICC_Profile res = null; 1173 1174 try { 1175 res = new ICC_Profile(data); 1176 } catch (CMMException e) { 1177 // awt.162=Invalid ICC Profile Data 1178 throw new IllegalArgumentException(Messages.getString("awt.162")); //$NON-NLS-1$ 1179 } 1180 1181 if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$ 1182 try { 1183 if (res.getColorSpaceType() == ColorSpace.TYPE_RGB 1184 && res.getDataSize(icSigMediaWhitePointTag) > 0 1185 && res.getDataSize(icSigRedColorantTag) > 0 1186 && res.getDataSize(icSigGreenColorantTag) > 0 1187 && res.getDataSize(icSigBlueColorantTag) > 0 1188 && res.getDataSize(icSigRedTRCTag) > 0 1189 && res.getDataSize(icSigGreenTRCTag) > 0 1190 && res.getDataSize(icSigBlueTRCTag) > 0) { 1191 res = new ICC_ProfileRGB(res.getProfileHandle()); 1192 } else if (res.getColorSpaceType() == ColorSpace.TYPE_GRAY 1193 && res.getDataSize(icSigMediaWhitePointTag) > 0 1194 && res.getDataSize(icSigGrayTRCTag) > 0) { 1195 res = new ICC_ProfileGray(res.getProfileHandle()); 1196 } 1197 1198 } catch (CMMException e) { /* return res in this case */ 1199 } 1200 } 1201 1202 return res; 1203 } 1204 1205 /** 1206 * Gets the single instance of ICC_Profile with the specific color space 1207 * defined by the ColorSpace class: CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ, 1208 * CS_PYCC, CS_GRAY. 1209 * 1210 * @param cspace 1211 * the type of color space defined in the ColorSpace class. 1212 * @return single instance of ICC_Profile. 1213 * @throws IllegalArgumentException 1214 * is not one of the defined color space types. 1215 */ 1216 public static ICC_Profile getInstance(int cspace) { 1217 try { 1218 switch (cspace) { 1219 1220 case ColorSpace.CS_sRGB: 1221 if (sRGBProfile == null) { 1222 sRGBProfile = getInstance("sRGB.pf"); //$NON-NLS-1$ 1223 } 1224 return sRGBProfile; 1225 1226 case ColorSpace.CS_CIEXYZ: 1227 if (xyzProfile == null) { 1228 xyzProfile = getInstance("CIEXYZ.pf"); //$NON-NLS-1$ 1229 } 1230 return xyzProfile; 1231 1232 case ColorSpace.CS_GRAY: 1233 if (grayProfile == null) { 1234 grayProfile = getInstance("GRAY.pf"); //$NON-NLS-1$ 1235 } 1236 return grayProfile; 1237 1238 case ColorSpace.CS_PYCC: 1239 if (pyccProfile == null) { 1240 pyccProfile = getInstance("PYCC.pf"); //$NON-NLS-1$ 1241 } 1242 return pyccProfile; 1243 1244 case ColorSpace.CS_LINEAR_RGB: 1245 if (linearRGBProfile == null) { 1246 linearRGBProfile = getInstance("LINEAR_RGB.pf"); //$NON-NLS-1$ 1247 } 1248 return linearRGBProfile; 1249 } 1250 1251 } catch (IOException e) { 1252 // awt.163=Can't open color profile 1253 throw new IllegalArgumentException(Messages.getString("Can't open color profile")); //$NON-NLS-1$ 1254 } 1255 1256 // awt.164=Not a predefined color space 1257 throw new IllegalArgumentException(Messages.getString("Not a predefined color space")); //$NON-NLS-1$ 1258 } 1259 1260 /** 1261 * Reads an integer from the profile header at the specified position. 1262 * 1263 * @param idx 1264 * - offset in bytes from the beginning of the header 1265 * @return the integer value from header 1266 */ 1267 private int getIntFromHeader(int idx) { 1268 if (headerData == null) { 1269 headerData = getData(icSigHead); 1270 } 1271 1272 return ((headerData[idx] & 0xFF) << 24) | ((headerData[idx + 1] & 0xFF) << 16) 1273 | ((headerData[idx + 2] & 0xFF) << 8) | ((headerData[idx + 3] & 0xFF)); 1274 } 1275 1276 /** 1277 * Reads byte from the profile header at the specified position. 1278 * 1279 * @param idx 1280 * - offset in bytes from the beginning of the header 1281 * @return the byte from header 1282 */ 1283 private byte getByteFromHeader(int idx) { 1284 if (headerData == null) { 1285 headerData = getData(icSigHead); 1286 } 1287 1288 return headerData[idx]; 1289 } 1290 1291 /** 1292 * Converts ICC color space signature to the java predefined color space 1293 * type. 1294 * 1295 * @param signature 1296 * the signature 1297 * @return the int 1298 */ 1299 private int csFromSignature(int signature) { 1300 switch (signature) { 1301 case icSigRgbData: 1302 return ColorSpace.TYPE_RGB; 1303 case icSigXYZData: 1304 return ColorSpace.TYPE_XYZ; 1305 case icSigCmykData: 1306 return ColorSpace.TYPE_CMYK; 1307 case icSigLabData: 1308 return ColorSpace.TYPE_Lab; 1309 case icSigGrayData: 1310 return ColorSpace.TYPE_GRAY; 1311 case icSigHlsData: 1312 return ColorSpace.TYPE_HLS; 1313 case icSigLuvData: 1314 return ColorSpace.TYPE_Luv; 1315 case icSigYCbCrData: 1316 return ColorSpace.TYPE_YCbCr; 1317 case icSigYxyData: 1318 return ColorSpace.TYPE_Yxy; 1319 case icSigHsvData: 1320 return ColorSpace.TYPE_HSV; 1321 case icSigCmyData: 1322 return ColorSpace.TYPE_CMY; 1323 case icSigSpace2CLR: 1324 return ColorSpace.TYPE_2CLR; 1325 case icSigSpace3CLR: 1326 return ColorSpace.TYPE_3CLR; 1327 case icSigSpace4CLR: 1328 return ColorSpace.TYPE_4CLR; 1329 case icSigSpace5CLR: 1330 return ColorSpace.TYPE_5CLR; 1331 case icSigSpace6CLR: 1332 return ColorSpace.TYPE_6CLR; 1333 case icSigSpace7CLR: 1334 return ColorSpace.TYPE_7CLR; 1335 case icSigSpace8CLR: 1336 return ColorSpace.TYPE_8CLR; 1337 case icSigSpace9CLR: 1338 return ColorSpace.TYPE_9CLR; 1339 case icSigSpaceACLR: 1340 return ColorSpace.TYPE_ACLR; 1341 case icSigSpaceBCLR: 1342 return ColorSpace.TYPE_BCLR; 1343 case icSigSpaceCCLR: 1344 return ColorSpace.TYPE_CCLR; 1345 case icSigSpaceDCLR: 1346 return ColorSpace.TYPE_DCLR; 1347 case icSigSpaceECLR: 1348 return ColorSpace.TYPE_ECLR; 1349 case icSigSpaceFCLR: 1350 return ColorSpace.TYPE_FCLR; 1351 default: 1352 } 1353 1354 // awt.165=Color space doesn't comply with ICC specification 1355 throw new IllegalArgumentException(Messages.getString("awt.165")); //$NON-NLS-1$ 1356 } 1357 1358 /** 1359 * Gets the profile handle. 1360 * 1361 * @return the profile handle 1362 */ 1363 private long getProfileHandle() { 1364 handleStolen = true; 1365 return profileHandle; 1366 } 1367 1368 /** 1369 * Gets the data size. 1370 * 1371 * @param tagSignature 1372 * the tag signature 1373 * @return the data size 1374 */ 1375 private int getDataSize(int tagSignature) { 1376 return NativeCMM.cmmGetProfileElementSize(profileHandle, tagSignature); 1377 } 1378 1379 /** 1380 * Reads XYZ value from the tag data. 1381 * 1382 * @param tagSignature 1383 * the tag signature 1384 * @return the XYZ value 1385 */ 1386 float[] getXYZValue(int tagSignature) { 1387 float[] res = new float[3]; 1388 byte[] data = getData(tagSignature); 1389 1390 // Convert from ICC s15Fixed16Number type 1391 // 1 (float) = 0x10000 (s15Fixed16Number), 1392 // hence dividing by 0x10000 1393 res[0] = ICC_ProfileHelper.getIntFromByteArray(data, 0) / 65536.f; 1394 res[1] = ICC_ProfileHelper.getIntFromByteArray(data, 4) / 65536.f; 1395 res[2] = ICC_ProfileHelper.getIntFromByteArray(data, 8) / 65536.f; 1396 1397 return res; 1398 } 1399 1400 /** 1401 * Gets the media white point. 1402 * 1403 * @return the media white point. 1404 */ 1405 float[] getMediaWhitePoint() { 1406 return getXYZValue(icSigMediaWhitePointTag); 1407 } 1408 1409 /** 1410 * If TRC is not a table returns gamma via return value and sets dataTRC to 1411 * null. If TRC is a table returns 0 and fills dataTRC with values. 1412 * 1413 * @param tagSignature 1414 * the tag signature 1415 * @param dataTRC 1416 * the data trc 1417 * @return - gamma or zero if TRC is a table 1418 */ 1419 private float getGammaOrTRC(int tagSignature, short[] dataTRC) { 1420 byte[] data = getData(tagSignature); 1421 int trcSize = ICC_ProfileHelper.getIntFromByteArray(data, icCurveCount); 1422 1423 dataTRC = null; 1424 1425 if (trcSize == 0) { 1426 return 1.0f; 1427 } 1428 1429 if (trcSize == 1) { 1430 // Cast from ICC u8Fixed8Number to float 1431 return ICC_ProfileHelper.getShortFromByteArray(data, icCurveData) / 256.f; 1432 } 1433 1434 // TRC is a table 1435 dataTRC = new short[trcSize]; 1436 for (int i = 0, pos = icCurveData; i < trcSize; i++, pos += 2) { 1437 dataTRC[i] = ICC_ProfileHelper.getShortFromByteArray(data, pos); 1438 } 1439 return 0; 1440 } 1441 1442 /** 1443 * Gets the gamma. 1444 * 1445 * @param tagSignature 1446 * the tag signature 1447 * @return the gamma 1448 */ 1449 float getGamma(int tagSignature) { 1450 short[] dataTRC = null; 1451 float gamma = getGammaOrTRC(tagSignature, dataTRC); 1452 1453 if (dataTRC == null) { 1454 return gamma; 1455 } 1456 // awt.166=TRC is not a simple gamma value. 1457 throw new ProfileDataException(Messages.getString("awt.166")); //$NON-NLS-1$ 1458 } 1459 1460 /** 1461 * Gets the TRC. 1462 * 1463 * @param tagSignature 1464 * the tag signature 1465 * @return the tRC 1466 */ 1467 short[] getTRC(int tagSignature) { 1468 short[] dataTRC = null; 1469 getGammaOrTRC(tagSignature, dataTRC); 1470 1471 if (dataTRC == null) { 1472 // awt.167=TRC is a gamma value, not a table. 1473 throw new ProfileDataException(Messages.getString("awt.167")); //$NON-NLS-1$ 1474 } 1475 return dataTRC; 1476 } 1477 } 1478