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