universal_template.cpp
3.34 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
#include <QFile>
#include <QFutureSynchronizer>
#include <QMutex>
#include <QMutexLocker>
#include <QtConcurrent>
#include <cstdlib>
#include <cstring>
#include "universal_template.h"
br_utemplate br_new_utemplate(const int8_t *imageID, const int8_t *templateID, int32_t algorithmID, uint32_t size, const int8_t *data)
{
br_utemplate utemplate = (br_utemplate) malloc(sizeof(br_universal_template) + size);
memcpy(utemplate->imageID, imageID, 16);
memcpy(utemplate->templateID, templateID, 16);
utemplate->algorithmID = algorithmID;
utemplate->size = size;
memcpy(utemplate+1, data, size);
return utemplate;
}
void br_free_utemplate(br_const_utemplate utemplate)
{
free((void*) utemplate);
}
void br_append_utemplate(FILE *file, br_const_utemplate utemplate)
{
br_append_utemplate_contents(file, utemplate->imageID, utemplate->templateID, utemplate->algorithmID, utemplate->size, utemplate->data);
}
void br_append_utemplate_contents(FILE *file, const unsigned char *imageID, const unsigned char *templateID, int32_t algorithmID, uint32_t size, const unsigned char *data)
{
static QMutex lock;
QMutexLocker locker(&lock);
fwrite(imageID, 16, 1, file);
fwrite(templateID, 16, 1, file);
fwrite(&algorithmID, 4, 1, file);
fwrite(&size, 4, 1, file);
fwrite(data, 1, size, 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->size);
}
}
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, bool eofAllowed)
{
size_t bytesRemaining = bytes;
while (bytesRemaining) {
const size_t bytesRead = fread(buffer, 1, bytesRemaining, file);
buffer += bytesRead;
bytesRemaining -= bytesRead;
if (feof(file)) {
if (eofAllowed && (bytesRemaining == bytes))
return false;
qFatal("Unexpected end of file after reading %d of %d bytes.", int(bytes - bytesRemaining), int(bytes));
}
if (ferror(file)) {
perror(NULL);
qFatal("Error while reading %d of %d bytes.", int(bytes - bytesRemaining), int(bytes));
}
}
return true;
}
void br_iterate_utemplates_file(FILE *file, br_utemplate_callback callback, br_callback_context context, bool parallel)
{
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), true)) {
free(t);
return;
}
t = (br_utemplate) realloc(t, sizeof(br_universal_template) + t->size);
read_buffer(file, (char*) &t->data, t->size, false);
if (parallel) futures.addFuture(QtConcurrent::run(callAndFree, callback, t, context));
else callAndFree(callback, t, context);
}
futures.waitForFinished();
}
void br_log(const char *message)
{
qDebug() << qPrintable(QTime::currentTime().toString("hh:mm:ss.zzz")) << "-" << message;
}