Joshua Moerman
13 years ago
18 changed files with 826 additions and 622 deletions
@ -1,3 +0,0 @@ |
|||||
#include "Canvas.hpp" |
|
||||
|
|
||||
// lol
|
|
@ -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 { |
#ifndef AwesomeAttractorND_Canvas_hpp |
||||
protected: |
#define AwesomeAttractorND_Canvas_hpp |
||||
|
|
||||
unsigned int dimension; |
#include <vector> |
||||
Canvas(const unsigned int dimension) : dimension(dimension) {}; |
#include <iterator> |
||||
|
#include "array.hpp" |
||||
|
|
||||
public: |
class Canvas2D { |
||||
|
typedef unsigned int value_type; |
||||
unsigned int getDimension() const { return dimension; }; |
typedef std::vector<value_type> Row; |
||||
|
typedef std::vector<Row> Storage; |
||||
|
|
||||
virtual ~Canvas() {}; |
public: |
||||
|
Canvas2D(size_t width, size_t height) |
||||
virtual void clear() = 0; |
: storage(width, Storage::value_type(height, 0)) |
||||
virtual void plot(const double* normalizedPosition, const double* normalizedColor) = 0; |
{} |
||||
virtual void output_file(cstd::string const & filename) const = 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 |
||||
|
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -1,2 +1,2 @@ |
|||||
#!/bin/bash |
#!/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 |
||||
|
@ -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
|
|
||||
|
|
@ -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); |
|
||||
} |
|
@ -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
|
|
||||
|
|
@ -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 |
|
@ -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 |
|
Reference in new issue