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