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