28 void dither(
const quint8 *src, quint8 *dst,
int x,
int y)
const override
33 void dither(
const quint8 *srcRowStart,
int srcRowStride, quint8 *dstRowStart,
int dstRowStride,
int x,
int y,
int columns,
int rows)
const override
35 ditherImpl(srcRowStart, srcRowStride, dstRowStart, dstRowStride, x, y, columns, rows);
39 template<DitherType t = dType, typename std::enable_if<t == DITHER_NONE && std::is_same<srcCSTraits, dstCSTraits>::value,
void>
::type * =
nullptr>
inline void ditherImpl(
const quint8 *src, quint8 *dst,
int,
int)
const
41 memcpy(dst, src, srcCSTraits::pixelSize);
44 template<DitherType t = dType, typename std::enable_if<t == DITHER_NONE && !std::is_same<srcCSTraits, dstCSTraits>::value,
void>
::type * =
nullptr>
inline void ditherImpl(
const quint8 *src, quint8 *dst,
int,
int)
const
49 for (
uint channelIndex = 0; channelIndex < srcCSTraits::channels_nb; ++channelIndex) {
50 if (channelIndex == srcCSTraits::alpha_pos) {
55 nativeDst[channelIndex] = scaleToA<srcChannelsType, dstChannelsType>(nativeSrc[channelIndex]);
60 template<DitherType t = dType, typename std::enable_if<t != DITHER_NONE, void>::type * =
nullptr>
inline void ditherImpl(
const quint8 *src, quint8 *dst,
int x,
int y)
const
70 for (
uint channelIndex = 0; channelIndex < srcCSTraits::channels_nb; ++channelIndex) {
71 if (channelIndex == srcCSTraits::alpha_pos) {
79 float c = normalize<srcChannelsType>(nativeSrc[channelIndex]);
81 nativeDst[channelIndex] = denormalize<dstChannelsType>(c);
87 template<DitherType t = dType, typename std::enable_if<t == DITHER_NONE && std::is_same<srcCSTraits, dstCSTraits>::value,
void>
::type * =
nullptr>
88 inline void ditherImpl(
const quint8 *srcRowStart,
int srcRowStride, quint8 *dstRowStart,
int dstRowStride,
int,
int,
int columns,
int rows)
const
90 const quint8 *nativeSrc = srcRowStart;
91 quint8 *nativeDst = dstRowStart;
93 for (
int y = 0; y < rows; ++y) {
94 memcpy(nativeDst, nativeSrc, srcCSTraits::pixelSize * columns);
96 nativeSrc += srcRowStride;
97 nativeDst += dstRowStride;
101 template<DitherType t = dType, typename std::enable_if<t == DITHER_NONE && !std::is_same<srcCSTraits, dstCSTraits>::value,
void>
::type * =
nullptr>
102 inline void ditherImpl(
const quint8 *srcRowStart,
int srcRowStride, quint8 *dstRowStart,
int dstRowStride,
int,
int,
int columns,
int rows)
const
104 const quint8 *nativeSrc = srcRowStart;
105 quint8 *nativeDst = dstRowStart;
107 for (
int y = 0; y < rows; ++y) {
111 for (
int x = 0; x < columns; ++x) {
112 for (
uint channelIndex = 0; channelIndex < srcCSTraits::channels_nb; ++channelIndex) {
113 if (channelIndex == srcCSTraits::alpha_pos) {
118 dstPtr[channelIndex] = scaleToA<srcChannelsType, dstChannelsType>(srcPtr[channelIndex]);
122 srcPtr += srcCSTraits::channels_nb;
123 dstPtr += dstCSTraits::channels_nb;
126 nativeSrc += srcRowStride;
127 nativeDst += dstRowStride;
131 template<DitherType t = dType, typename std::enable_if<t != DITHER_NONE, void>::type * =
nullptr>
132 inline void ditherImpl(
const quint8 *srcRowStart,
int srcRowStride, quint8 *dstRowStart,
int dstRowStride,
int x,
int y,
int columns,
int rows)
const
134 const quint8 *nativeSrc = srcRowStart;
135 quint8 *nativeDst = dstRowStart;
139 for (
int a = 0; a < rows; ++a) {
143 for (
int b = 0; b < columns; ++b) {
144 float f =
factor(x + b, y + a);
146 for (
uint channelIndex = 0; channelIndex < srcCSTraits::channels_nb; ++channelIndex) {
147 if (channelIndex == srcCSTraits::alpha_pos) {
155 float c = normalize<srcChannelsType>(srcPtr[channelIndex]);
157 dstPtr[channelIndex] = denormalize<dstChannelsType>(c);
162 srcPtr += srcCSTraits::channels_nb;
163 dstPtr += dstCSTraits::channels_nb;
166 nativeSrc += srcRowStride;
167 nativeDst += dstRowStride;
173 template<typename A, typename U = srcCSTraits, typename std::enable_if<std::numeric_limits<A>::is_integer,
void>
::type * =
nullptr>
inline float normalize(
A value)
const
178 template<typename A, typename std::enable_if<!std::numeric_limits<A>::is_integer,
void>
::type * =
nullptr>
inline float normalize(
A value)
const
183 template<typename A, typename std::enable_if<std::numeric_limits<A>::is_integer,
void>
::type * =
nullptr>
inline A denormalize(
float value)
const
188 template<typename A, typename std::enable_if<!std::numeric_limits<A>::is_integer,
void>
::type * =
nullptr>
inline A denormalize(
float value)
const
193 template<
typename A,
typename B>
inline B scaleToA(
A c)
const
195 return denormalize<B>(normalize<A>(c));
198 template<typename U = typename dstCSTraits::channels_type, typename std::enable_if<!std::numeric_limits<U>::is_integer,
void>
::type * =
nullptr>
inline constexpr float scale()
const
203 template<typename U = typename dstCSTraits::channels_type, typename std::enable_if<std::numeric_limits<U>::is_integer,
void>
::type * =
nullptr>
inline constexpr float scale()
const
205 return 1.f /
static_cast<float>(1 << dstCSTraits::depth);
208 template<DitherType t = dType, typename std::enable_if<t == DITHER_BAYER, void>::type * =
nullptr>
inline float factor(
int x,
int y)
const
213 template<DitherType t = dType, typename std::enable_if<t == DITHER_BLUE_NOISE, void>::type * =
nullptr>
inline float factor(
int x,
int y)
const
229 static_assert(std::is_same<srcCSTraits, KoCmykU8Traits>::value || std::is_same<srcCSTraits, KoCmykU16Traits>::value ||
231 std::is_same<srcCSTraits, KoCmykF16Traits>::value ||
233 std::is_same<srcCSTraits, KoCmykF32Traits>::value,
234 "Missing colorspace, add a transform case!");
float value(const T *src, size_t ch)
void addCmykDitherOpsByDepth(KoColorSpace *cs, const KoID &dstDepth)
void addStandardDitherOps(KoColorSpace *cs)
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
float normalize(A value) const
void ditherImpl(const quint8 *srcRowStart, int srcRowStride, quint8 *dstRowStart, int dstRowStride, int, int, int columns, int rows) const
void dither(const quint8 *src, quint8 *dst, int x, int y) const override
float factor(int x, int y) const
constexpr float scale() const
KisCmykDitherOpImpl(const KoID &srcId, const KoID &dstId)
typename dstCSTraits::channels_type dstChannelsType
float normalize(A value) const
A denormalize(float value) const
void ditherImpl(const quint8 *src, quint8 *dst, int x, int y) const
void ditherImpl(const quint8 *src, quint8 *dst, int, int) const
void ditherImpl(const quint8 *srcRowStart, int srcRowStride, quint8 *dstRowStart, int dstRowStride, int x, int y, int columns, int rows) const
void dither(const quint8 *srcRowStart, int srcRowStride, quint8 *dstRowStart, int dstRowStride, int x, int y, int columns, int rows) const override
typename srcCSTraits::channels_type srcChannelsType
DitherType type() const override
static _Tdst scaleToA(_T a)
virtual quint32 pixelSize() const =0
virtual void addDitherOp(KisDitherOp *op)
virtual KoID colorDepthId() const =0
float apply_dither(float f, float d, float s)
float dither_factor_bayer_8(int x, int y)
float dither_factor_blue_noise_64(int x, int y)