Commit 0381878f authored by Dmitry Kazakov's avatar Dmitry Kazakov

Fix a crash when loading JPEG image with a weird color profile

The profile in question has a weird RGB->XYZ transformation matrix,
which is not invertible. Therefore, this profile cannot be used as
a workspace color profile and we should convert the image to sRGB
right on loading.

LCMS doesn't have a separate method for checking if conversion matrix
is invertible, therefore we just try to create a simple transformation,
where the profile is both, input and output. If the transformation
is created successfully, then this profile is probably suitable for
usage as a working color space.

BUG:410864
parent 46ad1506
......@@ -27,6 +27,9 @@
#include <QMutex>
#include <QMutexLocker>
#include "kis_assert.h"
class LcmsColorProfileContainer;
class KoLcmsInfo
......@@ -202,7 +205,7 @@ protected:
d->qcolordata = new quint8[3];
Q_CHECK_PTR(d->qcolordata);
Q_ASSERT(d->profile);
KIS_ASSERT(d->profile);
if (KoLcmsDefaultTransformations::s_RGBProfile == 0) {
KoLcmsDefaultTransformations::s_RGBProfile = cmsCreate_sRGBProfile();
......@@ -216,14 +219,15 @@ protected:
this->colorSpaceType(),
KoColorConversionTransformation::internalRenderingIntent(),
KoColorConversionTransformation::internalConversionFlags());
Q_ASSERT(d->defaultTransformations->fromRGB);
KIS_SAFE_ASSERT_RECOVER_NOOP(d->defaultTransformations->fromRGB || !d->colorProfile->isSuitableForOutput());
d->defaultTransformations->toRGB = cmsCreateTransform(d->profile->lcmsProfile(),
this->colorSpaceType(),
KoLcmsDefaultTransformations::s_RGBProfile,
TYPE_BGR_8,
KoColorConversionTransformation::internalRenderingIntent(),
KoColorConversionTransformation::internalConversionFlags());
Q_ASSERT(d->defaultTransformations->toRGB);
KIS_SAFE_ASSERT_RECOVER_NOOP(d->defaultTransformations->toRGB);
KoLcmsDefaultTransformations::s_transformations[ this->id()][ d->profile ] = d->defaultTransformations;
}
}
......@@ -256,7 +260,7 @@ public:
LcmsColorProfileContainer *profile = asLcmsProfile(koprofile);
if (profile == 0) {
// Default sRGB
Q_ASSERT(d->defaultTransformations && d->defaultTransformations->fromRGB);
KIS_ASSERT(d->defaultTransformations && d->defaultTransformations->fromRGB);
cmsDoTransform(d->defaultTransformations->fromRGB, d->qcolordata, dst, 1);
} else {
......@@ -270,6 +274,7 @@ public:
d->lastRGBProfile = profile->lcmsProfile();
}
KIS_ASSERT(d->lastFromRGB);
cmsDoTransform(d->lastFromRGB, d->qcolordata, dst, 1);
}
......
......@@ -30,6 +30,9 @@
#include "lcms2.h"
#include "kis_assert.h"
struct IccColorProfile::Data::Private {
QByteArray rawData;
};
......@@ -71,6 +74,7 @@ struct IccColorProfile::Private {
QScopedPointer<IccColorProfile::Data> data;
QScopedPointer<LcmsColorProfileContainer> lcmsProfile;
QVector<KoChannelInfo::DoubleRange> uiMinMaxes;
bool canCreateCyclicTransform = false;
};
QSharedPointer<Shared> shared;
};
......@@ -137,7 +141,7 @@ float IccColorProfile::version() const
bool IccColorProfile::isSuitableForOutput() const
{
if (d->shared->lcmsProfile) {
return d->shared->lcmsProfile->isSuitableForOutput();
return d->shared->lcmsProfile->isSuitableForOutput() && d->shared->canCreateCyclicTransform;
}
return false;
}
......@@ -372,6 +376,19 @@ void IccColorProfile::calculateFloatUIMinMax(void)
cmsDeleteTransform(trans);
}//else, we'll just default to [0..1] below
// Some (calibration) proifles may have a weird RGB->XYZ transformation matrix,
// which is not invertible. Therefore, such profile cannot be used as
// a workspace color profile and we should convert the image to sRGB
// right on image loading
// LCMS doesn't have a separate method for checking if conversion matrix
// is invertible, therefore we just try to create a simple transformation,
// where the profile is both, input and output. If the transformation
// is created successfully, then this profile is probably suitable for
// usage as a working color space.
d->shared->canCreateCyclicTransform = bool(trans);
ret.resize(num_channels);
for (unsigned int i = 0; i < num_channels; ++i) {
if (out_min_pixel[i] < out_max_pixel[i]) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment