General Support Types and Functions

../_images/utils1.png

The Utils package contains a set of C++ support functions and classes. Due to the library dependency order, these classes have no internal dependencies. In particular, the utils package does not contain classes or functions that are related to image processing.

Basic Types

ICL’s basic data types are defined in ICLUtils/BasicTypes.h. Unlike all other classes, types and functions, the basic types are defined directly in the icl -namespace. The type syntax is copied from the Intel IPP library: All types have an icl-prefix, an integer-value that describes the number of bits used, and a suffix

  • u for unsigned integers
  • s for signed integers
  • f for floating point numbers
  • c for complex floating point numbers

The most common types are

  • icl8u for 8 bit unsigned integers (commonly known as unsigned char)
  • icl16s for 16 bit signed integers (commonly known as short)
  • icl32s for 32 bit signed integers (usually int)
  • icl32f for floats
  • icl64f for doubles

ICL’s image classes (provided by the ICLCore module) are implemented for these common types Note: Please ensure not to mix up the basic data types with the alternatives for the enumeration core::depth which are

The core::depth value is used for run-time type-inference

Support Types

Point and Point32f

A simple 2D point class with int (float for Point32f) elements x and y. Other than this, points behave like built-in types. They are serialized as and de-serialized from “(x,y)”

Note

in case of Intel IPP Support, Point is derived from it’s IPP-counter-part IppiPoint

Size and Size32f

Like the Point classes, but with members width and height. Serialized and de-serialized from “WxH”.

Note

in case of Intel IPP Support, Size is derived from it’s IPP-counter-part IppiSize

Rect and Rect32f

Defines a rectangle by given x, y, width and height. Serialization: “(x,y)WxH”

Note

in case of Intel IPP Support, Rect is derived from it’s IPP-counter-part IppiRect

Range and SteppingRange

A template class for ranges, described by minVal and maxVal. SteppingRange extends the Range template by a stepping member variable of the same type

Uncopyable and Lockable

Two straight-forward to use interfaces. Uncopyable just declares copy constructor and assignment operators in a private scope to avoid copying instances of classes that are derived from it. The Lockable interfaces contains a Mutex and provides a lock and unlock method. Mutex and Lockable instances can be scope-locked using an instance of Mutex::Locker.

VisualizationDescription

Utility class for describing visualizations in a state-machine manner. With this tool, classes can e.g. provide a visualization of something, that can then be rendered generically

Program Argument Evaluation

The program argument evaluation toolkit is used in most ICL-based applications. It provides

  • a simple and intuitive string-based description of allowed program arguments
  • an easy to use way to describe program arguments
  • a efficient parser for program arguments, that provides human-readable error messages
  • an automatically supported set of common default program arguments, such as -version or -help
  • a concise method pa that can be use to query whether a specific program argument has been given and what it’s sub arguments where

The usage of the program argument evaluation toolkit is explain in an extra chapter of the tutorial (see Evaluating Program Arguments)

The Configurable interface

The Configurable-interface can be used to define a classes parameters/properties that shall be changed at runtime. The Configurable-subclasses can define properties that can be accessed by string identifiers. Each property has a type, a type-dependend description of possible values, a current value and a so called volatileness. Further details and examples are given in the tutorial The Configurable Interface.

Smart-Pointer and Smart-Array

ICL provides a very simple, yet powerful reference counting smart-pointer implementation SmartPtr that basically behaves like the boost::shared_ptr. For array-pointers (where the data was created using new []), the SmartArray can be used.

Time and Timer Support

utils::Time

Here, the main utility class is Time, which was originally copied from libiceutils. The Time class provides microsecond resolutions internally represented as an icl64s. Time::now() returns the current system time. Time instances can easily be added, subtracted and compared. In contrast to e.g. the boost-libraries, the time class represents absolute times and time intervalls at once.

FPSEstimator

This class can be used to estimate the average frames-per-second count of a running application:

void runction(){
  static icl::utils::FPSEstimator fps(10); // averages over 10 iterations
  std::cout << fps.getFPSString() << std::endl;
}

FPSLimiter

The limiter inherits the FPSEstimator class. It’s FPSLimiter::wait() method will wait long enough to ensure, the desired FPS-limit is not overshot.

StackTimer

The StackTimer is a very special tool, that can be used for coarse profiling. The header ICLUtils/StackTimer.h provides the magic-macros BENCHMARK_THIS_FUNCTION and BENCHMARK_THIS_SCOPE(STRING):

void foo(){
  BENCHMARK_THIS_FUNCTION;
  // some other stuff
}

Now, you’ll get an evaluation of the run-time of your function when your program exits normally.

Exceptions Types

ICL’s basic exception type is ICLException that inherits std::runtime_error. In addition, there are several other exception types either implemented in the ICLUtils/Exception.h header or within one of the other ICL modules. ICL’s exception hierarchy is rather flat; most of the time either ICLException or a direct child-class instance is thrown.

Multi-Threading Tools

Here, the two fundamental classes are Thread and Mutex which are basically simple wrappers of the corresponding PThread-types. Most of the time, threading must not be implemented explicitly. Instead the ICLApplication can be used for multi-threaded (interactive) applications.

XML-based Configuration Files

We included the Pugi-XML parsing framework into the ICL source tree. Even though, this can be uses for XML file parsing and creation, ICL provides a much simpler tool for XML-based configuration files, the ConfigFile class. This is documented in an extra chapter of the tutorial (see XML-based Configuration Files)

String Manipulation

str and parse

Since C++’s support for string manipulation is a bit weak, ICL supports a set of support functions for intuitive and easy-to use string manipulation. Most important are the two function templates:

template<class T>
std::string str(const T &instance);

template<class T>
T parse(const std::string &text);

where str converts a type instance into a string, and parse converts a string into a type instance. Internally, these functions make use of the in- and output stream-operators (<< and >>). Therefore, str is automatically supported for each type that supports the std::ostream-operator and parse for each type that supports the std::istream-operator. For most of the common ICL-types, this is true.

Array2D

Any

Any is a utility class that defines a string-serialized object. Any is derived from the std::string, and extends it’s functionality by easy to use serialization and de-serialization functions. An Any instance can be created from every type that is supported by the str-template (see above). And it can be converted to any type that is supported by the parse-template

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <ICLUtils/Any.h>

#include <ICLMath/FixedMatrix.h>
#include <ICLUtils/Size.h>
#include <ICLCore/Types.h>
#include <ICLCore/CoreFunctions.h>

using namespace icl;

int main(){
  /// create Any instance from data types (implicitly)
  utils::Any i = 5;
  utils::Any d = M_PI;
  utils::Any s = utils::Size::VGA;
  utils::Any f = core::formatRGB;
  utils::Any m = math::FixedMatrix<float,3,2>(1,2,3,
                                              4,5,6);

  // show
  std::cout << " int:" << i << " double:" << d 
            << " size:" << s << " format:" << f 
            << std::endl << " matrix:" << m << std::endl;

  /// create data-type from Any instances (implicitly)
  int ii = i;
  double dd = d;
  utils::Size ss = s;
  core::format ff = f;
  math::FixedMatrix<float,3,2> mm = m;

  // show
  std::cout << " int:" << ii << " double:" << dd 
            << " size:" << ss << " format:" << ff 
            << std::endl << " matrix:" << mm << std::endl;

  
  
  // explicit cross-type parsing
  int x = d.as<int>();
  utils::Point y = s.as<utils::Point>();
  
  std::cout << "double as int:" << x << std::endl;

  std::cout << "size as point:" << y << std::endl;
  
}

tok and cat

The two support functions are used for tokenization and concatination of string. tok can tokenize strings an std::vector<string> tokens. It can either use a set of single allowed char-delimiters, or a delimiting std::string. Furthermore, an escape-character can be defined for also being able to use the delimiting characters.

The opposite of tok is cat, which concatenate the elements of an std::vector<std::string>. Optionally a delimiter can be inserted between the elements here.

match

Is a regular expression matching function. It also supports accessing sub-matches.

The Generic Function Class

The Function class and it’s heavily overloaded creator function function, is a simplification of the well known boost::function type. The Function defines a generic interface for

  • global functions
  • static functions (in classes, that are basically global)
  • member functions
  • functors
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
#include <ICLUtils/Function.h>
#include <iostream>
#include <algorithm>
#include <vector>


using namespace icl::utils;

void global_foo(){
  std::cout << "void global_foo()" << std::endl;
}
int global_foo2(){
  std::cout << "int global_foo() returning 5" << std::endl;
  return 5;
}

int global_add(int a, int b) { return a+b; }

struct Foo{
  int add(int a, int b){
    std::cout << "Foo.add(" << a << "," << b << ") = " << a+b << std::endl;
    return a+b;
  }
  int operator()(int a, int b){
    std::cout << "Foo(" << a << "," << b << ") = " << a+b << std::endl;
    return a+b;
  }
  static void show_int(int i){
    std::cout << i << std::endl;
  }
};

int main(){
  /// simple parameterless global function
  Function<void> gfoo(global_foo);
  gfoo();

  /// global function that returns an int
  Function<int> gfoo2(global_foo2);
  std::cout << gfoo2() << std::endl;

  /// Implicit cast from function with return value to function without return value
  Function<int> gfoo3 = function(global_foo2);
  gfoo3();

  /// Global function with parameters
  /// identical to function(global_add)(4,5)
  Function<int,int,int> gadd(global_add);
  std::cout << "global_add(4,5)=" << gadd(4,5) << std::endl;

  /// create an std::vector
  std::vector<int> v;

  /// void-Member function with one parameter
  /// preserve type-correctness (argument is not int, but const int&)
  Function<void,const int&> vpush = function(v,&std::vector<int>::push_back);
  vpush(1);  vpush(2);  vpush(3);

  /// access elements with this function
  Function<int&,size_t> vat = function(v,&std::vector<int>::at);
  std::cout << "elem 0: " << vat(0) << std::endl;
  std::cout << "elem 1: " << vat(1) << std::endl;
  std::cout << "elem 2: " << vat(2) << std::endl;

  /// create an instance of the foo class
  Foo f;

  /// creating a list of functions of same type
  std::vector<Function<int,int,int> > list;
  list.push_back(function(f,&Foo::add)); // member function
  list.push_back(function(f,SelectFunctor<int,int,int>())); // a functor
  list.push_back(global_add);  // a global function

  /// Finally, we are also able to implement the FunctionImpl-interface
  /// here, we have to implement the corresponding constructor
  /// (which must const!!!)
  struct Impl : FunctionImpl<int,int,int>{
    virtual int operator()(int a, int b) const{
      std::cout << "custom impl:operator()(a,b) = " << a+b << std::endl;
      return a+b;
    }
  };
  // list.push_back(function(new Impl));
  // would also be possible, but implicit cast is possible
  list.push_back(new Impl);

  /// clear the vector of ints also by using a Function-instance:
  function(v,&std::vector<int>::clear)();

  /// create a function that wraps the index operator
  Function<int&,size_t> vidxop = function(v,&std::vector<int>::operator[]);

  /// push the results of the function in the vector
  for(unsigned int i=0;i<list.size();++i){
    vpush(list[i](i,i));
  }

  /// create a function for the vector size
  Function<size_t> vsize = function(v,&std::vector<int>::size);

  /// show the result of the vector-size function
  std::cout << vsize() << std::endl;


  for(unsigned int i=0;i<vsize();++i){
    std::cout << "v[" << i << "] = " << vidxop(i) << std::endl;
  }

  /// or use a function and std::for_each to print the results
  std::for_each(v.begin(),v.end(),function(Foo::show_int));
}

Random Number Generation

Even though, creation of random numbers is supported sufficiently in C++, ICL provides some extra functions and classes here. In particular creation of Gaussian distributed random numbers usually requires some extra work. In addition to the normal random number generation functions random(min,max) and gaussRandom(mean,variance), few special classes are provided, that can be created with the random number generation properties, and that will draw a new random number, whenever they are assigned to something.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <ICLUtils/Random.h>
#include <vector>
#include <algorithm>

using namespace icl;

int main(){
  // intialize with current system time
  utils::randomSeed();
  
  // uniformly distributed random number between 0 and 1
  float f = utils::random(0,1);
  
  // Gaussian random number with mean 0 and variance 1
  float g = utils::gaussRandom(0,1);

  // buffer
  std::vector<float> ns(100);
  
  // fill each element with a random number
  // here uniformly distributed in [10,20]
  std::fill(ns.begin(),ns.end(), utils::URand(10,20));

  // or with gaussian random numbers
  std::fill(ns.begin(),ns.end(), utils::GRand(0,3));

  // create random indices (int values between 0 and given max)
  std::vector<int> is(100);
  std::fill(is.begin(),is.end(),utils::URandI(99));
}

The File class

The File class is a simple, yet powerful wrapper of a default C-Style FILE-pointer. In case of zlib-support, it provides built-in abilities for gzipped file I/O. I.e. as soon as a file-ending ”.gz” is detected, the file will be written and read using zlib-functions.

In addition to this it supports

  • buffered reading
  • decomposition of file names into directory, basename and suffix
  • several reading and writing functions
  • File::exists()

OpenCL Support Framework

ICL’s OpenCL support framework is intendet to provide an even easier access to OpenCL based acceleration. The framework is even settled on a higher level then OpenCL’s C++ front-end allowing to create and embed OpenCL code with only a few lines of support code. Relevant classes are:

  • utils::CLProgram, functioning as the main-class and as a factory for instances of the other support classes
  • utils::CLKernel, referencing a callable OpenCL function usually called kernel. Kernels can be filled with arguments and be called.
  • utils::CLBuffer, buffers are used to exchange memory with graphics card memory (i.e. uploading and downloading memory blocks from and to the graphics card memory)

An example for a simple 3x3 image convolution can be found in the utils::CLProgram API documentation-

Others

MultiTypeMap

Abstract map implementation, that can hold entries of different types

ProcessMonitor

Grants process information at run-time such as the current memory consumption, the application’s thread-count or the average processor usage of the system and the current process.

ShallowCopyable

A generic, but difficult to use utility class for the creation of shallow- copyable classes

SignalHandler

C++-based wrapper of the C-functions around sigaction for process signal handling

Support Macros

DEBUG_LOG(MESSAGE-STREAM)

Can be used to show standard debug messages, that automatically include the source file, line and function name. Internally a C++-stream is used so that debug messages can easily be composed:

DEBUG_LOG("loop " << i );

WARNING_LOG and ERROR_LOG

Can be used to show warning and critical log messages. They work identically like DEBUG_LOG

ICLASSERT(assertion)

Standard assertion wrapper that shows the code position of the failure. For convenience also ASSERT_RETURN(assertion), ASSERT_THROW(assertion,exception) and ASSERT_RETURN_VAL(assertion,return-value) are provided.

ICL_UNLIKELY(unlikely-test)

Is a wrapper of gcc’s __builtin_expect:

if(ICL_UNLIKELY(error)){
   break;
}

ICL_DEPRECATED

Can be used to add a deprecated status to functions and classes:

void ICL_DEPRECATED foo(){ .. }
class ICL_DEPRECATED Bar { ...};

sqr

Is a generic power-of-two template, that is sometimes very useful.

Note

utils::sqr is a function rather than a macro and therefore is lies within the icl::utils-namespace

iclMin and iclMax

Are generic replacements of the sometimes missing std::min and std::max function templates. Usually, iclMin and iclMax are just macros that forward their arguments to the std-functions

ICL_DELETE(pointer)

Deletes only non-null pointers and sets them to 0 after deletion. For arrays, ICL_DELETE_ARRAY(pointer) has to be used.