< prev index next >

src/java.desktop/share/native/liblcms/cmsvirt.c

Print this page




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2017 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 373 }
 374 
 375 // Ink-limiting algorithm
 376 //
 377 //  Sum = C + M + Y + K
 378 //  If Sum > InkLimit
 379 //        Ratio= 1 - (Sum - InkLimit) / (C + M + Y)
 380 //        if Ratio <0
 381 //              Ratio=0
 382 //        endif
 383 //     Else
 384 //         Ratio=1
 385 //     endif
 386 //
 387 //     C = Ratio * C
 388 //     M = Ratio * M
 389 //     Y = Ratio * Y
 390 //     K: Does not change
 391 
 392 static
 393 int InkLimitingSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
 394 {
 395     cmsFloat64Number InkLimit = *(cmsFloat64Number *) Cargo;
 396     cmsFloat64Number SumCMY, SumCMYK, Ratio;
 397 
 398     InkLimit = (InkLimit * 655.35);
 399 
 400     SumCMY   = In[0]  + In[1] + In[2];
 401     SumCMYK  = SumCMY + In[3];
 402 
 403     if (SumCMYK > InkLimit) {
 404 
 405         Ratio = 1 - ((SumCMYK - InkLimit) / SumCMY);
 406         if (Ratio < 0)
 407             Ratio = 0;
 408     }
 409     else Ratio = 1;
 410 
 411     Out[0] = _cmsQuickSaturateWord(In[0] * Ratio);     // C
 412     Out[1] = _cmsQuickSaturateWord(In[1] * Ratio);     // M
 413     Out[2] = _cmsQuickSaturateWord(In[2] * Ratio);     // Y


 624 Error:
 625 
 626     if (LUT != NULL)
 627         cmsPipelineFree(LUT);
 628 
 629     if (hProfile != NULL)
 630         cmsCloseProfile(hProfile);
 631 
 632     return NULL;
 633 }
 634 
 635 
 636 cmsHPROFILE CMSEXPORT cmsCreateXYZProfile(void)
 637 {
 638     return cmsCreateXYZProfileTHR(NULL);
 639 }
 640 
 641 
 642 //sRGB Curves are defined by:
 643 //
 644 //If  R’sRGB,G’sRGB, B’sRGB < 0.04045
 645 //
 646 //    R =  R’sRGB / 12.92
 647 //    G =  G’sRGB / 12.92
 648 //    B =  B’sRGB / 12.92
 649 //
 650 //
 651 //else if  R’sRGB,G’sRGB, B’sRGB >= 0.04045
 652 //
 653 //    R = ((R’sRGB + 0.055) / 1.055)^2.4
 654 //    G = ((G’sRGB + 0.055) / 1.055)^2.4
 655 //    B = ((B’sRGB + 0.055) / 1.055)^2.4
 656 
 657 static
 658 cmsToneCurve* Build_sRGBGamma(cmsContext ContextID)
 659 {
 660     cmsFloat64Number Parameters[5];
 661 
 662     Parameters[0] = 2.4;
 663     Parameters[1] = 1. / 1.055;
 664     Parameters[2] = 0.055 / 1.055;
 665     Parameters[3] = 1. / 12.92;
 666     Parameters[4] = 0.04045;
 667 
 668     return cmsBuildParametricToneCurve(ContextID, 4, Parameters);
 669 }
 670 
 671 // Create the ICC virtual profile for sRGB space
 672 cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
 673 {
 674        cmsCIExyY       D65 = { 0.3127, 0.3290, 1.0 };
 675        cmsCIExyYTRIPLE Rec709Primaries = {


 698 
 699 cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void)
 700 {
 701     return cmsCreate_sRGBProfileTHR(NULL);
 702 }
 703 
 704 
 705 
 706 typedef struct {
 707                 cmsFloat64Number Brightness;
 708                 cmsFloat64Number Contrast;
 709                 cmsFloat64Number Hue;
 710                 cmsFloat64Number Saturation;
 711                 cmsBool          lAdjustWP;
 712                 cmsCIEXYZ WPsrc, WPdest;
 713 
 714 } BCHSWADJUSTS, *LPBCHSWADJUSTS;
 715 
 716 
 717 static
 718 int bchswSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
 719 {
 720     cmsCIELab LabIn, LabOut;
 721     cmsCIELCh LChIn, LChOut;
 722     cmsCIEXYZ XYZ;
 723     LPBCHSWADJUSTS bchsw = (LPBCHSWADJUSTS) Cargo;
 724 
 725 
 726     cmsLabEncoded2Float(&LabIn, In);
 727 
 728 
 729     cmsLab2LCh(&LChIn, &LabIn);
 730 
 731     // Do some adjusts on LCh
 732 
 733     LChOut.L = LChIn.L * bchsw ->Contrast + bchsw ->Brightness;
 734     LChOut.C = LChIn.C + bchsw -> Saturation;
 735     LChOut.h = LChIn.h + bchsw -> Hue;
 736 
 737 
 738     cmsLCh2Lab(&LabOut, &LChOut);


1108 
1109     // Check if is a named color transform
1110     if (mpe != NULL) {
1111 
1112         if (cmsStageType(mpe) == cmsSigNamedColorElemType) {
1113             return CreateNamedColorDevicelink(hTransform);
1114         }
1115     }
1116 
1117     // First thing to do is to get a copy of the transformation
1118     LUT = cmsPipelineDup(xform ->Lut);
1119     if (LUT == NULL) return NULL;
1120 
1121     // Time to fix the Lab2/Lab4 issue.
1122     if ((xform ->EntryColorSpace == cmsSigLabData) && (Version < 4.0)) {
1123 
1124         if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocLabV2ToV4curves(ContextID)))
1125             goto Error;
1126     }
1127 
1128     // On the output side too
1129     if ((xform ->ExitColorSpace) == cmsSigLabData && (Version < 4.0)) {
1130 

1131         if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID)))
1132             goto Error;
1133     }
1134 
1135 
1136     hProfile = cmsCreateProfilePlaceholder(ContextID);
1137     if (!hProfile) goto Error;                    // can't allocate
1138 
1139     cmsSetProfileVersion(hProfile, Version);
1140 
1141     FixColorSpaces(hProfile, xform -> EntryColorSpace, xform -> ExitColorSpace, dwFlags);
1142 
1143     // Optimize the LUT and precalculate a devicelink
1144 
1145     ChansIn  = cmsChannelsOf(xform -> EntryColorSpace);
1146     ChansOut = cmsChannelsOf(xform -> ExitColorSpace);
1147 
1148     ColorSpaceBitsIn  = _cmsLCMScolorSpace(xform -> EntryColorSpace);
1149     ColorSpaceBitsOut = _cmsLCMScolorSpace(xform -> ExitColorSpace);
1150 




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2020 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 373 }
 374 
 375 // Ink-limiting algorithm
 376 //
 377 //  Sum = C + M + Y + K
 378 //  If Sum > InkLimit
 379 //        Ratio= 1 - (Sum - InkLimit) / (C + M + Y)
 380 //        if Ratio <0
 381 //              Ratio=0
 382 //        endif
 383 //     Else
 384 //         Ratio=1
 385 //     endif
 386 //
 387 //     C = Ratio * C
 388 //     M = Ratio * M
 389 //     Y = Ratio * Y
 390 //     K: Does not change
 391 
 392 static
 393 int InkLimitingSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo)
 394 {
 395     cmsFloat64Number InkLimit = *(cmsFloat64Number *) Cargo;
 396     cmsFloat64Number SumCMY, SumCMYK, Ratio;
 397 
 398     InkLimit = (InkLimit * 655.35);
 399 
 400     SumCMY   = In[0]  + In[1] + In[2];
 401     SumCMYK  = SumCMY + In[3];
 402 
 403     if (SumCMYK > InkLimit) {
 404 
 405         Ratio = 1 - ((SumCMYK - InkLimit) / SumCMY);
 406         if (Ratio < 0)
 407             Ratio = 0;
 408     }
 409     else Ratio = 1;
 410 
 411     Out[0] = _cmsQuickSaturateWord(In[0] * Ratio);     // C
 412     Out[1] = _cmsQuickSaturateWord(In[1] * Ratio);     // M
 413     Out[2] = _cmsQuickSaturateWord(In[2] * Ratio);     // Y


 624 Error:
 625 
 626     if (LUT != NULL)
 627         cmsPipelineFree(LUT);
 628 
 629     if (hProfile != NULL)
 630         cmsCloseProfile(hProfile);
 631 
 632     return NULL;
 633 }
 634 
 635 
 636 cmsHPROFILE CMSEXPORT cmsCreateXYZProfile(void)
 637 {
 638     return cmsCreateXYZProfileTHR(NULL);
 639 }
 640 
 641 
 642 //sRGB Curves are defined by:
 643 //
 644 //If  R'sRGB,G'sRGB, B'sRGB < 0.04045
 645 //
 646 //    R =  R'sRGB / 12.92
 647 //    G =  G'sRGB / 12.92
 648 //    B =  B'sRGB / 12.92
 649 //
 650 //
 651 //else if  R'sRGB,G'sRGB, B'sRGB >= 0.04045
 652 //
 653 //    R = ((R'sRGB + 0.055) / 1.055)^2.4
 654 //    G = ((G'sRGB + 0.055) / 1.055)^2.4
 655 //    B = ((B'sRGB + 0.055) / 1.055)^2.4
 656 
 657 static
 658 cmsToneCurve* Build_sRGBGamma(cmsContext ContextID)
 659 {
 660     cmsFloat64Number Parameters[5];
 661 
 662     Parameters[0] = 2.4;
 663     Parameters[1] = 1. / 1.055;
 664     Parameters[2] = 0.055 / 1.055;
 665     Parameters[3] = 1. / 12.92;
 666     Parameters[4] = 0.04045;
 667 
 668     return cmsBuildParametricToneCurve(ContextID, 4, Parameters);
 669 }
 670 
 671 // Create the ICC virtual profile for sRGB space
 672 cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfileTHR(cmsContext ContextID)
 673 {
 674        cmsCIExyY       D65 = { 0.3127, 0.3290, 1.0 };
 675        cmsCIExyYTRIPLE Rec709Primaries = {


 698 
 699 cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void)
 700 {
 701     return cmsCreate_sRGBProfileTHR(NULL);
 702 }
 703 
 704 
 705 
 706 typedef struct {
 707                 cmsFloat64Number Brightness;
 708                 cmsFloat64Number Contrast;
 709                 cmsFloat64Number Hue;
 710                 cmsFloat64Number Saturation;
 711                 cmsBool          lAdjustWP;
 712                 cmsCIEXYZ WPsrc, WPdest;
 713 
 714 } BCHSWADJUSTS, *LPBCHSWADJUSTS;
 715 
 716 
 717 static
 718 int bchswSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo)
 719 {
 720     cmsCIELab LabIn, LabOut;
 721     cmsCIELCh LChIn, LChOut;
 722     cmsCIEXYZ XYZ;
 723     LPBCHSWADJUSTS bchsw = (LPBCHSWADJUSTS) Cargo;
 724 
 725 
 726     cmsLabEncoded2Float(&LabIn, In);
 727 
 728 
 729     cmsLab2LCh(&LChIn, &LabIn);
 730 
 731     // Do some adjusts on LCh
 732 
 733     LChOut.L = LChIn.L * bchsw ->Contrast + bchsw ->Brightness;
 734     LChOut.C = LChIn.C + bchsw -> Saturation;
 735     LChOut.h = LChIn.h + bchsw -> Hue;
 736 
 737 
 738     cmsLCh2Lab(&LabOut, &LChOut);


1108 
1109     // Check if is a named color transform
1110     if (mpe != NULL) {
1111 
1112         if (cmsStageType(mpe) == cmsSigNamedColorElemType) {
1113             return CreateNamedColorDevicelink(hTransform);
1114         }
1115     }
1116 
1117     // First thing to do is to get a copy of the transformation
1118     LUT = cmsPipelineDup(xform ->Lut);
1119     if (LUT == NULL) return NULL;
1120 
1121     // Time to fix the Lab2/Lab4 issue.
1122     if ((xform ->EntryColorSpace == cmsSigLabData) && (Version < 4.0)) {
1123 
1124         if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocLabV2ToV4curves(ContextID)))
1125             goto Error;
1126     }
1127 
1128     // On the output side too. Note that due to V2/V4 PCS encoding on lab we cannot fix white misalignments
1129     if ((xform ->ExitColorSpace) == cmsSigLabData && (Version < 4.0)) {
1130 
1131         dwFlags |= cmsFLAGS_NOWHITEONWHITEFIXUP;
1132         if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID)))
1133             goto Error;
1134     }
1135 
1136 
1137     hProfile = cmsCreateProfilePlaceholder(ContextID);
1138     if (!hProfile) goto Error;                    // can't allocate
1139 
1140     cmsSetProfileVersion(hProfile, Version);
1141 
1142     FixColorSpaces(hProfile, xform -> EntryColorSpace, xform -> ExitColorSpace, dwFlags);
1143 
1144     // Optimize the LUT and precalculate a devicelink
1145 
1146     ChansIn  = cmsChannelsOf(xform -> EntryColorSpace);
1147     ChansOut = cmsChannelsOf(xform -> ExitColorSpace);
1148 
1149     ColorSpaceBitsIn  = _cmsLCMScolorSpace(xform -> EntryColorSpace);
1150     ColorSpaceBitsOut = _cmsLCMScolorSpace(xform -> ExitColorSpace);
1151 


< prev index next >