commit 5807b7da0373d7158594a8917ca31b2a2a0153a9
parent 930300bb66eaf35a6a8a94b9202afe5a3769a86c
Author: Fabian Wermelinger <fabianw@mavt.ethz.ch>
Date: Thu, 28 Apr 2016 12:23:34 +0200
added apps
Diffstat:
20 files changed, 938 insertions(+), 87 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,17 +1,30 @@
include ./Makefile.config
-CC = mpic++
+CC = g++
HDR = $(wildcard src/*.h)
SRC = $(wildcard src/*.cpp)
OBJ = ${SRC:.cpp=.o}
-polaroidCamera: Polaroid
+INC += -Iapps/polaroidCamera
+INC += -Iapps
+APPSRC = $(wildcard apps/polaroidCamera/*.cpp)
+APPSRC += $(wildcard apps/*.cpp)
+APPPOBJ = ${APPSRC:.cpp=.o}
-Polaroid: $(HDR) $(OBJ) third_party
+
+polaroidCamera: third_party Polaroid $(APPOBJ)
+ $(CC) $(CPPFLAGS) $(INC) -o bin/polaroidCamera $(APPSRC) $(LIB) -lpng -lPolaroid
+
+Polaroid: third_party $(HDR) $(OBJ)
ar rcs lib/libPolaroid.a $(OBJ)
+third_party: FORCE
+ $(MAKE) -C third_party all
+
+FORCE:
+
# schlierenCamera: all schlierenCamera.cpp
# $(CC) $(CPPFLAGS) $(INC) -o schlierenCamera schlierenCamera.cpp $(OBJ) $(LIB) -lz -lpng -lhdf5 -lWaveletCompressor
@@ -24,11 +37,9 @@ Polaroid: $(HDR) $(OBJ) third_party
%.o: %.cpp
g++ $(CPPFLAGS) $(INC) -c $< -o $@
-third_party:
- (cd third_party; make all)
-
clean:
find . -iname "*~" -exec rm -f {} \;
rm -f $(OBJ)
rm -f lib/libPolaroid.a
- (cd third_party; make clean)
+ rm -f bin/polaroidCamera
+ $(MAKE) -C third_party clean
diff --git a/Makefile.config b/Makefile.config
@@ -1,12 +1,12 @@
config ?= release
bs ?= 16
align ?= 16
-omp ?= 0
+omp ?= 1
hdf ?= 1
cubismz ?= 1
prec ?= float
-INC = -Iinclude
+INC = -Iinclude -Ithird_party/pngwriter-0.5.4
LIB = -Llib
CFLAGS =
@@ -18,7 +18,7 @@ ifeq "$(omp)" "1"
endif
ifeq "$(hdf)" "1"
- INC += -I/opt/hdf5_openmpi/include
+ INC += -I/usr/local/include
LIB += -lhdf5
CPPFLAGS += -D_USE_HDF_
endif
@@ -30,7 +30,7 @@ ifeq "$(cubismz)" "1"
endif
ifeq "$(prec)" "float"
- CPPFLAGS += -D_SP_
+ CPPFLAGS += -D_FLOAT_PRECISION_ -D_SP_COMP_
endif
ifneq "$(config)" "release"
diff --git a/apps/OrganizerOMP.cpp b/apps/OrganizerOMP.cpp
@@ -0,0 +1,60 @@
+// File : OrganizerOMP.cpp
+// Date : Thu Apr 28 10:59:03 2016
+// Author : Fabian Wermelinger
+// Description: OpenMP Organizer Implementation
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#include <string>
+#include <iostream>
+#include <cstdio>
+#include <cstdlib>
+#include "OrganizerOMP.h"
+
+using namespace std;
+
+OrganizerOMP::OrganizerOMP(const int argc, char ** const argv) : m_nscenes(0), m_scenes(nullptr), m_argc(1)
+{
+ // get scenes
+ bool bfoundScenes = false;
+ for (int i=1; i < argc; ++i)
+ {
+ const string key(argv[i]);
+ if (key == "-scenes")
+ {
+ m_scenes = (argv + (i+1));
+ m_nscenes = argc - (i+1);
+ bfoundScenes = true;
+ break;
+ }
+ ++m_argc;
+ }
+ if (!bfoundScenes)
+ {
+ // Define input scenes (=input files) at the end of the argument list
+ // by using the option "-scenes". You can use globbing here if there
+ // are many scenes.
+ cerr << "ERROR: No input scenes given. Abort..." << endl;
+ cerr << " : (Note: -scenes must be the last argument, followed by [list of] input files)" << endl;
+ abort();
+ }
+}
+
+vector<char*> OrganizerOMP::split_work() const
+{
+ const int myID = tid();
+ const int nthreads = size();
+ const int myshare = m_nscenes/nthreads;
+ const int rem = m_nscenes - nthreads * myshare;
+ vector<char*> myscenes;
+
+ for (int i=0; i < myshare; ++i) // try to distribute work equally
+ myscenes.push_back(m_scenes[i*nthreads + myID]);
+
+ if (myID < rem)
+ myscenes.push_back(m_scenes[myshare*nthreads + myID]);
+
+#pragma omp critical
+ {
+ printf("[Thread %d/%d: Load = %d scene(s), start @ %s]\n", myID, nthreads, myscenes.size(), myscenes.front());
+ }
+ return myscenes;
+}
diff --git a/apps/OrganizerOMP.h b/apps/OrganizerOMP.h
@@ -0,0 +1,63 @@
+// File : OrganizerOMP.h
+// Date : Thu Apr 28 09:53:58 2016
+// Author : Fabian Wermelinger
+// Description: OpenMP Organizer
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#ifndef ORGANIZEROMP_H_8HFBYG90
+#define ORGANIZEROMP_H_8HFBYG90
+
+#include <vector>
+#ifdef _USE_OMP_
+#include <omp.h>
+#endif /* _USE_OMP_ */
+
+
+class OrganizerOMP
+{
+private:
+ int m_nscenes;
+ char** m_scenes;
+ int m_argc;
+
+public:
+ OrganizerOMP(const int argc, char ** const argv);
+
+ static int max_size()
+ {
+#ifdef _USE_OMP_
+ return omp_get_max_threads();
+#else
+ return 1;
+#endif /* _USE_OMP_ */
+ }
+
+ static void set_size(const int nthreads)
+ {
+#ifdef _USE_OMP_
+ return omp_set_num_threads(nthreads);
+#endif /* _USE_OMP_ */
+ }
+
+ inline int size() const
+ {
+#ifdef _USE_OMP_
+ return omp_get_num_threads();
+#else
+ return 1;
+#endif /* _USE_OMP_ */
+ }
+
+ inline int tid() const
+ {
+#ifdef _USE_OMP_
+ return omp_get_thread_num();
+#else
+ return 0;
+#endif /* _USE_OMP_ */
+ }
+
+ std::vector<char*> split_work() const;
+ inline int argc() const { return m_argc; }
+};
+
+#endif /* ORGANIZEROMP_H_8HFBYG90 */
diff --git a/apps/polaroidCamera/Cartridges.h b/apps/polaroidCamera/Cartridges.h
@@ -0,0 +1,12 @@
+// File : Cartridges.h
+// Date : Wed Apr 27 21:37:25 2016
+// Author : Fabian Wermelinger
+// Description: Cartridge Collection
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#ifndef CARTRIDGES_H_LTWKNANR
+#define CARTRIDGES_H_LTWKNANR
+
+#include "TransmissionCartridge.h"
+#include "NormalizerCartridge.h"
+
+#endif /* CARTRIDGES_H_LTWKNANR */
diff --git a/apps/polaroidCamera/NormalizerCartridge.h b/apps/polaroidCamera/NormalizerCartridge.h
@@ -0,0 +1,44 @@
+// File : NormalizerCartridge.h
+// Date : Thu Apr 28 09:32:20 2016
+// Author : Fabian Wermelinger
+// Description: Data Normalization Cartridge
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#ifndef NORMALIZERCARTRIDGE_H_ONAUDSVX
+#define NORMALIZERCARTRIDGE_H_ONAUDSVX
+
+#include "Cartridge.h"
+
+class NormalizerCartridge : public Cartridge
+{
+public:
+ NormalizerCartridge(ArgumentParser& parser) : Cartridge(parser) {}
+
+ virtual void capture(PhotoPaper& photo, Slice& data)
+ {
+ photo.resize(data.width(), data.height());
+
+ // set description
+ string desc("2D Normalized Slice Data");
+ photo.set_description(desc.c_str());
+
+ // compute min/max
+ Real data_min = data(0,0);
+ Real data_max = data(0,0);
+ for (int h=0; h < data.height(); ++h)
+ for (int w=0; w < data.width(); ++w)
+ {
+ data_min = min(data_min, data(w,h));
+ data_max = max(data_max, data(w,h));
+ }
+ const Real data_normInv = 1.0 / (data_max - data_min);
+
+ // compute pixel
+ for (int h=0; h < data.height(); ++h)
+ for (int w=0; w < data.width(); ++w)
+ photo.set_pixel(w, h, (data(w,h) - data_min) * data_normInv);
+
+ photo.write();
+ }
+};
+
+#endif /* NORMALIZERCARTRIDGE_H_ONAUDSVX */
diff --git a/apps/polaroidCamera/TransmissionCartridge.h b/apps/polaroidCamera/TransmissionCartridge.h
@@ -0,0 +1,33 @@
+// File : TransmissionCartridge.h
+// Date : Thu Apr 28 09:29:22 2016
+// Author : Fabian Wermelinger
+// Description: Simple Data Transmission Cartridge
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#ifndef TRANSMISSIONCARTRIDGE_H_Z4VDKHDO
+#define TRANSMISSIONCARTRIDGE_H_Z4VDKHDO
+
+#include "Cartridge.h"
+
+class TransmissionCartridge : public Cartridge
+{
+public:
+ TransmissionCartridge(ArgumentParser& parser) : Cartridge(parser) {}
+
+ virtual void capture(PhotoPaper& photo, Slice& data)
+ {
+ photo.resize(data.width(), data.height());
+
+ // set description
+ string desc("2D Slice Data Propagation");
+ photo.set_description(desc.c_str());
+
+ // put pixel
+ for (int h=0; h < data.height(); ++h)
+ for (int w=0; w < data.width(); ++w)
+ photo.set_pixel(w, h, data(w,h));
+
+ photo.write();
+ }
+};
+
+#endif /* TRANSMISSIONCARTRIDGE_H_Z4VDKHDO */
diff --git a/apps/polaroidCamera/polaroidCameraMPI.cpp b/apps/polaroidCamera/polaroidCameraMPI.cpp
@@ -0,0 +1,40 @@
+// File : polaroidCameraMPI.cpp
+// Date : Wed Apr 27 14:40:05 2016
+// Author : Fabian Wermelinger
+// Description: Polaroid Cam app
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#include <iostream>
+#include <vector>
+#ifdef _USE_OMP_
+#include <omp.h>
+#endif /* _USE_OMP_ */
+
+#include "OrganizerOMP.h"
+#include "ArgumentParser.h"
+#include "Polaroid.h"
+#include "Cartridges.h"
+#include "PhotoFormats.h"
+
+using namespace std;
+
+int main(int argc, char* argv[])
+{
+#pragma omp parallel
+ {
+ OrganizerOMP threads(argc, argv);
+
+ ArgumentParser myparser(threads.argc(), (const char**)argv);
+ myparser.print_args();
+
+ vector<char*> myscenes = threads.split_work();
+
+ Polaroid cam;
+ NormalizerCartridge transmission(myparser);
+ // PhotoHDF5 photo("hello");
+ PNG_MONO photo("hello");
+ cam.load_hdf5(myscenes[0], 0.5, 2, 0);
+ cam.capture(transmission, photo);
+ }
+
+ return 0;
+}
diff --git a/include/ArgumentParser.h b/include/ArgumentParser.h
@@ -0,0 +1,375 @@
+/*
+ * ArgumentParser.h
+ * Cubism
+ *
+ * This argument parser assumes that all arguments are optional ie, each of the argument names is preceded by a '-'
+ * all arguments are however NOT optional to avoid a mess with default values and returned values when not found!
+ *
+ * More converter could be required:
+ * add as needed
+ * TypeName as{TypeName}() in Value
+ *
+ * Created by Christian Conti on 6/7/10.
+ * Copyright 2010 ETH Zurich. All rights reserved.
+ *
+ */
+
+#pragma once
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <map>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <fstream>
+#include <limits>
+
+
+using namespace std;
+
+class Value
+{
+private:
+ string content;
+
+public:
+
+ Value() : content("") {}
+
+ Value(string content_) : content(content_) { /*printf("%s\n",content.c_str());*/ }
+
+ double asDouble(double def=0)
+ {
+ if (content == "")
+ {
+ ostringstream sbuf;
+ sbuf << def;
+ content = sbuf.str();
+ }
+ return (double) atof(content.c_str());
+ }
+
+ int asInt(int def=0)
+ {
+ if (content == "")
+ {
+ ostringstream sbuf;
+ sbuf << def;
+ content = sbuf.str();
+ }
+ return atoi(content.c_str());
+ }
+
+ bool asBool(bool def=false)
+ {
+ if (content == "")
+ {
+ if (def) content = "true";
+ else content = "false";
+ }
+ if (content == "0") return false;
+ if (content == "false") return false;
+
+ return true;
+ }
+
+ string asString(string def="")
+ {
+ if (content == "") content = def;
+
+ return content;
+ }
+};
+
+class CommandlineParser
+{
+private:
+ const int iArgC;
+ const char** vArgV;
+ bool bStrictMode, bVerbose;
+
+protected:
+ map<string,Value> mapArguments;
+
+public:
+
+ Value& operator()(const string arg)
+ {
+ if (bStrictMode)
+ {
+ map<string,Value>::const_iterator it = mapArguments.find(arg);
+
+ if (it == mapArguments.end())
+ {
+ printf("Runtime option NOT SPECIFIED! ABORTING! name: %s\n",arg.data());
+ abort();
+ }
+ }
+
+ if (bVerbose) printf("%s is %s\n", arg.data(), mapArguments[arg].asString().data());
+ return mapArguments[arg];
+ }
+
+ bool check(const string arg) const
+ {
+ return mapArguments.find(arg) != mapArguments.end();
+ }
+
+ CommandlineParser(const int argc, const char ** argv) : mapArguments(), iArgC(argc), vArgV(argv), bStrictMode(false), bVerbose(true)
+ {
+ for (int i=1; i<argc; i++)
+ if (argv[i][0] == '-')
+ {
+ string values = "";
+ int itemCount = 0;
+
+ for (int j=i+1; j<argc; j++)
+ if (argv[j][0] == '-')
+ break;
+ else
+ {
+ if (strcmp(values.c_str(), ""))
+ values += ' ';
+
+ values += argv[j];
+ itemCount++;
+ }
+
+ if (itemCount == 0)
+ values = "true";
+
+ mapArguments[argv[i]] = Value(values);
+ i += itemCount;
+ }
+
+ mute();
+ //printf("found %ld arguments of %d\n",mapArguments.size(),argc);
+ }
+
+ int getargc() const { return iArgC; }
+
+ const char** getargv() const { return vArgV; }
+
+ void set_strict_mode()
+ {
+ bStrictMode = true;
+ }
+
+ void unset_strict_mode()
+ {
+ bStrictMode = false;
+ }
+
+ void mute()
+ {
+ bVerbose = false;
+ }
+
+ void loud()
+ {
+ bVerbose = true;
+ }
+
+ void save_options(string path=".")
+ {
+ string options;
+ for(map<string,Value>::iterator it=mapArguments.begin(); it!=mapArguments.end(); it++)
+ {
+ options+= it->first + " " + it->second.asString() + " ";
+ }
+ string filepath = (path + "/" + string("argumentparser.log"));
+ FILE * f = fopen(filepath.data(), "a");
+ if (f == NULL)
+ {
+ printf("impossible to write %s.\n", filepath.data());
+ return;
+ }
+ fprintf(f, "%s\n", options.data());
+ fclose(f);
+ }
+
+ void print_args()
+ {
+ for(map<string,Value>::iterator it=mapArguments.begin(); it!=mapArguments.end(); it++)
+ {
+ std::cout.width(50);
+ std::cout.fill('.');
+ std::cout << std::left << it->first;
+ std::cout << ": " << it->second.asString() << std::endl;
+ }
+ }
+};
+
+
+class ArgumentParser: public CommandlineParser
+{
+ typedef std::map<std::string, Value> ArgMap;
+ typedef std::map<std::string, Value*> pArgMap;
+ typedef std::map<std::string, ArgMap* > FileMap;
+
+ // keep a reference form option origin
+ ArgMap from_commandline;
+ FileMap from_files;
+ pArgMap from_code;
+
+ // helper
+ void _ignoreComments(std::ifstream& stream, const char commentChar = '#')
+ {
+ stream >> std::ws;
+ int nextchar = stream.peek();
+ while (nextchar == commentChar)
+ {
+ stream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+ stream >> std::ws;
+ nextchar = stream.peek();
+ }
+ }
+
+ bool _existKey(std::string& key) const
+ {
+ const std::string og_key = key;
+ bool bExist = true;
+
+ // look for both possible keys (i.e. with leading "-" and without)
+ ArgMap::const_iterator it = mapArguments.find(key);
+ if (it == mapArguments.end())
+ {
+ if (key[0] == '-') key = key.erase(0, 1);
+ else key = "-" + key;
+ it = mapArguments.find(key);
+ if (it == mapArguments.end())
+ {
+ key = og_key;
+ bExist = false;
+ }
+ }
+ return bExist;
+ }
+
+ inline std::string _stripKey(std::string key) const
+ {
+ if (key[0] == '-') key = key.erase(0, 1);
+ return key;
+ }
+
+
+public:
+ ArgumentParser(const int _argc, const char ** _argv):
+ CommandlineParser(_argc, _argv) { from_commandline = mapArguments; }
+
+ virtual ~ArgumentParser()
+ {
+ for (FileMap::iterator it = from_files.begin(); it != from_files.end(); it++)
+ delete it->second;
+ }
+
+ void readFile(const std::string filepath)
+ {
+ from_files[filepath] = new ArgMap;
+ ArgMap& myFMap = *(from_files[filepath]);
+
+ std::ifstream confFile(filepath.c_str());
+ if (confFile.is_open())
+ {
+ // read (key value) pairs from input file, ignore comments
+ // beginning with "#"
+ std::string key, val;
+ while (!confFile.eof())
+ {
+ _ignoreComments(confFile);
+ confFile >> key >> val;
+ if (_existKey(key)) continue;
+ std::pair<string, Value> item(key, Value(val));
+ mapArguments.insert(item); // add to parent container
+ myFMap.insert(item); // add to private container
+ }
+ }
+ }
+
+ Value& operator()(std::string key)
+ {
+ const bool bDefaultInCode = !_existKey(key);
+ Value& retval = CommandlineParser::operator()(key);
+ if (bDefaultInCode) from_code[key] = &retval;
+ return retval;
+ }
+
+ inline bool check(std::string key) const { return _existKey(key); }
+ inline bool exist(std::string key) const { return _existKey(key); }
+
+ void print_args()
+ {
+ std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
+ std::cout << "* Summary:" << std::endl;
+ std::cout << "* Parameter read from command line: " << from_commandline.size() << std::endl;
+ size_t nFiles = 0;
+ size_t nFileParameter = 0;
+ for (FileMap::const_iterator it=from_files.begin(); it!=from_files.end(); ++it)
+ {
+ if (it->second->size() > 0)
+ {
+ ++nFiles;
+ nFileParameter += it->second->size();
+ }
+ }
+ std::cout << "* Parameter read from " << std::setw(3) << std::right << nFiles << " file(s): " << nFileParameter << std::endl;
+ std::cout << "* Parameter read from defaults in code: " << from_code.size() << std::endl;
+ std::cout << "* Total number of parameter read from all sources: " << mapArguments.size() << std::endl;
+ std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
+
+ // command line given arguments
+ if (!from_commandline.empty())
+ {
+ std::cout << "* Command Line:" << std::endl;
+ std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
+ for(ArgMap::iterator it=from_commandline.begin(); it!=from_commandline.end(); it++)
+ {
+ std::cout.width(50);
+ std::cout.fill('.');
+ std::cout << std::left << _stripKey(it->first);
+ std::cout << ": " << it->second.asString() << std::endl;
+ }
+ std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
+ }
+
+ // options read from input files
+ if (!from_files.empty())
+ {
+ for (FileMap::iterator itFile=from_files.begin(); itFile!=from_files.end(); itFile++)
+ {
+ if (!itFile->second->empty())
+ {
+ std::cout << "* File: " << itFile->first << std::endl;
+ std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
+ ArgMap& fileArgs = *(itFile->second);
+ for(ArgMap::iterator it=fileArgs.begin(); it!=fileArgs.end(); it++)
+ {
+ std::cout.width(50);
+ std::cout.fill('.');
+ std::cout << std::left << _stripKey(it->first);
+ std::cout << ": " << it->second.asString() << std::endl;
+ }
+ std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
+ }
+ }
+ }
+
+ // defaults defined in code
+ if (!from_code.empty())
+ {
+ std::cout << "* Defined in Code:" << std::endl;
+ std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
+ for(pArgMap::iterator it=from_code.begin(); it!=from_code.end(); it++)
+ {
+ std::cout.width(50);
+ std::cout.fill('.');
+ std::cout << std::left << _stripKey(it->first);
+ std::cout << ": " << it->second->asString() << std::endl;
+ }
+ std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl;
+ }
+ }
+};
diff --git a/include/Cartridge.h b/include/Cartridge.h
@@ -0,0 +1,25 @@
+// File : Cartridge.h
+// Date : Wed Apr 27 21:17:10 2016
+// Author : Fabian Wermelinger
+// Description: Simple Transmission Cartridge Module for Polaroid Camera
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#ifndef CARTRIDGE_H_IRUVKOCT
+#define CARTRIDGE_H_IRUVKOCT
+
+#include "ArgumentParser.h"
+#include "Types.h"
+#include "PhotoPaper.h"
+
+class Cartridge
+{
+protected:
+ ArgumentParser& m_parser;
+
+public:
+ Cartridge(ArgumentParser& parser) : m_parser(parser) {}
+ virtual ~Cartridge() {}
+
+ virtual void capture(PhotoPaper& photo, Slice& data) = 0;
+};
+
+#endif /* CARTRIDGE_H_IRUVKOCT */
diff --git a/include/PhotoFormats.h b/include/PhotoFormats.h
@@ -0,0 +1,13 @@
+// File : PhotoFormats.h
+// Date : Wed Apr 27 21:39:13 2016
+// Author : Fabian Wermelinger
+// Description: Photo Format Collection
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#ifndef PHOTOFORMATS_H_3IWQHPAU
+#define PHOTOFORMATS_H_3IWQHPAU
+
+#include "PhotoPaper.h"
+#include "PhotoHDF5.h"
+#include "PhotoPNG.h"
+
+#endif /* PHOTOFORMATS_H_3IWQHPAU */
diff --git a/include/PhotoHDF5.h b/include/PhotoHDF5.h
@@ -6,10 +6,12 @@
#ifndef PHOTOHDF5_H_VN6WHSEO
#define PHOTOHDF5_H_VN6WHSEO
+#ifdef _USE_HDF_
#include <hdf5.h>
#include <string>
#include "common.h"
+#include "Polaroid.h"
#include "PhotoPaper.h"
class PhotoHDF5 : public PhotoPaper
@@ -28,22 +30,31 @@ private:
hsize_t m_hdf5_offset[4];
// helper
+ void _open_hdf_file();
+ void _close_hdf_file();
void _dump_xmf() const;
public:
PhotoHDF5(const std::string filename="hdf5", const Real t=0) : PhotoPaper(0,0), m_fname(filename), m_description("data"), m_open(false), m_hdfraw(nullptr), m_time(t) {}
+ PhotoHDF5(const Polaroid& cam, const std::string filename="hdf5", const Real t=0) : PhotoPaper(0,0), m_fname(filename), m_description("data"), m_open(false), m_hdfraw(nullptr), m_time(t)
+ {
+ resize(cam.width(), cam.height());
+ }
PhotoHDF5(const int width, const int height, const std::string filename="hdf5", const Real t=0) : PhotoPaper(0,0), m_fname(filename), m_description("data"), m_open(false), m_hdfraw(nullptr), m_time(t)
{
- make_new(width,height);
+ resize(width,height);
}
- ~PhotoHDF5() { if (m_hdfraw) delete [] m_hdfraw; }
+ virtual ~PhotoHDF5() { if (m_hdfraw) delete [] m_hdfraw; }
- virtual void make_new(const int width, const int height);
+ virtual void make_new(const std::string name, const int width, const int height);
+ virtual void resize(const int width, const int height);
virtual void write();
virtual void set_pixel(const int x, const int y, const double phi);
virtual std::string suffix() const { return std::string(".h5"); }
virtual void set_description(const char* const desc) { m_description = std::string(desc); }
inline void set_time(const Real t) { m_time = t; }
+ inline void set_filename(const std::string new_name) { m_fname = new_name; }
};
+#endif /* _USE_HDF_ */
#endif /* PHOTOHDF5_H_VN6WHSEO */
diff --git a/include/PhotoPNG.h b/include/PhotoPNG.h
@@ -0,0 +1,95 @@
+// 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 "Polaroid.h"
+#include "PhotoPaper.h"
+#include "pngwriter.h"
+
+class PNG_HSV : public PhotoPaper
+{
+protected:
+ std::string m_fname;
+ std::string m_description;
+ bool m_open;
+ pngwriter* m_png;
+ double m_saturation, m_value, m_background;
+ std::string m_title, m_author, m_software;
+
+ // helper
+ inline void _default_info()
+ {
+ m_title = "Portable Network Graphics";
+ m_author = "Walt Disney";
+ m_software = "Polaroid++";
+ }
+ inline void _dispose() { delete m_png; m_png=nullptr; }
+
+public:
+
+ PNG_HSV(const std::string filename="hsv", const double saturation=1.0, const double value=1.0, const double bg=1.0) :
+ PhotoPaper(0,0), m_fname(filename), m_description("PNG HSV colorscheme"), m_open(false), m_png(nullptr),
+ m_saturation(saturation), m_value(value), m_background(bg)
+ {
+ _default_info();
+ }
+ PNG_HSV(const Polaroid& cam, const std::string filename="hsv", const double saturation=1.0, const double value=1.0, const double bg=1.0) :
+ PhotoPaper(0,0), m_fname(filename), m_description("PNG HSV colorscheme"), m_open(false), m_png(nullptr),
+ m_saturation(saturation), m_value(value), m_background(bg)
+ {
+ _default_info();
+ resize(cam.width(), cam.height());
+ }
+ PNG_HSV(const int width, const int height, const std::string filename="hsv", const double saturation=1.0, const double value=1.0, const double bg=1.0) :
+ PhotoPaper(0,0), m_fname(filename), m_description("PNG HSV colorscheme"), m_open(false), m_png(nullptr),
+ m_saturation(saturation), m_value(value), m_background(bg)
+ {
+ _default_info();
+ resize(width, height);
+ }
+
+ virtual ~PNG_HSV()
+ {
+ if (m_open)
+ {
+ m_png->close();
+ _dispose();
+ }
+ }
+
+ virtual void make_new(const std::string name, const int width, const int height);
+ virtual void resize(const int width, const int height);
+ virtual void write();
+ virtual void set_pixel(const int x, const int y, const double phi);
+ virtual std::string suffix() const { return std::string(".png"); }
+ virtual void set_description(const char* const desc) { m_description = desc; }
+};
+
+class PNG_MONO : public PNG_HSV
+{
+public:
+ PNG_MONO(const std::string filename="mono") : PNG_HSV(filename) { }
+ PNG_MONO(const Polaroid& cam, const std::string filename="mono") : PNG_HSV(cam, filename) { }
+ PNG_MONO(const int width, const int height, const std::string filename="mono") : PNG_HSV(width, height, filename) { }
+
+ virtual void set_pixel(const int x, const int y, const double phi);
+};
+
+class PNG_RGB : public PNG_HSV
+{
+ PNG_RGB(const std::string filename="rgb") : PNG_HSV(filename) { }
+ PNG_RGB(const Polaroid& cam, const std::string filename="rgb") : PNG_HSV(cam, filename) { }
+ PNG_RGB(const int width, const int height, const std::string filename="rgb") : PNG_HSV(width, height, filename) { }
+
+ inline void set_pixel(const int x, const int y, const double R, const double G, const double B)
+ {
+ if (m_open)
+ m_png->plot(x+1, y+1, R, G, B);
+ }
+};
+
+#endif /* PHOTOPNG_H_7DZT9TLW */
diff --git a/include/PhotoPaper.h b/include/PhotoPaper.h
@@ -6,6 +6,7 @@
#ifndef PHOTOPAPER_H_B0K8P9TO
#define PHOTOPAPER_H_B0K8P9TO
+#include <string>
#include "Types.h"
class PhotoPaper
@@ -17,7 +18,8 @@ public:
PhotoPaper(const int width, const int height) : m_width(width), m_height(height) {};
virtual ~PhotoPaper() {};
- virtual void make_new(const int width, const int height) = 0;
+ virtual void make_new(const std::string name, const int width, const int height) = 0;
+ virtual void resize(const int width, const int height) = 0;
virtual void write() = 0;
virtual void set_pixel(const int x, const int y, const double phi) = 0;
virtual std::string suffix() const = 0;
diff --git a/include/Polaroid.h b/include/Polaroid.h
@@ -7,26 +7,36 @@
#define POLAROID_H_HXFL9YPG
#include "Types.h"
-#include "PhotoPaper.h"
+#include "Cartridge.h"
+
+class PhotoPaper;
class Polaroid
{
protected:
- Slice2D<0,0,-2,2> m_data;
+ Slice m_data;
// Cartridge inserted?
bool m_loaded;
public:
Polaroid() : m_loaded(false) { }
+ virtual ~Polaroid() {}
- // data loader
+ // scene 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
+ // capture scene
inline bool check_scene() const { return m_loaded; }
- virtual void capture(PhotoPaper* const paper);
+ inline void capture(Cartridge& cartridge, PhotoPaper& photo)
+ {
+ if (m_loaded)
+ cartridge.capture(photo, m_data);
+ }
+
+ inline int width() const { return m_data.width(); }
+ inline int height() const { return m_data.height(); }
};
#endif /* POLAROID_H_HXFL9YPG */
diff --git a/include/Types.h b/include/Types.h
@@ -8,23 +8,18 @@
#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;
+ Real* 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;
}
@@ -53,12 +48,16 @@ public:
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; }
+ // inline Real* const data() { return m_data; }
+ // inline const Real* const data() const { return m_data; }
};
+typedef Slice2D<0,0,-2,2> Slice;
+
#endif /* TYPES_H_QATFIWCK */
diff --git a/include/common.h b/include/common.h
@@ -6,14 +6,14 @@
#ifndef COMMON_H_13EQ6YAI
#define COMMON_H_13EQ6YAI
-#ifdef _SP_
+#ifdef _FLOAT_PRECISION_
typedef float Real;
#else
typedef double Real;
#endif
#ifdef _USE_HDF_
-#ifdef _SP_
+#ifdef _FLOAT_PRECISION_
#define HDF_PRECISION H5T_NATIVE_FLOAT
#else
#define HDF_PRECISION H5T_NATIVE_DOUBLE
diff --git a/src/PhotoHDF5.cpp b/src/PhotoHDF5.cpp
@@ -3,10 +3,32 @@
// Author : Fabian Wermelinger
// Description: HDF5 Photo Implementation
// Copyright 2016 ETH Zurich. All Rights Reserved.
+#ifdef _USE_HDF_
#include <cassert>
#include <cstdio>
#include "PhotoHDF5.h"
+void PhotoHDF5::_open_hdf_file()
+{
+ hsize_t tmp[4] = { 1, static_cast<hsize_t>(m_height), static_cast<hsize_t>(m_width), 1 };
+ for (int i = 0; i < 4; ++i)
+ {
+ m_hdf5_count[i] = tmp[i];
+ m_hdf5_dims[i] = tmp[i];
+ m_hdf5_offset[i]= 0;
+ }
+ H5open();
+ hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+ m_hdf5_fileid = H5Fcreate((m_fname+this->suffix()).c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
+ H5Pclose(fapl_id);
+}
+
+void PhotoHDF5::_close_hdf_file()
+{
+ H5Fclose(m_hdf5_fileid);
+ H5close();
+}
+
void PhotoHDF5::_dump_xmf() const
{
FILE *xmf = 0;
@@ -37,29 +59,29 @@ void PhotoHDF5::_dump_xmf() const
fclose(xmf);
}
-void PhotoHDF5::make_new(const int width, const int height)
+void PhotoHDF5::make_new(const string name, const int width, const int height)
+{
+ m_fname = name;
+ resize(width, height);
+}
+
+void PhotoHDF5::resize(const int width, const int height)
{
- if (m_hdfraw) delete [] m_hdfraw;
+ if (m_open)
+ {
+ _close_hdf_file();
+ if (m_hdfraw) delete [] m_hdfraw;
+ }
m_hdfraw = new Real[width*height];
m_width = width;
m_height= height;
- hsize_t tmp[4] = { 1, static_cast<hsize_t>(height), static_cast<hsize_t>(width), 1 };
- for (int i = 0; i < 4; ++i)
- {
- m_hdf5_count[i] = tmp[i];
- m_hdf5_dims[i] = tmp[i];
- m_hdf5_offset[i]= 0;
- }
-
- H5open();
- hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS);
- m_hdf5_fileid = H5Fcreate((m_fname+".h5").c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
- H5Pclose(fapl_id);
+ _open_hdf_file();
m_open = true;
}
+
void PhotoHDF5::write()
{
if (m_open)
@@ -77,8 +99,7 @@ void PhotoHDF5::write()
H5Dclose(dataset_id);
H5Pclose(fapl_id);
- H5Fclose(m_hdf5_fileid);
- H5close();
+ _close_hdf_file();
_dump_xmf();
@@ -97,3 +118,4 @@ void PhotoHDF5::set_pixel(const int ix, const int iy, const double phi)
m_hdfraw[iy*m_width + ix] = static_cast<Real>(phi);
}
}
+#endif /* _USE_HDF_ */
diff --git a/src/PhotoPNG.cpp b/src/PhotoPNG.cpp
@@ -0,0 +1,53 @@
+// File : PhotoPNG.cpp
+// Date : Wed Apr 27 22:46:32 2016
+// Author : Fabian Wermelinger
+// Description: PNG Photos implementation
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#include "PhotoPNG.h"
+
+void PNG_HSV::make_new(const string name, const int width, const int height)
+{
+ m_fname = name;
+ resize(width, height);
+}
+
+void PNG_HSV::resize(const int width, const int height)
+{
+ if (m_open)
+ {
+ m_png->close();
+ _dispose();
+ }
+ m_png = new pngwriter(width, height, m_background, (m_fname+this->suffix()).c_str());
+
+ m_width = width;
+ m_height = height;
+ m_open = true;
+}
+
+void PNG_HSV::write()
+{
+ if (m_open)
+ {
+ m_png->settext(m_title.c_str(), m_author.c_str(), m_description.c_str(), m_software.c_str());
+ m_png->write_png();
+ m_png->close();
+ _dispose();
+ m_open = false;
+ }
+}
+
+void PNG_HSV::set_pixel(const int x, const int y, const double phi)
+{
+ if (m_open)
+ {
+ const double hue = 2./3. * (1.0 - phi);
+ m_png->plotHSV(x+1, y+1, hue, m_saturation, m_value);
+ }
+}
+
+void PNG_MONO::set_pixel(const int x, const int y, const double phi)
+{
+ if (m_open)
+ m_png->plot(x+1, y+1, phi, phi, phi);
+}
diff --git a/src/Polaroid.cpp b/src/Polaroid.cpp
@@ -57,31 +57,25 @@ void Polaroid::load_hdf5(const char* filename, const double fraction, const int
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.resize(maxDim[1], maxDim[2]);
+ for (int h=0; h < m_data.height(); ++h)
+ for (int w=0; w < m_data.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.resize(maxDim[0], maxDim[2]);
+ for (int h=0; h < m_data.height(); ++h)
+ for (int w=0; w < m_data.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.resize(maxDim[0], maxDim[1]);
+ for (int h=0; h < m_data.height(); ++h)
+ for (int w=0; w < m_data.width(); ++w)
m_data(w,h) = data[channel + NCH * ID3(w,h,fixed,maxDim[0], maxDim[1])];
}
else
@@ -109,15 +103,13 @@ void Polaroid::load_wavelet(const char* filename, const double fraction, const i
const int NBZ = myreader.zblocks();
const int maxDim[3] = {NBX*_BLOCKSIZE_, NBY*_BLOCKSIZE_, NBZ*_BLOCKSIZE_};
- static Real blockdata[_BLOCKSIZE_][_BLOCKSIZE_][_BLOCKSIZE_];
+ 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);
+ m_data.resize(maxDim[1], maxDim[2]);
const int fixedBID = fixed/_BLOCKSIZE_;
const int BlocalID = fixed % _BLOCKSIZE_;
@@ -127,15 +119,17 @@ void Polaroid::load_wavelet(const char* filename, const double fraction, const i
const double zratio = myreader.load_block2(fixedBID, iy, iz, blockdata);
for (int z=0; z < _BLOCKSIZE_; ++z)
for (int y=0; y < _BLOCKSIZE_; ++y)
+ {
+ assert(iy*_BLOCKSIZE_+y < m_data.width());
+ assert(iz*_BLOCKSIZE_+z < m_data.height());
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);
+ m_data.resize(maxDim[0], maxDim[2]);
const int fixedBID = fixed/_BLOCKSIZE_;
const int BlocalID = fixed % _BLOCKSIZE_;
@@ -145,15 +139,17 @@ void Polaroid::load_wavelet(const char* filename, const double fraction, const i
const double zratio = myreader.load_block2(ix, fixedBID, iz, blockdata);
for (int z=0; z < _BLOCKSIZE_; ++z)
for (int x=0; x < _BLOCKSIZE_; ++x)
+ {
+ assert(ix*_BLOCKSIZE_+x < m_data.width());
+ assert(iz*_BLOCKSIZE_+z < m_data.height());
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);
+ m_data.resize(maxDim[0], maxDim[1]);
const int fixedBID = fixed/_BLOCKSIZE_;
const int BlocalID = fixed % _BLOCKSIZE_;
@@ -163,7 +159,11 @@ void Polaroid::load_wavelet(const char* filename, const double fraction, const i
const double zratio = myreader.load_block2(ix, iy, fixedBID, blockdata);
for (int y=0; y < _BLOCKSIZE_; ++y)
for (int x=0; x < _BLOCKSIZE_; ++x)
+ {
+ assert(ix*_BLOCKSIZE_+x < m_data.width());
+ assert(iy*_BLOCKSIZE_+y < m_data.height());
m_data(ix*_BLOCKSIZE_+x, iy*_BLOCKSIZE_+y) = blockdata[BlocalID][y][x];
+ }
}
}
else
@@ -177,20 +177,3 @@ void Polaroid::load_wavelet(const char* filename, const double fraction, const i
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));
- }
-}