Krita Source Code Documentation
Loading...
Searching...
No Matches
KoClipMaskApplicator.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef KOCLIPMASKAPPLICATOR_H
8#define KOCLIPMASKAPPLICATOR_H
9
10#include <krita_xsimd_macos_workaround.h>
11
12#include <KoStreamedMath.h>
14#include <QDebug>
15
16template<typename _impl,
17 typename EnableDummyType = void>
19 virtual void applyLuminanceMask(quint8 *pixels, quint8 *maskPixels, const int nPixels) const override {
20 KoClipMaskApplicatorBase::fallbackLuminanceMask(pixels, maskPixels, nPixels);
21 }
22};
23
24#if !defined(XSIMD_NO_SUPPORTED_ARCHITECTURE) && !defined(DISABLE_CLIP_MASK_PAINTER_ON_MACOS)
25
26template<typename _impl>
28 typename std::enable_if<!std::is_same<_impl, xsimd::generic>::value>::type> : public KoClipMaskApplicatorBase
29{
32
33 const uint_v mask = 0xFF;
34 const quint32 colorChannelsMask = 0x00FFFFFF;
35 const float redLum = 0.2125f;
36 const float greenLum = 0.7154f;
37 const float blueLum = 0.0721f;
38 const float normCoeff = 1.0f / 255.0f;
39
40 virtual void applyLuminanceMask(quint8 *pixels,
41 quint8 *maskPixels,
42 const int nPixels) const override {
43
44 const int block = nPixels / static_cast<int>(float_v::size);
45 const int block2 = nPixels % static_cast<int>(float_v::size);
46 const int vectorPixelStride = 4 * static_cast<int>(float_v::size);
47
48 for (int i = 0; i < block; i++) {
49 uint_v shapeData = uint_v::load_unaligned(reinterpret_cast<const quint32 *>(pixels));
50 const uint_v maskData = uint_v::load_unaligned(reinterpret_cast<const quint32 *>(maskPixels));
51
52 const float_v maskAlpha = xsimd::to_float(xsimd::bitwise_cast_compat<int>((maskData >> 24) & mask));
53 const float_v maskRed = xsimd::to_float(xsimd::bitwise_cast_compat<int>((maskData >> 16) & mask));
54 const float_v maskGreen = xsimd::to_float(xsimd::bitwise_cast_compat<int>((maskData >> 8) & mask));
55 const float_v maskBlue = xsimd::to_float(xsimd::bitwise_cast_compat<int>((maskData) & mask));
56 const float_v maskValue = maskAlpha * ((redLum * maskRed) + (greenLum * maskGreen) + (blueLum * maskBlue)) * normCoeff;
57
58 const float_v pixelAlpha = xsimd::to_float(xsimd::bitwise_cast_compat<int>(shapeData >> 24U)) * normCoeff * maskValue;
59 const uint_v pixelAlpha_i = xsimd::bitwise_cast_compat<unsigned int>(xsimd::nearbyint_as_int(pixelAlpha));
60 shapeData = (shapeData & colorChannelsMask) | (pixelAlpha_i << 24);
61
62 shapeData.store_unaligned(reinterpret_cast<typename uint_v::value_type *>(pixels));
63
64 pixels += vectorPixelStride;
65 maskPixels += vectorPixelStride;
66 }
67
68 KoClipMaskApplicatorBase::fallbackLuminanceMask(pixels, maskPixels, block2);
69 }
70};
71
72#endif /* !defined(XSIMD_NO_SUPPORTED_ARCHITECTURE) && !defined(DISABLE_CLIP_MASK_PAINTER_ON_MACOS) */
73
74#endif // KOCLIPMASKAPPLICATOR_H
virtual void fallbackLuminanceMask(quint8 *pixels, quint8 *maskPixels, const int nPixels) const
fallbackLuminanceMask This is the fallback algorithm for leftover pixels that for whatever reason can...
virtual void applyLuminanceMask(quint8 *pixels, quint8 *maskPixels, const int nPixels) const override
applyLuminanceMask This applies an ARGB32 mask to an ARGB32 image as per w3c specs....
virtual void applyLuminanceMask(quint8 *pixels, quint8 *maskPixels, const int nPixels) const override
applyLuminanceMask This applies an ARGB32 mask to an ARGB32 image as per w3c specs....
xsimd::batch< unsigned int, _impl > uint_v
xsimd::batch< float, _impl > float_v