1 /***************************************************************************** 2 3 Dither.h 4 Author: Laurent de Soras, 2021 5 6 --- Legal stuff --- 7 8 This program is free software. It comes without any warranty, to 9 the extent permitted by applicable law. You can redistribute it 10 and/or modify it under the terms of the Do What The Fuck You Want 11 To Public License, Version 2, as published by Sam Hocevar. See 12 http://www.wtfpl.net/ for more details. 13 14 *Tab=3***********************************************************************/ 15 16 17 18 #pragma once 19 #if ! defined (fmtcl_Dither_HEADER_INCLUDED) 20 #define fmtcl_Dither_HEADER_INCLUDED 21 22 23 24 /*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 25 26 #include "conc/ObjPool.h" 27 #include "fmtcl/ColorFamily.h" 28 #include "fmtcl/BitBltConv.h" 29 #include "fmtcl/ErrDifBuf.h" 30 #include "fmtcl/ErrDifBufFactory.h" 31 #include "fmtcl/MatrixWrap.h" 32 #include "fmtcl/SplFmt.h" 33 #include "fstb/def.h" 34 #include "fstb/ArrayAlign.h" 35 36 #if (fstb_ARCHI == fstb_ARCHI_X86) 37 #include <emmintrin.h> 38 #endif // fstb_ARCHI_X86 39 40 #include <array> 41 #include <memory> 42 #include <vector> 43 44 45 46 namespace fmtcl 47 { 48 49 50 51 class Dither 52 { 53 54 /*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 55 56 public: 57 58 static constexpr int _max_nbr_planes = 4; 59 60 // Maximum width in pixels for the halftone patterns. Must be a power of 2. 61 static constexpr int _pat_max_size = 1024; 62 63 enum DMode 64 { 65 DMode_ROUND_ALIAS = -1, 66 DMode_BAYER = 0, 67 DMode_ROUND, // 1 68 DMode_FAST, // 2 69 DMode_FILTERLITE, // 3 70 DMode_STUCKI, // 4 71 DMode_ATKINSON, // 5 72 DMode_FLOYD, // 6 73 DMode_OSTRO, // 7 74 DMode_VOIDCLUST, // 8 75 DMode_QUASIRND, // 9 76 77 DMode_NBR_ELT, 78 79 DMode_VERY_LARGE = 0x12345678 80 }; 81 82 explicit Dither ( 83 SplFmt src_fmt, int src_res, bool src_full_flag, 84 SplFmt dst_fmt, int dst_res, bool dst_full_flag, 85 ColorFamily color_fam, int nbr_planes, int w, 86 DMode dmode, int pat_size, double ampo, double ampn, 87 bool dyn_flag, bool static_noise_flag, bool correlated_planes_flag, 88 bool tpdfo_flag, bool tpdfn_flag, 89 bool sse2_flag, bool avx2_flag 90 ); 91 92 void process_plane (uint8_t *dst_ptr, int dst_stride, const uint8_t *src_ptr, int src_stride, int w, int h, int frame_index, int plane_index); 93 94 95 96 /*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 97 98 protected: 99 100 101 102 /*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 103 104 private: 105 106 // Must be a power of 2 (because cycled with & as modulo) 107 static constexpr int _pat_period = 4; 108 109 // Minimum pattern size to execute operations, constrained by SIMD vector 110 // sizes. Original pattern can be smaller. Must be a power of 2 111 static constexpr int _pat_min_size = 8; 112 113 // Bit depth of the amplitude fractionnal part. The whole thing is 7 bits, 114 // and we need a few bits for the integer part. 115 static constexpr int _amp_bits = 5; 116 117 // Resolution (bits) of the temporary data for error diffusion when source 118 // bitdepth is not high enough (relative to the destination bitdepth) to 119 // guarantee an accurate error diffusion. 120 static constexpr int _err_res = 24; 121 122 // Maximum width (pixels) for variable formats 123 static constexpr int _max_unk_width = 65536; 124 125 class SclInf 126 { 127 public: 128 BitBltConv::ScaleInfo 129 _info; 130 BitBltConv::ScaleInfo * // 0 if _info is not used. 131 _ptr = 0; 132 }; 133 134 typedef int16_t PatDataType; 135 typedef MatrixWrap <PatDataType> PatData; 136 typedef std::array <PatData, _pat_period> PatDataArray; 137 138 class AmpInfo 139 { 140 public: 141 int _o_i = 0; // [0 ; 127], 1.0 = 1 << _amp_bits 142 int _n_i = 0; // [0 ; 127], 1.0 = 1 << _amp_bits 143 int _e_i = 0; // [0 ; 2047], 1.0 = 256 144 float _e_f = 0; 145 float _n_f = 0; 146 }; 147 148 class SegContext 149 { 150 public: 151 inline const PatDataType * 152 extract_pattern_row () const noexcept; 153 const PatData* _pattern_ptr = nullptr; // Ordered dithering 154 uint32_t _rnd_state = 0; // Anything excepted fast mode 155 const BitBltConv::ScaleInfo * // Float processing 156 _scale_info_ptr = nullptr; 157 ErrDifBuf * // Error diffusion 158 _ed_buf_ptr = nullptr; 159 int _y = -1; // Ordered dithering and error diffusion 160 uint32_t _qrs_seed = 0; // For the quasirandom sequences 161 AmpInfo _amp; 162 }; 163 164 void build_dither_pat (); 165 void build_dither_pat_round (); 166 void build_dither_pat_bayer (); 167 void build_dither_pat_void_and_cluster (bool aztec_flag); 168 void expand_dither_pat (const PatData &small); 169 void build_next_dither_pat (); 170 void copy_dither_pat_rotate (PatData &dst, const PatData &src, int angle) noexcept; 171 void init_fnc_fast () noexcept; 172 void init_fnc_ordered () noexcept; 173 void init_fnc_quasirandom () noexcept; 174 void init_fnc_errdiff () noexcept; 175 176 void dither_plane (uint8_t *dst_ptr, int dst_stride, const uint8_t *src_ptr, int src_stride, int w, int h, const BitBltConv::ScaleInfo &scale_info, int frame_index, int plane_index); 177 178 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 179 static void process_seg_fast_int_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &/*ctx*/) noexcept; 180 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE> 181 static void process_seg_fast_flt_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 182 183 #if (fstb_ARCHI == fstb_ARCHI_X86) 184 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, SplFmt DST_FMT, int DST_BITS, SplFmt SRC_FMT, int SRC_BITS> 185 static void process_seg_fast_int_int_sse2 (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &/*ctx*/) noexcept; 186 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, SplFmt DST_FMT, int DST_BITS, SplFmt SRC_FMT> 187 static void process_seg_fast_flt_int_sse2 (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 188 #endif 189 190 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 191 static void process_seg_ord_int_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 192 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE> 193 static void process_seg_ord_flt_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 194 195 #if (fstb_ARCHI == fstb_ARCHI_X86) 196 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, SplFmt DST_FMT, int DST_BITS, SplFmt SRC_FMT, int SRC_BITS> 197 static void process_seg_ord_int_int_sse2 (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 198 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, SplFmt DST_FMT, int DST_BITS, SplFmt SRC_FMT> 199 static void process_seg_ord_flt_int_sse2 (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 200 #endif 201 202 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 203 static void process_seg_qrs_int_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 204 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE> 205 static void process_seg_qrs_flt_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 206 207 #if (fstb_ARCHI == fstb_ARCHI_X86) 208 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, SplFmt DST_FMT, int DST_BITS, SplFmt SRC_FMT, int SRC_BITS> 209 static void process_seg_qrs_int_int_sse2 (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 210 template <bool S_FLAG, bool TO_FLAG, bool TN_FLAG, SplFmt DST_FMT, int DST_BITS, SplFmt SRC_FMT> 211 static void process_seg_qrs_flt_int_sse2 (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 212 #endif 213 214 template <bool S_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS, typename DFNC> 215 static fstb_FORCEINLINE void 216 process_seg_common_int_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx, DFNC dither_fnc) noexcept; 217 template <bool S_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE, typename DFNC> 218 static fstb_FORCEINLINE void 219 process_seg_common_flt_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx, DFNC dither_fnc) noexcept; 220 template <bool T_FLAG> 221 static fstb_FORCEINLINE int 222 generate_dith_n_scalar (uint32_t &rnd_state) noexcept; 223 static fstb_FORCEINLINE int 224 remap_tpdf_scalar (int d) noexcept; 225 226 #if (fstb_ARCHI == fstb_ARCHI_X86) 227 template <bool S_FLAG, bool TN_FLAG, SplFmt DST_FMT, int DST_BITS, SplFmt SRC_FMT, int SRC_BITS, typename DFNC> 228 static fstb_FORCEINLINE void 229 process_seg_common_int_int_sse2 (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx, DFNC dither_fnc) noexcept; 230 template <bool S_FLAG, bool TN_FLAG, SplFmt DST_FMT, int DST_BITS, SplFmt SRC_FMT, typename DFNC> 231 static fstb_FORCEINLINE void 232 process_seg_common_flt_int_sse2 (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx, DFNC dither_fnc) noexcept; 233 template <bool T_FLAG> 234 static fstb_FORCEINLINE __m128i 235 generate_dith_n_vec (uint32_t &rnd_state) noexcept; 236 static fstb_FORCEINLINE __m128i 237 remap_tpdf_vec (__m128i d) noexcept; 238 #endif 239 240 template <bool S_FLAG, bool TN_FLAG, class ERRDIF> 241 static void process_seg_errdif_int_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 242 template <bool S_FLAG, bool TN_FLAG, class ERRDIF> 243 static void process_seg_errdif_flt_int_cpp (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) noexcept; 244 245 static inline void 246 generate_rnd (uint32_t &state) noexcept; 247 static inline void 248 generate_rnd_eol (uint32_t &state) noexcept; 249 250 template <bool S_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 251 static inline void 252 quantize_pix_int (DST_TYPE * fstb_RESTRICT dst_ptr, const SRC_TYPE * fstb_RESTRICT src_ptr, SRC_TYPE &src_raw, int x, int & fstb_RESTRICT err, uint32_t &rnd_state, int ampe_i, int ampn_i) noexcept; 253 template <bool S_FLAG, bool TN_FLAG, class DST_TYPE, int DST_BITS, class SRC_TYPE> 254 static inline void 255 quantize_pix_flt (DST_TYPE * fstb_RESTRICT dst_ptr, const SRC_TYPE * fstb_RESTRICT src_ptr, SRC_TYPE &src_raw, int x, float & fstb_RESTRICT err, uint32_t &rnd_state, float ampe_f, float ampn_f, float mul, float add) noexcept; 256 257 template <class DT, int DB, class ST, int SB, int EL> 258 class ErrDifAddParam 259 { 260 public: 261 typedef DT DstType; 262 typedef ST SrcType; 263 static constexpr int _dst_bits = DB; 264 static constexpr int _src_bits = SB; 265 static constexpr int _nbr_err_lines = EL; 266 }; 267 268 template <class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 269 class DiffuseFloydSteinberg 270 : public ErrDifAddParam <DST_TYPE, DST_BITS, SRC_TYPE, SRC_BITS, 1> 271 { 272 public: 273 template <int DIR> 274 static fstb_FORCEINLINE void 275 diffuse (int err, int & fstb_RESTRICT err_nxt0, int & fstb_RESTRICT err_nxt1, int16_t * fstb_RESTRICT err0_ptr, int16_t * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 276 template <int DIR> 277 static fstb_FORCEINLINE void 278 diffuse (float err, float & fstb_RESTRICT err_nxt0, float & fstb_RESTRICT err_nxt1, float * fstb_RESTRICT err0_ptr, float * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 279 template <typename EB> 280 static fstb_FORCEINLINE void 281 prepare_next_line (EB * fstb_RESTRICT err_ptr) noexcept; 282 private: 283 template <int DIR, typename ET, typename EB> 284 static fstb_FORCEINLINE void 285 spread_error (ET e1, ET e3, ET e5, ET e7, ET & fstb_RESTRICT err_nxt0, EB * fstb_RESTRICT err0_ptr) noexcept; 286 }; 287 288 template <class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 289 class DiffuseFilterLite 290 : public ErrDifAddParam <DST_TYPE, DST_BITS, SRC_TYPE, SRC_BITS, 1> 291 { 292 public: 293 template <int DIR> 294 static fstb_FORCEINLINE void 295 diffuse (int err, int & fstb_RESTRICT err_nxt0, int & fstb_RESTRICT err_nxt1, int16_t * fstb_RESTRICT err0_ptr, int16_t * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 296 template <int DIR> 297 static fstb_FORCEINLINE void 298 diffuse (float err, float & fstb_RESTRICT err_nxt0, float & fstb_RESTRICT err_nxt1, float * fstb_RESTRICT err0_ptr, float * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 299 template <typename EB> 300 static fstb_FORCEINLINE void 301 prepare_next_line (EB * fstb_RESTRICT err_ptr) noexcept; 302 private: 303 template <int DIR, typename ET, typename EB> 304 static fstb_FORCEINLINE void 305 spread_error (ET e1, ET e2, ET & fstb_RESTRICT err_nxt0, EB * fstb_RESTRICT err0_ptr) noexcept; 306 }; 307 308 template <class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 309 class DiffuseStucki 310 : public ErrDifAddParam <DST_TYPE, DST_BITS, SRC_TYPE, SRC_BITS, 2> 311 { 312 public: 313 template <int DIR> 314 static fstb_FORCEINLINE void 315 diffuse (int err, int & fstb_RESTRICT err_nxt0, int & fstb_RESTRICT err_nxt1, int16_t * fstb_RESTRICT err0_ptr, int16_t * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 316 template <int DIR> 317 static fstb_FORCEINLINE void 318 diffuse (float err, float & fstb_RESTRICT err_nxt0, float & fstb_RESTRICT err_nxt1, float * fstb_RESTRICT err0_ptr, float * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 319 template <typename EB> 320 static fstb_FORCEINLINE void 321 prepare_next_line (EB * fstb_RESTRICT err_ptr) noexcept; 322 private: 323 template <int DIR, typename ET, typename EB> 324 static fstb_FORCEINLINE void 325 spread_error (ET e1, ET e2, ET e4, ET e8, ET & fstb_RESTRICT err_nxt0, ET & fstb_RESTRICT err_nxt1, EB * fstb_RESTRICT err0_ptr, EB * fstb_RESTRICT err1_ptr) noexcept; 326 }; 327 328 template <class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 329 class DiffuseAtkinson 330 : public ErrDifAddParam <DST_TYPE, DST_BITS, SRC_TYPE, SRC_BITS, 2> 331 { 332 public: 333 template <int DIR> 334 static fstb_FORCEINLINE void 335 diffuse (int err, int & fstb_RESTRICT err_nxt0, int & fstb_RESTRICT err_nxt1, int16_t * fstb_RESTRICT err0_ptr, int16_t * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 336 template <int DIR> 337 static fstb_FORCEINLINE void 338 diffuse (float err, float & fstb_RESTRICT err_nxt0, float & fstb_RESTRICT err_nxt1, float * fstb_RESTRICT err0_ptr, float * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 339 template <typename EB> 340 static fstb_FORCEINLINE void 341 prepare_next_line (EB * fstb_RESTRICT err_ptr) noexcept; 342 private: 343 template <int DIR, typename ET, typename EB> 344 static fstb_FORCEINLINE void 345 spread_error (ET e1, ET & fstb_RESTRICT err_nxt0, ET & fstb_RESTRICT err_nxt1, EB * fstb_RESTRICT err0_ptr, EB * fstb_RESTRICT err1_ptr) noexcept; 346 }; 347 348 class DiffuseOstromoukhovBase 349 { 350 public: 351 struct TableEntry 352 { 353 int _c0; 354 int _c1; 355 int _c2; // Actually not used 356 int _sum; 357 float _inv_sum; // Possible optimization: store 1/_c0 and 1/_c1 instead of this field. 358 }; 359 360 static constexpr int _t_bits = 8; 361 static constexpr int _t_len = 1 << _t_bits; 362 static constexpr int _t_mask = _t_len - 1; 363 364 static const std::array <TableEntry, _t_len> 365 _table; 366 }; 367 368 template <int DST_BITS, int SRC_BITS> 369 class DiffuseOstromoukhovBase2 370 : public DiffuseOstromoukhovBase 371 { 372 public: 373 template <class SRC_TYPE> 374 static inline int 375 get_index (SRC_TYPE src_raw) noexcept; 376 static inline int 377 get_index (float src_raw) noexcept; 378 }; 379 380 template <class DST_TYPE, int DST_BITS, class SRC_TYPE, int SRC_BITS> 381 class DiffuseOstromoukhov 382 : public ErrDifAddParam <DST_TYPE, DST_BITS, SRC_TYPE, SRC_BITS, 1> 383 , public DiffuseOstromoukhovBase2 <DST_BITS, SRC_BITS> 384 { 385 public: 386 typedef DiffuseOstromoukhov <DST_TYPE, DST_BITS, SRC_TYPE, SRC_BITS> ThisType; 387 template <int DIR> 388 static fstb_FORCEINLINE void 389 diffuse (int err, int & fstb_RESTRICT err_nxt0, int & fstb_RESTRICT err_nxt1, int16_t * fstb_RESTRICT err0_ptr, int16_t * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 390 template <int DIR> 391 static fstb_FORCEINLINE void 392 diffuse (float err, float & fstb_RESTRICT err_nxt0, float & fstb_RESTRICT err_nxt1, float * fstb_RESTRICT err0_ptr, float * fstb_RESTRICT err1_ptr, SRC_TYPE src_raw) noexcept; 393 template <typename EB> 394 static fstb_FORCEINLINE void 395 prepare_next_line (EB * fstb_RESTRICT err_ptr) noexcept; 396 private: 397 template <int DIR, typename ET, typename EB> 398 static fstb_FORCEINLINE void 399 spread_error (ET e1, ET e2, ET e3, ET & fstb_RESTRICT err_nxt0, EB * fstb_RESTRICT err0_ptr) noexcept; 400 }; 401 402 SplFmt _splfmt_src = SplFmt_ILLEGAL; 403 SplFmt _splfmt_dst = SplFmt_ILLEGAL; 404 int _src_res = 0; 405 int _dst_res = 0; 406 bool _full_range_in_flag = false; 407 bool _full_range_out_flag = false; 408 ColorFamily _color_fam = ColorFamily_INVALID; 409 int _nbr_planes = 0; 410 411 std::array <SclInf, _max_nbr_planes> 412 _scale_info_arr; 413 bool _upconv_flag = false; 414 bool _sse2_flag = false; 415 bool _avx2_flag = false; 416 bool _range_def_flag = false; 417 418 int _dmode = DMode_FAST; 419 bool _alt_flag = false; 420 int _pat_size = 32; // Must be a power of 2 421 double _ampo = 1; 422 double _ampn = 0; 423 bool _dyn_flag = false; 424 bool _static_noise_flag = false; 425 bool _correlated_planes_flag = false; 426 bool _tpdfo_flag = false; 427 bool _tpdfn_flag = false; 428 429 bool _errdif_flag = false; // Indicates a dithering method using error diffusion. 430 bool _simple_flag = false; // Simplified implementation for ampo == 1 and ampn == 0 431 PatDataArray _dither_pat_arr; // Contains levels for ordered dithering 432 433 AmpInfo _amp; 434 435 conc::ObjPool <ErrDifBuf> 436 _buf_pool; 437 std::unique_ptr <ErrDifBufFactory> 438 _buf_factory_uptr; 439 440 void (* _process_seg_int_int_ptr) (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) = nullptr; 441 void (* _process_seg_flt_int_ptr) (uint8_t * fstb_RESTRICT dst_ptr, const uint8_t * fstb_RESTRICT src_ptr, int w, SegContext &ctx) = nullptr; 442 443 444 445 /*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 446 447 private: 448 449 Dither () = delete; 450 Dither (const Dither &other) = delete; 451 Dither (Dither &&other) = delete; 452 Dither & operator = (const Dither &other) = delete; 453 Dither & operator = (Dither &&other) = delete; 454 bool operator == (const Dither &other) const = delete; 455 bool operator != (const Dither &other) const = delete; 456 457 }; // class Dither 458 459 460 461 } // namespace fmtcl 462 463 464 465 //#include "fmtcl/Dither.hpp" 466 467 468 469 #endif // fmtcl_Dither_HEADER_INCLUDED 470 471 472 473 /*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 474