1 /*****************************************************************************
2 
3         fnc.cpp
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 #if defined (_MSC_VER)
19 	#pragma warning (1 : 4130 4223 4705 4706)
20 	#pragma warning (4 : 4355 4786 4800)
21 #endif
22 
23 
24 
25 /*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
26 
27 #include "fmtc/fnc.h"
28 #include "fmtcl/fnc.h"
29 #include "fmtcl/MatrixProc.h"
30 #include "vsutl/FilterBase.h"
31 #include "vsutl/fnc.h"
32 #include "vswrap.h"
33 
34 #include <algorithm>
35 
36 #include <cassert>
37 
38 
39 
40 namespace fmtc
41 {
42 
43 
44 
45 /*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
46 
47 
48 
49 /*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
50 
51 
52 
conv_vsfmt_to_picfmt(const::VSFormat & fmt,bool full_flag)53 fmtcl::PicFmt	conv_vsfmt_to_picfmt (const ::VSFormat &fmt, bool full_flag)
54 {
55 	fmtcl::PicFmt  pic_fmt;
56 	pic_fmt._sf        = conv_vsfmt_to_splfmt (fmt);
57 	pic_fmt._res       = fmt.bitsPerSample;
58 	pic_fmt._col_fam   = conv_vsfmt_to_colfam (fmt);
59 	pic_fmt._full_flag = full_flag;
60 
61 	return pic_fmt;
62 }
63 
64 
65 
conv_vsfmt_to_splfmt(const::VSFormat & fmt)66 fmtcl::SplFmt	conv_vsfmt_to_splfmt (const ::VSFormat &fmt)
67 {
68 	fmtcl::SplFmt  splfmt = fmtcl::SplFmt_ILLEGAL;
69 
70 	if (fmt.sampleType == ::stFloat && fmt.bitsPerSample == 32)
71 	{
72 		splfmt = fmtcl::SplFmt_FLOAT;
73 	}
74 	else
75 	{
76 		if (fmt.bitsPerSample <= 8)
77 		{
78 			splfmt = fmtcl::SplFmt_INT8;
79 		}
80 		else if (fmt.bitsPerSample <= 16)
81 		{
82 			splfmt = fmtcl::SplFmt_INT16;
83 		}
84 	}
85 
86 	return splfmt;
87 }
88 
89 
90 
conv_vsfmt_to_splfmt(fmtcl::SplFmt & type,int & bitdepth,const::VSFormat & fmt)91 void	conv_vsfmt_to_splfmt (fmtcl::SplFmt &type, int &bitdepth, const ::VSFormat &fmt)
92 {
93 	type     = conv_vsfmt_to_splfmt (fmt);
94 	bitdepth = fmt.bitsPerSample;
95 }
96 
97 
98 
conv_vsfmt_to_colfam(const::VSFormat & fmt)99 fmtcl::ColorFamily	conv_vsfmt_to_colfam (const ::VSFormat &fmt)
100 {
101 	auto          col_fam = fmtcl::ColorFamily_INVALID;
102 
103 	switch (fmt.colorFamily)
104 	{
105 	case cfGray:
106 	case cmGray:
107 		col_fam = fmtcl::ColorFamily_GRAY;
108 		break;
109 	case cfRGB:
110 	case cmRGB:
111 		col_fam = fmtcl::ColorFamily_RGB;
112 		break;
113 	case cfYUV:
114 	case cmYUV:
115 		col_fam = fmtcl::ColorFamily_YUV;
116 		break;
117 	case cmYCoCg:
118 		col_fam = fmtcl::ColorFamily_YCGCO;
119 		break;
120 	default:
121 		assert (false);
122 		break;
123 	}
124 
125 	return col_fam;
126 }
127 
128 
129 
conv_fmtcl_colfam_to_vs(fmtcl::ColorFamily cf)130 int	conv_fmtcl_colfam_to_vs (fmtcl::ColorFamily cf)
131 {
132 	assert (cf >= 0);
133 	assert (cf < fmtcl::ColorFamily_NBR_ELT);
134 
135 	int            vs_cf = ::cfUndefined;
136 	switch (cf)
137 	{
138 	case fmtcl::ColorFamily_GRAY:  vs_cf = ::cmGray;  break;
139 	case fmtcl::ColorFamily_RGB:   vs_cf = ::cmRGB;   break;
140 	case fmtcl::ColorFamily_YCGCO: vs_cf = ::cmYCoCg; break;
141 	case fmtcl::ColorFamily_YUV:   vs_cf = ::cmYUV;   break;
142 	default:
143 		assert (false);
144 		break;
145 	}
146 
147 	return vs_cf;
148 }
149 
150 
151 
prepare_matrix_coef(const vsutl::FilterBase & filter,fmtcl::MatrixProc & mat_proc,const fmtcl::Mat4 & mat_main,const::VSFormat & fmt_dst,bool full_range_dst_flag,const::VSFormat & fmt_src,bool full_range_src_flag,fmtcl::ColorSpaceH265 csp_out,int plane_out)152 void	prepare_matrix_coef (const vsutl::FilterBase &filter, fmtcl::MatrixProc &mat_proc, const fmtcl::Mat4 &mat_main, const ::VSFormat &fmt_dst, bool full_range_dst_flag, const ::VSFormat &fmt_src, bool full_range_src_flag, fmtcl::ColorSpaceH265 csp_out, int plane_out)
153 {
154 	const fmtcl::PicFmt  fmt_src_fmtcl =
155 		conv_vsfmt_to_picfmt (fmt_src, full_range_src_flag);
156 	const fmtcl::PicFmt  fmt_dst_fmtcl =
157 		conv_vsfmt_to_picfmt (fmt_dst, full_range_dst_flag);
158 
159 	const int      ret_val = fmtcl::prepare_matrix_coef (
160 		mat_proc, mat_main, fmt_dst_fmtcl, fmt_src_fmtcl, csp_out, plane_out
161 	);
162 
163 	if (ret_val != fmtcl::MatrixProc::Err_OK)
164 	{
165 		if (ret_val == fmtcl::MatrixProc::Err_POSSIBLE_OVERFLOW)
166 		{
167 			filter.throw_inval_arg (
168 				"one of the coefficients could cause an overflow."
169 			);
170 		}
171 		else if (ret_val == fmtcl::MatrixProc::Err_TOO_BIG_COEF)
172 		{
173 			filter.throw_inval_arg (
174 				"too big matrix coefficient."
175 			);
176 		}
177 		else if (ret_val == fmtcl::MatrixProc::Err_INVALID_FORMAT_COMBINATION)
178 		{
179 			filter.throw_inval_arg (
180 				"invalid frame format combination."
181 			);
182 		}
183 		else
184 		{
185 			assert (false);
186 			filter.throw_inval_arg (
187 				"unidentified error while building the matrix."
188 			);
189 		}
190 	}
191 }
192 
193 
194 
build_mat_proc(const::VSAPI & vsapi,::VSFrameRef & dst,const::VSFrameRef & src,bool single_plane_flag)195 fmtcl::ProcComp3Arg	build_mat_proc (const ::VSAPI &vsapi, ::VSFrameRef &dst, const ::VSFrameRef &src, bool single_plane_flag)
196 {
197 	fmtcl::ProcComp3Arg  pa;
198 
199 	pa._w = vsapi.getFrameWidth (&dst, 0);
200 	pa._h = vsapi.getFrameHeight (&dst, 0);
201 
202 	const int      nbr_active_planes = std::min <int> (
203 		fmtcl::ProcComp3Arg::_nbr_planes,
204 		vsapi.getFrameFormat (&src)->numPlanes
205 	);
206 	assert (nbr_active_planes == 1 || nbr_active_planes == 3);
207 
208 	for (int p_idx = 0; p_idx < nbr_active_planes; ++p_idx)
209 	{
210 		if (! single_plane_flag || p_idx == 0)
211 		{
212 			pa._dst [p_idx]._ptr    = vsapi.getWritePtr (&dst, p_idx);
213 			pa._dst [p_idx]._stride = vsapi.getStride (&dst, p_idx);
214 		}
215 		pa._src [p_idx]._ptr    = vsapi.getReadPtr (&src, p_idx);
216 		pa._src [p_idx]._stride = vsapi.getStride (&src, p_idx);
217 	}
218 
219 	return pa;
220 }
221 
222 
223 
224 }	// namespace fmtc
225 
226 
227 
228 /*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
229