summaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp89
1 files changed, 44 insertions, 45 deletions
diff --git a/main.cpp b/main.cpp
index e801015..2eac799 100644
--- a/main.cpp
+++ b/main.cpp
@@ -12,22 +12,15 @@
using namespace std;
-//defaults
-
-//TODO remove temp_settings
+//Argument defaults. Really not used to using constants over preprocessor defines; this feels cursed
const uint32_t DEFAULT_WIDTH = 1920;
const uint32_t DEFAULT_HEIGHT = 1080;
const int DEFAULT_JOBS = 1;
const string DEFAULT_IMG_PATH = "out.png";
-//CONTENDOR_HI REPLACEMENT - 50000 iterations
const complex<double> DEFAULT_MIN_CORD (-0.74364386269 - 0.00000003000, 0.13182590271 - 0.00000003000);
const complex<double> DEFAULT_MAX_CORD (-0.74364386269 + 0.00000003000, 0.13182590271 + 0.00000003000);
-//CONTENDOR_ZOOM- 50000 iterations
-//const complex<double> DEFAULT_MIN_CORD (-0.74364386269 - 0.00000001000, 0.13182590271 - 0.00000001000);
-//const complex<double> DEFAULT_MAX_CORD (-0.74364386269 + 0.00000001000, 0.13182590271 + 0.00000001000);
-
const unsigned int DEFAULT_ITERS = 50000;
const unsigned int DEFAULT_BAILOUT = 256;
@@ -66,10 +59,45 @@ bool getopt_int(t& number, char *optarg, char opt, char *arg) {
return false;
}
+/** colors using linear histrogram method with generic hue shift **/
+//TODO figure out how to pass constant arrays without allowing pointed material to be modified
+void calc_colors(const double *value_map, unsigned int *histogram, png &image, unsigned int max_iters) {
+ double below, above, hue;
+ int c;
+ uint32_t x, y;
+ int rgb[3];
+ unsigned int histogram_sum = 0;
+ double current_hue = 0;
+ double *freq_hue = new double[max_iters]();
+
+ //find the sum of all histogram values, we could ajust this to increase or decrease contrast
+ for(unsigned int p = 0; p < max_iters; p++) histogram_sum += histogram[p];
+
+ for(unsigned int i = 0; i < max_iters; i++) {
+ current_hue += histogram[i] / (double)histogram_sum;
+ freq_hue[i] = current_hue;
+ }
+
+ for(y = 0; y < image.height(); y++) {
+ for(x = 0; x < image.width(); x++) {
+ below = freq_hue[(int)value_map[(y * image.width()) + x]];
+ above = freq_hue[(int)ceil(value_map[((y * image.width()) + x) + 1])];
+ hue = (((above - below) * fmod(value_map[(y * image.width()) + x], 1.0)) + below);
+ rgb[0] = 255 * cos((M_PI * hue) - M_PI);
+ rgb[1] = 255 * cos((M_PI * hue) - ((M_PI) / 2.0));
+ rgb[2] = 255 * cos(M_PI * hue);
+ for(c = 0; c < 3; c++) if(rgb[c] < 0) rgb[c] = 0;
+ image.set_pixel(x, y, (png_byte)rgb[0], (png_byte)rgb[1], (png_byte)rgb[2]);
+ }
+ }
+}
+
int main(int argc, char **argv) {
+
+
//argument options
uint32_t width = DEFAULT_WIDTH;
uint32_t height = DEFAULT_HEIGHT;
@@ -80,10 +108,9 @@ int main(int argc, char **argv) {
unsigned int m_iters = DEFAULT_ITERS;
unsigned int bailout = DEFAULT_BAILOUT;
bool jobs_set = false;
+ int arg; //for getopt
- //I could not find a better way to turn a string into a complex variable
stringstream complex_str_buffer;
- int arg;
while((arg = getopt(argc, argv, "hw:H:o:j:c:C:i:I:")) != -1) {
switch(arg) {
case 'h':
@@ -129,15 +156,11 @@ int main(int argc, char **argv) {
"See " << argv[0] << " -h for help.\n" << endl;
}
- double *vmap = new double[width * height];
+ //dependent on getopt settings
+ double *bail_map = new double[width * height];
unsigned int *histogram = new unsigned int[m_iters]();
- unsigned int histogram_sum = 0;
- double *freq_hue = new double[m_iters]();
- double current_hue = 0;
-
unsigned int width_per_job = width / jobs;
atomic<uint32_t> progress(0);
-
png image(img_path, width, height);
thread threads[jobs];
@@ -149,14 +172,14 @@ int main(int argc, char **argv) {
for(unsigned int j = 0; j < jobs - 1; j++) {
worker_objects[j] = new mthread(j * width_per_job, (j + 1) * width_per_job,
min_cord, max_cord, bailout, m_iters,
- image, vmap, histogram, worker_objects, j, jobs, progress);
+ image, bail_map, histogram, worker_objects, j, jobs, progress);
}
//last worker thread needs the width to go all the way to the edge of the screen,
//regardless of rounding issues
worker_objects[jobs - 1] = new mthread((jobs - 1) * width_per_job, width - 1,
min_cord, max_cord, bailout, m_iters,
- image, vmap, histogram, worker_objects, jobs - 1, jobs, progress);
+ image, bail_map, histogram, worker_objects, jobs - 1, jobs, progress);
for(unsigned int j = 0; j < jobs; j++) worker_objects[j]->dispatch();
@@ -173,36 +196,12 @@ int main(int argc, char **argv) {
//now to color the image
cout << "Coloring image... (this shouldn't take more then a few seconds)" << endl;
- //find the sum of all histogram values, we could ajust this to increase or decrease contrast
- for(unsigned int p = 0; p < m_iters; p++) histogram_sum += histogram[p];
-
- for(unsigned int i = 0; i < m_iters; i++) {
- current_hue += histogram[i] / (double)histogram_sum;
- freq_hue[i] = current_hue;
- }
-
- //now to calculate the colors
- {
- double below, above, hue;
- int c;
- uint32_t x, y;
- int rgb[3];
- for(y = 0; y < height; y++) {
- for(x = 0; x < width; x++) {
- below = freq_hue[(int)vmap[(y * width) + x]];
- above = freq_hue[(int)ceil(vmap[((y * width) + x) + 1])];
- hue = (((above - below) * fmod(vmap[(y * width) + x], 1.0)) + below);
- rgb[0] = 255 * cos((M_PI * hue) - M_PI);
- rgb[1] = 255 * cos((M_PI * hue) - ((M_PI) / 2.0));
- rgb[2] = 255 * cos(M_PI * hue);
- for(c = 0; c < 3; c++) if(rgb[c] < 0) rgb[c] = 0;
- image.set_pixel(x, y, (png_byte)rgb[0], (png_byte)rgb[1], (png_byte)rgb[2]);
- }
- }
- }
+ //actually writes image as well
+ calc_colors(bail_map, histogram, image, m_iters);
for(unsigned int j = 0; j < jobs; j++) delete worker_objects[j];
+ //image will be deleted (and written) upon funciton exit
cout << "Image exported to " << img_path << "." << endl;
}