Krita Source Code Documentation
Loading...
Searching...
No Matches
IccColorProfile::Private Struct Reference

Classes

struct  ProfileInfo
 
struct  Shared
 

Public Types

using LazyProfileInfo = KisLazyStorage<KisLazyValueWrapper<ProfileInfo>, std::function<ProfileInfo()>>
 

Public Member Functions

ProfileInfo calculateFloatUIMinMax () const
 
 Private ()
 

Public Attributes

QSharedPointer< Sharedshared
 

Detailed Description

Definition at line 68 of file IccColorProfile.cpp.

Member Typedef Documentation

◆ LazyProfileInfo

Constructor & Destructor Documentation

◆ Private()

IccColorProfile::Private::Private ( )
inline

Definition at line 87 of file IccColorProfile.cpp.

Member Function Documentation

◆ calculateFloatUIMinMax()

IccColorProfile::Private::ProfileInfo IccColorProfile::Private::calculateFloatUIMinMax ( ) const

Definition at line 535 of file IccColorProfile.cpp.

536{
537 Private::ProfileInfo info;
539
540 cmsHPROFILE cprofile = shared->lcmsProfile->lcmsProfile();
541 Q_ASSERT(cprofile);
542
543 cmsColorSpaceSignature color_space_sig = cmsGetColorSpace(cprofile);
544 unsigned int num_channels = cmsChannelsOf(color_space_sig);
545 unsigned int color_space_mask = _cmsLCMScolorSpace(color_space_sig);
546
547 Q_ASSERT(num_channels >= 1 && num_channels <= 4); // num_channels==1 is for grayscale, we need to handle it
548 Q_ASSERT(color_space_mask);
549
550 // to try to find the max range of float/doubles for this profile,
551 // pass in min/max int and make the profile convert that
552 // this is far from perfect, we need a better way, if possible to get the "bounds" of a profile
553
554 uint16_t in_min_pixel[4] = {0, 0, 0, 0};
555 uint16_t in_max_pixel[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
556 qreal out_min_pixel[4] = {0, 0, 0, 0};
557 qreal out_max_pixel[4] = {0, 0, 0, 0};
558
559 cmsHTRANSFORM trans = cmsCreateTransform(
560 cprofile,
561 (COLORSPACE_SH(color_space_mask) | CHANNELS_SH(num_channels) | BYTES_SH(2)),
562 cprofile,
563 (COLORSPACE_SH(color_space_mask) | FLOAT_SH(1) | CHANNELS_SH(num_channels) | BYTES_SH(0)), //NOTE THAT 'BYTES' FIELD IS SET TO ZERO ON DLB because 8 bytes overflows the bitfield
564 INTENT_ABSOLUTE_COLORIMETRIC, 0); // does the intent matter in this case?
565 // absolute colorimetric gives bigger bounds with cmyk's Chemical Proof
566
567 if (trans) {
568 cmsDoTransform(trans, in_min_pixel, out_min_pixel, 1);
569 cmsDoTransform(trans, in_max_pixel, out_max_pixel, 1);
570 cmsDeleteTransform(trans);
571 }//else, we'll just default to [0..1] below
572
573 // Some (calibration) profiles may have a weird RGB->XYZ transformation matrix,
574 // which is not invertible. Therefore, such profile cannot be used as
575 // a workspace color profile and we should convert the image to sRGB
576 // right on image loading
577
578 // LCMS doesn't have a separate method for checking if conversion matrix
579 // is invertible, therefore we just try to create a simple transformation,
580 // where the profile is both, input and output. If the transformation
581 // is created successfully, then this profile is probably suitable for
582 // usage as a working color space.
583
584 info.canCreateCyclicTransform = bool(trans);
585
586 ret.resize(num_channels);
587 for (unsigned int i = 0; i < num_channels; ++i) {
588 if (color_space_sig == cmsSigYCbCrData) {
589 // Although YCbCr profiles are essentially LUT-based
590 // (due to the inability of ICC to represent multiple successive
591 // matrix transforms except with BtoD0 tags in V4),
592 // YCbCr is intended to be a roundtrip transform to the
593 // corresponding RGB transform (BT.601, BT.709).
594 // Force enable the full range of values.
595 ret[i].minVal = 0;
596 ret[i].maxVal = 1;
597 } else if (out_min_pixel[i] < out_max_pixel[i]) {
598 ret[i].minVal = out_min_pixel[i];
599 ret[i].maxVal = out_max_pixel[i];
600 } else {
601 // apparently we can't even guarantee that converted_to_double(0x0000) < converted_to_double(0xFFFF)
602 // assume [0..1] in such cases
603 // we need to find a really solid way of determining the bounds of a profile, if possible
604 ret[i].minVal = 0;
605 ret[i].maxVal = 1;
606 }
607 }
608
609 return info;
610}
#define INTENT_ABSOLUTE_COLORIMETRIC
Definition kis_global.h:106

References KoColorProfile::info, INTENT_ABSOLUTE_COLORIMETRIC, and shared.

Member Data Documentation

◆ shared

QSharedPointer<Shared> IccColorProfile::Private::shared

Definition at line 91 of file IccColorProfile.cpp.


The documentation for this struct was generated from the following file: