-
Notifications
You must be signed in to change notification settings - Fork 1
/
Film.h
103 lines (78 loc) · 2.79 KB
/
Film.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#ifndef FILM_H
#define FILM_H
#include "lodepng.h"
#include <vector>
#include <iostream>
#include "Color.h"
using namespace std;
//CODE FOR WRITING TO AN IMAGE FILE (LODEPNG LIBRARY),
//CITATION: code relating to the writeimage and commit methods is ADAPTED/BORROWED/COPIED FROM THE EXAMPLE FILE ON THE LODEPNG WEBSITE.
//I DO NOT ASSUME 100% CREDIT FOR THAT CODE. ALL DUE CREDIT IS GIVEN TO THE MAKERS OF THE LIBRARY.
//"g++ lodepng.cpp example_encode.cpp -ansi -pedantic -Wall -Wextra -O3"
//From lodepng example: "Encode from raw pixels to disk with a single function call"
//"The image argument has width * height RGBA pixels or width * height * 4 bytes"
//CITATION: code for constructing, adding, multiplying, transforming etc. vectors is powered by the Eigen library. All due credits is given to the makers
//of this library
//ALL OTHER CODE WRITTEN BY SHIV SUNDRAM AND ANDREY ELENSKIY
class Bucket{
public:
int n;
Color c;
Bucket();
void add(Color);
};
Bucket::Bucket(){
Color initial(0.0, 0.0, 0.0);
c = initial;
n=0;
}
void Bucket::add(Color inC){
c = c + inC;
n++;
}
class Film {
private:
int width, height;
vector<Bucket> buckets;
vector<unsigned char> image;
public:
Film(int widthIn, int heightIn);
void writeImage(const char* name);
void commit(int x, int y, Color c);
void convert();
};
void Film::commit(int x, int y, Color c){
buckets[width * y + x].add(c);
}
Film::Film(int widthIn, int heightIn){
width = widthIn;
height = heightIn;
image.resize(4*width * height );
buckets.resize(width * height );
for (int y=0; y<height; y++){
for (int x=0; x<width; x++){
buckets.push_back(Bucket());
}
}
}
void Film::writeImage(const char* name) {
//NOTE: this sample will overwrite the file or rayprint.png without warning!
convert();
//Encode the image
unsigned error = lodepng::encode(name, image, width, height);
//if there's an error, display it
if (error) cout << "encoder error " << error << ": " << lodepng_error_text(error) << endl;
}
//saves image to filename given as argument. Warning, this overwrites the file without warning!. at the moment, only one sample per picture
void Film::convert() {
for (int y=0; y<height; y++){
for (int x=0; x<width; x++){
double count = buckets[width * y + x].n;
image[4 * width * y + 4 * x + 0] = fmin(buckets[width * y + x].c.getRed() / count, 255.0f); //RED
image[4 * width * y + 4 * x + 1] = fmin(buckets[width * y + x].c.getGreen() / count, 255.0f);
image[4 * width * y + 4 * x + 2] = fmin(buckets[width * y + x].c.getBlue() / count, 255.0f);
image[4 * width * y + 4 * x + 3] = 255.0; //ALPHA for controlling transaperncy: MAINTAIN AT 255
}
}
}
#endif