-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimage.h
88 lines (61 loc) · 2.17 KB
/
image.h
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
#ifndef IMAGE_H
#define IMAGE_H
#define STB_IMAGE_IMPLEMENTATION
#define STBI_FAILURE_USERMSG
#include "external/stb_image.h"
#include <string>
#include <iostream>
class Image {
public:
Image(std::string const & filename);
~Image();
double * const color_at(int x, int y) const;
int width = 0;
int height = 0;
private:
// the color values for the image, a [0-1] for each component of a pixel,
// so overall there will be width * height * components per pixel parts to this array
double * colorData = nullptr;
// total number of color components (i.e r, g, b) per row of image, used for color value lookups
int componentsPerRow = 0;
// for when the image couldn't be loaded
static double FALLBACK_COLOR[];
static int const COMPONENTS_PER_PIXEL = 3;
};
// ------
double Image::FALLBACK_COLOR[] = {255, 0, 0};
Image::Image(std::string const & filename) {
int imageBytesPerPixel = 0;
float* floatData = stbi_loadf(filename.c_str(), &width, &height, &imageBytesPerPixel, COMPONENTS_PER_PIXEL);
if (floatData == nullptr) {
std::cerr << "Error loading image " << filename << ", reason: " << stbi_failure_reason() << std::endl;
return;
}
std::clog << "Loaded image " << filename <<
". Width: " << width << ", height: " << height << ", bytes per pixel: " << imageBytesPerPixel
<< "\n";
int totalBytes = height * width * COMPONENTS_PER_PIXEL;
colorData = new double[totalBytes];
for (int i = 0; i < totalBytes; i++) {
colorData[i] = static_cast<double>(floatData[i]);
}
componentsPerRow = COMPONENTS_PER_PIXEL * width;
STBI_FREE(floatData);
}
Image::~Image() {
delete[] colorData;
}
static int clamp_within(int x, int lowInclusive, int highExclusive) {
if (x < lowInclusive) return lowInclusive;
if (x < highExclusive) return x;
return highExclusive - 1;
}
double * const Image::color_at(int x, int y) const {
if (this->colorData == nullptr) {
return FALLBACK_COLOR;
}
x = clamp_within(x, 0, width);
y = clamp_within(y, 0, height);
return colorData + (x * COMPONENTS_PER_PIXEL) + (y * componentsPerRow);
}
#endif