1 /*****************************************************************************
2 
3         FilterResize.h
4         Author: Laurent de Soras, 2011
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 #if ! defined (fmtcl_FilterResize_HEADER_INCLUDED)
19 #define	fmtcl_FilterResize_HEADER_INCLUDED
20 
21 #if defined (_MSC_VER)
22 	#pragma once
23 	#pragma warning (4 : 4250)
24 #endif
25 
26 
27 
28 /*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
29 
30 #include "fstb/def.h"
31 #include "conc/ObjPool.h"
32 #include "fmtcl/BitBltConv.h"
33 #include "fmtcl/SplFmt.h"
34 #include "fmtcl/ResizeData.h"
35 #include "fmtcl/ResizeDataFactory.h"
36 #include "fmtcl/Scaler.h"
37 #include "avstp.h"
38 #include "AvstpWrapper.h"
39 
40 #include <vector>
41 #include <memory>
42 
43 #include <cstdint>
44 
45 
46 
47 namespace fmtcl
48 {
49 
50 
51 
52 class ContFirInterface;
53 class ResampleSpecPlane;
54 
55 class FilterResize
56 {
57 
58 /*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
59 
60 public:
61 
62 	enum Dir
63 	{
64 		Dir_H = 0,
65 		Dir_V,
66 
67 		Dir_NBR_ELT
68 	};
69 
70 	typedef	FilterResize	ThisType;
71 
72 	explicit       FilterResize (const ResampleSpecPlane &spec, ContFirInterface &kernel_fnc_h, ContFirInterface &kernel_fnc_v, bool norm_flag, double norm_val_h, double norm_val_v, double gain, SplFmt src_type, int src_res, SplFmt dst_type, int dst_res, bool int_flag, bool sse2_flag, bool avx2_flag);
~FilterResize()73 	virtual        ~FilterResize () {}
74 
75 	void           process_plane (uint8_t *dst_ptr, const uint8_t *src_ptr, int stride_dst, int stride_src, bool chroma_flag);
76 
77 
78 
79 /*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
80 
81 protected:
82 
83 
84 
85 /*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
86 
87 private:
88 
89 	enum PassType
90 	{
91 		PassType_NONE = 0,
92 		PassType_RESIZE,
93 		PassType_TRANSPOSE,
94 
95 		PassType_NBR_ELT
96 	};
97 
98 	static const int  MAX_NBR_PASSES = 4;                 // 2 * (transpose + resize)
99 	static const int  BUF_SIZE       = 65536;             // Number of pixels (float or int16_t)
100 	static const int  MAX_BUF_SIZE   = BUF_SIZE * 1024;   // Number of pixels (float or int16_t)
101 
102 	class TaskRszGlobal
103 	{
104 	public:
105 		FilterResize * _this_ptr;
106 		uint8_t *      _dst_ptr;
107 		const uint8_t *
108 		               _src_ptr;
109 		int            _dst_bpp;        // Pointed bytes per pixel (1 for stack16)
110 		int            _src_bpp;        // Pointed bytes per pixel (1 for stack16)
111 		int            _stride_dst;     // Bytes
112 		int            _stride_src;     // Bytes
113 		int            _offset_crop;    // Bytes
114 		int            _stride_dst_pix; // Pixels
115 		int            _stride_src_pix; // Pixels
116 	};
117 
118 	class TaskRsz
119 	{
120 	public:
121 		const TaskRszGlobal *
122 		               _glob_data_ptr;
123 		int            _dst_beg [Dir_NBR_ELT];
124 		int            _work_dst [Dir_NBR_ELT];
125 		int            _src_beg [Dir_NBR_ELT];
126 		int            _src_end [Dir_NBR_ELT];
127 	};
128 
129 	typedef	conc::LockFreeCell <TaskRsz>	TaskRszCell;
130 
131 	void           process_plane_bypass (uint8_t *dst_ptr, const uint8_t *src_ptr, int stride_dst, int stride_src, bool chroma_flag);
132 	void           process_plane_normal (uint8_t *dst_ptr, const uint8_t *src_ptr, int stride_dst, int stride_src);
133 	void           process_tile (TaskRszCell &tr_cell);
134 	void           process_tile_resize (const TaskRsz &tr, const TaskRszGlobal& trg, ResizeData &rd, int stride_buf [2], const int pass, Dir &cur_dir, int &cur_buf, int cur_size [Dir_NBR_ELT]);
135 
136 	template <typename T, SplFmt BUFT>
137 	void           process_tile_transpose (const TaskRsz &tr, const TaskRszGlobal& trg, ResizeData &rd, int stride_buf [2], const int pass, Dir &cur_dir, int &cur_buf, int cur_size [Dir_NBR_ELT]);
138 
139 	template <typename T>
140 	void           transpose (T *dst_ptr, const T *src_ptr, int w, int h, int stride_dst, int stride_src);
141 
142 	template <typename T>
143 	void           transpose_cpp (T *dst_ptr, const T *src_ptr, int w, int h, int stride_dst, int stride_src);
144 
145 #if (fstb_ARCHI == fstb_ARCHI_X86)
146 	void           transpose_sse2 (float *dst_ptr, const float *src_ptr, int w, int h, int stride_dst, int stride_src);
147 	void           transpose_sse2 (uint16_t *dst_ptr, const uint16_t *src_ptr, int w, int h, int stride_dst, int stride_src);
148 #endif
149 
150 	bool           is_kernel_neutral (Dir di) const;
151 
152 	inline bool    has_buf_src (int pass) const;
153 	inline bool    has_buf_dst (int pass) const;
154 	void           compute_req_src_tile_size (int &tw, int &th, int dw, int dh) const;
155 
156 	static void    redirect_task_resize (avstp_TaskDispatcher *dispatcher_ptr, void *data_ptr);
157 
158 	AvstpWrapper & _avstp;
159 	conc::CellPool <TaskRsz>
160 	               _task_rsz_pool;
161 
162 	int            _src_size [Dir_NBR_ELT];
163 	int            _dst_size [Dir_NBR_ELT];
164 	double         _win_pos [Dir_NBR_ELT];
165 	double         _win_size [Dir_NBR_ELT];
166 	double         _kernel_scale [Dir_NBR_ELT];
167 	bool           _kernel_force_flag [Dir_NBR_ELT];
168 	ContFirInterface *
169 	               _kernel_ptr_arr [Dir_NBR_ELT];
170 	bool				_norm_flag;
171 	double         _norm_val [Dir_NBR_ELT];
172 	double         _center_pos_src [Dir_NBR_ELT];
173 	double         _center_pos_dst [Dir_NBR_ELT];
174 	double         _gain;            // Scale adjustment for bitdepth conversions
175 	double         _add_cst;         // Constant added to U and V planes when converting between floating-point (range -0.5 +0.5) and integer formats (range 0 max)
176 	SplFmt         _src_type;
177 	int            _src_res;
178 	SplFmt         _dst_type;
179 	int            _dst_res;
180 	Dir            _bd_chg_dir;      // The resizer in charge of the bitdepth conversion.
181 	bool           _int_flag;        // Use 16-bit int as temporary data instead of float, if possible
182 	bool           _sse2_flag;
183 	bool           _avx2_flag;
184 
185 	conc::ObjPool <ResizeData>
186 						_pool;
187 	std::unique_ptr <ResizeDataFactory>
188 	               _factory_uptr;
189 
190 	int            _crop_pos [Dir_NBR_ELT];
191 	int            _crop_size [Dir_NBR_ELT];
192 
193 	std::unique_ptr <Scaler>         // 0 if bypassed
194 	               _scaler_uptr [Dir_NBR_ELT];
195 	BitBltConv     _blitter;
196 
197 	bool           _resize_flag [Dir_NBR_ELT];
198 	PassType       _roadmap [MAX_NBR_PASSES];
199 	int            _tile_size_dst [Dir_NBR_ELT];
200 	int            _nbr_passes;      // 0 = bypass
201 	int            _buf_size;        // In pixels
202 	bool           _buffer_flag;
203 
204 
205 
206 /*\\\ FORBIDDEN MEMBER FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
207 
208 private:
209 
210 	               FilterResize ()                               = delete;
211 	               FilterResize (const FilterResize &other)      = delete;
212 	FilterResize & operator = (const FilterResize &other)        = delete;
213 	bool           operator == (const FilterResize &other) const = delete;
214 	bool           operator != (const FilterResize &other) const = delete;
215 
216 };	// class FilterResize
217 
218 
219 
220 }	// namespace fmtcl
221 
222 
223 
224 //#include "fmtcl/FilterResize.hpp"
225 
226 
227 
228 #endif	// fmtcl_FilterResize_HEADER_INCLUDED
229 
230 
231 
232 /*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
233