polaroid-pp

Schlieren and contour plot tool
git clone https://git.0xfab.ch/polaroid-pp.git
Log | Files | Refs | Submodules | README | LICENSE

commit d308c93a5d2fef2df16a23c972e1b02fa40b72f7
parent b3ac17c4e50917a393b5e48f76d06c7664aa1e3c
Author: Fabian Wermelinger <fabianw@mavt.ethz.ch>
Date:   Tue, 26 Apr 2016 23:16:45 +0200

added Makefile base, implemented Polaroid base

Diffstat:
M.gitignore | 1+
AMakefile | 32++++++++++++++++++++++++++++++++
AMakefile.config | 45+++++++++++++++++++++++++++++++++++++++++++++
Ainclude/Types.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/common.h | 23+++++++++++++++++++++++
Alib/.gitignore | 1+
Asrc/PhotoPNG.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PhotoPaper.h | 26++++++++++++++++++++++++++
Asrc/Polaroid.cpp | 196+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Polaroid.h | 32++++++++++++++++++++++++++++++++
Athird_party/Makefile | 32++++++++++++++++++++++++++++++++
11 files changed, 527 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,3 +3,4 @@ *.swo *.bak *.o +build diff --git a/Makefile b/Makefile @@ -0,0 +1,32 @@ +include ./Makefile.config + +CC = g++ + +# SRC = Polaroid.cpp PhotoPaper.cpp +# HDR = Polaroid.h PhotoPaper.h IdealSchlieren.h +SRC = src/Polaroid.cpp +HDR = src/Polaroid.h src/PhotoPaper.h +OBJ = ${SRC:.cpp=.o} + +Polaroid: $(HDR) $(OBJ) liball + +# schlierenCamera: all schlierenCamera.cpp +# $(CC) $(CPPFLAGS) $(INC) -o schlierenCamera schlierenCamera.cpp $(OBJ) $(LIB) -lz -lpng -lhdf5 -lWaveletCompressor + +# hsvCamera: all hsvCamera.cpp +# $(CC) $(CPPFLAGS) $(INC) -o hsvCamera hsvCamera.cpp $(OBJ) $(LIB) -lz -lpng -lhdf5 -lWaveletCompressor + +# test: all +# (cd test; make all) + +%.o: %.cpp + $(CC) $(CPPFLAGS) $(INC) -c $< -o $@ + +liball: + (cd third_party; make all) + +# clean: +# find . -iname "*~" -exec rm -f {} \; +# rm -f $(OBJ) schlierenCamera hsvCamera +# (cd lib; make clean) +# (cd test; make clean) diff --git a/Makefile.config b/Makefile.config @@ -0,0 +1,45 @@ +config ?= release +bs ?= 16 +align ?= 16 +omp ?= 1 +hdf ?= 1 +cubismz ?= 1 +prec ?= float + +INC = -Iinclude +LIB = -Llib + +CFLAGS = +CPPFLAGS = -std=c++11 + +ifeq "$(omp)" "1" + CFLAGS += -fopenmp + CPPFLAGS += -fopenmp -D_USE_OMP_ +endif + +ifeq "$(hdf)" "1" + INC += -I/opt/hdf5_openmpi/include + LIB += -lhdf5 + CPPFLAGS += -D_USE_HDF_ +endif + +ifeq "$(cubismz)" "1" + INC += -Ithird_party/CubismZ/CubismApps/Compressor/source + LIB += -lCubismZ + CPPFLAGS += -D_USE_CUBISMZ_ +endif + +ifeq "$(prec)" "float" + CPPFLAGS += -D_SP_ +endif + +ifneq "$(config)" "release" + CFLAGS = -g -O0 + CPPFLAGS = -g -O0 +else + CFLAGS = -O3 -DNDEBUG + CPPFLAGS = -O3 -DNDEBUG +endif + +LIB += -lm -lz -ldl +CPPFLAGS += -Wall -Wextra -Wno-deprecated -D_ALIGNBYTES_=$(align) -D_BLOCKSIZE_=$(bs) diff --git a/include/Types.h b/include/Types.h @@ -0,0 +1,64 @@ +// File : Types.h +// Date : Tue Apr 26 14:49:41 2016 +// Author : Fabian Wermelinger +// Description: Various types +// Copyright 2016 ETH Zurich. All Rights Reserved. +#ifndef TYPES_H_QATFIWCK +#define TYPES_H_QATFIWCK + +#include <cassert> +#include "common.h" +// #ifdef _USE_OMP_ +// #include <omp.h> +// #endif /* _USE_OMP_ */ + + +template <int _SX, int _EX, int _SY, int _EY> +class Slice2D +{ + int m_width, m_height, m_N; + Real * const m_data; + +public: + Slice2D() : m_width(0), m_height(0), m_N(0), m_data(nullptr) {} + Slice2D(const int width, const int height) : m_width(width), m_height(height), m_N((width+_EX-_SX)*(height+_EY-_SY)) + { + m_data = new Real[m_N]; +#pragma omp parallel for + for (int i = 0; i < m_N; ++i) + m_data[i] = 0.0; + } + virtual ~Slice2D() { delete [] m_data; } + + inline Real operator()(const int ix, const int iy) const + { + assert(ix >= _SX); assert(ix < m_width+_EX); + assert(iy >= _SY); assert(iy < m_height+_EY); + + return m_data[(iy-_SY)*m_width + (ix-_SX)]; + } + + inline Real& operator()(const int ix, const int iy) + { + assert(ix >= _SX); assert(ix < m_width+_EX); + assert(iy >= _SY); assert(iy < m_height+_EY); + + return m_data[(iy-_SY)*m_width + (ix-_SX)]; + } + + inline void resize(const int width, const int height) + { + m_width = width; + m_height = height; + m_N = (width+_EX-_SX)*(height+_EY-_SY); + if (m_data) delete [] m_data; + m_data = new Real[m_N]; +#pragma omp parallel for + for (int i = 0; i < m_N; ++i) + m_data[i] = 0.0; + } + inline int width() const { return m_width; } + inline int height() const { return m_height; } +}; + +#endif /* TYPES_H_QATFIWCK */ diff --git a/include/common.h b/include/common.h @@ -0,0 +1,23 @@ +// File : common.h +// Date : Tue Apr 26 22:13:00 2016 +// Author : Fabian Wermelinger +// Description: Common stuff +// Copyright 2016 ETH Zurich. All Rights Reserved. +#ifndef COMMON_H_13EQ6YAI +#define COMMON_H_13EQ6YAI + +#ifdef _SP_ +typedef float Real; +#else +typedef double Real; +#endif + +#ifdef _USE_HDF_ +#ifdef _SP_ +#define HDF_PRECISION H5T_NATIVE_FLOAT +#else +#define HDF_PRECISION H5T_NATIVE_DOUBLE +#endif +#endif /* _USE_HDF_ */ + +#endif /* COMMON_H_13EQ6YAI */ diff --git a/lib/.gitignore b/lib/.gitignore @@ -0,0 +1 @@ +*.a diff --git a/src/PhotoPNG.h b/src/PhotoPNG.h @@ -0,0 +1,75 @@ +// File : PhotoPNG.h +// Date : Tue Apr 26 14:46:18 2016 +// Author : Fabian Wermelinger +// Description: PNG Photos +// Copyright 2016 ETH Zurich. All Rights Reserved. +#ifndef PHOTOPNG_H_7DZT9TLW +#define PHOTOPNG_H_7DZT9TLW + +#include "PhotoPaper.h" +#include "pngwriter.h" + +class PNG_MONOCHROME : public PNG_HSV +{ +public: + PNG_MONOCHROME(const std::string filename="mono.png", const double saturation=1.0, const double value=1.0, const double bg=1.0) : + PNG_HSV(filename, saturation, value, bg) + { } + + inline void set_pixel(const int x, const int y, const double phi) + { + if (m_png) m_png->plot(x+1, y+1, phi, phi, phi); + } +}; + +class PNG_RGB : public PNG_HSV +{ + PNG_RGB(const std::string filename="rgb.png", const double saturation=1.0, const double value=1.0, const double bg=1.0) : + PNG_HSV(filename, saturation, value, bg) + { } + + inline void set_pixel(const int x, const int y, const double R, const double G, const double B) + { + if (m_png) m_png->plot(x+1, y+1, R, G, B); + } +}; + +class PNG_HSV : public PhotoPaper +{ +public: + PNG_HSV(const std::string filename="hsv.png", const double saturation=1.0, const double value=1.0, const double bg=1.0); + virtual ~PNG_HSV() + { + if (m_png) m_png->close(); + _dispose(); + } + + void make_new(const int width, const int height); + inline void set_pixel(const int x, const int y, const double phi) + { + const double hue = 2./3. * (1.0 - phi); + if (m_png) m_png->plotHSV(x+1, y+1, hue, m_saturation, m_value); + } + inline void set_description(const char* const desc) { m_description = desc; } + inline void write() + { + if (m_png) + { + m_png->settext(m_title.c_str(), m_author.c_str(), m_description.c_str(), m_software.c_str()); + m_png->write_png(); + } + } + inline void set_filename(const std::string new_name) { m_filename=new_name; m_title=new_name; } + inline std::string suffix() const { return std::string(".png"); } + +protected: + pngwriter* m_png; + int m_width, m_height; + double m_saturation, m_value, m_background; + std::string m_filename; + std::string m_title, m_author, m_description, m_software; + + inline void _dispose() { delete m_png; m_png=0; } +}; + +#endif /* PHOTOPNG_H_7DZT9TLW */ diff --git a/src/PhotoPaper.h b/src/PhotoPaper.h @@ -0,0 +1,26 @@ +// File : PhotoPaper.h +// Date : Tue Apr 26 14:45:19 2016 +// Author : Fabian Wermelinger +// Description: Photo Paper Base +// Copyright 2016 ETH Zurich. All Rights Reserved. +#ifndef PHOTOPAPER_H_B0K8P9TO +#define PHOTOPAPER_H_B0K8P9TO + +#include "Types.h" + +class PhotoPaper +{ +protected: + int m_width, m_height; + +public: + PhotoPaper(const int width=256, const int height=256) : m_width(width), m_height(height) {}; + virtual ~PhotoPaper() {}; + + virtual void make_new(const int width, const int height) = 0; + virtual void set_pixel(const int x, const int y, const double phi) = 0; + virtual inline std::string suffix() const = 0; + virtual void set_description(const char* const desc) { } +}; + +#endif /* PHOTOPAPER_H_B0K8P9TO */ diff --git a/src/Polaroid.cpp b/src/Polaroid.cpp @@ -0,0 +1,196 @@ +// File : Polaroid.cpp +// Date : Tue Apr 26 22:14:08 2016 +// Author : Fabian Wermelinger +// Description: Polaroid Implementation +// Copyright 2016 ETH Zurich. All Rights Reserved. +#include <cmath> +#include <string> +#include <sstream> +#include <cstdlib> +#ifdef _USE_HDF_ +#include <hdf5.h> +#endif /* _USE_HDF_ */ + +#include "Polaroid.h" +#ifdef _USE_CUBISMZ_ +#include "Reader_WaveletCompression.h" +#endif /* _USE_CUBISMZ_ */ + +using namespace std; + +#define ID3(ix, iy, iz, NX, NY) ((ix) + (NX) * ((iy) + (NY) * (iz))) + +void Polaroid::load_hdf5(const char* filename, const double fraction, const int dir, const int channel) +{ +#ifdef _USE_HDF_ + /* open data */ + hid_t file_id, dataset_id, dataspace_id, file_dataspace_id; + hsize_t* dims; + hssize_t num_elem; + int rank, ndims, NCH; + int maxDim[3]; + Real* data; + + file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT); + dataset_id = H5Dopen(file_id, "/data", H5P_DEFAULT); + file_dataspace_id = H5Dget_space(dataset_id); + rank = H5Sget_simple_extent_ndims(file_dataspace_id); + dims = new hsize_t[rank]; + ndims = H5Sget_simple_extent_dims(file_dataspace_id, dims, NULL); + num_elem = H5Sget_simple_extent_npoints(file_dataspace_id); + data = new Real[num_elem]; + maxDim[2] = dims[0]; + maxDim[1] = dims[1]; + maxDim[0] = dims[2]; + NCH = dims[3]; + dataspace_id = H5Screate_simple(rank, dims, NULL); + int status = H5Dread(dataset_id, HDF_PRECISION, dataspace_id, file_dataspace_id, H5P_DEFAULT, data); + + /* release stuff */ + delete [] dims; + status = H5Dclose(dataset_id); + status = H5Sclose(dataspace_id); + status = H5Sclose(file_dataspace_id); + status = H5Fclose(file_id); + + /* extract plane */ + if (0 == dir) // y-z plane + { + const int fixed = static_cast<int>(maxDim[0]*fraction); + width = maxDim[1]; + height = maxDim[2]; + m_data.resize(width, height); + for (int h=0; h < height; ++h) + for (int w=0; w < width; ++w) + m_data(w,h) = data[channel + NCH * ID3(fixed,w,h,maxDim[0], maxDim[1])]; + } + else if (1 == dir) // x-z plane + { + const int fixed = static_cast<int>(maxDim[1]*fraction); + width = maxDim[0]; + height = maxDim[2]; + m_data.resize(width, height); + for (int h=0; h < height; ++h) + for (int w=0; w < width; ++w) + m_data(w,h) = data[channel + NCH * ID3(w,fixed,h,maxDim[0], maxDim[1])]; + } + else if (2 == dir) // x-y plane + { + const int fixed = static_cast<int>(maxDim[2]*fraction); + width = maxDim[0]; + height = maxDim[1]; + m_data.resize(width, height); + for (int h=0; h < height; ++h) + for (int w=0; w < width; ++w) + m_data(w,h) = data[channel + NCH * ID3(w,h,fixed,maxDim[0], maxDim[1])]; + } + else + { + fprintf(stderr, "ERROR: Direction '%d' unsupported.", dir); + abort(); + } + + delete [] data; + m_loaded = true; + +#else + fprintf(stderr, "WARNING: Executable was compiled without HDF support...\n"); +#endif /* _USE_HDF_ */ +} + +void Polaroid::load_wavelet(const char* filename, const double fraction, const int dir, const int channel, const bool doswapping, const int wtype) +{ +#ifdef _USE_CUBISMZ_ + const string fname(filename); + Reader_WaveletCompression myreader(fname, doswapping, wtype); + myreader.load_file(); + const int NBX = myreader.xblocks(); + const int NBY = myreader.yblocks(); + const int NBZ = myreader.zblocks(); + const int maxDim[3] = {NBX*_BLOCKSIZE_, NBY*_BLOCKSIZE_, NBZ*_BLOCKSIZE_}; + + static Real blockdata[_BLOCKSIZE_][_BLOCKSIZE_][_BLOCKSIZE_]; + + /* extract plane */ + if (0 == dir) // y-z plane + { + const int fixed = static_cast<int>(maxDim[0]*fraction); + width = maxDim[1]; + height = maxDim[2]; + m_data.resize(width, height); + + const int fixedBID = fixed/_BLOCKSIZE_; + const int BlocalID = fixed % _BLOCKSIZE_; + for (int iz=0; iz < NBZ; ++iz) + for (int iy=0; iy < NBY; ++iy) + { + const double zratio = myreader.load_block2(fixedBID, iy, iz, blockdata); + for (int z=0; z < _BLOCKSIZE_; ++z) + for (int y=0; y < _BLOCKSIZE_; ++y) + m_data(iy*_BLOCKSIZE_+y, iz*_BLOCKSIZE_+z) = blockdata[z][y][BlocalID]; + } + } + else if (1 == dir) // x-z plane + { + const int fixed = static_cast<int>(maxDim[1]*fraction); + width = maxDim[0]; + height = maxDim[2]; + m_data.resize(width, height); + + const int fixedBID = fixed/_BLOCKSIZE_; + const int BlocalID = fixed % _BLOCKSIZE_; + for (int iz=0; iz < NBZ; ++iz) + for (int ix=0; ix < NBX; ++ix) + { + const double zratio = myreader.load_block2(ix, fixedBID, iz, blockdata); + for (int z=0; z < _BLOCKSIZE_; ++z) + for (int x=0; x < _BLOCKSIZE_; ++x) + m_data(ix*_BLOCKSIZE_+x, iz*_BLOCKSIZE_+z) = blockdata[z][BlocalID][x]; + } + } + else if (2 == dir) // x-y plane + { + const int fixed = static_cast<int>(maxDim[2]*fraction); + width = maxDim[0]; + height = maxDim[1]; + m_data.resize(width, height); + + const int fixedBID = fixed/_BLOCKSIZE_; + const int BlocalID = fixed % _BLOCKSIZE_; + for (int iy=0; iy < NBY; ++iy) + for (int ix=0; ix < NBX; ++ix) + { + const double zratio = myreader.load_block2(ix, iy, fixedBID, blockdata); + for (int y=0; y < _BLOCKSIZE_; ++y) + for (int x=0; x < _BLOCKSIZE_; ++x) + m_data(ix*_BLOCKSIZE_+x, iy*_BLOCKSIZE_+y) = blockdata[BlocalID][y][x]; + } + } + else + { + fprintf(stderr, "ERROR: Direction '%d' unsupported.", dir); + abort(); + } + + m_loaded = true; +#else + fprintf(stderr, "WARNING: Executable was compiled without wavelet compressor support...\n"); +#endif /* _USE_CUBISMZ_ */ +} + +void Polaroid::capture(PhotoPaper* const paper) +{ + if (m_loaded) + { + paper->make_new(m_data.width(), m_data.height()); + + // set description + string desc("2D Slice Data"); + paper->set_description(desc.c_str()); + + // put pixel + for (int h=0; h < m_data.height(); ++h) + for (int w=0; w < m_data.width(); ++w) + paper->set_pixel(w, h, m_data(w,h)); + } +} diff --git a/src/Polaroid.h b/src/Polaroid.h @@ -0,0 +1,32 @@ +// File : Polaroid.h +// Date : Tue Apr 26 14:41:37 2016 +// Author : Fabian Wermelinger +// Description: Polaroid Camera base +// Copyright 2016 ETH Zurich. All Rights Reserved. +#ifndef POLAROID_H_HXFL9YPG +#define POLAROID_H_HXFL9YPG + +#include "Types.h" +#include "PhotoPaper.h" + +class Polaroid +{ +protected: + Slice2D<0,0,-2,2> m_data; + + // Cartridge inserted? + bool m_loaded; + +public: + Polaroid() : m_loaded(false) { } + + // data loader + virtual void load_hdf5(const char* filename, const double fraction, const int dir, const int channel=0); + virtual void load_wavelet(const char* filename, const double fraction, const int dir, const int channel=0, const bool doswapping=false, const int wtype=1); + + // capture image + inline bool check_scene() const { return m_loaded; } + virtual void capture(PhotoPaper* const paper); +}; + +#endif /* POLAROID_H_HXFL9YPG */ diff --git a/third_party/Makefile b/third_party/Makefile @@ -0,0 +1,32 @@ +include ../Makefile.config +include ./CubismZ/CubismApps/Makefile.config + +CubismZ_SRC = CubismZ/CubismApps/Compressor/source/WaveletCompressor.cpp +PNG_SRC = $(wildcard libpng-1.2.51/*.c) +PNGWRTR_SRC = $(wildcard pngwriter-0.5.4/*.cc) + +INC += -Ilibpng-1.2.51 + +OBJLib1 = ${CubismZ_SRC:.cpp=.o} +OBJLib2 = ${PNG_SRC:.c=.o} +OBJLib3 = ${PNGWRTR_SRC:.cc=.o} + +all: libCubismZ.a libpng.a + +libCubismZ.a: $(OBJLib1) + ar rcs ../lib/libCubismZ.a $(OBJLib1) + +libpng.a: $(OBJLib2) $(OBJLib3) + ar rcs ../lib/libpng.a $(OBJLib2) $(OBJLib3) + +.c.o: + gcc -c $(CFLAGS) -o $@ $< + +.cpp.o: + g++ -c $(CPPFLAGS) $(INC) -o $@ $< + +.cc.o: + g++ -c $(CPPFLAGS) $(INC) -o $@ $< + +clean: + rm -rf $(OBJLib1) $(OBJLib2) $(OBJLib3) ../lib/libpng.a ../lib/libCubismZ.a