File indexing completed on 2024-12-22 04:09:15
0001 /* 0002 * SPDX-FileCopyrightText: 2023 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KOCLIPMASKAPPLICATOR_H 0008 #define KOCLIPMASKAPPLICATOR_H 0009 0010 #include <krita_xsimd_macos_workaround.h> 0011 0012 #include <KoStreamedMath.h> 0013 #include <KoClipMaskApplicatorBase.h> 0014 #include <QDebug> 0015 0016 template<typename _impl, 0017 typename EnableDummyType = void> 0018 struct KoClipMaskApplicator : public KoClipMaskApplicatorBase { 0019 virtual void applyLuminanceMask(quint8 *pixels, quint8 *maskPixels, const int nPixels) const override { 0020 KoClipMaskApplicatorBase::fallbackLuminanceMask(pixels, maskPixels, nPixels); 0021 } 0022 }; 0023 0024 #if defined(HAVE_XSIMD) && !defined(XSIMD_NO_SUPPORTED_ARCHITECTURE) && !defined(DISABLE_CLIP_MASK_PAINTER_ON_MACOS) 0025 0026 template<typename _impl> 0027 struct KoClipMaskApplicator<_impl, 0028 typename std::enable_if<!std::is_same<_impl, xsimd::generic>::value>::type> : public KoClipMaskApplicatorBase 0029 { 0030 using uint_v = typename KoStreamedMath<_impl>::uint_v; 0031 using float_v = typename KoStreamedMath<_impl>::float_v; 0032 0033 const uint_v mask = 0xFF; 0034 const quint32 colorChannelsMask = 0x00FFFFFF; 0035 const float redLum = 0.2125f; 0036 const float greenLum = 0.7154f; 0037 const float blueLum = 0.0721f; 0038 const float normCoeff = 1.0f / 255.0f; 0039 0040 virtual void applyLuminanceMask(quint8 *pixels, 0041 quint8 *maskPixels, 0042 const int nPixels) const override { 0043 0044 const int block = nPixels / static_cast<int>(float_v::size); 0045 const int block2 = nPixels % static_cast<int>(float_v::size); 0046 const int vectorPixelStride = 4 * static_cast<int>(float_v::size); 0047 0048 for (int i = 0; i < block; i++) { 0049 uint_v shapeData = uint_v::load_unaligned(reinterpret_cast<const quint32 *>(pixels)); 0050 const uint_v maskData = uint_v::load_unaligned(reinterpret_cast<const quint32 *>(maskPixels)); 0051 0052 const float_v maskAlpha = xsimd::to_float(xsimd::bitwise_cast_compat<int>((maskData >> 24) & mask)); 0053 const float_v maskRed = xsimd::to_float(xsimd::bitwise_cast_compat<int>((maskData >> 16) & mask)); 0054 const float_v maskGreen = xsimd::to_float(xsimd::bitwise_cast_compat<int>((maskData >> 8) & mask)); 0055 const float_v maskBlue = xsimd::to_float(xsimd::bitwise_cast_compat<int>((maskData) & mask)); 0056 const float_v maskValue = maskAlpha * ((redLum * maskRed) + (greenLum * maskGreen) + (blueLum * maskBlue)) * normCoeff; 0057 0058 const float_v pixelAlpha = xsimd::to_float(xsimd::bitwise_cast_compat<int>(shapeData >> 24U)) * normCoeff * maskValue; 0059 const uint_v pixelAlpha_i = xsimd::bitwise_cast_compat<unsigned int>(xsimd::nearbyint_as_int(pixelAlpha)); 0060 shapeData = (shapeData & colorChannelsMask) | (pixelAlpha_i << 24); 0061 0062 shapeData.store_unaligned(reinterpret_cast<typename uint_v::value_type *>(pixels)); 0063 0064 pixels += vectorPixelStride; 0065 maskPixels += vectorPixelStride; 0066 } 0067 0068 KoClipMaskApplicatorBase::fallbackLuminanceMask(pixels, maskPixels, block2); 0069 } 0070 }; 0071 0072 #endif /* HAVE_XSIMD */ 0073 0074 #endif // KOCLIPMASKAPPLICATOR_H