<commit_before>#include "includes.h"
#include "spdlog/sinks/dup_filter_sink.h"
#include "test_sink.h"

using namespace spdlog;
using namespace spdlog::sinks;

TEST_CASE("dup_filter_test1", "[dup_filter_sink]")
{
    dup_filter_sink_st dup_sink{std::chrono::seconds{5}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    for (int i = 0; i < 10; i++)
    {
        dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
    }

    REQUIRE(test_sink->msg_counter() == 1);
}

TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
{
    dup_filter_sink_st dup_sink{std::chrono::seconds{0}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    for (int i = 0; i < 10; i++)
    {
        dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
        std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }

    REQUIRE(test_sink->msg_counter() == 10);
}

TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
{
    dup_filter_sink_st dup_sink{std::chrono::seconds{0}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    for (int i = 0; i < 10; i++)
    {
        dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
        dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"});
    }

    REQUIRE(test_sink->msg_counter() == 20);
}

TEST_CASE("dup_filter_test4", "[dup_filter_sink]")
{
    dup_filter_sink_mt dup_sink{std::chrono::milliseconds{10}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"});
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"});
    REQUIRE(test_sink->msg_counter() == 2);
}

TEST_CASE("dup_filter_test5", "[dup_filter_sink]")
{
    dup_filter_sink_mt dup_sink{std::chrono::seconds{5}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"});

    REQUIRE(test_sink->msg_counter() == 3); // skip 2 messages but log the "skipped.." message before message2
}
<commit_msg>Fixed dup_filter test<commit_after>#include "includes.h"
#include "spdlog/sinks/dup_filter_sink.h"
#include "test_sink.h"

using namespace spdlog;
using namespace spdlog::sinks;

TEST_CASE("dup_filter_test1", "[dup_filter_sink]")
{
    dup_filter_sink_st dup_sink{std::chrono::seconds{5}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    for (int i = 0; i < 10; i++)
    {
        dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
    }

    REQUIRE(test_sink->msg_counter() == 1);
}

TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
{
    dup_filter_sink_st dup_sink{std::chrono::seconds{0}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    for (int i = 0; i < 10; i++)
    {
        dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
        std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }

    REQUIRE(test_sink->msg_counter() == 10);
}

TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
{
    dup_filter_sink_st dup_sink{std::chrono::seconds{1}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    for (int i = 0; i < 10; i++)
    {
        dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
        dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"});
    }

    REQUIRE(test_sink->msg_counter() == 20);
}

TEST_CASE("dup_filter_test4", "[dup_filter_sink]")
{
    dup_filter_sink_mt dup_sink{std::chrono::milliseconds{10}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"});
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"});
    REQUIRE(test_sink->msg_counter() == 2);
}

TEST_CASE("dup_filter_test5", "[dup_filter_sink]")
{
    dup_filter_sink_mt dup_sink{std::chrono::seconds{5}};
    auto test_sink = std::make_shared<test_sink_mt>();
    dup_sink.add_sink(test_sink);

    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"});
    dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"});

    REQUIRE(test_sink->msg_counter() == 3); // skip 2 messages but log the "skipped.." message before message2
}
<|endoftext|>


<commit_before>#ifndef GUI_PROCESS_HPP
#define GUI_PROCESS_HPP

class wxWindow;
class wxString;

namespace Slic3r {
namespace GUI {

// Start a new slicer instance, optionally with a file to open.
void start_new_slicer(const wxString *path_to_open = nullptr, bool single_instance = false);
void start_new_slicer(const std::vector<wxString>& files, bool single_instance = false);

// Start a new G-code viewer instance, optionally with a file to open.
void start_new_gcodeviewer(const wxString *path_to_open = nullptr);
// Open a file dialog, ask the user to select a new G-code to open, start a new G-code viewer.
void start_new_gcodeviewer_open_file(wxWindow *parent = nullptr);

} // namespace GUI
} // namespace Slic3r

#endif // GUI_PROCESS_HPP
<commit_msg>Added a missing include<commit_after>#ifndef GUI_PROCESS_HPP
#define GUI_PROCESS_HPP

#include <vector>

class wxWindow;
class wxString;

namespace Slic3r {
namespace GUI {

// Start a new slicer instance, optionally with a file to open.
void start_new_slicer(const wxString *path_to_open = nullptr, bool single_instance = false);
void start_new_slicer(const std::vector<wxString>& files, bool single_instance = false);

// Start a new G-code viewer instance, optionally with a file to open.
void start_new_gcodeviewer(const wxString *path_to_open = nullptr);
// Open a file dialog, ask the user to select a new G-code to open, start a new G-code viewer.
void start_new_gcodeviewer_open_file(wxWindow *parent = nullptr);

} // namespace GUI
} // namespace Slic3r

#endif // GUI_PROCESS_HPP
<|endoftext|>


<commit_before>// timer.cpp
// 30. April 2017
// Created by:
// 		Bryan Burkhardt (bmburkhardt@alaska.edu)
// 		Alexander Eckert (aeckert@alaska.edu)
// 		Jeremiah Jacobson (jjacobson2@alaska.edu)
// 		Jarye Murphy (jmurphy11@alaska.edu)
// 		Cameron Showalter (cjshowalter@alaska.edu)
//
// Source file for timer

#include <iomanip>

#include "../include/timer.hpp"

/****** Timer Functions ******/

void Timer::updateTimer() {
	/****** Current Timer Stuff ******/
	currentTimer = music->_music.getPlayingOffset();
	currentTimeSeconds = (int)currentTimer.asSeconds();
	currentTimeMinutes = convertToMinutes((int)currentTimer.asSeconds());
	currentTimeHours = convertToHours((int) currentTimeSeconds);
	currentTimerStreamSeconds.str("");
	currentTimerStreamMinutes.str("");
	currentTimerStreamHours.str("");
	currentTimerStreamSeconds << std::fixed << std::setprecision(0) << (int) currentTimeSeconds % 60;
	currentTimerStreamMinutes << std::fixed << std::setprecision(0) << ((int)currentTimeMinutes%60);
	currentTimerStreamHours << std::fixed << std::setprecision(0) << (currentTimeHours);

	/****** Total Timer Stuff ******/
	totalTimer = music->_music.getDuration();
	totalTimeSeconds = (int)totalTimer.asSeconds();
	totalTimeMinutes = convertToMinutes((int) totalTimeSeconds);
	totalTimeHours = convertToHours((int) totalTimeSeconds);
	totalTimerStreamSeconds.str("");
	totalTimerStreamMinutes.str("");
	totalTimerStreamHours.str("");
	totalTimerStreamSeconds << std::fixed << std::setprecision(0) << (int) totalTimeSeconds % 60;
	totalTimerStreamMinutes << std::fixed << std::setprecision(0) << ((int)totalTimeMinutes%60);
	totalTimerStreamHours << std::fixed << std::setprecision(0) << (totalTimeHours);

	// Seconds
	if ((int)currentTimeSeconds%60 < 10) {
		currentSec = "0" + currentTimerStreamSeconds.str() + "/";
	}
	else {
		currentSec = currentTimerStreamSeconds.str() + "/";
	}
	if((int)totalTimeSeconds%60 < 10) {
			totalSec = "0" + totalTimerStreamSeconds.str();
	}
	else {
		totalSec = totalTimerStreamSeconds.str();
	}
	// Minutes
	if((int)currentTimeMinutes%60 < 10 && (int)totalTimeMinutes < 10 && (int)totalTimeHours < 1) {
		currentMin = currentTimerStreamMinutes.str() + ":";
		totalMin = totalTimerStreamMinutes.str() + ":";
	}
	else if((int)currentTimeMinutes%60 < 10 && (int)totalTimeMinutes > 9 && (int)totalTimeHours < 1) {
		currentMin = "0" + currentTimerStreamMinutes.str() + ":";
		totalMin = totalTimerStreamMinutes.str() + ":";
	}
	else if((int)currentTimeMinutes%60 < 10 && (int)totalTimeHours > 0) {
		currentMin = "0" + currentTimerStreamMinutes.str() + ":";
		totalMin = "0" + totalTimerStreamMinutes.str() + ":";
	}
	else {
		currentMin = currentTimerStreamMinutes.str() + ":";
		totalMin = totalTimerStreamMinutes.str() + ":";
	}
	// Hours
	currentHour = currentTimerStreamHours.str() + ":";
	totalHour = totalTimerStreamHours.str() + ":";

}

std::string Timer::selectDisplayTimer() {
	std::string rv = "";

	if(music->_music.getStatus() == 0) {
		music->callNextSong();
	}
	// 0:xx
	if(totalTimeMinutes < 1) {
		rv = "0:";
		rv += currentSec + "0:";
		rv += totalSec;
		return rv;
	}
	// xx:xx
	else if(currentTimeHours < 1 && totalTimeHours < 1 && totalTimeMinutes > 1) {
		return currentMin + currentSec + totalMin + totalSec;
	}
	// xx:xx:xx
	else {
		return currentHour + currentMin + currentSec + totalHour + totalMin + totalSec;
	}
}

void Timer::displayTimer() {
	updateTimer();
	selectDisplayTimer();
}

int Timer::convertToMinutes(int seconds) {
	return seconds/60;
}

int Timer::convertToHours(int seconds) {
	return (seconds/(60*60));
}

Timer::Timer(std::shared_ptr<Music> music) : music(music) {
}<commit_msg>fixed timer bug<commit_after>// timer.cpp
// 30. April 2017
// Created by:
// 		Bryan Burkhardt (bmburkhardt@alaska.edu)
// 		Alexander Eckert (aeckert@alaska.edu)
// 		Jeremiah Jacobson (jjacobson2@alaska.edu)
// 		Jarye Murphy (jmurphy11@alaska.edu)
// 		Cameron Showalter (cjshowalter@alaska.edu)
//
// Source file for timer

#include <iomanip>

#include "../include/timer.hpp"

/****** Timer Functions ******/

void Timer::updateTimer() {
	/****** Current Timer Stuff ******/
	currentTimer = music->_music.getPlayingOffset();
	currentTimeSeconds = (int)currentTimer.asSeconds();
	currentTimeMinutes = convertToMinutes((int)currentTimer.asSeconds());
	currentTimeHours = convertToHours((int) currentTimeSeconds);
	currentTimerStreamSeconds.str("");
	currentTimerStreamMinutes.str("");
	currentTimerStreamHours.str("");
	currentTimerStreamSeconds << std::fixed << std::setprecision(0) << (int) currentTimeSeconds % 60;
	currentTimerStreamMinutes << std::fixed << std::setprecision(0) << ((int)currentTimeMinutes%60);
	currentTimerStreamHours << std::fixed << std::setprecision(0) << (currentTimeHours);

	/****** Total Timer Stuff ******/
	totalTimer = music->_music.getDuration();
	totalTimeSeconds = (int)totalTimer.asSeconds();
	totalTimeMinutes = convertToMinutes((int) totalTimeSeconds);
	totalTimeHours = convertToHours((int) totalTimeSeconds);
	totalTimerStreamSeconds.str("");
	totalTimerStreamMinutes.str("");
	totalTimerStreamHours.str("");
	totalTimerStreamSeconds << std::fixed << std::setprecision(0) << (int) totalTimeSeconds % 60;
	totalTimerStreamMinutes << std::fixed << std::setprecision(0) << ((int)totalTimeMinutes%60);
	totalTimerStreamHours << std::fixed << std::setprecision(0) << (totalTimeHours);

	// Seconds
	if ((int)currentTimeSeconds%60 < 10) {
		currentSec = "0" + currentTimerStreamSeconds.str() + "/";
	}
	else {
		currentSec = currentTimerStreamSeconds.str() + "/";
	}
	if((int)totalTimeSeconds%60 < 10) {
			totalSec = "0" + totalTimerStreamSeconds.str();
	}
	else {
		totalSec = totalTimerStreamSeconds.str();
	}
	// Minutes
	if((int)currentTimeMinutes%60 < 10 && (int)totalTimeMinutes < 10 && (int)totalTimeHours < 1) {
		currentMin = currentTimerStreamMinutes.str() + ":";
		totalMin = totalTimerStreamMinutes.str() + ":";
	}
	else if((int)currentTimeMinutes%60 < 10 && (int)totalTimeMinutes > 9 && (int)totalTimeHours < 1) {
		currentMin = "0" + currentTimerStreamMinutes.str() + ":";
		totalMin = totalTimerStreamMinutes.str() + ":";
	}
	else if((int)currentTimeMinutes%60 < 10 && (int)totalTimeMinutes%60 < 10 && (int)totalTimeHours > 0) {
		currentMin = "0" + currentTimerStreamMinutes.str() + ":";
		totalMin = "0" + totalTimerStreamMinutes.str() + ":";
	}
	else {
		currentMin = currentTimerStreamMinutes.str() + ":";
		totalMin = totalTimerStreamMinutes.str() + ":";
	}
	// Hours
	currentHour = currentTimerStreamHours.str() + ":";
	totalHour = totalTimerStreamHours.str() + ":";

}

std::string Timer::selectDisplayTimer() {
	std::string rv = "";

	if(music->_music.getStatus() == 0) {
		music->callNextSong();
	}
	// 0:xx
	if(totalTimeMinutes < 1) {
		rv = "0:";
		rv += currentSec + "0:";
		rv += totalSec;
		return rv;
	}
	// xx:xx
	else if(currentTimeHours < 1 && totalTimeHours < 1 && totalTimeMinutes > 1) {
		return currentMin + currentSec + totalMin + totalSec;
	}
	// xx:xx:xx
	else {
		return currentHour + currentMin + currentSec + totalHour + totalMin + totalSec;
	}
}

void Timer::displayTimer() {
	updateTimer();
	selectDisplayTimer();
}

int Timer::convertToMinutes(int seconds) {
	return seconds/60;
}

int Timer::convertToHours(int seconds) {
	return (seconds/(60*60));
}

Timer::Timer(std::shared_ptr<Music> music) : music(music) {
}<|endoftext|>


<commit_before>
#if !defined(MAX_TIMERS)
#define MAX_TIMERS MAX_WORKER_THREADS
#endif

typedef int (*taction)(void *arg);

struct ttimer {
	double time;
	double period;
	taction action;
	void *arg;
};

struct ttimers {
	pthread_t threadid;               /* Timer thread ID */
	pthread_mutex_t mutex;            /* Protects timer lists */
	struct ttimer timers[MAX_TIMERS]; /* List of timers */
	unsigned timer_count;             /* Current size of timer list */
};

static double
timer_getcurrenttime(void)
{
#if defined(_WIN32)
	/* GetTickCount returns milliseconds since system start as
	 * unsigned 32 bit value. It will wrap around every 49.7 days.
	 * We need to use a 64 bit counter (will wrap in 500 mio. years),
	 * by adding the 32 bit difference since the last call to a
	 * 64 bit counter. This algorithm will only work, if this
	 * function is called at least once every 7 weeks. */
	static DWORD last_tick;
	static uint64_t now_tick64;

	DWORD now_tick = GetTickCount();

	now_tick64 += ((DWORD)(now_tick - last_tick));
	last_tick = now_tick;
	return (double)now_tick64 * 1.0E-3;
#else
	struct timespec now_ts;

	clock_gettime(CLOCK_MONOTONIC, &now);
	return (double)now.tv_sec + (double)now.tv_nsec * 1.0E-9;
#endif
}

static int
timer_add(struct mg_context *ctx,
          double next_time,
          double period,
          int is_relative,
          taction action,
          void *arg)
{
	unsigned u, v;
	int error = 0;
	double now;

	if (ctx->stop_flag) {
		return 0;
	}

	now = timer_getcurrenttime();

	/* HCP24: if is_relative = 0 and next_time < now
	 *        action will be called so fast as possible
	 *        if additional period > 0
	 *        action will be called so fast as possible
	 *        n times until (next_time + (n * period)) > now
	 *        then the period is working
	 * Solution:
	 *        if next_time < now then we set next_time = now.
	 *        The first callback will be so fast as possible (now)
	 *        but the next callback on period
	*/
	if (is_relative) {
		next_time += now;
	}

	/* You can not set timers into the past */
	if (next_time < now) {
		next_time = now;
	}

	pthread_mutex_lock(&ctx->timers->mutex);
	if (ctx->timers->timer_count == MAX_TIMERS) {
		error = 1;
	} else {
		/* Insert new timer into a sorted list. */
		/* The linear list is still most efficient for short lists (small
		 * number of timers) - if there are many timers, different
		 * algorithms will work better. */
		for (u = 0; u < ctx->timers->timer_count; u++) {
			if (ctx->timers->timers[u].time > next_time) {
				/* HCP24: moving all timers > next_time */
				for (v = ctx->timers->timer_count; v > u; v--) {
					ctx->timers->timers[v] = ctx->timers->timers[v - 1];
				}
				break;
			}
		}
		ctx->timers->timers[u].time = next_time;
		ctx->timers->timers[u].period = period;
		ctx->timers->timers[u].action = action;
		ctx->timers->timers[u].arg = arg;
		ctx->timers->timer_count++;
	}
	pthread_mutex_unlock(&ctx->timers->mutex);
	return error;
}

static void
timer_thread_run(void *thread_func_param)
{
	struct mg_context *ctx = (struct mg_context *)thread_func_param;
	double d;
	unsigned u;
	int re_schedule;
	struct ttimer t;

	mg_set_thread_name("timer");

	if (ctx->callbacks.init_thread) {
		/* Timer thread */
		ctx->callbacks.init_thread(ctx, 2);
	}

	d = timer_getcurrenttime();

	while (ctx->stop_flag == 0) {
		pthread_mutex_lock(&ctx->timers->mutex);
		if ((ctx->timers->timer_count > 0)
		    && (d >= ctx->timers->timers[0].time)) {
			t = ctx->timers->timers[0];
			for (u = 1; u < ctx->timers->timer_count; u++) {
				ctx->timers->timers[u - 1] = ctx->timers->timers[u];
			}
			ctx->timers->timer_count--;
			pthread_mutex_unlock(&ctx->timers->mutex);
			re_schedule = t.action(t.arg);
			if (re_schedule && (t.period > 0)) {
				timer_add(ctx, t.time + t.period, t.period, 0, t.action, t.arg);
			}
			continue;
		} else {
			pthread_mutex_unlock(&ctx->timers->mutex);
		}

/* 10 ms seems reasonable.
 * A faster loop (smaller sleep value) increases CPU load,
 * a slower loop (higher sleep value) decreases timer accuracy.
 */
#ifdef _WIN32
		Sleep(10);
#else
		usleep(10000);
#endif

		d = timer_getcurrenttime();
	}
	ctx->timers->timer_count = 0;
}

#ifdef _WIN32
static unsigned __stdcall timer_thread(void *thread_func_param)
{
	timer_thread_run(thread_func_param);
	return 0;
}
#else
static void *
timer_thread(void *thread_func_param)
{
	timer_thread_run(thread_func_param);
	return NULL;
}
#endif /* _WIN32 */

static int
timers_init(struct mg_context *ctx)
{
	ctx->timers = (struct ttimers *)mg_calloc(sizeof(struct ttimers), 1);
	(void)pthread_mutex_init(&ctx->timers->mutex, NULL);

	(void)timer_getcurrenttime();

	/* Start timer thread */
	mg_start_thread_with_id(timer_thread, ctx, &ctx->timers->threadid);

	return 0;
}

static void
timers_exit(struct mg_context *ctx)
{
	if (ctx->timers) {
		pthread_mutex_lock(&ctx->timers->mutex);
		ctx->timers->timer_count = 0;
		(void)pthread_mutex_destroy(&ctx->timers->mutex);
		mg_free(ctx->timers);
	}
}
<commit_msg>Fix copy/paste error for Linux<commit_after>
#if !defined(MAX_TIMERS)
#define MAX_TIMERS MAX_WORKER_THREADS
#endif

typedef int (*taction)(void *arg);

struct ttimer {
	double time;
	double period;
	taction action;
	void *arg;
};

struct ttimers {
	pthread_t threadid;               /* Timer thread ID */
	pthread_mutex_t mutex;            /* Protects timer lists */
	struct ttimer timers[MAX_TIMERS]; /* List of timers */
	unsigned timer_count;             /* Current size of timer list */
};

static double
timer_getcurrenttime(void)
{
#if defined(_WIN32)
	/* GetTickCount returns milliseconds since system start as
	 * unsigned 32 bit value. It will wrap around every 49.7 days.
	 * We need to use a 64 bit counter (will wrap in 500 mio. years),
	 * by adding the 32 bit difference since the last call to a
	 * 64 bit counter. This algorithm will only work, if this
	 * function is called at least once every 7 weeks. */
	static DWORD last_tick;
	static uint64_t now_tick64;

	DWORD now_tick = GetTickCount();

	now_tick64 += ((DWORD)(now_tick - last_tick));
	last_tick = now_tick;
	return (double)now_tick64 * 1.0E-3;
#else
	struct timespec now_ts;

	clock_gettime(CLOCK_MONOTONIC, &now_ts);
	return (double)now_ts.tv_sec + (double)now_ts.tv_nsec * 1.0E-9;
#endif
}

static int
timer_add(struct mg_context *ctx,
          double next_time,
          double period,
          int is_relative,
          taction action,
          void *arg)
{
	unsigned u, v;
	int error = 0;
	double now;

	if (ctx->stop_flag) {
		return 0;
	}

	now = timer_getcurrenttime();

	/* HCP24: if is_relative = 0 and next_time < now
	 *        action will be called so fast as possible
	 *        if additional period > 0
	 *        action will be called so fast as possible
	 *        n times until (next_time + (n * period)) > now
	 *        then the period is working
	 * Solution:
	 *        if next_time < now then we set next_time = now.
	 *        The first callback will be so fast as possible (now)
	 *        but the next callback on period
	*/
	if (is_relative) {
		next_time += now;
	}

	/* You can not set timers into the past */
	if (next_time < now) {
		next_time = now;
	}

	pthread_mutex_lock(&ctx->timers->mutex);
	if (ctx->timers->timer_count == MAX_TIMERS) {
		error = 1;
	} else {
		/* Insert new timer into a sorted list. */
		/* The linear list is still most efficient for short lists (small
		 * number of timers) - if there are many timers, different
		 * algorithms will work better. */
		for (u = 0; u < ctx->timers->timer_count; u++) {
			if (ctx->timers->timers[u].time > next_time) {
				/* HCP24: moving all timers > next_time */
				for (v = ctx->timers->timer_count; v > u; v--) {
					ctx->timers->timers[v] = ctx->timers->timers[v - 1];
				}
				break;
			}
		}
		ctx->timers->timers[u].time = next_time;
		ctx->timers->timers[u].period = period;
		ctx->timers->timers[u].action = action;
		ctx->timers->timers[u].arg = arg;
		ctx->timers->timer_count++;
	}
	pthread_mutex_unlock(&ctx->timers->mutex);
	return error;
}

static void
timer_thread_run(void *thread_func_param)
{
	struct mg_context *ctx = (struct mg_context *)thread_func_param;
	double d;
	unsigned u;
	int re_schedule;
	struct ttimer t;

	mg_set_thread_name("timer");

	if (ctx->callbacks.init_thread) {
		/* Timer thread */
		ctx->callbacks.init_thread(ctx, 2);
	}

	d = timer_getcurrenttime();

	while (ctx->stop_flag == 0) {
		pthread_mutex_lock(&ctx->timers->mutex);
		if ((ctx->timers->timer_count > 0)
		    && (d >= ctx->timers->timers[0].time)) {
			t = ctx->timers->timers[0];
			for (u = 1; u < ctx->timers->timer_count; u++) {
				ctx->timers->timers[u - 1] = ctx->timers->timers[u];
			}
			ctx->timers->timer_count--;
			pthread_mutex_unlock(&ctx->timers->mutex);
			re_schedule = t.action(t.arg);
			if (re_schedule && (t.period > 0)) {
				timer_add(ctx, t.time + t.period, t.period, 0, t.action, t.arg);
			}
			continue;
		} else {
			pthread_mutex_unlock(&ctx->timers->mutex);
		}

/* 10 ms seems reasonable.
 * A faster loop (smaller sleep value) increases CPU load,
 * a slower loop (higher sleep value) decreases timer accuracy.
 */
#ifdef _WIN32
		Sleep(10);
#else
		usleep(10000);
#endif

		d = timer_getcurrenttime();
	}
	ctx->timers->timer_count = 0;
}

#ifdef _WIN32
static unsigned __stdcall timer_thread(void *thread_func_param)
{
	timer_thread_run(thread_func_param);
	return 0;
}
#else
static void *
timer_thread(void *thread_func_param)
{
	timer_thread_run(thread_func_param);
	return NULL;
}
#endif /* _WIN32 */

static int
timers_init(struct mg_context *ctx)
{
	ctx->timers = (struct ttimers *)mg_calloc(sizeof(struct ttimers), 1);
	(void)pthread_mutex_init(&ctx->timers->mutex, NULL);

	(void)timer_getcurrenttime();

	/* Start timer thread */
	mg_start_thread_with_id(timer_thread, ctx, &ctx->timers->threadid);

	return 0;
}

static void
timers_exit(struct mg_context *ctx)
{
	if (ctx->timers) {
		pthread_mutex_lock(&ctx->timers->mutex);
		ctx->timers->timer_count = 0;
		(void)pthread_mutex_destroy(&ctx->timers->mutex);
		mg_free(ctx->timers);
	}
}
<|endoftext|>


<commit_before>/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "vk/GrVkPipelineStateBuilder.h"

#include "vk/GrVkDescriptorSetManager.h"
#include "vk/GrVkGpu.h"
#include "vk/GrVkRenderPass.h"

GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
                                                               GrVkGpu* gpu,
                                                               const GrPipeline& pipeline,
                                                               const GrStencilSettings& stencil,
                                                               const GrPrimitiveProcessor& primProc,
                                                               GrPrimitiveType primitiveType,
                                                               const GrVkPipelineState::Desc& desc,
                                                               const GrVkRenderPass& renderPass) {
    // create a builder.  This will be handed off to effects so they can use it to add
    // uniforms, varyings, textures, etc
    GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc);

    GrGLSLExpr4 inputColor;
    GrGLSLExpr4 inputCoverage;

    if (!builder.emitAndInstallProcs(&inputColor, &inputCoverage)) {
        builder.cleanupFragmentProcessors();
        return nullptr;
    }

    return builder.finalize(stencil, primitiveType, renderPass, desc);
}

GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
                                                   const GrPipeline& pipeline,
                                                   const GrPrimitiveProcessor& primProc,
                                                   const GrProgramDesc& desc)
    : INHERITED(pipeline, primProc, desc)
    , fGpu(gpu)
    , fVaryingHandler(this)
    , fUniformHandler(this) {
}

const GrCaps* GrVkPipelineStateBuilder::caps() const {
    return fGpu->caps();
}
const GrGLSLCaps* GrVkPipelineStateBuilder::glslCaps() const {
    return fGpu->vkCaps().glslCaps();
}

void GrVkPipelineStateBuilder::finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) {
    outputColor.setLayoutQualifier("location = 0, index = 0");
}

void GrVkPipelineStateBuilder::finalizeFragmentSecondaryColor(GrGLSLShaderVar& outputColor) {
    outputColor.setLayoutQualifier("location = 0, index = 1");
}

bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
                                                    VkShaderStageFlagBits stage,
                                                    const GrGLSLShaderBuilder& builder,
                                                    VkShaderModule* shaderModule,
                                                    VkPipelineShaderStageCreateInfo* stageInfo) {
    SkString shaderString;
    for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
        if (builder.fCompilerStrings[i]) {
            shaderString.append(builder.fCompilerStrings[i]);
            shaderString.append("\n");
        }
    }
    return GrCompileVkShaderModule(gpu, shaderString.c_str(), stage, shaderModule, stageInfo);
}

GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil,
                                                      GrPrimitiveType primitiveType,
                                                      const GrVkRenderPass& renderPass,
                                                      const GrVkPipelineState::Desc& desc) {
    VkDescriptorSetLayout dsLayout[2];
    VkPipelineLayout pipelineLayout;
    VkShaderModule vertShaderModule;
    VkShaderModule fragShaderModule;

    GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
    // This layout is not owned by the PipelineStateBuilder and thus should no be destroyed
    dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();

    GrVkDescriptorSetManager::Handle samplerDSHandle;
    resourceProvider.getSamplerDescriptorSetHandle(fUniformHandler, &samplerDSHandle);
    dsLayout[GrVkUniformHandler::kSamplerDescSet] =
            resourceProvider.getSamplerDSLayout(samplerDSHandle);

    // Create the VkPipelineLayout
    VkPipelineLayoutCreateInfo layoutCreateInfo;
    memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
    layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    layoutCreateInfo.pNext = 0;
    layoutCreateInfo.flags = 0;
    layoutCreateInfo.setLayoutCount = 2;
    layoutCreateInfo.pSetLayouts = dsLayout;
    layoutCreateInfo.pushConstantRangeCount = 0;
    layoutCreateInfo.pPushConstantRanges = nullptr;

    GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(),
                                                                  &layoutCreateInfo,
                                                                  nullptr,
                                                                  &pipelineLayout));

    // We need to enable the following extensions so that the compiler can correctly make spir-v
    // from our glsl shaders.
    fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
    fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
    fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
    fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");

    this->finalizeShaders();

    VkPipelineShaderStageCreateInfo shaderStageInfo[2];
    SkAssertResult(CreateVkShaderModule(fGpu,
                                        VK_SHADER_STAGE_VERTEX_BIT,
                                        fVS,
                                        &vertShaderModule,
                                        &shaderStageInfo[0]));

    SkAssertResult(CreateVkShaderModule(fGpu,
                                        VK_SHADER_STAGE_FRAGMENT_BIT,
                                        fFS,
                                        &fragShaderModule,
                                        &shaderStageInfo[1]));

    GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
                                                             stencil,
                                                             fPrimProc,
                                                             shaderStageInfo,
                                                             2,
                                                             primitiveType,
                                                             renderPass,
                                                             pipelineLayout);
    GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule,
                                                        nullptr));
    GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule,
                                                        nullptr));

    if (!pipeline) {
        GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
                                                              nullptr));
        GR_VK_CALL(fGpu->vkInterface(),
                   DestroyDescriptorSetLayout(fGpu->device(),
                                              dsLayout[GrVkUniformHandler::kSamplerDescSet],
                                              nullptr));

        this->cleanupFragmentProcessors();
        return nullptr;
    }

    return new GrVkPipelineState(fGpu,
                                 desc,
                                 pipeline,
                                 pipelineLayout,
                                 samplerDSHandle,
                                 fUniformHandles,
                                 fUniformHandler.fUniforms,
                                 fUniformHandler.fCurrentVertexUBOOffset,
                                 fUniformHandler.fCurrentFragmentUBOOffset,
                                 (uint32_t)fUniformHandler.numSamplers(),
                                 fGeometryProcessor,
                                 fXferProcessor,
                                 fFragmentProcessors);
}

<commit_msg>Fix double deletion of DescriptorSetLayouts<commit_after>/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "vk/GrVkPipelineStateBuilder.h"

#include "vk/GrVkDescriptorSetManager.h"
#include "vk/GrVkGpu.h"
#include "vk/GrVkRenderPass.h"

GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
                                                               GrVkGpu* gpu,
                                                               const GrPipeline& pipeline,
                                                               const GrStencilSettings& stencil,
                                                               const GrPrimitiveProcessor& primProc,
                                                               GrPrimitiveType primitiveType,
                                                               const GrVkPipelineState::Desc& desc,
                                                               const GrVkRenderPass& renderPass) {
    // create a builder.  This will be handed off to effects so they can use it to add
    // uniforms, varyings, textures, etc
    GrVkPipelineStateBuilder builder(gpu, pipeline, primProc, desc);

    GrGLSLExpr4 inputColor;
    GrGLSLExpr4 inputCoverage;

    if (!builder.emitAndInstallProcs(&inputColor, &inputCoverage)) {
        builder.cleanupFragmentProcessors();
        return nullptr;
    }

    return builder.finalize(stencil, primitiveType, renderPass, desc);
}

GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
                                                   const GrPipeline& pipeline,
                                                   const GrPrimitiveProcessor& primProc,
                                                   const GrProgramDesc& desc)
    : INHERITED(pipeline, primProc, desc)
    , fGpu(gpu)
    , fVaryingHandler(this)
    , fUniformHandler(this) {
}

const GrCaps* GrVkPipelineStateBuilder::caps() const {
    return fGpu->caps();
}
const GrGLSLCaps* GrVkPipelineStateBuilder::glslCaps() const {
    return fGpu->vkCaps().glslCaps();
}

void GrVkPipelineStateBuilder::finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) {
    outputColor.setLayoutQualifier("location = 0, index = 0");
}

void GrVkPipelineStateBuilder::finalizeFragmentSecondaryColor(GrGLSLShaderVar& outputColor) {
    outputColor.setLayoutQualifier("location = 0, index = 1");
}

bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
                                                    VkShaderStageFlagBits stage,
                                                    const GrGLSLShaderBuilder& builder,
                                                    VkShaderModule* shaderModule,
                                                    VkPipelineShaderStageCreateInfo* stageInfo) {
    SkString shaderString;
    for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
        if (builder.fCompilerStrings[i]) {
            shaderString.append(builder.fCompilerStrings[i]);
            shaderString.append("\n");
        }
    }
    return GrCompileVkShaderModule(gpu, shaderString.c_str(), stage, shaderModule, stageInfo);
}

GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil,
                                                      GrPrimitiveType primitiveType,
                                                      const GrVkRenderPass& renderPass,
                                                      const GrVkPipelineState::Desc& desc) {
    VkDescriptorSetLayout dsLayout[2];
    VkPipelineLayout pipelineLayout;
    VkShaderModule vertShaderModule;
    VkShaderModule fragShaderModule;

    GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
    // These layouts are not owned by the PipelineStateBuilder and thus should not be destroyed
    dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();

    GrVkDescriptorSetManager::Handle samplerDSHandle;
    resourceProvider.getSamplerDescriptorSetHandle(fUniformHandler, &samplerDSHandle);
    dsLayout[GrVkUniformHandler::kSamplerDescSet] =
            resourceProvider.getSamplerDSLayout(samplerDSHandle);

    // Create the VkPipelineLayout
    VkPipelineLayoutCreateInfo layoutCreateInfo;
    memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
    layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    layoutCreateInfo.pNext = 0;
    layoutCreateInfo.flags = 0;
    layoutCreateInfo.setLayoutCount = 2;
    layoutCreateInfo.pSetLayouts = dsLayout;
    layoutCreateInfo.pushConstantRangeCount = 0;
    layoutCreateInfo.pPushConstantRanges = nullptr;

    GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(),
                                                                  &layoutCreateInfo,
                                                                  nullptr,
                                                                  &pipelineLayout));

    // We need to enable the following extensions so that the compiler can correctly make spir-v
    // from our glsl shaders.
    fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
    fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
    fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
    fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");

    this->finalizeShaders();

    VkPipelineShaderStageCreateInfo shaderStageInfo[2];
    SkAssertResult(CreateVkShaderModule(fGpu,
                                        VK_SHADER_STAGE_VERTEX_BIT,
                                        fVS,
                                        &vertShaderModule,
                                        &shaderStageInfo[0]));

    SkAssertResult(CreateVkShaderModule(fGpu,
                                        VK_SHADER_STAGE_FRAGMENT_BIT,
                                        fFS,
                                        &fragShaderModule,
                                        &shaderStageInfo[1]));

    GrVkPipeline* pipeline = resourceProvider.createPipeline(fPipeline,
                                                             stencil,
                                                             fPrimProc,
                                                             shaderStageInfo,
                                                             2,
                                                             primitiveType,
                                                             renderPass,
                                                             pipelineLayout);
    GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule,
                                                        nullptr));
    GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule,
                                                        nullptr));

    if (!pipeline) {
        GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
                                                              nullptr));
        this->cleanupFragmentProcessors();
        return nullptr;
    }

    return new GrVkPipelineState(fGpu,
                                 desc,
                                 pipeline,
                                 pipelineLayout,
                                 samplerDSHandle,
                                 fUniformHandles,
                                 fUniformHandler.fUniforms,
                                 fUniformHandler.fCurrentVertexUBOOffset,
                                 fUniformHandler.fCurrentFragmentUBOOffset,
                                 (uint32_t)fUniformHandler.numSamplers(),
                                 fGeometryProcessor,
                                 fXferProcessor,
                                 fFragmentProcessors);
}

<|endoftext|>


<commit_before>#include "common.h"
#include <cmath>

using namespace std;

extern "C"
void fft_inplace_even(complexd * data, int size, int pitch);

// In principle, we can calculate 1 - (t2/r)^2 separately
//   because it does not depend on w and can be reused for
//   all layers, but we don't bother with caching and copying them
//   over and thus recalculate them each time
void mkGCFLayer(
    complexd arena[] // Full oversampled layer (padded)
  , int size         // linear size of the arena
  , int pitch        // pitch of the arena
  , double t2
  , double w
  , int max_support
  ){
  acc2d<complexd> center = acc2d<complexd>(arena + size * pitch / 2, pitch);

  int radius = max_support / 2;
  double normer = t2 / double (radius);

  #pragma omp parallel for // not so much important
  // Can make this slightly more optimal ...
  for(int i = 0; i <= radius; i++)
  for(int j = 0; i <= radius; i++) {
    double x, y, ph;
    x = double(i) / normer;
    y = double(j) / normer;
    ph = w * (1 - sqrt(1 - x*x - y*y));
    double s, c;
    sincos(2.0 * M_PI * ph, &s, &c);
      center[-i][-j]
    = center[-i][ j]
    = center[ i][-j]
    = center[ i][ j] = complexd(c,-s);
  }
  fft_inplace_even(arena, size, pitch);
  // TODO:
  // Transposition and extraction here.
  // I believe we should combine transposition with extraction.
}
<commit_msg>Add transposition/extraction to CPU GCF (need to integrate this in the whole, thus need to decide where to do this -- in Haskell or C++ land).<commit_after>#include "common.h"
#include <cmath>

using namespace std;

extern "C"
void fft_inplace_even(complexd * data, int size, int pitch);

// In principle, we can calculate 1 - (t2/r)^2 separately
//   because it does not depend on w and can be reused for
//   all layers, but we don't bother with caching and copying them
//   over and thus recalculate them each time
void mkGCFLayer(
    complexd arena[] // Full oversampled layer (padded)
  , int size         // linear size of the arena
  , int pitch        // pitch of the arena
  , double t2
  , double w
  , int max_support
  ){
  acc2d<complexd> center = acc2d<complexd>(arena + size * pitch / 2, pitch);

  int radius = max_support / 2;
  double normer = t2 / double (radius);

  #pragma omp parallel for // not so much important
  // Can make this slightly more optimal ...
  for(int i = 0; i <= radius; i++)
  for(int j = 0; i <= radius; i++) {
    double x, y, ph;
    x = double(i) / normer;
    y = double(j) / normer;
    ph = w * (1 - sqrt(1 - x*x - y*y));
    double s, c;
    sincos(2.0 * M_PI * ph, &s, &c);
      center[-i][-j]
    = center[-i][ j]
    = center[ i][-j]
    = center[ i][ j] = complexd(c,-s);
  }
  fft_inplace_even(arena, size, pitch);
  // TODO:
  // Transposition and extraction here.
  // I believe we should combine transposition with extraction.
}

template <int over>
void __transpose_and_extract(
    complexd dst[]       // [over][over][support][support]
  , const complexd src[] // [max_support][over][max_support][over]
  , int support
  , int max_support
  , int src_pad
  ) {
  int
      src_size = max_support * over
    , src_pitch = src_size + src_pad
    , start_loc = (max_support - support) * over * src_pitch / 2
    ;
  const complexd * srcp = src + start_loc;

  // NOTE: check this thoroughly
  for (int overu = 0; overu < over; overu++, srcp+=src_pitch) {
    const complexd * srcp1; srcp1 = srcp;
    for (int overv = 0; overv < over; overv++, srcp1++) {
      const complexd * srcp2; srcp2 = srcp1;
      for (int suppu = 0; suppu < support; suppu++, srcp2+=over*src_pitch) {
        const complexd * srcp3; srcp3 = srcp2;
        for (int suppv = 0; suppv < support; suppv++, srcp3+=over) {
          *dst++ = *srcp3;
        }
      }
    }
  }
}

// Inst
extern "C"
void transpose_and_extract(
    complexd dst[]
  , const complexd src[]
  , int support
  , int max_support
  , int src_pad
  ) {
  __transpose_and_extract<8>(dst, src, support, max_support, src_pad);
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_FUN_MULTIPLY_LOWER_TRI_SELF_TRANSPOSE_HPP
#define STAN_MATH_REV_FUN_MULTIPLY_LOWER_TRI_SELF_TRANSPOSE_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/fun/dot_product.hpp>
#include <stan/math/rev/fun/dot_self.hpp>
#include <stan/math/rev/fun/typedefs.hpp>
#include <stan/math/prim/fun/Eigen.hpp>

namespace stan {
namespace math {

template <typename T, require_rev_matrix_t<T>* = nullptr>
inline plain_type_t<T> multiply_lower_tri_self_transpose(const T& L) {
  using T_double = Eigen::MatrixXd;
  using T_var = plain_type_t<T>;

  if (L.size() == 0)
    return L;

  arena_t<T_var> arena_L = L;
  arena_t<T_double> arena_L_val
      = value_of(arena_L).template triangularView<Eigen::Lower>();

  arena_t<T_var> res = arena_L_val.template triangularView<Eigen::Lower>()
                       * arena_L_val.transpose();

  reverse_pass_callback([res, arena_L, arena_L_val]() mutable {
    const auto& adj = to_ref(res.adj());
    Eigen::MatrixXd adjL = (adj.transpose() + adj) * arena_L_val.template triangularView<Eigen::Lower>();

    arena_L.adj() += adjL.template triangularView<Eigen::Lower>();
  });

  return res;
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 6.0.1-14 (tags/RELEASE_601/final)<commit_after>#ifndef STAN_MATH_REV_FUN_MULTIPLY_LOWER_TRI_SELF_TRANSPOSE_HPP
#define STAN_MATH_REV_FUN_MULTIPLY_LOWER_TRI_SELF_TRANSPOSE_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/rev/core.hpp>
#include <stan/math/rev/fun/dot_product.hpp>
#include <stan/math/rev/fun/dot_self.hpp>
#include <stan/math/rev/fun/typedefs.hpp>
#include <stan/math/prim/fun/Eigen.hpp>

namespace stan {
namespace math {

template <typename T, require_rev_matrix_t<T>* = nullptr>
inline plain_type_t<T> multiply_lower_tri_self_transpose(const T& L) {
  using T_double = Eigen::MatrixXd;
  using T_var = plain_type_t<T>;

  if (L.size() == 0)
    return L;

  arena_t<T_var> arena_L = L;
  arena_t<T_double> arena_L_val
      = value_of(arena_L).template triangularView<Eigen::Lower>();

  arena_t<T_var> res = arena_L_val.template triangularView<Eigen::Lower>()
                       * arena_L_val.transpose();

  reverse_pass_callback([res, arena_L, arena_L_val]() mutable {
    const auto& adj = to_ref(res.adj());
    Eigen::MatrixXd adjL
        = (adj.transpose() + adj)
          * arena_L_val.template triangularView<Eigen::Lower>();

    arena_L.adj() += adjL.template triangularView<Eigen::Lower>();
  });

  return res;
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2011, Willow Garage, 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 the name of the copyright holder(s) nor the names of its
 *     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
 *  COPYRIGHT OWNER 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.
 *
 */

#include <pcl/common/time.h> //fps calculations
#include <pcl/io/openni_grabber.h>
#include <pcl/io/openni_camera/openni_driver.h>
#include <pcl/console/parse.h>
#include <vector>
#include <string>

#include <pcl/visualization/vtk.h>
#include <pcl/visualization/pcl_visualizer.h>
#include "boost.h"

#define SHOW_FPS 1
#if SHOW_FPS
#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = pcl::getTime ();\
    double now = pcl::getTime (); \
    ++count; \
    if (now - last >= 1.0) \
    { \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)
#else
#define FPS_CALC(_WHAT_) \
do \
{ \
}while(false)
#endif

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class SimpleOpenNIViewer
{
  public:
    SimpleOpenNIViewer (pcl::OpenNIGrabber& grabber)
      : grabber_ (grabber)
      , image_mutex_ ()
      , image_ ()
      , depth_image_ ()
      , importer_ (vtkSmartPointer<vtkImageImport>::New ())
      , depth_importer_ (vtkSmartPointer<vtkImageImport>::New ())
      , writer_ (vtkSmartPointer<vtkTIFFWriter>::New ())
      , flipper_ (vtkSmartPointer<vtkImageFlip>::New ())
    {
      importer_->SetNumberOfScalarComponents (3);
      importer_->SetDataScalarTypeToUnsignedChar ();
      depth_importer_->SetNumberOfScalarComponents (1);
      depth_importer_->SetDataScalarTypeToUnsignedShort ();
      writer_->SetCompressionToPackBits ();
      flipper_->SetFilteredAxes (1);
    }

    void
    image_callback (const boost::shared_ptr<openni_wrapper::Image> &image,
                    const boost::shared_ptr<openni_wrapper::DepthImage> &depth_image, float)
    {
      FPS_CALC ("image callback");
      boost::mutex::scoped_lock lock (image_mutex_);
      image_ = image;
      depth_image_ = depth_image;
    }

    void
    run ()
    {
      boost::function<void (const boost::shared_ptr<openni_wrapper::Image>&, const boost::shared_ptr<openni_wrapper::DepthImage>&, float) > image_cb = boost::bind (&SimpleOpenNIViewer::image_callback, this, _1, _2, _3);
      boost::signals2::connection image_connection = grabber_.registerCallback (image_cb);

      grabber_.start ();

      unsigned char* rgb_data = 0;
      unsigned rgb_data_size = 0;
      const void* data;

      while (true)
      {
        boost::mutex::scoped_lock lock (image_mutex_);

        std::string time = boost::posix_time::to_iso_string (boost::posix_time::microsec_clock::local_time ());
        if (image_)
        {
          FPS_CALC ("writer callback");
          boost::shared_ptr<openni_wrapper::Image> image;
          image.swap (image_);

          if (image->getEncoding() == openni_wrapper::Image::RGB)
          {
            data = reinterpret_cast<const void*> (image->getMetaData ().Data ());
            importer_->SetWholeExtent (0, image->getWidth () - 1, 0, image->getHeight () - 1, 0, 0);
            importer_->SetDataExtentToWholeExtent ();
          }
          else
          {
            if (rgb_data_size < image->getWidth () * image->getHeight ())
            {
              rgb_data_size = image->getWidth () * image->getHeight ();
              rgb_data = new unsigned char [rgb_data_size * 3];
              importer_->SetWholeExtent (0, image->getWidth () - 1, 0, image->getHeight () - 1, 0, 0);
              importer_->SetDataExtentToWholeExtent ();
            }
            image->fillRGB (image->getWidth (), image->getHeight (), rgb_data);
            data = reinterpret_cast<const void*> (rgb_data);
          }

          std::stringstream ss;
          ss << "frame_" + time + "_rgb.tiff";
          importer_->SetImportVoidPointer (const_cast<void*>(data), 1);
          importer_->Update ();
          flipper_->SetInputConnection (importer_->GetOutputPort ());
          flipper_->Update ();
          writer_->SetFileName (ss.str ().c_str ());
          writer_->SetInputConnection (flipper_->GetOutputPort ());
          writer_->Write ();
        }

        if (depth_image_)
        {
          boost::shared_ptr<openni_wrapper::DepthImage> depth_image;
          depth_image.swap (depth_image_);

          std::stringstream ss;
          ss << "frame_" + time + "_depth.tiff";

          depth_importer_->SetWholeExtent (0, depth_image->getWidth () - 1, 0, depth_image->getHeight () - 1, 0, 0);
          depth_importer_->SetDataExtentToWholeExtent ();
          depth_importer_->SetImportVoidPointer (const_cast<void*> (reinterpret_cast<const void*> (depth_image->getDepthMetaData ().Data ())), 1);
          depth_importer_->Update ();
          flipper_->SetInputConnection (depth_importer_->GetOutputPort ());
          flipper_->Update ();
          writer_->SetFileName (ss.str ().c_str ());
          writer_->SetInputConnection (flipper_->GetOutputPort ());
          writer_->Write ();
        }
      }

      grabber_.stop ();

      image_connection.disconnect ();

      if (rgb_data)
        delete[] rgb_data;
    }

    pcl::OpenNIGrabber& grabber_;
    boost::mutex image_mutex_;
    boost::shared_ptr<openni_wrapper::Image> image_;
    boost::shared_ptr<openni_wrapper::DepthImage> depth_image_;
    vtkSmartPointer<vtkImageImport> importer_, depth_importer_;
    vtkSmartPointer<vtkTIFFWriter> writer_;
    vtkSmartPointer<vtkImageFlip> flipper_;
};

void
usage (char ** argv)
{
  cout << "usage: " << argv[0] << " [((<device_id> | <path-to-oni-file>) [-imagemode <mode>] | -l [<device_id>]| -h | --help)]" << endl;
  cout << argv[0] << " -h | --help : shows this help" << endl;
  cout << argv[0] << " -l : list all available devices" << endl;
  cout << argv[0] << " -l <device-id> : list all available modes for specified device" << endl;

  cout << "                 device_id may be #1, #2, ... for the first, second etc device in the list"
#ifndef _WIN32
       << " or" << endl
       << "                 bus@address for the device connected to a specific usb-bus / address combination or" << endl
       << "                 <serial-number>"
#endif
       << endl;
  cout << endl;
  cout << "examples:" << endl;
  cout << argv[0] << " \"#1\"" << endl;
  cout << "    uses the first device." << endl;
  cout << argv[0] << " \"./temp/test.oni\"" << endl;
  cout << "    uses the oni-player device to play back oni file given by path." << endl;
  cout << argv[0] << " -l" << endl;
  cout << "    lists all available devices." << endl;
  cout << argv[0] << " -l \"#2\"" << endl;
  cout << "    lists all available modes for the second device" << endl;
#ifndef _WIN32
  cout << argv[0] << " A00361800903049A" << endl;
  cout << "    uses the device with the serial number \'A00361800903049A\'." << endl;
  cout << argv[0] << " 1@16" << endl;
  cout << "    uses the device on address 16 at USB bus 1." << endl;
#endif
  return;
}

int
main(int argc, char ** argv)
{
  std::string device_id ("");
  pcl::OpenNIGrabber::Mode image_mode = pcl::OpenNIGrabber::OpenNI_Default_Mode;

  if (argc >= 2)
  {
    device_id = argv[1];
    if (device_id == "--help" || device_id == "-h")
    {
      usage(argv);
      return 0;
    }
    else if (device_id == "-l")
    {
      if (argc >= 3)
      {
        pcl::OpenNIGrabber grabber (argv[2]);
        boost::shared_ptr<openni_wrapper::OpenNIDevice> device = grabber.getDevice ();
        std::vector<std::pair<int, XnMapOutputMode> > modes;

        if (device->hasImageStream ())
        {
          cout << endl << "Supported image modes for device: " << device->getVendorName () << " , " << device->getProductName () << endl;
          modes = grabber.getAvailableImageModes ();
          for (std::vector<std::pair<int, XnMapOutputMode> >::const_iterator it = modes.begin (); it != modes.end (); ++it)
          {
            cout << it->first << " = " << it->second.nXRes << " x " << it->second.nYRes << " @ " << it->second.nFPS << endl;
          }
        }
      }
      else
      {
        openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
        if (driver.getNumberDevices () > 0)
        {
          for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices (); ++deviceIdx)
          {
            cout << "Device: " << deviceIdx + 1 << ", vendor: " << driver.getVendorName (deviceIdx) << ", product: " << driver.getProductName (deviceIdx)
              << ", connected: " << driver.getBus (deviceIdx) << " @ " << driver.getAddress (deviceIdx) << ", serial number: \'" << driver.getSerialNumber (deviceIdx) << "\'" << endl;
          }

        }
        else
          cout << "No devices connected." << endl;

        cout <<"Virtual Devices available: ONI player" << endl;
      }
      return (0);
    }
  }
  else
  {
    openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
    if (driver.getNumberDevices () > 0)
      cout << "Device Id not set, using first device." << endl;
  }

  unsigned mode;
  if (pcl::console::parse (argc, argv, "-imagemode", mode) != -1)
    image_mode = pcl::OpenNIGrabber::Mode (mode);

  pcl::OpenNIGrabber grabber (device_id, pcl::OpenNIGrabber::OpenNI_Default_Mode, image_mode);
  SimpleOpenNIViewer v (grabber);
  v.run ();

  return (0);
}
<commit_msg>Added depth_mode argument to openni_save_image.cpp<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2011, Willow Garage, 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 the name of the copyright holder(s) nor the names of its
 *     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
 *  COPYRIGHT OWNER 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.
 *
 */

#include <pcl/common/time.h> //fps calculations
#include <pcl/io/openni_grabber.h>
#include <pcl/io/openni_camera/openni_driver.h>
#include <pcl/console/parse.h>
#include <vector>
#include <string>

#include <pcl/visualization/vtk.h>
#include <pcl/visualization/pcl_visualizer.h>
#include "boost.h"

#define SHOW_FPS 1
#if SHOW_FPS
#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = pcl::getTime ();\
    double now = pcl::getTime (); \
    ++count; \
    if (now - last >= 1.0) \
    { \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)
#else
#define FPS_CALC(_WHAT_) \
do \
{ \
}while(false)
#endif

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class SimpleOpenNIViewer
{
  public:
    SimpleOpenNIViewer (pcl::OpenNIGrabber& grabber)
      : grabber_ (grabber)
      , image_mutex_ ()
      , image_ ()
      , depth_image_ ()
      , importer_ (vtkSmartPointer<vtkImageImport>::New ())
      , depth_importer_ (vtkSmartPointer<vtkImageImport>::New ())
      , writer_ (vtkSmartPointer<vtkTIFFWriter>::New ())
      , flipper_ (vtkSmartPointer<vtkImageFlip>::New ())
    {
      importer_->SetNumberOfScalarComponents (3);
      importer_->SetDataScalarTypeToUnsignedChar ();
      depth_importer_->SetNumberOfScalarComponents (1);
      depth_importer_->SetDataScalarTypeToUnsignedShort ();
      writer_->SetCompressionToPackBits ();
      flipper_->SetFilteredAxes (1);
    }

    void
    image_callback (const boost::shared_ptr<openni_wrapper::Image> &image,
                    const boost::shared_ptr<openni_wrapper::DepthImage> &depth_image, float)
    {
      FPS_CALC ("image callback");
      boost::mutex::scoped_lock lock (image_mutex_);
      image_ = image;
      depth_image_ = depth_image;
    }

    void
    run ()
    {
      boost::function<void (const boost::shared_ptr<openni_wrapper::Image>&, const boost::shared_ptr<openni_wrapper::DepthImage>&, float) > image_cb = boost::bind (&SimpleOpenNIViewer::image_callback, this, _1, _2, _3);
      boost::signals2::connection image_connection = grabber_.registerCallback (image_cb);

      grabber_.start ();

      unsigned char* rgb_data = 0;
      unsigned rgb_data_size = 0;
      const void* data;

      while (true)
      {
        boost::mutex::scoped_lock lock (image_mutex_);

        std::string time = boost::posix_time::to_iso_string (boost::posix_time::microsec_clock::local_time ());
        if (image_)
        {
          FPS_CALC ("writer callback");
          boost::shared_ptr<openni_wrapper::Image> image;
          image.swap (image_);

          if (image->getEncoding() == openni_wrapper::Image::RGB)
          {
            data = reinterpret_cast<const void*> (image->getMetaData ().Data ());
            importer_->SetWholeExtent (0, image->getWidth () - 1, 0, image->getHeight () - 1, 0, 0);
            importer_->SetDataExtentToWholeExtent ();
          }
          else
          {
            if (rgb_data_size < image->getWidth () * image->getHeight ())
            {
              rgb_data_size = image->getWidth () * image->getHeight ();
              rgb_data = new unsigned char [rgb_data_size * 3];
              importer_->SetWholeExtent (0, image->getWidth () - 1, 0, image->getHeight () - 1, 0, 0);
              importer_->SetDataExtentToWholeExtent ();
            }
            image->fillRGB (image->getWidth (), image->getHeight (), rgb_data);
            data = reinterpret_cast<const void*> (rgb_data);
          }

          std::stringstream ss;
          ss << "frame_" + time + "_rgb.tiff";
          importer_->SetImportVoidPointer (const_cast<void*>(data), 1);
          importer_->Update ();
          flipper_->SetInputConnection (importer_->GetOutputPort ());
          flipper_->Update ();
          writer_->SetFileName (ss.str ().c_str ());
          writer_->SetInputConnection (flipper_->GetOutputPort ());
          writer_->Write ();
        }

        if (depth_image_)
        {
          boost::shared_ptr<openni_wrapper::DepthImage> depth_image;
          depth_image.swap (depth_image_);

          std::stringstream ss;
          ss << "frame_" + time + "_depth.tiff";

          depth_importer_->SetWholeExtent (0, depth_image->getWidth () - 1, 0, depth_image->getHeight () - 1, 0, 0);
          depth_importer_->SetDataExtentToWholeExtent ();
          depth_importer_->SetImportVoidPointer (const_cast<void*> (reinterpret_cast<const void*> (depth_image->getDepthMetaData ().Data ())), 1);
          depth_importer_->Update ();
          flipper_->SetInputConnection (depth_importer_->GetOutputPort ());
          flipper_->Update ();
          writer_->SetFileName (ss.str ().c_str ());
          writer_->SetInputConnection (flipper_->GetOutputPort ());
          writer_->Write ();
        }
      }

      grabber_.stop ();

      image_connection.disconnect ();

      if (rgb_data)
        delete[] rgb_data;
    }

    pcl::OpenNIGrabber& grabber_;
    boost::mutex image_mutex_;
    boost::shared_ptr<openni_wrapper::Image> image_;
    boost::shared_ptr<openni_wrapper::DepthImage> depth_image_;
    vtkSmartPointer<vtkImageImport> importer_, depth_importer_;
    vtkSmartPointer<vtkTIFFWriter> writer_;
    vtkSmartPointer<vtkImageFlip> flipper_;
};

void
usage (char ** argv)
{
  cout << "usage: " << argv[0] << " [((<device_id> | <path-to-oni-file>) [-imagemode <mode>] | -l [<device_id>]| -h | --help)]" << endl;
  cout << argv[0] << " -h | --help : shows this help" << endl;
  cout << argv[0] << " -l : list all available devices" << endl;
  cout << argv[0] << " -l <device-id> : list all available modes for specified device" << endl;

  cout << "                 device_id may be #1, #2, ... for the first, second etc device in the list"
#ifndef _WIN32
       << " or" << endl
       << "                 bus@address for the device connected to a specific usb-bus / address combination or" << endl
       << "                 <serial-number>"
#endif
       << endl;
  cout << endl;
  cout << "examples:" << endl;
  cout << argv[0] << " \"#1\"" << endl;
  cout << "    uses the first device." << endl;
  cout << argv[0] << " \"./temp/test.oni\"" << endl;
  cout << "    uses the oni-player device to play back oni file given by path." << endl;
  cout << argv[0] << " -l" << endl;
  cout << "    lists all available devices." << endl;
  cout << argv[0] << " -l \"#2\"" << endl;
  cout << "    lists all available modes for the second device" << endl;
#ifndef _WIN32
  cout << argv[0] << " A00361800903049A" << endl;
  cout << "    uses the device with the serial number \'A00361800903049A\'." << endl;
  cout << argv[0] << " 1@16" << endl;
  cout << "    uses the device on address 16 at USB bus 1." << endl;
#endif
  return;
}

int
main(int argc, char ** argv)
{
  std::string device_id ("");
  pcl::OpenNIGrabber::Mode image_mode = pcl::OpenNIGrabber::OpenNI_Default_Mode;
  pcl::OpenNIGrabber::Mode depth_mode = pcl::OpenNIGrabber::OpenNI_Default_Mode;

  if (argc >= 2)
  {
    device_id = argv[1];
    if (device_id == "--help" || device_id == "-h")
    {
      usage(argv);
      return 0;
    }
    else if (device_id == "-l")
    {
      if (argc >= 3)
      {
        pcl::OpenNIGrabber grabber (argv[2]);
        boost::shared_ptr<openni_wrapper::OpenNIDevice> device = grabber.getDevice ();
        std::vector<std::pair<int, XnMapOutputMode> > modes;

        if (device->hasImageStream ())
        {
          cout << endl << "Supported image modes for device: " << device->getVendorName () << " , " << device->getProductName () << endl;
          modes = grabber.getAvailableImageModes ();
          for (std::vector<std::pair<int, XnMapOutputMode> >::const_iterator it = modes.begin (); it != modes.end (); ++it)
          {
            cout << it->first << " = " << it->second.nXRes << " x " << it->second.nYRes << " @ " << it->second.nFPS << endl;
          }
        }
      }
      else
      {
        openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
        if (driver.getNumberDevices () > 0)
        {
          for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices (); ++deviceIdx)
          {
            cout << "Device: " << deviceIdx + 1 << ", vendor: " << driver.getVendorName (deviceIdx) << ", product: " << driver.getProductName (deviceIdx)
              << ", connected: " << driver.getBus (deviceIdx) << " @ " << driver.getAddress (deviceIdx) << ", serial number: \'" << driver.getSerialNumber (deviceIdx) << "\'" << endl;
          }

        }
        else
          cout << "No devices connected." << endl;

        cout <<"Virtual Devices available: ONI player" << endl;
      }
      return (0);
    }
  }
  else
  {
    openni_wrapper::OpenNIDriver& driver = openni_wrapper::OpenNIDriver::getInstance ();
    if (driver.getNumberDevices () > 0)
      cout << "Device Id not set, using first device." << endl;
  }

  unsigned imagemode;
  if (pcl::console::parse (argc, argv, "-imagemode", imagemode) != -1)
    image_mode = pcl::OpenNIGrabber::Mode (imagemode);
  unsigned depthmode;
  if (pcl::console::parse (argc, argv, "-depthmode", depthmode) != -1)
    depth_mode = pcl::OpenNIGrabber::Mode (depthmode);

  pcl::OpenNIGrabber grabber (device_id, depth_mode, image_mode);
  SimpleOpenNIViewer v (grabber);
  v.run ();

  return (0);
}
<|endoftext|>


<commit_before>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "dense_lambda_peek_optimizer.h"
#include "dense_lambda_peek_function.h"
#include "dense_cell_range_function.h"
#include <vespa/eval/instruction/replace_type_function.h>
#include <vespa/eval/eval/value.h>
#include <vespa/eval/eval/node_tools.h>
#include <vespa/eval/eval/basic_nodes.h>
#include <vespa/eval/eval/operator_nodes.h>
#include <vespa/eval/eval/call_nodes.h>
#include <vespa/eval/eval/tensor_nodes.h>
#include <vespa/eval/eval/llvm/compile_cache.h>
#include <optional>

using namespace vespalib::eval::nodes;

namespace vespalib::eval {

namespace {

// 'simple peek': deterministic peek into a single parameter with
//                compilable dimension index expressions.
const TensorPeek *find_simple_peek(const tensor_function::Lambda &lambda) {
    const Function &function = lambda.lambda();
    const size_t num_dims = lambda.result_type().dimensions().size();
    auto peek = as<TensorPeek>(function.root());
    if (peek && (function.num_params() == (num_dims + 1))) {
        auto param = as<Symbol>(peek->get_child(0));
        if (param && (param->id() == num_dims)) {
            for (size_t i = 1; i < peek->num_children(); ++i) {
                const Node &dim_expr = peek->get_child(i);
                if (NodeTools::min_num_params(dim_expr) > num_dims) {
                    return nullptr;
                }
                if (CompiledFunction::detect_issues(dim_expr)) {
                    return nullptr;
                }
            }
            return peek;
        }
    }
    return nullptr;
}

Node_UP make_dim_expr(const TensorPeek::Dim &src_dim) {
    if (src_dim.second.is_expr()) {
        return NodeTools::copy(*src_dim.second.expr);
    } else {
        return std::make_unique<Number>(as_number(src_dim.second.label));
    }
}

template <typename OP>
Node_UP make_op(Node_UP a, Node_UP b) {
    auto res = std::make_unique<OP>();
    res->bind(std::move(a), std::move(b));
    return res;
}

Node_UP make_floor(Node_UP a) {
    auto res = std::make_unique<Floor>();
    res->bind_next(std::move(a));
    return res;
}

struct PeekAnalyzer {
    std::vector<size_t> dst_dim_sizes;
    std::vector<size_t> src_dim_sizes;
    std::vector<CompiledFunction::UP> src_dim_funs;
    std::shared_ptr<Function const> src_idx_fun;

    struct CellRange {
        size_t offset;
        size_t length;
        bool is_full(size_t num_cells) const {
            return ((offset == 0) && (length == num_cells));
        }
    };

    struct Result {
        bool valid;
        std::optional<CellRange> cell_range;
        static Result simple(CellRange range) { return Result{true, range}; }
        static Result complex() { return Result{true, std::nullopt}; }
        static Result invalid() { return Result{false, std::nullopt}; }
    };

    PeekAnalyzer(const ValueType &dst_type, const ValueType &src_type,
                 const TensorPeek::DimList &dim_list)
    {
        for (const auto& dim: dst_type.dimensions()) {
            dst_dim_sizes.push_back(dim.size);
        }
        for (const auto& dim: src_type.dimensions()) {
            src_dim_sizes.push_back(dim.size);
        }
        Node_UP idx_expr;
        size_t num_params = dst_dim_sizes.size();
        for (size_t i = 0; i < dim_list.size(); ++i) {
            auto dim_expr = make_dim_expr(dim_list[i]);
            src_dim_funs.push_back(std::make_unique<CompiledFunction>(*dim_expr, num_params, PassParams::ARRAY));
            if (i == 0) {
                idx_expr = std::move(dim_expr);
            } else {
                idx_expr = make_floor(std::move(idx_expr));
                idx_expr = make_op<Mul>(std::move(idx_expr), std::make_unique<Number>(src_dim_sizes[i]));
                idx_expr = make_op<Add>(std::move(idx_expr), std::move(dim_expr));
            }
        }
        src_idx_fun = Function::create(std::move(idx_expr), dst_type.dimension_names());
    }

    bool step_params(std::vector<double> &params) {
        for (size_t idx = params.size(); idx-- > 0; ) {
            if (size_t(params[idx] += 1.0) < dst_dim_sizes[idx]) {
                return true;
            } else {
                params[idx] = 0.0;
            }
        }
        return false;
    }

    size_t calculate_index(const std::vector<size_t> &src_address) {
        size_t result = 0;
        for (size_t i = 0; i < src_address.size(); ++i) {
            result *= src_dim_sizes[i];
            result += src_address[i];
        }
        return result;
    }

    Result analyze_indexes() {
        CellRange range{0,0};
        bool is_complex = false;
        std::vector<double> params(dst_dim_sizes.size(), 0.0);
        std::vector<size_t> src_address(src_dim_sizes.size(), 0);
        do {
            for (size_t i = 0; i < src_dim_funs.size(); ++i) {
                auto dim_fun = src_dim_funs[i]->get_function();
                size_t dim_idx = dim_fun(&params[0]);
                if (dim_idx >= src_dim_sizes[i]) {
                    return Result::invalid();
                }
                src_address[i] = dim_idx;
            }
            size_t idx = calculate_index(src_address);
            if (range.length == 0) {
                range.offset = idx;
            }
            if (idx == (range.offset + range.length)) {
                ++range.length;
            } else {
                is_complex = true;
            }
        } while(step_params(params));
        if (is_complex) {
            return Result::complex();
        }
        return Result::simple(range);
    }
};

} // namespace <unnamed>

const TensorFunction &
DenseLambdaPeekOptimizer::optimize(const TensorFunction &expr, Stash &stash)
{
    if (auto lambda = as<tensor_function::Lambda>(expr)) {
        if (auto peek = find_simple_peek(*lambda)) {
            const ValueType &dst_type = lambda->result_type();
            const ValueType &src_type = lambda->types().get_type(peek->param());
            if (src_type.is_dense()) {
                assert(lambda->bindings().size() == 1);
                assert(src_type.dimensions().size() == peek->dim_list().size());
                size_t param_idx = lambda->bindings()[0];
                PeekAnalyzer analyzer(dst_type, src_type, peek->dim_list());
                auto result = analyzer.analyze_indexes();
                if (result.valid) {
                    const auto &get_param = tensor_function::inject(src_type, param_idx, stash);
                    if (result.cell_range && (dst_type.cell_type() == src_type.cell_type())) {
                        auto cell_range = result.cell_range.value();
                        if (cell_range.is_full(src_type.dense_subspace_size())) {
                            return ReplaceTypeFunction::create_compact(dst_type, get_param, stash);
                        } else {
                            return stash.create<DenseCellRangeFunction>(dst_type, get_param,
                                    cell_range.offset, cell_range.length);
                        }
                    } else {
                        return stash.create<DenseLambdaPeekFunction>(dst_type, get_param,
                                std::move(analyzer.src_idx_fun));
                    }
                }
            }
        }
    }
    return expr;
}

} // namespace
<commit_msg>use SmallVector in dense_lambda_peek_optimizer<commit_after>// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "dense_lambda_peek_optimizer.h"
#include "dense_lambda_peek_function.h"
#include "dense_cell_range_function.h"
#include <vespa/eval/instruction/replace_type_function.h>
#include <vespa/eval/eval/value.h>
#include <vespa/eval/eval/node_tools.h>
#include <vespa/eval/eval/basic_nodes.h>
#include <vespa/eval/eval/operator_nodes.h>
#include <vespa/eval/eval/call_nodes.h>
#include <vespa/eval/eval/tensor_nodes.h>
#include <vespa/eval/eval/llvm/compile_cache.h>
#include <optional>

using namespace vespalib::eval::nodes;

namespace vespalib::eval {

namespace {

// 'simple peek': deterministic peek into a single parameter with
//                compilable dimension index expressions.
const TensorPeek *find_simple_peek(const tensor_function::Lambda &lambda) {
    const Function &function = lambda.lambda();
    const size_t num_dims = lambda.result_type().dimensions().size();
    auto peek = as<TensorPeek>(function.root());
    if (peek && (function.num_params() == (num_dims + 1))) {
        auto param = as<Symbol>(peek->get_child(0));
        if (param && (param->id() == num_dims)) {
            for (size_t i = 1; i < peek->num_children(); ++i) {
                const Node &dim_expr = peek->get_child(i);
                if (NodeTools::min_num_params(dim_expr) > num_dims) {
                    return nullptr;
                }
                if (CompiledFunction::detect_issues(dim_expr)) {
                    return nullptr;
                }
            }
            return peek;
        }
    }
    return nullptr;
}

Node_UP make_dim_expr(const TensorPeek::Dim &src_dim) {
    if (src_dim.second.is_expr()) {
        return NodeTools::copy(*src_dim.second.expr);
    } else {
        return std::make_unique<Number>(as_number(src_dim.second.label));
    }
}

template <typename OP>
Node_UP make_op(Node_UP a, Node_UP b) {
    auto res = std::make_unique<OP>();
    res->bind(std::move(a), std::move(b));
    return res;
}

Node_UP make_floor(Node_UP a) {
    auto res = std::make_unique<Floor>();
    res->bind_next(std::move(a));
    return res;
}

struct PeekAnalyzer {
    SmallVector<size_t> dst_dim_sizes;
    SmallVector<size_t> src_dim_sizes;
    SmallVector<CompiledFunction::UP> src_dim_funs;
    std::shared_ptr<Function const> src_idx_fun;

    struct CellRange {
        size_t offset;
        size_t length;
        bool is_full(size_t num_cells) const {
            return ((offset == 0) && (length == num_cells));
        }
    };

    struct Result {
        bool valid;
        std::optional<CellRange> cell_range;
        static Result simple(CellRange range) { return Result{true, range}; }
        static Result complex() { return Result{true, std::nullopt}; }
        static Result invalid() { return Result{false, std::nullopt}; }
    };

    PeekAnalyzer(const ValueType &dst_type, const ValueType &src_type,
                 const TensorPeek::DimList &dim_list)
    {
        for (const auto& dim: dst_type.dimensions()) {
            dst_dim_sizes.push_back(dim.size);
        }
        for (const auto& dim: src_type.dimensions()) {
            src_dim_sizes.push_back(dim.size);
        }
        Node_UP idx_expr;
        size_t num_params = dst_dim_sizes.size();
        for (size_t i = 0; i < dim_list.size(); ++i) {
            auto dim_expr = make_dim_expr(dim_list[i]);
            src_dim_funs.push_back(std::make_unique<CompiledFunction>(*dim_expr, num_params, PassParams::ARRAY));
            if (i == 0) {
                idx_expr = std::move(dim_expr);
            } else {
                idx_expr = make_floor(std::move(idx_expr));
                idx_expr = make_op<Mul>(std::move(idx_expr), std::make_unique<Number>(src_dim_sizes[i]));
                idx_expr = make_op<Add>(std::move(idx_expr), std::move(dim_expr));
            }
        }
        src_idx_fun = Function::create(std::move(idx_expr), dst_type.dimension_names());
    }

    bool step_params(SmallVector<double> &params) {
        for (size_t idx = params.size(); idx-- > 0; ) {
            if (size_t(params[idx] += 1.0) < dst_dim_sizes[idx]) {
                return true;
            } else {
                params[idx] = 0.0;
            }
        }
        return false;
    }

    size_t calculate_index(const SmallVector<size_t> &src_address) {
        size_t result = 0;
        for (size_t i = 0; i < src_address.size(); ++i) {
            result *= src_dim_sizes[i];
            result += src_address[i];
        }
        return result;
    }

    Result analyze_indexes() {
        CellRange range{0,0};
        bool is_complex = false;
        SmallVector<double> params(dst_dim_sizes.size(), 0.0);
        SmallVector<size_t> src_address(src_dim_sizes.size(), 0);
        do {
            for (size_t i = 0; i < src_dim_funs.size(); ++i) {
                auto dim_fun = src_dim_funs[i]->get_function();
                size_t dim_idx = dim_fun(&params[0]);
                if (dim_idx >= src_dim_sizes[i]) {
                    return Result::invalid();
                }
                src_address[i] = dim_idx;
            }
            size_t idx = calculate_index(src_address);
            if (range.length == 0) {
                range.offset = idx;
            }
            if (idx == (range.offset + range.length)) {
                ++range.length;
            } else {
                is_complex = true;
            }
        } while(step_params(params));
        if (is_complex) {
            return Result::complex();
        }
        return Result::simple(range);
    }
};

} // namespace <unnamed>

const TensorFunction &
DenseLambdaPeekOptimizer::optimize(const TensorFunction &expr, Stash &stash)
{
    if (auto lambda = as<tensor_function::Lambda>(expr)) {
        if (auto peek = find_simple_peek(*lambda)) {
            const ValueType &dst_type = lambda->result_type();
            const ValueType &src_type = lambda->types().get_type(peek->param());
            if (src_type.is_dense()) {
                assert(lambda->bindings().size() == 1);
                assert(src_type.dimensions().size() == peek->dim_list().size());
                size_t param_idx = lambda->bindings()[0];
                PeekAnalyzer analyzer(dst_type, src_type, peek->dim_list());
                auto result = analyzer.analyze_indexes();
                if (result.valid) {
                    const auto &get_param = tensor_function::inject(src_type, param_idx, stash);
                    if (result.cell_range && (dst_type.cell_type() == src_type.cell_type())) {
                        auto cell_range = result.cell_range.value();
                        if (cell_range.is_full(src_type.dense_subspace_size())) {
                            return ReplaceTypeFunction::create_compact(dst_type, get_param, stash);
                        } else {
                            return stash.create<DenseCellRangeFunction>(dst_type, get_param,
                                    cell_range.offset, cell_range.length);
                        }
                    } else {
                        return stash.create<DenseLambdaPeekFunction>(dst_type, get_param,
                                std::move(analyzer.src_idx_fun));
                    }
                }
            }
        }
    }
    return expr;
}

} // namespace
<|endoftext|>


<commit_before>//
//  Copyright (C) 2013-2014 mogemimi.
//
//  Distributed under the MIT License.
//  See accompanying file LICENSE.md or copy at
//  http://enginetrouble.net/pomdog/LICENSE.md for details.
//

#include "VoxModelLoader.hpp"
#include "Pomdog/Content/detail/AssetLoaderContext.hpp"
#include "Pomdog/Utility/Exception.hpp"
#include <fstream>
#include <algorithm>
#include <utility>

///@todo badcode
#include <Pomdog/../../src/Content/Utility/MakeFourCC.hpp>
#include <Pomdog/../../src/Content/Utility/BinaryReader.hpp>

namespace Pomdog {
namespace Details {
namespace {
//-----------------------------------------------------------------------
static bool IsMagicaVoxelFormat(std::uint32_t signature)
{
	constexpr auto fourCC = MakeFourCC('V', 'O', 'X', ' ');
	return fourCC == signature;
}
//-----------------------------------------------------------------------
static std::string Error(std::string const& assetPath, char const* description)
{
	return description + (": " + assetPath);
}

struct Chunk {
	std::int32_t ID;
	std::int32_t ContentSize;
	std::int32_t ChildrenSize;
};

//-----------------------------------------------------------------------
static std::size_t ChunkSize(std::ifstream & stream, Chunk const& chunk)
{
	POMDOG_ASSERT(chunk.ContentSize >= 0);
	POMDOG_ASSERT(chunk.ChildrenSize >= 0);
	POMDOG_ASSERT(stream.tellg() >= 0);

	return static_cast<std::size_t>(stream.tellg()) + chunk.ContentSize + chunk.ChildrenSize;
}

//-----------------------------------------------------------------------
}// unnamed namespace
//-----------------------------------------------------------------------
MagicaVoxel::VoxModel AssetLoader<MagicaVoxel::VoxModel>::operator()(
	AssetLoaderContext const& loaderContext, std::string const& assetPath)
{
	constexpr int MagicaVoxelVersion = 150;
	constexpr auto IdMain = MakeFourCC('M', 'A', 'I', 'N');
	constexpr auto IdSize = MakeFourCC('S', 'I', 'Z', 'E');
	constexpr auto IdXYZI = MakeFourCC('X', 'Y', 'Z', 'I');
	constexpr auto IdRGBA = MakeFourCC('R', 'G', 'B', 'A');

	std::ifstream stream = loaderContext.OpenStream(assetPath);

	if (stream.fail()) {
		POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "cannot open file"));
	}

	if (!IsMagicaVoxelFormat(BinaryReader::Read<std::uint32_t>(stream))) {
		POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "invalid format"));
	}

	if (MagicaVoxelVersion != BinaryReader::Read<std::int32_t>(stream)) {
		POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "version does not much"));
	}

	const auto mainChunk = BinaryReader::Read<Chunk>(stream);

	if (mainChunk.ID != IdMain) {
		POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "cannot find main chunk"));
	}

	const auto mainChunkEnd = ChunkSize(stream, mainChunk);

	stream.seekg(mainChunk.ContentSize, std::ios::cur);

	MagicaVoxel::VoxModel model;

	while (stream.tellg() < mainChunkEnd)
	{
		const auto chunk = BinaryReader::Read<Chunk>(stream);
		const auto chunkEnd = ChunkSize(stream, chunk);

		switch (chunk.ID) {
		case IdSize: {
			const auto x = BinaryReader::Read<std::int32_t>(stream);
			const auto y = BinaryReader::Read<std::int32_t>(stream);
			const auto z = BinaryReader::Read<std::int32_t>(stream);

			POMDOG_ASSERT(x >= 0);
			POMDOG_ASSERT(y >= 0);
			POMDOG_ASSERT(z >= 0);

			model.X = static_cast<std::uint32_t>(x);
			model.Y = static_cast<std::uint32_t>(y);
			model.Z = static_cast<std::uint32_t>(z);
			break;
		}
		case IdXYZI: {
			const auto voxelCount = BinaryReader::Read<std::int32_t>(stream);
			if (voxelCount < 0) {
				POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "negative number of voxels"));
			}

			if (voxelCount > 0) {
				model.Voxels = BinaryReader::ReadArray<MagicaVoxel::Voxel>(stream, voxelCount);
			}
			break;
		}
		case IdRGBA: {
			model.ColorPalette = BinaryReader::Read<decltype(model.ColorPalette)>(stream);

			model.ColorPalette.back() = Color::Black;

			POMDOG_ASSERT(model.ColorPalette.size() == 256);
			std::rotate(std::begin(model.ColorPalette), std::next(std::begin(model.ColorPalette), 255), std::end(model.ColorPalette));
			break;
		}
		default:
			break;
		}

		stream.seekg(chunkEnd, std::ios::beg);
	}

	return std::move(model);
}

}// namespace Details
}// namespace Pomdog
<commit_msg>Fix build warning<commit_after>//
//  Copyright (C) 2013-2014 mogemimi.
//
//  Distributed under the MIT License.
//  See accompanying file LICENSE.md or copy at
//  http://enginetrouble.net/pomdog/LICENSE.md for details.
//

#include "VoxModelLoader.hpp"
#include "Pomdog/Content/detail/AssetLoaderContext.hpp"
#include "Pomdog/Utility/Exception.hpp"
#include <fstream>
#include <algorithm>
#include <utility>

///@todo badcode
#include <Pomdog/../../src/Content/Utility/MakeFourCC.hpp>
#include <Pomdog/../../src/Content/Utility/BinaryReader.hpp>

namespace Pomdog {
namespace Details {
namespace {
//-----------------------------------------------------------------------
static bool IsMagicaVoxelFormat(std::uint32_t signature)
{
	constexpr auto fourCC = MakeFourCC('V', 'O', 'X', ' ');
	return fourCC == signature;
}
//-----------------------------------------------------------------------
static std::string Error(std::string const& assetPath, char const* description)
{
	return description + (": " + assetPath);
}

struct Chunk {
	std::int32_t ID;
	std::int32_t ContentSize;
	std::int32_t ChildrenSize;
};

//-----------------------------------------------------------------------
static std::ifstream::pos_type ChunkSize(std::ifstream & stream, Chunk const& chunk)
{
	POMDOG_ASSERT(chunk.ContentSize >= 0);
	POMDOG_ASSERT(chunk.ChildrenSize >= 0);
	POMDOG_ASSERT(stream.tellg() >= 0);

	return stream.tellg() + static_cast<std::ifstream::pos_type>(chunk.ContentSize + chunk.ChildrenSize);
}

//-----------------------------------------------------------------------
}// unnamed namespace
//-----------------------------------------------------------------------
MagicaVoxel::VoxModel AssetLoader<MagicaVoxel::VoxModel>::operator()(
	AssetLoaderContext const& loaderContext, std::string const& assetPath)
{
	constexpr int MagicaVoxelVersion = 150;
	constexpr auto IdMain = MakeFourCC('M', 'A', 'I', 'N');
	constexpr auto IdSize = MakeFourCC('S', 'I', 'Z', 'E');
	constexpr auto IdXYZI = MakeFourCC('X', 'Y', 'Z', 'I');
	constexpr auto IdRGBA = MakeFourCC('R', 'G', 'B', 'A');

	std::ifstream stream = loaderContext.OpenStream(assetPath);

	if (stream.fail()) {
		POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "cannot open file"));
	}

	if (!IsMagicaVoxelFormat(BinaryReader::Read<std::uint32_t>(stream))) {
		POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "invalid format"));
	}

	if (MagicaVoxelVersion != BinaryReader::Read<std::int32_t>(stream)) {
		POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "version does not much"));
	}

	const auto mainChunk = BinaryReader::Read<Chunk>(stream);

	if (mainChunk.ID != IdMain) {
		POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "cannot find main chunk"));
	}

	const auto mainChunkEnd = ChunkSize(stream, mainChunk);

	stream.seekg(mainChunk.ContentSize, std::ios::cur);

	MagicaVoxel::VoxModel model;

	while (stream.tellg() < mainChunkEnd)
	{
		const auto chunk = BinaryReader::Read<Chunk>(stream);
		const auto chunkEnd = ChunkSize(stream, chunk);

		switch (chunk.ID) {
		case IdSize: {
			const auto x = BinaryReader::Read<std::int32_t>(stream);
			const auto y = BinaryReader::Read<std::int32_t>(stream);
			const auto z = BinaryReader::Read<std::int32_t>(stream);

			POMDOG_ASSERT(x >= 0);
			POMDOG_ASSERT(y >= 0);
			POMDOG_ASSERT(z >= 0);

			model.X = static_cast<std::uint32_t>(x);
			model.Y = static_cast<std::uint32_t>(y);
			model.Z = static_cast<std::uint32_t>(z);
			break;
		}
		case IdXYZI: {
			const auto voxelCount = BinaryReader::Read<std::int32_t>(stream);
			if (voxelCount < 0) {
				POMDOG_THROW_EXCEPTION(std::invalid_argument, Error(assetPath, "negative number of voxels"));
			}

			if (voxelCount > 0) {
				model.Voxels = BinaryReader::ReadArray<MagicaVoxel::Voxel>(stream, voxelCount);
			}
			break;
		}
		case IdRGBA: {
			model.ColorPalette = BinaryReader::Read<decltype(model.ColorPalette)>(stream);

			model.ColorPalette.back() = Color::Black;

			POMDOG_ASSERT(model.ColorPalette.size() == 256);
			std::rotate(std::begin(model.ColorPalette), std::next(std::begin(model.ColorPalette), 255), std::end(model.ColorPalette));
			break;
		}
		default:
			break;
		}

		stream.seekg(chunkEnd, std::ios::beg);
	}

	return std::move(model);
}

}// namespace Details
}// namespace Pomdog
<|endoftext|>