text:
//------------------------------------------------------------------------------
/*
    This file is part of divvyd: https://github.com/xdv/divvyd
    Copyright (c) 2018 Ripple Labs Inc.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose  with  or without fee is hereby granted, provided that the above
    copyright notice and this permission notice appear in all copies.

    THE  SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    WITH  REGARD  TO  THIS  SOFTWARE  INCLUDING  ALL  IMPLIED  WARRANTIES  OF
    MERCHANTABILITY  AND  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    ANY  SPECIAL ,  DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    WHATSOEVER  RESULTING  FROM  LOSS  OF USE, DATA OR PROFITS, WHETHER IN AN
    ACTION  OF  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <divvy/beast/asio/io_latency_probe.h>
#include <divvy/beast/unit_test.h>
#include <beast/test/yield_to.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <chrono>

using namespace std::chrono_literals;

class io_latency_probe_test :
    public beast::unit_test::suite, public beast::test::enable_yield_to
{
    using MyTimer = boost::asio::basic_waitable_timer<std::chrono::steady_clock>;

    struct test_sampler
    {
        beast::io_latency_probe <std::chrono::steady_clock> probe_;
        std::vector<std::chrono::steady_clock::duration> durations_;

        test_sampler (
            std::chrono::milliseconds interval,
            boost::asio::io_service& ios)
            : probe_ (interval, ios)
        {
        }

        void
        start()
        {
            probe_.sample (std::ref(*this));
        }

        void
        start_one()
        {
            probe_.sample_one (std::ref(*this));
        }

        void operator() (std::chrono::steady_clock::duration const& elapsed)
        {
            durations_.push_back(elapsed);
        }
    };

    void
    testSampleOne(boost::asio::yield_context& yield)
    {
        testcase << "sample one";
        boost::system::error_code ec;
        test_sampler io_probe {100ms, get_io_service()};
        io_probe.start_one();
        MyTimer timer {get_io_service(), 1s};
        timer.async_wait(yield[ec]);
        if(! BEAST_EXPECTS(! ec, ec.message()))
            return;
        BEAST_EXPECT(io_probe.durations_.size() == 1);
        io_probe.probe_.cancel_async();
    }

    void
    testSampleOngoing(boost::asio::yield_context& yield)
    {
        testcase << "sample ongoing";
        boost::system::error_code ec;
        test_sampler io_probe {99ms, get_io_service()};
        io_probe.start();
        MyTimer timer {get_io_service(), 1s};
        timer.async_wait(yield[ec]);
        if(! BEAST_EXPECTS(! ec, ec.message()))
            return;
        auto probes_seen = io_probe.durations_.size();
        BEAST_EXPECTS(probes_seen >=9 && probes_seen <= 11,
            std::string("probe count is ") + std::to_string(probes_seen));
        io_probe.probe_.cancel_async();
        // wait again in order to flush the remaining
        // probes from the work queue
        timer.expires_from_now(1s);
        timer.async_wait(yield[ec]);
    }

    void
    testCanceled(boost::asio::yield_context& yield)
    {
        testcase << "canceled";
        test_sampler io_probe {100ms, get_io_service()};
        io_probe.probe_.cancel_async();
        except<std::logic_error>( [&io_probe](){ io_probe.start_one(); });
        except<std::logic_error>( [&io_probe](){ io_probe.start(); });
    }

public:
    void run () override
    {
        yield_to([&](boost::asio::yield_context& yield)
        {
            testSampleOne (yield);
            testSampleOngoing (yield);
            testCanceled (yield);
        });
    }
};

BEAST_DEFINE_TESTSUITE(io_latency_probe, asio, beast);

max_stars_repo_name: xdvproject/rippled

max_issues_repo_name: xdvproject/rippled

max_forks_repo_name: xdvproject/rippled


text:
#include "./ut_support/UnitTestSupport.hpp"
#include <swizzle/lexer/states/StringLiteralState.hpp>

#include <swizzle/Exceptions.hpp>
#include <swizzle/lexer/Token.hpp>
#include <swizzle/lexer/TokenInfo.hpp>
#include <swizzle/lexer/TokenizerState.hpp>
#include <swizzle/lexer/FileInfo.hpp>

#include <boost/utility/string_view.hpp>
#include <deque>
#include <string>

namespace {
    using namespace swizzle::lexer;

    class CreateTokenCallback
    {
    public:
        CreateTokenCallback(std::deque<TokenInfo>& tokens)
            : tokens_(tokens)
        {
        }

        void operator()(const TokenInfo& info)
        {
            tokens_.push_back(info);
        }

        void operator()(TokenInfo&& info)
        {
            tokens_.emplace_back(info);
        }

    private:
        std::deque<TokenInfo>& tokens_;
    };

    struct StringLiteralFixture
    {
        std::deque<TokenInfo> tokens;
        CreateTokenCallback callback = CreateTokenCallback(tokens);

        FileInfo info = FileInfo("testfile");
        states::StringLiteralState<CreateTokenCallback> state = states::StringLiteralState<CreateTokenCallback>(callback);

        std::size_t position = 0;
    };

    TEST_FIXTURE(StringLiteralFixture, verifyConstruction)
    {
    }

    struct WhenNextCharIsAlpha : public StringLiteralFixture
    {
        const std::string s = "a";
        const boost::string_view sv = boost::string_view(s);

        Token token = Token(sv, 0, 0, TokenType::string_literal);
    };

    TEST_FIXTURE(WhenNextCharIsAlpha, verifyConsume)
    {
        CHECK_EQUAL(0U, tokens.size());

        auto tokenState = state.consume(sv, position++, info, token);

        CHECK_EQUAL(TokenizerState::StringLiteral, tokenState);
        CHECK_EQUAL(TokenType::string_literal, token.type());
        CHECK_EQUAL("a", token.to_string());

        CHECK_EQUAL(0U, tokens.size());
    }

    struct WhenNextCharIsNumber : public StringLiteralFixture
    {
        const std::string s = "4";
        const boost::string_view sv = boost::string_view(s);

        Token token = Token(sv, 0, 0, TokenType::string_literal);
    };

    TEST_FIXTURE(WhenNextCharIsNumber, verifyConsume)
    {
        CHECK_EQUAL(0U, tokens.size());

        auto tokenState = state.consume(sv, position++, info, token);

        CHECK_EQUAL(TokenizerState::StringLiteral, tokenState);
        CHECK_EQUAL(TokenType::string_literal, token.type());
        CHECK_EQUAL("4", token.to_string());

        CHECK_EQUAL(0U, tokens.size());
    }

    struct WhenNextCharIsBackslash : public StringLiteralFixture
    {
        const std::string s = "\\";
        const boost::string_view sv = boost::string_view(s);

        Token token = Token(sv, 0, 0, TokenType::string_literal);
    };

    TEST_FIXTURE(WhenNextCharIsBackslash, verifyConsume)
    {
        CHECK_EQUAL(0U, tokens.size());

        auto tokenState = state.consume(sv, position++, info, token);

        CHECK_EQUAL(TokenizerState::EscapedCharInStringLiteral, tokenState);
        CHECK_EQUAL(TokenType::string_literal, token.type());
        CHECK_EQUAL("\\", token.to_string());

        CHECK_EQUAL(0U, tokens.size());
    }

    struct WhenNextCharIsDoubleQuote : public StringLiteralFixture
    {
        const std::string s = "\"";
        const boost::string_view sv = boost::string_view(s);

        Token token = Token(sv, 0, 0, TokenType::string_literal);
    };

    TEST_FIXTURE(WhenNextCharIsDoubleQuote, verifyConsume)
    {
        CHECK_EQUAL(0U, tokens.size());

        auto tokenState = state.consume(sv, position++, info, token);

        CHECK_EQUAL(TokenizerState::Init, tokenState);

        REQUIRE CHECK_EQUAL(1U, tokens.size());

        CHECK_EQUAL(1U, tokens[0].fileInfo().start().line());
        CHECK_EQUAL(1U, tokens[0].fileInfo().start().column());
        CHECK_EQUAL(1U, tokens[0].fileInfo().end().line());
        CHECK_EQUAL(2U, tokens[0].fileInfo().end().column());
    }
}

ext: cpp

max_stars_repo_name: SenorAgosto/Swizzle

max_issues_repo_name: SenorAgosto/Swizzle

max_forks_repo_name: SenorAgosto/Swizzle


text:
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <regex>
#include <fstream>
#include <boost/algorithm/string.hpp>

#include "../common.hpp"

using namespace std;

bool sum(const vector<int> & nums, int offset, int target) {
    for (int x = offset; x < nums.size(); x++) {
        for (int y = x + 1; y < nums.size(); y++) {
            if ((nums[x] + nums[y]) == target) {
                return true;
            }
        }
    }
    return false;
}

int range(const vector<int> & nums, int offset, int target) {
    int smallest = INT_MAX;
    int largest = 0;
    int total = 0;
    int i = offset;
    while (total < target && i < nums.size()) {
        total += nums[i];

        smallest = min(smallest, nums[i]);
        largest = max(largest, nums[i]);

        i++;
    }
    if (total == target) {
        return smallest + largest;
    }
    return 0;
}

int main() {
    ifstream file ("2020/9.txt");
    if (!file.is_open()) {
        cout << "Failed to open file: " << strerror(errno) << endl;
        return -1;
    }

    int answer1 = 0;
    int answer2 = 0;

    int preamble = 25;
    vector<int> nums;

    string line;
    while (getline(file, line, '\n')) {
        boost::trim(line);

        if (line == "") {
            continue;
        }

        int i = stoi(line);

        if (nums.size() > preamble) {
            // Start checking
            if (!sum(nums, nums.size() - preamble, i)) {
                answer1 = i;
                break;
            }
        }

        nums.push_back(i);
    }

    cout << "Answer 9.1: " << answer1 << endl;

    for (int x = 0; x < nums.size(); x++) {
        answer2 = range(nums, x, answer1);
        if (answer2) {
            break;
        }
    }

    cout << "Answer 9.2: " << answer2 << endl;

    file.close();
}

max_stars_repo_name: bramp/aoc

max_issues_repo_name: bramp/aoc

max_forks_repo_name: bramp/aoc


text:
#include "CCMCTime.h"
#include "cdf.h"
#include "string.h"
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>

namespace ccmc
{

	Time::Time()
	{
		//do nothing
		this->year = 0;
		this->month = 0;
		this->day = 0;
		this->hour = 0;
		this->minute = 0;
		this->seconds = 0;
		this->milliseconds = 0;
		//getEpoch();//update epoch values;
		updateEpoch();
	}
	Time::~Time()
	{
		//destructor for Time object
	}

	Time::Time(const std::string& timeString)
	{
		//extern "C" double parseEPOCH3(char epString[EPOCH3_STRING_LEN+1]);
		//extern "C" void encodeEPOCH3(double epoch, char epString[EPOCH3_STRING_LEN+1]);
		//ensure that it uses '-' instead of '/'
		char timeString_c_str[EPOCH3_STRING_LEN+1];
		strcpy(timeString_c_str, (char *)timeString.c_str());
		timeString_c_str[4] = '-';
		timeString_c_str[7] = '-';
		epoch = parseEPOCH3(timeString_c_str);
		//std::cout << "epoch value in parseTime: " << epoch << std::endl;
		long lyear, lmonth, lday, lhour, lminute, lsecond, lmsec;
		lyear = lmonth = lday = lhour = lminute = lsecond = lmsec = 1;
		EPOCHbreakdown(epoch, &lyear, &lmonth, &lday, &lhour, &lminute, &lsecond, &lmsec);
		year = ((short)lyear);
		month = ((short)lmonth);
		day = ((short)lday);
		hour = ((short)lhour);
		minute = ((short)lminute);
		seconds = ((short)lsecond);
		milliseconds = ((short)lmsec);
	}

	Time::Time(double epochTime)
	{
		EPOCHbreakdown(epochTime, (long*)&year, (long *)&month, (long*)&day, (long*)&hour, (long*)&minute, (long*)&seconds, (long*)&milliseconds);
		this->epoch = epochTime;
	}

	void Time::updateEpoch()
	{
		epoch = computeEPOCH(year, month, day, hour, minute, seconds, milliseconds);
		// std::cout << "epoch: " << epoch << std::endl;
	}

	std::string Time::toString() const
	{
		std::string timeString = "";
		std::string monthStr = "";
		std::string dayStr = "";
		std::string hourStr = "";
		std::string minuteStr = "";
		std::string secondStr = "";
		std::string yearStr = "";
		std::string msecStr = "";
		yearStr = (boost::format("%04d") % boost::lexical_cast<std::string>(year)).str();
		monthStr = (boost::format("%02d") % boost::lexical_cast<std::string>(month)).str();
		dayStr = (boost::format("%02d") % boost::lexical_cast<std::string>(day)).str();
		hourStr = (boost::format("%02d") % boost::lexical_cast<std::string>(hour)).str();
		minuteStr = (boost::format("%02d") % boost::lexical_cast<std::string>(minute)).str();
		secondStr = (boost::format("%02d") % boost::lexical_cast<std::string>(seconds)).str();
		msecStr = (boost::format("%03d") % boost::lexical_cast<std::string>(milliseconds)).str();

		timeString  = yearStr  +  "-" + monthStr + "-" + dayStr + "T" + hourStr + ":" + minuteStr + ":" + secondStr + "." + msecStr + "Z";
		return timeString;
	}

	std::ostream& operator<<(std::ostream& out, const Time time)
	{
		out << time.toString();
		return out;
	}

	double Time::getEpoch() const
	{
		return epoch;
	}

	double operator-(const Time& time1, const Time& time2)
	{
		return time1.getEpoch() - time2.getEpoch();

	}

	bool operator==(const Time& time1, const Time& time2)
	{
		if (time1.getYear() == time2.getYear() &&
			time1.getMonth() == time2.getMonth() &&
			time1.getDay() == time2.getDay() &&
			time1.getHour() == time2.getHour() &&
			time1.getMinute() == time2.getMinute() &&
			time1.getSeconds() == time2.getSeconds() &&
			time1.getMilliseconds() == time2.getMilliseconds())
			return true;
		else
		{
			// std::cout << "time1: " << time1.toString() << " time2: " << time2.toString() << std::endl;
			return false;
		}
	}

	bool operator<(const Time& time1, const Time& time2)
	{
		if (time1.getEpoch() < time2.getEpoch())
			return true;
		else
			return false;
	}

	bool operator>(const Time& time1, const Time& time2)
	{
		if (time1.getEpoch() > time2.getEpoch())
			return true;
		else
			return false;
	}

	bool operator>=(const Time& time1, const Time& time2)
	{
		if (time1 > time2 || time1 == time2)
			return true;
		else
			return false;
	}

	short Time::getDay() const {
		return day;
	}

	void Time::setDay(short day) {
		this->day = day;
		updateEpoch();
	}

	void Time::setEpoch(double epoch) {
		this->epoch = epoch;
	}

	short Time::getHour() const {
		return hour;
	}

	void Time::setHour(short hour) {
		this->hour = hour;
		updateEpoch();
	}

	short Time::getMilliseconds() const {
		return milliseconds;
	}

	void Time::setMilliseconds(short milliseconds) {
		this->milliseconds = milliseconds;
		updateEpoch();
	}

	short Time::getMinute() const {
		return minute;
	}

	void Time::setMinute(short minute) {
		this->minute = minute;
		updateEpoch();
	}

	short Time::getMonth() const {
		return month;
	}

	void Time::setMonth(short month) {
		this->month = month;
		updateEpoch();
	}

	short Time::getSeconds() const {
		return seconds;
	}

	void Time::setSeconds(double seconds) {
		this->seconds = seconds;
		updateEpoch();
	}

	short Time::getYear() const {
		return year;
	}

	void Time::setYear(short year) {
		this->year = year;
		updateEpoch();
	}
}

max_stars_repo_name: alexanderbock/Kameleon-Converter

max_issues_repo_name: alexanderbock/Kameleon-Converter

max_forks_repo_name: alexanderbock/Kameleon-Converter


text:
#pragma once

#include <boost/type_index.hpp>

namespace sfy
{
    template <typename T>
    inline auto type()
    {
        return boost::typeindex::type_id_with_cvr<T>().pretty_name();
    }

    inline auto type(auto&& var)
    {
        return boost::typeindex::type_id_with_cvr<decltype(var)>().pretty_name();
    }
}

ext: hpp

max_stars_repo_name: muqsitnawaz/sfy

max_issues_repo_name: muqsitnawaz/sfy

max_forks_repo_name: muqsitnawaz/sfy


text:
#pragma once

#include <exception>
#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

#include <gsl/span>

#include <boost/filesystem.hpp>
#include <fmt/format.h>

namespace pisa::io {

/// Indicates that a file was not found.
///
/// As opposed to the standard c++ IO error, this one preserves the file name in the message for
/// more informative logging.
class NoSuchFile: public std::exception {
  public:
    explicit NoSuchFile(std::string file) : m_message(fmt::format("No such file: {}", file)) {}
    [[nodiscard]] auto what() const noexcept -> char const* { return m_message.c_str(); }

  private:
    std::string m_message;
};

[[nodiscard]] inline auto resolve_path(std::string const& file) -> boost::filesystem::path
{
    boost::filesystem::path p(file);
    if (not boost::filesystem::exists(p)) {
        throw NoSuchFile(file);
    }
    return p;
}

class Line: public std::string {
    friend std::istream& operator>>(std::istream& is, Line& line) { return std::getline(is, line); }
};

template <typename Integral>
[[nodiscard]] inline auto read_string_map(std::string const& filename)
    -> std::unordered_map<std::string, Integral>
{
    std::unordered_map<std::string, Integral> mapping;
    std::ifstream is(filename);
    std::string line;
    Integral idx{};
    while (std::getline(is, line)) {
        mapping[line] = idx++;
    }
    return mapping;
}

[[nodiscard]] inline auto read_string_vector(std::string const& filename) -> std::vector<std::string>
{
    std::vector<std::string> vec;
    std::ifstream is(filename);
    std::string line;
    while (std::getline(is, line)) {
        vec.push_back(std::move(line));
    }
    return vec;
}

template <typename Function>
void for_each_line(std::istream& is, Function fn)
{
    std::string line;
    while (std::getline(is, line)) {
        fn(line);
    }
}

[[nodiscard]] inline auto load_data(std::string const& data_file)
{
    std::vector<char> data;
    std::ifstream in(data_file.c_str(), std::ios::binary);
    in.seekg(0, std::ios::end);
    std::streamsize size = in.tellg();
    in.seekg(0, std::ios::beg);
    data.resize(size);
    if (not in.read(data.data(), size)) {
        throw std::runtime_error("Failed reading " + data_file);
    }
    return data;
}

inline void write_data(std::string const& data_file, gsl::span<std::byte const> bytes)
{
    std::ofstream os(data_file);
    os.write(reinterpret_cast<char const*>(bytes.data()), bytes.size());
}

}  // namespace pisa::io

max_stars_repo_name: mrgrassho/pisa

max_issues_repo_name: mrgrassho/pisa

max_forks_repo_name: mrgrassho/pisa


text:
/*ckwg +29
 * Copyright 2013-2015 by Kitware, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither name of Kitware, Inc. nor the names of any contributors may be used
 *    to endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * \file
 * \brief Feature tracker utility
 */

#include <iostream>
#include <fstream>
#include <exception>
#include <string>
#include <vector>

#include <maptk/algo/image_io.h>
#include <maptk/algo/compute_ref_homography.h>
#include <maptk/algo/convert_image.h>
#include <maptk/algo/track_features.h>

#include <maptk/algorithm_plugin_manager.h>
#include <maptk/config_block.h>
#include <maptk/config_block_io.h>
#include <maptk/exceptions.h>
#include <maptk/logging_macros.h>
#include <maptk/track_set_io.h>
#include <maptk/types.h>

#include <boost/foreach.hpp>

#include <boost/filesystem.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/value_semantic.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/make_shared.hpp>

namespace bfs = boost::filesystem;

static std::string LOGGING_PREFIX = "track_features_tool";

static maptk::config_block_sptr default_config()
{
  maptk::config_block_sptr config = maptk::config_block::empty_config("feature_tracker_tool");

  config->set_value("image_list_file", "",
                    "Path to an input file containing new-line separated paths "
                    "to sequential image files.");
  config->set_value("mask_list_file", "",
                    "Optional path to an input file containing new-line "
                    "separated paths to mask images. This list should be "
                    "parallel in association to files specified in "
                    "``image_list_file``. Mask image must be the same size as "
                    "the image they are associated with.\n"
                    "\n"
                    "Leave this blank if no image masking is desired.");
  config->set_value("invert_masks", false,
                    "If true, all mask images will be inverted after loading. "
                    "This is useful if mask images read in use positive "
                    "values to indicated masked areas instead of non-masked "
                    "areas.");
  config->set_value("expect_multichannel_masks", false,
                    "A majority of the time, mask images are a single channel, "
                    "however it is feasibly possible that certain "
                    "implementations may use multi-channel masks. If this is "
                    "true we will expect multiple-channel mask images, "
                    "warning when a single-channel mask is provided. If this "
                    "is false we error upon seeing a multi-channel mask "
                    "image.");
  config->set_value("output_tracks_file", "",
                    "Path to a file to write output tracks to. If this "
                    "file exists, it will be overwritten.");
  config->set_value("output_homography_file", "",
                    "Optional path to a file to write source-to-reference "
                    "homographies for each frame. Leave blank to disable this "
                    "output. The output_homography_generator algorithm type "
                    "only needs to be set if this is set.");

  maptk::algo::track_features::get_nested_algo_configuration("feature_tracker", config, maptk::algo::track_features_sptr());
  maptk::algo::image_io::get_nested_algo_configuration("image_reader", config, maptk::algo::image_io_sptr());
  maptk::algo::convert_image::get_nested_algo_configuration("convert_image", config, maptk::algo::convert_image_sptr());
  maptk::algo::compute_ref_homography::get_nested_algo_configuration("output_homography_generator",
                                                                     config, maptk::algo::compute_ref_homography_sptr());
  return config;
}

static bool check_config(maptk::config_block_sptr config)
{
  bool config_valid = true;

#define MAPTK_CONFIG_FAIL(msg) \
  std::cerr << "Config Check Fail: " << msg << std::endl; \
  config_valid = false

  // A given homography file is invalid if it names a directory, or if its
  // parent path either doesn't exist or names a regular file.
  if ( config->has_value("output_homography_file")
    && config->get_value<std::string>("output_homography_file") != "" )
  {
    maptk::path_t fp = config->get_value<maptk::path_t>("output_homography_file");
    if ( bfs::is_directory(fp) )
    {
      MAPTK_CONFIG_FAIL("Given output homography file is a directory! "
                        << "(Given: " << fp << ")");
    }
    else if ( fp.parent_path() != "" &&
              ( (!bfs::is_directory(fp.parent_path())) ||
                 bfs::is_regular_file(fp.parent_path()) ) )
    {
      MAPTK_CONFIG_FAIL("Given output homography file does not have a valid "
                        << "parent path! (Given: " << fp << ")");
    }

    // Check that compute_ref_homography algo is correctly configured
    if( !maptk::algo::compute_ref_homography
             ::check_nested_algo_configuration("output_homography_generator",
                                               config) )
    {
      MAPTK_CONFIG_FAIL("output_homography_generator configuration check failed");
    }
  }

  if (!config->has_value("image_list_file") ||
      config->get_value<std::string>("image_list_file") == "")
  {
    MAPTK_CONFIG_FAIL("Config needs value image_list_file");
  }
  else
  {
    std::string path = config->get_value<std::string>("image_list_file");
    if (!bfs::exists(maptk::path_t(path)))
    {
      MAPTK_CONFIG_FAIL("image_list_file path, " << path << ", does not exist");
    }
    else if (!bfs::is_regular_file(maptk::path_t(path)))
    {
      MAPTK_CONFIG_FAIL("image_list_file path, " << path << ", is not a regular file");
    }
  }

  // If given an mask image list file, check that the file exists and is a file
  if (config->has_value("mask_list_file") && config->get_value<std::string>("mask_list_file") != "" )
  {
    std::string mask_list_file = config->get_value<std::string>("mask_list_file");
    if (mask_list_file != "" && bfs::is_regular_file( maptk::path_t(mask_list_file) ))
    {
      MAPTK_CONFIG_FAIL("mask_list_file path, " << mask_list_file << ", does not exist");
    }
  }

  if (!config->has_value("output_tracks_file") ||
      config->get_value<std::string>("output_tracks_file") == "" )
  {
    MAPTK_CONFIG_FAIL("Config needs value output_tracks_file");
  }
  else if (!bfs::is_directory(bfs::absolute(
               config->get_value<maptk::path_t>("output_tracks_file")).parent_path()))
  {
    MAPTK_CONFIG_FAIL("output_tracks_file is not in a valid directory");
  }

  if (!maptk::algo::track_features::check_nested_algo_configuration("feature_tracker", config))
  {
    MAPTK_CONFIG_FAIL("feature_tracker configuration check failed");
  }

  if (!maptk::algo::image_io::check_nested_algo_configuration("image_reader", config))
  {
    MAPTK_CONFIG_FAIL("image_reader configuration check failed");
  }

  if (!maptk::algo::convert_image::check_nested_algo_configuration("convert_image", config))
  {
    MAPTK_CONFIG_FAIL("convert_image configuration check failed");
  }

#undef MAPTK_CONFIG_FAIL

  return config_valid;
}

static maptk::image::byte invert_mask_pixel( maptk::image::byte const &b )
{
  return !b;
}

#define print_config(config) \
  do \
  { \
    BOOST_FOREACH( maptk::config_block_key_t key, config->available_values() ) \
    { \
      std::cerr << "\t" \
           << key << " = " << config->get_value<maptk::config_block_key_t>(key) \
           << std::endl; \
    } \
  } while (false)

static int maptk_main(int argc, char const* argv[])
{
  // register the algorithm implementations
  maptk::algorithm_plugin_manager::instance().register_plugins();

  // define/parse CLI options
  boost::program_options::options_description opt_desc;
  opt_desc.add_options()
    ("help,h", "output help message and exit")
    ("config,c",
     boost::program_options::value<maptk::path_t>(),
     "Configuration file for the tool.")
    ("output-config,o",
     boost::program_options::value<maptk::path_t>(),
     "Output a configuration.This may be seeded with a configuration file from -c/--config.")
    ;
  boost::program_options::variables_map vm;

  try
  {
    boost::program_options::store(boost::program_options::parse_command_line(argc, argv, opt_desc),
                                  vm);
  }
  catch (boost::program_options::unknown_option const& e)
  {
    std::cerr << "Error: unknown option " << e.get_option_name() << std::endl;
    return EXIT_FAILURE;
  }

  boost::program_options::notify(vm);

  if(vm.count("help"))
  {
    std::cerr << opt_desc << std::endl;
    return EXIT_SUCCESS;
  }

  // Set config to algo chain
  // Get config from algo chain after set
  // Check config validity, store result
  //
  // If -o/--output-config given, output config result and notify of current (in)validity
  // Else error if provided config not valid.

  namespace algo = maptk::algo;
  namespace bfs = boost::filesystem;

  // Set up top level configuration w/ defaults where applicable.
  maptk::config_block_sptr config = default_config();
  algo::track_features_sptr feature_tracker;
  algo::image_io_sptr image_reader;
  algo::convert_image_sptr image_converter;
  algo::compute_ref_homography_sptr out_homog_generator;

  // If -c/--config given, read in confg file, merge in with default just generated
  if(vm.count("config"))
  {
    //std::cerr << "[DEBUG] Given config file: " << vm["config"].as<maptk::path_t>() << std::endl;
    config->merge_config(maptk::read_config_file(vm["config"].as<maptk::path_t>()));
  }

  //std::cerr << "[DEBUG] Config BEFORE set:" << std::endl;
  //print_config(config);

  algo::track_features::set_nested_algo_configuration("feature_tracker", config, feature_tracker);
  algo::track_features::get_nested_algo_configuration("feature_tracker", config, feature_tracker);
  algo::image_io::set_nested_algo_configuration("image_reader", config, image_reader);
  algo::image_io::get_nested_algo_configuration("image_reader", config, image_reader);
  algo::convert_image::set_nested_algo_configuration("convert_image", config, image_converter);
  algo::convert_image::get_nested_algo_configuration("convert_image", config, image_converter);
  algo::compute_ref_homography::set_nested_algo_configuration("output_homography_generator", config, out_homog_generator);
  algo::compute_ref_homography::get_nested_algo_configuration("output_homography_generator", config, out_homog_generator);

  //std::cerr << "[DEBUG] Config AFTER set:" << std::endl;
  //print_config(config);

  bool valid_config = check_config(config);

  if(vm.count("output-config"))
  {
    //std::cerr << "[DEBUG] Given config output target: " << vm["output-config"].as<maptk::path_t>() << std::endl;
    write_config_file(config, vm["output-config"].as<maptk::path_t>());
    if(valid_config)
    {
      std::cerr << "INFO: Configuration file contained valid parameters and may be used for running" << std::endl;
    }
    else
    {
      std::cerr << "WARNING: Configuration deemed not valid." << std::endl;
    }
    return EXIT_SUCCESS;
  }
  else if(!valid_config)
  {
    std::cerr << "ERROR: Configuration not valid." << std::endl;
    return EXIT_FAILURE;
  }

  // Attempt opening input and output files.
  //  - filepath validity checked above
  std::string image_list_file = config->get_value<std::string>("image_list_file");
  std::string mask_list_file = config->get_value<std::string>("mask_list_file");
  bool invert_masks = config->get_value<bool>("invert_masks");
  bool expect_multichannel_masks = config->get_value<bool>("expect_multichannel_masks");
  std::string output_tracks_file = config->get_value<std::string>("output_tracks_file");

  std::ifstream ifs(image_list_file.c_str());
  if (!ifs)
  {
    std::cerr << "Error: Could not open image list \""<<image_list_file<<"\""<<std::endl;
    return EXIT_FAILURE;
  }
  // Creating input image list, checking file existance
  std::vector<maptk::path_t> files;
  for (std::string line; std::getline(ifs,line); )
  {
    files.push_back(line);
    if (!bfs::exists(files[files.size()-1]))
    {
      throw maptk::path_not_exists(files[files.size()-1]);
    }
  }

  // Create mask image list if a list file was given, else fill list with empty
  // images. Files vector will only be populated if the use_masks bool is true
  bool use_masks = false;
  std::vector<maptk::path_t> mask_files;
  if( mask_list_file != "" )
  {
    LOG_DEBUG( LOGGING_PREFIX,
               "Loading paired mask images from list file" );

    use_masks = true;
    // Load file stream
    std::ifstream mask_ifs(mask_list_file.c_str());
    if( !mask_ifs )
    {
      throw maptk::path_not_exists(mask_list_file);
    }
    // load filepaths from file
    for( std::string line; std::getline(mask_ifs, line); )
    {
      mask_files.push_back(line);
      if( !bfs::is_regular_file( mask_files[mask_files.size()-1] ) )
      {
        throw maptk::path_not_exists( mask_files[mask_files.size()-1] );
      }
    }
    // Check that image/mask list sizes are the same
    if( files.size() != mask_files.size() )
    {
      throw maptk::invalid_value("Image and mask file lists are not congruent "
                                 "in size.");
    }
    LOG_DEBUG( LOGGING_PREFIX,
               "Loaded " << mask_files.size() << " mask image files." );
  }

  // verify that we can open the output file for writing
  // so that we don't find a problem only after spending
  // hours of computation time.
  std::ofstream ofs(output_tracks_file.c_str());
  if (!ofs)
  {
    std::cerr << "Error: Could not open track file for writing: \""
              << output_tracks_file << "\"" << std::endl;
    return EXIT_FAILURE;
  }
  ofs.close();

  // Create the output homography file stream if specified
  // Validity of file path checked during configuration file validity check.
  std::ofstream homog_ofs;
  if ( config->has_value("output_homography_file") &&
       config->get_value<std::string>("output_homography_file") != "" )
  {
    maptk::path_t homog_fp = config->get_value<maptk::path_t>("output_homography_file");
    homog_ofs.open( homog_fp.string().c_str() );
    if ( !homog_ofs )
    {
      std::cerr << "Error: Could not open homography file for writing: "
                << homog_fp
                << std::endl;
      return EXIT_FAILURE;
    }
  }

  // Track features on each frame sequentially
  maptk::track_set_sptr tracks;
  for(unsigned i=0; i<files.size(); ++i)
  {
    std::cout << "processing frame "<<i<<": "<<files[i]<<std::endl;

    //maptk::image_container_sptr img = image_reader->load(files[i].string());
    //maptk::image_container_sptr converted = image_converter->convert(img);

    maptk::image_container_sptr converted_img,
                                mask, converted_mask;
    converted_img = image_converter->convert( image_reader->load( files[i].string() ) );

    // Load the mask for this image if we were given a mask image list
    if( use_masks )
    {
      mask = image_reader->load( mask_files[i].string() );

      // error out if we are not expecting a multi-channel mask
      if( !expect_multichannel_masks && mask->depth() > 1 )
      {
        LOG_ERROR( LOGGING_PREFIX,
                   "Encounted multi-channel mask image!" );
        return EXIT_FAILURE;
      }
      else if( expect_multichannel_masks && mask->depth() == 1 )
      {
        LOG_WARN( LOGGING_PREFIX,
                  "Expecting multi-channel masks but received one that was "
                  "single-channel." );
      }

      if( invert_masks )
      {
        LOG_DEBUG( LOGGING_PREFIX,
                   "Inverting mask image pixels" );
        maptk::image mask_img( mask->get_image() );
        maptk::transform_image( mask_img, invert_mask_pixel );
        LOG_DEBUG( LOGGING_PREFIX,
                   "Inverting mask image pixels -- Done" );
      }

      converted_mask = image_converter->convert( mask );
    }

    tracks = feature_tracker->track(tracks, i, converted_img, converted_mask);

    // Compute ref homography for current frame with current track set + write to file
    // -> still doesn't take into account a full shotbreak, which would incur a track reset
    if ( homog_ofs.is_open() )
    {
      std::cout << "\twritting homography" << std::endl;
      homog_ofs << *(out_homog_generator->estimate(i, tracks)) << std::endl;
    }
  }

  if ( homog_ofs.is_open() )
  {
    homog_ofs.close();
  }

  // Writing out tracks to file
  maptk::write_track_file(tracks, output_tracks_file);

  return EXIT_SUCCESS;
}

int main(int argc, char const* argv[])
{
  try
  {
    return maptk_main(argc, argv);
  }
  catch (std::exception const& e)
  {
    std::cerr << "Exception caught: " << e.what() << std::endl;

    return EXIT_FAILURE;
  }
  catch (...)
  {
    std::cerr << "Unknown exception caught" << std::endl;

    return EXIT_FAILURE;
  }
}

ext: cxx

max_stars_repo_name: efernandez/maptk

max_issues_repo_name: efernandez/maptk

max_forks_repo_name: efernandez/maptk