Commit 7b17e41327f0e2b71ecf7d9ccc30929a6d909475
1 parent
e8a5fd10
remove universal template
Showing
6 changed files
with
1 additions
and
375 deletions
openbr/CMakeLists.txt
| @@ -4,8 +4,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) | @@ -4,8 +4,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) | ||
| 4 | 4 | ||
| 5 | # Collect source files | 5 | # Collect source files |
| 6 | set(SRC openbr.cpp | 6 | set(SRC openbr.cpp |
| 7 | - openbr_plugin.cpp | ||
| 8 | - universal_template.cpp) | 7 | + openbr_plugin.cpp) |
| 9 | aux_source_directory(core BR_CORE) | 8 | aux_source_directory(core BR_CORE) |
| 10 | include(plugins/plugins.cmake) | 9 | include(plugins/plugins.cmake) |
| 11 | 10 |
openbr/openbr_plugin.cpp
| @@ -407,128 +407,6 @@ static T findAndRemove(QVariantMap &map, const QString &key, const T &defaultVal | @@ -407,128 +407,6 @@ static T findAndRemove(QVariantMap &map, const QString &key, const T &defaultVal | ||
| 407 | return result; | 407 | return result; |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | -br_utemplate Template::toUniversalTemplate(const Template &t) | ||
| 411 | -{ | ||
| 412 | - QVariantMap map = t.file.localMetadata(); | ||
| 413 | - | ||
| 414 | - // QJsonObject::fromVariantMap (below) fails to convert | ||
| 415 | - // QRects and QPoints to string, replacing them with null values. | ||
| 416 | - // so hand-convert these weirdos | ||
| 417 | - foreach (const QString &k, map.keys()) { | ||
| 418 | - QVariant v = map[k]; | ||
| 419 | - if (v.canConvert(QVariant::PointF) || v.canConvert(QVariant::RectF)) { | ||
| 420 | - QString newv = QtUtils::toString(v); | ||
| 421 | - map[k] = newv; | ||
| 422 | - } | ||
| 423 | - // lists of points and rects, too | ||
| 424 | - else if (v.type() == QVariant::List) { | ||
| 425 | - QVariantList oldlist = qvariant_cast<QVariantList>(v); | ||
| 426 | - if (!oldlist.isEmpty() && (oldlist.first().canConvert(QVariant::PointF) || oldlist.first().canConvert(QVariant::RectF))) { | ||
| 427 | - QVariantList newlist; | ||
| 428 | - foreach (const QVariant &subv, oldlist) { | ||
| 429 | - newlist.append(QtUtils::toString(subv)); | ||
| 430 | - } | ||
| 431 | - map[k] = newlist; | ||
| 432 | - } | ||
| 433 | - } | ||
| 434 | - } | ||
| 435 | - | ||
| 436 | - const int32_t algorithmID = findAndRemove<int32_t> (map, "AlgorithmID", 0); | ||
| 437 | - const uint32_t frame = findAndRemove<uint32_t>(map, "Frame" , std::numeric_limits<uint32_t>::max()); | ||
| 438 | - const int32_t x = findAndRemove<int32_t> (map, "X" , 0); | ||
| 439 | - const int32_t y = findAndRemove<int32_t> (map, "Y" , 0); | ||
| 440 | - const uint32_t width = findAndRemove<uint32_t>(map, "Width" , 0); | ||
| 441 | - const uint32_t height = findAndRemove<uint32_t>(map, "Height" , 0); | ||
| 442 | - const float confidence = findAndRemove<float> (map, "Confidence" , 0); | ||
| 443 | - const uint32_t personID = findAndRemove<uint32_t>(map, "PersonID" , std::numeric_limits<uint32_t>::max()); | ||
| 444 | - const QByteArray metadata = QJsonDocument(QJsonObject::fromVariantMap(map)).toJson(); | ||
| 445 | - const Mat &m = t; | ||
| 446 | - return br_new_utemplate(algorithmID, frame, x, y, width, height, confidence, personID, metadata.constData(), (const char*) m.data, m.rows * m.cols * m.elemSize()); | ||
| 447 | -} | ||
| 448 | - | ||
| 449 | -Template Template::fromUniversalTemplate(br_const_utemplate ut) | ||
| 450 | -{ | ||
| 451 | - QVariantMap map = QJsonDocument::fromJson(QByteArray((const char*) ut->data)).object().toVariantMap(); | ||
| 452 | - | ||
| 453 | - // QJsonDocument::fromJson doesn't know about QRects and QPoints | ||
| 454 | - // so convert any QStrings that can be converted | ||
| 455 | - foreach (const QString &k, map.keys()) { | ||
| 456 | - QVariant v = map[k]; | ||
| 457 | - QVariant newv; | ||
| 458 | - bool istype; | ||
| 459 | - if (v.type() == QVariant::String) { | ||
| 460 | - QString vstr = qvariant_cast<QString>(v); | ||
| 461 | - newv = QtUtils::toRect(vstr, &istype); | ||
| 462 | - if (!istype) { | ||
| 463 | - newv = QtUtils::toPoint(vstr, &istype); | ||
| 464 | - if (!istype) { | ||
| 465 | - newv = v; | ||
| 466 | - } | ||
| 467 | - } | ||
| 468 | - map[k] = newv; | ||
| 469 | - } | ||
| 470 | - // convert lists of rects and points, too | ||
| 471 | - else if (v.type() == QVariant::List) { | ||
| 472 | - QVariantList oldlist = qvariant_cast<QVariantList>(v); | ||
| 473 | - if (!oldlist.isEmpty() && oldlist.first().type() == QVariant::String) { | ||
| 474 | - QString test = qvariant_cast<QString>(oldlist.first()); | ||
| 475 | - QtUtils::toRect(test, &istype); | ||
| 476 | - QVariantList newlist; | ||
| 477 | - if (istype) { | ||
| 478 | - foreach (const QVariant &subv, oldlist) { | ||
| 479 | - newlist.append(QtUtils::toRect(qvariant_cast<QString>(subv))); | ||
| 480 | - } | ||
| 481 | - } else { | ||
| 482 | - QtUtils::toPoint(test, &istype); | ||
| 483 | - if (istype) { | ||
| 484 | - foreach (const QVariant &subv, oldlist) { | ||
| 485 | - newlist.append(QtUtils::toPoint(qvariant_cast<QString>(subv))); | ||
| 486 | - } | ||
| 487 | - } else { | ||
| 488 | - newlist = oldlist; | ||
| 489 | - } | ||
| 490 | - } | ||
| 491 | - map[k] = newlist; | ||
| 492 | - } | ||
| 493 | - } | ||
| 494 | - } | ||
| 495 | - | ||
| 496 | - map.insert("AlgorithmID", ut->algorithmID); | ||
| 497 | - map.insert("Frame" , ut->frame ); | ||
| 498 | - map.insert("X" , ut->x ); | ||
| 499 | - map.insert("Y" , ut->y ); | ||
| 500 | - map.insert("Width" , ut->width ); | ||
| 501 | - map.insert("Height" , ut->height ); | ||
| 502 | - map.insert("Confidence" , ut->confidence ); | ||
| 503 | - map.insert("PersonID" , ut->personID ); | ||
| 504 | - const Mat m = Mat(1, ut->fvSize, CV_8UC1, (void*)(ut->data + ut->mdSize)).clone(); | ||
| 505 | - return Template(File(map), m); | ||
| 506 | -} | ||
| 507 | - | ||
| 508 | -br_utemplate Template::readUniversalTemplate(QFile &file) | ||
| 509 | -{ | ||
| 510 | - const size_t headerSize = sizeof(br_universal_template); | ||
| 511 | - br_universal_template *t = (br_universal_template*) malloc(headerSize); | ||
| 512 | - file.read((char*) t, headerSize); | ||
| 513 | - | ||
| 514 | - const size_t dataSize = t->mdSize + t->fvSize; | ||
| 515 | - t = (br_universal_template*) realloc(t, headerSize + dataSize); | ||
| 516 | - file.read((char*) &t->data, dataSize); | ||
| 517 | - return t; | ||
| 518 | -} | ||
| 519 | - | ||
| 520 | -void Template::writeUniversalTemplate(QFile &file, br_const_utemplate t) | ||
| 521 | -{ | ||
| 522 | - const qint64 size = sizeof(br_universal_template) + t->mdSize + t->fvSize; | ||
| 523 | - if (file.write((const char *) t, size) != size) | ||
| 524 | - qFatal("Failed to write universal template!"); | ||
| 525 | -} | ||
| 526 | - | ||
| 527 | -void Template::freeUniversalTemplate(br_const_utemplate t) | ||
| 528 | -{ | ||
| 529 | - free((void*) t); | ||
| 530 | -} | ||
| 531 | - | ||
| 532 | QDataStream &br::operator<<(QDataStream &stream, const Template &t) | 410 | QDataStream &br::operator<<(QDataStream &stream, const Template &t) |
| 533 | { | 411 | { |
| 534 | return stream << static_cast<const QList<cv::Mat>&>(t) << t.file; | 412 | return stream << static_cast<const QList<cv::Mat>&>(t) << t.file; |
openbr/openbr_plugin.h
| @@ -41,7 +41,6 @@ | @@ -41,7 +41,6 @@ | ||
| 41 | #include <QVector> | 41 | #include <QVector> |
| 42 | #include <opencv2/core.hpp> | 42 | #include <opencv2/core.hpp> |
| 43 | #include <openbr/openbr.h> | 43 | #include <openbr/openbr.h> |
| 44 | -#include <openbr/universal_template.h> | ||
| 45 | #include <assert.h> | 44 | #include <assert.h> |
| 46 | 45 | ||
| 47 | namespace br | 46 | namespace br |
| @@ -296,12 +295,6 @@ struct Template : public QList<cv::Mat> | @@ -296,12 +295,6 @@ struct Template : public QList<cv::Mat> | ||
| 296 | foreach (const cv::Mat &m, *this) other += m.clone(); | 295 | foreach (const cv::Mat &m, *this) other += m.clone(); |
| 297 | return other; | 296 | return other; |
| 298 | } | 297 | } |
| 299 | - | ||
| 300 | - static br_utemplate toUniversalTemplate(const Template &t); | ||
| 301 | - static Template fromUniversalTemplate(br_const_utemplate ut); | ||
| 302 | - static br_utemplate readUniversalTemplate(QFile &file); | ||
| 303 | - static void writeUniversalTemplate(QFile &file, br_const_utemplate t); | ||
| 304 | - static void freeUniversalTemplate(br_const_utemplate t); | ||
| 305 | }; | 298 | }; |
| 306 | 299 | ||
| 307 | BR_EXPORT QDataStream &operator<<(QDataStream &stream, const Template &t); | 300 | BR_EXPORT QDataStream &operator<<(QDataStream &stream, const Template &t); |
openbr/plugins/gallery/binary.cpp
| @@ -201,33 +201,6 @@ BR_REGISTER(Gallery, galGallery) | @@ -201,33 +201,6 @@ BR_REGISTER(Gallery, galGallery) | ||
| 201 | 201 | ||
| 202 | /*! | 202 | /*! |
| 203 | * \ingroup galleries | 203 | * \ingroup galleries |
| 204 | - * \brief A contiguous array of br_universal_template. | ||
| 205 | - * \author Josh Klontz \cite jklontz | ||
| 206 | - */ | ||
| 207 | -class utGallery : public BinaryGallery | ||
| 208 | -{ | ||
| 209 | - Q_OBJECT | ||
| 210 | - | ||
| 211 | - Template readTemplate() | ||
| 212 | - { | ||
| 213 | - const br_const_utemplate ut = Template::readUniversalTemplate(gallery); | ||
| 214 | - const Template t = Template::fromUniversalTemplate(ut); | ||
| 215 | - Template::freeUniversalTemplate(ut); | ||
| 216 | - return t; | ||
| 217 | - } | ||
| 218 | - | ||
| 219 | - void writeTemplate(const Template &t) | ||
| 220 | - { | ||
| 221 | - const br_utemplate ut = Template::toUniversalTemplate(t); | ||
| 222 | - gallery.write((const char*) ut, sizeof(br_universal_template) + ut->mdSize + ut->fvSize); | ||
| 223 | - Template::freeUniversalTemplate(ut); | ||
| 224 | - } | ||
| 225 | -}; | ||
| 226 | - | ||
| 227 | -BR_REGISTER(Gallery, utGallery) | ||
| 228 | - | ||
| 229 | -/*! | ||
| 230 | - * \ingroup galleries | ||
| 231 | * \brief Newline-separated URLs. | 204 | * \brief Newline-separated URLs. |
| 232 | * \author Josh Klontz \cite jklontz | 205 | * \author Josh Klontz \cite jklontz |
| 233 | */ | 206 | */ |
openbr/universal_template.cpp deleted
| 1 | -#include <QFile> | ||
| 2 | -#include <QFutureSynchronizer> | ||
| 3 | -#include <QMutex> | ||
| 4 | -#include <QMutexLocker> | ||
| 5 | -#include <QtConcurrent> | ||
| 6 | -#include <cstdlib> | ||
| 7 | -#include <cstring> | ||
| 8 | - | ||
| 9 | -#include "universal_template.h" | ||
| 10 | - | ||
| 11 | -br_utemplate br_new_utemplate(int32_t algorithmID, uint32_t frame, int32_t x, int32_t y, uint32_t width, uint32_t height, float confidence, uint32_t personID, const char *metadata, const char *featureVector, uint32_t fvSize) | ||
| 12 | -{ | ||
| 13 | - const uint32_t mdSize = strlen(metadata) + 1; | ||
| 14 | - br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + mdSize + fvSize); | ||
| 15 | - utemplate->algorithmID = algorithmID; | ||
| 16 | - utemplate->frame = frame; | ||
| 17 | - utemplate->x = x; | ||
| 18 | - utemplate->y = y; | ||
| 19 | - utemplate->width = width; | ||
| 20 | - utemplate->height = height; | ||
| 21 | - utemplate->confidence = confidence; | ||
| 22 | - utemplate->personID = personID; | ||
| 23 | - utemplate->mdSize = mdSize; | ||
| 24 | - utemplate->fvSize = fvSize; | ||
| 25 | - memcpy(reinterpret_cast<char*>(utemplate+1) + 0, metadata , mdSize); | ||
| 26 | - memcpy(reinterpret_cast<char*>(utemplate+1) + mdSize, featureVector, fvSize); | ||
| 27 | - return utemplate; | ||
| 28 | -} | ||
| 29 | - | ||
| 30 | -void br_free_utemplate(br_const_utemplate utemplate) | ||
| 31 | -{ | ||
| 32 | - free((void*) utemplate); | ||
| 33 | -} | ||
| 34 | - | ||
| 35 | -void br_append_utemplate(FILE *file, br_const_utemplate utemplate) | ||
| 36 | -{ | ||
| 37 | - fwrite(utemplate, sizeof(br_universal_template) + utemplate->mdSize + utemplate->fvSize, 1, file); | ||
| 38 | -} | ||
| 39 | - | ||
| 40 | -void br_iterate_utemplates(br_const_utemplate begin, br_const_utemplate end, br_utemplate_callback callback, br_callback_context context) | ||
| 41 | -{ | ||
| 42 | - while (begin != end) { | ||
| 43 | - callback(begin, context); | ||
| 44 | - begin = reinterpret_cast<br_const_utemplate>(reinterpret_cast<const char*>(begin) + sizeof(br_universal_template) + begin->mdSize + begin->fvSize); | ||
| 45 | - if (begin > end) | ||
| 46 | - qFatal("Overshot end of buffer"); | ||
| 47 | - } | ||
| 48 | -} | ||
| 49 | - | ||
| 50 | -static void callAndFree(br_utemplate_callback callback, br_utemplate t, br_callback_context context) | ||
| 51 | -{ | ||
| 52 | - callback(t, context); | ||
| 53 | - free(t); | ||
| 54 | -} | ||
| 55 | - | ||
| 56 | -static bool read_buffer(FILE *file, char *buffer, size_t bytes) | ||
| 57 | -{ | ||
| 58 | - size_t bytesRemaining = bytes; | ||
| 59 | - while (bytesRemaining) { | ||
| 60 | - const size_t bytesRead = fread(buffer, 1, bytesRemaining, file); | ||
| 61 | - buffer += bytesRead; | ||
| 62 | - bytesRemaining -= bytesRead; | ||
| 63 | - | ||
| 64 | - if (feof(file)) { | ||
| 65 | - if ((bytesRemaining != bytes) && !fseek(file, bytesRemaining - bytes, SEEK_CUR)) // Try to rewind | ||
| 66 | - bytesRemaining = bytes; | ||
| 67 | - if (bytesRemaining == bytes) | ||
| 68 | - return false; | ||
| 69 | - qFatal("End of file after reading %d of %d bytes.", int(bytes - bytesRemaining), int(bytes)); | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - if (ferror(file)) { | ||
| 73 | - perror(NULL); | ||
| 74 | - qFatal("Error after reading %d of %d bytes.", int(bytes - bytesRemaining), int(bytes)); | ||
| 75 | - } | ||
| 76 | - } | ||
| 77 | - return true; | ||
| 78 | -} | ||
| 79 | - | ||
| 80 | -int br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_callback_context context, bool parallel) | ||
| 81 | -{ | ||
| 82 | - int count = 0; | ||
| 83 | - QFutureSynchronizer<void> futures; | ||
| 84 | - while (true) { | ||
| 85 | - br_utemplate t = (br_utemplate) malloc(sizeof(br_universal_template)); | ||
| 86 | - | ||
| 87 | - if (!read_buffer(file, (char*) t, sizeof(br_universal_template))) { | ||
| 88 | - free(t); | ||
| 89 | - break; | ||
| 90 | - } | ||
| 91 | - | ||
| 92 | - t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->mdSize + t->fvSize); | ||
| 93 | - if (!read_buffer(file, (char*) &t->data, t->mdSize + t->fvSize)) { | ||
| 94 | - free(t); | ||
| 95 | - | ||
| 96 | - // Try to rewind header read | ||
| 97 | - if (fseek(file, -long(sizeof(br_universal_template)), SEEK_CUR)) | ||
| 98 | - qFatal("Unable to recover from partial template read!"); | ||
| 99 | - | ||
| 100 | - break; | ||
| 101 | - } | ||
| 102 | - | ||
| 103 | - if (parallel) futures.addFuture(QtConcurrent::run(callAndFree, callback, t, context)); | ||
| 104 | - else callAndFree(callback, t, context); | ||
| 105 | - count++; | ||
| 106 | - } | ||
| 107 | - return count; | ||
| 108 | -} | ||
| 109 | - | ||
| 110 | -void br_log(const char *message) | ||
| 111 | -{ | ||
| 112 | - qDebug() << qPrintable(QTime::currentTime().toString("hh:mm:ss.zzz")) << "-" << message; | ||
| 113 | -} |
openbr/universal_template.h deleted
| 1 | -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
| 2 | - * Copyright 2014 Noblis * | ||
| 3 | - * * | ||
| 4 | - * Licensed under the Apache License, Version 2.0 (the "License"); * | ||
| 5 | - * you may not use this file except in compliance with the License. * | ||
| 6 | - * You may obtain a copy of the License at * | ||
| 7 | - * * | ||
| 8 | - * http://www.apache.org/licenses/LICENSE-2.0 * | ||
| 9 | - * * | ||
| 10 | - * Unless required by applicable law or agreed to in writing, software * | ||
| 11 | - * distributed under the License is distributed on an "AS IS" BASIS, * | ||
| 12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * | ||
| 13 | - * See the License for the specific language governing permissions and * | ||
| 14 | - * limitations under the License. * | ||
| 15 | - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
| 16 | - | ||
| 17 | -#ifndef BR_UNIVERSAL_TEMPLATE_H | ||
| 18 | -#define BR_UNIVERSAL_TEMPLATE_H | ||
| 19 | - | ||
| 20 | -#include <stdio.h> | ||
| 21 | -#include <stdint.h> | ||
| 22 | -#include <openbr/openbr_export.h> | ||
| 23 | - | ||
| 24 | -#ifdef __cplusplus | ||
| 25 | -extern "C" { | ||
| 26 | -#endif | ||
| 27 | - | ||
| 28 | -// Disable 'nonstandard extension used : zero-sized array in struct/union' warning | ||
| 29 | -#ifdef _MSC_VER | ||
| 30 | -# pragma warning(disable: 4200) | ||
| 31 | -#endif // _MSC_VER | ||
| 32 | - | ||
| 33 | -/*! | ||
| 34 | - * \brief A flat template format for representing arbitrary feature vectors. | ||
| 35 | - */ | ||
| 36 | -struct br_universal_template | ||
| 37 | -{ | ||
| 38 | - int32_t algorithmID; /*!< Interpretation of _data_ after _mdSize_. */ | ||
| 39 | - uint32_t frame; /*!< Video frame number, or <tt>numeric_limits<uint32_t>::max()</tt> for still images. */ | ||
| 40 | - int32_t x; /*!< Region of interest horizontal offset (pixels). */ | ||
| 41 | - int32_t y; /*!< Region of interest vertical offset (pixels). */ | ||
| 42 | - uint32_t width; /*!< Region of interest horizontal size (pixels). */ | ||
| 43 | - uint32_t height; /*!< Region of interest vertical size (pixels). */ | ||
| 44 | - float confidence; /*!< Region of interest confidence. */ | ||
| 45 | - uint32_t personID; /*!< Unique identifier or <tt>numeric_limits<uint32_t>::max()</tt> if unknown. */ | ||
| 46 | - uint32_t mdSize; /*!< Length of a null-terminated metadata string at the beginning of _data_, | ||
| 47 | - including the null-terminator character itself. */ | ||
| 48 | - uint32_t fvSize; /*!< Length of the feature vector after the metadata in _data_. */ | ||
| 49 | - unsigned char data[]; /*!< (_mdSize_ + _fvSize_)-byte buffer. | ||
| 50 | - The first _mdSize_ bytes represent the metadata. | ||
| 51 | - The remaining _fvSize_ bytes represent the feature vector. */ | ||
| 52 | -}; | ||
| 53 | - | ||
| 54 | -typedef struct br_universal_template *br_utemplate; | ||
| 55 | -typedef const struct br_universal_template *br_const_utemplate; | ||
| 56 | - | ||
| 57 | -/*! | ||
| 58 | - * \brief br_universal_template constructor. | ||
| 59 | - * \see br_free_utemplate | ||
| 60 | - */ | ||
| 61 | -BR_EXPORT br_utemplate br_new_utemplate(int32_t algorithmID, uint32_t frame, int32_t x, int32_t y, uint32_t width, uint32_t height, float confidence, uint32_t personID, const char *metadata, const char *featureVector, uint32_t fvSize); | ||
| 62 | - | ||
| 63 | -/*! | ||
| 64 | - * \brief br_universal_template destructor. | ||
| 65 | - * \see br_new_utemplate | ||
| 66 | - */ | ||
| 67 | -BR_EXPORT void br_free_utemplate(br_const_utemplate utemplate); | ||
| 68 | - | ||
| 69 | -/*! | ||
| 70 | - * \brief Serialize a br_universal_template to a file. | ||
| 71 | - * \see br_append_utemplate_contents | ||
| 72 | - */ | ||
| 73 | -BR_EXPORT void br_append_utemplate(FILE *file, br_const_utemplate utemplate); | ||
| 74 | - | ||
| 75 | -/*! | ||
| 76 | - * \brief br_universal_template iterator callback. | ||
| 77 | - * \see br_iterate_utemplates | ||
| 78 | - */ | ||
| 79 | -typedef void *br_callback_context; | ||
| 80 | -typedef void (*br_utemplate_callback)(br_const_utemplate, br_callback_context); | ||
| 81 | - | ||
| 82 | -/*! | ||
| 83 | - * \brief Iterate over an inplace array of br_universal_template. | ||
| 84 | - * \see br_iterate_utemplates_file | ||
| 85 | - */ | ||
| 86 | -BR_EXPORT void br_iterate_utemplates(br_const_utemplate begin, br_const_utemplate end, br_utemplate_callback callback, br_callback_context context); | ||
| 87 | - | ||
| 88 | -/*! | ||
| 89 | - * \brief Iterate over br_universal_template in a file. | ||
| 90 | - * \return The number of templates iterated | ||
| 91 | - * \see br_iterate_utemplates | ||
| 92 | - */ | ||
| 93 | -BR_EXPORT int br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_callback_context context, bool parallel); | ||
| 94 | - | ||
| 95 | -/*! | ||
| 96 | - * \brief Write a message annotated with the current time to stderr. | ||
| 97 | - */ | ||
| 98 | -BR_EXPORT void br_log(const char *message); | ||
| 99 | - | ||
| 100 | -#ifdef __cplusplus | ||
| 101 | -} | ||
| 102 | -#endif | ||
| 103 | - | ||
| 104 | -#endif // BR_UNIVERSAL_TEMPLATE_H |