From b03bcd11d7f1a1ac48d126f3ce09f30489aa051b Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Thu, 17 Nov 2011 16:40:54 +0100 Subject: [PATCH] made a bmp class for mac osx (very ugly). some small fixes --- Attractor.hpp | 1 + AttractorKernel.hpp | 2 +- AwesomeAttract0r.xcodeproj/project.pbxproj | 2 + Canvas.hpp | 2 +- batch.sh | 2 +- canvae/PNG.hpp | 5 +- canvae/bmp.hpp | 88 ++++++++++++++++++++++ canvae/libpng.hpp | 73 +++++++++++++++--- main.cpp | 77 ++++++++++--------- 9 files changed, 201 insertions(+), 51 deletions(-) create mode 100644 canvae/bmp.hpp diff --git a/Attractor.hpp b/Attractor.hpp index 9ba5a4a..73ef7ae 100644 --- a/Attractor.hpp +++ b/Attractor.hpp @@ -71,6 +71,7 @@ public: stfu::node system; system.addChild("AttractorKernel", kernel_node); system.addChild("Projector", projector_node); + system.addValue("Projector") = "Projector"; return system; } diff --git a/AttractorKernel.hpp b/AttractorKernel.hpp index fea06e8..97bce4f 100644 --- a/AttractorKernel.hpp +++ b/AttractorKernel.hpp @@ -63,7 +63,7 @@ public: { std::stringstream dimStream; dimStream << dimension; - output.value("dimension") = dimStream.str(); + output.value("dimensions") = dimStream.str(); stf_other(output); } diff --git a/AwesomeAttract0r.xcodeproj/project.pbxproj b/AwesomeAttract0r.xcodeproj/project.pbxproj index 48e6894..6af455c 100644 --- a/AwesomeAttract0r.xcodeproj/project.pbxproj +++ b/AwesomeAttract0r.xcodeproj/project.pbxproj @@ -64,6 +64,7 @@ 01C5707D13B63CF9009D151B /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = /usr/local/lib/libpng.a; sourceTree = ""; }; 08FB7796FE84155DC02AAC07 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; 420486591455B11C0025CC53 /* libpng.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = libpng.hpp; path = canvae/libpng.hpp; sourceTree = ""; }; + 42D2E10F1455D88C00FBC16A /* bmp.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = bmp.hpp; path = canvae/bmp.hpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -124,6 +125,7 @@ 01C5709D13B63E3A009D151B /* Attractors */, 01C5709C13B63E2F009D151B /* stf */, 01C5702613B63B56009D151B /* PNG.hpp */, + 42D2E10F1455D88C00FBC16A /* bmp.hpp */, 01C5702713B63B56009D151B /* Raw.hpp */, 01C5702813B63B56009D151B /* Raw.cpp */, 01C5700613B63AF0009D151B /* Projector.hpp */, diff --git a/Canvas.hpp b/Canvas.hpp index 5b9f7ff..c854006 100644 --- a/Canvas.hpp +++ b/Canvas.hpp @@ -16,7 +16,7 @@ public: virtual void clear() = 0; virtual void plot(const double* normalizedPosition, const double* normalizedColor) = 0; - virtual void output_file(const char* filename) const = 0; + virtual void output_file(cstd::string const & filename) const = 0; }; #endif // CANVAS_HPP diff --git a/batch.sh b/batch.sh index 3e5d0dd..dff384b 100755 --- a/batch.sh +++ b/batch.sh @@ -1,2 +1,2 @@ #!/bin/bash -while true; do ./AwesomeAttractor -P /var/www/render2/ -R -I 2000 -W 1024 -H 1024 -v attractors/emptyUnravel3D.stf; done +while true; do ~/Library/Developer/Xcode/DerivedData/AwesomeAttract0r-akxvgtneyociakezlpkfgaywuvoo/Build/Products/Debug/AwesomeAttract0r -P /Users/joshua/Documents/Code/AwesomeAttractor/render/ -R -I 20 -W 640 -H 640 -v attractors/emptyUnravel3D.stf; done diff --git a/canvae/PNG.hpp b/canvae/PNG.hpp index 407d2a6..4634c8b 100644 --- a/canvae/PNG.hpp +++ b/canvae/PNG.hpp @@ -71,7 +71,7 @@ public: } } - virtual void output_file(const char* filename_in) const { + virtual void output_file(std::string const & filename_in) const { std::string filename = filename_in; filename += ".png"; unsigned int* max_int = new unsigned int[num_colors]; @@ -97,7 +97,7 @@ public: power[i] = -2.5/std::log(average/(double)max_int[i]); if(power[i] < 0) { power[i] = 1; - LogInfo("negative power\n"); + LogError("negative power\n"); } if(n < width) { @@ -143,7 +143,6 @@ public: b += (std::pow(norm_value, power[c]*power_matrix[c+4]))*output_matrix[c+4]; } - // TODO: also clamp is below 0 ? r = std::max(0.0, std::min(1.0, r)); b = std::max(0.0, std::min(1.0, b)); g = std::max(0.0, std::min(1.0, g)); diff --git a/canvae/bmp.hpp b/canvae/bmp.hpp new file mode 100644 index 0000000..a4a4615 --- /dev/null +++ b/canvae/bmp.hpp @@ -0,0 +1,88 @@ +// +// bmp.hpp +// AwesomeAttract0r +// +// Created by Joshua Moerman on 10/24/11. +// Copyright 2011 Vadovas. All rights reserved. +// + +#ifndef AwesomeAttract0r_bmp_hpp +#define AwesomeAttract0r_bmp_hpp + +#include +#include +#include +#include + +namespace bmp { + + struct bitmap_file_header { + uint32_t filesize; + uint16_t creator1; + uint16_t creator2; + uint32_t bmp_offset; + + template + bitmap_file_header(DIBT dib_header): + filesize(dib_header.bytes() + dib_header.header_sz + 12 + 2), + creator1(0), + creator2(0), + bmp_offset(dib_header.header_sz + 12 + 2){} + + void write(std::ostream& out) const { + out << "BM"; + out.write(reinterpret_cast(this), 12); + } + }; + + struct bitmapcoreheader { + uint32_t header_sz; + uint16_t width; + uint16_t height; + uint16_t nplanes; + uint16_t bitspp; + + bitmapcoreheader(int width, int height): + header_sz(sizeof(bitmapcoreheader)), + width(width), + height(height), + nplanes(1), + bitspp(24){} + + void write(std::ostream& out) const { + out.write(reinterpret_cast(this), header_sz); + } + + unsigned int bytes(){ + return width*height*bitspp/8; + } + }; + + template + struct bitmap { + DIBT dib_header; + bitmap_file_header header; + T const * data; + + bitmap(int width, int height) + : dib_header(width, height) + , header(dib_header) + , data(0) {} + + void write(std::string const & filename){ + std::ofstream file(filename.c_str()); + write(file); + } + + void write(std::ostream& out){ + header.write(out); + dib_header.write(out); + //std::copy_n((char const *)data, dib_header.bytes(), std::ostream_iterator(out)); + std::copy((char const *)data, (char const *)data + dib_header.bytes(), std::ostream_iterator(out)); + } + + }; + +} + +#endif diff --git a/canvae/libpng.hpp b/canvae/libpng.hpp index b4685b9..9be96cc 100644 --- a/canvae/libpng.hpp +++ b/canvae/libpng.hpp @@ -12,22 +12,75 @@ #ifndef __APPLE__ #include #else -#warning PNG++ is not yet supported +#warning PNG++ is not yet supported (will save as bmp) +#include "bmp.hpp" namespace png { - template - struct image{ - image(unsigned int, unsigned int){} + struct rgb_pixel{ + char* data; + char red, green, blue; - image& operator[](unsigned int){return *this;} + rgb_pixel(char* d) + : data(d) + , red(0) + , green(0) + , blue(0) + {} - template - image& operator=(S const &){return *this;} + rgb_pixel(unsigned int r, unsigned int g, unsigned int b) + : data(0) + , red(r) + , green(g) + , blue(b) + {} - void write(std::string const &){} + void operator=(rgb_pixel const & rh){ + data[0] = rh.blue; + data[1] = rh.green; + data[2] = rh.red; + } }; - struct rgb_pixel{ - rgb_pixel(unsigned int, unsigned int, unsigned int){} + struct row{ + char * data; + + row(char* d) + : data(d) + {} + + rgb_pixel operator[](unsigned int c){return rgb_pixel(data + c*3);} + }; + + template + struct image{ + bmp::bitmap bitmap; + char * data; + + unsigned int width; + unsigned int height; + + image(unsigned int w, unsigned int h) + : bitmap(w, h) + , data(0) + , width(w) + , height(h) + { + data = new char[width*height*3]; + bitmap.data = data; + } + + ~image(){ + delete[] data; + } + + row operator[](unsigned int r){return row(data + r*height*3);} + + void write(std::string const & filename){ + bitmap.write(filename); + } + + private: + image(image const &); + image & operator=(image const &); }; } #endif diff --git a/main.cpp b/main.cpp index ecee783..d9d502d 100644 --- a/main.cpp +++ b/main.cpp @@ -35,6 +35,36 @@ void showHelpText() { exit(0); } +std::string generate_filename(){ + char filename[64]; + time_t t = time(0); + struct tm* lt = localtime(&t); + sprintf(filename, "attractor_%04d-%02d-%02d_%02d-%02d-%02d", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec); + + return std::string(filename); +} + +void render(Attractor & myAttractor, unsigned int iterations){ + clock_t start = clock(); + + for(unsigned int j = 1; j <= iterations; ++j) { + for(unsigned int i = 0; i < 1000000; ++i) { + myAttractor.iterate(); + myAttractor.plot(); + } + if(verbose >= 0) { + std::cout << "\r" << j << " out of " << iterations << " done." << std::flush; + } + } + + clock_t end = clock(); + + double totalIterations = 1000000.0*iterations; + double totalTime = ((double)(end-start)/(double)(CLOCKS_PER_SEC)); + LogInfo("\nTotal clock time: %f\n", totalTime); + LogMoreInfo("Average iterations per second: %f\n\n", totalIterations/totalTime); +} + int main(int argc, char* argv[]) { verbose = 0; std::string attractorFile = ""; @@ -94,46 +124,23 @@ int main(int argc, char* argv[]) { myAttractor.init_range(); LogInfo("\nRendering\n"); + render(myAttractor, iterations); - clock_t start, end; - start = clock(); - for(unsigned int j = 1; j <= iterations; ++j) { - for(unsigned int i = 0; i < 1000000; ++i) { - myAttractor.iterate(); - myAttractor.plot(); - } - //if (j%16 == 0) sleep(1); - if(verbose >= 0) { - std::cout << "\r" << j << " out of " << iterations << " done." << std::flush; - } - } - end = clock(); + // saving image + std::string filename = generate_filename(); + for(int vibrancy = 2; vibrancy <= 2; ++vibrancy){ + clock_t start = clock(); + myAttractor.projector->canvas->output_file(output_path+filename); + clock_t end = clock(); - double totalIterations = 1000000.0*iterations; - double totalTime = ((double)(end-start)/(double)(CLOCKS_PER_SEC)); - LogInfo("\nTotal clock time: %f\n", totalTime); - LogMoreInfo("Average iterations per second: %f\n\n", totalIterations/totalTime); - - // saving output - for(int vibrancy = -3; vibrancy <= 5; ++vibrancy){ - char filename[256]; - time_t t = time(0); - struct tm* lt = localtime(&t); - int r = vibrancy + 3; - output->v = vibrancy; - sprintf(filename, (output_path+"attractor_%04d-%02d-%02d_%02d-%02d-%02d-%01d").c_str(), lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, r); - - start = clock(); - myAttractor.projector->canvas->output_file(filename); - end = clock(); - - totalTime = ((double)(end-start)/(double)(CLOCKS_PER_SEC)); + double totalTime = ((double)(end-start)/(double)(CLOCKS_PER_SEC)); LogInfo("Total clock time for writing png: %f\n", totalTime); } - - if(0){ - std::string path; + + // saving stf + { + std::string path(filename); path += ".stf"; std::ofstream file(path.c_str());