Fix HDR colorspace transforms for non-SSE2/non-NEON

Task-number: QTBUG-127646
Change-Id: Ie3eab7b7e07155a0e9f70455c8e33f308f7b84d1
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit 8e942c9d704376232d8a5437f861174709a26600)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Allan Sandfeld Jensen 2024-08-07 14:21:28 +02:00 committed by Qt Cherry-pick Bot
parent a83d113f66
commit 4ba6cd2dcd

View File

@ -780,6 +780,9 @@ void loadUnpremultiplied(QColorVector *buffer, const T *src, const qsizetype len
template<> template<>
void loadPremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizetype len, const QColorTransformPrivate *d_ptr) void loadPremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
{ {
const int rangeMaxR = d_ptr->colorSpaceIn->lut[0]->m_unclampedToLinear;
const int rangeMaxG = d_ptr->colorSpaceIn->lut[1]->m_unclampedToLinear;
const int rangeMaxB = d_ptr->colorSpaceIn->lut[2]->m_unclampedToLinear;
for (qsizetype i = 0; i < len; ++i) { for (qsizetype i = 0; i < len; ++i) {
const uint p = src[i]; const uint p = src[i];
const int a = qAlpha(p); const int a = qAlpha(p);
@ -788,9 +791,16 @@ void loadPremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizet
const int ridx = int(qRed(p) * ia + 0.5f); const int ridx = int(qRed(p) * ia + 0.5f);
const int gidx = int(qGreen(p) * ia + 0.5f); const int gidx = int(qGreen(p) * ia + 0.5f);
const int bidx = int(qBlue(p) * ia + 0.5f); const int bidx = int(qBlue(p) * ia + 0.5f);
buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256)); if (ridx <= rangeMaxR && gidx <= rangeMaxG && bidx <= rangeMaxB) {
buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256)); buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256));
buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256)); buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256));
buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256));
} else {
constexpr float f = 1.f / QColorTrcLut::Resolution;
buffer[i].x = d_ptr->colorSpaceIn->trc[0].applyExtended(ridx * f);
buffer[i].y = d_ptr->colorSpaceIn->trc[1].applyExtended(gidx * f);
buffer[i].z = d_ptr->colorSpaceIn->trc[2].applyExtended(bidx * f);
}
} else { } else {
buffer[i].x = buffer[i].y = buffer[i].z = 0.0f; buffer[i].x = buffer[i].y = buffer[i].z = 0.0f;
} }
@ -800,6 +810,9 @@ void loadPremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizet
template<> template<>
void loadPremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const qsizetype len, const QColorTransformPrivate *d_ptr) void loadPremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
{ {
const int rangeMaxR = d_ptr->colorSpaceIn->lut[0]->m_unclampedToLinear;
const int rangeMaxG = d_ptr->colorSpaceIn->lut[1]->m_unclampedToLinear;
const int rangeMaxB = d_ptr->colorSpaceIn->lut[2]->m_unclampedToLinear;
for (qsizetype i = 0; i < len; ++i) { for (qsizetype i = 0; i < len; ++i) {
const QRgba64 &p = src[i]; const QRgba64 &p = src[i];
const int a = p.alpha(); const int a = p.alpha();
@ -808,9 +821,16 @@ void loadPremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const
const int ridx = int(p.red() * ia + 0.5f); const int ridx = int(p.red() * ia + 0.5f);
const int gidx = int(p.green() * ia + 0.5f); const int gidx = int(p.green() * ia + 0.5f);
const int bidx = int(p.blue() * ia + 0.5f); const int bidx = int(p.blue() * ia + 0.5f);
buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256)); if (ridx <= rangeMaxR && gidx <= rangeMaxG && bidx <= rangeMaxB) {
buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256)); buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256));
buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256)); buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256));
buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256));
} else {
constexpr float f = 1.f / QColorTrcLut::Resolution;
buffer[i].x = d_ptr->colorSpaceIn->trc[0].applyExtended(ridx * f);
buffer[i].y = d_ptr->colorSpaceIn->trc[1].applyExtended(gidx * f);
buffer[i].z = d_ptr->colorSpaceIn->trc[2].applyExtended(bidx * f);
}
} else { } else {
buffer[i].x = buffer[i].y = buffer[i].z = 0.0f; buffer[i].x = buffer[i].y = buffer[i].z = 0.0f;
} }
@ -820,22 +840,54 @@ void loadPremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const
template<> template<>
void loadUnpremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizetype len, const QColorTransformPrivate *d_ptr) void loadUnpremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
{ {
const int rangeMaxR = d_ptr->colorSpaceIn->lut[0]->m_unclampedToLinear;
const int rangeMaxG = d_ptr->colorSpaceIn->lut[1]->m_unclampedToLinear;
const int rangeMaxB = d_ptr->colorSpaceIn->lut[2]->m_unclampedToLinear;
for (qsizetype i = 0; i < len; ++i) { for (qsizetype i = 0; i < len; ++i) {
const uint p = src[i]; const uint p = src[i];
buffer[i].x = d_ptr->colorSpaceIn->lut[0]->u8ToLinearF32(qRed(p)); const int ridx = qRed(p) << QColorTrcLut::ShiftUp;
buffer[i].y = d_ptr->colorSpaceIn->lut[1]->u8ToLinearF32(qGreen(p)); const int gidx = qGreen(p) << QColorTrcLut::ShiftUp;
buffer[i].z = d_ptr->colorSpaceIn->lut[2]->u8ToLinearF32(qBlue(p)); const int bidx = qBlue(p) << QColorTrcLut::ShiftUp;
if (ridx <= rangeMaxR && gidx <= rangeMaxG && bidx <= rangeMaxB) {
buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256));
buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256));
buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256));
} else {
constexpr float f = 1.f / QColorTrcLut::Resolution;
buffer[i].x = d_ptr->colorSpaceIn->trc[0].applyExtended(ridx * f);
buffer[i].y = d_ptr->colorSpaceIn->trc[1].applyExtended(gidx * f);
buffer[i].z = d_ptr->colorSpaceIn->trc[2].applyExtended(bidx * f);
}
} }
} }
static int u16toidx(int c)
{
c -= c >> 8;
return c >> QColorTrcLut::ShiftDown;
}
template<> template<>
void loadUnpremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const qsizetype len, const QColorTransformPrivate *d_ptr) void loadUnpremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
{ {
const int rangeMaxR = d_ptr->colorSpaceIn->lut[0]->m_unclampedToLinear;
const int rangeMaxG = d_ptr->colorSpaceIn->lut[1]->m_unclampedToLinear;
const int rangeMaxB = d_ptr->colorSpaceIn->lut[2]->m_unclampedToLinear;
for (qsizetype i = 0; i < len; ++i) { for (qsizetype i = 0; i < len; ++i) {
const QRgba64 &p = src[i]; const QRgba64 &p = src[i];
buffer[i].x = d_ptr->colorSpaceIn->lut[0]->u16ToLinearF32(p.red()); const int ridx = u16toidx(p.red());
buffer[i].y = d_ptr->colorSpaceIn->lut[1]->u16ToLinearF32(p.green()); const int gidx = u16toidx(p.green());
buffer[i].z = d_ptr->colorSpaceIn->lut[2]->u16ToLinearF32(p.blue()); const int bidx = u16toidx(p.blue());
if (ridx <= rangeMaxR && gidx <= rangeMaxG && bidx <= rangeMaxB) {
buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256));
buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256));
buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256));
} else {
constexpr float f = 1.f / QColorTrcLut::Resolution;
buffer[i].x = d_ptr->colorSpaceIn->trc[0].applyExtended(ridx * f);
buffer[i].y = d_ptr->colorSpaceIn->trc[1].applyExtended(gidx * f);
buffer[i].z = d_ptr->colorSpaceIn->trc[2].applyExtended(bidx * f);
}
} }
} }
#endif #endif