universal_template.cpp
3.79 KB
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
112
113
#include <QFile>
#include <QFutureSynchronizer>
#include <QMutex>
#include <QMutexLocker>
#include <QtConcurrent>
#include <cstdlib>
#include <cstring>
#include "universal_template.h"
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)
{
const uint32_t mdSize = strlen(metadata) + 1;
br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + mdSize + fvSize);
utemplate->algorithmID = algorithmID;
utemplate->frame = frame;
utemplate->x = x;
utemplate->y = y;
utemplate->width = width;
utemplate->height = height;
utemplate->confidence = confidence;
utemplate->personID = personID;
utemplate->mdSize = mdSize;
utemplate->fvSize = fvSize;
memcpy(reinterpret_cast<char*>(utemplate+1) + 0, metadata , mdSize);
memcpy(reinterpret_cast<char*>(utemplate+1) + mdSize, featureVector, fvSize);
return utemplate;
}
void br_free_utemplate(br_const_utemplate utemplate)
{
free((void*) utemplate);
}
void br_append_utemplate(FILE *file, br_const_utemplate utemplate)
{
fwrite(utemplate, sizeof(br_universal_template) + utemplate->mdSize + utemplate->fvSize, 1, file);
}
void br_iterate_utemplates(br_const_utemplate begin, br_const_utemplate end, br_utemplate_callback callback, br_callback_context context)
{
while (begin != end) {
callback(begin, context);
begin = reinterpret_cast<br_const_utemplate>(reinterpret_cast<const char*>(begin) + sizeof(br_universal_template) + begin->mdSize + begin->fvSize);
if (begin > end)
qFatal("Overshot end of buffer");
}
}
static void callAndFree(br_utemplate_callback callback, br_utemplate t, br_callback_context context)
{
callback(t, context);
free(t);
}
static bool read_buffer(FILE *file, char *buffer, size_t bytes)
{
size_t bytesRemaining = bytes;
while (bytesRemaining) {
const size_t bytesRead = fread(buffer, 1, bytesRemaining, file);
buffer += bytesRead;
bytesRemaining -= bytesRead;
if (feof(file)) {
if ((bytesRemaining != bytes) && !fseek(file, bytesRemaining - bytes, SEEK_CUR)) // Try to rewind
bytesRemaining = bytes;
if (bytesRemaining == bytes)
return false;
qFatal("End of file after reading %d of %d bytes.", int(bytes - bytesRemaining), int(bytes));
}
if (ferror(file)) {
perror(NULL);
qFatal("Error after reading %d of %d bytes.", int(bytes - bytesRemaining), int(bytes));
}
}
return true;
}
int br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_callback_context context, bool parallel)
{
int count = 0;
QFutureSynchronizer<void> futures;
while (true) {
br_utemplate t = (br_utemplate) malloc(sizeof(br_universal_template));
if (!read_buffer(file, (char*) t, sizeof(br_universal_template))) {
free(t);
break;
}
t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->mdSize + t->fvSize);
if (!read_buffer(file, (char*) &t->data, t->mdSize + t->fvSize)) {
free(t);
// Try to rewind header read
if (fseek(file, -long(sizeof(br_universal_template)), SEEK_CUR))
qFatal("Unable to recover from partial template read!");
break;
}
if (parallel) futures.addFuture(QtConcurrent::run(callAndFree, callback, t, context));
else callAndFree(callback, t, context);
count++;
}
return count;
}
void br_log(const char *message)
{
qDebug() << qPrintable(QTime::currentTime().toString("hh:mm:ss.zzz")) << "-" << message;
}