Commit d8923cc42b9d5f05d227d735021904eecc6c4f7d
1 parent
7e6ac9f2
fixed embedded builds
Showing
5 changed files
with
168 additions
and
171 deletions
sdk/openbr_export.cpp
| @@ -82,6 +82,7 @@ $ br -help | @@ -82,6 +82,7 @@ $ br -help | ||
| 82 | * -# Consider the free open source program <a href="http://wincdemu.sysprogs.org">WinCDEmu</a> if you need a program to mount ISO images. | 82 | * -# Consider the free open source program <a href="http://wincdemu.sysprogs.org">WinCDEmu</a> if you need a program to mount ISO images. |
| 83 | * -# You will have to register with Microsoft after installation, but it's free. | 83 | * -# You will have to register with Microsoft after installation, but it's free. |
| 84 | * -# Grab any available <a href="http://www.microsoft.com/visualstudio/eng/downloads#d-visual-studio-2012-update">Visual Studio Updates</a>. | 84 | * -# Grab any available <a href="http://www.microsoft.com/visualstudio/eng/downloads#d-visual-studio-2012-update">Visual Studio Updates</a>. |
| 85 | + * -# Download and install <a href="http://msdn.microsoft.com/en-us/windows/hardware/hh852363.aspx">Windows 8 SDK</a>. | ||
| 85 | * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2-win32-x86.exe">Download CMake 2.8.10.2</a> and install. | 86 | * -# <a href="http://www.cmake.org/files/v2.8/cmake-2.8.10.2-win32-x86.exe">Download CMake 2.8.10.2</a> and install. |
| 86 | * -# During installation setup select "add CMake to PATH". | 87 | * -# During installation setup select "add CMake to PATH". |
| 87 | * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.4/OpenCV-2.4.4.tar.bz2">Download OpenCV 2.4.4</a>. | 88 | * -# <a href="http://downloads.sourceforge.net/project/opencvlibrary/opencv-unix/2.4.4/OpenCV-2.4.4.tar.bz2">Download OpenCV 2.4.4</a>. |
| @@ -100,19 +101,8 @@ $ br -help | @@ -100,19 +101,8 @@ $ br -help | ||
| 100 | * $ nmake install | 101 | * $ nmake install |
| 101 | * $ nmake clean | 102 | * $ nmake clean |
| 102 | * \endcode | 103 | * \endcode |
| 103 | - * -# <a href="http://releases.qt-project.org/qt5/5.0.1/single/qt-everywhere-opensource-src-5.0.1.zip">Download Qt 5.0.1</a> and unzip. | ||
| 104 | - * -# Install Perl/Python/Ruby dependencies as explained in the "Windows" section of "README". Make sure they are added to "path" when given the option during installation. | 104 | + * -# <a href="http://releases.qt-project.org/digia/5.0.1/backups/2013-01-18-412/qt-windows-opensource-5.0.1-msvc2012_64-x86_64-offline-2013-01-18-412.exe">Download Qt 5.0.1</a> and install. |
| 105 | * -# <a href="http://www.microsoft.com/en-us/download/confirmation.aspx?id=6812">Download Direct X Software Developement Kit</a> and install. | 105 | * -# <a href="http://www.microsoft.com/en-us/download/confirmation.aspx?id=6812">Download Direct X Software Developement Kit</a> and install. |
| 106 | - * -# From the VS2012 x64 Cross Tools Command Prompt: | ||
| 107 | - * \code | ||
| 108 | - * $ cd qt-everywhere-opensource-src-5.0.1 | ||
| 109 | - * $ configure -prefix C:\Qt\5.0.1\msvc2012 -opensource -confirm-license -nomake examples -nomake tests | ||
| 110 | - * $ nmake | ||
| 111 | - * $ nmake install | ||
| 112 | - * $ cd .. | ||
| 113 | - * $ rmdir /Q /S qt-everywhere-opensource-src-5.0.1 | ||
| 114 | - * \endcode | ||
| 115 | - * -# nmake will take several hours to finish. | ||
| 116 | * -# Create a <a href="github.com">GitHub</a> account and follow their instructions for <a href="https://help.github.com/articles/set-up-git">setting up Git</a>. | 106 | * -# Create a <a href="github.com">GitHub</a> account and follow their instructions for <a href="https://help.github.com/articles/set-up-git">setting up Git</a>. |
| 117 | * -# Launch "Git Bash" from the Desktop and clone OpenBR: | 107 | * -# Launch "Git Bash" from the Desktop and clone OpenBR: |
| 118 | * \code | 108 | * \code |
| @@ -128,7 +118,7 @@ $ br -help | @@ -128,7 +118,7 @@ $ br -help | ||
| 128 | * $ cd C:\openbr | 118 | * $ cd C:\openbr |
| 129 | * $ mkdir build-msvc2012 | 119 | * $ mkdir build-msvc2012 |
| 130 | * $ cd build-msvc2012 | 120 | * $ cd build-msvc2012 |
| 131 | - * $ cmake -G "CodeBlocks - NMake Makefiles" -DCMAKE_PREFIX_PATH="C:/OpenCV-2.4.4/build-msvc2012/install;C:/Qt/5.0.1/msvc2012" -DCMAKE_INSTALL_PREFIX="./install" -DBR_INSTALL_DEPENDENCIES=ON -DCMAKE_BUILD_TYPE=Release .. | 121 | + * $ cmake -G "CodeBlocks - NMake Makefiles" -DCMAKE_PREFIX_PATH="C:/OpenCV-2.4.4/build-msvc2012/install;C:/Qt/Qt5.0.1/5.0.1/msvc2012_64" -DCMAKE_INSTALL_PREFIX="./install" -DBR_INSTALL_DEPENDENCIES=ON -DCMAKE_BUILD_TYPE=Release .. |
| 132 | * $ nmake | 122 | * $ nmake |
| 133 | * $ nmake install | 123 | * $ nmake install |
| 134 | * \endcode | 124 | * \endcode |
sdk/plugins/format.cpp
| @@ -565,7 +565,6 @@ class webcamFormat : public Format | @@ -565,7 +565,6 @@ class webcamFormat : public Format | ||
| 565 | 565 | ||
| 566 | BR_REGISTER(Format, webcamFormat) | 566 | BR_REGISTER(Format, webcamFormat) |
| 567 | 567 | ||
| 568 | -#ifndef BR_EMBEDDED | ||
| 569 | /*! | 568 | /*! |
| 570 | * \ingroup formats | 569 | * \ingroup formats |
| 571 | * \brief Decodes images from Base64 xml | 570 | * \brief Decodes images from Base64 xml |
| @@ -578,13 +577,15 @@ class xmlFormat : public Format | @@ -578,13 +577,15 @@ class xmlFormat : public Format | ||
| 578 | 577 | ||
| 579 | Template read() const | 578 | Template read() const |
| 580 | { | 579 | { |
| 580 | + Template t; | ||
| 581 | + | ||
| 582 | +#ifndef BR_EMBEDDED | ||
| 581 | QDomDocument doc(file); | 583 | QDomDocument doc(file); |
| 582 | QFile f(file); | 584 | QFile f(file); |
| 583 | if (!f.open(QIODevice::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(file.flat())); | 585 | if (!f.open(QIODevice::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(file.flat())); |
| 584 | if (!doc.setContent(&f)) qFatal("Unable to parse %s.", qPrintable(file.flat())); | 586 | if (!doc.setContent(&f)) qFatal("Unable to parse %s.", qPrintable(file.flat())); |
| 585 | f.close(); | 587 | f.close(); |
| 586 | 588 | ||
| 587 | - Template t; | ||
| 588 | QDomElement docElem = doc.documentElement(); | 589 | QDomElement docElem = doc.documentElement(); |
| 589 | QDomNode subject = docElem.firstChild(); | 590 | QDomNode subject = docElem.firstChild(); |
| 590 | while (!subject.isNull()) { | 591 | while (!subject.isNull()) { |
| @@ -620,6 +621,7 @@ class xmlFormat : public Format | @@ -620,6 +621,7 @@ class xmlFormat : public Format | ||
| 620 | if (current.month() < dob.month()) age--; | 621 | if (current.month() < dob.month()) age--; |
| 621 | t.file.set("Age", age); | 622 | t.file.set("Age", age); |
| 622 | } | 623 | } |
| 624 | +#endif // BR_EMBEDDED | ||
| 623 | 625 | ||
| 624 | return t; | 626 | return t; |
| 625 | } | 627 | } |
| @@ -632,7 +634,6 @@ class xmlFormat : public Format | @@ -632,7 +634,6 @@ class xmlFormat : public Format | ||
| 632 | }; | 634 | }; |
| 633 | 635 | ||
| 634 | BR_REGISTER(Format, xmlFormat) | 636 | BR_REGISTER(Format, xmlFormat) |
| 635 | -#endif // BR_EMBEDDED | ||
| 636 | 637 | ||
| 637 | } // namespace br | 638 | } // namespace br |
| 638 | 639 |
sdk/plugins/gui.cmake
0 โ 100644
sdk/plugins/gui.cpp
0 โ 100644
| 1 | +#include <QApplication> | ||
| 2 | +#include <QLabel> | ||
| 3 | +#include <opencv2/imgproc/imgproc.hpp> | ||
| 4 | +#include <openbr_plugin.h> | ||
| 5 | + | ||
| 6 | +using namespace cv; | ||
| 7 | + | ||
| 8 | +namespace br | ||
| 9 | +{ | ||
| 10 | + | ||
| 11 | +QImage toQImage(const Mat &mat) | ||
| 12 | +{ | ||
| 13 | + // Convert to 8U depth | ||
| 14 | + Mat mat8u; | ||
| 15 | + if (mat.depth() != CV_8U) { | ||
| 16 | + double globalMin = std::numeric_limits<double>::max(); | ||
| 17 | + double globalMax = -std::numeric_limits<double>::max(); | ||
| 18 | + | ||
| 19 | + std::vector<Mat> mv; | ||
| 20 | + split(mat, mv); | ||
| 21 | + for (size_t i=0; i<mv.size(); i++) { | ||
| 22 | + double min, max; | ||
| 23 | + minMaxLoc(mv[i], &min, &max); | ||
| 24 | + globalMin = std::min(globalMin, min); | ||
| 25 | + globalMax = std::max(globalMax, max); | ||
| 26 | + } | ||
| 27 | + assert(globalMax >= globalMin); | ||
| 28 | + | ||
| 29 | + double range = globalMax - globalMin; | ||
| 30 | + if (range != 0) { | ||
| 31 | + double scale = 255 / range; | ||
| 32 | + convertScaleAbs(mat, mat8u, scale, -(globalMin * scale)); | ||
| 33 | + } else { | ||
| 34 | + // Monochromatic | ||
| 35 | + mat8u = Mat(mat.size(), CV_8UC1, Scalar((globalMin+globalMax)/2)); | ||
| 36 | + } | ||
| 37 | + } else { | ||
| 38 | + mat8u = mat; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + // Convert to 3 channels | ||
| 42 | + Mat mat8uc3; | ||
| 43 | + if (mat8u.channels() == 4) cvtColor(mat8u, mat8uc3, CV_BGRA2RGB); | ||
| 44 | + else if (mat8u.channels() == 3) cvtColor(mat8u, mat8uc3, CV_BGR2RGB); | ||
| 45 | + else if (mat8u.channels() == 1) cvtColor(mat8u, mat8uc3, CV_GRAY2RGB); | ||
| 46 | + | ||
| 47 | + return QImage(mat8uc3.data, mat8uc3.cols, mat8uc3.rows, 3*mat8uc3.cols, QImage::Format_RGB888).copy(); | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +// Provides slots for manipulating a QLabel, but does not inherit from QWidget. | ||
| 51 | +// Therefore, it can be moved to the main thread if not created there initially | ||
| 52 | +// since god forbid you create a QWidget subclass in not the main thread. | ||
| 53 | +class GUIProxy : public QObject | ||
| 54 | +{ | ||
| 55 | + Q_OBJECT | ||
| 56 | + | ||
| 57 | + QLabel * window; | ||
| 58 | + | ||
| 59 | +public: | ||
| 60 | + GUIProxy() | ||
| 61 | + { | ||
| 62 | + window =NULL; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | +public slots: | ||
| 66 | + void showImage(QPixmap pixmap) | ||
| 67 | + { | ||
| 68 | + window->show(); | ||
| 69 | + window->setPixmap(pixmap); | ||
| 70 | + window->setFixedSize(pixmap.size()); | ||
| 71 | + window->update(); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + void createWindow() | ||
| 75 | + { | ||
| 76 | + delete window; | ||
| 77 | + window = NULL; | ||
| 78 | + window = new QLabel(); | ||
| 79 | + } | ||
| 80 | +}; | ||
| 81 | + | ||
| 82 | +/*! | ||
| 83 | + * \ingroup transforms | ||
| 84 | + * \brief Displays templates in a GUI pop-up window using QT. | ||
| 85 | + * \author Charles Otto \cite caotto | ||
| 86 | + * Unlike ShowTransform, this can be used with parallelism enabled, although it | ||
| 87 | + * is considered TimeVarying. | ||
| 88 | + */ | ||
| 89 | +class Show2Transform : public TimeVaryingTransform | ||
| 90 | +{ | ||
| 91 | + Q_OBJECT | ||
| 92 | +public: | ||
| 93 | + Show2Transform() : TimeVaryingTransform(false, false) | ||
| 94 | + { | ||
| 95 | + // Create our GUI proxy | ||
| 96 | + gui = new GUIProxy(); | ||
| 97 | + // Move it to the main thread, this means signals we send to it will | ||
| 98 | + // be run in the main thread, which is hopefully in an event loop | ||
| 99 | + gui->moveToThread(QApplication::instance()->thread()); | ||
| 100 | + // Connect our signals to the proxy's slots | ||
| 101 | + connect(this, SIGNAL(needWindow()), gui, SLOT(createWindow()), Qt::BlockingQueuedConnection); | ||
| 102 | + connect(this, SIGNAL(updateImage(QPixmap)), gui, SLOT(showImage(QPixmap))); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + ~Show2Transform() | ||
| 106 | + { | ||
| 107 | + delete gui; | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + void train(const TemplateList &data) { (void) data; } | ||
| 111 | + | ||
| 112 | + void project(const TemplateList &src, TemplateList &dst) const | ||
| 113 | + { | ||
| 114 | + Transform * non_const = (Show2Transform *) this; | ||
| 115 | + non_const->projectUpdate(src,dst); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + void projectUpdate(const TemplateList &src, TemplateList &dst) | ||
| 119 | + { | ||
| 120 | + dst = src; | ||
| 121 | + | ||
| 122 | + if (src.empty()) | ||
| 123 | + return; | ||
| 124 | + | ||
| 125 | + foreach (const Template & t, src) { | ||
| 126 | + foreach(const cv::Mat & m, t) { | ||
| 127 | + QImage qImageBuffer = toQImage(m); | ||
| 128 | + displayBuffer.convertFromImage(qImageBuffer); | ||
| 129 | + emit updateImage(displayBuffer); | ||
| 130 | + } | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + void finalize(TemplateList & output) | ||
| 135 | + { | ||
| 136 | + (void) output; | ||
| 137 | + // todo: hide ui? | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + void init() | ||
| 141 | + { | ||
| 142 | + emit needWindow(); | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | +protected: | ||
| 146 | + GUIProxy * gui; | ||
| 147 | + QPixmap displayBuffer; | ||
| 148 | + | ||
| 149 | +signals: | ||
| 150 | + void needWindow(); | ||
| 151 | + void updateImage(QPixmap input); | ||
| 152 | +}; | ||
| 153 | + | ||
| 154 | +BR_REGISTER(Transform, Show2Transform) | ||
| 155 | + | ||
| 156 | +} // namespace br | ||
| 157 | + | ||
| 158 | +#include "gui.moc" |
sdk/plugins/misc.cpp
| @@ -19,13 +19,6 @@ | @@ -19,13 +19,6 @@ | ||
| 19 | 19 | ||
| 20 | #include "core/opencvutils.h" | 20 | #include "core/opencvutils.h" |
| 21 | 21 | ||
| 22 | -#ifndef BR_EMBEDDED | ||
| 23 | -#include <QLabel> | ||
| 24 | -#include <opencv2/imgproc/imgproc.hpp> | ||
| 25 | -#include <QApplication> | ||
| 26 | -#endif | ||
| 27 | - | ||
| 28 | - | ||
| 29 | using namespace cv; | 22 | using namespace cv; |
| 30 | 23 | ||
| 31 | namespace br | 24 | namespace br |
| @@ -97,154 +90,6 @@ int ShowTransform::counter = 0; | @@ -97,154 +90,6 @@ int ShowTransform::counter = 0; | ||
| 97 | 90 | ||
| 98 | BR_REGISTER(Transform, ShowTransform) | 91 | BR_REGISTER(Transform, ShowTransform) |
| 99 | 92 | ||
| 100 | -#ifndef BR_EMBEDDED | ||
| 101 | - | ||
| 102 | -QImage toQImage(const Mat &mat) | ||
| 103 | -{ | ||
| 104 | - // Convert to 8U depth | ||
| 105 | - Mat mat8u; | ||
| 106 | - if (mat.depth() != CV_8U) { | ||
| 107 | - double globalMin = std::numeric_limits<double>::max(); | ||
| 108 | - double globalMax = -std::numeric_limits<double>::max(); | ||
| 109 | - | ||
| 110 | - std::vector<Mat> mv; | ||
| 111 | - split(mat, mv); | ||
| 112 | - for (size_t i=0; i<mv.size(); i++) { | ||
| 113 | - double min, max; | ||
| 114 | - minMaxLoc(mv[i], &min, &max); | ||
| 115 | - globalMin = std::min(globalMin, min); | ||
| 116 | - globalMax = std::max(globalMax, max); | ||
| 117 | - } | ||
| 118 | - assert(globalMax >= globalMin); | ||
| 119 | - | ||
| 120 | - double range = globalMax - globalMin; | ||
| 121 | - if (range != 0) { | ||
| 122 | - double scale = 255 / range; | ||
| 123 | - convertScaleAbs(mat, mat8u, scale, -(globalMin * scale)); | ||
| 124 | - } else { | ||
| 125 | - // Monochromatic | ||
| 126 | - mat8u = Mat(mat.size(), CV_8UC1, Scalar((globalMin+globalMax)/2)); | ||
| 127 | - } | ||
| 128 | - } else { | ||
| 129 | - mat8u = mat; | ||
| 130 | - } | ||
| 131 | - | ||
| 132 | - // Convert to 3 channels | ||
| 133 | - Mat mat8uc3; | ||
| 134 | - if (mat8u.channels() == 4) cvtColor(mat8u, mat8uc3, CV_BGRA2RGB); | ||
| 135 | - else if (mat8u.channels() == 3) cvtColor(mat8u, mat8uc3, CV_BGR2RGB); | ||
| 136 | - else if (mat8u.channels() == 1) cvtColor(mat8u, mat8uc3, CV_GRAY2RGB); | ||
| 137 | - | ||
| 138 | - return QImage(mat8uc3.data, mat8uc3.cols, mat8uc3.rows, 3*mat8uc3.cols, QImage::Format_RGB888).copy(); | ||
| 139 | -} | ||
| 140 | - | ||
| 141 | -// Provides slots for manipulating a QLabel, but does not inherit from QWidget. | ||
| 142 | -// Therefore, it can be moved to the main thread if not created there initially | ||
| 143 | -// since god forbid you create a QWidget subclass in not the main thread. | ||
| 144 | -class GUIProxy : public QObject | ||
| 145 | -{ | ||
| 146 | - Q_OBJECT | ||
| 147 | - | ||
| 148 | - QLabel * window; | ||
| 149 | - | ||
| 150 | -public: | ||
| 151 | - GUIProxy() | ||
| 152 | - { | ||
| 153 | - window =NULL; | ||
| 154 | - } | ||
| 155 | - | ||
| 156 | -public slots: | ||
| 157 | - void showImage(QPixmap pixmap) | ||
| 158 | - { | ||
| 159 | - window->show(); | ||
| 160 | - window->setPixmap(pixmap); | ||
| 161 | - window->setFixedSize(pixmap.size()); | ||
| 162 | - window->update(); | ||
| 163 | - } | ||
| 164 | - | ||
| 165 | - void createWindow() | ||
| 166 | - { | ||
| 167 | - delete window; | ||
| 168 | - window = NULL; | ||
| 169 | - window = new QLabel(); | ||
| 170 | - } | ||
| 171 | -}; | ||
| 172 | - | ||
| 173 | -/*! | ||
| 174 | - * \ingroup transforms | ||
| 175 | - * \brief Displays templates in a GUI pop-up window using QT. | ||
| 176 | - * \author Charles Otto \cite caotto | ||
| 177 | - * Unlike ShowTransform, this can be used with parallelism enabled, although it | ||
| 178 | - * is considered TimeVarying. | ||
| 179 | - */ | ||
| 180 | -class Show2Transform : public TimeVaryingTransform | ||
| 181 | -{ | ||
| 182 | - Q_OBJECT | ||
| 183 | -public: | ||
| 184 | - Show2Transform() : TimeVaryingTransform(false, false) | ||
| 185 | - { | ||
| 186 | - // Create our GUI proxy | ||
| 187 | - gui = new GUIProxy(); | ||
| 188 | - // Move it to the main thread, this means signals we send to it will | ||
| 189 | - // be run in the main thread, which is hopefully in an event loop | ||
| 190 | - gui->moveToThread(QApplication::instance()->thread()); | ||
| 191 | - // Connect our signals to the proxy's slots | ||
| 192 | - connect(this, SIGNAL(needWindow()), gui, SLOT(createWindow()), Qt::BlockingQueuedConnection); | ||
| 193 | - connect(this, SIGNAL(updateImage(QPixmap)), gui, SLOT(showImage(QPixmap))); | ||
| 194 | - } | ||
| 195 | - | ||
| 196 | - ~Show2Transform() | ||
| 197 | - { | ||
| 198 | - delete gui; | ||
| 199 | - } | ||
| 200 | - | ||
| 201 | - void train(const TemplateList &data) { (void) data; } | ||
| 202 | - | ||
| 203 | - void project(const TemplateList &src, TemplateList &dst) const | ||
| 204 | - { | ||
| 205 | - Transform * non_const = (Show2Transform *) this; | ||
| 206 | - non_const->projectUpdate(src,dst); | ||
| 207 | - } | ||
| 208 | - | ||
| 209 | - void projectUpdate(const TemplateList &src, TemplateList &dst) | ||
| 210 | - { | ||
| 211 | - dst = src; | ||
| 212 | - | ||
| 213 | - if (src.empty()) | ||
| 214 | - return; | ||
| 215 | - | ||
| 216 | - foreach (const Template & t, src) { | ||
| 217 | - foreach(const cv::Mat & m, t) { | ||
| 218 | - QImage qImageBuffer = toQImage(m); | ||
| 219 | - displayBuffer.convertFromImage(qImageBuffer); | ||
| 220 | - emit updateImage(displayBuffer); | ||
| 221 | - } | ||
| 222 | - } | ||
| 223 | - } | ||
| 224 | - | ||
| 225 | - void finalize(TemplateList & output) | ||
| 226 | - { | ||
| 227 | - (void) output; | ||
| 228 | - // todo: hide ui? | ||
| 229 | - } | ||
| 230 | - | ||
| 231 | - void init() | ||
| 232 | - { | ||
| 233 | - emit needWindow(); | ||
| 234 | - } | ||
| 235 | - | ||
| 236 | -protected: | ||
| 237 | - GUIProxy * gui; | ||
| 238 | - QPixmap displayBuffer; | ||
| 239 | - | ||
| 240 | -signals: | ||
| 241 | - void needWindow(); | ||
| 242 | - void updateImage(QPixmap input); | ||
| 243 | -}; | ||
| 244 | - | ||
| 245 | -BR_REGISTER(Transform, Show2Transform) | ||
| 246 | -#endif | ||
| 247 | - | ||
| 248 | /*! | 93 | /*! |
| 249 | * \ingroup transforms | 94 | * \ingroup transforms |
| 250 | * \brief Prints the template's file to stdout or stderr. | 95 | * \brief Prints the template's file to stdout or stderr. |