src/share/native/sun/java2d/cmm/lcms/cmssamp.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-2010 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 //---------------------------------------------------------------------------------


 352     if (fabs(a) < 1.0E-10) {
 353 
 354         return cmsmin(0, cmsmax(50, -c/b ));
 355     }
 356     else {
 357 
 358          d = b*b - 4.0 * a * c;
 359          if (d <= 0) {
 360              return 0;
 361          }
 362          else {
 363 
 364              double rt = (-b + sqrt(d)) / (2.0 * a);
 365 
 366              return cmsmax(0, cmsmin(50, rt));
 367          }
 368    }
 369 
 370 }
 371 
 372 /*
 373 static
 374 cmsBool IsMonotonic(int n, const cmsFloat64Number Table[])
 375 {
 376     int i;
 377     cmsFloat64Number last;
 378 
 379     last = Table[n-1];
 380 
 381     for (i = n-2; i >= 0; --i) {
 382 
 383         if (Table[i] > last)
 384 
 385             return FALSE;
 386         else
 387             last = Table[i];
 388 
 389     }
 390 
 391     return TRUE;
 392 }
 393 */
 394 
 395 // Calculates the black point of a destination profile.
 396 // This algorithm comes from the Adobe paper disclosing its black point compensation method.
 397 cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
 398 {
 399     cmsColorSpaceSignature ColorSpace;
 400     cmsHTRANSFORM hRoundTrip = NULL;
 401     cmsCIELab InitialLab, destLab, Lab;
 402     cmsFloat64Number inRamp[256], outRamp[256];
 403     cmsFloat64Number MinL, MaxL;
 404     cmsBool NearlyStraightMidrange = TRUE;
 405     cmsFloat64Number yRamp[256];
 406     cmsFloat64Number x[256], y[256];
 407     cmsFloat64Number lo, hi;
 408     int n, l;
 409     cmsProfileClassSignature devClass;
 410 
 411     // Make sure the device class is adequate
 412     devClass = cmsGetDeviceClass(hProfile);
 413     if (devClass == cmsSigLinkClass ||


 498 
 499         inRamp[l]  = Lab.L;
 500         outRamp[l] = destLab.L;
 501     }
 502 
 503     // Make monotonic
 504     for (l = 254; l > 0; --l) {
 505         outRamp[l] = cmsmin(outRamp[l], outRamp[l+1]);
 506     }
 507 
 508     // Check
 509     if (! (outRamp[0] < outRamp[255])) {
 510 
 511         cmsDeleteTransform(hRoundTrip);
 512         BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
 513         return FALSE;
 514     }
 515 
 516 
 517     // Test for mid range straight (only on relative colorimetric)
 518 
 519     NearlyStraightMidrange = TRUE;
 520     MinL = outRamp[0]; MaxL = outRamp[255];
 521     if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
 522 
 523         for (l=0; l < 256; l++) {
 524 
 525             if (! ((inRamp[l] <= MinL + 0.2 * (MaxL - MinL) ) ||
 526                 (fabs(inRamp[l] - outRamp[l]) < 4.0 )))
 527                 NearlyStraightMidrange = FALSE;
 528         }
 529 
 530         // If the mid range is straight (as determined above) then the
 531         // DestinationBlackPoint shall be the same as initialLab.
 532         // Otherwise, the DestinationBlackPoint shall be determined
 533         // using curve fitting.
 534 
 535         if (NearlyStraightMidrange) {
 536 
 537             cmsLab2XYZ(NULL, BlackPoint, &InitialLab);
 538             cmsDeleteTransform(hRoundTrip);
 539             return TRUE;
 540         }
 541     }
 542 
 543 
 544     // curve fitting: The round-trip curve normally looks like a nearly constant section at the black point,
 545     // with a corner and a nearly straight line to the white point.
 546 
 547     for (l=0; l < 256; l++) {
 548 
 549         yRamp[l] = (outRamp[l] - MinL) / (MaxL - MinL);
 550     }
 551 
 552     // find the black point using the least squares error quadratic curve fitting
 553 
 554     if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
 555         lo = 0.1;
 556         hi = 0.5;
 557     }
 558     else {
 559 
 560         // Perceptual and saturation
 561         lo = 0.03;
 562         hi = 0.25;
 563     }
 564 
 565     // Capture shadow points for the fitting.
 566     n = 0;
 567     for (l=0; l < 256; l++) {
 568 
 569         cmsFloat64Number ff = yRamp[l];
 570 
 571         if (ff >= lo && ff < hi) {
 572             x[n] = inRamp[l];
 573             y[n] = yRamp[l];




  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-2014 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 //---------------------------------------------------------------------------------


 352     if (fabs(a) < 1.0E-10) {
 353 
 354         return cmsmin(0, cmsmax(50, -c/b ));
 355     }
 356     else {
 357 
 358          d = b*b - 4.0 * a * c;
 359          if (d <= 0) {
 360              return 0;
 361          }
 362          else {
 363 
 364              double rt = (-b + sqrt(d)) / (2.0 * a);
 365 
 366              return cmsmax(0, cmsmin(50, rt));
 367          }
 368    }
 369 
 370 }
 371 
















 372 





 373 
 374 // Calculates the black point of a destination profile.
 375 // This algorithm comes from the Adobe paper disclosing its black point compensation method.
 376 cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
 377 {
 378     cmsColorSpaceSignature ColorSpace;
 379     cmsHTRANSFORM hRoundTrip = NULL;
 380     cmsCIELab InitialLab, destLab, Lab;
 381     cmsFloat64Number inRamp[256], outRamp[256];
 382     cmsFloat64Number MinL, MaxL;
 383     cmsBool NearlyStraightMidrange = TRUE;
 384     cmsFloat64Number yRamp[256];
 385     cmsFloat64Number x[256], y[256];
 386     cmsFloat64Number lo, hi;
 387     int n, l;
 388     cmsProfileClassSignature devClass;
 389 
 390     // Make sure the device class is adequate
 391     devClass = cmsGetDeviceClass(hProfile);
 392     if (devClass == cmsSigLinkClass ||


 477 
 478         inRamp[l]  = Lab.L;
 479         outRamp[l] = destLab.L;
 480     }
 481 
 482     // Make monotonic
 483     for (l = 254; l > 0; --l) {
 484         outRamp[l] = cmsmin(outRamp[l], outRamp[l+1]);
 485     }
 486 
 487     // Check
 488     if (! (outRamp[0] < outRamp[255])) {
 489 
 490         cmsDeleteTransform(hRoundTrip);
 491         BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
 492         return FALSE;
 493     }
 494 
 495 
 496     // Test for mid range straight (only on relative colorimetric)

 497     NearlyStraightMidrange = TRUE;
 498     MinL = outRamp[0]; MaxL = outRamp[255];
 499     if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
 500 
 501         for (l=0; l < 256; l++) {
 502 
 503             if (! ((inRamp[l] <= MinL + 0.2 * (MaxL - MinL) ) ||
 504                 (fabs(inRamp[l] - outRamp[l]) < 4.0 )))
 505                 NearlyStraightMidrange = FALSE;
 506         }
 507 
 508         // If the mid range is straight (as determined above) then the
 509         // DestinationBlackPoint shall be the same as initialLab.
 510         // Otherwise, the DestinationBlackPoint shall be determined
 511         // using curve fitting.

 512         if (NearlyStraightMidrange) {
 513 
 514             cmsLab2XYZ(NULL, BlackPoint, &InitialLab);
 515             cmsDeleteTransform(hRoundTrip);
 516             return TRUE;
 517         }
 518     }
 519 
 520 
 521     // curve fitting: The round-trip curve normally looks like a nearly constant section at the black point,
 522     // with a corner and a nearly straight line to the white point.

 523     for (l=0; l < 256; l++) {
 524 
 525         yRamp[l] = (outRamp[l] - MinL) / (MaxL - MinL);
 526     }
 527 
 528     // find the black point using the least squares error quadratic curve fitting

 529     if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
 530         lo = 0.1;
 531         hi = 0.5;
 532     }
 533     else {
 534 
 535         // Perceptual and saturation
 536         lo = 0.03;
 537         hi = 0.25;
 538     }
 539 
 540     // Capture shadow points for the fitting.
 541     n = 0;
 542     for (l=0; l < 256; l++) {
 543 
 544         cmsFloat64Number ff = yRamp[l];
 545 
 546         if (ff >= lo && ff < hi) {
 547             x[n] = inRamp[l];
 548             y[n] = yRamp[l];