1 /***************************************************************************** 2 3 TransLut.h 4 Author: Laurent de Soras, 2015 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://sam.zoy.org/wtfpl/COPYING for more details. 13 14 *Tab=3***********************************************************************/ 15 16 17 18 #pragma once 19 #if ! defined (fmtcl_TransLut_HEADER_INCLUDED) 20 #define fmtcl_TransLut_HEADER_INCLUDED 21 22 #if defined (_MSC_VER) 23 #pragma warning (4 : 4250) 24 #endif 25 26 27 28 /*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 29 30 #include "fstb/def.h" 31 32 #include "fmtcl/ArrayMultiType.h" 33 #include "fmtcl/Plane.h" 34 #include "fmtcl/PlaneRO.h" 35 #include "fmtcl/SplFmt.h" 36 37 #include <cstdint> 38 39 40 41 namespace fmtcl 42 { 43 44 45 46 class TransOpInterface; 47 48 class TransLut 49 { 50 51 /*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 52 53 public: 54 55 typedef TransLut ThisType; 56 57 static constexpr int LINLUT_RES_L2 = 14; // log2 of the linear table resolution (size of a unity segment) 58 static constexpr int LINLUT_MIN_F = -1; // Min value for float LUTs 59 static constexpr int LINLUT_MAX_F = 2; // Max value for float LUTs 60 61 static constexpr int LINLUT_SIZE_F = ((LINLUT_MAX_F - LINLUT_MIN_F) << LINLUT_RES_L2) + 1; 62 63 // Log LUT are only for floating point input 64 static constexpr int LOGLUT_MIN_L2 = -16; // log2(x) for the first index in a log table (negative) 65 static constexpr int LOGLUT_MAX_L2 = 16; // log2(x) for the last index in a log table (positive) 66 static constexpr int LOGLUT_RES_L2 = 10; // log2 of the log table resolution (size of each [x ; 2*x[ segment). 67 68 static constexpr int LOGLUT_HSIZE = ((LOGLUT_MAX_L2 - LOGLUT_MIN_L2) << LOGLUT_RES_L2) + 1; // Table made of half-open segments (and whitout x=0) + 1 more value for LOGLUT_MAX, closing the last segment. 69 static constexpr int LOGLUT_SIZE = 2 * LOGLUT_HSIZE + 1; // Negative + 0 + positive 70 71 union FloatIntMix 72 { 73 float _f; 74 uint32_t _i; 75 }; 76 77 class MapperLin 78 { 79 public: 80 explicit MapperLin (int lut_size, double range_beg, double range_lst) noexcept; get_lut_size()81 inline int get_lut_size () const noexcept { return (_lut_size); } 82 inline double find_val (int index) const noexcept; 83 static inline void 84 find_index (const FloatIntMix &val, int &index, float &frac) noexcept; 85 private: 86 const int _lut_size = 0; 87 const double _range_beg = 0; 88 const double _step = 0; 89 }; 90 91 class MapperLog 92 { 93 public: get_lut_size()94 inline int get_lut_size () const noexcept { return (LOGLUT_SIZE); } 95 inline double find_val (int index) const noexcept; 96 static inline void 97 find_index (const FloatIntMix &val, int &index, float &frac) noexcept; 98 }; 99 100 explicit TransLut (const TransOpInterface &curve, bool log_flag, SplFmt src_fmt, int src_bits, bool src_full_flag, SplFmt dst_fmt, int dst_bits, bool dst_full_flag, bool sse2_flag, bool avx2_flag); ~TransLut()101 virtual ~TransLut () {} 102 103 void process_plane (const Plane <> &dst, const PlaneRO <> &src, int w, int h) const noexcept; 104 105 static bool is_loglut_req (const TransOpInterface &curve); 106 107 108 109 /*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 110 111 protected: 112 113 114 115 /*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 116 117 private: 118 119 template <class T> 120 class Convert 121 { 122 public: 123 static inline T 124 cast (float val) noexcept; 125 }; 126 127 void generate_lut (const TransOpInterface &curve); 128 template <class T> 129 void generate_lut_int (const TransOpInterface &curve, int lut_size, double range_beg, double range_lst, double mul, double add); 130 template <class T, class M> 131 void generate_lut_flt (const TransOpInterface &curve, const M &mapper); 132 133 void init_proc_fnc (); 134 #if (fstb_ARCHI == fstb_ARCHI_X86) 135 void init_proc_fnc_sse2 (int selector); 136 void init_proc_fnc_avx2 (int selector); 137 #endif 138 139 template <class TS, class TD> 140 void process_plane_int_any_cpp (Plane <> dst, PlaneRO <> src, int w, int h) const noexcept; 141 template <class TD, class M> 142 void process_plane_flt_any_cpp (Plane <> dst, PlaneRO <> src, int w, int h) const noexcept; 143 #if (fstb_ARCHI == fstb_ARCHI_X86) 144 template <class TD, class M> 145 void process_plane_flt_any_sse2 (Plane <> dst, PlaneRO <> src, int w, int h) const noexcept; 146 template <class TD, class M> 147 void process_plane_flt_any_avx2 (Plane <> dst, PlaneRO <> src, int w, int h) const noexcept; 148 #endif 149 150 bool _loglut_flag = false; 151 152 SplFmt _src_fmt = SplFmt_ILLEGAL; 153 int _src_bits = 0; 154 bool _src_full_flag = false; 155 156 SplFmt _dst_fmt = SplFmt_ILLEGAL; 157 int _dst_bits = 0; 158 bool _dst_full_flag = false; 159 160 bool _sse2_flag = false; 161 bool _avx2_flag = false; 162 163 void (ThisType:: * 164 _process_plane_ptr) (Plane <> dst, PlaneRO <> src, int w, int h) const noexcept = nullptr; 165 166 // Opaque array, contains uint8_t, uint16_t or float depending on the 167 // output datatype. Table size is always 256, 65536 or 65536*3+1 168 // (float input, covering -1 to +2 range inclusive). 169 ArrayMultiType _lut; 170 171 172 173 /*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 174 175 private: 176 177 TransLut () = delete; 178 TransLut (const TransLut &other) = delete; 179 TransLut & operator = (const TransLut &other) = delete; 180 bool operator == (const TransLut &other) const = delete; 181 bool operator != (const TransLut &other) const = delete; 182 183 }; // class TransLut 184 185 186 187 } // namespace fmtcl 188 189 190 191 //#include "fmtcl/TransLut.hpp" 192 193 194 195 #endif // fmtcl_TransLut_HEADER_INCLUDED 196 197 198 199 /*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 200