diff --git a/src/gui/painting/qcolortransform.cpp b/src/gui/painting/qcolortransform.cpp index 33b1dcdeb01..7692e853fee 100644 --- a/src/gui/painting/qcolortransform.cpp +++ b/src/gui/painting/qcolortransform.cpp @@ -390,6 +390,14 @@ template<> inline int getAlpha(const QRgba64 &p) { return p.alpha(); } +template +static inline constexpr int getFactor(); +template<> +inline constexpr int getFactor() +{ return 255; } +template<> +inline constexpr int getFactor() +{ return 65535; } #endif template @@ -823,8 +831,9 @@ static void storePremultiplied(D *dst, const S *src, const QColorVector *buffer, const __m128 vTrcRes = _mm_set1_ps(float(QColorTrcLut::Resolution)); const __m128 iFF00 = _mm_set1_ps(1.0f / (255 * 256)); constexpr bool isARGB = isArgb(); + static_assert(getFactor() >= getFactor()); for (qsizetype i = 0; i < len; ++i) { - const int a = getAlpha(src[i]); + const int a = getAlpha(src[i]) * (getFactor() / getFactor()); __m128 vf = _mm_loadu_ps(&buffer[i].x); __m128i v = _mm_cvtps_epi32(_mm_mul_ps(vf, vTrcRes)); __m128 va = _mm_mul_ps(_mm_set1_ps(a), iFF00); @@ -905,8 +914,9 @@ static void storeUnpremultiplied(D *dst, const S *src, const QColorVector *buffe { const __m128 vTrcRes = _mm_set1_ps(float(QColorTrcLut::Resolution)); constexpr bool isARGB = isArgb(); + static_assert(getFactor() >= getFactor()); for (qsizetype i = 0; i < len; ++i) { - const int a = getAlpha(src[i]); + const int a = getAlpha(src[i]) * (getFactor() / getFactor()); __m128 vf = _mm_loadu_ps(&buffer[i].x); __m128i v = _mm_cvtps_epi32(_mm_mul_ps(vf, vTrcRes)); const int ridx = _mm_extract_epi16(v, 0); @@ -1029,8 +1039,9 @@ static void storePremultiplied(D *dst, const S *src, const QColorVector *buffer, { const float iFF00 = 1.0f / (255 * 256); constexpr bool isARGB = isArgb(); + static_assert(getFactor() >= getFactor()); for (qsizetype i = 0; i < len; ++i) { - const int a = getAlpha(src[i]); + const int a = getAlpha(src[i]) * (getFactor() / getFactor()); float32x4_t vf = vld1q_f32(&buffer[i].x); uint32x4_t v = vcvtq_u32_f32(vaddq_f32(vmulq_n_f32(vf, float(QColorTrcLut::Resolution)), vdupq_n_f32(0.5f))); const int ridx = vgetq_lane_u32(v, 0); @@ -1073,8 +1084,9 @@ static void storeUnpremultiplied(D *dst, const S *src, const QColorVector *buffe const QColorTransformPrivate *d_ptr) { constexpr bool isARGB = isArgb(); + static_assert(getFactor() >= getFactor()); for (qsizetype i = 0; i < len; ++i) { - const int a = getAlpha(src[i]); + const int a = getAlpha(src[i]) * (getFactor() / getFactor()); float32x4_t vf = vld1q_f32(&buffer[i].x); uint16x4_t v = vmovn_u32(vcvtq_u32_f32(vaddq_f32(vmulq_n_f32(vf, float(QColorTrcLut::Resolution)), vdupq_n_f32(0.5f)))); const int ridx = vget_lane_u16(v, 0); diff --git a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp index 7505d463ed1..48f792b9ede 100644 --- a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp +++ b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp @@ -71,6 +71,8 @@ private slots: void setWhitePoint(); void grayColorSpace(); void grayColorSpaceEffectivelySRgb(); + + void scaleAlphaValue(); }; tst_QColorSpace::tst_QColorSpace() @@ -1030,5 +1032,14 @@ void tst_QColorSpace::grayColorSpaceEffectivelySRgb() QCOMPARE(rgbImage1, rgbImage2); } +void tst_QColorSpace::scaleAlphaValue() +{ + QImage image(1, 1, QImage::Format_ARGB32); + image.setPixel(0, 0, qRgba(255, 255, 255, 125)); + image.setColorSpace(QColorSpace::SRgb); + image.convertToColorSpace(QColorSpace::SRgbLinear, QImage::Format_RGBA64); + QCOMPARE(reinterpret_cast(image.constBits())->alpha(), 257 * 125); +} + QTEST_MAIN(tst_QColorSpace) #include "tst_qcolorspace.moc"