forked from kidanger/vpv
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImage.cpp
More file actions
109 lines (95 loc) · 2.62 KB
/
Image.cpp
File metadata and controls
109 lines (95 loc) · 2.62 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
#include <cmath>
#include <cfloat>
#include <string>
#include <cstdlib>
#include <unordered_map>
#include <mutex>
extern "C" {
#include "iio.h"
}
#include "Image.hpp"
#include "watcher.hpp"
#include "globals.hpp"
#include "Sequence.hpp"
std::unordered_map<std::string, Image*> Image::cache;
Image::Image(float* pixels, int w, int h, Format format)
: pixels(pixels), w(w), h(h), format(format), type(FLOAT), is_cached(false)
{
min = std::numeric_limits<float>::max();
max = std::numeric_limits<float>::min();
for (int i = 0; i < w*h*format; i++) {
float v = pixels[i];
if (std::isfinite(v)) {
min = fminf(min, v);
max = fmaxf(max, v);
}
}
}
Image::~Image()
{
free(pixels);
}
void Image::getPixelValueAt(int x, int y, float* values, int d) const
{
if (x < 0 || y < 0 || x >= w || y >= h)
return;
if (type == Image::UINT8) {
const uint8_t* data = (uint8_t*) pixels + (w * y + x)*format;
const uint8_t* end = (uint8_t*) pixels + (w * h)*format;
for (int i = 0; i < d; i++) {
if (data + i >= end) break;
values[i] = data[i];
}
} else if (type == Image::FLOAT) {
const float* data = (float*) pixels + (w * y + x)*format;
const float* end = (float*) pixels + (w * h)*format;
for (int i = 0; i < d; i++) {
if (data + i >= end) break;
values[i] = data[i];
}
}
}
Image* Image::load(const std::string& filename, bool force_load)
{
auto i = cache.find(filename);
if (i != cache.end()) {
return i->second;
}
if (!force_load) {
return 0;
}
int w, h, d;
float* pixels = iio_read_image_float_vec(filename.c_str(), &w, &h, &d);
if (!pixels) {
fprintf(stderr, "cannot load image '%s'\n", filename.c_str());
return 0;
}
Image* img = new Image(pixels, w, h, (Format) d);
if (useCache) {
cache[filename] = img;
img->is_cached = true;
}
printf("'%s' loaded\n", filename.c_str());
watcher_add_file(filename, [](const std::string& filename) {
if (cache.find(filename) != cache.end()) {
Image* img = cache[filename];
for (auto seq : gSequences) {
seq->forgetImage();
}
delete img;
cache.erase(filename);
}
printf("'%s' modified on disk, cache invalidated\n", filename.c_str());
});
return img;
}
void Image::flushCache()
{
for (auto v : cache) {
delete v.second;
}
cache.clear();
for (auto seq : gSequences) {
seq->forgetImage();
}
}