text:
#ifndef BOOST_CERTIFY_VERIFICATION_UTILS_HPP
#define BOOST_CERTIFY_VERIFICATION_UTILS_HPP

#include <boost/certify/https_verification.hpp>

#include <boost/asio/ssl/error.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/error_code.hpp>
#include <boost/utility/string_view.hpp>
#include <openssl/pem.h>
#include <openssl/x509.h>

namespace boost
{
namespace certify
{

class certificate_chain
{
public:
    using native_handle_type = STACK_OF(X509) *;

    explicit certificate_chain(native_handle_type h) noexcept
      : handle_{h}
    {
    }

    native_handle_type native_handle() const
    {
        return handle_.get();
    }

    static certificate_chain from_file(
      boost::filesystem::path const& chain_path)
    {
        auto const bio_free = [](::BIO* b) { ::BIO_free(b); };
        std::unique_ptr<::BIO, decltype(bio_free)> file{
          ::BIO_new_file(chain_path.string().c_str(), "rb"), bio_free};
        assert(file != nullptr);
        auto* certs = sk_X509_new_null();
        assert(certs != nullptr);
        while (1)
        {
            auto* cert =
              ::PEM_read_bio_X509_AUX(file.get(), nullptr, nullptr, nullptr);
            if (!cert)
            {
                ::ERR_clear_error();
                break;
            }
            auto ret = sk_X509_push(certs, cert);
            assert(ret != 0);
        }
        assert(sk_X509_num(certs) > 0);

        return certificate_chain{certs};
    }

private:
    struct chain_free
    {
        void operator()(native_handle_type h)
        {
            sk_X509_pop_free(h, &::X509_free);
        }
    };

    std::unique_ptr<STACK_OF(X509), chain_free> handle_;
};

class certificate_store
{
public:
    using native_handle_type = ::X509_STORE*;

    explicit certificate_store()
      : handle_{::X509_STORE_new()}
    {
        if (handle_ == nullptr)
        {
            system::error_code ec;
            ec = {static_cast<int>(::ERR_get_error()),
                  boost::asio::error::get_ssl_category()};
            boost::throw_exception(system::system_error{ec});
        }
    }

    void set_default_paths()
    {
        auto ret = ::X509_STORE_set_default_paths(handle_.get());
        assert(ret == 1);
    }

    native_handle_type native_handle() const
    {
        return handle_.get();
    }

private:
    struct free
    {
        void operator()(native_handle_type h)
        {
            ::X509_STORE_free(h);
        }
    };

    std::unique_ptr<::X509_STORE, free> handle_;
};

class store_ctx_category : public system::error_category
{
public:
    const char* name() const BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT
    {
        return "certify.store_ctx";
    }

    std::string message(int value) const
    {
        const char* s = ::X509_verify_cert_error_string(value);
        return s ? s : "certify.store_ctx error";
    }
};

inline system::error_category const&
get_store_ctx_category()
{
    static store_ctx_category const instance;
    return instance;
}

class store_ctx
{
public:
    using native_handle_type = ::X509_STORE_CTX*;

    explicit store_ctx(certificate_chain& chain, certificate_store& store)
      : handle_{::X509_STORE_CTX_new()}
    {
        system::error_code ec;
        if (handle_ == nullptr)
        {
            ec = {static_cast<int>(::ERR_get_error()),
                  boost::asio::error::get_ssl_category()};
            boost::throw_exception(system::system_error{ec});
        }

        X509* const cert = sk_X509_value(chain.native_handle(), 0);
        auto const ret = ::X509_STORE_CTX_init(
          handle_.get(), store.native_handle(), cert, chain.native_handle());
        if (ret != 1)
        {

            ec = {static_cast<int>(::ERR_get_error()),
                  boost::asio::error::get_ssl_category()};
            boost::throw_exception(system::system_error{ec});
        }
        ::X509_STORE_CTX_set_verify_cb(handle_.get(),
                                       &detail::verify_server_certificates);
    }

    store_ctx(store_ctx const&) = delete;
    store_ctx& operator=(store_ctx const&) = delete;

    store_ctx(store_ctx&&) = delete;
    store_ctx& operator=(store_ctx&&) = delete;

    ~store_ctx() = default;

    native_handle_type native_handle() const
    {
        return handle_.get();
    }

    void set_server_hostname(string_view hostname)
    {
        auto* param = ::X509_STORE_CTX_get0_param(handle_.get());
        system::error_code ec;
        detail::set_server_hostname(param, hostname, ec);
        if (ec)
            boost::throw_exception(system::system_error{ec});
    }

    void verify(system::error_code& ec)
    {
        auto ret = ::X509_verify_cert(handle_.get());
        if (ret != 1)
        {
            auto const err = ::X509_STORE_CTX_get_error(handle_.get());
            ec = {err, get_store_ctx_category()};
        }
        else
            ec.assign(0, ec.category());
    }

    void verify()
    {
        system::error_code ec;
        verify(ec);
        if (ec)
            boost::throw_exception(system::system_error{ec});
    }

private:
    struct free
    {
        void operator()(native_handle_type h)
        {
            ::X509_STORE_CTX_free(h);
        }
    };

    std::unique_ptr<::X509_STORE_CTX, free> handle_;
};

void
verify_chain(boost::filesystem::path const& chain_path,
             boost::certify::certificate_store& store,
             system::error_code& ec)
{
    if (!boost::filesystem::is_regular_file(chain_path))
        return;

    auto cert_chain = boost::certify::certificate_chain::from_file(chain_path);
    boost::certify::store_ctx ctx{cert_chain, store};
    ctx.set_server_hostname(chain_path.stem().string());
    ctx.verify(ec);
}

} // namespace certify
} // namespace boost

#endif // BOOST_CERTIFY_VERIFICATION_UTILS_HPP

max_stars_repo_name: djarek/tlsverify

max_issues_repo_name: djarek/tlsverify

max_forks_repo_name: djarek/tlsverify


text:
/*! \file */

// C++ includes
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>
#include <unordered_map>
#include <unordered_set>
#include <string>
#include <cmath>
#include <stdexcept>
#include <thread>
#include <mutex>
#include <sys/resource.h>
#include <chrono>

// Other utilities
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <boost/variant.hpp>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/filereadstream.h"

#ifdef _MSC_VER
typedef unsigned uint;
#endif

#include "geomtypes.h"

// Tilemaker code
#include "helpers.h"
#include "coordinates.h"

#include "attribute_store.h"
#include "output_object.h"
#include "osm_lua_processing.h"
#include "mbtiles.h"
#include "write_geometry.h"

#include "shared_data.h"
#include "read_pbf.h"
#include "read_shp.h"
#include "tile_worker.h"
#include "osm_mem_tiles.h"
#include "shp_mem_tiles.h"

// Namespaces
using namespace std;
namespace po = boost::program_options;
namespace geom = boost::geometry;

// Global verbose switch
bool verbose = false;

/**
 *\brief The Main function is responsible for command line processing, loading data and starting worker threads.
 *
 * Data is loaded into OsmMemTiles and ShpMemTiles.
 *
 * Worker threads write the output tiles, and start in the outputProc function.
 */
int main(int argc, char* argv[]) {

	// ----	Read command-line options

	vector<string> inputFiles;
	string luaFile;
	string jsonFile;
	uint threadNum;
	string outputFile;
	bool _verbose = false, sqlite= false, combineSimilarObjs = false, mergeSqlite = false, mapsplit = false;

	po::options_description desc("tilemaker (c) 2016-2020 Richard Fairhurst and contributors\nConvert OpenStreetMap .pbf files into vector tiles\n\nAvailable options");
	desc.add_options()
		("help",                                                                 "show help message")
		("input",  po::value< vector<string> >(&inputFiles),                     "source .osm.pbf file")
		("output", po::value< string >(&outputFile),                             "target directory or .mbtiles/.sqlite file")
		("merge"  ,po::bool_switch(&mergeSqlite),                                "merge with existing .mbtiles (overwrites otherwise)")
		("config", po::value< string >(&jsonFile)->default_value("config.json"), "config JSON file")
		("process",po::value< string >(&luaFile)->default_value("process.lua"),  "tag-processing Lua file")
		("verbose",po::bool_switch(&_verbose),                                   "verbose error output")
		("threads",po::value< uint >(&threadNum)->default_value(0),              "number of threads (automatically detected if 0)")
		("combine",po::bool_switch(&combineSimilarObjs),                         "combine similar objects (reduces output size but takes considerably longer)");
	po::positional_options_description p;
	p.add("input", -1);
	po::variables_map vm;
    try {
        po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
    } catch (const po::unknown_option& ex) {
        cerr << "Unknown option: " << ex.get_option_name() << endl;
        return -1;
    }
	po::notify(vm);

	if (vm.count("help")) { cout << desc << endl; return 0; }
	if (vm.count("output")==0) { cerr << "You must specify an output file or directory. Run with --help to find out more." << endl; return -1; }
	if (vm.count("input")==0) { cout << "No source .osm.pbf file supplied" << endl; }

	if (ends_with(outputFile, ".mbtiles") || ends_with(outputFile, ".sqlite")) { sqlite=true; }
	if (threadNum == 0) { threadNum = max(thread::hardware_concurrency(), 1u); }
	verbose = _verbose;

	#ifdef COMPACT_NODES
	cout << "tilemaker compiled without 64-bit node support, use 'osmium renumber' first if working with OpenStreetMap-sourced data" << endl;
	#endif

	// ---- Check config

	if (!boost::filesystem::exists(jsonFile)) { cerr << "Couldn't open .json config: " << jsonFile << endl; return -1; }
	if (!boost::filesystem::exists(luaFile )) { cerr << "Couldn't open .lua script: "  << luaFile  << endl; return -1; }

	// ---- Remove existing .mbtiles if it exists

	if (sqlite && !mergeSqlite && static_cast<bool>(std::ifstream(outputFile))) {
		cout << "mbtiles file exists, will overwrite (Ctrl-C to abort, rerun with --merge to keep)" << endl;
		std::this_thread::sleep_for(std::chrono::milliseconds(2000));
		if (remove(outputFile.c_str()) != 0) {
			cerr << "Couldn't remove existing file" << endl;
			return 0;
		}
	}

	// ----	Read bounding box from first .pbf (if there is one) or mapsplit file

	bool hasClippingBox = false;
	Box clippingBox;
	MBTiles mapsplitFile;
	double minLon=0.0, maxLon=0.0, minLat=0.0, maxLat=0.0;
	if (inputFiles.size()==1 && (ends_with(inputFiles[0], ".mbtiles") || ends_with(inputFiles[0], ".sqlite") || ends_with(inputFiles[0], ".msf"))) {
		mapsplit = true;
		mapsplitFile.openForReading(&inputFiles[0]);
		mapsplitFile.readBoundingBox(minLon, maxLon, minLat, maxLat);
		cout << "Bounding box " << minLon << ", " << maxLon << ", " << minLat << ", " << maxLat << endl;
		clippingBox = Box(geom::make<Point>(minLon, lat2latp(minLat)),
		                  geom::make<Point>(maxLon, lat2latp(maxLat)));
		hasClippingBox = true;

	} else if (inputFiles.size()>0) {
		int ret = ReadPbfBoundingBox(inputFiles[0], minLon, maxLon, minLat, maxLat, hasClippingBox);
		if(ret != 0) return ret;
		if(hasClippingBox) {
			clippingBox = Box(geom::make<Point>(minLon, lat2latp(minLat)),
			                  geom::make<Point>(maxLon, lat2latp(maxLat)));
		}
	}

	// ----	Read JSON config

	rapidjson::Document jsonConfig;
	class Config config;
	try {
		FILE* fp = fopen(jsonFile.c_str(), "r");
		char readBuffer[65536];
		rapidjson::FileReadStream is(fp, readBuffer, sizeof(readBuffer));
		jsonConfig.ParseStream(is);
		if (jsonConfig.HasParseError()) { cerr << "Invalid JSON file." << endl; return -1; }
		fclose(fp);

		config.readConfig(jsonConfig, hasClippingBox, clippingBox);
		config.combineSimilarObjs = combineSimilarObjs;
	} catch (...) {
		cerr << "Couldn't find expected details in JSON file." << endl;
		return -1;
	}

	// For each tile, objects to be used in processing
	class OsmMemTiles osmMemTiles(config.baseZoom);
	class ShpMemTiles shpMemTiles(config.baseZoom);
	class LayerDefinition layers(config.layers);
	AttributeStore attributeStore;
	OsmLuaProcessing osmLuaProcessing(config, layers, luaFile,
		shpMemTiles, osmMemTiles, attributeStore);

	// ---- Load external shp files

	for (size_t layerNum=0; layerNum<layers.layers.size(); layerNum++) {
		// External layer sources
		LayerDef &layer = layers.layers[layerNum];
		if(layer.indexed) { shpMemTiles.CreateNamedLayerIndex(layer.name); }

		if (layer.source.size()>0) {
			if (!hasClippingBox) {
				cerr << "Can't read shapefiles unless a bounding box is provided." << endl;
				exit(EXIT_FAILURE);
			}
			cout << "Reading .shp " << layer.name << endl;
			readShapefile(clippingBox,
			              layers,
			              config.baseZoom, layerNum,
						  shpMemTiles, osmLuaProcessing);
		}
	}

	// ----	Read significant node tags

	vector<string> nodeKeyVec = osmLuaProcessing.GetSignificantNodeKeys();
	unordered_set<string> nodeKeys(nodeKeyVec.begin(), nodeKeyVec.end());

	// ----	Read all PBFs

	class PbfReader pbfReader;
	pbfReader.output = &osmLuaProcessing;
	if (!mapsplit) {
		for (auto inputFile : inputFiles) {
			cout << "Reading .pbf " << inputFile << endl;
			int ret = pbfReader.ReadPbfFile(inputFile, nodeKeys);
			if (ret != 0) return ret;
		}
	}

	// ----	Initialise SharedData

	std::vector<class TileDataSource *> sources = {&osmMemTiles, &shpMemTiles};
	class TileData tileData(sources);

	if (!mapsplit) attributeStore.sortOsmAttributes();
	attributeStore.sortShpAttributes();

	class SharedData sharedData(config, layers, tileData, attributeStore);
	sharedData.threadNum = threadNum;
	sharedData.outputFile = outputFile;
	sharedData.sqlite = sqlite;

	// ----	Initialise mbtiles if required

	if (sharedData.sqlite) {
		ostringstream bounds;
		bounds << fixed << sharedData.config.minLon << "," << sharedData.config.minLat << "," << sharedData.config.maxLon << "," << sharedData.config.maxLat;
		sharedData.mbtiles.openForWriting(&sharedData.outputFile);
		sharedData.mbtiles.writeMetadata("name",sharedData.config.projectName);
		sharedData.mbtiles.writeMetadata("type","baselayer");
		sharedData.mbtiles.writeMetadata("version",sharedData.config.projectVersion);
		sharedData.mbtiles.writeMetadata("description",sharedData.config.projectDesc);
		sharedData.mbtiles.writeMetadata("format","pbf");
		sharedData.mbtiles.writeMetadata("bounds",bounds.str());
		sharedData.mbtiles.writeMetadata("minzoom",to_string(sharedData.config.startZoom));
		sharedData.mbtiles.writeMetadata("maxzoom",to_string(sharedData.config.endZoom));
		if (!sharedData.config.defaultView.empty()) { sharedData.mbtiles.writeMetadata("center",sharedData.config.defaultView); }
	}

	// ----	Write out data

	// If mapsplit, read list of tiles available
	unsigned runs=1;
	vector<tuple<int,int,int>> tileList;
	if (mapsplit) {
		mapsplitFile.readTileList(tileList);
		runs = tileList.size();
	}

	for (unsigned run=0; run<runs; run++) {
		// Read mapsplit tile and parse, if applicable
		int srcZ = -1, srcX = -1, srcY = -1, tmsY = -1;
		if (mapsplit) {
			osmMemTiles.Clear();
			attributeStore.clearOsmAttributes();
			tie(srcZ,srcX,tmsY) = tileList.back();
			srcY = pow(2,srcZ) - tmsY - 1; // TMS
			if (srcZ > config.baseZoom) {
				cerr << "Mapsplit tiles (zoom " << srcZ << ") must not be greater than basezoom " << config.baseZoom << endl;
				return 0;
			} else if (srcZ > config.startZoom) {
				cout << "Mapsplit tiles (zoom " << srcZ << ") can't write data at zoom level " << config.startZoom << endl;
			}
			cout << "Reading tile " << srcZ << ": " << srcX << "," << srcY << " (" << (run+1) << "/" << runs << ")" << endl;
			vector<char> pbf = mapsplitFile.readTile(srcZ,srcX,tmsY);
			// Write to a temp file and read back in - can we do this better via a stringstream or similar?
			ofstream tempfile;
			tempfile.open("/tmp/temp.pbf");
			copy(pbf.cbegin(), pbf.cend(), ostreambuf_iterator<char>(tempfile));
			tempfile.close();
			pbfReader.ReadPbfFile("/tmp/temp.pbf", nodeKeys);
			tileList.pop_back();
			attributeStore.sortOsmAttributes();
		}

		for (uint zoom=sharedData.config.startZoom; zoom<=sharedData.config.endZoom; zoom++) {

			tileData.SetZoom(zoom);
			sharedData.zoom = zoom;

			if(threadNum == 1) {
				// Single thread (is easier to debug)
				outputProc(0, &sharedData, srcZ,srcX,srcY);
			} else {

				// Multi thread processing loop
				vector<thread> worker;
				for (uint threadId = 0; threadId < threadNum; threadId++)
					worker.emplace_back(outputProc, threadId, &sharedData, srcZ,srcX,srcY);
				for (auto &t: worker) t.join();

			}
		}
	}

	// ----	Close tileset

	if (sqlite) {
		// Write mbtiles 1.3+ json object
		sharedData.mbtiles.writeMetadata("json", layers.serialiseToJSON());

		// Write user-defined metadata
		if (jsonConfig["settings"].HasMember("metadata")) {
			const rapidjson::Value &md = jsonConfig["settings"]["metadata"];
			for(rapidjson::Value::ConstMemberIterator it=md.MemberBegin(); it != md.MemberEnd(); ++it) {
				if (it->value.IsString()) {
					sharedData.mbtiles.writeMetadata(it->name.GetString(), it->value.GetString());
				} else {
					rapidjson::StringBuffer strbuf;
					rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
					it->value.Accept(writer);
					sharedData.mbtiles.writeMetadata(it->name.GetString(), strbuf.GetString());
				}
			}
		}
		sharedData.mbtiles.closeForWriting();
	}
	google::protobuf::ShutdownProtobufLibrary();

	if (verbose) {
		struct rusage r_usage;
		getrusage(RUSAGE_SELF, &r_usage);
		cout << "\nMemory used: " << r_usage.ru_maxrss << endl;
	}

	cout << endl << "Filled the tileset with good things at " << sharedData.outputFile << endl;
}

ext: cpp

max_stars_repo_name: swiss-knight/tilemaker

max_issues_repo_name: swiss-knight/tilemaker

max_forks_repo_name: swiss-knight/tilemaker


text:
#include <Zivid/Zivid.h>

#include <dynamic_reconfigure/config_tools.h>

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>

#include <algorithm>
#include <cctype>
#include <chrono>
#include <fstream>
#include <iostream>
#include <regex>
#include <sstream>
#include <string>

namespace
{
template <class T>
using NormalizedType = std::remove_const_t<std::remove_reference_t<T>>;

template <class T, class ZividSetting>
constexpr bool isZividSetting = std::is_same<NormalizedType<T>, ZividSetting>::value;

template <class T>
constexpr bool isFilters = isZividSetting<T, Zivid::Settings::Filters>;

template <class T>
constexpr bool isColorBalance =
    isZividSetting<T, Zivid::Settings::BlueBalance> || isZividSetting<T, Zivid::Settings::RedBalance>;

template <class T>
constexpr bool isGeneralSetting = isFilters<T> || isColorBalance<T>;

template <typename C, typename = void>
struct HasRange : std::false_type
{
};

template <typename C>
struct HasRange<C, std::void_t<decltype(std::declval<C>().range())>> : std::true_type
{
};

template <typename ZividSetting>
struct AssertValue
{
  static constexpr bool value = false;
};

std::string convertSettingsPathToZividClassName(const std::string& path)
{
  return "Zivid::Settings::" + boost::replace_all_copy<std::string>(path, "/", "::");
}

std::string convertSettingsPathToConfigPath(std::string path)
{
  path = boost::replace_all_copy<std::string>(path, "/", "_");
  const std::regex re("([^_^])([A-Z])");
  path = std::regex_replace(path, re, "$1_$2");  // Convert fex ExposureTime to Exposure_Time
  return boost::algorithm::to_lower_copy(path);
}

class DynamicReconfigureCfgGenerator
{
public:
  DynamicReconfigureCfgGenerator(const std::string& className) : className_(className), insertEnabled_(false)
  {
  }

  template <class ValueType>
  auto convertValueToRosValue(ValueType value)
  {
    // Convert from our own setting value types to the types that ROS params supports.
    if constexpr (std::is_same_v<ValueType, bool> || std::is_same_v<ValueType, double>)
    {
      return value;
    }
    else if constexpr (std::is_same_v<ValueType, std::size_t>)
    {
      return static_cast<int>(value);
    }
    else if constexpr (std::is_same_v<ValueType, std::chrono::microseconds>)
    {
      return std::chrono::duration_cast<std::chrono::duration<double>>(value).count();
    }
    else
    {
      static_assert(AssertValue<ValueType>::value, "Could not convert ValueType to ROS type.");
    }
  }

  template <class RosType>
  std::string rosTypeName()
  {
    if constexpr (std::is_same_v<RosType, bool>)
    {
      return "bool_t";
    }
    else if constexpr (std::is_same_v<RosType, double>)
    {
      return "double_t";
    }
    else if constexpr (std::is_same_v<RosType, int>)
    {
      return "int_t";
    }
    else
    {
      static_assert(AssertValue<RosType>::value, "Could not convert RosType to a ROS typename string.");
    }
  }

  template <class RosType>
  std::string rosTypeToString(RosType v)
  {
    if constexpr (std::is_same_v<RosType, bool>)
    {
      return v ? "True" : "False";
    }
    else if constexpr (std::is_same_v<RosType, double> || std::is_same_v<RosType, int>)
    {
      return std::to_string(v);
    }
    else
    {
      static_assert(AssertValue<RosType>::value, "Could not convert RosType to a string value.");
    }
  }

  template <class ValueType>
  std::string valueTypeToRosTypeString(ValueType v)
  {
    return rosTypeToString(convertValueToRosValue(v));
  }

  template <class ZividSetting>
  void apply(const ZividSetting& s)
  {
    const auto setting_name = convertSettingsPathToConfigPath(s.path);
    const auto level = "0";
    // Newlines must be converted to \\n so that the auto-generated files end up being correct
    const auto description = boost::replace_all_copy<std::string>(s.description, "\n", R"(\\n)");
    const auto type_name = rosTypeName<decltype(convertValueToRosValue(s.value()))>();
    const auto default_value = valueTypeToRosTypeString(s.value());

    ss_ << "gen.add(\"" << setting_name << "\", " << type_name << ", " << level << ", "
        << "\"" << description << "\", " << default_value;

    if constexpr (HasRange<NormalizedType<ZividSetting>>::value)
    {
      ss_ << ", " << valueTypeToRosTypeString(s.range().min()) << ", " << valueTypeToRosTypeString(s.range().max());
    }
    ss_ << ")\n";
  }

  void insertEnabled()
  {
    insertEnabled_ = true;
  }

  std::string str()
  {
    std::stringstream res;
    res << "#!/usr/bin/env python\n\n"
           "# This is an auto-generated cfg file. Do not edit!\n\n"
           "PACKAGE = \"zivid_camera\"\n"
           "import roslib\n"
           "roslib.load_manifest(PACKAGE);\n"
           "from dynamic_reconfigure.parameter_generator_catkin import *\n\n";

    res << "gen = ParameterGenerator()\n";
    if (insertEnabled_)
    {
      res << "gen.add(\"enabled\", bool_t, 0, \"When frame is enabled it will be included in captures\", "
             "False)\n";
    }
    res << ss_.str();
    res << "gen.generate(PACKAGE, \"zivid_camera\", \"" + className_ + "\")\n";
    return res.str();
  }

private:
  std::string className_;
  bool insertEnabled_;
  std::stringstream ss_;
};

class ApplyConfigToZividSettingsGenerator
{
public:
  ApplyConfigToZividSettingsGenerator(const std::string& className) : className_(className)
  {
  }

  template <class ZividSetting>
  void apply(const ZividSetting& s)
  {
    using T = NormalizedType<decltype(s)>;
    using VT = typename T::ValueType;

    const auto cfgId = "cfg." + convertSettingsPathToConfigPath(s.path);
    const auto zividClassName = convertSettingsPathToZividClassName(s.path);
    ss_ << "  s.set(" + zividClassName + "{ ";

    if constexpr (std::is_same_v<VT, std::size_t>)
    {
      ss_ << "static_cast<std::size_t>(" + cfgId + ")";
    }
    else if constexpr (std::is_same_v<VT, std::chrono::microseconds>)
    {
      ss_ << "std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(" + cfgId + "))";
    }
    else
    {
      ss_ << cfgId;
    }
    ss_ << " });\n";
  }

  std::string str()
  {
    std::stringstream res;
    res << "void apply" << className_
        << "ConfigToZividSettings(const zivid_camera::" + className_ + "Config& cfg, Zivid::Settings& s)\n";
    res << "{\n";
    res << ss_.str();
    res << "}\n";
    return res.str();
  }

private:
  std::string className_;
  std::stringstream ss_;
};

class GetConfigMinMaxDefFromZividSettingsGenerator
{
public:
  enum class Type
  {
    Min,
    Max,
    Default
  };

  GetConfigMinMaxDefFromZividSettingsGenerator(const std::string& className, Type type)
    : className_(className), type_(type)
  {
  }

  template <class ZividSetting>
  void apply(const ZividSetting& s)
  {
    using T = NormalizedType<decltype(s)>;
    using VT = typename T::ValueType;
    const auto cfgId = "cfg." + convertSettingsPathToConfigPath(s.path);
    const auto zividClassName = convertSettingsPathToZividClassName(s.path);

    const auto valueStr = [&]() {
      if (type_ == Type::Min || type_ == Type::Max)
      {
        return "s.get<" + zividClassName + ">().range()." + type() + "()";
      }
      else
      {
        return "s.get<" + zividClassName + ">().value()";
      }
    }();

    if (type_ == Type::Default || HasRange<T>::value)
    {
      if constexpr (std::is_same_v<VT, std::chrono::microseconds>)
      {
        ss_ << "  " + cfgId + " = std::chrono::duration_cast<std::chrono::duration<double>>(" + valueStr +
                   ").count();\n";
      }
      else
      {
        ss_ << "  " + cfgId + " = " + valueStr + ";\n";
      }
    }
  }

  std::string typeUcFirst()
  {
    switch (type_)
    {
      case Type::Min:
        return "Min";
      case Type::Max:
        return "Max";
      case Type::Default:
        return "Default";
    }
    return "";
  }

  std::string type()
  {
    auto _type = typeUcFirst();
    _type[0] = std::tolower(_type[0]);
    return _type;
  }

  std::string str()
  {
    const auto fullClassName = "zivid_camera::" + className_ + "Config";
    std::stringstream res;
    res << fullClassName << " get" << className_
        << "Config" + typeUcFirst() + "FromZividSettings(const Zivid::Settings& s)\n";
    res << "{\n";
    res << "  auto cfg = " + fullClassName + "::__get" + typeUcFirst() + "__();\n";
    res << ss_.str();
    res << "  return cfg;\n";
    res << "}\n";
    return res.str();
  }

private:
  std::string className_;
  Type type_;
  std::stringstream ss_;
};

class ConfigUtilsHeaderGenerator
{
public:
  ConfigUtilsHeaderGenerator(const std::string& className)
    : apply_config_zivid_settings_gen(className)
    , get_config_min_from_zivid_settings_gen(className, GetConfigMinMaxDefFromZividSettingsGenerator::Type::Min)
    , get_config_max_from_zivid_settings_gen(className, GetConfigMinMaxDefFromZividSettingsGenerator::Type::Max)
    , get_config_def_from_zivid_settings_gen(className, GetConfigMinMaxDefFromZividSettingsGenerator::Type::Default)
  {
  }

  template <class ZividSetting>
  void apply(const ZividSetting& s)
  {
    apply_config_zivid_settings_gen.apply(s);
    get_config_min_from_zivid_settings_gen.apply(s);
    get_config_max_from_zivid_settings_gen.apply(s);
    get_config_def_from_zivid_settings_gen.apply(s);
  }

  std::string str()
  {
    std::stringstream res;
    res << "#pragma once\n\n";
    res << "// This is an auto-generated header. Do not edit.\n\n";
    res << apply_config_zivid_settings_gen.str() << "\n";
    res << get_config_min_from_zivid_settings_gen.str() << "\n";
    res << get_config_max_from_zivid_settings_gen.str() << "\n";
    res << get_config_def_from_zivid_settings_gen.str() << "\n";
    return res.str();
  }

  ApplyConfigToZividSettingsGenerator apply_config_zivid_settings_gen;
  GetConfigMinMaxDefFromZividSettingsGenerator get_config_min_from_zivid_settings_gen;
  GetConfigMinMaxDefFromZividSettingsGenerator get_config_max_from_zivid_settings_gen;
  GetConfigMinMaxDefFromZividSettingsGenerator get_config_def_from_zivid_settings_gen;
};

class Generator
{
public:
  Generator(const std::string& className) : dynamic_reconfigure_cfg_gen(className), config_utils_header_gen(className)
  {
  }

  template <class ZividSetting>
  void apply(const ZividSetting& s)
  {
    dynamic_reconfigure_cfg_gen.apply(s);
    config_utils_header_gen.apply(s);
  }

  DynamicReconfigureCfgGenerator dynamic_reconfigure_cfg_gen;
  ConfigUtilsHeaderGenerator config_utils_header_gen;
};

template <typename ZividSetting>
void traverseGeneralSettingsTree(const ZividSetting& s, Generator& general_settings)
{
  if constexpr (ZividSetting::isContainer)
  {
    s.forEach([&](const auto& c) { traverseGeneralSettingsTree(c, general_settings); });
  }
  else
  {
    general_settings.apply(s);
  }
}

template <typename ZividSetting>
void traverseSettingsTree(const ZividSetting& s, Generator& general_settings, Generator& frame_settings)
{
  if constexpr (isGeneralSetting<ZividSetting>)
  {
    traverseGeneralSettingsTree(s, general_settings);
  }
  else if constexpr (ZividSetting::isContainer)
  {
    s.forEach([&](const auto& c) { traverseSettingsTree(c, general_settings, frame_settings); });
  }
  else
  {
    frame_settings.apply(s);
  }
}

void writeToFile(const std::string& file_name, const std::string& text)
{
  std::ofstream cfg_file;
  cfg_file.open(file_name);
  cfg_file << text;
  cfg_file.close();
}

}  // namespace

int main(int /*argc*/, char** /*argv*/)
{
  Generator capture_general_gen("CaptureGeneral");
  Generator capture_frame_gen("CaptureFrame");

  const auto settings = Zivid::Settings{};
  traverseSettingsTree(settings, capture_general_gen, capture_frame_gen);
  capture_frame_gen.dynamic_reconfigure_cfg_gen.insertEnabled();

  writeToFile("CaptureGeneral.cfg", capture_general_gen.dynamic_reconfigure_cfg_gen.str());
  writeToFile("CaptureFrame.cfg", capture_frame_gen.dynamic_reconfigure_cfg_gen.str());

  writeToFile("generated_headers/CaptureGeneralConfigUtils.h", capture_general_gen.config_utils_header_gen.str());
  writeToFile("generated_headers/CaptureFrameConfigUtils.h", capture_frame_gen.config_utils_header_gen.str());

  return 0;
}

max_stars_repo_name: carlosmccosta/effective-parakeet

max_issues_repo_name: carlosmccosta/effective-parakeet

max_forks_repo_name: carlosmccosta/effective-parakeet


text:
//
// OpenTissue, A toolbox for physical based simulation and animation.
// Copyright (C) 2007 Department of Computer Science, University of Copenhagen
//
#include <OpenTissue/configuration.h>

#include <OpenTissue/gpu/image/io/image_read.h>
#include <OpenTissue/gpu/image/io/image_write.h>

#define BOOST_AUTO_TEST_MAIN
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(opentissue_io);

BOOST_AUTO_TEST_CASE(test_cases)
{
  {
    // TODO: The read function does not extract optional chunks from the image, hence the result image lack those chunks.
    // We either have to modify the read function to extract the chunks or find an image that does not contain any of the
    // chunks so that we can do fair a comparision. For now this tests that there is no mayor exceptions comming from libpng
    // while reading/writting a png image.
    OpenTissue::image::Image<unsigned char> image;
    OpenTissue::image::read("pax.png", image);
    OpenTissue::image::write("pax_out.png", image);
  }
}

BOOST_AUTO_TEST_SUITE_END();


text:
#pragma once

#include <Eigen/Core>
#include <Eigen/SparseCore>

#include <ipc/utils/eigen_ext.hpp>

namespace ipc {

typedef Eigen::DiagonalMatrix<double, 3> DiagonalMatrix3d;

template <typename T>
Eigen::SparseMatrix<T> SparseDiagonal(const VectorX<T>& x);

template <typename T> inline Matrix2<T> Hat(T x);
template <typename T> inline Matrix3<T> Hat(Vector3<T> x);
template <typename T> inline MatrixMax3<T> Hat(VectorMax3<T> x);

} // namespace ipc

#include "eigen_ext.tpp"

ext: hpp

max_stars_repo_name: ipc-sim/rigid-ipc

max_issues_repo_name: ipc-sim/rigid-ipc

max_forks_repo_name: ipc-sim/rigid-ipc


text:
//
// Created by dchansen on 2/21/19.
//

#include "PureCmrCartesianKSpaceBinningCineGadget.h"
#include <boost/range/algorithm/copy.hpp>

namespace {
    using namespace Gadgetron;
    void set_time_stamps(
        IsmrmrdImageArray& res, const hoNDArray<float>& acq_time, const hoNDArray<float>& cpt_time, float time_tick) {

        size_t N   = res.headers_.get_size(0);
        size_t S   = res.headers_.get_size(1);
        size_t SLC = res.headers_.get_size(2);

        size_t n, s, slc;
        for (slc = 0; slc < SLC; slc++) {
            for (s = 0; s < S; s++) {
                for (n = 0; n < N; n++) {
                    res.headers_(n, s, slc).acquisition_time_stamp = (uint32_t)lround(acq_time(n, s, slc) / time_tick);
                    res.headers_(n, s, slc).physiology_time_stamp[0]
                        = (uint32_t)lround(cpt_time(n, s, slc) / time_tick);
                }
            }
        }
    }

}

Gadgetron::IsmrmrdImageArray Gadgetron::PureCmrCartesianKSpaceBinningCineGadget::process_function(
    Gadgetron::IsmrmrdReconData args) const {

    if (args.rbit_.size() > 1)
        throw std::runtime_error("Only single encoding space supported");
    size_t encoding = 0;
    auto result     = perform_binning(args.rbit_[encoding], encoding);
    set_image_header(args.rbit_[encoding], result.image, encoding);
    set_time_stamps(result.image, result.acquisition_time, result.capture_time, time_tick);
    prepare_image_array(result.image, 0, 2, GADGETRON_IMAGE_RETRO);
    return std::move(result.image);
}
CmrKSpaceBinning<float> PureCmrCartesianKSpaceBinningCineGadget::create_binner() const {
    auto binner = CmrKSpaceBinning<float>{};

    //    binner.perform_timing_ = this->perform_timing;
    //    binner.verbose_        = this->verbose;

    binner.use_multiple_channel_recon_         = this->use_multiple_channel_recon;
    binner.use_paralell_imaging_binning_recon_ = true;
    binner.use_nonlinear_binning_recon_        = this->use_nonlinear_binning_recon;

    binner.estimate_respiratory_navigator_          = true;
    binner.respiratory_navigator_moco_reg_strength_ = this->respiratory_navigator_moco_reg_strength;
    binner.respiratory_navigator_moco_iters_        = this->respiratory_navigator_moco_iters;

    binner.time_tick_                  = this->time_tick;
    binner.trigger_time_index_         = 0;
    binner.arrhythmia_rejector_factor_ = this->arrhythmia_rejector_factor;

    binner.grappa_kSize_RO_                           = this->grappa_kSize_RO;
    binner.grappa_kSize_E1_                           = this->grappa_kSize_E1;
    binner.grappa_reg_lamda_                          = this->grappa_reg_lamda;
    binner.downstream_coil_compression_num_modesKept_ = this->downstream_coil_compression_num_modesKept;
    binner.downstream_coil_compression_thres_         = this->downstream_coil_compression_thres;

    binner.kspace_binning_interpolate_heart_beat_images_ = this->kspace_binning_interpolate_heart_beat_images;
    binner.kspace_binning_navigator_acceptance_window_   = this->kspace_binning_navigator_acceptance_window;

    binner.kspace_binning_moco_reg_strength_ = this->kspace_binning_moco_reg_strength;
    binner.kspace_binning_moco_iters_        = this->kspace_binning_moco_iters;

    binner.kspace_binning_max_temporal_window_             = this->kspace_binning_max_temporal_window;
    binner.kspace_binning_minimal_cardiac_phase_width_     = this->kspace_binning_minimal_cardiac_phase_width;
    binner.kspace_binning_kSize_RO_                        = this->kspace_binning_kSize_RO;
    binner.kspace_binning_kSize_E1_                        = this->kspace_binning_kSize_E1;
    binner.kspace_binning_reg_lamda_                       = this->kspace_binning_reg_lamda;
    binner.kspace_binning_linear_iter_max_                 = this->kspace_binning_linear_iter_max;
    binner.kspace_binning_linear_iter_thres_               = this->kspace_binning_linear_iter_thres;
    binner.kspace_binning_nonlinear_iter_max_              = this->kspace_binning_nonlinear_iter_max;
    binner.kspace_binning_nonlinear_iter_thres_            = this->kspace_binning_nonlinear_iter_thres;
    binner.kspace_binning_nonlinear_data_fidelity_lamda_   = this->kspace_binning_nonlinear_data_fidelity_lamda;
    binner.kspace_binning_nonlinear_image_reg_lamda_       = this->kspace_binning_nonlinear_image_reg_lamda;
    binner.kspace_binning_nonlinear_reg_N_weighting_ratio_ = this->kspace_binning_nonlinear_reg_N_weighting_ratio;
    binner.kspace_binning_nonlinear_reg_use_coil_sen_map_  = this->kspace_binning_nonlinear_reg_use_coil_sen_map;
    binner.kspace_binning_nonlinear_reg_with_approx_coeff_ = this->kspace_binning_nonlinear_reg_with_approx_coeff;
    binner.kspace_binning_nonlinear_reg_wav_name_          = this->kspace_binning_nonlinear_reg_wav_name;

    return binner;
}
PureCmrCartesianKSpaceBinningCineGadget::BinningResult PureCmrCartesianKSpaceBinningCineGadget::perform_binning(
    IsmrmrdReconBit recon_bit, size_t encoding) const {
    size_t RO  = recon_bit.data_.data_.get_size(0);
    size_t E1  = recon_bit.data_.data_.get_size(1);
    size_t E2  = recon_bit.data_.data_.get_size(2);
    size_t CHA = recon_bit.data_.data_.get_size(3);
    size_t N   = recon_bit.data_.data_.get_size(4);
    size_t S   = recon_bit.data_.data_.get_size(5);
    size_t SLC = recon_bit.data_.data_.get_size(6);

    size_t binned_N = number_of_output_phases;

    auto binner = create_binner();
    BinningResult result;
    result.image.data_      = hoNDArray<std::complex<float>>(RO, E1, E2, 1, binned_N, S, SLC);
    result.acquisition_time = hoNDArray<float>(N, S, SLC);
    result.capture_time     = hoNDArray<float>(N, S, SLC);

    for (size_t slc = 0; slc < SLC; slc++) {
        std::stringstream os;

        // set up the binning object
        binner.binning_obj_.data_.create(
            RO, E1, CHA, N, S, recon_bit.data_.data_.begin() + slc * RO * E1 * CHA * N * S);
        binner.binning_obj_.sampling_ = recon_bit.data_.sampling_;
        binner.binning_obj_.headers_.create(E1, N, S, recon_bit.data_.headers_.begin() + slc * E1 * N * S);

        binner.binning_obj_.output_N_        = binned_N;
        binner.binning_obj_.accel_factor_E1_ = acceFactorE1_[encoding];
        binner.binning_obj_.random_sampling_
            = (calib_mode_[encoding] != ISMRMRD_embedded && calib_mode_[encoding] != ISMRMRD_interleaved
                && calib_mode_[encoding] != ISMRMRD_separate && calib_mode_[encoding] != ISMRMRD_noacceleration);

        binner.process_binning_recon();

        std::copy_n(binner.binning_obj_.complex_image_binning_.data(),
            binner.binning_obj_.complex_image_binning_.get_number_of_bytes(),
            result.image.data_.data() + slc * RO * E1 * N * S * SLC);

        for (size_t s = 0; s < S; s++) {

            for (size_t n = 0; n < binned_N; n++) {
                result.acquisition_time(n, s, slc) = binner.binning_obj_.phs_time_stamp_(n, s);
                result.capture_time(n, s, slc)     = binner.binning_obj_.mean_RR_ * binner.binning_obj_.desired_cpt_[n];
            }
        }
    }
    return result;
}

PureCmrCartesianKSpaceBinningCineGadget::PureCmrCartesianKSpaceBinningCineGadget(
    const Core::Context& context, const Core::GadgetProperties& props)
    : PureGadget(context,props) {
    auto h    = context.header;
    size_t NE = h.encoding.size();

    acceFactorE1_.resize(NE, 1);
    acceFactorE2_.resize(NE, 1);
    calib_mode_.resize(NE, ISMRMRD_noacceleration);
    space_matrix_offset_E1_.resize(NE, 0);
    space_matrix_offset_E2_.resize(NE, 0);

    for (size_t e = 0; e < h.encoding.size(); e++) {

        if (!h.encoding[e].parallelImaging) {
            calib_mode_[e]   = ISMRMRD_noacceleration;
            acceFactorE1_[e] = 1;
            acceFactorE2_[e] = 1;
        } else {
            ISMRMRD::ParallelImaging p_imaging = *h.encoding[e].parallelImaging;

            acceFactorE1_[e] = p_imaging.accelerationFactor.kspace_encoding_step_1;
            acceFactorE2_[e] = p_imaging.accelerationFactor.kspace_encoding_step_2;

            std::string calib = *p_imaging.calibrationMode;

            bool separate    = calib == "separate";
            bool embedded    = calib == "embedded";
            bool external    = calib == "external";
            bool interleaved = calib == "interleaved";
            bool other       = calib == "other";

            calib_mode_[e] = Gadgetron::ISMRMRD_noacceleration;
            if (acceFactorE1_[e] > 1 || acceFactorE2_[e] > 1) {
                if (interleaved)
                    calib_mode_[e] = Gadgetron::ISMRMRD_interleaved;
                else if (embedded)
                    calib_mode_[e] = Gadgetron::ISMRMRD_embedded;
                else if (separate)
                    calib_mode_[e] = Gadgetron::ISMRMRD_separate;
                else if (external)
                    calib_mode_[e] = Gadgetron::ISMRMRD_external;
                else if (other)
                    calib_mode_[e] = Gadgetron::ISMRMRD_other;
            }
        }

        bool is_cartesian_sampling = (h.encoding[e].trajectory == ISMRMRD::TrajectoryType::CARTESIAN);
        bool is_epi_sampling       = (h.encoding[e].trajectory == ISMRMRD::TrajectoryType::EPI);
        if (is_cartesian_sampling || is_epi_sampling) {
            if (h.encoding[e].encodingLimits.kspace_encoding_step_1.is_present()) {
                space_matrix_offset_E1_[e] = (int)h.encoding[e].encodedSpace.matrixSize.y / 2
                                             - (int)h.encoding[e].encodingLimits.kspace_encoding_step_1->center;
            }

            if (h.encoding[e].encodingLimits.kspace_encoding_step_2.is_present()
                && h.encoding[e].encodedSpace.matrixSize.z > 1) {
                space_matrix_offset_E2_[e] = (int)h.encoding[e].encodedSpace.matrixSize.z / 2
                                             - (int)h.encoding[e].encodingLimits.kspace_encoding_step_2->center;
            }
        }
        // -------------------------------------------------
    }
}

void PureCmrCartesianKSpaceBinningCineGadget::set_image_header(
    const IsmrmrdReconBit& recon_bit, IsmrmrdImageArray& res, size_t enc) const {
    size_t RO  = res.data_.get_size(0);
    size_t E1  = res.data_.get_size(1);
    size_t E2  = res.data_.get_size(2);
    size_t CHA = res.data_.get_size(3);
    size_t N   = res.data_.get_size(4);
    size_t S   = res.data_.get_size(5);
    size_t SLC = res.data_.get_size(6);

    GADGET_CHECK_THROW(N == recon_bit.data_.headers_.get_size(2));
    GADGET_CHECK_THROW(S == recon_bit.data_.headers_.get_size(3));

    res.headers_.create(N, S, SLC);
    res.meta_.resize(N * S * SLC);

    size_t n, s, slc;

    for (slc = 0; slc < SLC; slc++) {
        for (s = 0; s < S; s++) {
            for (n = 0; n < N; n++) {
                size_t header_E1 = recon_bit.data_.headers_.get_size(0);
                size_t header_E2 = recon_bit.data_.headers_.get_size(1);

                // for every kspace, find the recorded header which is closest to the kspace center [E1/2 E2/2]
                ISMRMRD::AcquisitionHeader acq_header;

                long long bestE1 = E1 + 1;
                long long bestE2 = E2 + 1;

                for (size_t e2 = 0; e2 < header_E2; e2++) {
                    for (size_t e1 = 0; e1 < header_E1; e1++) {
                        const ISMRMRD::AcquisitionHeader& curr_header = recon_bit.data_.headers_(e1, e2, n, s, slc);

                        long long e1_in_bucket = curr_header.idx.kspace_encode_step_1 + space_matrix_offset_E1_[enc];

                        if (E2 > 1) {
                            long long e2_in_bucket
                                = curr_header.idx.kspace_encode_step_2 + space_matrix_offset_E2_[enc];

                            if (std::abs(e1_in_bucket - (long long)(E1 / 2)) < bestE1
                                && std::abs(e2_in_bucket - (long long)(E2 / 2)) < bestE2) {
                                bestE1 = std::abs(e1_in_bucket - (long long)E1 / 2);
                                bestE2 = std::abs(e2_in_bucket - (long long)E2 / 2);

                                acq_header = curr_header;
                            }
                        } else {
                            if (std::abs(e1_in_bucket - (long long)(E1 / 2)) < bestE1) {
                                bestE1 = std::abs(e1_in_bucket - (long long)E1 / 2);

                                acq_header = curr_header;
                            }
                        }
                    }
                }

                ISMRMRD::ImageHeader& im_header = res.headers_(n, s, slc);
                ISMRMRD::MetaContainer& meta    = res.meta_[n + s * N + slc * N * S];

                im_header.version         = acq_header.version;
                im_header.data_type       = ISMRMRD::ISMRMRD_CXFLOAT;
                im_header.flags           = acq_header.flags;
                im_header.measurement_uid = acq_header.measurement_uid;

                boost::copy(std::vector<uint16_t>{ (uint16_t)RO, (uint16_t)E1, (uint16_t)E2 }, im_header.matrix_size);

                boost::copy(recon_bit.data_.sampling_.recon_FOV_, im_header.field_of_view);

                im_header.channels = (uint16_t)CHA;

                boost::copy(acq_header.position, im_header.position);
                boost::copy(acq_header.read_dir, im_header.read_dir);
                boost::copy(acq_header.phase_dir, im_header.phase_dir);

                boost::copy(acq_header.slice_dir, im_header.slice_dir);
                boost::copy(acq_header.patient_table_position, im_header.patient_table_position);

                im_header.average    = acq_header.idx.average;
                im_header.slice      = acq_header.idx.slice;
                im_header.contrast   = acq_header.idx.contrast;
                im_header.phase      = acq_header.idx.phase;
                im_header.repetition = acq_header.idx.repetition;
                im_header.set        = acq_header.idx.set;

                im_header.acquisition_time_stamp = acq_header.acquisition_time_stamp;

                boost::copy(acq_header.physiology_time_stamp, im_header.physiology_time_stamp);

                im_header.image_type         = ISMRMRD::ISMRMRD_IMTYPE_MAGNITUDE;
                im_header.image_index        = (uint16_t)(n + s * N + slc * N * S);
                im_header.image_series_index = 0;

                boost::copy(acq_header.user_int, im_header.user_int);
                boost::copy(acq_header.user_float, im_header.user_float);

                im_header.attribute_string_len = 0;

                meta.set("encoding", (long)enc);

                meta.set("encoding_FOV", recon_bit.data_.sampling_.encoded_FOV_[0]);
                meta.append("encoding_FOV", recon_bit.data_.sampling_.encoded_FOV_[1]);
                meta.append("encoding_FOV", recon_bit.data_.sampling_.encoded_FOV_[2]);

                meta.set("recon_FOV", recon_bit.data_.sampling_.recon_FOV_[0]);
                meta.append("recon_FOV", recon_bit.data_.sampling_.recon_FOV_[1]);
                meta.append("recon_FOV", recon_bit.data_.sampling_.recon_FOV_[2]);

                meta.set("encoded_matrix", (long)recon_bit.data_.sampling_.encoded_matrix_[0]);
                meta.append("encoded_matrix", (long)recon_bit.data_.sampling_.encoded_matrix_[1]);
                meta.append("encoded_matrix", (long)recon_bit.data_.sampling_.encoded_matrix_[2]);

                meta.set("recon_matrix", (long)recon_bit.data_.sampling_.recon_matrix_[0]);
                meta.append("recon_matrix", (long)recon_bit.data_.sampling_.recon_matrix_[1]);
                meta.append("recon_matrix", (long)recon_bit.data_.sampling_.recon_matrix_[2]);

                meta.set("sampling_limits_RO", (long)recon_bit.data_.sampling_.sampling_limits_[0].min_);
                meta.append("sampling_limits_RO", (long)recon_bit.data_.sampling_.sampling_limits_[0].center_);
                meta.append("sampling_limits_RO", (long)recon_bit.data_.sampling_.sampling_limits_[0].max_);

                meta.set("sampling_limits_E1", (long)recon_bit.data_.sampling_.sampling_limits_[1].min_);
                meta.append("sampling_limits_E1", (long)recon_bit.data_.sampling_.sampling_limits_[1].center_);
                meta.append("sampling_limits_E1", (long)recon_bit.data_.sampling_.sampling_limits_[1].max_);

                meta.set("sampling_limits_E2", (long)recon_bit.data_.sampling_.sampling_limits_[2].min_);
                meta.append("sampling_limits_E2", (long)recon_bit.data_.sampling_.sampling_limits_[2].center_);
                meta.append("sampling_limits_E2", (long)recon_bit.data_.sampling_.sampling_limits_[2].max_);

                meta.set("PatientPosition", (double)res.headers_(n, s, slc).position[0]);
                meta.append("PatientPosition", (double)res.headers_(n, s, slc).position[1]);
                meta.append("PatientPosition", (double)res.headers_(n, s, slc).position[2]);

                meta.set("read_dir", (double)res.headers_(n, s, slc).read_dir[0]);
                meta.append("read_dir", (double)res.headers_(n, s, slc).read_dir[1]);
                meta.append("read_dir", (double)res.headers_(n, s, slc).read_dir[2]);

                meta.set("phase_dir", (double)res.headers_(n, s, slc).phase_dir[0]);
                meta.append("phase_dir", (double)res.headers_(n, s, slc).phase_dir[1]);
                meta.append("phase_dir", (double)res.headers_(n, s, slc).phase_dir[2]);

                meta.set("slice_dir", (double)res.headers_(n, s, slc).slice_dir[0]);
                meta.append("slice_dir", (double)res.headers_(n, s, slc).slice_dir[1]);
                meta.append("slice_dir", (double)res.headers_(n, s, slc).slice_dir[2]);

                meta.set("patient_table_position", (double)res.headers_(n, s, slc).patient_table_position[0]);
                meta.append("patient_table_position", (double)res.headers_(n, s, slc).patient_table_position[1]);
                meta.append("patient_table_position", (double)res.headers_(n, s, slc).patient_table_position[2]);

                meta.set("acquisition_time_stamp", (long)res.headers_(n, s, slc).acquisition_time_stamp);

                meta.set("physiology_time_stamp", (long)res.headers_(n, s, slc).physiology_time_stamp[0]);
                meta.append("physiology_time_stamp", (long)res.headers_(n, s, slc).physiology_time_stamp[1]);
                meta.append("physiology_time_stamp", (long)res.headers_(n, s, slc).physiology_time_stamp[2]);
            }
        }
    }
}

max_stars_repo_name: roopchansinghv/gadgetron