18#include <QSharedPointer>
74 QScopedPointer<IccColorProfile::Data>
data;
114 cmsCIExyY whitePoint;
120 if (modifiedColorants.size()>=2) {
121 whitePoint.x = modifiedColorants[0];
122 whitePoint.y = modifiedColorants[1];
130 if (modifiedColorants.size()>2 && modifiedColorants.size() <= 8) {
131 primaries = {{modifiedColorants[2], modifiedColorants[3], 1.0},
132 {modifiedColorants[4], modifiedColorants[5], 1.0},
133 {modifiedColorants[6], modifiedColorants[7], 1.0}};
136 cmsHPROFILE iccProfile =
nullptr;
138 if (colorants.size() == 2) {
139 iccProfile = cmsCreateGrayProfile(&whitePoint, mainCurve);
142 cmsToneCurve *curve[3];
143 curve[0] = curve[1] = curve[2] = mainCurve;
144 iccProfile = cmsCreateRGBProfile(&whitePoint, &
primaries, curve);
150 name.append(
"Krita");
154 cmsCIEXYZ media_blackpoint = {0.0, 0.0, 0.0};
155 cmsWriteTag (iccProfile, cmsSigMediaBlackPointTag, &media_blackpoint);
159 mlu = cmsMLUalloc (NULL, 1);
160 cmsMLUsetASCII (mlu,
"en",
"US",
name.join(
" ").toLatin1());
161 cmsWriteTag (iccProfile, cmsSigProfileDescriptionTag, mlu);
163 mlu = cmsMLUalloc (NULL, 1);
164 cmsMLUsetASCII (mlu,
"en",
"US", QString(
"Profile generated by Krita, Public domain.").toLatin1());
165 cmsWriteTag(iccProfile, cmsSigCopyrightTag, mlu);
173 cmsCloseProfile(iccProfile);
197 return d->shared->data->rawData();
202 d->shared->data->setRawData(
rawData);
207 if (
d->shared->lcmsProfile) {
208 return d->shared->lcmsProfile->valid();
214 if (
d->shared->lcmsProfile) {
215 return d->shared->lcmsProfile->version();
224 switch (
d->shared->lcmsProfile->colorSpaceSignature()) {
240 case cmsSigYCbCrData:
252 if (
d->shared->lcmsProfile) {
253 return d->shared->lcmsProfile->isSuitableForOutput() &&
d->shared->profileInfo->value.canCreateCyclicTransform;
260 if (
d->shared->lcmsProfile) {
261 return d->shared->lcmsProfile->isSuitableForPrinting();
268 if (
d->shared->lcmsProfile) {
269 return d->shared->lcmsProfile->isSuitableForDisplay();
276 if (
d->shared->lcmsProfile) {
277 return d->shared->lcmsProfile->supportsPerceptual();
283 if (
d->shared->lcmsProfile) {
284 return d->shared->lcmsProfile->supportsSaturation();
290 if (
d->shared->lcmsProfile) {
291 return d->shared->lcmsProfile->supportsAbsolute();
297 if (
d->shared->lcmsProfile) {
298 return d->shared->lcmsProfile->supportsRelative();
304 if (
d->shared->lcmsProfile) {
305 return d->shared->lcmsProfile->hasColorants();
311 if (
d->shared->lcmsProfile)
312 return d->shared->lcmsProfile->hasTRC();
317 if (
d->shared->lcmsProfile)
318 return d->shared->lcmsProfile->isLinear();
323 if (
d->shared->lcmsProfile) {
324 return d->shared->lcmsProfile->getColorantsXYZ();
330 if (
d->shared->lcmsProfile) {
331 return d->shared->lcmsProfile->getColorantsxyY();
337 QVector <qreal> d50Dummy(3);
338 d50Dummy << 0.9642 << 1.0000 << 0.8249;
339 if (
d->shared->lcmsProfile) {
340 return d->shared->lcmsProfile->getWhitePointXYZ();
346 QVector <qreal> d50Dummy(3);
347 d50Dummy << 0.34773 << 0.35952 << 1.0;
348 if (
d->shared->lcmsProfile) {
349 return d->shared->lcmsProfile->getWhitePointxyY();
355 QVector <qreal> dummy(3);
357 if (
d->shared->lcmsProfile) {
358 return d->shared->lcmsProfile->getEstimatedTRC();
365 if (
d->shared->lcmsProfile) {
373 if (
d->shared->lcmsProfile)
374 d->shared->lcmsProfile->LinearizeFloatValue(
Value);
378 if (
d->shared->lcmsProfile)
379 d->shared->lcmsProfile->DelinearizeFloatValue(
Value);
383 if (
d->shared->lcmsProfile)
384 d->shared->lcmsProfile->LinearizeFloatValueFast(
Value);
388 if (
d->shared->lcmsProfile)
389 d->shared->lcmsProfile->DelinearizeFloatValueFast(
Value);
395 if (
d->shared->lcmsProfile) {
396 dummy =
d->shared->lcmsProfile->getProfileUniqueId();
404 file.open(QIODevice::ReadOnly);
405 QByteArray
rawData = file.readAll();
411 qWarning() <<
"Failed to load profile from " <<
fileName();
422 if (!
d->shared->lcmsProfile) {
425 if (
d->shared->lcmsProfile->init()) {
426 setName(
d->shared->lcmsProfile->name());
427 setInfo(
d->shared->lcmsProfile->info());
430 if (
d->shared->lcmsProfile->valid()) {
432 return d->calculateFloatUIMinMax();
443 Q_ASSERT(
d->shared->lcmsProfile);
444 return d->shared->lcmsProfile.data();
451 return d->shared == rhsIcc->
d->shared;
458 Q_ASSERT(!
d->shared->profileInfo->value.uiMinMaxes.isEmpty());
459 return d->shared->profileInfo->value.uiMinMaxes;
468 cmsHPROFILE cprofile =
shared->lcmsProfile->lcmsProfile();
471 cmsColorSpaceSignature color_space_sig = cmsGetColorSpace(cprofile);
472 unsigned int num_channels = cmsChannelsOf(color_space_sig);
473 unsigned int color_space_mask = _cmsLCMScolorSpace(color_space_sig);
475 Q_ASSERT(num_channels >= 1 && num_channels <= 4);
476 Q_ASSERT(color_space_mask);
482 uint16_t in_min_pixel[4] = {0, 0, 0, 0};
483 uint16_t in_max_pixel[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
484 qreal out_min_pixel[4] = {0, 0, 0, 0};
485 qreal out_max_pixel[4] = {0, 0, 0, 0};
487 cmsHTRANSFORM trans = cmsCreateTransform(
489 (COLORSPACE_SH(color_space_mask) | CHANNELS_SH(num_channels) | BYTES_SH(2)),
491 (COLORSPACE_SH(color_space_mask) | FLOAT_SH(1) | CHANNELS_SH(num_channels) | BYTES_SH(0)),
496 cmsDoTransform(trans, in_min_pixel, out_min_pixel, 1);
497 cmsDoTransform(trans, in_max_pixel, out_max_pixel, 1);
498 cmsDeleteTransform(trans);
512 info.canCreateCyclicTransform = bool(trans);
514 ret.resize(num_channels);
515 for (
unsigned int i = 0; i < num_channels; ++i) {
516 if (color_space_sig == cmsSigYCbCrData) {
525 }
else if (out_min_pixel[i] < out_max_pixel[i]) {
526 ret[i].minVal = out_min_pixel[i];
527 ret[i].maxVal = out_max_pixel[i];
ColorPrimaries
The colorPrimaries enum Enum of colorants, follows ITU H.273 for values 0 to 255, and has extra known...
TransferCharacteristics
The transferCharacteristics enum Enum of transfer characteristics, follows ITU H.273 for values 0 to ...
QScopedPointer< Private > const d
void setRawData(const QByteArray &)
bool isSuitableForDisplay() const override
void linearizeFloatValueFast(QVector< qreal > &Value) const override
QVector< qreal > getColorantsxyY() const override
void setRawData(const QByteArray &rawData)
bool operator==(const KoColorProfile &) const override
~IccColorProfile() override
LcmsColorProfileContainer * asLcms() const
QVector< qreal > getColorantsXYZ() const override
bool supportsRelative() const override
bool hasColorants() const override
bool supportsPerceptual() const override
bool isSuitableForPrinting() const override
QVector< qreal > getWhitePointXYZ() const override
bool isLinear() const override
void delinearizeFloatValue(QVector< qreal > &Value) const override
QString colorModelID() const override
QByteArray rawData() const override
void linearizeFloatValue(QVector< qreal > &Value) const override
const QVector< KoChannelInfo::DoubleRange > & getFloatUIMinMax(void) const
bool isSuitableForOutput() const override
bool supportsSaturation() const override
bool valid() const override
bool hasTRC() const override
IccColorProfile(const QString &fileName=QString())
float version() const override
QByteArray uniqueId() const override
void delinearizeFloatValueFast(QVector< qreal > &Value) const override
KoColorProfile * clone() const override
QScopedPointer< Private > d
QVector< qreal > getWhitePointxyY() const override
bool compareTRC(TransferCharacteristics characteristics, float error) const override
bool supportsAbsolute() const override
QVector< qreal > getEstimatedTRC() const override
static cmsToneCurve * transferFunction(TransferCharacteristics transferFunction)
static QByteArray lcmsProfileToByteArray(const cmsHPROFILE profile)
#define INTENT_ABSOLUTE_COLORIMETRIC
QVector< KoChannelInfo::DoubleRange > uiMinMaxes
bool canCreateCyclicTransform
QScopedPointer< LcmsColorProfileContainer > lcmsProfile
QScopedPointer< IccColorProfile::Data > data
LazyProfileInfo profileInfo
ProfileInfo calculateFloatUIMinMax() const
QSharedPointer< Shared > shared
KisLazyStorage< KisLazyValueWrapper< ProfileInfo >, std::function< ProfileInfo()> > LazyProfileInfo
static void colorantsForType(ColorPrimaries primaries, QVector< double > &colorants)
colorantsForPrimaries fills a QVector<float> with the xy values of the whitepoint and red,...
void setFileName(const QString &filename)
TransferCharacteristics characteristics
void setCopyright(const QString ©right)
static QString getTransferCharacteristicName(TransferCharacteristics curve)
getTransferCharacteristicName
static QString getColorPrimariesName(ColorPrimaries primaries)
getColorPrimariesName
void setName(const QString &name)
void setManufacturer(const QString &manufacturer)
void setCharacteristics(ColorPrimaries primaries, TransferCharacteristics curve)
setCharacteristics ideally, we'd read this from the icc profile curve, but that can be tricky,...
void setInfo(const QString &info)