<commit_before>#include "plugin.h"
#include "plugininterface.h"
#include "pluginmanager.h"

#include <QApplication>
#include <QDir>
#include <QPluginLoader>

namespace OpenCOR {

PluginManager::PluginManager(QSettings *pSettings,
                             const PluginInfo::PluginType &pGuiOrConsoleType) :
    mSettings(pSettings),
    mGuiOrConsoleType(pGuiOrConsoleType)
{
    mPluginsDir =  QDir(qApp->applicationDirPath()).canonicalPath()
                  +QDir::separator()+QString("..")
#ifndef Q_WS_MAC
                  +QDir::separator()+"plugins"
#else
                  +QDir::separator()+"PlugIns"
#endif
                  +QDir::separator()+qApp->applicationName();

#ifndef Q_WS_MAC
    // The plugins directory should be correct, but in case we try to run
    // OpenCOR on Windows or Linux AND from within Qt Creator, then the binary
    // will be running from [OpenCOR]/build/OpenCOR[.exe] rather than
    // [OpenCOR]/build/bin/OpenCOR[.exe] as it should if we were to mimic the
    // case where OpenCOR has been deployed. Then, because the plugins are in
    // [OpenCOR]/build/plugins/OpenCOR, we must skip the "../" bit. Yes, it's
    // not neat, but... is there another solution?...

    if (!QDir(mPluginsDir).exists())
        mPluginsDir =  QDir(qApp->applicationDirPath()).canonicalPath()
                      +QDir::separator()+"plugins"
                      +QDir::separator()+qApp->applicationName();
#endif

    // Retrieve the list of plugins available for loading

    QFileInfoList fileInfoList = QDir(mPluginsDir).entryInfoList(QStringList("*"+PluginExtension),
                                                                 QDir::Files);

    QStringList fileNames;

    foreach (const QFileInfo &file, fileInfoList)
        fileNames << QDir::toNativeSeparators(file.canonicalFilePath());

    // Self-contained plugins (e.g. the Core plugin) don't, by default, get
    // loaded, but the situation is obviously different if such a plugin is
    // required by another plugin (e.g. the Help plugin requires the Core
    // plugin), in which case the self-contained plugin should be loaded. So, we
    // must here determine which of those plugins need to be loaded...

    QStringList plugins;

    foreach (const QString &fileName, fileNames)
        plugins << requiredPlugins(fileName);

    plugins.removeDuplicates();

    // Knowing which plugins are required, we must now ensure that these are
    // loaded first. Note that this is not required on Windows (even though it
    // clearly doesn't harm having them loaded first!), but on Linux (and maybe
    // also on Mac OS X -- TO BE CHECKED!) it is otherwise the plugin's status
    // will be wrong (since on Linux and Mac OS X, we check that dependencies
    // are first loaded before loading the plugin itself), so...

    QStringList orderedFileNames;

    foreach (const QString &plugin, plugins)
        orderedFileNames << Plugin::fileName(mPluginsDir, plugin);

    orderedFileNames << fileNames;

    orderedFileNames.removeDuplicates();

    // Deal with all the plugins we can find

    foreach (const QString &fileName, orderedFileNames)
        mPlugins.insert(Plugin::name(fileName),
                        new Plugin(this, fileName, mGuiOrConsoleType,
                                   plugins.contains(Plugin::name(fileName))));
}

PluginManager::~PluginManager()
{
    // Delete all of the plugins

    while (!mPlugins.isEmpty()) {
        delete mPlugins.begin().value();

        mPlugins.erase(mPlugins.begin());
    }
}

QList<Plugin *> PluginManager::plugins(const bool &pOnlyLoadedPlugins)
{
    // Return a list of all the plugins

    QList<Plugin *> res;

    QMap<QString, Plugin *>::const_iterator iter = mPlugins.begin();

    while (iter != mPlugins.constEnd()) {
        if (   !pOnlyLoadedPlugins
            || (   pOnlyLoadedPlugins
                && (iter.value()->status() == Plugin::Loaded)))
        res << iter.value();

        ++iter;
    }

    return res;
}

QList<Plugin *> PluginManager::loadedPlugins()
{
    // Return a list of all the loaded plugins

    return plugins(true);
}

Plugin * PluginManager::plugin(const QString &pName)
{
    // Return the plugin which name is that we have been passed

    return mPlugins.value(pName);
}

QSettings * PluginManager::settings()
{
    // Return the settings object

    return mSettings;
}

QStringList PluginManager::requiredPlugins(const QString &pFileName,
                                           const int &pLevel)
{
    // Return the list of plugins required by a given plugin

    QStringList res;

    // Recursively look for the plugins required by the current plugin

    foreach(const QString &plugin, Plugin::info(pFileName).dependencies())
        res << requiredPlugins(Plugin::fileName(mPluginsDir, plugin), pLevel+1);

    // Add the current plugin to the list if it is not the original plugin for
    // which we want to know what its requirements are

    if (pLevel)
        res << Plugin::name(pFileName);

    return res;
}

}
<commit_msg>Updated a comment about ordering the loading of the plugins, now that things have been tested on Mac OS X.<commit_after>#include "plugin.h"
#include "plugininterface.h"
#include "pluginmanager.h"

#include <QApplication>
#include <QDir>
#include <QPluginLoader>

namespace OpenCOR {

PluginManager::PluginManager(QSettings *pSettings,
                             const PluginInfo::PluginType &pGuiOrConsoleType) :
    mSettings(pSettings),
    mGuiOrConsoleType(pGuiOrConsoleType)
{
    mPluginsDir =  QDir(qApp->applicationDirPath()).canonicalPath()
                  +QDir::separator()+QString("..")
#ifndef Q_WS_MAC
                  +QDir::separator()+"plugins"
#else
                  +QDir::separator()+"PlugIns"
#endif
                  +QDir::separator()+qApp->applicationName();

#ifndef Q_WS_MAC
    // The plugins directory should be correct, but in case we try to run
    // OpenCOR on Windows or Linux AND from within Qt Creator, then the binary
    // will be running from [OpenCOR]/build/OpenCOR[.exe] rather than
    // [OpenCOR]/build/bin/OpenCOR[.exe] as it should if we were to mimic the
    // case where OpenCOR has been deployed. Then, because the plugins are in
    // [OpenCOR]/build/plugins/OpenCOR, we must skip the "../" bit. Yes, it's
    // not neat, but... is there another solution?...

    if (!QDir(mPluginsDir).exists())
        mPluginsDir =  QDir(qApp->applicationDirPath()).canonicalPath()
                      +QDir::separator()+"plugins"
                      +QDir::separator()+qApp->applicationName();
#endif

    // Retrieve the list of plugins available for loading

    QFileInfoList fileInfoList = QDir(mPluginsDir).entryInfoList(QStringList("*"+PluginExtension),
                                                                 QDir::Files);

    QStringList fileNames;

    foreach (const QFileInfo &file, fileInfoList)
        fileNames << QDir::toNativeSeparators(file.canonicalFilePath());

    // Self-contained plugins (e.g. the Core plugin) don't, by default, get
    // loaded, but the situation is obviously different if such a plugin is
    // required by another plugin (e.g. the Help plugin requires the Core
    // plugin), in which case the self-contained plugin should be loaded. So, we
    // must here determine which of those plugins need to be loaded...

    QStringList plugins;

    foreach (const QString &fileName, fileNames)
        plugins << requiredPlugins(fileName);

    plugins.removeDuplicates();

    // Knowing which plugins are required, we must now ensure that these are
    // loaded first. Note that this is not required on Windows (even though it
    // clearly doesn't harm having them loaded first!), but on Linux and Mac OS
    // X it certainly is since otherwise the plugin's status will be wrong
    // (indeed, on those systems, we check that dependencies are first loaded
    // before loading the plugin itself), so...

    QStringList orderedFileNames;

    foreach (const QString &plugin, plugins)
        orderedFileNames << Plugin::fileName(mPluginsDir, plugin);

    orderedFileNames << fileNames;

    orderedFileNames.removeDuplicates();

    // Deal with all the plugins we can find

    foreach (const QString &fileName, orderedFileNames)
        mPlugins.insert(Plugin::name(fileName),
                        new Plugin(this, fileName, mGuiOrConsoleType,
                                   plugins.contains(Plugin::name(fileName))));
}

PluginManager::~PluginManager()
{
    // Delete all of the plugins

    while (!mPlugins.isEmpty()) {
        delete mPlugins.begin().value();

        mPlugins.erase(mPlugins.begin());
    }
}

QList<Plugin *> PluginManager::plugins(const bool &pOnlyLoadedPlugins)
{
    // Return a list of all the plugins

    QList<Plugin *> res;

    QMap<QString, Plugin *>::const_iterator iter = mPlugins.begin();

    while (iter != mPlugins.constEnd()) {
        if (   !pOnlyLoadedPlugins
            || (   pOnlyLoadedPlugins
                && (iter.value()->status() == Plugin::Loaded)))
        res << iter.value();

        ++iter;
    }

    return res;
}

QList<Plugin *> PluginManager::loadedPlugins()
{
    // Return a list of all the loaded plugins

    return plugins(true);
}

Plugin * PluginManager::plugin(const QString &pName)
{
    // Return the plugin which name is that we have been passed

    return mPlugins.value(pName);
}

QSettings * PluginManager::settings()
{
    // Return the settings object

    return mSettings;
}

QStringList PluginManager::requiredPlugins(const QString &pFileName,
                                           const int &pLevel)
{
    // Return the list of plugins required by a given plugin

    QStringList res;

    // Recursively look for the plugins required by the current plugin

    foreach(const QString &plugin, Plugin::info(pFileName).dependencies())
        res << requiredPlugins(Plugin::fileName(mPluginsDir, plugin), pLevel+1);

    // Add the current plugin to the list if it is not the original plugin for
    // which we want to know what its requirements are

    if (pLevel)
        res << Plugin::name(pFileName);

    return res;
}

}
<|endoftext|>


<commit_before>/**
 * @file
 *
 * @brief Write key sets using yaml-cpp
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#include "write.hpp"
#include "yaml.h"

#include <kdbease.h>
#include <kdblogger.h>
#include <kdbplugin.h>

#include <fstream>

using namespace std;
using namespace kdb;

namespace
{
NameIterator relativeKeyIterator (Key const & key, Key const & parent)
{
	auto parentIterator = parent.begin ();
	auto keyIterator = key.begin ();
	while (parentIterator != parent.end () && keyIterator != key.end ())
	{
		parentIterator++;
		keyIterator++;
	}
	return keyIterator;
}

void addKey (YAML::Node & data, NameIterator & keyIterator, Key const & key)
{
	if (keyIterator == --key.end ())
	{
		data[*keyIterator] = YAML::Node (key.getString ());
		return;
	}

	YAML::Node dictionary = (data[*keyIterator] && data[*keyIterator].IsMap ()) ? data[*keyIterator] : YAML::Node (YAML::NodeType::Map);
	data[*keyIterator] = dictionary;

	addKey (dictionary, ++keyIterator, key);
}

void addKeys (YAML::Node & data, KeySet const & mappings, Key const & parent)
{
	for (auto key : mappings)
	{
		NameIterator keyIterator = relativeKeyIterator (key, parent);
		addKey (data, keyIterator, key);
	}
}

} // end namespace

/**
 * @brief This function saves the key-value pairs stored in `mappings` as YAML data in the location specified via `parent`.
 *
 * @param mappings This key set stores the mappings that should be saved as YAML data.
 * @param parent This key specifies the path to the YAML data file that should be written.
 */
void yamlcpp::yamlWrite (KeySet const & mappings, Key const & parent)
{
	ofstream output (parent.getString ());
	auto data = YAML::Node (YAML::NodeType::Map);
	addKeys (data, mappings, parent);

	output << data;
}
<commit_msg>YAML CPP: Add documentation for write functions<commit_after>/**
 * @file
 *
 * @brief Write key sets using yaml-cpp
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#include "write.hpp"
#include "yaml.h"

#include <kdbease.h>
#include <kdblogger.h>
#include <kdbplugin.h>

#include <fstream>

using namespace std;
using namespace kdb;

namespace
{

/**
* @brief This function returns a `NameIterator` starting at the first level that is not part of `parent`.
*
* @pre The parameter `key` must be a child of `parent`.
*
* @param key This is the key for which this function returns a relative iterator.
* @param parent This key specifies the part of the name iterator that will not be part of the return value of this function.
*
* @returns A relative iterator that starts with the first part of the name of `key` not contained in `parent`.
*/
NameIterator relativeKeyIterator (Key const & key, Key const & parent)
{
	auto parentIterator = parent.begin ();
	auto keyIterator = key.begin ();
	while (parentIterator != parent.end () && keyIterator != key.end ())
	{
		parentIterator++;
		keyIterator++;
	}
	return keyIterator;
}

/**
 * @brief This function adds a key to a YAML node.
 *
 * @param data This node stores the data specified via `keyIterator`.
 * @param keyIterator This iterator specifies the current part of the key name this function adds to `data`.
 * @param key This parameter specifies the key that should be added to `data`.
 *
**/
void addKey (YAML::Node & data, NameIterator & keyIterator, Key const & key)
{
	if (keyIterator == --key.end ())
	{
		data[*keyIterator] = YAML::Node (key.getString ());
		return;
	}

	YAML::Node dictionary = (data[*keyIterator] && data[*keyIterator].IsMap ()) ? data[*keyIterator] : YAML::Node (YAML::NodeType::Map);
	data[*keyIterator] = dictionary;

	addKey (dictionary, ++keyIterator, key);
}

/**
 * @brief This function adds a key set to a YAML node.
 *
 * @param data This node stores the data specified via `mappings`.
 * @param mappings This keyset specifies all keys and values this function adds to `data`.
 * @param parent This key is the root of all keys stored in `mappings`.
 *
**/
void addKeys (YAML::Node & data, KeySet const & mappings, Key const & parent)
{
	for (auto key : mappings)
	{
		NameIterator keyIterator = relativeKeyIterator (key, parent);
		addKey (data, keyIterator, key);
	}
}

} // end namespace

/**
 * @brief This function saves the key-value pairs stored in `mappings` as YAML data in the location specified via `parent`.
 *
 * @param mappings This key set stores the mappings that should be saved as YAML data.
 * @param parent This key specifies the path to the YAML data file that should be written.
 */
void yamlcpp::yamlWrite (KeySet const & mappings, Key const & parent)
{
	ofstream output (parent.getString ());
	auto data = YAML::Node (YAML::NodeType::Map);
	addKeys (data, mappings, parent);

	output << data;
}
<|endoftext|>


<commit_before>/*
Copyright 2016 fixstars

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http ://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <stdlib.h>
#include <iostream>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <stereo_sgm.h>

#include "demo.h"
#include "renderer.h"

int main(int argc, char* argv[]) {

	if (argc < 3) {
		std::cerr << "usage: stereosgm left_img_fmt right_img_fmt [disp_size]" << std::endl;
		std::exit(EXIT_FAILURE);
	}
	std::string left_filename_fmt, right_filename_fmt;
	left_filename_fmt = argv[1];
	right_filename_fmt = argv[2];

	// dangerous
	char buf[1024];
	sprintf(buf, left_filename_fmt.c_str(), 0);
	cv::Mat left = cv::imread(buf, -1);
	sprintf(buf, right_filename_fmt.c_str(), 0);
	cv::Mat right = cv::imread(buf, -1);

	int disp_size = 64;
	if (argc >= 4) {
		disp_size = atoi(argv[3]);
	}

	if (left.size() != right.size() || left.type() != right.type()) {
		std::cerr << "mismatch input image size" << std::endl;
		std::exit(EXIT_FAILURE);
	}

	int bits = 0;

	switch (left.type()) {
		// case CV_8UC1: bits = 8; break; // TODO
	case CV_16UC1: bits = 16; break;
	default:
		std::cerr << "invalid input image color format" << left.type() << std::endl;
		std::exit(EXIT_FAILURE);
	}

	int width = left.cols;
	int height = left.rows;

	cudaGLSetGLDevice(0);

	SGMDemo demo(width, height);

	if (demo.init()) {
		printf("fail to init SGM Demo\n");
		std::exit(EXIT_FAILURE);
	}

	sgm::StereoSGM ssgm(width, height, bits, disp_size);

	Renderer renderer(width, height);

	uint16_t* d_output_buffer = NULL;

	int frame_no = 0;
	int max_frame = INT_MAX;
	while (!demo.should_close()) {

		glClearColor(0.0, 0.0, 0.0, 1.0);
		glClear(GL_COLOR_BUFFER_BIT);

		if (frame_no == max_frame) { frame_no = 0; }

		sprintf(buf, left_filename_fmt.c_str(), frame_no);
		cv::Mat left = cv::imread(buf, -1);
		sprintf(buf, right_filename_fmt.c_str(), frame_no);
		cv::Mat right = cv::imread(buf, -1);

		if (left.size() == cv::Size(0, 0) || right.size() == cv::Size(0, 0)) {
			max_frame = frame_no;
			frame_no = 0;
			continue;
		}

		ssgm.execute(left.data, right.data, (void**)&d_output_buffer, sgm::DST_TYPE_CUDA_PTR, 16);

		switch (demo.get_flag()) {
		case 0:
			{
				renderer.render_input((uint16_t*)left.data);
			}
			break;
		case 1:
			renderer.render_disparity(d_output_buffer, disp_size);
			break;
		case 2:
			renderer.render_disparity_color(d_output_buffer, disp_size);
			break;
		}

		demo.swap_buffer();
		frame_no++;
	}
}
<commit_msg>add frame_num arg<commit_after>/*
Copyright 2016 fixstars

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http ://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <stdlib.h>
#include <iostream>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <stereo_sgm.h>

#include "demo.h"
#include "renderer.h"

int main(int argc, char* argv[]) {

	if (argc < 3) {
		std::cerr << "usage: stereosgm left_img_fmt right_img_fmt [disp_size] [max_frame_num]" << std::endl;
		std::exit(EXIT_FAILURE);
	}
	std::string left_filename_fmt, right_filename_fmt;
	left_filename_fmt = argv[1];
	right_filename_fmt = argv[2];

	// dangerous
	char buf[1024];
	sprintf(buf, left_filename_fmt.c_str(), 0);
	cv::Mat left = cv::imread(buf, -1);
	sprintf(buf, right_filename_fmt.c_str(), 0);
	cv::Mat right = cv::imread(buf, -1);

	int disp_size = 64;
	if (argc >= 4) {
		disp_size = atoi(argv[3]);
	}

	int max_frame = 100;
	if(argc >= 5) {
		max_frame = atoi(argv[4]);
	}

	if (left.size() != right.size() || left.type() != right.type()) {
		std::cerr << "mismatch input image size" << std::endl;
		std::exit(EXIT_FAILURE);
	}

	int bits = 0;

	switch (left.type()) {
		// case CV_8UC1: bits = 8; break; // TODO
	case CV_16UC1: bits = 16; break;
	default:
		std::cerr << "invalid input image color format" << left.type() << std::endl;
		std::exit(EXIT_FAILURE);
	}

	int width = left.cols;
	int height = left.rows;

	cudaGLSetGLDevice(0);

	SGMDemo demo(width, height);

	if (demo.init()) {
		printf("fail to init SGM Demo\n");
		std::exit(EXIT_FAILURE);
	}

	sgm::StereoSGM ssgm(width, height, bits, disp_size);

	Renderer renderer(width, height);

	uint16_t* d_output_buffer = NULL;

	int frame_no = 0;
	while (!demo.should_close()) {

		glClearColor(0.0, 0.0, 0.0, 1.0);
		glClear(GL_COLOR_BUFFER_BIT);

		if (frame_no == max_frame) { frame_no = 0; }

		sprintf(buf, left_filename_fmt.c_str(), frame_no);
		cv::Mat left = cv::imread(buf, -1);
		sprintf(buf, right_filename_fmt.c_str(), frame_no);
		cv::Mat right = cv::imread(buf, -1);

		if (left.size() == cv::Size(0, 0) || right.size() == cv::Size(0, 0)) {
			max_frame = frame_no;
			frame_no = 0;
			continue;
		}

		ssgm.execute(left.data, right.data, (void**)&d_output_buffer, sgm::DST_TYPE_CUDA_PTR, 16);

		switch (demo.get_flag()) {
		case 0:
			{
				renderer.render_input((uint16_t*)left.data);
			}
			break;
		case 1:
			renderer.render_disparity(d_output_buffer, disp_size);
			break;
		case 2:
			renderer.render_disparity_color(d_output_buffer, disp_size);
			break;
		}

		demo.swap_buffer();
		frame_no++;
	}
}
<|endoftext|>


<commit_before>/*******************************************************************************
 The MIT License (MIT)

 Copyright (c) 2014 Alexander Zolotarev <me@alex.bio> from Minsk, Belarus

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 *******************************************************************************/

#include "../http_client.h"
#include "../file_manager.h"
#include "../logger.h"

#include <array>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>   // std::cerr
#include <stdexcept>  // std::runtime_error
#include <assert.h>   // assert
#include <stdio.h>    // popen

#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#else
#include <unistd.h>  // close
#endif

// Used as a test stub for basic HTTP client implementation.
// Make sure that you have curl installed in the PATH.
// TODO(AlexZ): Not a production-ready implementation.
namespace alohalytics {

std::string RunCurl(const std::string & cmd) {
  FILE * pipe = ::popen(cmd.c_str(), "r");
  assert(pipe);
  std::array<char, 8 * 1024> arr;
  std::string result;
  size_t read;
  do {
    read = ::fread(arr.data(), 1, arr.size(), pipe);
    if (read > 0) {
      result.append(arr.data(), read);
    }
  } while (read == arr.size());
  const int err = ::pclose(pipe);
  if (err) {
    throw std::runtime_error("Error " + std::to_string(err) + " while calling " + cmd);
  }
  return result;
}

// TODO(AlexZ): Move this function to File Manager.
std::string GetTmpFileName() {
#ifdef _MSC_VER
  char tmp_file[L_tmpnam];
  const errno_t err = ::tmpnam_s(tmp_file, L_tmpnam);
  if (err != 0) {
    throw std::runtime_error("Error " + std::to_string(err) + ", failed to create temporary file.");
  }
#else
  char tmp_file[] = "/tmp/alohalyticstmp-XXXXXX";
  if (nullptr == ::mktemp(tmp_file)) {  // tmpnam is deprecated and insecure.
    throw std::runtime_error("Error: failed to create temporary file.");
  }
#endif
  return tmp_file;
}

typedef std::vector<std::pair<std::string, std::string>> HeadersT;

HeadersT ParseHeaders(const std::string & raw) {
  std::istringstream stream(raw);
  HeadersT headers;
  std::string line;
  while (std::getline(stream, line)) {
    const auto cr = line.rfind('\r');
    if (cr != std::string::npos) {
      line.erase(cr);
    }
    const auto delims = line.find(": ");
    if (delims != std::string::npos) {
      headers.push_back(std::make_pair(line.substr(0, delims), line.substr(delims + 2)));
    }
  }
  return headers;
}

// Extract HTTP headers via temporary file with -D switch.
// HTTP status code is extracted from curl output (-w switches).
// Redirects are handled recursively. TODO(AlexZ): avoid infinite redirects loop.
bool HTTPClientPlatformWrapper::RunHTTPRequest() {
  const alohalytics::ScopedRemoveFile headers_deleter(GetTmpFileName());
  std::string cmd = "curl -s -w '%{http_code}' -X " + http_method_ + " -D '" + headers_deleter.file + "' ";

  if (!content_type_.empty()) {
    cmd += "-H 'Content-Type: " + content_type_ + "' ";
  }
  if (!content_encoding_.empty()) {
    cmd += "-H 'Content-Encoding: " + content_encoding_ + "' ";
  }
  if (!basic_auth_user_.empty()) {
    cmd += "-u '" + basic_auth_user_ + ":" + basic_auth_password_ + "' ";
  }
  if (!cookies_.empty()) {
    cmd += "-b '" + cookies_ + "' ";
  }

  alohalytics::ScopedRemoveFile body_deleter;
  if (!body_data_.empty()) {
    body_deleter.file = GetTmpFileName();
    // POST body through tmp file to avoid breaking command line.
    if (!(std::ofstream(body_deleter.file) << body_data_).good()) {
      std::cerr << "Error: failed to write into a temporary file." << std::endl;
      return false;
    }
    // TODO(AlexZ): Correctly clean up this internal var to avoid client confusion.
    body_file_ = body_deleter.file;
  }
  if (!body_file_.empty()) {
    // Content-Length is added automatically by curl.
    cmd += "--data-binary '@" + body_file_ + "' ";
  }

  // Use temporary file to receive data from server.
  // If user has specified file name to save data, it is not temporary and is not deleted automatically.
  alohalytics::ScopedRemoveFile received_file_deleter;
  std::string rfile = received_file_;
  if (rfile.empty()) {
    rfile = GetTmpFileName();
    received_file_deleter.file = rfile;
  }
  cmd += "-o " + rfile + " ";

  cmd += "'" + url_requested_ + "'";
  try {
    if (debug_mode_) {
      ALOG("Executing", cmd);
    }
    error_code_ = std::stoi(RunCurl(cmd));
    const HeadersT headers = ParseHeaders(alohalytics::FileManager::ReadFileAsString(headers_deleter.file));
    for (const auto & header : headers) {
      if (header.first == "Set-Cookie") {
        server_cookies_ += header.second + ", ";
      } else if (header.first == "Content-Type") {
        content_type_received_ = header.second;
      } else if (header.first == "Content-Encoding") {
        content_encoding_received_ = header.second;
      } else if (header.first == "Location") {
        url_received_ = header.second;
      }
    }
    server_cookies_ = normalize_server_cookies(std::move(server_cookies_));

    if (url_received_.empty()) {
      url_received_ = url_requested_;
      // Load body contents in final request only (skip redirects).
      if (received_file_.empty()) {
        // Sometimes server can reply with empty body, and it's ok.
        try {
          server_response_ = alohalytics::FileManager::ReadFileAsString(rfile);
        } catch (const std::exception &) {
        }
      }
    } else {
      // Handle HTTP redirect.
      // TODO(AlexZ): Should we check HTTP redirect code here?
      if (debug_mode_) {
        ALOG("HTTP redirect", error_code_, "to", url_received_);
      }
      HTTPClientPlatformWrapper redirect(url_received_);
      redirect.set_cookies(combined_cookies());
      const bool success = redirect.RunHTTPRequest();
      if (success) {
        error_code_ = redirect.error_code();
        url_received_ = redirect.url_received();
        server_cookies_ = move(redirect.server_cookies_);
        server_response_ = move(redirect.server_response_);
        content_type_received_ = move(redirect.content_type_received_);
        content_encoding_received_ = move(redirect.content_encoding_received_);
      } else {
        error_code_ = -1;
      }
      return success;
    }
  } catch (const std::exception & ex) {
    std::cerr << "Exception " << ex.what() << std::endl;
    return false;
  }
  return true;
}

}  // namespace alohalytics
<commit_msg>Fixed linux compilation warning about mktemp.<commit_after>/*******************************************************************************
 The MIT License (MIT)

 Copyright (c) 2014 Alexander Zolotarev <me@alex.bio> from Minsk, Belarus

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all
 copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 *******************************************************************************/

#include "../http_client.h"
#include "../file_manager.h"
#include "../logger.h"

#include <array>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>   // std::cerr
#include <stdexcept>  // std::runtime_error
#include <assert.h>   // assert
#include <stdio.h>    // popen

#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#else
#include <unistd.h>  // close
#endif

// Used as a test stub for basic HTTP client implementation.
// Make sure that you have curl installed in the PATH.
// TODO(AlexZ): Not a production-ready implementation.
namespace alohalytics {

std::string RunCurl(const std::string & cmd) {
  FILE * pipe = ::popen(cmd.c_str(), "r");
  assert(pipe);
  std::array<char, 8 * 1024> arr;
  std::string result;
  size_t read;
  do {
    read = ::fread(arr.data(), 1, arr.size(), pipe);
    if (read > 0) {
      result.append(arr.data(), read);
    }
  } while (read == arr.size());
  const int err = ::pclose(pipe);
  if (err) {
    throw std::runtime_error("Error " + std::to_string(err) + " while calling " + cmd);
  }
  return result;
}

// TODO(AlexZ): Move this function to File Manager.
// TODO(AlexZ): Rewrite code to use safe opened descriptors instead of file names.
std::string GetTmpFileName() {
#ifdef _MSC_VER
  char tmp_file[L_tmpnam];
  const errno_t err = ::tmpnam_s(tmp_file, L_tmpnam);
  if (err != 0) {
    throw std::runtime_error("Error " + std::to_string(err) + ", failed to create temporary file.");
  }
#else
  char tmp_file[] = "/tmp/alohalyticstmp-XXXXXX";
  int fd = ::mkstemp(tmp_file);  // tmpnam is deprecated and insecure.
  if (fd == -1) {
    throw std::runtime_error("Error: failed to create temporary file.");
  }
  ::close(fd);
#endif
  return tmp_file;
}

typedef std::vector<std::pair<std::string, std::string>> HeadersT;

HeadersT ParseHeaders(const std::string & raw) {
  std::istringstream stream(raw);
  HeadersT headers;
  std::string line;
  while (std::getline(stream, line)) {
    const auto cr = line.rfind('\r');
    if (cr != std::string::npos) {
      line.erase(cr);
    }
    const auto delims = line.find(": ");
    if (delims != std::string::npos) {
      headers.push_back(std::make_pair(line.substr(0, delims), line.substr(delims + 2)));
    }
  }
  return headers;
}

// Extract HTTP headers via temporary file with -D switch.
// HTTP status code is extracted from curl output (-w switches).
// Redirects are handled recursively. TODO(AlexZ): avoid infinite redirects loop.
bool HTTPClientPlatformWrapper::RunHTTPRequest() {
  const alohalytics::ScopedRemoveFile headers_deleter(GetTmpFileName());
  std::string cmd = "curl -s -w '%{http_code}' -X " + http_method_ + " -D '" + headers_deleter.file + "' ";

  if (!content_type_.empty()) {
    cmd += "-H 'Content-Type: " + content_type_ + "' ";
  }
  if (!content_encoding_.empty()) {
    cmd += "-H 'Content-Encoding: " + content_encoding_ + "' ";
  }
  if (!basic_auth_user_.empty()) {
    cmd += "-u '" + basic_auth_user_ + ":" + basic_auth_password_ + "' ";
  }
  if (!cookies_.empty()) {
    cmd += "-b '" + cookies_ + "' ";
  }

  alohalytics::ScopedRemoveFile body_deleter;
  if (!body_data_.empty()) {
    body_deleter.file = GetTmpFileName();
    // POST body through tmp file to avoid breaking command line.
    if (!(std::ofstream(body_deleter.file) << body_data_).good()) {
      std::cerr << "Error: failed to write into a temporary file." << std::endl;
      return false;
    }
    // TODO(AlexZ): Correctly clean up this internal var to avoid client confusion.
    body_file_ = body_deleter.file;
  }
  if (!body_file_.empty()) {
    // Content-Length is added automatically by curl.
    cmd += "--data-binary '@" + body_file_ + "' ";
  }

  // Use temporary file to receive data from server.
  // If user has specified file name to save data, it is not temporary and is not deleted automatically.
  alohalytics::ScopedRemoveFile received_file_deleter;
  std::string rfile = received_file_;
  if (rfile.empty()) {
    rfile = GetTmpFileName();
    received_file_deleter.file = rfile;
  }
  cmd += "-o " + rfile + " ";

  cmd += "'" + url_requested_ + "'";
  try {
    if (debug_mode_) {
      ALOG("Executing", cmd);
    }
    error_code_ = std::stoi(RunCurl(cmd));
    const HeadersT headers = ParseHeaders(alohalytics::FileManager::ReadFileAsString(headers_deleter.file));
    for (const auto & header : headers) {
      if (header.first == "Set-Cookie") {
        server_cookies_ += header.second + ", ";
      } else if (header.first == "Content-Type") {
        content_type_received_ = header.second;
      } else if (header.first == "Content-Encoding") {
        content_encoding_received_ = header.second;
      } else if (header.first == "Location") {
        url_received_ = header.second;
      }
    }
    server_cookies_ = normalize_server_cookies(std::move(server_cookies_));

    if (url_received_.empty()) {
      url_received_ = url_requested_;
      // Load body contents in final request only (skip redirects).
      if (received_file_.empty()) {
        // Sometimes server can reply with empty body, and it's ok.
        try {
          server_response_ = alohalytics::FileManager::ReadFileAsString(rfile);
        } catch (const std::exception &) {
        }
      }
    } else {
      // Handle HTTP redirect.
      // TODO(AlexZ): Should we check HTTP redirect code here?
      if (debug_mode_) {
        ALOG("HTTP redirect", error_code_, "to", url_received_);
      }
      HTTPClientPlatformWrapper redirect(url_received_);
      redirect.set_cookies(combined_cookies());
      const bool success = redirect.RunHTTPRequest();
      if (success) {
        error_code_ = redirect.error_code();
        url_received_ = redirect.url_received();
        server_cookies_ = move(redirect.server_cookies_);
        server_response_ = move(redirect.server_response_);
        content_type_received_ = move(redirect.content_type_received_);
        content_encoding_received_ = move(redirect.content_encoding_received_);
      } else {
        error_code_ = -1;
      }
      return success;
    }
  } catch (const std::exception & ex) {
    std::cerr << "Exception " << ex.what() << std::endl;
    return false;
  }
  return true;
}

}  // namespace alohalytics
<|endoftext|>


<commit_before>/***************************************************************************
    copyright            : (C) 2002, 2003 by Scott Wheeler
    email                : wheeler@kde.org
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it  under the terms of the GNU Lesser General Public License version  *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
 *   USA                                                                   *
 ***************************************************************************/

#include <tbytevectorlist.h>
#include <tdebug.h>

#include "commentsframe.h"

using namespace TagLib;
using namespace ID3v2;

class CommentsFrame::CommentsFramePrivate
{
public:
  CommentsFramePrivate() : textEncoding(String::Latin1) {}
  String::Type textEncoding;
  ByteVector language;
  String description;
  String text;
};

////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////

CommentsFrame::CommentsFrame(String::Type encoding) : Frame("COMM")
{
  d = new CommentsFramePrivate;
  d->textEncoding = encoding;
}

CommentsFrame::CommentsFrame(const ByteVector &data) : Frame(data)
{
  d = new CommentsFramePrivate;
  parseFields(data.mid(Header::size(header()->version()), size()));
}

CommentsFrame::~CommentsFrame()
{
  delete d;
}

String CommentsFrame::toString() const
{
  return d->text;
}

ByteVector CommentsFrame::language() const
{
  return d->language;
}

String CommentsFrame::description() const
{
  return d->description;
}

String CommentsFrame::text() const
{
  return d->text;
}

void CommentsFrame::setLanguage(const ByteVector &languageEncoding)
{
  d->language = languageEncoding.mid(0, 3);
}

void CommentsFrame::setDescription(const String &s)
{
  d->description = s;
}

void CommentsFrame::setText(const String &s)
{
  d->text = s;
}

String::Type CommentsFrame::textEncoding() const
{
  return d->textEncoding;
}

void CommentsFrame::setTextEncoding(String::Type encoding)
{
  d->textEncoding = encoding;
}

////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////

void CommentsFrame::parseFields(const ByteVector &data)
{
  if(data.size() < 5) {
    debug("A comment frame must contain at least 5 bytes.");
    return;
  }

  d->textEncoding = String::Type(data[0]);
  d->language = data.mid(1, 3);

  int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;

  ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign);

  if(l.size() == 2) {
    d->description = String(l.front(), d->textEncoding);
    d->text = String(l.back(), d->textEncoding);
  }
}

ByteVector CommentsFrame::renderFields() const
{
  ByteVector v;

  v.append(char(d->textEncoding));
  v.append(d->language);
  v.append(d->description.data(d->textEncoding));
  v.append(textDelimiter(d->textEncoding));
  v.append(d->text.data(d->textEncoding));

  return v;
}

////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////

CommentsFrame::CommentsFrame(const ByteVector &data, Header *h) : Frame(h)
{
  d = new CommentsFramePrivate();
  parseFields(fieldData(data));
}
<commit_msg>Use setData() rather than parseFields() here to make sure that the frame header is initialized.<commit_after>/***************************************************************************
    copyright            : (C) 2002, 2003 by Scott Wheeler
    email                : wheeler@kde.org
 ***************************************************************************/

/***************************************************************************
 *   This library is free software; you can redistribute it and/or modify  *
 *   it  under the terms of the GNU Lesser General Public License version  *
 *   2.1 as published by the Free Software Foundation.                     *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
 *   USA                                                                   *
 ***************************************************************************/

#include <tbytevectorlist.h>
#include <tdebug.h>

#include "commentsframe.h"

using namespace TagLib;
using namespace ID3v2;

class CommentsFrame::CommentsFramePrivate
{
public:
  CommentsFramePrivate() : textEncoding(String::Latin1) {}
  String::Type textEncoding;
  ByteVector language;
  String description;
  String text;
};

////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////

CommentsFrame::CommentsFrame(String::Type encoding) : Frame("COMM")
{
  d = new CommentsFramePrivate;
  d->textEncoding = encoding;
}

CommentsFrame::CommentsFrame(const ByteVector &data) : Frame(data)
{
  d = new CommentsFramePrivate;
  setData(data);
}

CommentsFrame::~CommentsFrame()
{
  delete d;
}

String CommentsFrame::toString() const
{
  return d->text;
}

ByteVector CommentsFrame::language() const
{
  return d->language;
}

String CommentsFrame::description() const
{
  return d->description;
}

String CommentsFrame::text() const
{
  return d->text;
}

void CommentsFrame::setLanguage(const ByteVector &languageEncoding)
{
  d->language = languageEncoding.mid(0, 3);
}

void CommentsFrame::setDescription(const String &s)
{
  d->description = s;
}

void CommentsFrame::setText(const String &s)
{
  d->text = s;
}

String::Type CommentsFrame::textEncoding() const
{
  return d->textEncoding;
}

void CommentsFrame::setTextEncoding(String::Type encoding)
{
  d->textEncoding = encoding;
}

////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////

void CommentsFrame::parseFields(const ByteVector &data)
{
  if(data.size() < 5) {
    debug("A comment frame must contain at least 5 bytes.");
    return;
  }

  d->textEncoding = String::Type(data[0]);
  d->language = data.mid(1, 3);

  int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;

  ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign);

  if(l.size() == 2) {
    d->description = String(l.front(), d->textEncoding);
    d->text = String(l.back(), d->textEncoding);
  }
}

ByteVector CommentsFrame::renderFields() const
{
  ByteVector v;

  v.append(char(d->textEncoding));
  v.append(d->language);
  v.append(d->description.data(d->textEncoding));
  v.append(textDelimiter(d->textEncoding));
  v.append(d->text.data(d->textEncoding));

  return v;
}

////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////

CommentsFrame::CommentsFrame(const ByteVector &data, Header *h) : Frame(h)
{
  d = new CommentsFramePrivate();
  parseFields(fieldData(data));
}
<|endoftext|>


<commit_before>#ifdef _DEBUG
#include "testdatapath.h"
#endif

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

#include "ImageScrap.h"

using namespace std;

//画像表示用関数
int showImage(const cv::Mat& image, int wait = 0){
	static const string wname("EBookChecker");

	cv::imshow(wname, image);
	return cv::waitKey(wait);
}

int main(int argc, char** argv)
{
#ifndef _DEBUG
	//コマンドライン引数の解析。デバッグの時は使わない
	string commandArgs =
		"@input |  | processing one image or image named serial number"
		;

	cv::CommandLineParser parser(argc, argv, commandArgs);

	string src = parser.get<string>(0);
#else
	string src = TEST_DATA_0;
#endif

	cout << "input file:" << src << endl;

	//画像の読み込み。グレースケール画像として読み込む
	cv::Mat image = cv::imread(src, CV_LOAD_IMAGE_GRAYSCALE);
	CV_Assert(image.channels() == 1 && image.type() == CV_8UC1);
	showImage(image);

	//二値化
	cv::Mat binary;
	int binaryMax = 1;//二値化時の最大値は1に。積分するときに白だったところか黒だったところかがわかればいい。
	int binaryThreshold = 128;
	cv::threshold(image, binary, binaryThreshold, binaryMax, cv::THRESH_BINARY_INV);
	CV_Assert(binary.channels() == 1 && binary.type() == CV_8UC1);
	showImage(binary);
	cv::imwrite("binary.jpg", binary);

	//積分画像の生成
	cv::Mat integral;
	cv::integral(binary, integral);
	CV_Assert(integral.channels() == 1 && integral.type() == CV_32SC1);
	showImage(integral);
	cv::imwrite("integral.jpg", integral);

	//積分画像を見やすくする処理
	cv::Mat integralVisible;
	double max;
	double min;
	cv::minMaxLoc(integral, &min, &max);//最大値だけほしいので第3引数まで。最小値は0のはずだが本当に0か確認するために使う
	CV_Assert(min == 0.0);//本当に最小値が0になっているか確認

	integral.convertTo(integralVisible, CV_8UC1, 255.0 / max); //betaは使わない。0-255の値をとるようにalphaを与える。
	showImage(integralVisible);
	cv::imwrite("integralVisible.jpg", integralVisible);

	//横方向
	//文字のない範囲を受け取る変数
	vector<Range> horizontalRanges;
	findSameValueHorizontal(integral, horizontalRanges);

	//1チャンネルの原画像から3チャンネルの画像を作る
	cv::Mat srcArray[] = {image, image, image};
	cv::Mat srcColor;
	cv::merge(srcArray, 3, srcColor);

	const cv::Scalar colorVertical(0, 0, 255);
	const cv::Scalar colorHorizontal(240, 176, 0);

	//文字のない範囲を書き込む画像
	cv::Mat horizontalRangeDst;
	drawRange(srcColor, horizontalRanges, ImageScrap::RANGE_COLS, horizontalRangeDst, colorHorizontal);

	/*
	//文字のない範囲を3チャンネルの原画像に書き込む
	for (size_t i = 0; i < horizontalRanges.size(); i++){
		Range& r = horizontalRanges[i];
		//文字のない範囲を3チャンネルの原画像から切り出す
		cv::Rect rect(r.start, 0, r.end - r.start, horizontalRangeDst.rows);
		cv::Mat roi(horizontalRangeDst, rect);
		//切り出した画像を1色で塗りつぶす
		roi = cv::Scalar(240, 176, 0);
	}
	*/

	showImage(horizontalRangeDst);
	cv::imwrite("horizontalDst.jpg", horizontalRangeDst);

	//縦方向
	//文字のない範囲を受け取る変数
	vector<Range> verticalRanges;
	findSameValueVertical(integral, verticalRanges);

	//文字のない範囲を書き込む画像
	cv::Mat verticalRangeDst;
	drawRange(srcColor, verticalRanges, ImageScrap::RANGE_ROWS, verticalRangeDst, colorVertical);
	/**
	//文字のない範囲を3チャンネルの原画像に書き込む
	for (size_t i = 0; i < verticalRanges.size(); i++){
		Range& r = verticalRanges[i];
		//文字のない範囲を3チャンネルの原画像から切り出す
		cv::Rect rect(0, r.start, verticalRangeDst.cols, r.end - r.start);
		cv::Mat roi(verticalRangeDst, rect);
		//切り出した画像を1色で塗りつぶす
		roi = cv::Scalar(0, 0, 255);
	}
	*/

	showImage(verticalRangeDst);
	cv::imwrite("verticalDst.jpg", verticalRangeDst);

	drawRange(horizontalRangeDst, verticalRanges, ImageScrap::RANGE_ROWS, horizontalRangeDst, colorVertical);

	/**
	//横方向の結果と縦方向の結果を合わせる
	for (size_t i = 0; i < verticalRanges.size(); i++){
		Range& r = verticalRanges[i];
		//文字のない範囲を3チャンネルの原画像から切り出す
		cv::Rect rect(0, r.start, horizontalRangeDst.cols, r.end - r.start);
		cv::Mat roi(horizontalRangeDst, rect);
		//切り出した画像を1色で塗りつぶす
		roi = cv::Scalar(0, 0, 255);
	}
	*/

	showImage(horizontalRangeDst);
	cv::imwrite("horizontalVerticalDst.jpg", horizontalRangeDst);
}<commit_msg>無駄なコメントやコードの削除<commit_after>#ifdef _DEBUG
#include "testdatapath.h"
#endif

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

#include "ImageScrap.h"

using namespace std;

//画像表示用関数
int showImage(const cv::Mat& image, int wait = 0){
	static const string wname("EBookChecker");

	cv::imshow(wname, image);
	return cv::waitKey(wait);
}

int main(int argc, char** argv)
{
#ifndef _DEBUG
	//コマンドライン引数の解析。デバッグの時は使わない
	string commandArgs =
		"@input |  | processing one image or image named serial number"
		;

	cv::CommandLineParser parser(argc, argv, commandArgs);

	string src = parser.get<string>(0);
#else
	string src = TEST_DATA_0;
#endif

	cout << "input file:" << src << endl;

	//画像の読み込み。グレースケール画像として読み込む
	cv::Mat image = cv::imread(src, CV_LOAD_IMAGE_GRAYSCALE);
	CV_Assert(image.channels() == 1 && image.type() == CV_8UC1);
	showImage(image);

	//二値化
	cv::Mat binary;
	int binaryMax = 1;//二値化時の最大値は1に。積分するときに白だったところか黒だったところかがわかればいい。
	int binaryThreshold = 128;
	cv::threshold(image, binary, binaryThreshold, binaryMax, cv::THRESH_BINARY_INV);
	CV_Assert(binary.channels() == 1 && binary.type() == CV_8UC1);
	showImage(binary);
	cv::imwrite("binary.jpg", binary);

	//積分画像の生成
	cv::Mat integral;
	cv::integral(binary, integral);
	CV_Assert(integral.channels() == 1 && integral.type() == CV_32SC1);
	showImage(integral);
	cv::imwrite("integral.jpg", integral);

	//積分画像を見やすくする処理
	cv::Mat integralVisible;
	double max;
	double min;
	cv::minMaxLoc(integral, &min, &max);//最大値だけほしいので第3引数まで。最小値は0のはずだが本当に0か確認するために使う
	CV_Assert(min == 0.0);//本当に最小値が0になっているか確認

	integral.convertTo(integralVisible, CV_8UC1, 255.0 / max); //betaは使わない。0-255の値をとるようにalphaを与える。
	showImage(integralVisible);
	cv::imwrite("integralVisible.jpg", integralVisible);

	//横方向
	//文字のない範囲を受け取る変数
	vector<Range> horizontalRanges;
	findSameValueHorizontal(integral, horizontalRanges);

	//1チャンネルの原画像から3チャンネルの画像を作る
	cv::Mat srcArray[] = {image, image, image};
	cv::Mat srcColor;
	cv::merge(srcArray, 3, srcColor);

	const cv::Scalar colorVertical(0, 0, 255);
	const cv::Scalar colorHorizontal(240, 176, 0);

	//文字のない範囲を書き込む画像
	cv::Mat horizontalRangeDst;
	drawRange(srcColor, horizontalRanges, ImageScrap::RANGE_COLS, horizontalRangeDst, colorHorizontal);
	showImage(horizontalRangeDst);
	cv::imwrite("horizontalDst.jpg", horizontalRangeDst);

	//縦方向
	//文字のない範囲を受け取る変数
	vector<Range> verticalRanges;
	findSameValueVertical(integral, verticalRanges);

	//文字のない範囲を書き込む画像
	cv::Mat verticalRangeDst;
	drawRange(srcColor, verticalRanges, ImageScrap::RANGE_ROWS, verticalRangeDst, colorVertical);
	showImage(verticalRangeDst);

	//縦横で文字のない範囲を書き込む
	cv::imwrite("verticalDst.jpg", verticalRangeDst);
	drawRange(horizontalRangeDst, verticalRanges, ImageScrap::RANGE_ROWS, horizontalRangeDst, colorVertical);
	showImage(horizontalRangeDst);
	cv::imwrite("horizontalVerticalDst.jpg", horizontalRangeDst);
}<|endoftext|>


<commit_before>#include <iostream>

int main()
{
	cout << "Hello World" << endl;
	return 0;
}
<commit_msg>delete CPP dir<commit_after><|endoftext|>


<commit_before>#include "bochs.h"
#include "cpu/extdb.h"
#ifdef WIN32
#  include <windows.h>
#else
#  error "extdb.cc only supported in win32 environment"
#endif

TRegs regs;

char debug_loaded = 0;

void (*call_debugger)(TRegs *,Bit8u *, Bit32u);

#if BX_SUPPORT_X86_64

void bx_external_debugger(BX_CPU_C *cpu)
{
     //printf("Calling debugger state=%d\n",regs.debug_state);
     switch (regs.debug_state) {
     case debug_run:
       return;
     case debug_count:
       if (--regs.debug_counter) return;
       regs.debug_state = debug_step;
       break;
     case debug_skip:
       if (cpu->dword.eip != regs.debug_eip ||
           cpu->sregs[1].selector.value != regs.debug_cs) return;
       regs.debug_state = debug_step;
       break;
     }

     regs.rax = cpu->gen_reg[0].rrx;
     regs.rcx = cpu->gen_reg[1].rrx;
     regs.rdx = cpu->gen_reg[2].rrx;
     regs.rbx = cpu->gen_reg[3].rrx;
     regs.rsp = cpu->gen_reg[4].rrx;
     regs.rbp = cpu->gen_reg[5].rrx;
     regs.rsi = cpu->gen_reg[6].rrx;
     regs.rdi = cpu->gen_reg[7].rrx;
     regs.r8  = cpu->gen_reg[8].rrx;
     regs.r9  = cpu->gen_reg[9].rrx;
     regs.r10 = cpu->gen_reg[10].rrx;
     regs.r11 = cpu->gen_reg[11].rrx;
     regs.r12 = cpu->gen_reg[12].rrx;
     regs.r13 = cpu->gen_reg[13].rrx;
     regs.r14 = cpu->gen_reg[14].rrx;
     regs.r15 = cpu->gen_reg[15].rrx;
     regs.rip = cpu->rip;
     regs.rflags = cpu->read_eflags();
     regs.es = cpu->sregs[0].selector.value;
     regs.cs = cpu->sregs[1].selector.value;
     regs.ss = cpu->sregs[2].selector.value;
     regs.ds = cpu->sregs[3].selector.value;
     regs.fs = cpu->sregs[4].selector.value;
     regs.gs = cpu->sregs[5].selector.value;
     regs.gdt.base = cpu->gdtr.base;
     regs.gdt.limit = cpu->gdtr.limit;
     regs.idt.base = cpu->idtr.base;
     regs.idt.limit = cpu->idtr.limit;
     regs.ldt = cpu->ldtr.selector.value;
     regs.cr0 = cpu->cr0.val32;
     regs.cr1 = cpu->cr1;
     regs.cr2 = cpu->cr2;
     regs.cr3 = cpu->cr3;
     regs.cr4 = cpu->cr4.val32;
     //regs.cr5 = cpu->cr5;
     //regs.cr6 = cpu->cr6;
     //regs.cr7 = cpu->cr7;
     regs.efer = (BX_CPU_THIS_PTR msr.sce << 0)
               | (BX_CPU_THIS_PTR msr.lme << 8)
               | (BX_CPU_THIS_PTR msr.lma << 10);

     if (debug_loaded == 0) {
       HINSTANCE hdbg;

       debug_loaded = 1;
       hdbg = LoadLibrary("debug.dll");
       call_debugger = (void (*)(TRegs *,Bit8u *, Bit32u)) GetProcAddress(hdbg,"call_debugger");

       if (call_debugger != NULL) debug_loaded = 2;
     }
     if (debug_loaded == 2) {
       bx_vga.timer();
       call_debugger(&regs,cpu->mem->vector,cpu->mem->len);
     }
}

#else  // x86-32

void bx_external_debugger(BX_CPU_C *cpu)
{
     switch (regs.debug_state) {
     case debug_run:
       return;
     case debug_count:
       if (--regs.debug_counter) return;
       regs.debug_state = debug_step;
       break;
     case debug_skip:
       if (cpu->dword.eip != regs.debug_eip ||
           cpu->sregs[1].selector.value != regs.debug_cs) return;
       regs.debug_state = debug_step;
       break;
     }

     regs.eax = cpu->gen_reg[0].dword.erx;
     regs.ecx = cpu->gen_reg[1].dword.erx;
     regs.edx = cpu->gen_reg[2].dword.erx;
     regs.ebx = cpu->gen_reg[3].dword.erx;
     regs.esp = cpu->gen_reg[4].dword.erx;
     regs.ebp = cpu->gen_reg[5].dword.erx;
     regs.esi = cpu->gen_reg[6].dword.erx;
     regs.edi = cpu->gen_reg[7].dword.erx;
     regs.eip = cpu->dword.eip;
     regs.eflags = cpu->read_eflags();
     regs.es = cpu->sregs[0].selector.value;
     regs.cs = cpu->sregs[1].selector.value;
     regs.ss = cpu->sregs[2].selector.value;
     regs.ds = cpu->sregs[3].selector.value;
     regs.fs = cpu->sregs[4].selector.value;
     regs.gs = cpu->sregs[5].selector.value;
     regs.gdt.base = cpu->gdtr.base;
     regs.gdt.limit = cpu->gdtr.limit;
     regs.idt.base = cpu->idtr.base;
     regs.idt.limit = cpu->idtr.limit;
     regs.ldt = cpu->ldtr.selector.value;
     regs.cr0 = cpu->cr0.val32;
     regs.cr1 = cpu->cr1;
     regs.cr2 = cpu->cr2;
     regs.cr3 = cpu->cr3;

     if (debug_loaded == 0) {
       HINSTANCE hdbg;

       debug_loaded = 1;
       hdbg = LoadLibrary("debug.dll");
       call_debugger = (void (*)(TRegs *,Bit8u *, Bit32u)) GetProcAddress(hdbg,"call_debugger");

       if (call_debugger != NULL) debug_loaded = 2;
     }
     if (debug_loaded == 2) call_debugger(&regs,cpu->mem->vector,cpu->mem->len);
}

#end   // #if BX_SUPPORT_X86_64
<commit_msg>Fixed CR4 reference in extdb.cc to use the new accessor model. Also, deleted the old 32-bit path in there as Peter said it's no longer useful to him.<commit_after>#include "bochs.h"
#include "cpu/extdb.h"
#ifdef WIN32
#  include <windows.h>
#else
#  error "extdb.cc only supported in win32 environment"
#endif

TRegs regs;

char debug_loaded = 0;

void (*call_debugger)(TRegs *,Bit8u *, Bit32u);

void bx_external_debugger(BX_CPU_C *cpu)
{
     //printf("Calling debugger state=%d\n",regs.debug_state);
     switch (regs.debug_state) {
     case debug_run:
       return;
     case debug_count:
       if (--regs.debug_counter) return;
       regs.debug_state = debug_step;
       break;
     case debug_skip:
       if (cpu->dword.eip != regs.debug_eip ||
           cpu->sregs[1].selector.value != regs.debug_cs) return;
       regs.debug_state = debug_step;
       break;
     }

     regs.rax = cpu->gen_reg[0].rrx;
     regs.rcx = cpu->gen_reg[1].rrx;
     regs.rdx = cpu->gen_reg[2].rrx;
     regs.rbx = cpu->gen_reg[3].rrx;
     regs.rsp = cpu->gen_reg[4].rrx;
     regs.rbp = cpu->gen_reg[5].rrx;
     regs.rsi = cpu->gen_reg[6].rrx;
     regs.rdi = cpu->gen_reg[7].rrx;
     regs.r8  = cpu->gen_reg[8].rrx;
     regs.r9  = cpu->gen_reg[9].rrx;
     regs.r10 = cpu->gen_reg[10].rrx;
     regs.r11 = cpu->gen_reg[11].rrx;
     regs.r12 = cpu->gen_reg[12].rrx;
     regs.r13 = cpu->gen_reg[13].rrx;
     regs.r14 = cpu->gen_reg[14].rrx;
     regs.r15 = cpu->gen_reg[15].rrx;
     regs.rip = cpu->rip;
     regs.rflags = cpu->read_eflags();
     regs.es = cpu->sregs[0].selector.value;
     regs.cs = cpu->sregs[1].selector.value;
     regs.ss = cpu->sregs[2].selector.value;
     regs.ds = cpu->sregs[3].selector.value;
     regs.fs = cpu->sregs[4].selector.value;
     regs.gs = cpu->sregs[5].selector.value;
     regs.gdt.base = cpu->gdtr.base;
     regs.gdt.limit = cpu->gdtr.limit;
     regs.idt.base = cpu->idtr.base;
     regs.idt.limit = cpu->idtr.limit;
     regs.ldt = cpu->ldtr.selector.value;
     regs.cr0 = cpu->cr0.val32;
     regs.cr1 = cpu->cr1;
     regs.cr2 = cpu->cr2;
     regs.cr3 = cpu->cr3;
     regs.cr4 = cpu->cr4.getRegister();
     //regs.cr5 = cpu->cr5;
     //regs.cr6 = cpu->cr6;
     //regs.cr7 = cpu->cr7;
     regs.efer = (BX_CPU_THIS_PTR msr.sce << 0)
               | (BX_CPU_THIS_PTR msr.lme << 8)
               | (BX_CPU_THIS_PTR msr.lma << 10);

     if (debug_loaded == 0) {
       HINSTANCE hdbg;

       debug_loaded = 1;
       hdbg = LoadLibrary("debug.dll");
       call_debugger = (void (*)(TRegs *,Bit8u *, Bit32u)) GetProcAddress(hdbg,"call_debugger");

       if (call_debugger != NULL) debug_loaded = 2;
     }
     if (debug_loaded == 2) {
       bx_vga.timer();
       call_debugger(&regs,cpu->mem->vector,cpu->mem->len);
     }
}
<|endoftext|>


<commit_before>/*
Copyright DaiMysha (c) 2015, All rights reserved.
DaiMysha@gmail.com
https://github.com/DaiMysha

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.

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 HOLDER 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 <iostream>

#include <SFML/OpenGL.hpp>

#include <DMUtils/sfml.hpp>

#include <LightSystem/LightSystem.hpp>
#include <LightSystem/staticData/staticData.hpp>
#include <LightSystem/ShadowSystem.hpp>

namespace dm {
namespace ls {

    const sf::RenderStates LightSystem::_multiplyState(sf::BlendMultiply);
    const sf::RenderStates LightSystem::_addState(sf::BlendAdd);
    //const sf::RenderStates LightSystem::_subtractState(sf::BlendMode(sf::BlendMode::One, sf::BlendMode::One, sf::BlendMode::ReverseSubtract));
    const sf::RenderStates LightSystem::_subtractState(sf::BlendMode(sf::BlendMode::Zero, sf::BlendMode::OneMinusSrcColor, sf::BlendMode::Add));

    LightSystem::LightSystem() : _ambiant(sf::Color::Black), _isometric(false), _autoDelete(true), _updateLightMapImage(true) {

        /*if(!_lightAttenuationShader.loadFromFile("shaders/lightAttenuation.frag",sf::Shader::Fragment)) {
            std::cerr << "Missing light attenuation Shader. System won't work" << std::endl;
        }*/

        if(!_lightAttenuationShader.loadFromMemory(dm::ls::StaticData::LIGHT_ATTENUATION_SHADER,sf::Shader::Fragment)) {
            std::cerr << "Missing light attenuation Shader. System won't work" << std::endl;
        }

        _shadowSystem = new ShadowSystem();

    }

    LightSystem::~LightSystem() {
        reset();
        delete _shadowSystem;
    }

    void LightSystem::addLight(Light* l) {
        if(l==nullptr) return;

        l->setIsometric(_isometric);//ignore what user set before
        l->preRender(&_lightAttenuationShader);

        if(l->isEmissive()) _emissiveLights.emplace_back(l);
        else if(l->isNegative()) _negativeLights.emplace_back(l);
        else _lights.emplace_back(l);

        l->setSystem(this);

        _updateLightMapImage = true;
    }

    void LightSystem::removeLight(Light* l) {
        if(l==nullptr) return;

        if(l->isEmissive()) _emissiveLights.remove(l);
        else if(l->isNegative()) _negativeLights.remove(l);
        else _lights.remove(l);
    }

    void LightSystem::reset() {

        for(Light* l : _lights) {
            l->setSystem(nullptr);
            if(_autoDelete) delete l;
        }
        for(Light* l : _negativeLights) {
            l->setSystem(nullptr);
            if(_autoDelete) delete l;
        }
        for(Light* l : _emissiveLights) {
            l->setSystem(nullptr);
            if(_autoDelete) delete l;
        }

        _lights.empty();
        _negativeLights.empty();
        _emissiveLights.empty();

        if(_shadowSystem) _shadowSystem->clear();
    }

    void LightSystem::addWall(const sf::ConvexShape& s) {
        if(_shadowSystem) _shadowSystem->addWall(s);
    }

    void LightSystem::render(const sf::View& screenView, sf::RenderTarget& target) {
        debugRender(screenView,target,LightSystem::DebugFlags::DEFAULT);
    }

    void LightSystem::debugRender(const sf::View& screenView, sf::RenderTarget& target, int flags) {
        sf::IntRect screen = DMUtils::sfml::getViewInWorldAABB(screenView);

        _sprite.setPosition(screen.left,screen.top);

        _renderTexture.clear(_ambiant);
        sf::RenderStates stAdd(_addState);
        sf::RenderStates stRm(_subtractState);
        sf::RenderStates stMp(_multiplyState);

        sf::Transform t;
        t.translate(-_sprite.getPosition());
        stAdd.transform.combine(t);
        stRm.transform.combine(t);
        stMp.transform.combine(t);

        sf::FloatRect screenRect(screen);

        for(Light* l : _lights) {
            if(l->getAABB().intersects(screen)) {
                if(flags & DebugFlags::SHADER_OFF) l->debugRender(_renderTexture,stAdd);
                else {
                    _buffer.clear(sf::Color::Black);
                    //sf::FloatRect rect(l->getAABB().left,l->getAABB().top,l->getAABB().width,l->getAABB().height);
                    l->calcShadow(_shadowSystem->getWalls());
                    //l->render(screen,_renderTexture,&_lightAttenuationShader,stAdd);
                    l->render(screen,_buffer,&_lightAttenuationShader,stMp);
                    _buffer.display();
                    _renderTexture.draw(_bufferSprite,_addState);
                }
            }
        }
        for(Light* l : _negativeLights) {
            if(l->getAABB().intersects(screen)) {
                if(flags & DebugFlags::SHADER_OFF) l->debugRender(_renderTexture,stRm);
                else {
                    _buffer.clear(sf::Color::Black);
                    //sf::FloatRect rect(l->getAABB().left,l->getAABB().top,l->getAABB().width,l->getAABB().height);
                    l->calcShadow(_shadowSystem->getWalls());
                    //l->render(screen,_renderTexture,&_lightAttenuationShader,stAdd);
                    l->render(screen,_buffer,&_lightAttenuationShader,stMp);
                    _buffer.display();
                    _renderTexture.draw(_bufferSprite,_subtractState);
                }
            }
        }

        _renderTexture.display();

        _updateLightMapImage = true;
        if(flags & DebugFlags::LIGHTMAP_ONLY) target.clear(sf::Color::White);
    }

    void LightSystem::draw(const sf::View& screenView, sf::RenderTarget& target) {
        sf::IntRect screen = DMUtils::sfml::getViewInWorldAABB(screenView);
        target.draw(_sprite,_multiplyState);
        for(Light* l : _emissiveLights) {
            if(l->getAABB().intersects(screen)) {
                l->render(screen,target,nullptr);
            }
        }
    }

    void LightSystem::drawAABB(const sf::View& screen, sf::RenderTarget& target) {
        drawAABB(DMUtils::sfml::getViewInWorldAABB(screen),target);
    }

    void LightSystem::drawAABB(const sf::IntRect& screen, sf::RenderTarget& target) {
        for(Light* l : _lights) {
            if(l->getAABB().intersects(screen)) l->drawAABB(screen,target);
        }
        for(Light* l : _negativeLights) {
            if(l->getAABB().intersects(screen)) l->drawAABB(screen,target);
        }
        for(Light* l : _emissiveLights) {
            if(l->getAABB().intersects(screen)) l->drawAABB(screen,target);
        }
    }

    void LightSystem::drawWalls(const sf::View& screenView, sf::RenderTarget& target) {
        //sf::IntRect screen = DMUtils::sfml::getViewInWorldAABB(screenView);
        if(_shadowSystem) {
            //for(Light* l : _lights) if(l->getAABB().intersects(screen)) _shadowSystem->debugDraw(l,screenView,target);
            //for(Light* l : _negativeLights) if(l->getAABB().intersects(screen)) _shadowSystem->debugDraw(l,screenView,target);
            _shadowSystem->draw(screenView,target);
        }
    }

    void LightSystem::update() {
        for(Light* l : _lights) update(l);
        for(Light* l : _negativeLights) update(l);
        for(Light* l : _emissiveLights) update(l);
    }

    void LightSystem::update(Light* l) {
        l->preRender(&_lightAttenuationShader);
        _updateLightMapImage = true;
    }

    size_t LightSystem::getLightsCount() const {
        return getNormalLightsCount() + getNegativeLightsCount() + getEmissiveLightsCount();
    }

    size_t LightSystem::getNormalLightsCount() const {
        return _lights.size();
    }

    size_t LightSystem::getNegativeLightsCount() const {
        return _negativeLights.size();
    }

    size_t LightSystem::getEmissiveLightsCount() const {
        return _emissiveLights.size();
    }

    sf::Image LightSystem::getLightMap() {
        if(_updateLightMapImage) {
            _lightMapImage = _renderTexture.getTexture().copyToImage();
            _updateLightMapImage = false;
        }
        return _lightMapImage;
    }

    sf::Color LightSystem::getLightMapPixel(const sf::View& view, unsigned int x, unsigned int y) {
        sf::Image lightMap = getLightMap();
        x -= view.getViewport().left;
        y -= view.getViewport().top;
        if(x>=0&&y>=0&&x<lightMap.getSize().x&&y<lightMap.getSize().y) return lightMap.getPixel(x,y);
        else return sf::Color::Black;
    }

    sf::Color LightSystem::getLightMapPixel(const sf::View& view, sf::Vector2f p) {
        return getLightMapPixel(view,p.x,p.y);
    }

    void LightSystem::setAmbiantLight(sf::Color c) {
        _ambiant = c;
    }

    sf::Color LightSystem::getAmbiantLight() const {
        return _ambiant;
    }

    /*void LightSystem::setIsometric(bool i) {
        _isometric = i;
        update();
    }

    bool LightSystem::isIsometric() const {
        return _isometric;
    }*/

    void LightSystem::setAutoDelete(bool ad) {
        _autoDelete = ad;
    }

    void LightSystem::setView(const sf::View& view) {
        _renderTexture.create(view.getSize().x,view.getSize().y);
        _buffer.create(view.getSize().x,view.getSize().y);

        _sprite.setTexture(_renderTexture.getTexture(),true);
        _bufferSprite.setTexture(_buffer.getTexture(),true);
    }
}
}
<commit_msg>Switched to reversed substract<commit_after>/*
Copyright DaiMysha (c) 2015, All rights reserved.
DaiMysha@gmail.com
https://github.com/DaiMysha

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.

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 HOLDER 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 <iostream>

#include <SFML/OpenGL.hpp>

#include <DMUtils/sfml.hpp>

#include <LightSystem/LightSystem.hpp>
#include <LightSystem/staticData/staticData.hpp>
#include <LightSystem/ShadowSystem.hpp>

namespace dm {
namespace ls {

    const sf::RenderStates LightSystem::_multiplyState(sf::BlendMultiply);
    const sf::RenderStates LightSystem::_addState(sf::BlendAdd);
    const sf::RenderStates LightSystem::_subtractState(sf::BlendMode(sf::BlendMode::One, sf::BlendMode::One, sf::BlendMode::ReverseSubtract));

    LightSystem::LightSystem() : _ambiant(sf::Color::Black), _isometric(false), _autoDelete(true), _updateLightMapImage(true) {

        /*if(!_lightAttenuationShader.loadFromFile("shaders/lightAttenuation.frag",sf::Shader::Fragment)) {
            std::cerr << "Missing light attenuation Shader. System won't work" << std::endl;
        }*/

        if(!_lightAttenuationShader.loadFromMemory(dm::ls::StaticData::LIGHT_ATTENUATION_SHADER,sf::Shader::Fragment)) {
            std::cerr << "Missing light attenuation Shader. System won't work" << std::endl;
        }

        _shadowSystem = new ShadowSystem();

    }

    LightSystem::~LightSystem() {
        reset();
        delete _shadowSystem;
    }

    void LightSystem::addLight(Light* l) {
        if(l==nullptr) return;

        l->setIsometric(_isometric);//ignore what user set before
        l->preRender(&_lightAttenuationShader);

        if(l->isEmissive()) _emissiveLights.emplace_back(l);
        else if(l->isNegative()) _negativeLights.emplace_back(l);
        else _lights.emplace_back(l);

        l->setSystem(this);

        _updateLightMapImage = true;
    }

    void LightSystem::removeLight(Light* l) {
        if(l==nullptr) return;

        if(l->isEmissive()) _emissiveLights.remove(l);
        else if(l->isNegative()) _negativeLights.remove(l);
        else _lights.remove(l);
    }

    void LightSystem::reset() {

        for(Light* l : _lights) {
            l->setSystem(nullptr);
            if(_autoDelete) delete l;
        }
        for(Light* l : _negativeLights) {
            l->setSystem(nullptr);
            if(_autoDelete) delete l;
        }
        for(Light* l : _emissiveLights) {
            l->setSystem(nullptr);
            if(_autoDelete) delete l;
        }

        _lights.empty();
        _negativeLights.empty();
        _emissiveLights.empty();

        if(_shadowSystem) _shadowSystem->clear();
    }

    void LightSystem::addWall(const sf::ConvexShape& s) {
        if(_shadowSystem) _shadowSystem->addWall(s);
    }

    void LightSystem::render(const sf::View& screenView, sf::RenderTarget& target) {
        debugRender(screenView,target,LightSystem::DebugFlags::DEFAULT);
    }

    void LightSystem::debugRender(const sf::View& screenView, sf::RenderTarget& target, int flags) {
        sf::IntRect screen = DMUtils::sfml::getViewInWorldAABB(screenView);

        _sprite.setPosition(screen.left,screen.top);

        _renderTexture.clear(_ambiant);
        sf::RenderStates stAdd(_addState);
        sf::RenderStates stRm(_subtractState);
        sf::RenderStates stMp(_multiplyState);

        sf::Transform t;
        t.translate(-_sprite.getPosition());
        stAdd.transform.combine(t);
        stRm.transform.combine(t);
        stMp.transform.combine(t);

        sf::FloatRect screenRect(screen);

        for(Light* l : _lights) {
            if(l->getAABB().intersects(screen)) {
                if(flags & DebugFlags::SHADER_OFF) l->debugRender(_renderTexture,stAdd);
                else {
                    _buffer.clear(sf::Color::Black);
                    //sf::FloatRect rect(l->getAABB().left,l->getAABB().top,l->getAABB().width,l->getAABB().height);
                    l->calcShadow(_shadowSystem->getWalls());
                    //l->render(screen,_renderTexture,&_lightAttenuationShader,stAdd);
                    l->render(screen,_buffer,&_lightAttenuationShader,stMp);
                    _buffer.display();
                    _renderTexture.draw(_bufferSprite,_addState);
                }
            }
        }
        for(Light* l : _negativeLights) {
            if(l->getAABB().intersects(screen)) {
                if(flags & DebugFlags::SHADER_OFF) l->debugRender(_renderTexture,stRm);
                else {
                    _buffer.clear(sf::Color::Black);
                    //sf::FloatRect rect(l->getAABB().left,l->getAABB().top,l->getAABB().width,l->getAABB().height);
                    l->calcShadow(_shadowSystem->getWalls());
                    //l->render(screen,_renderTexture,&_lightAttenuationShader,stAdd);
                    l->render(screen,_buffer,&_lightAttenuationShader,stMp);
                    _buffer.display();
                    _renderTexture.draw(_bufferSprite,_subtractState);
                }
            }
        }

        _renderTexture.display();

        _updateLightMapImage = true;
        if(flags & DebugFlags::LIGHTMAP_ONLY) target.clear(sf::Color::White);
    }

    void LightSystem::draw(const sf::View& screenView, sf::RenderTarget& target) {
        sf::IntRect screen = DMUtils::sfml::getViewInWorldAABB(screenView);
        target.draw(_sprite,_multiplyState);
        for(Light* l : _emissiveLights) {
            if(l->getAABB().intersects(screen)) {
                l->render(screen,target,nullptr);
            }
        }
    }

    void LightSystem::drawAABB(const sf::View& screen, sf::RenderTarget& target) {
        drawAABB(DMUtils::sfml::getViewInWorldAABB(screen),target);
    }

    void LightSystem::drawAABB(const sf::IntRect& screen, sf::RenderTarget& target) {
        for(Light* l : _lights) {
            if(l->getAABB().intersects(screen)) l->drawAABB(screen,target);
        }
        for(Light* l : _negativeLights) {
            if(l->getAABB().intersects(screen)) l->drawAABB(screen,target);
        }
        for(Light* l : _emissiveLights) {
            if(l->getAABB().intersects(screen)) l->drawAABB(screen,target);
        }
    }

    void LightSystem::drawWalls(const sf::View& screenView, sf::RenderTarget& target) {
        //sf::IntRect screen = DMUtils::sfml::getViewInWorldAABB(screenView);
        if(_shadowSystem) {
            //for(Light* l : _lights) if(l->getAABB().intersects(screen)) _shadowSystem->debugDraw(l,screenView,target);
            //for(Light* l : _negativeLights) if(l->getAABB().intersects(screen)) _shadowSystem->debugDraw(l,screenView,target);
            _shadowSystem->draw(screenView,target);
        }
    }

    void LightSystem::update() {
        for(Light* l : _lights) update(l);
        for(Light* l : _negativeLights) update(l);
        for(Light* l : _emissiveLights) update(l);
    }

    void LightSystem::update(Light* l) {
        l->preRender(&_lightAttenuationShader);
        _updateLightMapImage = true;
    }

    size_t LightSystem::getLightsCount() const {
        return getNormalLightsCount() + getNegativeLightsCount() + getEmissiveLightsCount();
    }

    size_t LightSystem::getNormalLightsCount() const {
        return _lights.size();
    }

    size_t LightSystem::getNegativeLightsCount() const {
        return _negativeLights.size();
    }

    size_t LightSystem::getEmissiveLightsCount() const {
        return _emissiveLights.size();
    }

    sf::Image LightSystem::getLightMap() {
        if(_updateLightMapImage) {
            _lightMapImage = _renderTexture.getTexture().copyToImage();
            _updateLightMapImage = false;
        }
        return _lightMapImage;
    }

    sf::Color LightSystem::getLightMapPixel(const sf::View& view, unsigned int x, unsigned int y) {
        sf::Image lightMap = getLightMap();
        x -= view.getViewport().left;
        y -= view.getViewport().top;
        if(x>=0&&y>=0&&x<lightMap.getSize().x&&y<lightMap.getSize().y) return lightMap.getPixel(x,y);
        else return sf::Color::Black;
    }

    sf::Color LightSystem::getLightMapPixel(const sf::View& view, sf::Vector2f p) {
        return getLightMapPixel(view,p.x,p.y);
    }

    void LightSystem::setAmbiantLight(sf::Color c) {
        _ambiant = c;
    }

    sf::Color LightSystem::getAmbiantLight() const {
        return _ambiant;
    }

    /*void LightSystem::setIsometric(bool i) {
        _isometric = i;
        update();
    }

    bool LightSystem::isIsometric() const {
        return _isometric;
    }*/

    void LightSystem::setAutoDelete(bool ad) {
        _autoDelete = ad;
    }

    void LightSystem::setView(const sf::View& view) {
        _renderTexture.create(view.getSize().x,view.getSize().y);
        _buffer.create(view.getSize().x,view.getSize().y);

        _sprite.setTexture(_renderTexture.getTexture(),true);
        _bufferSprite.setTexture(_buffer.getTexture(),true);
    }
}
}
<|endoftext|>


<commit_before>#include "wled.h"

/*
 * Handles playlists, timed sequences of presets
 */

typedef struct PlaylistEntry {
  uint8_t preset; //ID of the preset to apply
  uint16_t dur;   //Duration of the entry (in tenths of seconds)
  uint16_t tr;    //Duration of the transition TO this entry (in tenths of seconds)
} ple;

byte           playlistRepeat = 1;        //how many times to repeat the playlist (0 = infinitely)
byte           playlistEndPreset = 0;     //what preset to apply after playlist end (0 = stay on last preset)
byte           playlistOptions = 0;       //bit 0: shuffle playlist after each iteration. bits 1-7 TBD

PlaylistEntry *playlistEntries = nullptr;
byte           playlistLen;               //number of playlist entries
int8_t         playlistIndex = -1;
uint16_t       playlistEntryDur = 0;      //duration of the current entry in tenths of seconds

//values we need to keep about the parent playlist while inside sub-playlist
//int8_t         parentPlaylistIndex = -1;
//byte           parentPlaylistRepeat = 0;
//byte           parentPlaylistPresetId = 0; //for re-loading

void shufflePlaylist() {
  int currentIndex = playlistLen;
  PlaylistEntry temporaryValue;

  // While there remain elements to shuffle...
  while (currentIndex--) {
    // Pick a random element...
    int randomIndex = random(0, currentIndex);
    // And swap it with the current element.
    temporaryValue = playlistEntries[currentIndex];
    playlistEntries[currentIndex] = playlistEntries[randomIndex];
    playlistEntries[randomIndex] = temporaryValue;
  }
  DEBUG_PRINTLN(F("Playlist shuffle."));
}

void unloadPlaylist() {
  if (playlistEntries != nullptr) {
    delete[] playlistEntries;
    playlistEntries = nullptr;
  }
  currentPlaylist = playlistIndex = -1;
  playlistLen = playlistEntryDur = playlistOptions = 0;
  DEBUG_PRINTLN(F("Playlist unloaded."));
}

int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
  unloadPlaylist();

  JsonArray presets = playlistObj["ps"];
  playlistLen = presets.size();
  if (playlistLen == 0) return -1;
  if (playlistLen > 100) playlistLen = 100;

  playlistEntries = new PlaylistEntry[playlistLen];
  if (playlistEntries == nullptr) return -1;

  byte it = 0;
  for (int ps : presets) {
    if (it >= playlistLen) break;
    playlistEntries[it].preset = ps;
    it++;
  }

  it = 0;
  JsonArray durations = playlistObj["dur"];
  if (durations.isNull()) {
    playlistEntries[0].dur = playlistObj["dur"] | 100; //10 seconds as fallback
    it = 1;
  } else {
    for (int dur : durations) {
      if (it >= playlistLen) break;
      playlistEntries[it].dur = (dur > 1) ? dur : 100;
      it++;
    }
  }
  for (int i = it; i < playlistLen; i++) playlistEntries[i].dur = playlistEntries[it -1].dur;

  it = 0;
  JsonArray tr = playlistObj[F("transition")];
  if (tr.isNull()) {
    playlistEntries[0].tr = playlistObj[F("transition")] | (transitionDelay / 100);
    it = 1;
  } else {
    for (int transition : tr) {
      if (it >= playlistLen) break;
      playlistEntries[it].tr = transition;
      it++;
    }
  }
  for (int i = it; i < playlistLen; i++) playlistEntries[i].tr = playlistEntries[it -1].tr;

  int rep = playlistObj[F("repeat")];
  bool shuffle = false;
  if (rep < 0) { //support negative values as infinite + shuffle
    rep = 0; shuffle = true;
  }

  playlistRepeat = rep;
  if (playlistRepeat > 0) playlistRepeat++; //add one extra repetition immediately since it will be deducted on first start
  playlistEndPreset = playlistObj[F("end")] | 0;
  shuffle = shuffle || playlistObj["r"];
  if (shuffle) playlistOptions += PL_OPTION_SHUFFLE;

  currentPlaylist = presetId;
  DEBUG_PRINTLN(F("Playlist loaded."));
  return currentPlaylist;
}

void handlePlaylist() {
  static unsigned long presetCycledTime = 0;
  if (currentPlaylist < 0 || playlistEntries == nullptr) return;

  if (millis() - presetCycledTime > (100*playlistEntryDur)) {
    presetCycledTime = millis();
    if (bri == 0 || nightlightActive) return;

    ++playlistIndex %= playlistLen; // -1 at 1st run (limit to playlistLen)

    // playlist roll-over
    if (!playlistIndex) {
      if (playlistRepeat == 1) { //stop if all repetitions are done
        unloadPlaylist();
        if (playlistEndPreset) applyPreset(playlistEndPreset);
        return;
      }
      if (playlistRepeat > 1) playlistRepeat--; // decrease repeat count on each index reset if not an endless playlist
      // playlistRepeat == 0: endless loop
      if (playlistOptions & PL_OPTION_SHUFFLE) shufflePlaylist(); // shuffle playlist and start over
    }

    jsonTransitionOnce = true;
    transitionDelayTemp = playlistEntries[playlistIndex].tr * 100;
    playlistEntryDur = playlistEntries[playlistIndex].dur;
    applyPreset(playlistEntries[playlistIndex].preset);
  }
}
<commit_msg>Playlist corrupting JSON buffer bugfix.<commit_after>#include "wled.h"

/*
 * Handles playlists, timed sequences of presets
 */

typedef struct PlaylistEntry {
  uint8_t preset; //ID of the preset to apply
  uint16_t dur;   //Duration of the entry (in tenths of seconds)
  uint16_t tr;    //Duration of the transition TO this entry (in tenths of seconds)
} ple;

byte           playlistRepeat = 1;        //how many times to repeat the playlist (0 = infinitely)
byte           playlistEndPreset = 0;     //what preset to apply after playlist end (0 = stay on last preset)
byte           playlistOptions = 0;       //bit 0: shuffle playlist after each iteration. bits 1-7 TBD

PlaylistEntry *playlistEntries = nullptr;
byte           playlistLen;               //number of playlist entries
int8_t         playlistIndex = -1;
uint16_t       playlistEntryDur = 0;      //duration of the current entry in tenths of seconds

//values we need to keep about the parent playlist while inside sub-playlist
//int8_t         parentPlaylistIndex = -1;
//byte           parentPlaylistRepeat = 0;
//byte           parentPlaylistPresetId = 0; //for re-loading

void shufflePlaylist() {
  int currentIndex = playlistLen;
  PlaylistEntry temporaryValue;

  // While there remain elements to shuffle...
  while (currentIndex--) {
    // Pick a random element...
    int randomIndex = random(0, currentIndex);
    // And swap it with the current element.
    temporaryValue = playlistEntries[currentIndex];
    playlistEntries[currentIndex] = playlistEntries[randomIndex];
    playlistEntries[randomIndex] = temporaryValue;
  }
  DEBUG_PRINTLN(F("Playlist shuffle."));
}

void unloadPlaylist() {
  if (playlistEntries != nullptr) {
    delete[] playlistEntries;
    playlistEntries = nullptr;
  }
  currentPlaylist = playlistIndex = -1;
  playlistLen = playlistEntryDur = playlistOptions = 0;
  DEBUG_PRINTLN(F("Playlist unloaded."));
}

int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
  unloadPlaylist();

  JsonArray presets = playlistObj["ps"];
  playlistLen = presets.size();
  if (playlistLen == 0) return -1;
  if (playlistLen > 100) playlistLen = 100;

  playlistEntries = new PlaylistEntry[playlistLen];
  if (playlistEntries == nullptr) return -1;

  byte it = 0;
  for (int ps : presets) {
    if (it >= playlistLen) break;
    playlistEntries[it].preset = ps;
    it++;
  }

  it = 0;
  JsonArray durations = playlistObj["dur"];
  if (durations.isNull()) {
    playlistEntries[0].dur = playlistObj["dur"] | 100; //10 seconds as fallback
    it = 1;
  } else {
    for (int dur : durations) {
      if (it >= playlistLen) break;
      playlistEntries[it].dur = (dur > 1) ? dur : 100;
      it++;
    }
  }
  for (int i = it; i < playlistLen; i++) playlistEntries[i].dur = playlistEntries[it -1].dur;

  it = 0;
  JsonArray tr = playlistObj[F("transition")];
  if (tr.isNull()) {
    playlistEntries[0].tr = playlistObj[F("transition")] | (transitionDelay / 100);
    it = 1;
  } else {
    for (int transition : tr) {
      if (it >= playlistLen) break;
      playlistEntries[it].tr = transition;
      it++;
    }
  }
  for (int i = it; i < playlistLen; i++) playlistEntries[i].tr = playlistEntries[it -1].tr;

  int rep = playlistObj[F("repeat")];
  bool shuffle = false;
  if (rep < 0) { //support negative values as infinite + shuffle
    rep = 0; shuffle = true;
  }

  playlistRepeat = rep;
  if (playlistRepeat > 0) playlistRepeat++; //add one extra repetition immediately since it will be deducted on first start
  playlistEndPreset = playlistObj[F("end")] | 0;
  shuffle = shuffle || playlistObj["r"];
  if (shuffle) playlistOptions += PL_OPTION_SHUFFLE;

  currentPlaylist = presetId;
  DEBUG_PRINTLN(F("Playlist loaded."));
  return currentPlaylist;
}

void handlePlaylist() {
  static unsigned long presetCycledTime = 0;
  // if fileDoc is not null JSON buffer is in use so just quit
  if (currentPlaylist < 0 || playlistEntries == nullptr || fileDoc != nullptr) return;

  if (millis() - presetCycledTime > (100*playlistEntryDur)) {
    presetCycledTime = millis();
    if (bri == 0 || nightlightActive) return;

    ++playlistIndex %= playlistLen; // -1 at 1st run (limit to playlistLen)

    // playlist roll-over
    if (!playlistIndex) {
      if (playlistRepeat == 1) { //stop if all repetitions are done
        unloadPlaylist();
        if (playlistEndPreset) applyPreset(playlistEndPreset);
        return;
      }
      if (playlistRepeat > 1) playlistRepeat--; // decrease repeat count on each index reset if not an endless playlist
      // playlistRepeat == 0: endless loop
      if (playlistOptions & PL_OPTION_SHUFFLE) shufflePlaylist(); // shuffle playlist and start over
    }

    jsonTransitionOnce = true;
    transitionDelayTemp = playlistEntries[playlistIndex].tr * 100;
    playlistEntryDur = playlistEntries[playlistIndex].dur;
    applyPreset(playlistEntries[playlistIndex].preset);
  }
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkImageToSurfaceFilter.h"
#include <vtkImageData.h>
#include <vtkDecimatePro.h>

mitk::ImageToSurfaceFilter::ImageToSurfaceFilter()
  : m_Smooth(false), m_Decimate(false), m_TargetReduction(0.05f){};
mitk::ImageToSurfaceFilter::~ImageToSurfaceFilter(){};

void mitk::ImageToSurfaceFilter::CreateSurface(int time, vtkImageData *vtkimage, mitk::Surface * surface, const ScalarType threshold)
{
  //Inkrement Referenzcounter Counter (hier: RC)
  vtkimage->Register(NULL);

  vtkPolyData *polydata = vtkPolyData::New();
  polydata->Register(NULL);// RC++

  //MarchingCube -->create Surface
  vtkMarchingCubes *skinExtractor = vtkMarchingCubes::New();
  skinExtractor->SetInput(vtkimage);//RC++
  vtkimage->Delete();//RC--
  skinExtractor->SetValue(0, threshold);
  polydata = skinExtractor->GetOutput();

  if (m_Smooth)
  {
    int spIterations =50;
    float spRelaxation =0.1;

    vtkSmoothPolyDataFilter *smoother = vtkSmoothPolyDataFilter::New();
    //read poly1 (poly1 can be the original polygon, or the decimated polygon)
    smoother->SetInput(polydata);//RC++
    polydata->Delete();//RC--
    smoother->SetNumberOfIterations( spIterations );
    smoother->SetRelaxationFactor( spRelaxation );
    smoother->SetFeatureAngle( 60 );
    smoother->FeatureEdgeSmoothingOff();
    smoother->BoundarySmoothingOff();
    smoother->SetConvergence( 0 );

    polydata = smoother->GetOutput();

  }

  //decimate = to reduce number of polygons
  if(m_Decimate)
  {
    vtkDecimatePro *decimate = vtkDecimatePro::New();
    decimate->SplittingOff();
    decimate->SetErrorIsAbsolute(5);
    decimate->SetFeatureAngle(30);
    decimate->PreserveTopologyOn();
    decimate->BoundaryVertexDeletionOff();
    decimate->SetDegree(10); //std-value is 25!

    decimate->SetInput(polydata);//RC++
    polydata->Delete();//RC--
    decimate->SetTargetReduction(m_TargetReduction);
    decimate->SetMaximumError(0.002);

    polydata = decimate->GetOutput();

  }

  surface->SetVtkPolyData(polydata, time);
}

void mitk::ImageToSurfaceFilter::GenerateData()
{
  mitk::Surface *surface = this->GetOutput();
  mitk::Image * image        =  (mitk::Image*)GetInput();
  mitk::Image::RegionType outputRegion = image->GetRequestedRegion();

  int tstart=outputRegion.GetIndex(3);
  int tmax=tstart+outputRegion.GetSize(3); //GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgelst

  int t;
  for( t=tstart; t < tmax; ++t)
  {
    vtkImageData *vtkimagedata =  image->GetVtkImageData(t);
    CreateSurface(t,vtkimagedata,surface,m_Threshold);
  }
}

void mitk::ImageToSurfaceFilter::SetInput(const mitk::Image *image)
{
  // Process object is not const-correct so the const_cast is required here
  this->ProcessObject::SetNthInput(0, const_cast< mitk::Image * >( image ) );
}

const mitk::Image *mitk::ImageToSurfaceFilter::GetInput(void)
{
  if (this->GetNumberOfInputs() < 1)
  {
    return 0;
  }

  return static_cast<const mitk::Image * >
    ( this->ProcessObject::GetInput(0) );
}

void mitk::ImageToSurfaceFilter::GenerateOutputInformation()
{
  mitk::Image::ConstPointer inputImage  =(mitk::Image*) this->GetInput();

  //mitk::Image *inputImage = (mitk::Image*)this->GetImage();
  mitk::Surface::Pointer output = this->GetOutput();

  itkDebugMacro(<<"GenerateOutputInformation()");

  if(inputImage.IsNull()) return;

  //Set Data
}
<commit_msg>FIX: pipline problem<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkImageToSurfaceFilter.h"
#include <vtkImageData.h>
#include <vtkDecimatePro.h>

mitk::ImageToSurfaceFilter::ImageToSurfaceFilter()
  : m_Smooth(false), m_Decimate(false), m_TargetReduction(0.05f){};
mitk::ImageToSurfaceFilter::~ImageToSurfaceFilter(){};

void mitk::ImageToSurfaceFilter::CreateSurface(int time, vtkImageData *vtkimage, mitk::Surface * surface, const ScalarType threshold)
{
  //Inkrement Referenzcounter Counter (hier: RC)
  vtkimage->Register(NULL);

  vtkPolyData *polydata = vtkPolyData::New();
  polydata->Register(NULL);// RC++

  //MarchingCube -->create Surface
  vtkMarchingCubes *skinExtractor = vtkMarchingCubes::New();
  skinExtractor->SetInput(vtkimage);//RC++
  vtkimage->Delete();//RC--
  skinExtractor->SetValue(0, threshold);
  polydata = skinExtractor->GetOutput();

  if (m_Smooth)
  {
    int spIterations =50;
    float spRelaxation =0.1;

    vtkSmoothPolyDataFilter *smoother = vtkSmoothPolyDataFilter::New();
    //read poly1 (poly1 can be the original polygon, or the decimated polygon)
    smoother->SetInput(polydata);//RC++
    polydata->Delete();//RC--
    smoother->SetNumberOfIterations( spIterations );
    smoother->SetRelaxationFactor( spRelaxation );
    smoother->SetFeatureAngle( 60 );
    smoother->FeatureEdgeSmoothingOff();
    smoother->BoundarySmoothingOff();
    smoother->SetConvergence( 0 );

    polydata = smoother->GetOutput();

  }

  //decimate = to reduce number of polygons
  if(m_Decimate)
  {
    vtkDecimatePro *decimate = vtkDecimatePro::New();
    decimate->SplittingOff();
    decimate->SetErrorIsAbsolute(5);
    decimate->SetFeatureAngle(30);
    decimate->PreserveTopologyOn();
    decimate->BoundaryVertexDeletionOff();
    decimate->SetDegree(10); //std-value is 25!

    decimate->SetInput(polydata);//RC++
    polydata->Delete();//RC--
    decimate->SetTargetReduction(m_TargetReduction);
    decimate->SetMaximumError(0.002);

    polydata = decimate->GetOutput();

  }

  //
  // HACK! Symptombekmpfung wegen stndiger Pipeline ausfhrung beim navigieren durch das Bild
  // Disconnect the result from the vtk pipeline.
  //
  vtkSource* source = polydata->GetSource();
  polydata->Update();
  polydata->SetSource(NULL);

  surface->SetVtkPolyData(polydata, time);
  source->Delete();
}

void mitk::ImageToSurfaceFilter::GenerateData()
{
  mitk::Surface *surface = this->GetOutput();
  mitk::Image * image        =  (mitk::Image*)GetInput();
  mitk::Image::RegionType outputRegion = image->GetRequestedRegion();

  int tstart=outputRegion.GetIndex(3);
  int tmax=tstart+outputRegion.GetSize(3); //GetSize()==1 - will aber 0 haben, wenn nicht zeitaufgelst

  int t;
  for( t=tstart; t < tmax; ++t)
  {
    vtkImageData *vtkimagedata =  image->GetVtkImageData(t);
    CreateSurface(t,vtkimagedata,surface,m_Threshold);
  }
}

void mitk::ImageToSurfaceFilter::SetInput(const mitk::Image *image)
{
  // Process object is not const-correct so the const_cast is required here
  this->ProcessObject::SetNthInput(0, const_cast< mitk::Image * >( image ) );
}

const mitk::Image *mitk::ImageToSurfaceFilter::GetInput(void)
{
  if (this->GetNumberOfInputs() < 1)
  {
    return 0;
  }

  return static_cast<const mitk::Image * >
    ( this->ProcessObject::GetInput(0) );
}

void mitk::ImageToSurfaceFilter::GenerateOutputInformation()
{
  mitk::Image::ConstPointer inputImage  =(mitk::Image*) this->GetInput();

  //mitk::Image *inputImage = (mitk::Image*)this->GetImage();
  mitk::Surface::Pointer output = this->GetOutput();

  itkDebugMacro(<<"GenerateOutputInformation()");

  if(inputImage.IsNull()) return;

  //Set Data
}
<|endoftext|>