Browse Source

using new output mechanism, and using boost program options

master
Joshua Moerman 13 years ago
parent
commit
f792af5803
  1. 3
      Attractor.hpp
  2. 66
      AwesomeAttract0r.xcodeproj/project.pbxproj
  3. 3
      Canvas.cpp
  4. 209
      Canvas.hpp
  5. 15
      Image.hpp
  6. 159
      ImageFormatBMP.hpp
  7. 103
      ImageFormatPNG.hpp
  8. 139
      Logger.hpp
  9. 29
      Projector.hpp
  10. 69
      Tonemapper.hpp
  11. 23
      array.hpp
  12. 2
      batch.sh
  13. 168
      canvae/PNG.hpp
  14. 65
      canvae/Raw.cpp
  15. 28
      canvae/Raw.hpp
  16. 88
      canvae/bmp.hpp
  17. 88
      canvae/libpng.hpp
  18. 191
      main.cpp

3
Attractor.hpp

@ -49,9 +49,6 @@ public:
void iterate() {
(*kernel)();
}
void plot() {
projector->plot(kernel->vector());
}

66
AwesomeAttract0r.xcodeproj/project.pbxproj

@ -8,14 +8,13 @@
/* Begin PBXBuildFile section */
01C5701213B63AF0009D151B /* Projector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01C5700713B63AF0009D151B /* Projector.cpp */; };
01C5701313B63AF0009D151B /* Canvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01C5700D13B63AF0009D151B /* Canvas.cpp */; };
01C5701413B63AF0009D151B /* AttractorKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01C5700F13B63AF0009D151B /* AttractorKernel.cpp */; };
01C5701513B63AF0009D151B /* Attractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01C5701113B63AF0009D151B /* Attractor.cpp */; };
01C5702913B63B56009D151B /* Raw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01C5702813B63B56009D151B /* Raw.cpp */; };
01C5703213B63B78009D151B /* stf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01C5703113B63B78009D151B /* stf.cpp */; };
01C5704313B63BBE009D151B /* Projection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01C5704013B63BBE009D151B /* Projection.cpp */; };
01C5704413B63BBE009D151B /* Normalizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 01C5704213B63BBE009D151B /* Normalizer.cpp */; };
01C5707E13B63CF9009D151B /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 01C5707D13B63CF9009D151B /* libpng.a */; };
427057AE147571FC00CBE978 /* libboost_program_options.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 427057AD147571FC00CBE978 /* libboost_program_options.a */; };
8DD76F650486A84900D96B5E /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* main.cpp */; settings = {ATTRIBUTES = (); }; };
/* End PBXBuildFile section */
@ -39,16 +38,11 @@
01C5700913B63AF0009D151B /* myMath.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = myMath.hpp; sourceTree = "<group>"; };
01C5700A13B63AF0009D151B /* Logger.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Logger.hpp; sourceTree = "<group>"; };
01C5700B13B63AF0009D151B /* defines.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = defines.hpp; sourceTree = "<group>"; };
01C5700C13B63AF0009D151B /* Canvas.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Canvas.hpp; sourceTree = "<group>"; };
01C5700D13B63AF0009D151B /* Canvas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Canvas.cpp; sourceTree = "<group>"; };
01C5700E13B63AF0009D151B /* AwesomeAttractorConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AwesomeAttractorConfig.h; sourceTree = "<group>"; };
01C5700F13B63AF0009D151B /* AttractorKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AttractorKernel.cpp; sourceTree = "<group>"; };
01C5701013B63AF0009D151B /* Attractor.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Attractor.hpp; sourceTree = "<group>"; };
01C5701113B63AF0009D151B /* Attractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Attractor.cpp; sourceTree = "<group>"; };
01C5701613B63AF0009D151B /* AwesomeAttract0r */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AwesomeAttract0r; sourceTree = BUILT_PRODUCTS_DIR; };
01C5702613B63B56009D151B /* PNG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = PNG.hpp; path = canvae/PNG.hpp; sourceTree = "<group>"; };
01C5702713B63B56009D151B /* Raw.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Raw.hpp; path = canvae/Raw.hpp; sourceTree = "<group>"; };
01C5702813B63B56009D151B /* Raw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Raw.cpp; path = canvae/Raw.cpp; sourceTree = "<group>"; };
01C5703013B63B78009D151B /* stf.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf.hpp; path = stfu/stf.hpp; sourceTree = "<group>"; };
01C5703113B63B78009D151B /* stf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stf.cpp; path = stfu/stf.cpp; sourceTree = "<group>"; };
01C5703913B63BA3009D151B /* Unravel3D.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Unravel3D.hpp; path = kernels/Unravel3D.hpp; sourceTree = "<group>"; };
@ -63,8 +57,13 @@
01C5704213B63BBE009D151B /* Normalizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Normalizer.cpp; path = projectors/Normalizer.cpp; sourceTree = "<group>"; };
01C5707D13B63CF9009D151B /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = /usr/local/lib/libpng.a; sourceTree = "<absolute>"; };
08FB7796FE84155DC02AAC07 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
420486591455B11C0025CC53 /* libpng.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = libpng.hpp; path = canvae/libpng.hpp; sourceTree = "<group>"; };
42D2E10F1455D88C00FBC16A /* bmp.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = bmp.hpp; path = canvae/bmp.hpp; sourceTree = "<group>"; };
427057A61475637B00CBE978 /* Canvas.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Canvas.hpp; sourceTree = "<group>"; };
427057A71475637B00CBE978 /* Image.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Image.hpp; sourceTree = "<group>"; };
427057A81475637B00CBE978 /* ImageFormatBMP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatBMP.hpp; sourceTree = "<group>"; };
427057A91475637B00CBE978 /* ImageFormatPNG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatPNG.hpp; sourceTree = "<group>"; };
427057AB1475637B00CBE978 /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = "<group>"; };
427057AC1475654E00CBE978 /* array.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = array.hpp; sourceTree = "<group>"; };
427057AD147571FC00CBE978 /* libboost_program_options.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_program_options.a; path = ../../../../../usr/local/lib/libboost_program_options.a; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -73,6 +72,7 @@
buildActionMask = 2147483647;
files = (
01C5707E13B63CF9009D151B /* libpng.a in Frameworks */,
427057AE147571FC00CBE978 /* libboost_program_options.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -88,7 +88,7 @@
name = stf;
sourceTree = "<group>";
};
01C5709D13B63E3A009D151B /* Attractors */ = {
01C5709D13B63E3A009D151B /* Kernels */ = {
isa = PBXGroup;
children = (
01C5700513B63AF0009D151B /* AttractorKernel.hpp */,
@ -100,21 +100,17 @@
01C5703D13B63BA3009D151B /* Logistic.hpp */,
01C5703E13B63BA3009D151B /* Ikeda3D.hpp */,
);
name = Attractors;
name = Kernels;
sourceTree = "<group>";
};
08FB7794FE84155DC02AAC07 /* AwesomeAttract0r */ = {
isa = PBXGroup;
children = (
420486591455B11C0025CC53 /* libpng.hpp */,
01C5703F13B63BBE009D151B /* Projection.hpp */,
01C5704013B63BBE009D151B /* Projection.cpp */,
01C5704113B63BBE009D151B /* Normalizer.hpp */,
01C5704213B63BBE009D151B /* Normalizer.cpp */,
08FB7795FE84155DC02AAC07 /* Source */,
C6859E8C029090F304C91782 /* Documentation */,
1AB674ADFE9D54B511CA2CBB /* Products */,
01C5707D13B63CF9009D151B /* libpng.a */,
427057AD147571FC00CBE978 /* libboost_program_options.a */,
);
name = AwesomeAttract0r;
sourceTree = "<group>";
@ -122,20 +118,19 @@
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
01C5709D13B63E3A009D151B /* Attractors */,
427057AC1475654E00CBE978 /* array.hpp */,
427057A61475637B00CBE978 /* Canvas.hpp */,
427057A71475637B00CBE978 /* Image.hpp */,
427057A81475637B00CBE978 /* ImageFormatBMP.hpp */,
427057A91475637B00CBE978 /* ImageFormatPNG.hpp */,
427057AB1475637B00CBE978 /* Tonemapper.hpp */,
427057A5147562DB00CBE978 /* Projectors */,
01C5709D13B63E3A009D151B /* Kernels */,
01C5709C13B63E2F009D151B /* stf */,
01C5702613B63B56009D151B /* PNG.hpp */,
42D2E10F1455D88C00FBC16A /* bmp.hpp */,
01C5702713B63B56009D151B /* Raw.hpp */,
01C5702813B63B56009D151B /* Raw.cpp */,
01C5700613B63AF0009D151B /* Projector.hpp */,
01C5700713B63AF0009D151B /* Projector.cpp */,
01C5700813B63AF0009D151B /* ostream_helpers.h */,
01C5700913B63AF0009D151B /* myMath.hpp */,
01C5700A13B63AF0009D151B /* Logger.hpp */,
01C5700B13B63AF0009D151B /* defines.hpp */,
01C5700C13B63AF0009D151B /* Canvas.hpp */,
01C5700D13B63AF0009D151B /* Canvas.cpp */,
01C5700E13B63AF0009D151B /* AwesomeAttractorConfig.h */,
01C5701013B63AF0009D151B /* Attractor.hpp */,
01C5701113B63AF0009D151B /* Attractor.cpp */,
@ -152,6 +147,19 @@
name = Products;
sourceTree = "<group>";
};
427057A5147562DB00CBE978 /* Projectors */ = {
isa = PBXGroup;
children = (
01C5700613B63AF0009D151B /* Projector.hpp */,
01C5700713B63AF0009D151B /* Projector.cpp */,
01C5703F13B63BBE009D151B /* Projection.hpp */,
01C5704013B63BBE009D151B /* Projection.cpp */,
01C5704113B63BBE009D151B /* Normalizer.hpp */,
01C5704213B63BBE009D151B /* Normalizer.cpp */,
);
name = Projectors;
sourceTree = "<group>";
};
C6859E8C029090F304C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
@ -211,10 +219,8 @@
files = (
8DD76F650486A84900D96B5E /* main.cpp in Sources */,
01C5701213B63AF0009D151B /* Projector.cpp in Sources */,
01C5701313B63AF0009D151B /* Canvas.cpp in Sources */,
01C5701413B63AF0009D151B /* AttractorKernel.cpp in Sources */,
01C5701513B63AF0009D151B /* Attractor.cpp in Sources */,
01C5702913B63B56009D151B /* Raw.cpp in Sources */,
01C5703213B63B78009D151B /* stf.cpp in Sources */,
01C5704313B63BBE009D151B /* Projection.cpp in Sources */,
01C5704413B63BBE009D151B /* Normalizer.cpp in Sources */,
@ -233,7 +239,7 @@
GCC_DEBUGGING_SYMBOLS = full;
GCC_FAST_MATH = YES;
GCC_OPTIMIZATION_LEVEL = 3;
HEADER_SEARCH_PATHS = "/usr/local/include//**";
HEADER_SEARCH_PATHS = /usr/local/include;
LIBRARY_SEARCH_PATHS = "/usr/local/lib//**";
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
@ -241,7 +247,6 @@
WARNING_CFLAGS = (
"-Wall",
"-Wextra",
"-Weffc++",
);
};
name = "Release with Symbols";
@ -280,7 +285,7 @@
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
HEADER_SEARCH_PATHS = "/usr/local/include//**";
HEADER_SEARCH_PATHS = /usr/local/include;
LIBRARY_SEARCH_PATHS = "/usr/local/lib//**";
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
@ -288,7 +293,6 @@
WARNING_CFLAGS = (
"-Wall",
"-Wextra",
"-Weffc++",
);
};
name = Debug;

3
Canvas.cpp

@ -1,3 +0,0 @@
#include "Canvas.hpp"
// lol

209
Canvas.hpp

@ -1,22 +1,201 @@
#ifndef CANVAS_HPP
#define CANVAS_HPP
//
// Canvas.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 10/28/11.
// Copyright 2011 Vadovas. All rights reserved.
//
/*
Interface (or Concept) Canvas:
Canvas canvas(width, height, ...); Constructs a Canvas with given dimensions
canvas[x][y]...[z] Returns a (const) reference to an element
canvas.plot(position) Plots on the canvas (where position is normalized, ie in the unit-cube)
canvas.size<N>() gives width/size for the given dimension N.
canvas.begin() .end() gives iterators to the elements (directly)
*/
class Canvas {
protected:
#ifndef AwesomeAttractorND_Canvas_hpp
#define AwesomeAttractorND_Canvas_hpp
unsigned int dimension;
Canvas(const unsigned int dimension) : dimension(dimension) {};
#include <vector>
#include <iterator>
#include "array.hpp"
public:
unsigned int getDimension() const { return dimension; };
class Canvas2D {
typedef unsigned int value_type;
typedef std::vector<value_type> Row;
typedef std::vector<Row> Storage;
virtual ~Canvas() {};
virtual void clear() = 0;
virtual void plot(const double* normalizedPosition, const double* normalizedColor) = 0;
virtual void output_file(cstd::string const & filename) const = 0;
public:
Canvas2D(size_t width, size_t height)
: storage(width, Storage::value_type(height, 0))
{}
Row & operator[](size_t r){
return storage[r];
}
Row const & operator[](size_t r) const {
return storage[r];
}
void plot(double const * const position){
const size_t width = size<0>();
const size_t height = size<1>();
const size_t c = 0.5*position[0]*width + width*.5;
const size_t r = 0.5*position[1]*width + height*.5;
if(c < width && r < height) {
storage[r][c]++;
}
}
size_t size() const {
return size<0>() * size<1>();
}
template <size_t N>
size_t size() const {
if ( N == 0 ) return storage.size();
if ( N == 1 ) return storage.front().size();
return 0;
}
struct iterator;
iterator begin(){
return iterator(this);
}
iterator end(){
return iterator(this, 0, size<1>());
};
struct const_iterator;
const_iterator begin() const {
return const_iterator(this);
}
const_iterator end() const {
return const_iterator(this, 0, size<1>());
}
const_iterator cbegin() const {
return const_iterator(this);
}
const_iterator cend() const {
return const_iterator(this, 0, size<1>());
}
struct iterator : public std::iterator<std::forward_iterator_tag, value_type> {
iterator(iterator const & rh)
: canvas(rh.canvas)
, c(rh.c)
, r(rh.r)
{}
iterator & operator++(){
++c;
if (c >= canvas->size<0>()) {
c = 0;
++r;
}
return *this;
}
iterator operator++(int){
iterator temp(*this);
++(*this);
return temp;
}
bool operator==(iterator const & rh) const {
return canvas == rh.canvas && c == rh.c && r == rh.r;
}
bool operator!=(iterator const & rh) const {
return canvas != rh.canvas || c != rh.c || r != rh.r;
}
value_type & operator*(){
return (*canvas)[r][c];
}
value_type & operator->(){
return (*canvas)[r][c];
}
private:
friend class Canvas2D;
iterator(Canvas2D * canvas, size_t c = 0, size_t r = 0)
: canvas(canvas)
, c(c)
, r(r)
{}
iterator();
Canvas2D * canvas;
size_t c;
size_t r;
};
struct const_iterator : public std::iterator<std::forward_iterator_tag, value_type const> {
const_iterator(const_iterator const & rh)
: canvas(rh.canvas)
, c(rh.c)
, r(rh.r)
{}
const_iterator & operator++(){
++c;
if (c >= canvas->size<0>()) {
c = 0;
++r;
}
return *this;
}
const_iterator operator++(int){
const_iterator temp(*this);
++(*this);
return temp;
}
bool operator==(const_iterator const & rh) const {
return canvas == rh.canvas && c == rh.c && r == rh.r;
}
bool operator!=(const_iterator const & rh) const {
return canvas != rh.canvas || c != rh.c || r != rh.r;
}
value_type const & operator*() const {
return (*canvas)[r][c];
}
value_type const & operator->() const {
return (*canvas)[r][c];
}
private:
friend class Canvas2D;
const_iterator(Canvas2D const * canvas, size_t c = 0, size_t r = 0)
: canvas(canvas)
, c(c)
, r(r)
{}
const_iterator();
Canvas2D const * canvas;
size_t c;
size_t r;
};
private:
Storage storage;
};
#endif // CANVAS_HPP
#endif

15
Image.hpp

@ -0,0 +1,15 @@
//
// Image.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 11/2/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_Image_hpp
#define AwesomeAttractorND_Image_hpp
#include "ImageFormatBMP.hpp"
#include "ImageFormatPNG.hpp"
#endif

159
ImageFormatBMP.hpp

@ -0,0 +1,159 @@
//
// ImageFormatBMP.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 11/12/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_ImageFormatBMP_hpp
#define AwesomeAttractorND_ImageFormatBMP_hpp
#include <ostream>
#include <fstream>
#include <stdexcept>
#include <algorithm>
namespace ImageFormats {
namespace bmp {
struct pixelBGR{
pixelBGR(double red, double green, double blue)
: blue(clamp(255*blue))
, green(clamp(255*green))
, red(clamp(255*red))
{}
pixelBGR(int red, int green, int blue)
: blue(clamp(blue))
, green(clamp(green))
, red(clamp(red))
{}
void swapRB(){
std::swap(red, blue);
}
private:
uint8_t clamp(int n){
return std::min(255, std::max(0, n));
}
uint8_t blue;
uint8_t green;
uint8_t red;
};
struct bitmap_file_header {
uint32_t filesize;
uint16_t creator1;
uint16_t creator2;
uint32_t bmp_offset;
template <typename DIBT>
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<const char*>(this), 12);
}
};
struct bitmapcoreheader {
uint32_t header_sz;
uint16_t width;
uint16_t height;
uint16_t nplanes;
uint16_t bitspp;
bitmapcoreheader(uint16_t width, uint16_t height, uint16_t bitspp = 24):
header_sz(sizeof(bitmapcoreheader)),
width(width),
height(height),
nplanes(1),
bitspp(bitspp){}
void write(std::ostream& out) const {
out.write(reinterpret_cast<const char*>(this), header_sz);
}
uint32_t bytes(){
return width*height*bitspp/8;
}
};
template <typename P = pixelBGR, typename DIBT = bitmapcoreheader>
struct bitmap {
typedef P pixel;
bitmap(uint16_t width, uint16_t height)
: dib_header(width, height, sizeof(pixel)*8)
, 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<char>(out));
std::copy((char const *)data, (char const *)data + dib_header.bytes(), std::ostream_iterator<char>(out));
}
private:
DIBT dib_header;
bitmap_file_header header;
P const * data;
};
template <typename P = pixelBGR, typename DIBT = bitmapcoreheader>
struct bitmap_stream {
typedef P pixel;
bitmap_stream(uint16_t width, uint16_t height, std::string filename)
: dib_header(width, height, sizeof(pixel)*8)
, header(dib_header)
, file(filename.c_str())
, x(0)
, y(0)
{
if(!file)
throw std::runtime_error("bitmap file could not be opened.");
header.write(file);
dib_header.write(file);
}
bitmap_stream& operator<<(pixel const & p){
if (y >= dib_header.height){
throw std::out_of_range("Writing BMP image out of bounds.");
}
pixel p2(p);
p2.swapRB();
file.write((char const *)&p2, sizeof(pixel));
++x;
if (x >= dib_header.width){
x = 0;
++y;
}
return *this;
}
private:
DIBT dib_header;
bitmap_file_header header;
std::ofstream file;
uint16_t x;
uint16_t y;
};
}
}
#endif

103
ImageFormatPNG.hpp

@ -0,0 +1,103 @@
//
// ImageFormatPNG.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 11/12/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_ImageFormatPNG_hpp
#define AwesomeAttractorND_ImageFormatPNG_hpp
#include <stdio.h>
#include <stdexcept>
#include <png.h>
namespace ImageFormats {
namespace png{
struct pixelRGB {
pixelRGB()
: red(0)
, green(0)
, blue(0)
{}
pixelRGB(double red, double green, double blue)
: red(clamp(255*red))
, green(clamp(255*green))
, blue(clamp(255*blue))
{}
pixelRGB(int red, int green, int blue)
: red(clamp(red))
, green(clamp(green))
, blue(clamp(blue))
{}
private:
uint8_t clamp(int n){
return std::min(255, std::max(0, n));
}
uint8_t red;
uint8_t green;
uint8_t blue;
};
struct png_stream{
typedef pixelRGB pixel;
png_stream(uint32_t width, uint32_t height, std::string filename)
: fp(0)
, png_ptr(0)
, info_ptr(0)
, row(width)
, x(0)
{
fp = fopen(filename.c_str(), "wb");
if(!fp) throw std::runtime_error("Could not open file");
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if(!png_ptr) throw std::runtime_error("PNG structure could not be allocated");
info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr) throw std::runtime_error("PNG information structure could not be allocated");
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_set_compression_level(png_ptr, 9);
png_write_info(png_ptr, info_ptr);
}
~png_stream(){
png_write_end(png_ptr, info_ptr);
png_destroy_info_struct(png_ptr, &info_ptr);
fclose(fp);
}
png_stream& operator<<(pixel const & p){
row[x] = p;
++x;
if(x >= row.size()){
png_write_row(png_ptr, reinterpret_cast<unsigned char const*>(row.data()));
x = 0;
}
return *this;
}
private:
FILE* fp;
png_structp png_ptr;
png_infop info_ptr;
std::vector<pixel> row;
uint32_t x;
};
}
}
#endif

139
Logger.hpp

@ -2,6 +2,11 @@
#define LOGGER_HPP_INCLUDED
#include <cstdio>
#include <iostream>
#include <stack>
#include <map>
#include <cassert>
#include <boost/date_time/posix_time/posix_time.hpp>
extern int verbose;
@ -17,6 +22,140 @@ extern int verbose;
#define LogError(s, ...) \
if ( verbose >= 0 ) { printf("%s, %s(), %d: ", __FILE__, __func__, __LINE__); printf(s, ##__VA_ARGS__); }
/*
Imported from Astrant:
Questions/Suggestions mail nick@astrant.net
*/
struct Logger {
Logger(std::ostream& logging_stream_, std::string prefix_ = std::string(""))
: logging_stream(&logging_stream_)
, prefix(prefix_)
{}
void log(std::string what){
*logging_stream << get_prefix() << "(" << what << ") took place at (" << boost::posix_time::microsec_clock::local_time() << std::endl;
}
void start(std::string what){
Event e;
e.start = boost::posix_time::microsec_clock::local_time();
e.name = what;
EventMap::iterator it = event_map.find(what);
if(it != event_map.end()){
*logging_stream << get_prefix() << "WARNING: Overwriting event(" << e.name << "), did you forget to call stop()?";
} else {
event_name_stack.push(what);
}
event_map.insert(it, std::make_pair(what, e));
}
void stop() {
assert(!event_name_stack.empty());
stop(event_name_stack.top());
}
private:
void stop(std::string what){
EventMap::iterator it = event_map.find(what);
if(it == event_map.end()){
*logging_stream << get_prefix() << "WARNING: No such, or already stopped, event(" << what << "), did you forget to call start()?";
} else {
it->second.end = boost::posix_time::microsec_clock::local_time();
log_event(it->second);
event_map.erase(it);
}
event_name_stack.pop();
}
struct Event {
boost::posix_time::ptime start;
boost::posix_time::ptime end;
std::string name;
};
// A map containing strings -> Event, used by start() and stop()
typedef std::map<std::string, Event> EventMap;
EventMap event_map;
// A stack used by 0-parameter stop() to stop the last start()ed event.
std::stack<std::string> event_name_stack;
std::ostream* logging_stream;
std::string prefix;
void log_event(Event const& e){
*logging_stream << get_prefix() << "Event(" << e.name << ") started at (" << e.start << ") ended at (" << e.end << ") duration (" << e.end - e.start << " ms) " << std::endl;
}
std::string get_prefix() const {
if(prefix == std::string("")){
return prefix;
} else {
return prefix + ": ";
}
}
};
/*
My progressbar class (as seen on github)
*/
struct Progressbar {
Progressbar(std::ostream & out, std::string prefix = "", std::string begin = "", std::string end = "")
: out(out)
, begin(begin)
, prefix(prefix)
, end(end)
{
if (begin != "") {
out << begin << std::endl;
}
show(0, 1, ' ');
}
~Progressbar(){
show(1, 1, '=');
if (end != "") {
out << "\n" << end << std::endl;
} else {
out << std::endl;
}
}
template <typename T>
void show(T const & progress, T const & max, char delim = '>'){
out << "\r";
size_t width = 80; // default terminal size :D
width -= prefix.size();
width -= 3; // [, > and ]
if (prefix != "") {
width -= 1;
out << prefix << ' ';
}
double ratio = (double) progress / (double) max;
size_t length = width * ratio;
std::string fill(length, '=');
std::string empty(width - length, ' ');
out << '[' << fill << delim << empty << ']' << std::flush;
}
private:
std::ostream & out;
std::string begin;
std::string prefix;
std::string end;
};
#endif // LOGGER_HPP_INCLUDED

29
Projector.hpp

@ -9,13 +9,13 @@
class Projector {
public:
// SHOULD NOT BE HERE
Canvas* canvas;
Projector(unsigned int inputDimension, unsigned int outputDimension) :
canvas(0), projector(0), projectedPoint(0), projectedColor(0),
inputDimension(inputDimension), outputDimension(outputDimension),
ready(true) {
Projector(unsigned int inputDimension, unsigned int outputDimension)
: projectedPoint(0)
, projectedColor(0)
, inputDimension(inputDimension)
, outputDimension(outputDimension)
, ready(true)
{
try {
allocate();
} catch(std::exception& e) {
@ -32,26 +32,15 @@ public:
void plot(const double* point) {
project(point);
if(ready) {
if(canvas != NULL) {
canvas->plot(projectedPoint, projectedColor);
}
/*if(projector != NULL) {
projector->plot(projectedPoint, projectedColor);
}*/
}
}
static Projector* createProjector(stfu::node& projector, unsigned int input_dimension);
protected:
Projector* projector;
public:
double* projectedPoint;
double* projectedColor;
protected:
unsigned int inputDimension;
unsigned int outputDimension;

69
Tonemapper.hpp

@ -0,0 +1,69 @@
//
// Tonemapper.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 10/28/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_Tonemapper_hpp
#define AwesomeAttractorND_Tonemapper_hpp
#include <algorithm>
#include <numeric>
#include <cmath>
namespace Tonemappers {
struct Normalizer {
Normalizer()
: max(0)
{}
template <typename C>
void analyse(C const & canvas){
max = *std::max_element(canvas.begin(), canvas.end());
}
template <typename C, typename I>
void process(C const & canvas, I & image){
for (typename C::const_iterator it = canvas.begin(); it != canvas.end(); ++it) {
const double grayscale = get_value(*it);
image << typename I::pixel(grayscale, grayscale, grayscale);
}
}
protected:
double get_value(unsigned int n){
return (double) n / (double) max;
}
unsigned int max;
};
struct GammaCorrector : public Normalizer {
template <typename C>
void analyse(C const & canvas){
Normalizer::analyse(canvas);
const unsigned int sum = std::accumulate(canvas.begin(), canvas.end(), 0);
const double average = sum / (double) canvas.size();
power = -2.5/std::log(average/max);
}
template <typename C, typename I>
void process(C const & canvas, I & image){
for (typename C::const_iterator it = canvas.begin(); it != canvas.end(); ++it) {
const double grayscale = get_value(*it);
image << typename I::pixel(grayscale, grayscale, grayscale);
}
}
protected:
double get_value(unsigned int n){
return std::pow(Normalizer::get_value(n), power);
}
double power;
};
}
#endif

23
array.hpp

@ -0,0 +1,23 @@
//
// array.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 11/2/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_array_hpp
#define AwesomeAttractorND_array_hpp
// workaround to easily work in xcode :D
#ifndef __APPLE__
#include <array>
#else
#include <tr1/array>
namespace std {
using tr1::array;
}
#endif
#endif

2
batch.sh

@ -1,2 +1,2 @@
#!/bin/bash
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
while true; do ./build/Debug/AwesomeAttract0r -P /Users/joshua/Documents/Code/AwesomeAttractor/render/ -R -I 20 -W 640 -H 640 -v -f attractors/emptyUnravel3D.stf; done

168
canvae/PNG.hpp

@ -1,168 +0,0 @@
#ifndef PNG_HPP
#define PNG_HPP
#include <memory>
#include <vector>
#include <cassert>
#include <cmath>
#ifndef __APPLE__
#include <array>
#else
#include <tr1/array>
namespace std {
using tr1::array;
}
#endif
#include "libpng.hpp"
#include "../Canvas.hpp"
class PNG : public Canvas {
unsigned int width;
unsigned int height;
unsigned int num_colors;
unsigned int* int_array;
//std::shared_ptr<std::vector<unsigned int>> int_array;
public:
double v;
PNG(unsigned int width, unsigned int height, unsigned int num_colors = 1)
: Canvas(2)
, width(width)
, height(height)
, num_colors(num_colors)
, int_array(0)
, v(2.0) {
//int_array = std::make_shared<vstd::vector<unsigned int>>(width*height*num_colors);
int_array = new unsigned int[width*height*num_colors];
LogInfo("PNG::PNG(): width: %d, height: %d, colors: %d\n", width, height, num_colors);
assert(int_array != 0);
clear();
LogDebug("New Canvas\n");
}
virtual void clear() {
std::fill_n(int_array, width*height*num_colors, 0);
}
virtual void plot(const double* normalizedPosition, const double* normalizedColor) {
const double& x = normalizedPosition[0];
const double& y = normalizedPosition[1];
const unsigned int x_int = x*width + width*.5;
const unsigned int y_int = y*width + height*.5;
const unsigned int index = x_int + width * y_int;
if(x_int < width && y_int < height) {
if(normalizedColor[0] > 0.0){
int_array[index]++;
} else {
int_array[index + width*height]++;
}
}
}
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];
double* power = new double[num_colors];
for(unsigned int i = 0; i < num_colors; ++i) {
max_int[i] = 0;
double cumulative = 0;
unsigned int n = 0;
for(unsigned int j = 0; j < width*height; j++) {
if(max_int[i] < int_array[j+i*width*height]) {
max_int[i] = int_array[j+i*width*height];
}
if(int_array[j+i* width* height] != 0) {
cumulative += int_array[j+i*width*height];
n++;
}
}
const double average = cumulative / (double)(width*height);
power[i] = -2.5/std::log(average/(double)max_int[i]);
if(power[i] < 0) {
power[i] = 1;
LogError("negative power\n");
}
if(n < width) {
LogInfo("not enough data in dimension %d\n", i);
return;
}
}
const double vibrancy = v;
// TODO: find a way to set these things:
// pngFile->setcompressionlevel(9);
// pngFile->settext("Attractor", "Joshua Moerman", "A awesome attractor", "AwesomeAttractor");
png::image< png::rgb_pixel > image(width, height);
std::array<double, 6> power_matrix = {{
1.0, 1.5,
2.0, 2.5,
3.0, 1.5
}};
std::array<double, 6> output_matrix = {{
2.0, 2.0,
2.0, 1.5,
2.0, 2.0
}};
for(unsigned int x = 0; x < width; x++) {
for(unsigned int y = 0; y < height; y++) {
double r = 0.0;
double g = 0.0;
double b = 0.0;
double average_norm_value = 0.0;
for(unsigned int c = 0; c < num_colors; ++c){
average_norm_value += (double)int_array[x + y*width + c*width*height]/max_int[c];
}
average_norm_value /= (double) num_colors;
for(unsigned int c = 0; c < num_colors; c++) {
double norm_value = (double)int_array[x + y*width + c*width*height]/max_int[c];
norm_value = vibrancy*norm_value + (1.0 - vibrancy) * average_norm_value;
norm_value = std::max(0.0, norm_value);
r += (std::pow(norm_value, power[c]*power_matrix[c+0]))*output_matrix[c+0];
g += (std::pow(norm_value, power[c]*power_matrix[c+2]))*output_matrix[c+2];
b += (std::pow(norm_value, power[c]*power_matrix[c+4]))*output_matrix[c+4];
}
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));
image[y][x] = png::rgb_pixel(r*255, g*255, b*255);
}
}
delete[] max_int;
delete[] power;
LogInfo("Writing %s\n", filename.c_str());
image.write(filename);
LogMoreInfo("File written");
}
private:
PNG(PNG const &);
PNG & operator=(PNG const &);
};
#endif // PNG_HPP

65
canvae/Raw.cpp

@ -1,65 +0,0 @@
#include "../Logger.hpp"
#include <fstream>
#include <cmath>
#include <cstdlib>
#include <cassert>
#include <algorithm>
#include <numeric>
#include <functional>
#include "Raw.hpp"
Raw::Raw(const unsigned int dimension, const unsigned int* sizes_)
: Canvas(dimension)
, sizes(0)
, sizesMultiplied(0)
, pixelArray(0)
, arraySize(1)
{
sizes = new unsigned int[dimension];
assert(sizes != NULL);
std::copy(sizes_, sizes_ + dimension, sizes);
sizesMultiplied = new unsigned int[dimension];
assert(sizesMultiplied != NULL);
sizesMultiplied[0] = 1;
for(unsigned int i = 1; i < dimension; ++i) {
sizesMultiplied[i] = sizesMultiplied[i-1]*sizes[i-1];
}
for(unsigned int i = 0; i < dimension; ++i) {
arraySize *= sizes[i];
}
pixelArray = new unsigned int[arraySize];
assert(pixelArray != NULL);
clear();
LogDebug("New RawCanvas of dimension %d\n", dimension);
}
void Raw::clear() {
std::fill_n(pixelArray, arraySize, 0);
}
void Raw::plot(const double* position) {
unsigned int index = 0;
for(unsigned int i = 0; i < dimension; ++i) {
index += (unsigned int)(position[i]*sizes[i] + 0.5*sizes[i])*sizesMultiplied[i];
}
if(index < arraySize) {
pixelArray[index]++;
}
}
/*
I/O functions
*/
void Raw::output_file(const char* filename) const {
std::ofstream outfile(filename, std::ofstream::binary);
outfile.write(reinterpret_cast<char*>(pixelArray), sizeof(unsigned int)*arraySize);
}

28
canvae/Raw.hpp

@ -1,28 +0,0 @@
#ifndef RAW_HPP
#define RAW_HPP
#include "../Canvas.hpp"
class Raw : public Canvas {
unsigned int* sizes;
unsigned int* sizesMultiplied;
unsigned int* pixelArray;
unsigned int arraySize;
public:
Raw(const unsigned int dimension, const unsigned int* sizes);
virtual void clear();
virtual void plot(const double* normalizedPosition);
virtual void output_file(const char* filename) const;
private:
Raw(Raw const &);
Raw & operator=(Raw const &);
};
#endif // RAW_HPP

88
canvae/bmp.hpp

@ -1,88 +0,0 @@
//
// 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 <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
namespace bmp {
struct bitmap_file_header {
uint32_t filesize;
uint16_t creator1;
uint16_t creator2;
uint32_t bmp_offset;
template <typename DIBT>
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<const char*>(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<const char*>(this), header_sz);
}
unsigned int bytes(){
return width*height*bitspp/8;
}
};
template <typename T, typename DIBT = bitmapcoreheader>
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<char>(out));
std::copy((char const *)data, (char const *)data + dib_header.bytes(), std::ostream_iterator<char>(out));
}
};
}
#endif

88
canvae/libpng.hpp

@ -1,88 +0,0 @@
//
// libpng.hpp
// AwesomeAttract0r
//
// Created by Joshua Moerman on 10/24/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttract0r_libpng_hpp
#define AwesomeAttract0r_libpng_hpp
#ifndef __APPLE__
#include <png++/png.hpp>
#else
#warning PNG++ is not yet supported (will save as bmp)
#include "bmp.hpp"
namespace png {
struct rgb_pixel{
char* data;
char red, green, blue;
rgb_pixel(char* d)
: data(d)
, red(0)
, green(0)
, blue(0)
{}
rgb_pixel(unsigned int r, unsigned int g, unsigned int b)
: data(0)
, red(r)
, green(g)
, blue(b)
{}
void operator=(rgb_pixel const & rh){
data[0] = rh.blue;
data[1] = rh.green;
data[2] = rh.red;
}
};
struct row{
char * data;
row(char* d)
: data(d)
{}
rgb_pixel operator[](unsigned int c){return rgb_pixel(data + c*3);}
};
template <typename T>
struct image{
bmp::bitmap<char> 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
#endif

191
main.cpp

@ -1,39 +1,23 @@
#include "Logger.hpp"
#include <iostream>
#include <fstream>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include "Attractor.hpp"
#include "Canvas.hpp"
#include "Projector.hpp"
#include "canvae/PNG.hpp"
#include "Logger.hpp"
#include "ostream_helpers.h"
#include "defines.hpp"
#include "AwesomeAttractorConfig.h"
#include "Attractor.hpp"
#include "Canvas.hpp"
#include "Image.hpp"
#include "Tonemapper.hpp"
int verbose;
#include <boost/program_options.hpp>
namespace po = boost::program_options;
void showHelpText() {
std::cout <<
"Awesome Attractor, version " __DATE__ "\n"
"Usage: AwesomeAttractor [OPTION]* [FILE]\n"
"Optons:\n"
" -h, --help Shows this help\n"
" -q quiet mode\n"
" -v verbose mode\n"
" -V loud mode\n"
" -W N Sets width of output image (1024)\n"
" -H N Sets height of output image (1024)\n"
" -I N Sets number of milions of iterations (100)\n"
" -R Random attractor (no file will be read)\n"
<< std::endl;
exit(0);
}
int verbose = 3;
std::string generate_filename(){
char filename[64];
@ -44,112 +28,95 @@ std::string generate_filename(){
return std::string(filename);
}
void render(Attractor & myAttractor, unsigned int iterations){
clock_t start = clock();
void render(Attractor & myAttractor, Canvas2D & canvas, unsigned int iterations){
Progressbar progress(std::cout, "rendering");
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;
canvas.plot(myAttractor.projector->projectedPoint);
}
progress.show(j, iterations);
}
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[]) {
LogInfo("Awesome Attractor, version %s\n", __DATE__);
verbose = 0;
std::string attractorFile = "";
std::string output_path = "render/";
std::string attractorFile;
std::string output_path;
bool generate_random = false;
unsigned int iterations = DEFAULT_ITERATIONS;
unsigned int width = DEFAULT_WIDTH;
unsigned int height = DEFAULT_HEIGHT;
unsigned int iterations, width, height;
srand(time(0));
if(argc <= 1) {
showHelpText();
}
for(int i = 1; i < argc; ++i) {
if(strcmp(argv[i], "-v") == 0) {
verbose = 1;
} else if(strcmp(argv[i], "-V") == 0) {
verbose = 3;
} else if(strcmp(argv[i], "-q") == 0) {
verbose = -1;
} else if(strcmp(argv[i], "--help") == 0) {
showHelpText();
} else if(strcmp(argv[i], "-h") == 0) {
showHelpText();
} else if(strcmp(argv[i], "-W") == 0) {
width = atoi(argv[++i]);
} else if(strcmp(argv[i], "-H") == 0) {
height = atoi(argv[++i]);
} else if(strcmp(argv[i], "-I") == 0) {
iterations = atoi(argv[++i]);
} else if(strcmp(argv[i], "-P") == 0) {
output_path = argv[++i];
} else if(strcmp(argv[i], "-R") == 0) {
generate_random = true;
} else {
attractorFile = argv[i];
}
}
LogInfo("Awesome Attractor, version %s\n", __DATE__);
Attractor* my_attractor_ptr = 0;
if(attractorFile != "")
my_attractor_ptr = new Attractor(attractorFile);
else if(generate_random)
my_attractor_ptr = new Attractor();
if(my_attractor_ptr == 0){
LogError("Nothing todo\n");
exit(0);
po::options_description desc("Usage");
desc.add_options()
("help,h", "produce help message")
("iterations,I", po::value<unsigned int>(&iterations)->default_value(DEFAULT_ITERATIONS), "set number of iterations (in milions)")
("width,W", po::value<unsigned int>(&width)->default_value(DEFAULT_WIDTH), "width of output image")
("height,H", po::value<unsigned int>(&height)->default_value(DEFAULT_HEIGHT), "height of output image")
("input-file,f", po::value<std::string>(&attractorFile)->default_value(""), "attractor file to read")
("output-path,P", po::value<std::string>(&output_path)->default_value("render/"), "path to output image")
("random,R", "use random parameters")
;
po::variables_map vm;
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
} catch(std::exception & e) {
std::cout << "Failed to read commandline: " << e.what() << std::endl;
std::cout << desc << std::endl;
return 1;
}
Attractor& myAttractor = *my_attractor_ptr;
PNG* output = new PNG(width, height, 2);
myAttractor.projector->canvas = output;
myAttractor.init_range();
LogInfo("\nRendering\n");
render(myAttractor, iterations);
// 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 totalTime = ((double)(end-start)/(double)(CLOCKS_PER_SEC));
LogInfo("Total clock time for writing png: %f\n", totalTime);
if (vm.count("help") || argc <= 1) {
std::cout << desc << std::endl;
return 1;
}
// saving stf
if(vm.count("random")) generate_random = true;
std::string filename = output_path + generate_filename();
Logger logger(std::cout);
Canvas2D canvas(width, height);
{
std::string path(filename);
path += ".stf";
Attractor* my_attractor_ptr = 0;
if(attractorFile != "")
my_attractor_ptr = new Attractor(attractorFile);
else if(generate_random)
my_attractor_ptr = new Attractor();
std::ofstream file(path.c_str());
file << myAttractor.stf_output() << std::endl;
}
if(my_attractor_ptr == 0){
LogError("Nothing todo\n");
exit(0);
}
my_attractor_ptr->init_range();
logger.start("rendering");
render(*my_attractor_ptr, canvas, iterations);
logger.stop();
{
std::string path(filename + ".stf");
std::ofstream file(path.c_str());
file << my_attractor_ptr->stf_output() << std::endl;
}
delete my_attractor_ptr;
}
delete my_attractor_ptr;
return 0;
{
Tonemappers::GammaCorrector tonemapper;
tonemapper.analyse(canvas);
logger.start("saving image");
ImageFormats::png::png_stream image(canvas.size<0>(), canvas.size<1>(), filename + ".png");
tonemapper.process(canvas, image);
logger.stop();
}
}