Add OpenCV source code
[platform/upstream/opencv.git] / modules / core / src / algorithm.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42
43 #include "precomp.hpp"
44
45 namespace cv
46 {
47
48 using std::pair;
49
50 template<typename _KeyTp, typename _ValueTp> struct sorted_vector
51 {
52     sorted_vector() {}
53     void clear() { vec.clear(); }
54     size_t size() const { return vec.size(); }
55     _ValueTp& operator [](size_t idx) { return vec[idx]; }
56     const _ValueTp& operator [](size_t idx) const { return vec[idx]; }
57
58     void add(const _KeyTp& k, const _ValueTp& val)
59     {
60         pair<_KeyTp, _ValueTp> p(k, val);
61         vec.push_back(p);
62         size_t i = vec.size()-1;
63         for( ; i > 0 && vec[i].first < vec[i-1].first; i-- )
64             std::swap(vec[i-1], vec[i]);
65         CV_Assert( i == 0 || vec[i].first != vec[i-1].first );
66     }
67
68     bool find(const _KeyTp& key, _ValueTp& value) const
69     {
70         size_t a = 0, b = vec.size();
71         while( b > a )
72         {
73             size_t c = (a + b)/2;
74             if( vec[c].first < key )
75                 a = c+1;
76             else
77                 b = c;
78         }
79
80         if( a < vec.size() && vec[a].first == key )
81         {
82             value = vec[a].second;
83             return true;
84         }
85         return false;
86     }
87
88     void get_keys(vector<_KeyTp>& keys) const
89     {
90         size_t i = 0, n = vec.size();
91         keys.resize(n);
92
93         for( i = 0; i < n; i++ )
94             keys[i] = vec[i].first;
95     }
96
97     vector<pair<_KeyTp, _ValueTp> > vec;
98 };
99
100
101 template<typename _ValueTp> inline const _ValueTp* findstr(const sorted_vector<string, _ValueTp>& vec,
102                                                            const char* key)
103 {
104     if( !key )
105         return 0;
106
107     size_t a = 0, b = vec.vec.size();
108     while( b > a )
109     {
110         size_t c = (a + b)/2;
111         if( strcmp(vec.vec[c].first.c_str(), key) < 0 )
112             a = c+1;
113         else
114             b = c;
115     }
116
117     if( ( a < vec.vec.size() ) && ( strcmp(vec.vec[a].first.c_str(), key) == 0 ))
118         return &vec.vec[a].second;
119     return 0;
120 }
121
122
123 Param::Param()
124 {
125     type = 0;
126     offset = 0;
127     readonly = false;
128     getter = 0;
129     setter = 0;
130 }
131
132
133 Param::Param(int _type, bool _readonly, int _offset,
134              Algorithm::Getter _getter, Algorithm::Setter _setter,
135              const string& _help)
136 {
137     type = _type;
138     readonly = _readonly;
139     offset = _offset;
140     getter = _getter;
141     setter = _setter;
142     help = _help;
143 }
144
145 struct CV_EXPORTS AlgorithmInfoData
146 {
147     sorted_vector<string, Param> params;
148     string _name;
149 };
150
151
152 static sorted_vector<string, Algorithm::Constructor>& alglist()
153 {
154     static sorted_vector<string, Algorithm::Constructor> alglist_var;
155     return alglist_var;
156 }
157
158 void Algorithm::getList(vector<string>& algorithms)
159 {
160     alglist().get_keys(algorithms);
161 }
162
163 Ptr<Algorithm> Algorithm::_create(const string& name)
164 {
165     Algorithm::Constructor c = 0;
166     if( !alglist().find(name, c) )
167         return Ptr<Algorithm>();
168     return c();
169 }
170
171 Algorithm::Algorithm()
172 {
173 }
174
175 Algorithm::~Algorithm()
176 {
177 }
178
179 string Algorithm::name() const
180 {
181     return info()->name();
182 }
183
184 void Algorithm::set(const string& parameter, int value)
185 {
186     info()->set(this, parameter.c_str(), ParamType<int>::type, &value);
187 }
188
189 void Algorithm::set(const string& parameter, double value)
190 {
191     info()->set(this, parameter.c_str(), ParamType<double>::type, &value);
192 }
193
194 void Algorithm::set(const string& parameter, bool value)
195 {
196     info()->set(this, parameter.c_str(), ParamType<bool>::type, &value);
197 }
198
199 void Algorithm::set(const string& parameter, const string& value)
200 {
201     info()->set(this, parameter.c_str(), ParamType<string>::type, &value);
202 }
203
204 void Algorithm::set(const string& parameter, const Mat& value)
205 {
206     info()->set(this, parameter.c_str(), ParamType<Mat>::type, &value);
207 }
208
209 void Algorithm::set(const string& parameter, const vector<Mat>& value)
210 {
211     info()->set(this, parameter.c_str(), ParamType<vector<Mat> >::type, &value);
212 }
213
214 void Algorithm::set(const string& parameter, const Ptr<Algorithm>& value)
215 {
216     info()->set(this, parameter.c_str(), ParamType<Algorithm>::type, &value);
217 }
218
219 void Algorithm::set(const char* parameter, int value)
220 {
221     info()->set(this, parameter, ParamType<int>::type, &value);
222 }
223
224 void Algorithm::set(const char* parameter, double value)
225 {
226     info()->set(this, parameter, ParamType<double>::type, &value);
227 }
228
229 void Algorithm::set(const char* parameter, bool value)
230 {
231     info()->set(this, parameter, ParamType<bool>::type, &value);
232 }
233
234 void Algorithm::set(const char* parameter, const string& value)
235 {
236     info()->set(this, parameter, ParamType<string>::type, &value);
237 }
238
239 void Algorithm::set(const char* parameter, const Mat& value)
240 {
241     info()->set(this, parameter, ParamType<Mat>::type, &value);
242 }
243
244 void Algorithm::set(const char* parameter, const vector<Mat>& value)
245 {
246     info()->set(this, parameter, ParamType<vector<Mat> >::type, &value);
247 }
248
249 void Algorithm::set(const char* parameter, const Ptr<Algorithm>& value)
250 {
251     info()->set(this, parameter, ParamType<Algorithm>::type, &value);
252 }
253
254
255 void Algorithm::setInt(const string& parameter, int value)
256 {
257     info()->set(this, parameter.c_str(), ParamType<int>::type, &value);
258 }
259
260 void Algorithm::setDouble(const string& parameter, double value)
261 {
262     info()->set(this, parameter.c_str(), ParamType<double>::type, &value);
263 }
264
265 void Algorithm::setBool(const string& parameter, bool value)
266 {
267     info()->set(this, parameter.c_str(), ParamType<bool>::type, &value);
268 }
269
270 void Algorithm::setString(const string& parameter, const string& value)
271 {
272     info()->set(this, parameter.c_str(), ParamType<string>::type, &value);
273 }
274
275 void Algorithm::setMat(const string& parameter, const Mat& value)
276 {
277     info()->set(this, parameter.c_str(), ParamType<Mat>::type, &value);
278 }
279
280 void Algorithm::setMatVector(const string& parameter, const vector<Mat>& value)
281 {
282     info()->set(this, parameter.c_str(), ParamType<vector<Mat> >::type, &value);
283 }
284
285 void Algorithm::setAlgorithm(const string& parameter, const Ptr<Algorithm>& value)
286 {
287     info()->set(this, parameter.c_str(), ParamType<Algorithm>::type, &value);
288 }
289
290 void Algorithm::setInt(const char* parameter, int value)
291 {
292     info()->set(this, parameter, ParamType<int>::type, &value);
293 }
294
295 void Algorithm::setDouble(const char* parameter, double value)
296 {
297     info()->set(this, parameter, ParamType<double>::type, &value);
298 }
299
300 void Algorithm::setBool(const char* parameter, bool value)
301 {
302     info()->set(this, parameter, ParamType<bool>::type, &value);
303 }
304
305 void Algorithm::setString(const char* parameter, const string& value)
306 {
307     info()->set(this, parameter, ParamType<string>::type, &value);
308 }
309
310 void Algorithm::setMat(const char* parameter, const Mat& value)
311 {
312     info()->set(this, parameter, ParamType<Mat>::type, &value);
313 }
314
315 void Algorithm::setMatVector(const char* parameter, const vector<Mat>& value)
316 {
317     info()->set(this, parameter, ParamType<vector<Mat> >::type, &value);
318 }
319
320 void Algorithm::setAlgorithm(const char* parameter, const Ptr<Algorithm>& value)
321 {
322     info()->set(this, parameter, ParamType<Algorithm>::type, &value);
323 }
324
325
326
327
328 int Algorithm::getInt(const string& parameter) const
329 {
330     return get<int>(parameter);
331 }
332
333 double Algorithm::getDouble(const string& parameter) const
334 {
335     return get<double>(parameter);
336 }
337
338 bool Algorithm::getBool(const string& parameter) const
339 {
340     return get<bool>(parameter);
341 }
342
343 string Algorithm::getString(const string& parameter) const
344 {
345     return get<string>(parameter);
346 }
347
348 Mat Algorithm::getMat(const string& parameter) const
349 {
350     return get<Mat>(parameter);
351 }
352
353 vector<Mat> Algorithm::getMatVector(const string& parameter) const
354 {
355     return get<vector<Mat> >(parameter);
356 }
357
358 Ptr<Algorithm> Algorithm::getAlgorithm(const string& parameter) const
359 {
360     return get<Algorithm>(parameter);
361 }
362
363 string Algorithm::paramHelp(const string& parameter) const
364 {
365     return info()->paramHelp(parameter.c_str());
366 }
367
368 int Algorithm::paramType(const string& parameter) const
369 {
370     return info()->paramType(parameter.c_str());
371 }
372
373 int Algorithm::paramType(const char* parameter) const
374 {
375     return info()->paramType(parameter);
376 }
377
378 void Algorithm::getParams(vector<string>& names) const
379 {
380     info()->getParams(names);
381 }
382
383 void Algorithm::write(FileStorage& fs) const
384 {
385     info()->write(this, fs);
386 }
387
388 void Algorithm::read(const FileNode& fn)
389 {
390     info()->read(this, fn);
391 }
392
393
394 AlgorithmInfo::AlgorithmInfo(const string& _name, Algorithm::Constructor create)
395 {
396     data = new AlgorithmInfoData;
397     data->_name = _name;
398     if (!alglist().find(_name, create))
399         alglist().add(_name, create);
400 }
401
402 AlgorithmInfo::~AlgorithmInfo()
403 {
404     delete data;
405 }
406
407 void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const
408 {
409     size_t i = 0, nparams = data->params.vec.size();
410     cv::write(fs, "name", algo->name());
411     for( i = 0; i < nparams; i++ )
412     {
413         const Param& p = data->params.vec[i].second;
414         const string& pname = data->params.vec[i].first;
415         if( p.type == Param::INT )
416             cv::write(fs, pname, algo->get<int>(pname));
417         else if( p.type == Param::BOOLEAN )
418             cv::write(fs, pname, (int)algo->get<bool>(pname));
419         else if( p.type == Param::SHORT )
420             cv::write(fs, pname, (int)algo->get<short>(pname));
421         else if( p.type == Param::REAL )
422             cv::write(fs, pname, algo->get<double>(pname));
423         else if( p.type == Param::STRING )
424             cv::write(fs, pname, algo->get<string>(pname));
425         else if( p.type == Param::MAT )
426             cv::write(fs, pname, algo->get<Mat>(pname));
427         else if( p.type == Param::MAT_VECTOR )
428             cv::write(fs, pname, algo->get<vector<Mat> >(pname));
429         else if( p.type == Param::ALGORITHM )
430         {
431             WriteStructContext ws(fs, pname, CV_NODE_MAP);
432             Ptr<Algorithm> nestedAlgo = algo->get<Algorithm>(pname);
433             nestedAlgo->write(fs);
434         }
435         else if( p.type == Param::FLOAT)
436             cv::write(fs, pname, algo->getDouble(pname));
437         else if( p.type == Param::UNSIGNED_INT)
438             cv::write(fs, pname, algo->getInt(pname));//TODO: implement cv::write(, , unsigned int)
439         else if( p.type == Param::UINT64)
440             cv::write(fs, pname, algo->getInt(pname));//TODO: implement cv::write(, , uint64)
441         else if( p.type == Param::UCHAR)
442             cv::write(fs, pname, algo->getInt(pname));
443         else
444         {
445             string msg = format("unknown/unsupported type of '%s' parameter == %d", pname.c_str(), p.type);
446             CV_Error( CV_StsUnsupportedFormat, msg.c_str());
447         }
448     }
449 }
450
451 void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const
452 {
453     size_t i = 0, nparams = data->params.vec.size();
454     AlgorithmInfo* info = algo->info();
455
456     for( i = 0; i < nparams; i++ )
457     {
458         const Param& p = data->params.vec[i].second;
459         const string& pname = data->params.vec[i].first;
460         const FileNode n = fn[pname];
461         if( n.empty() )
462             continue;
463         if( p.type == Param::INT || p.type == Param::SHORT )
464         {
465             int val = (int)n;
466             info->set(algo, pname.c_str(), p.type, &val, true);
467         }
468         else if( p.type == Param::BOOLEAN )
469         {
470             bool val = (int)n != 0;
471             info->set(algo, pname.c_str(), p.type, &val, true);
472         }
473         else if( p.type == Param::REAL )
474         {
475             double val = (double)n;
476             info->set(algo, pname.c_str(), p.type, &val, true);
477         }
478         else if( p.type == Param::STRING )
479         {
480             string val = (string)n;
481             info->set(algo, pname.c_str(), p.type, &val, true);
482         }
483         else if( p.type == Param::MAT )
484         {
485             Mat m;
486             cv::read(n, m);
487             info->set(algo, pname.c_str(), p.type, &m, true);
488         }
489         else if( p.type == Param::MAT_VECTOR )
490         {
491             vector<Mat> mv;
492             cv::read(n, mv);
493             info->set(algo, pname.c_str(), p.type, &mv, true);
494         }
495         else if( p.type == Param::ALGORITHM )
496         {
497             Ptr<Algorithm> nestedAlgo = Algorithm::_create((string)n["name"]);
498             CV_Assert( !nestedAlgo.empty() );
499             nestedAlgo->read(n);
500             info->set(algo, pname.c_str(), p.type, &nestedAlgo, true);
501         }
502         else if( p.type == Param::FLOAT )
503         {
504             float val = (float)n;
505             info->set(algo, pname.c_str(), p.type, &val, true);
506         }
507         else if( p.type == Param::UNSIGNED_INT )
508         {
509             unsigned int val = (unsigned int)((int)n);//TODO: implement conversion (unsigned int)FileNode
510             info->set(algo, pname.c_str(), p.type, &val, true);
511         }
512         else if( p.type == Param::UINT64)
513         {
514             uint64 val = (uint64)((int)n);//TODO: implement conversion (uint64)FileNode
515             info->set(algo, pname.c_str(), p.type, &val, true);
516         }
517         else if( p.type == Param::UCHAR)
518         {
519             uchar val = (uchar)((int)n);
520             info->set(algo, pname.c_str(), p.type, &val, true);
521         }
522         else
523         {
524             string msg = format("unknown/unsupported type of '%s' parameter == %d", pname.c_str(), p.type);
525             CV_Error( CV_StsUnsupportedFormat, msg.c_str());
526         }
527     }
528 }
529
530 string AlgorithmInfo::name() const
531 {
532     return data->_name;
533 }
534
535 union GetSetParam
536 {
537     int (Algorithm::*get_int)() const;
538     bool (Algorithm::*get_bool)() const;
539     double (Algorithm::*get_double)() const;
540     string (Algorithm::*get_string)() const;
541     Mat (Algorithm::*get_mat)() const;
542     vector<Mat> (Algorithm::*get_mat_vector)() const;
543     Ptr<Algorithm> (Algorithm::*get_algo)() const;
544     float (Algorithm::*get_float)() const;
545     unsigned int (Algorithm::*get_uint)() const;
546     uint64 (Algorithm::*get_uint64)() const;
547     uchar (Algorithm::*get_uchar)() const;
548
549     void (Algorithm::*set_int)(int);
550     void (Algorithm::*set_bool)(bool);
551     void (Algorithm::*set_double)(double);
552     void (Algorithm::*set_string)(const string&);
553     void (Algorithm::*set_mat)(const Mat&);
554     void (Algorithm::*set_mat_vector)(const vector<Mat>&);
555     void (Algorithm::*set_algo)(const Ptr<Algorithm>&);
556     void (Algorithm::*set_float)(float);
557     void (Algorithm::*set_uint)(unsigned int);
558     void (Algorithm::*set_uint64)(uint64);
559     void (Algorithm::*set_uchar)(uchar);
560 };
561
562 static string getNameOfType(int argType);
563
564 static string getNameOfType(int argType)
565 {
566     switch(argType)
567     {
568         case Param::INT: return "integer";
569         case Param::SHORT: return "short";
570         case Param::BOOLEAN: return "boolean";
571         case Param::REAL: return "double";
572         case Param::STRING: return "string";
573         case Param::MAT: return "cv::Mat";
574         case Param::MAT_VECTOR: return "std::vector<cv::Mat>";
575         case Param::ALGORITHM: return "algorithm";
576         case Param::FLOAT: return "float";
577         case Param::UNSIGNED_INT: return "unsigned int";
578         case Param::UINT64: return "unsigned int64";
579         case Param::UCHAR: return "unsigned char";
580         default: CV_Error(CV_StsBadArg, "Wrong argument type");
581     }
582     return "";
583 }
584 static string getErrorMessageForWrongArgumentInSetter(string algoName, string paramName, int paramType, int argType);
585 static string getErrorMessageForWrongArgumentInSetter(string algoName, string paramName, int paramType, int argType)
586 {
587     string message = string("Argument error: the setter")
588         + " method was called for the parameter '" + paramName + "' of the algorithm '" + algoName
589         +"', the parameter has " + getNameOfType(paramType) + " type, ";
590
591     if (paramType == Param::INT || paramType == Param::BOOLEAN || paramType == Param::REAL
592             || paramType == Param::FLOAT || paramType == Param::UNSIGNED_INT || paramType == Param::UINT64 || paramType == Param::UCHAR)
593     {
594         message += "so it should be set by integer, unsigned integer, uint64, unsigned char, boolean, float or double value, ";
595     }
596     else if (paramType == Param::SHORT)
597     {
598         message += "so it should be set by integer value, ";
599     }
600     message += "but the setter was called with " + getNameOfType(argType) + " value";
601
602     return message;
603 }
604
605 static string getErrorMessageForWrongArgumentInGetter(string algoName, string paramName, int paramType, int argType);
606 static string getErrorMessageForWrongArgumentInGetter(string algoName, string paramName, int paramType, int argType)
607 {
608     string message = string("Argument error: the getter")
609         + " method was called for the parameter '" + paramName + "' of the algorithm '" + algoName
610         +"', the parameter has " + getNameOfType(paramType) + " type, ";
611
612     if (paramType == Param::BOOLEAN)
613     {
614         message += "so it should be get as integer, unsigned integer, uint64, boolean, unsigned char, float or double value, ";
615     }
616     else if (paramType == Param::INT || paramType == Param::UNSIGNED_INT || paramType == Param::UINT64 || paramType == Param::UCHAR)
617     {
618         message += "so it should be get as integer, unsigned integer, uint64, unsigned char, float or double value, ";
619     }
620     else if (paramType == Param::SHORT)
621     {
622         message += "so it should be get as integer value, ";
623     }
624     else if (paramType == Param::FLOAT || paramType == Param::REAL)
625     {
626         message += "so it should be get as float or double value, ";
627     }
628     message += "but the getter was called to get a " + getNameOfType(argType) + " value";
629
630     return message;
631 }
632
633 void AlgorithmInfo::set(Algorithm* algo, const char* parameter, int argType, const void* value, bool force) const
634 {
635     const Param* p = findstr(data->params, parameter);
636
637     if( !p )
638         CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
639
640     if( !force && p->readonly )
641         CV_Error_( CV_StsError, ("Parameter '%s' is readonly", parameter));
642
643     GetSetParam f;
644     f.set_int = p->setter;
645
646     if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::SHORT
647             || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)
648     {
649         if ( !( p->type == Param::INT || p->type == Param::REAL || p->type == Param::BOOLEAN
650                 || p->type == Param::UNSIGNED_INT || p->type == Param::UINT64 || p->type == Param::FLOAT || p->type == Param::UCHAR
651                 || (p->type == Param::SHORT && argType == Param::INT)) )
652         {
653             string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType);
654             CV_Error(CV_StsBadArg, message);
655         }
656
657         if( p->type == Param::INT )
658         {
659             bool is_ok = true;
660             int val = argType == Param::INT ? *(const int*)value :
661                 argType == Param::BOOLEAN ? (int)*(const bool*)value :
662                 argType == Param::REAL ? saturate_cast<int>(*(const double*)value) :
663                 argType == Param::FLOAT ?  saturate_cast<int>(*(const float*)value) :
664                 argType == Param::UNSIGNED_INT ? (int)*(const unsigned int*)value :
665                 argType == Param::UINT64 ? (int)*(const uint64*)value :
666                 argType == Param::UCHAR ? (int)*(const uchar*)value :
667                 (int)(is_ok = false);
668
669             if (!is_ok)
670             {
671                 CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
672             }
673
674             if( p->setter )
675                 (algo->*f.set_int)(val);
676             else
677                 *(int*)((uchar*)algo + p->offset) = val;
678         }
679         else if( p->type == Param::SHORT )
680         {
681             CV_DbgAssert(argType == Param::INT);
682             int val = *(const int*)value;
683             if( p->setter )
684                 (algo->*f.set_int)(val);
685             else
686                 *(short*)((uchar*)algo + p->offset) = (short)val;
687         }
688         else if( p->type == Param::BOOLEAN )
689         {
690             bool is_ok = true;
691             bool val = argType == Param::INT ? *(const int*)value != 0 :
692                     argType == Param::BOOLEAN ? *(const bool*)value :
693                     argType == Param::REAL ? (*(const double*)value != 0) :
694                     argType == Param::FLOAT ?  (*(const float*)value != 0) :
695                     argType == Param::UNSIGNED_INT ? (*(const unsigned int*)value != 0):
696                     argType == Param::UINT64 ? (*(const uint64*)value != 0):
697                     argType == Param::UCHAR ? (*(const uchar*)value != 0):
698                     (int)(is_ok = false);
699
700             if (!is_ok)
701             {
702                 CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
703             }
704
705             if( p->setter )
706                 (algo->*f.set_bool)(val);
707             else
708                 *(bool*)((uchar*)algo + p->offset) = val;
709         }
710         else if( p->type == Param::REAL )
711         {
712             bool is_ok = true;
713             double val = argType == Param::INT ? (double)*(const int*)value :
714                          argType == Param::BOOLEAN ? (double)*(const bool*)value :
715                          argType == Param::REAL ? (double)(*(const double*)value ) :
716                          argType == Param::FLOAT ?  (double)(*(const float*)value ) :
717                          argType == Param::UNSIGNED_INT ? (double)(*(const unsigned int*)value ) :
718                          argType == Param::UINT64 ? (double)(*(const uint64*)value ) :
719                          argType == Param::UCHAR ? (double)(*(const uchar*)value ) :
720                          (double)(is_ok = false);
721
722             if (!is_ok)
723             {
724                 CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
725             }
726             if( p->setter )
727                 (algo->*f.set_double)(val);
728             else
729                 *(double*)((uchar*)algo + p->offset) = val;
730         }
731         else if( p->type == Param::FLOAT )
732         {
733             bool is_ok = true;
734             double val = argType == Param::INT ? (double)*(const int*)value :
735                          argType == Param::BOOLEAN ? (double)*(const bool*)value :
736                          argType == Param::REAL ? (double)(*(const double*)value ) :
737                          argType == Param::FLOAT ?  (double)(*(const float*)value ) :
738                          argType == Param::UNSIGNED_INT ? (double)(*(const unsigned int*)value ) :
739                          argType == Param::UINT64 ? (double)(*(const uint64*)value ) :
740                          argType == Param::UCHAR ? (double)(*(const uchar*)value ) :
741                          (double)(is_ok = false);
742
743             if (!is_ok)
744             {
745                 CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
746             }
747             if( p->setter )
748                 (algo->*f.set_float)((float)val);
749             else
750                 *(float*)((uchar*)algo + p->offset) = (float)val;
751         }
752         else if( p->type == Param::UNSIGNED_INT )
753         {
754             bool is_ok = true;
755             unsigned int val = argType == Param::INT ? (unsigned int)*(const int*)value :
756                          argType == Param::BOOLEAN ? (unsigned int)*(const bool*)value :
757                          argType == Param::REAL ? saturate_cast<unsigned int>(*(const double*)value ) :
758                          argType == Param::FLOAT ?  saturate_cast<unsigned int>(*(const float*)value ) :
759                          argType == Param::UNSIGNED_INT ? (unsigned int)(*(const unsigned int*)value ) :
760                          argType == Param::UINT64 ? (unsigned int)(*(const uint64*)value ) :
761                          argType == Param::UCHAR ? (unsigned int)(*(const uchar*)value ) :
762                          (int)(is_ok = false);
763
764             if (!is_ok)
765             {
766                 CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
767             }
768             if( p->setter )
769                 (algo->*f.set_uint)(val);
770             else
771                 *(unsigned int*)((uchar*)algo + p->offset) = val;
772         }
773         else if( p->type == Param::UINT64 )
774         {
775             bool is_ok = true;
776             uint64 val = argType == Param::INT ? (uint64)*(const int*)value :
777                          argType == Param::BOOLEAN ? (uint64)*(const bool*)value :
778                          argType == Param::REAL ? saturate_cast<uint64>(*(const double*)value ) :
779                          argType == Param::FLOAT ?  saturate_cast<uint64>(*(const float*)value ) :
780                          argType == Param::UNSIGNED_INT ? (uint64)(*(const unsigned int*)value ) :
781                          argType == Param::UINT64 ? (uint64)(*(const uint64*)value ) :
782                          argType == Param::UCHAR ? (uint64)(*(const uchar*)value ) :
783                          (int)(is_ok = false);
784
785             if (!is_ok)
786             {
787                 CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
788             }
789             if( p->setter )
790                 (algo->*f.set_uint64)(val);
791             else
792                 *(uint64*)((uchar*)algo + p->offset) = val;
793         }
794         else if( p->type == Param::UCHAR )
795         {
796             bool is_ok = true;
797             uchar val = argType == Param::INT ? (uchar)*(const int*)value :
798                          argType == Param::BOOLEAN ? (uchar)*(const bool*)value :
799                          argType == Param::REAL ? saturate_cast<uchar>(*(const double*)value ) :
800                          argType == Param::FLOAT ?  saturate_cast<uchar>(*(const float*)value ) :
801                          argType == Param::UNSIGNED_INT ? (uchar)(*(const unsigned int*)value ) :
802                          argType == Param::UINT64 ? (uchar)(*(const uint64*)value ) :
803                          argType == Param::UCHAR ? (uchar)(*(const uchar*)value ) :
804                          (int)(is_ok = false);
805
806             if (!is_ok)
807             {
808                 CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
809             }
810             if( p->setter )
811                 (algo->*f.set_uchar)(val);
812             else
813                 *(uchar*)((uchar*)algo + p->offset) = val;
814         }
815         else
816             CV_Error(CV_StsBadArg, "Wrong parameter type in the setter");
817     }
818     else if( argType == Param::STRING )
819     {
820         if( p->type != Param::STRING )
821         {
822             string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType);
823             CV_Error(CV_StsBadArg, message);
824         }
825
826         const string& val = *(const string*)value;
827         if( p->setter )
828             (algo->*f.set_string)(val);
829         else
830             *(string*)((uchar*)algo + p->offset) = val;
831     }
832     else if( argType == Param::MAT )
833     {
834         if( p->type != Param::MAT )
835         {
836             string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType);
837             CV_Error(CV_StsBadArg, message);
838         }
839
840         const Mat& val = *(const Mat*)value;
841         if( p->setter )
842             (algo->*f.set_mat)(val);
843         else
844             *(Mat*)((uchar*)algo + p->offset) = val;
845     }
846     else if( argType == Param::MAT_VECTOR )
847     {
848         if( p->type != Param::MAT_VECTOR )
849         {
850             string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType);
851             CV_Error(CV_StsBadArg, message);
852         }
853
854         const vector<Mat>& val = *(const vector<Mat>*)value;
855         if( p->setter )
856             (algo->*f.set_mat_vector)(val);
857         else
858             *(vector<Mat>*)((uchar*)algo + p->offset) = val;
859     }
860     else if( argType == Param::ALGORITHM )
861     {
862         if( p->type != Param::ALGORITHM )
863         {
864             string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType);
865             CV_Error(CV_StsBadArg, message);
866         }
867
868         const Ptr<Algorithm>& val = *(const Ptr<Algorithm>*)value;
869         if( p->setter )
870             (algo->*f.set_algo)(val);
871         else
872             *(Ptr<Algorithm>*)((uchar*)algo + p->offset) = val;
873     }
874     else
875         CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type");
876 }
877
878 void AlgorithmInfo::get(const Algorithm* algo, const char* parameter, int argType, void* value) const
879 {
880     const Param* p = findstr(data->params, parameter);
881     if( !p )
882         CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
883
884     GetSetParam f;
885     f.get_int = p->getter;
886
887     if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::SHORT
888             || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)
889     {
890         if( p->type == Param::INT )
891         {
892             if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
893             {
894                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
895                 CV_Error(CV_StsBadArg, message);
896             }
897             int val = p->getter ? (algo->*f.get_int)() : *(int*)((uchar*)algo + p->offset);
898
899             if( argType == Param::INT )
900                 *(int*)value = (int)val;
901             else if ( argType == Param::REAL )
902                 *(double*)value = (double)val;
903             else if ( argType == Param::FLOAT)
904                 *(float*)value = (float)val;
905             else if ( argType == Param::UNSIGNED_INT )
906                 *(unsigned int*)value = (unsigned int)val;
907             else if ( argType == Param::UINT64 )
908                 *(uint64*)value = (uint64)val;
909             else if ( argType == Param::UCHAR)
910                 *(uchar*)value = (uchar)val;
911             else
912                 CV_Error(CV_StsBadArg, "Wrong argument type");
913
914         }
915         else if( p->type == Param::SHORT )
916         {
917             if( argType != Param::INT )
918             {
919                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
920                 CV_Error(CV_StsBadArg, message);
921             }
922             int val = p->getter ? (algo->*f.get_int)() : *(short*)((uchar*)algo + p->offset);
923
924             *(int*)value = val;
925         }
926         else if( p->type == Param::BOOLEAN )
927         {
928             if (!( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
929             {
930                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
931                 CV_Error(CV_StsBadArg, message);
932             }
933             bool val = p->getter ? (algo->*f.get_bool)() : *(bool*)((uchar*)algo + p->offset);
934
935             if( argType == Param::INT )
936                 *(int*)value = (int)val;
937             else if( argType == Param::BOOLEAN )
938                 *(bool*)value = val;
939             else if ( argType == Param::REAL )
940                 *(double*)value = (int)val;
941             else if ( argType == Param::FLOAT)
942                 *(float*)value = (float)((int)val);
943             else if ( argType == Param::UNSIGNED_INT )
944                 *(unsigned int*)value = (unsigned int)val;
945             else if ( argType == Param::UINT64 )
946                 *(uint64*)value = (int)val;
947             else if ( argType == Param::UCHAR)
948                 *(uchar*)value = (uchar)val;
949             else
950                 CV_Error(CV_StsBadArg, "Wrong argument type");
951         }
952         else if( p->type == Param::REAL )
953         {
954             if(!( argType == Param::REAL || argType == Param::FLOAT))
955             {
956                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
957                 CV_Error(CV_StsBadArg, message);
958             }
959             double val = p->getter ? (algo->*f.get_double)() : *(double*)((uchar*)algo + p->offset);
960
961             if ( argType == Param::REAL )
962                 *(double*)value = val;
963             else if ( argType == Param::FLOAT)
964                 *(float*)value = (float)val;
965             else
966                 CV_Error(CV_StsBadArg, "Wrong argument type");
967         }
968         else if( p->type == Param::FLOAT )
969         {
970             if(!( argType == Param::REAL || argType == Param::FLOAT))
971             {
972                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
973                 CV_Error(CV_StsBadArg, message);
974             }
975             float val = p->getter ? (algo->*f.get_float)() : *(float*)((uchar*)algo + p->offset);
976
977             if ( argType == Param::REAL )
978                 *(double*)value = (double)val;
979             else if ( argType == Param::FLOAT)
980                 *(float*)value = (float)val;
981             else
982                 CV_Error(CV_StsBadArg, "Wrong argument type");
983         }
984         else if( p->type == Param::UNSIGNED_INT )
985         {
986             if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
987             {
988                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
989                 CV_Error(CV_StsBadArg, message);
990             }
991             unsigned int val = p->getter ? (algo->*f.get_uint)() : *(unsigned int*)((uchar*)algo + p->offset);
992
993             if( argType == Param::INT )
994                 *(int*)value = (int)val;
995             else if ( argType == Param::REAL )
996                 *(double*)value = (double)val;
997             else if ( argType == Param::FLOAT)
998                 *(float*)value = (float)val;
999             else if ( argType == Param::UNSIGNED_INT )
1000                 *(unsigned int*)value = (unsigned int)val;
1001             else if ( argType == Param::UINT64 )
1002                 *(uint64*)value = (uint64)val;
1003             else if ( argType == Param::UCHAR)
1004                 *(uchar*)value = (uchar)val;
1005             else
1006                 CV_Error(CV_StsBadArg, "Wrong argument type");
1007         }
1008         else if( p->type == Param::UINT64 )
1009         {
1010             if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
1011             {
1012                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
1013                 CV_Error(CV_StsBadArg, message);
1014             }
1015             uint64 val = p->getter ? (algo->*f.get_uint64)() : *(uint64*)((uchar*)algo + p->offset);
1016
1017             if( argType == Param::INT )
1018                 *(int*)value = (int)val;
1019             else if ( argType == Param::REAL )
1020                 *(double*)value = (double)val;
1021             else if ( argType == Param::FLOAT)
1022                 *(float*)value = (float)val;
1023             else if ( argType == Param::UNSIGNED_INT )
1024                 *(unsigned int*)value = (unsigned int)val;
1025             else if ( argType == Param::UINT64 )
1026                 *(uint64*)value = (uint64)val;
1027             else if ( argType == Param::UCHAR)
1028                 *(uchar*)value = (uchar)val;
1029             else
1030                 CV_Error(CV_StsBadArg, "Wrong argument type");
1031         }
1032         else if( p->type == Param::UCHAR )
1033         {
1034             if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
1035             {
1036                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
1037                 CV_Error(CV_StsBadArg, message);
1038             }
1039             uchar val = p->getter ? (algo->*f.get_uchar)() : *(uchar*)((uchar*)algo + p->offset);
1040
1041             if( argType == Param::INT )
1042                 *(int*)value = val;
1043             else if ( argType == Param::REAL )
1044                 *(double*)value = val;
1045             else if ( argType == Param::FLOAT)
1046                 *(float*)value = val;
1047             else if ( argType == Param::UNSIGNED_INT )
1048                 *(unsigned int*)value = val;
1049             else if ( argType == Param::UINT64 )
1050                 *(uint64*)value = val;
1051             else if ( argType == Param::UCHAR)
1052                 *(uchar*)value = val;
1053             else
1054                 CV_Error(CV_StsBadArg, "Wrong argument type");
1055
1056         }
1057         else
1058             CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type");
1059     }
1060     else if( argType == Param::STRING )
1061     {
1062         if( p->type != Param::STRING )
1063         {
1064             string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
1065             CV_Error(CV_StsBadArg, message);
1066         }
1067
1068         *(string*)value = p->getter ? (algo->*f.get_string)() :
1069             *(string*)((uchar*)algo + p->offset);
1070     }
1071     else if( argType == Param::MAT )
1072     {
1073         if( p->type != Param::MAT )
1074         {
1075             string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
1076             CV_Error(CV_StsBadArg, message);
1077         }
1078
1079         *(Mat*)value = p->getter ? (algo->*f.get_mat)() :
1080             *(Mat*)((uchar*)algo + p->offset);
1081     }
1082     else if( argType == Param::MAT_VECTOR )
1083     {
1084         if( p->type != Param::MAT_VECTOR )
1085         {
1086             string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
1087             CV_Error(CV_StsBadArg, message);
1088         }
1089
1090         *(vector<Mat>*)value = p->getter ? (algo->*f.get_mat_vector)() :
1091         *(vector<Mat>*)((uchar*)algo + p->offset);
1092     }
1093     else if( argType == Param::ALGORITHM )
1094     {
1095         if( p->type != Param::ALGORITHM )
1096         {
1097             string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
1098             CV_Error(CV_StsBadArg, message);
1099         }
1100
1101         *(Ptr<Algorithm>*)value = p->getter ? (algo->*f.get_algo)() :
1102             *(Ptr<Algorithm>*)((uchar*)algo + p->offset);
1103     }
1104     else
1105     {
1106         string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
1107         CV_Error(CV_StsBadArg, message);
1108     }
1109 }
1110
1111
1112 int AlgorithmInfo::paramType(const char* parameter) const
1113 {
1114     const Param* p = findstr(data->params, parameter);
1115     if( !p )
1116         CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
1117     return p->type;
1118 }
1119
1120
1121 string AlgorithmInfo::paramHelp(const char* parameter) const
1122 {
1123     const Param* p = findstr(data->params, parameter);
1124     if( !p )
1125         CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
1126     return p->help;
1127 }
1128
1129
1130 void AlgorithmInfo::getParams(vector<string>& names) const
1131 {
1132     data->params.get_keys(names);
1133 }
1134
1135
1136 void AlgorithmInfo::addParam_(Algorithm& algo, const char* parameter, int argType,
1137                               void* value, bool readOnly,
1138                               Algorithm::Getter getter, Algorithm::Setter setter,
1139                               const string& help)
1140 {
1141     CV_Assert( argType == Param::INT || argType == Param::BOOLEAN ||
1142                argType == Param::REAL || argType == Param::STRING ||
1143                argType == Param::MAT || argType == Param::MAT_VECTOR ||
1144                argType == Param::ALGORITHM || argType == Param::SHORT
1145                || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64
1146                || argType == Param::UCHAR);
1147     data->params.add(string(parameter), Param(argType, readOnly,
1148                      (int)((size_t)value - (size_t)(void*)&algo),
1149                      getter, setter, help));
1150 }
1151
1152
1153 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1154                              int& value, bool readOnly,
1155                              int (Algorithm::*getter)(),
1156                              void (Algorithm::*setter)(int),
1157                              const string& help)
1158 {
1159     addParam_(algo, parameter, ParamType<int>::type, &value, readOnly,
1160               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1161 }
1162
1163 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1164                              short& value, bool readOnly,
1165                              int (Algorithm::*getter)(),
1166                              void (Algorithm::*setter)(int),
1167                              const string& help)
1168 {
1169     addParam_(algo, parameter, ParamType<short>::type, &value, readOnly,
1170               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1171 }
1172
1173 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1174                              bool& value, bool readOnly,
1175                              int (Algorithm::*getter)(),
1176                              void (Algorithm::*setter)(int),
1177                              const string& help)
1178 {
1179     addParam_(algo, parameter, ParamType<bool>::type, &value, readOnly,
1180               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1181 }
1182
1183 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1184                              double& value, bool readOnly,
1185                              double (Algorithm::*getter)(),
1186                              void (Algorithm::*setter)(double),
1187                              const string& help)
1188 {
1189     addParam_(algo, parameter, ParamType<double>::type, &value, readOnly,
1190               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1191 }
1192
1193 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1194                              string& value, bool readOnly,
1195                              string (Algorithm::*getter)(),
1196                              void (Algorithm::*setter)(const string&),
1197                              const string& help)
1198 {
1199     addParam_(algo, parameter, ParamType<string>::type, &value, readOnly,
1200               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1201 }
1202
1203 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1204                              Mat& value, bool readOnly,
1205                              Mat (Algorithm::*getter)(),
1206                              void (Algorithm::*setter)(const Mat&),
1207                              const string& help)
1208 {
1209     addParam_(algo, parameter, ParamType<Mat>::type, &value, readOnly,
1210               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1211 }
1212
1213 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1214                              vector<Mat>& value, bool readOnly,
1215                              vector<Mat> (Algorithm::*getter)(),
1216                              void (Algorithm::*setter)(const vector<Mat>&),
1217                              const string& help)
1218 {
1219     addParam_(algo, parameter, ParamType<vector<Mat> >::type, &value, readOnly,
1220               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1221 }
1222
1223 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1224                              Ptr<Algorithm>& value, bool readOnly,
1225                              Ptr<Algorithm> (Algorithm::*getter)(),
1226                              void (Algorithm::*setter)(const Ptr<Algorithm>&),
1227                              const string& help)
1228 {
1229     addParam_(algo, parameter, ParamType<Algorithm>::type, &value, readOnly,
1230               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1231 }
1232
1233 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1234                              float& value, bool readOnly,
1235                              float (Algorithm::*getter)(),
1236                              void (Algorithm::*setter)(float),
1237                              const string& help)
1238 {
1239     addParam_(algo, parameter, ParamType<float>::type, &value, readOnly,
1240               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1241 }
1242
1243 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1244                              unsigned int& value, bool readOnly,
1245                              unsigned int (Algorithm::*getter)(),
1246                              void (Algorithm::*setter)(unsigned int),
1247                              const string& help)
1248 {
1249     addParam_(algo, parameter, ParamType<unsigned int>::type, &value, readOnly,
1250               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1251 }
1252
1253 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1254                              uint64& value, bool readOnly,
1255                              uint64 (Algorithm::*getter)(),
1256                              void (Algorithm::*setter)(uint64),
1257                              const string& help)
1258 {
1259     addParam_(algo, parameter, ParamType<uint64>::type, &value, readOnly,
1260               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1261 }
1262
1263 void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
1264                              uchar& value, bool readOnly,
1265                              uchar (Algorithm::*getter)(),
1266                              void (Algorithm::*setter)(uchar),
1267                              const string& help)
1268 {
1269     addParam_(algo, parameter, ParamType<uchar>::type, &value, readOnly,
1270               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
1271 }
1272
1273 }
1274
1275 /* End of file. */