~ubuntu-branches/ubuntu/wily/libde265/wily

« back to all changes in this revision

Viewing changes to libde265/configparam.cc

  • Committer: Package Import Robot
  • Author(s): Joachim Bauch
  • Date: 2015-07-16 11:07:46 UTC
  • mfrom: (2.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20150716110746-76vsv24j3yux7tnu
Tags: 1.0.2-1
* Imported Upstream version 1.0.2
* Added new files to copyright information.
* Only export decoder API and update symbols for new version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * H.265 video codec.
 
3
 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
 
4
 *
 
5
 * Authors: struktur AG, Dirk Farin <farin@struktur.de>
 
6
 *
 
7
 * This file is part of libde265.
 
8
 *
 
9
 * libde265 is free software: you can redistribute it and/or modify
 
10
 * it under the terms of the GNU Lesser General Public License as
 
11
 * published by the Free Software Foundation, either version 3 of
 
12
 * the License, or (at your option) any later version.
 
13
 *
 
14
 * libde265 is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU Lesser General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU Lesser General Public License
 
20
 * along with libde265.  If not, see <http://www.gnu.org/licenses/>.
 
21
 */
 
22
 
 
23
#include "configparam.h"
 
24
 
 
25
#include <string.h>
 
26
#include <ctype.h>
 
27
#include <sstream>
 
28
#include <iomanip>
 
29
#include <iostream>
 
30
#include <algorithm>
 
31
#include <typeinfo>
 
32
 
 
33
#ifndef RTTI_ENABLED
 
34
#error "Need to compile with RTTI enabled."
 
35
#endif
 
36
 
 
37
static void remove_option(int* argc,char** argv,int idx, int n=1)
 
38
{
 
39
  for (int i=idx+n;i<*argc;i++) {
 
40
    argv[i-n] = argv[i];
 
41
  }
 
42
 
 
43
  *argc-=n;
 
44
}
 
45
 
 
46
 
 
47
bool option_string::processCmdLineArguments(char** argv, int* argc, int idx)
 
48
{
 
49
  if (argv==NULL)   { return false; }
 
50
  if (idx >= *argc) { return false; }
 
51
 
 
52
  value = argv[idx];
 
53
  value_set = true;
 
54
 
 
55
  remove_option(argc,argv,idx,1);
 
56
 
 
57
  return true;
 
58
}
 
59
 
 
60
 
 
61
void option_int::set_range(int mini,int maxi)
 
62
{
 
63
  have_low_limit =true;
 
64
  have_high_limit=true;
 
65
  low_limit =mini;
 
66
  high_limit=maxi;
 
67
}
 
68
 
 
69
std::string option_int::getTypeDescr() const
 
70
{
 
71
  std::stringstream sstr;
 
72
  sstr << "(int)";
 
73
 
 
74
  if (have_low_limit || have_high_limit) { sstr << " "; }
 
75
  if (have_low_limit) { sstr << low_limit << " <= "; }
 
76
  if (have_low_limit || have_high_limit) { sstr << "x"; }
 
77
  if (have_high_limit) { sstr << " <= " << high_limit; }
 
78
 
 
79
  if (!valid_values_set.empty()) {
 
80
    sstr << " {";
 
81
    bool first=true;
 
82
    FOR_LOOP(int, v, valid_values_set) {
 
83
      if (!first) sstr << ","; else first=false;
 
84
      sstr << v;
 
85
    }
 
86
    sstr << "}";
 
87
  }
 
88
 
 
89
  return sstr.str();
 
90
}
 
91
 
 
92
bool option_int::processCmdLineArguments(char** argv, int* argc, int idx)
 
93
{
 
94
  if (argv==NULL)   { return false; }
 
95
  if (idx >= *argc) { return false; }
 
96
 
 
97
  int v = atoi(argv[idx]);
 
98
  if (!is_valid(v)) { return false; }
 
99
 
 
100
  value = v;
 
101
  value_set = true;
 
102
 
 
103
  remove_option(argc,argv,idx,1);
 
104
 
 
105
  return true;
 
106
}
 
107
 
 
108
bool option_int::is_valid(int v) const
 
109
{
 
110
  if (have_low_limit  && v<low_limit)  { return false; }
 
111
  if (have_high_limit && v>high_limit) { return false; }
 
112
 
 
113
  if (!valid_values_set.empty()) {
 
114
    auto iter = std::find(valid_values_set.begin(), valid_values_set.end(), v);
 
115
    if (iter==valid_values_set.end()) { return false; }
 
116
  }
 
117
 
 
118
  return true;
 
119
}
 
120
 
 
121
std::string option_int::get_default_string() const
 
122
{
 
123
  std::stringstream sstr;
 
124
  sstr << default_value;
 
125
  return sstr.str();
 
126
}
 
127
 
 
128
 
 
129
std::string choice_option_base::getTypeDescr() const
 
130
{
 
131
  std::vector<std::string> choices = get_choice_names();
 
132
 
 
133
  std::stringstream sstr;
 
134
  sstr << "{";
 
135
 
 
136
  bool first=true;
 
137
#ifdef FOR_LOOP_AUTO_SUPPORT
 
138
  FOR_LOOP(auto, c, choices) {
 
139
#else
 
140
  FOR_LOOP(std::string, c, choices) {
 
141
#endif
 
142
    if (first) { first=false; }
 
143
    else { sstr << ","; }
 
144
 
 
145
    sstr << c;
 
146
  }
 
147
 
 
148
  sstr << "}";
 
149
  return sstr.str();
 
150
}
 
151
 
 
152
 
 
153
bool choice_option_base::processCmdLineArguments(char** argv, int* argc, int idx)
 
154
{
 
155
  if (argv==NULL)   { return false; }
 
156
  if (idx >= *argc) { return false; }
 
157
 
 
158
  std::string value = argv[idx];
 
159
 
 
160
  std::cout << "set " << value << "\n";
 
161
  bool success = set_value(value);
 
162
  std::cout << "success " << success << "\n";
 
163
 
 
164
  remove_option(argc,argv,idx,1);
 
165
 
 
166
  return success;
 
167
}
 
168
 
 
169
 
 
170
static char* fill_strings_into_memory(const std::vector<std::string>& strings_list)
 
171
{
 
172
  // calculate memory requirement
 
173
 
 
174
  int totalStringLengths = 0;
 
175
#ifdef FOR_LOOP_AUTO_SUPPORT
 
176
  FOR_LOOP(auto, str, strings_list) {
 
177
#else
 
178
  FOR_LOOP(std::string, str, strings_list) {
 
179
#endif
 
180
    totalStringLengths += str.length() +1; // +1 for null termination
 
181
  }
 
182
 
 
183
  int numStrings = strings_list.size();
 
184
 
 
185
  int pointersSize = (numStrings+1) * sizeof(const char*);
 
186
 
 
187
  char* memory = new char[pointersSize + totalStringLengths];
 
188
 
 
189
 
 
190
  // copy strings to memory area
 
191
 
 
192
  char* stringPtr = memory + (numStrings+1) * sizeof(const char*);
 
193
  const char** tablePtr = (const char**)memory;
 
194
 
 
195
#ifdef FOR_LOOP_AUTO_SUPPORT
 
196
  FOR_LOOP(auto, str, strings_list) {
 
197
#else
 
198
  FOR_LOOP(std::string, str, strings_list) {
 
199
#endif
 
200
    *tablePtr++ = stringPtr;
 
201
 
 
202
    strcpy(stringPtr, str.c_str());
 
203
    stringPtr += str.length()+1;
 
204
  }
 
205
 
 
206
  *tablePtr = NULL;
 
207
 
 
208
  return memory;
 
209
}
 
210
 
 
211
 
 
212
const char** choice_option_base::get_choices_string_table() const
 
213
{
 
214
  if (choice_string_table==NULL) {
 
215
    choice_string_table = fill_strings_into_memory(get_choice_names());
 
216
  }
 
217
 
 
218
  return (const char**)choice_string_table;
 
219
}
 
220
 
 
221
 
 
222
 
 
223
bool config_parameters::parse_command_line_params(int* argc, char** argv, int* first_idx_ptr,
 
224
                                                  bool ignore_unknown_options)
 
225
{
 
226
  int first_idx=1;
 
227
  if (first_idx_ptr) { first_idx = *first_idx_ptr; }
 
228
 
 
229
  for (int i=first_idx;i < *argc;i++) {
 
230
 
 
231
    if (argv[i][0]=='-') {
 
232
      // option
 
233
 
 
234
      if (argv[i][1]=='-') {
 
235
        // long option
 
236
 
 
237
        bool option_found=false;
 
238
 
 
239
        for (int o=0;o<mOptions.size();o++) {
 
240
          if (mOptions[o]->hasLongOption() && strcmp(mOptions[o]->getLongOption().c_str(),
 
241
                                                     argv[i]+2)==0) {
 
242
            option_found=true;
 
243
 
 
244
            bool success = mOptions[o]->processCmdLineArguments(argv,argc, i+1);
 
245
            if (!success) {
 
246
              if (first_idx_ptr) { *first_idx_ptr = i; }
 
247
              return false;
 
248
            }
 
249
 
 
250
            remove_option(argc,argv,i);
 
251
            i--;
 
252
 
 
253
            break;
 
254
          }
 
255
        }
 
256
 
 
257
        if (option_found == false && !ignore_unknown_options) {
 
258
          return false;
 
259
        }
 
260
      }
 
261
      else {
 
262
        // short option
 
263
 
 
264
        bool is_single_option = (argv[i][1] != 0 && argv[i][2]==0);
 
265
        bool do_remove_option = true;
 
266
 
 
267
        for (int n=1; argv[i][n]; n++) {
 
268
          char option = argv[i][n];
 
269
 
 
270
          bool option_found=false;
 
271
 
 
272
          for (int o=0;o<mOptions.size();o++) {
 
273
            if (mOptions[o]->getShortOption() == option) {
 
274
              option_found=true;
 
275
 
 
276
              bool success;
 
277
              if (is_single_option) {
 
278
                success = mOptions[o]->processCmdLineArguments(argv,argc, i+1);
 
279
              }
 
280
              else {
 
281
                success = mOptions[o]->processCmdLineArguments(NULL,NULL, 0);
 
282
              }
 
283
 
 
284
              if (!success) {
 
285
                if (first_idx_ptr) { *first_idx_ptr = i; }
 
286
                return false;
 
287
              }
 
288
 
 
289
              break;
 
290
            }
 
291
          }
 
292
 
 
293
          if (!option_found) {
 
294
            if (!ignore_unknown_options) {
 
295
              fprintf(stderr, "unknown option -%c\n",option);
 
296
              return false;
 
297
            }
 
298
            else {
 
299
              do_remove_option=false;
 
300
            }
 
301
          }
 
302
 
 
303
        } // all short options
 
304
 
 
305
        if (do_remove_option) {
 
306
          remove_option(argc,argv,i);
 
307
          i--;
 
308
        }
 
309
      } // is short option
 
310
    } // is option
 
311
  } // all command line arguments
 
312
 
 
313
  return true;
 
314
}
 
315
 
 
316
 
 
317
void config_parameters::print_params() const
 
318
{
 
319
  for (int i=0;i<mOptions.size();i++) {
 
320
    const option_base* o = mOptions[i];
 
321
 
 
322
    std::stringstream sstr;
 
323
    sstr << "  ";
 
324
    if (o->hasShortOption()) {
 
325
      sstr << '-' << o->getShortOption();
 
326
    } else {
 
327
      sstr << "  ";
 
328
    }
 
329
 
 
330
    if (o->hasShortOption() && o->hasLongOption()) {
 
331
      sstr << ", ";
 
332
    } else {
 
333
      sstr << "  ";
 
334
    }
 
335
 
 
336
    if (o->hasLongOption()) {
 
337
      sstr << "--" << std::setw(12) << std::left << o->getLongOption();
 
338
    } else {
 
339
      sstr << "              ";
 
340
    }
 
341
 
 
342
    sstr << " ";
 
343
    sstr << o->getTypeDescr();
 
344
 
 
345
    if (o->has_default()) {
 
346
      sstr << ", default=" << o->get_default_string();
 
347
    }
 
348
 
 
349
    sstr << "\n";
 
350
 
 
351
    std::cerr << sstr.str();
 
352
  }
 
353
}
 
354
 
 
355
 
 
356
void config_parameters::add_option(option_base* o)
 
357
{
 
358
  mOptions.push_back(o);
 
359
  delete[] param_string_table; // delete old table, since we got a new parameter
 
360
  param_string_table = NULL;
 
361
}
 
362
 
 
363
 
 
364
std::vector<std::string> config_parameters::get_parameter_IDs() const
 
365
{
 
366
  std::vector<std::string> ids;
 
367
 
 
368
#ifdef FOR_LOOP_AUTO_SUPPORT
 
369
  FOR_LOOP(auto, option, mOptions) {
 
370
#else
 
371
  FOR_LOOP(option_base*, option, mOptions) {
 
372
#endif
 
373
    ids.push_back(option->get_name());
 
374
  }
 
375
 
 
376
  return ids;
 
377
}
 
378
 
 
379
 
 
380
enum en265_parameter_type config_parameters::get_parameter_type(const char* param) const
 
381
{
 
382
  option_base* option = find_option(param);
 
383
  assert(option);
 
384
 
 
385
  if (dynamic_cast<option_int*>   (option)) { return en265_parameter_int; }
 
386
  if (dynamic_cast<option_bool*>  (option)) { return en265_parameter_bool; }
 
387
  if (dynamic_cast<option_string*>(option)) { return en265_parameter_string; }
 
388
  if (dynamic_cast<choice_option_base*>(option)) { return en265_parameter_choice; }
 
389
 
 
390
  assert(false);
 
391
  return en265_parameter_bool;
 
392
}
 
393
 
 
394
 
 
395
std::vector<std::string> config_parameters::get_parameter_choices(const char* param) const
 
396
{
 
397
  option_base* option = find_option(param);
 
398
  assert(option);
 
399
 
 
400
  choice_option_base* o = dynamic_cast<choice_option_base*>(option);
 
401
  assert(o);
 
402
  
 
403
  return o->get_choice_names();
 
404
}
 
405
 
 
406
 
 
407
option_base* config_parameters::find_option(const char* param) const
 
408
{
 
409
#ifdef FOR_LOOP_AUTO_SUPPORT
 
410
  FOR_LOOP(auto, o, mOptions) {
 
411
#else
 
412
  FOR_LOOP(option_base*, o, mOptions) {
 
413
#endif
 
414
    if (strcmp(o->get_name().c_str(), param)==0) { return o; }
 
415
  }
 
416
 
 
417
  return NULL;
 
418
}
 
419
 
 
420
 
 
421
bool config_parameters::set_bool(const char* param, bool value)
 
422
{
 
423
  option_base* option = find_option(param);
 
424
  assert(option);
 
425
 
 
426
  option_bool* o = dynamic_cast<option_bool*>(option);
 
427
  assert(o);
 
428
 
 
429
  return o->set(value);
 
430
}
 
431
 
 
432
bool config_parameters::set_int(const char* param, int value)
 
433
{
 
434
  option_base* option = find_option(param);
 
435
  assert(option);
 
436
 
 
437
  option_int* o = dynamic_cast<option_int*>(option);
 
438
  assert(o);
 
439
 
 
440
  return o->set(value);
 
441
}
 
442
 
 
443
bool config_parameters::set_string(const char* param, const char* value)
 
444
{
 
445
  option_base* option = find_option(param);
 
446
  assert(option);
 
447
 
 
448
  option_string* o = dynamic_cast<option_string*>(option);
 
449
  assert(o);
 
450
 
 
451
  return o->set(value);
 
452
}
 
453
 
 
454
bool config_parameters::set_choice(const char* param, const char* value)
 
455
{
 
456
  option_base* option = find_option(param);
 
457
  assert(option);
 
458
 
 
459
  choice_option_base* o = dynamic_cast<choice_option_base*>(option);
 
460
  assert(o);
 
461
 
 
462
  return o->set(value);
 
463
}
 
464
 
 
465
 
 
466
 
 
467
const char** config_parameters::get_parameter_choices_table(const char* param) const
 
468
{
 
469
  option_base* option = find_option(param);
 
470
  assert(option);
 
471
 
 
472
  choice_option_base* o = dynamic_cast<choice_option_base*>(option);
 
473
  assert(o);
 
474
 
 
475
  return o->get_choices_string_table();
 
476
}
 
477
 
 
478
const char** config_parameters::get_parameter_string_table() const
 
479
{
 
480
  if (param_string_table==NULL) {
 
481
    param_string_table = fill_strings_into_memory(get_parameter_IDs());
 
482
  }
 
483
 
 
484
  return (const char**)param_string_table;
 
485
}