libtgd 4.1
A library that makes working with multidimensional arrays in C++ easy
libtgd Reference

Tagged Grid Data (TGD): Overview

TGD manages multidimensional arrays. Each array element consists of a fixed number of components. All components are of the same data type (integer or floating point). For example, an array holding image data could be a two-dimensional array with size 800x600, and each element could consist of three uint8 components representing the R, G, and B channels.

Metadata is managed using tags, which are key/value pairs where both key and value are represented as strings. An array has a global tag lists (typically describing the array data as a whole), dimension-specific tag lists (typically describing the dimensions), and component-specific tag lists (typically describing the interpretation of each component).

The libtgd Library

The library works with the following classes: TGD::TagList to manage metadata, TGD::ArrayDescription to handle all metadata describing an array, TGD::ArrayContainer to handle array data of any type, and finally TGD::Array to handle arrays with a specific data type so that convenient operations on the data are possible.

All array data is shared by default when making copies of an array. If you want a copy of the data, use TGD::ArrayContainer::deepCopy() or TGD::Array::deepCopy().

Input and output are managed by the TGD::Importer and TGD::Exporter classes, and there are shortcuts TGD::load() and TGD::save() to read and write arrays in just one line of code.

TGD Manual

The tgd manual contains an overview of supported file formats, the specification of the native TGD file format, and a list of common tags.

Examples

This program creates an image:

#include <tgd/array.hpp>
#include <tgd/io.hpp>
int main(void)
{
TGD::Array<uint8_t> image({800, 600}, 3);
for (size_t y = 0; y < image.dimension(1); y++) {
for (size_t x = 0; x < image.dimension(0); x++) {
image[{x, y}][0] = x / (image.dimension(0) - 1.0f) * 255; // red
image[{x, y}][1] = y / (image.dimension(1) - 1.0f) * 255; // green
image[{x, y}][2] = 0; // blue
}
}
TGD::save(image, "image.ppm");
return 0;
}
An Array with a specific component data type given the template parameter. This is the main class to ...
Definition: array.hpp:887
bool save(const ArrayContainer &A, const std::string &fileName, bool append=Overwrite, Error *error=nullptr, const TagList &hints=TagList())
Shortcut to write a single array to a file in a single line of code.
Definition: io.hpp:208

This example loads an image, extracts the red channel, and saves it to a file:

#include <tgd/array.hpp>
#include <tgd/io.hpp>
int main(void)
{
TGD::Array<uint8_t> image = TGD::load("image.ppm");
TGD::Array<uint8_t> greenChannel(image.dimensions(), 1);
for (size_t i = 0; i < greenChannel.elementCount(); i++) {
greenChannel[i][0] = image[i][1];
}
TGD::save(greenChannel, "green.pgm");
return 0;
}
const std::vector< size_t > & dimensions() const
Returns the list of dimensions.
Definition: array.hpp:419
ArrayContainer load(const std::string &fileName, const TagList &hints=TagList(), Error *error=nullptr)
Shortcut to read a single array from a file in a single line of code.
Definition: io.hpp:202

This example modifies array data using operators and alternatively TGD::forEachComponent() which works with lambdas, functors and functions. There are also variants that take two arrays as input, and variants that work on elements instead of components.

#include <tgd/array.hpp>
#include <tgd/foreach.hpp>
#include <tgd/operators.hpp>
#include <tgd/io.hpp>
uint8_t func(uint8_t a)
{
return a * a;
}
struct {
uint8_t operator()(uint8_t a)
{
return a * a;
}
} functor;
int main(void)
{
TGD::Array<uint8_t> image = TGD::load("image.ppm");
// Modify via operator
TGD::Array<uint8_t> r3 = image * image;
// Modify via lambda
TGD::Array<uint8_t> r0 = TGD::forEachComponent(image, [] (uint8_t a) -> uint8_t { return a * a; });
// Modify via function
// Modify via functor
// Save results. All are the same.
// Note that a*a will overflow an uint8_t, but that creates a nice pattern ;)
TGD::save(r0, "r0.ppm");
TGD::save(r1, "r1.ppm");
TGD::save(r2, "r2.ppm");
TGD::save(r3, "r3.ppm");
return 0;
}
Array< T > forEachComponent(const Array< T > &a, FUNC func)
Apply func to all components in array a.
Definition: foreach.hpp:39

This example shows that STL algorithms can work on TGD arrays both on component and on element level:

#include <algorithm>
#include <tgd/array.hpp>
#include <tgd/io.hpp>
int main(void)
{
TGD::Array<uint8_t> image = TGD::load("image.ppm");
TGD::Array<uint8_t> sorted = image.deepCopy();
std::sort(sorted.componentBegin(), sorted.componentEnd());
TGD::save(sorted, "sorted.ppm");
TGD::Array<uint8_t> answer = image.deepCopy();
std::for_each(answer.componentBegin(), answer.componentEnd(),
[](uint8_t& v) { v = 42; });
TGD::save(answer, "answer.ppm");
TGD::Array<uint8_t> orange = image.deepCopy();
std::for_each(orange.elementBegin(), orange.elementEnd(),
[](uint8_t* v) { v[0] = 255; v[1] = 128; v[2] = 64; });
TGD::save(orange, "orange.ppm");
return 0;
}
ElementIterator elementBegin() noexcept
Returns an iterator pointing to the first element.
Definition: array.hpp:1103
ElementIterator elementEnd() noexcept
Returns an iterator pointing past the last element.
Definition: array.hpp:1105
ComponentIterator componentBegin() noexcept
Returns an iterator pointing to the first component of the first element.
Definition: array.hpp:1099
ComponentIterator componentEnd() noexcept
Returns an iterator pointing past the last component of the last element.
Definition: array.hpp:1101
Array deepCopy() const
Construct an array and perform deep copy of data.
Definition: array.hpp:921