diff --git a/autotests/read/psd/laba_16bit.png b/autotests/read/psd/laba_16bit.png index d0db793..d3d317c 100644 Binary files a/autotests/read/psd/laba_16bit.png and b/autotests/read/psd/laba_16bit.png differ diff --git a/autotests/read/psd/laba_8bit.png b/autotests/read/psd/laba_8bit.png index 1fd7e71..c691745 100644 Binary files a/autotests/read/psd/laba_8bit.png and b/autotests/read/psd/laba_8bit.png differ diff --git a/src/imageformats/fastmath_p.h b/src/imageformats/fastmath_p.h new file mode 100644 index 0000000..17bd2dd --- /dev/null +++ b/src/imageformats/fastmath_p.h @@ -0,0 +1,35 @@ +/* + Approximated math functions used into conversions. + + SPDX-FileCopyrightText: Edward Kmett + SPDX-FileCopyrightText: 2023 Mirco Miranda + + SPDX-License-Identifier: BSD-3-Clause +*/ +#ifndef FASTMATH_P_H +#define FASTMATH_P_H + +#include + +/*! + * \brief fastPow + * Based on Edward Kmett code released into the public domain. + * See also: https://github.com/ekmett/approximate + */ +inline double fastPow(double x, double y) +{ + union { + double d; + qint32 i[2]; + } u = {x}; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + u.i[1] = qint32(y * (u.i[1] - 1072632447) + 1072632447); + u.i[0] = 0; +#else // never tested + u.i[0] = qint32(y * (u.i[0] - 1072632447) + 1072632447); + u.i[1] = 0; +#endif + return u.d; +} + +#endif // FASTMATH_P_H diff --git a/src/imageformats/psd.cpp b/src/imageformats/psd.cpp index ed1327f..8b28979 100644 --- a/src/imageformats/psd.cpp +++ b/src/imageformats/psd.cpp @@ -32,6 +32,7 @@ * color management engine (e.g. LittleCMS). */ +#include "fastmath_p.h" #include "psd_p.h" #include "util_p.h" @@ -50,7 +51,7 @@ typedef quint8 uchar; * This should not be a problem because the Qt's QColorSpace supports the linear * sRgb colorspace. * - * Using linear conversion, the loading speed is improved by 4x. Anyway, if you are using + * Using linear conversion, the loading speed is slightly improved. Anyway, if you are using * an software that discard color info, you should comment it. * * At the time I'm writing (07/2022), Gwenview and Krita supports linear sRgb but KDE @@ -898,8 +899,9 @@ inline double gammaCorrection(double linear) #ifdef PSD_FAST_LAB_CONVERSION return linear; #else - // NOTE: pow() slow down the performance by a 4 factor :( - return (linear > 0.0031308 ? 1.055 * std::pow(linear, 1.0 / 2.4) - 0.055 : 12.92 * linear); + // Replacing fastPow with std::pow the conversion time is 2/3 times longer: using fastPow + // there are minimal differences in the conversion that are not visually noticeable. + return (linear > 0.0031308 ? 1.055 * fastPow(linear, 1.0 / 2.4) - 0.055 : 12.92 * linear); #endif }