<commit_before>/*
 * Copyright (c) 2016 liblcf authors
 * This file is released under the MIT License
 * http://opensource.org/licenses/MIT
 */

#include "reader_options.h"

#ifdef LCF_SUPPORT_ICU
#   include <unicode/ucsdet.h>
#   include <unicode/ucnv.h>
#else
#   ifdef _MSC_VER
#		error MSVC builds require ICU
#	endif
#endif

#ifdef _WIN32
#   define WIN32_LEAN_AND_MEAN
#   ifndef NOMINMAX
#       define NOMINMAX
#   endif
#   include <windows.h>
#else
#   ifndef LCF_SUPPORT_ICU
#       include <iconv.h>
#   endif
#   include <locale>
#endif

#include <cstdlib>
#include <cstdio>
#include <sstream>
#include <vector>

#include "data.h"
#include "inireader.h"
#include "ldb_reader.h"
#include "reader_util.h"

namespace ReaderUtil {
}

std::string ReaderUtil::CodepageToEncoding(int codepage) {
	if (codepage == 0)
		return std::string();

	if (codepage == 932) {
#ifdef LCF_SUPPORT_ICU
		return "ibm-943_P15A-2003";
#else
		return "SHIFT_JIS";
#endif
	}
	if (codepage == 949) {
#ifdef LCF_SUPPORT_ICU
		return "windows-949-2000";
#else
		return "cp949";
#endif
	}
	std::ostringstream out;
#ifdef LCF_SUPPORT_ICU
	out << "windows-" << codepage;
#else
	out << "CP" << codepage;
#endif

	// Looks like a valid codepage
	std::string outs = out.str();
	return outs;
}

std::string ReaderUtil::DetectEncoding(const std::string& database_file) {
	std::string encoding;
#ifdef LCF_SUPPORT_ICU
	std::ostringstream text;

	//Populate Data::terms and Data::system or will empty by default even if load fails
	LDB_Reader::Load(database_file, "");

	text <<
	Data::terms.menu_save << " " <<
	Data::terms.menu_quit << " " <<
	Data::terms.new_game << " " <<
	Data::terms.load_game << " " <<
	Data::terms.exit_game << " " <<
	Data::terms.status << " " <<
	Data::terms.row << " " <<
	Data::terms.order << " " <<
	Data::terms.wait_on << " " <<
	Data::terms.wait_off << " " <<
	Data::terms.level << " " <<
	Data::terms.health_points << " " <<
	Data::terms.spirit_points << " " <<
	Data::terms.normal_status << " " <<
	Data::terms.exp_short << " " <<
	Data::terms.lvl_short << " " <<
	Data::terms.hp_short << " " <<
	Data::terms.sp_short << " " <<
	Data::terms.sp_cost << " " <<
	Data::terms.attack << " " <<
	Data::terms.defense << " " <<
	Data::terms.spirit << " " <<
	Data::terms.agility << " " <<
	Data::terms.weapon << " " <<
	Data::terms.shield << " " <<
	Data::terms.armor << " " <<
	Data::terms.helmet << " " <<
	Data::terms.accessory << " " <<
	Data::terms.save_game_message << " " <<
	Data::terms.load_game_message << " " <<
	Data::terms.file << " " <<
	Data::terms.exit_game_message << " " <<
	Data::terms.yes << " " <<
	Data::terms.no << " " <<
	Data::system.boat_name << " " <<
	Data::system.ship_name << " " <<
	Data::system.airship_name << " " <<
	Data::system.title_name << " " <<
	Data::system.gameover_name << " " <<
	Data::system.system_name << " " <<
	Data::system.system2_name << " " <<
	Data::system.battletest_background << " " <<
	Data::system.frame_name;

	// Checks if there are more than the above 42 spaces (no data)
	if (text.str().size() > 42)
	{
		UErrorCode status = U_ZERO_ERROR;
		UCharsetDetector* detector = ucsdet_open(&status);

		std::string s = text.str();
		ucsdet_setText(detector, s.c_str(), s.length(), &status);

		const UCharsetMatch* match = ucsdet_detect(detector, &status);
		if (match != NULL)
		{
			encoding = ucsdet_getName(match, &status);
		}
		ucsdet_close(detector);

		// Fixes to ensure proper Windows encodings
		if (encoding == "Shift_JIS")
		{
			encoding = "ibm-943_P15A-2003"; // Japanese with \ as backslash
		}
		else if (encoding == "EUC-KR")
		{
			encoding = "windows-949-2000"; // Korean with \ as backlash
		}
		else if (encoding == "ISO-8859-1" || encoding == "windows-1252")
		{
			encoding = "ibm-5348_P100-1997"; // Occidental with Euro
		}
		else if (encoding == "ISO-8859-2" || encoding == "windows-1250")
		{
			encoding = "ibm-5346_P100-1998"; // Central Europe with Euro
		}
		else if (encoding == "ISO-8859-5" || encoding == "windows-1251")
		{
			encoding = "ibm-5347_P100-1998"; // Cyrillic with Euro
		}
		else if (encoding == "ISO-8859-6" || encoding == "windows-1256")
		{
			encoding = "ibm-9448_X100-2005"; // Arabic with Euro + 8 chars
		}
		else if (encoding == "ISO-8859-7" || encoding == "windows-1253")
		{
			encoding = "ibm-5349_P100-1998"; // Greek with Euro
		}
		else if (encoding == "ISO-8859-8" || encoding == "windows-1255")
		{
			encoding = "ibm-9447_P100-2002"; // Hebrew with Euro
		}
	}
#endif

	return encoding;
}

std::string ReaderUtil::GetEncoding(const std::string& ini_file) {
	INIReader ini(ini_file);
	if (ini.ParseError() != -1) {
		std::string encoding = ini.Get("EasyRPG", "Encoding", std::string());
		if (!encoding.empty()) {
			return ReaderUtil::CodepageToEncoding(atoi(encoding.c_str()));
		}
	}
	return std::string();
}

std::string ReaderUtil::GetLocaleEncoding() {
#ifdef _WIN32
	int codepage = GetACP();
#elif __ANDROID__
	// No std::locale support in NDK
	// Doesn't really matter because the Android version auto-detects via ICU
	int codepage = 1252;
#else
	int codepage = 1252;

	std::locale loc = std::locale("");
	// Gets the language and culture part only
	std::string loc_full = loc.name().substr(0, loc.name().find_first_of("@."));
	// Gets the language part only
	std::string loc_lang = loc.name().substr(0, loc.name().find_first_of("_"));

	if      (loc_lang == "th")    codepage = 874;
	else if (loc_lang == "ja")    codepage = 932;
	else if (loc_full == "zh_CN" ||
	         loc_full == "zh_SG") codepage = 936;
	else if (loc_lang == "ko")    codepage = 949;
	else if (loc_full == "zh_TW" ||
	         loc_full == "zh_HK") codepage = 950;
	else if (loc_lang == "cs" ||
	         loc_lang == "hu" ||
	         loc_lang == "pl" ||
	         loc_lang == "ro" ||
	         loc_lang == "hr" ||
	         loc_lang == "sk" ||
	         loc_lang == "sl")    codepage = 1250;
	else if (loc_lang == "ru")    codepage = 1251;
	else if (loc_lang == "ca" ||
	         loc_lang == "da" ||
	         loc_lang == "de" ||
	         loc_lang == "en" ||
	         loc_lang == "es" ||
	         loc_lang == "fi" ||
	         loc_lang == "fr" ||
	         loc_lang == "it" ||
	         loc_lang == "nl" ||
	         loc_lang == "nb" ||
	         loc_lang == "pt" ||
	         loc_lang == "sv" ||
	         loc_lang == "eu")    codepage = 1252;
	else if (loc_lang == "el")    codepage = 1253;
	else if (loc_lang == "tr")    codepage = 1254;
	else if (loc_lang == "he")    codepage = 1255;
	else if (loc_lang == "ar")    codepage = 1256;
	else if (loc_lang == "et" ||
	         loc_lang == "lt" ||
	         loc_lang == "lv")    codepage = 1257;
	else if (loc_lang == "vi")    codepage = 1258;
#endif

	return CodepageToEncoding(codepage);
}

std::string ReaderUtil::Recode(const std::string& str_to_encode, const std::string& source_encoding) {
	return ReaderUtil::Recode(str_to_encode, source_encoding, "UTF-8");
}

std::string ReaderUtil::Recode(const std::string& str_to_encode,
                               const std::string& src_enc,
                               const std::string& dst_enc) {
	std::string src_enc_str = src_enc;
	std::string dst_enc_str = dst_enc;

	if (src_enc.empty() || dst_enc.empty() || str_to_encode.empty()) {
		return str_to_encode;
	}
	if (atoi(src_enc.c_str()) > 0) {
		src_enc_str = ReaderUtil::CodepageToEncoding(atoi(src_enc.c_str()));
	}
	if (atoi(dst_enc.c_str()) > 0) {
		dst_enc_str = ReaderUtil::CodepageToEncoding(atoi(dst_enc.c_str()));
	}
#ifdef LCF_SUPPORT_ICU
	UErrorCode status = U_ZERO_ERROR;
	int size = str_to_encode.size() * 4;
	UChar* unicode_str = new UChar[size];
	UConverter *conv;
	int length;
	std::string result_str;

	conv = ucnv_open(src_enc_str.c_str(), &status);

	if (status != U_ZERO_ERROR && status != U_AMBIGUOUS_ALIAS_WARNING) {
		fprintf(stderr, "liblcf:  ucnv_open() error for source encoding \"%s\": %s\n", src_enc_str.c_str(), u_errorName(status));
		return std::string();
	}
	status = U_ZERO_ERROR;

	length = ucnv_toUChars(conv, unicode_str, size, str_to_encode.c_str(), -1, &status);
	ucnv_close(conv);
	if (status != U_ZERO_ERROR) {
		fprintf(stderr, "liblcf: ucnv_toUChars() error when encoding \"%s\": %s\n", str_to_encode.c_str(), u_errorName(status));
		delete[] unicode_str;
		return std::string();
	}

	char* result = new char[length * 4];

	conv = ucnv_open(dst_enc_str.c_str(), &status);
	if (status != U_ZERO_ERROR && status != U_AMBIGUOUS_ALIAS_WARNING) {
		fprintf(stderr, "liblcf: ucnv_open() error for destination encoding \"%s\": %s\n", dst_enc_str.c_str(), u_errorName(status));
		delete[] unicode_str;
		delete[] result;
		return std::string();
	}
	status = U_ZERO_ERROR;

	ucnv_fromUChars(conv, result, length * 4, unicode_str, -1, &status);
	ucnv_close(conv);
	if (status != U_ZERO_ERROR) {
		fprintf(stderr, "liblcf: ucnv_fromUChars() error: %s\n", u_errorName(status));
		delete[] unicode_str;
		delete[] result;
		return std::string();
	}

	result_str = result;

	delete[] unicode_str;
	delete[] result;

	return std::string(result_str);
#else
	iconv_t cd = iconv_open(dst_enc_str.c_str(), src_enc_str.c_str());
	if (cd == (iconv_t)-1)
		return str_to_encode;
	char *src = const_cast<char *>(str_to_encode.c_str());
	size_t src_left = str_to_encode.size();
	size_t dst_size = str_to_encode.size() * 5 + 10;
	char *dst = new char[dst_size];
	size_t dst_left = dst_size;
#    ifdef ICONV_CONST
	char ICONV_CONST *p = src;
#    else
	char *p = src;
#    endif
	char *q = dst;
	size_t status = iconv(cd, &p, &src_left, &q, &dst_left);
	iconv_close(cd);
	if (status == (size_t) -1 || src_left > 0) {
		delete[] dst;
		return std::string();
	}
	*q++ = '\0';
	std::string result(dst);
	delete[] dst;
	return result;
#endif
}
<commit_msg>Remove unnecesary spaces in the text for the encoding detector<commit_after>/*
 * Copyright (c) 2016 liblcf authors
 * This file is released under the MIT License
 * http://opensource.org/licenses/MIT
 */

#include "reader_options.h"

#ifdef LCF_SUPPORT_ICU
#   include <unicode/ucsdet.h>
#   include <unicode/ucnv.h>
#else
#   ifdef _MSC_VER
#		error MSVC builds require ICU
#	endif
#endif

#ifdef _WIN32
#   define WIN32_LEAN_AND_MEAN
#   ifndef NOMINMAX
#       define NOMINMAX
#   endif
#   include <windows.h>
#else
#   ifndef LCF_SUPPORT_ICU
#       include <iconv.h>
#   endif
#   include <locale>
#endif

#include <cstdlib>
#include <cstdio>
#include <sstream>
#include <vector>

#include "data.h"
#include "inireader.h"
#include "ldb_reader.h"
#include "reader_util.h"

namespace ReaderUtil {
}

std::string ReaderUtil::CodepageToEncoding(int codepage) {
	if (codepage == 0)
		return std::string();

	if (codepage == 932) {
#ifdef LCF_SUPPORT_ICU
		return "ibm-943_P15A-2003";
#else
		return "SHIFT_JIS";
#endif
	}
	if (codepage == 949) {
#ifdef LCF_SUPPORT_ICU
		return "windows-949-2000";
#else
		return "cp949";
#endif
	}
	std::ostringstream out;
#ifdef LCF_SUPPORT_ICU
	out << "windows-" << codepage;
#else
	out << "CP" << codepage;
#endif

	// Looks like a valid codepage
	std::string outs = out.str();
	return outs;
}

std::string ReaderUtil::DetectEncoding(const std::string& database_file) {
	std::string encoding;
#ifdef LCF_SUPPORT_ICU
	std::ostringstream text;

	//Populate Data::terms and Data::system or will empty by default even if load fails
	LDB_Reader::Load(database_file, "");

	text <<
	Data::terms.menu_save <<
	Data::terms.menu_quit <<
	Data::terms.new_game <<
	Data::terms.load_game <<
	Data::terms.exit_game <<
	Data::terms.status <<
	Data::terms.row <<
	Data::terms.order <<
	Data::terms.wait_on <<
	Data::terms.wait_off <<
	Data::terms.level <<
	Data::terms.health_points <<
	Data::terms.spirit_points <<
	Data::terms.normal_status <<
	Data::terms.exp_short <<
	Data::terms.lvl_short <<
	Data::terms.hp_short <<
	Data::terms.sp_short <<
	Data::terms.sp_cost <<
	Data::terms.attack <<
	Data::terms.defense <<
	Data::terms.spirit <<
	Data::terms.agility <<
	Data::terms.weapon <<
	Data::terms.shield <<
	Data::terms.armor <<
	Data::terms.helmet <<
	Data::terms.accessory <<
	Data::terms.save_game_message <<
	Data::terms.load_game_message <<
	Data::terms.file <<
	Data::terms.exit_game_message <<
	Data::terms.yes <<
	Data::terms.no <<
	Data::system.boat_name <<
	Data::system.ship_name <<
	Data::system.airship_name <<
	Data::system.title_name <<
	Data::system.gameover_name <<
	Data::system.system_name <<
	Data::system.system2_name <<
	Data::system.battletest_background <<
	Data::system.frame_name;

	if (!text.str().empty())
	{
		UErrorCode status = U_ZERO_ERROR;
		UCharsetDetector* detector = ucsdet_open(&status);

		std::string s = text.str();
		ucsdet_setText(detector, s.c_str(), s.length(), &status);

		const UCharsetMatch* match = ucsdet_detect(detector, &status);
		if (match != NULL)
		{
			encoding = ucsdet_getName(match, &status);
		}
		ucsdet_close(detector);

		// Fixes to ensure proper Windows encodings
		if (encoding == "Shift_JIS")
		{
			encoding = "ibm-943_P15A-2003"; // Japanese with \ as backslash
		}
		else if (encoding == "EUC-KR")
		{
			encoding = "windows-949-2000"; // Korean with \ as backlash
		}
		else if (encoding == "ISO-8859-1" || encoding == "windows-1252")
		{
			encoding = "ibm-5348_P100-1997"; // Occidental with Euro
		}
		else if (encoding == "ISO-8859-2" || encoding == "windows-1250")
		{
			encoding = "ibm-5346_P100-1998"; // Central Europe with Euro
		}
		else if (encoding == "ISO-8859-5" || encoding == "windows-1251")
		{
			encoding = "ibm-5347_P100-1998"; // Cyrillic with Euro
		}
		else if (encoding == "ISO-8859-6" || encoding == "windows-1256")
		{
			encoding = "ibm-9448_X100-2005"; // Arabic with Euro + 8 chars
		}
		else if (encoding == "ISO-8859-7" || encoding == "windows-1253")
		{
			encoding = "ibm-5349_P100-1998"; // Greek with Euro
		}
		else if (encoding == "ISO-8859-8" || encoding == "windows-1255")
		{
			encoding = "ibm-9447_P100-2002"; // Hebrew with Euro
		}
	}
#endif

	return encoding;
}

std::string ReaderUtil::GetEncoding(const std::string& ini_file) {
	INIReader ini(ini_file);
	if (ini.ParseError() != -1) {
		std::string encoding = ini.Get("EasyRPG", "Encoding", std::string());
		if (!encoding.empty()) {
			return ReaderUtil::CodepageToEncoding(atoi(encoding.c_str()));
		}
	}
	return std::string();
}

std::string ReaderUtil::GetLocaleEncoding() {
#ifdef _WIN32
	int codepage = GetACP();
#elif __ANDROID__
	// No std::locale support in NDK
	// Doesn't really matter because the Android version auto-detects via ICU
	int codepage = 1252;
#else
	int codepage = 1252;

	std::locale loc = std::locale("");
	// Gets the language and culture part only
	std::string loc_full = loc.name().substr(0, loc.name().find_first_of("@."));
	// Gets the language part only
	std::string loc_lang = loc.name().substr(0, loc.name().find_first_of("_"));

	if      (loc_lang == "th")    codepage = 874;
	else if (loc_lang == "ja")    codepage = 932;
	else if (loc_full == "zh_CN" ||
	         loc_full == "zh_SG") codepage = 936;
	else if (loc_lang == "ko")    codepage = 949;
	else if (loc_full == "zh_TW" ||
	         loc_full == "zh_HK") codepage = 950;
	else if (loc_lang == "cs" ||
	         loc_lang == "hu" ||
	         loc_lang == "pl" ||
	         loc_lang == "ro" ||
	         loc_lang == "hr" ||
	         loc_lang == "sk" ||
	         loc_lang == "sl")    codepage = 1250;
	else if (loc_lang == "ru")    codepage = 1251;
	else if (loc_lang == "ca" ||
	         loc_lang == "da" ||
	         loc_lang == "de" ||
	         loc_lang == "en" ||
	         loc_lang == "es" ||
	         loc_lang == "fi" ||
	         loc_lang == "fr" ||
	         loc_lang == "it" ||
	         loc_lang == "nl" ||
	         loc_lang == "nb" ||
	         loc_lang == "pt" ||
	         loc_lang == "sv" ||
	         loc_lang == "eu")    codepage = 1252;
	else if (loc_lang == "el")    codepage = 1253;
	else if (loc_lang == "tr")    codepage = 1254;
	else if (loc_lang == "he")    codepage = 1255;
	else if (loc_lang == "ar")    codepage = 1256;
	else if (loc_lang == "et" ||
	         loc_lang == "lt" ||
	         loc_lang == "lv")    codepage = 1257;
	else if (loc_lang == "vi")    codepage = 1258;
#endif

	return CodepageToEncoding(codepage);
}

std::string ReaderUtil::Recode(const std::string& str_to_encode, const std::string& source_encoding) {
	return ReaderUtil::Recode(str_to_encode, source_encoding, "UTF-8");
}

std::string ReaderUtil::Recode(const std::string& str_to_encode,
                               const std::string& src_enc,
                               const std::string& dst_enc) {
	std::string src_enc_str = src_enc;
	std::string dst_enc_str = dst_enc;

	if (src_enc.empty() || dst_enc.empty() || str_to_encode.empty()) {
		return str_to_encode;
	}
	if (atoi(src_enc.c_str()) > 0) {
		src_enc_str = ReaderUtil::CodepageToEncoding(atoi(src_enc.c_str()));
	}
	if (atoi(dst_enc.c_str()) > 0) {
		dst_enc_str = ReaderUtil::CodepageToEncoding(atoi(dst_enc.c_str()));
	}
#ifdef LCF_SUPPORT_ICU
	UErrorCode status = U_ZERO_ERROR;
	int size = str_to_encode.size() * 4;
	UChar* unicode_str = new UChar[size];
	UConverter *conv;
	int length;
	std::string result_str;

	conv = ucnv_open(src_enc_str.c_str(), &status);

	if (status != U_ZERO_ERROR && status != U_AMBIGUOUS_ALIAS_WARNING) {
		fprintf(stderr, "liblcf:  ucnv_open() error for source encoding \"%s\": %s\n", src_enc_str.c_str(), u_errorName(status));
		return std::string();
	}
	status = U_ZERO_ERROR;

	length = ucnv_toUChars(conv, unicode_str, size, str_to_encode.c_str(), -1, &status);
	ucnv_close(conv);
	if (status != U_ZERO_ERROR) {
		fprintf(stderr, "liblcf: ucnv_toUChars() error when encoding \"%s\": %s\n", str_to_encode.c_str(), u_errorName(status));
		delete[] unicode_str;
		return std::string();
	}

	char* result = new char[length * 4];

	conv = ucnv_open(dst_enc_str.c_str(), &status);
	if (status != U_ZERO_ERROR && status != U_AMBIGUOUS_ALIAS_WARNING) {
		fprintf(stderr, "liblcf: ucnv_open() error for destination encoding \"%s\": %s\n", dst_enc_str.c_str(), u_errorName(status));
		delete[] unicode_str;
		delete[] result;
		return std::string();
	}
	status = U_ZERO_ERROR;

	ucnv_fromUChars(conv, result, length * 4, unicode_str, -1, &status);
	ucnv_close(conv);
	if (status != U_ZERO_ERROR) {
		fprintf(stderr, "liblcf: ucnv_fromUChars() error: %s\n", u_errorName(status));
		delete[] unicode_str;
		delete[] result;
		return std::string();
	}

	result_str = result;

	delete[] unicode_str;
	delete[] result;

	return std::string(result_str);
#else
	iconv_t cd = iconv_open(dst_enc_str.c_str(), src_enc_str.c_str());
	if (cd == (iconv_t)-1)
		return str_to_encode;
	char *src = const_cast<char *>(str_to_encode.c_str());
	size_t src_left = str_to_encode.size();
	size_t dst_size = str_to_encode.size() * 5 + 10;
	char *dst = new char[dst_size];
	size_t dst_left = dst_size;
#    ifdef ICONV_CONST
	char ICONV_CONST *p = src;
#    else
	char *p = src;
#    endif
	char *q = dst;
	size_t status = iconv(cd, &p, &src_left, &q, &dst_left);
	iconv_close(cd);
	if (status == (size_t) -1 || src_left > 0) {
		delete[] dst;
		return std::string();
	}
	*q++ = '\0';
	std::string result(dst);
	delete[] dst;
	return result;
#endif
}
<|endoftext|>


<commit_before>#include "reidmanager.h"

#include <iostream>
#include <fstream>
#include <list>

using namespace std;

static const float thresholdValueSamePerson = 0.5;

ReidManager::ReidManager()
{
    Features::getInstance();
}

void ReidManager::computeNext()
{
    // Get the next received sequence
    string nextSeqString = getNextSeqString();
    if(nextSeqString.empty())
    {
        return;
    }

    cout << "Compute: " << nextSeqString << endl;

    size_t sizeArray = 0;
    float *arrayReceived = reconstructArray(nextSeqString, sizeArray);

    // Extractions on the features

    vector<FeaturesElement> listCurrentSequenceFeatures;
    Features::getInstance().extractArray(arrayReceived, sizeArray, listCurrentSequenceFeatures);

    delete arrayReceived;

    // Match with the dataset

    bool newPers = true; // Not recognize yet

    for(PersonElement currentPers : database)
    {
        float meanPrediction = 0.0;
        for(FeaturesElement featuresDatabase : currentPers.features)
        {
            for(FeaturesElement featuresSequence : listCurrentSequenceFeatures)
            {
                meanPrediction += Features::getInstance().computeDistance(featuresDatabase, featuresSequence);
            }
        }
        meanPrediction /= (currentPers.features.size() * listCurrentSequenceFeatures.size());

        // Match. Update database ?
        if(meanPrediction > thresholdValueSamePerson)
        {
            cout << "Match (" << meanPrediction << ") : " << currentPers.name << endl;
            newPers = false;
        }
    }

    // No match
    if(newPers)
    {
        cout << "No match: Add the new person to the dataset" << endl;

        // Add the new person to the database
        database.push_back(PersonElement());
        database.back().features.swap(listCurrentSequenceFeatures);
        database.back().name = std::to_string(database.size());
    }
}

string ReidManager::getNextSeqString() const
{
    string nextSeqString;

    // Read all lines
    ifstream receivedFileIn("../../Data/Received/received.txt", ios::in);
    if(!receivedFileIn.is_open())
    {
        cout << "Unable to open the file (please, check your working directory)" << endl;
    }
    else
    {
        string line;
        list<std::string> filelines;
        while (receivedFileIn)
        {
             getline(receivedFileIn, line);
             if(!line.empty())
             {
                 filelines.push_back(line);
             }
        }
        receivedFileIn.close();

        // Extract the current element

        if(!filelines.empty())
        {
            nextSeqString = filelines.front();
            filelines.pop_front();
        }

        // Save the file
        ofstream receivedFileOut("../../Data/Received/received.txt", ios::out | ios::trunc);
        if(!receivedFileOut.is_open())
        {
            cout << "Unable to open the file (please, check your working directory)" << endl;
        }

        for(string currentLine : filelines)
        {
            receivedFileOut << currentLine << endl;
        }

        receivedFileOut.close();
    }

    return nextSeqString;
}

float *ReidManager::reconstructArray(const string &seqId, size_t &sizeOut) const
{
    // Extraction of the received array
    ifstream seqFile("../../Data/Received/seq" + seqId + ".txt", ios_base::in);
    if(!seqFile.is_open())
    {
        cout << "Unable to open the sequence file (please, check your working directory)" << endl;
        return nullptr;
    }

    size_t arrayReceivedSize = 0;
    float *arrayReceived = nullptr;

    seqFile >> arrayReceivedSize;

    arrayReceived = new float[arrayReceivedSize];

    for(size_t i = 0 ; i < arrayReceivedSize ; ++i)
    {
        seqFile >> arrayReceived[i];
    }

    sizeOut = arrayReceivedSize;
    return arrayReceived;
}
<commit_msg>Get the id (hash code) associated with the person of the received sequence<commit_after>#include "reidmanager.h"

#include <iostream>
#include <fstream>
#include <list>

using namespace std;

static const float thresholdValueSamePerson = 0.5;

ReidManager::ReidManager()
{
    Features::getInstance();
}

void ReidManager::computeNext()
{
    // Get the next received sequence
    string nextSeqString = getNextSeqString();
    if(nextSeqString.empty())
    {
        return;
    }

    cout << "Compute: " << nextSeqString << endl;

    size_t sizeArray = 0;
    float *arrayReceived = reconstructArray(nextSeqString, sizeArray);

    // Extractions on the features

    float hashSeqId = arrayReceived[0]; // Get the id of the sequence

    vector<FeaturesElement> listCurrentSequenceFeatures;
    size_t offset = 1;
    Features::getInstance().extractArray(&arrayReceived[offset], sizeArray-offset, listCurrentSequenceFeatures);

    delete arrayReceived;

    // Match with the dataset

    bool newPers = true; // Not recognize yet

    for(PersonElement currentPers : database)
    {
        float meanPrediction = 0.0;
        for(FeaturesElement featuresDatabase : currentPers.features)
        {
            for(FeaturesElement featuresSequence : listCurrentSequenceFeatures)
            {
                meanPrediction += Features::getInstance().computeDistance(featuresDatabase, featuresSequence);
            }
        }
        meanPrediction /= (currentPers.features.size() * listCurrentSequenceFeatures.size());

        // Match. Update database ?
        if(meanPrediction > thresholdValueSamePerson)
        {
            cout << "Match (" << meanPrediction << ") : " << currentPers.name << endl;
            newPers = false;
        }
    }

    // No match
    if(newPers)
    {
        cout << "No match: Add the new person to the dataset" << endl;

        // Add the new person to the database
        database.push_back(PersonElement());
        database.back().features.swap(listCurrentSequenceFeatures);
        database.back().name = std::to_string(database.size());
    }
}

string ReidManager::getNextSeqString() const
{
    string nextSeqString;

    // Read all lines
    ifstream receivedFileIn("../../Data/Received/received.txt", ios::in);
    if(!receivedFileIn.is_open())
    {
        cout << "Unable to open the file (please, check your working directory)" << endl;
    }
    else
    {
        string line;
        list<std::string> filelines;
        while (receivedFileIn)
        {
             getline(receivedFileIn, line);
             if(!line.empty())
             {
                 filelines.push_back(line);
             }
        }
        receivedFileIn.close();

        // Extract the current element

        if(!filelines.empty())
        {
            nextSeqString = filelines.front();
            filelines.pop_front();
        }

        // Save the file
        ofstream receivedFileOut("../../Data/Received/received.txt", ios::out | ios::trunc);
        if(!receivedFileOut.is_open())
        {
            cout << "Unable to open the file (please, check your working directory)" << endl;
        }

        for(string currentLine : filelines)
        {
            receivedFileOut << currentLine << endl;
        }

        receivedFileOut.close();
    }

    return nextSeqString;
}

float *ReidManager::reconstructArray(const string &seqId, size_t &sizeOut) const
{
    // Extraction of the received array
    ifstream seqFile("../../Data/Received/seq" + seqId + ".txt", ios_base::in);
    if(!seqFile.is_open())
    {
        cout << "Unable to open the sequence file (please, check your working directory)" << endl;
        return nullptr;
    }

    size_t arrayReceivedSize = 0;
    float *arrayReceived = nullptr;

    seqFile >> arrayReceivedSize;

    arrayReceived = new float[arrayReceivedSize];

    for(size_t i = 0 ; i < arrayReceivedSize ; ++i)
    {
        seqFile >> arrayReceived[i];
    }

    sizeOut = arrayReceivedSize;
    return arrayReceived;
}
<|endoftext|>


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

#include "SkAdvancedTypefaceMetrics.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkDescriptor.h"
#include "SkFontDescriptor.h"
#include "SkGlyph.h"
#include "SkMask.h"
// #include "SkOTUtils.h"
#include "SkScalerContext.h"
#include "SkTestScalerContext.h"
#include "SkTypefaceCache.h"

SkTestFont::SkTestFont(const SkTestFontData& fontData)
    : INHERITED()
    , fCharCodes(fontData.fCharCodes)
    , fCharCodesCount(fontData.fCharCodesCount)
    , fWidths(fontData.fWidths)
    , fMetrics(fontData.fMetrics)
    , fName(fontData.fName)
    , fPaths(NULL)
{
    init(fontData.fPoints, fontData.fVerbs);
#ifdef SK_DEBUG
    sk_bzero(fDebugBits, sizeof(fDebugBits));
    sk_bzero(fDebugOverage, sizeof(fDebugOverage));
#endif
}

SkTestFont::~SkTestFont() {
    for (unsigned index = 0; index < fCharCodesCount; ++index) {
        SkDELETE(fPaths[index]);
    }
    SkDELETE_ARRAY(fPaths);
}

#ifdef SK_DEBUG

#include "SkThread.h"
SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);

#endif

int SkTestFont::codeToIndex(SkUnichar charCode) const {
#ifdef SK_DEBUG  // detect missing test font data
    {
        SkAutoMutexAcquire ac(gUsedCharsMutex);
        if (charCode >= ' ' && charCode <= '~') {
            int bitOffset = charCode - ' ';
            fDebugBits[bitOffset >> 3] |= 1 << (bitOffset & 7);
        } else {
            int index = 0;
            while (fDebugOverage[index] != 0 && fDebugOverage[index] != charCode
                    && index < (int) sizeof(fDebugOverage)) {
                ++index;
            }
            SkASSERT(index < (int) sizeof(fDebugOverage));
            if (fDebugOverage[index] == 0) {
                fDebugOverage[index] = charCode;
            }
        }
    }
#endif
    for (unsigned index = 0; index < fCharCodesCount; ++index) {
        if (fCharCodes[index] == (unsigned) charCode) {
            return (int) index;
        }
    }
    SkDEBUGF(("missing '%c' (%d) from %s %d\n", (char) charCode, charCode,
            fDebugName, fDebugStyle));
    return 0;
}

void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
    fPaths = SkNEW_ARRAY(SkPath*, fCharCodesCount);
    for (unsigned index = 0; index < fCharCodesCount; ++index) {
        SkPath* path = SkNEW(SkPath);
        SkPath::Verb verb;
        while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
            switch (verb) {
                case SkPath::kMove_Verb:
                    path->moveTo(pts[0], pts[1]);
                    pts += 2;
                    break;
                case SkPath::kLine_Verb:
                    path->lineTo(pts[0], pts[1]);
                    pts += 2;
                    break;
                case SkPath::kQuad_Verb:
                    path->quadTo(pts[0], pts[1], pts[2], pts[3]);
                    pts += 4;
                    break;
                case SkPath::kCubic_Verb:
                    path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
                    pts += 6;
                    break;
                case SkPath::kClose_Verb:
                    path->close();
                    break;
                default:
                    SkDEBUGFAIL("bad verb");
                    return;
            }
        }
        fPaths[index] = path;
    }
}

SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style)
    : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
    , fTestFont(testFont) {
}

void SkTestTypeface::getAdvance(SkGlyph* glyph) {
    glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()];
    glyph->fAdvanceY = 0;
}

void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
    *metrics = fTestFont->fMetrics;
}

void SkTestTypeface::getMetrics(SkGlyph* glyph) {
    glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()];
    glyph->fAdvanceY = 0;
}

void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
    *path = *fTestFont->fPaths[glyph.getGlyphID()];
}

void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
    rec->setHinting(SkPaint::kNo_Hinting);
}

SkAdvancedTypefaceMetrics* SkTestTypeface::onGetAdvancedTypefaceMetrics(
                                PerGlyphInfo ,
                                const uint32_t* glyphIDs,
                                uint32_t glyphIDsCount) const {
// pdf only
    SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
    info->fFontName.set(fTestFont->fName);
    info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
    info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag;
    info->fLastGlyphID = static_cast<uint16_t>(fTestFont->fCharCodesCount - 1);
    info->fEmSize = 0;
    info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
    info->fStyle = 0;
    info->fItalicAngle = 0;
    info->fAscent = 0;
    info->fDescent = 0;
    info->fStemV = 0;
    info->fCapHeight = 0;
    info->fBBox = SkIRect::MakeEmpty();
    return info;
}

void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
    desc->setFamilyName(fTestFont->fName);
    *isLocal = false;
}

int SkTestTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
                            uint16_t glyphs[], int glyphCount) const {
    SkASSERT(encoding == kUTF16_Encoding);
    for (int index = 0; index < glyphCount; ++index) {
        SkUnichar ch = ((SkUnichar*) chars)[index];
        glyphs[index] = fTestFont->codeToIndex(ch);
    }
    return glyphCount;
}

void SkTestTypeface::onGetFamilyName(SkString* familyName) const {
    *familyName = fTestFont->fName;
}

SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const {
    SkString familyName(fTestFont->fName);
    SkString language("und"); //undetermined
SkASSERT(0);  // incomplete
    return NULL;
//     return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
}

class SkTestScalerContext : public SkScalerContext {
public:
    SkTestScalerContext(SkTestTypeface* face, const SkDescriptor* desc)
        : SkScalerContext(face, desc)
        , fFace(face)
    {
        fRec.getSingleMatrix(&fMatrix);
        this->forceGenerateImageFromPath();
    }

    virtual ~SkTestScalerContext() {
    }

protected:
    unsigned generateGlyphCount() override {
        return fFace->onCountGlyphs();
    }

    uint16_t generateCharToGlyph(SkUnichar uni) override {
        uint16_t glyph;
        (void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
        return glyph;
    }

    void generateAdvance(SkGlyph* glyph) override {
        fFace->getAdvance(glyph);

        const SkVector advance = fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
                                               SkFixedToScalar(glyph->fAdvanceY));
        glyph->fAdvanceX = SkScalarToFixed(advance.fX);
        glyph->fAdvanceY = SkScalarToFixed(advance.fY);
    }

    void generateMetrics(SkGlyph* glyph) override {
        fFace->getMetrics(glyph);

        const SkVector advance = fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
                                               SkFixedToScalar(glyph->fAdvanceY));
        glyph->fAdvanceX = SkScalarToFixed(advance.fX);
        glyph->fAdvanceY = SkScalarToFixed(advance.fY);

        SkPath path;
        fFace->getPath(*glyph, &path);
        path.transform(fMatrix);

        SkRect storage;
        const SkPaint paint;
        const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
                                                            &storage,
                                                            SkPaint::kFill_Style);
        SkIRect ibounds;
        newBounds.roundOut(&ibounds);
        glyph->fLeft = ibounds.fLeft;
        glyph->fTop = ibounds.fTop;
        glyph->fWidth = ibounds.width();
        glyph->fHeight = ibounds.height();
    }

    void generateImage(const SkGlyph& glyph) override {
        SkPath path;
        fFace->getPath(glyph, &path);

        SkBitmap bm;
        bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
                            glyph.fImage, glyph.rowBytes());
        bm.eraseColor(0);

        SkCanvas canvas(bm);
        canvas.translate(-SkIntToScalar(glyph.fLeft),
                            -SkIntToScalar(glyph.fTop));
        canvas.concat(fMatrix);
        SkPaint paint;
        paint.setAntiAlias(true);
        canvas.drawPath(path, paint);
    }

    void generatePath(const SkGlyph& glyph, SkPath* path) override {
        fFace->getPath(glyph, path);
        path->transform(fMatrix);
    }

    void generateFontMetrics(SkPaint::FontMetrics* metrics) override {
        fFace->getFontMetrics(metrics);
        if (metrics) {
            SkScalar scale = fMatrix.getScaleY();
            metrics->fTop = SkScalarMul(metrics->fTop, scale);
            metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
            metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
            metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
            metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
            metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
            metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
            metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
            metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
        }
    }

private:
    SkTestTypeface*  fFace;
    SkMatrix         fMatrix;
};

SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
    return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), desc));
}
<commit_msg>remove duplicate assign of fLastGlyphID<commit_after>/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkAdvancedTypefaceMetrics.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkDescriptor.h"
#include "SkFontDescriptor.h"
#include "SkGlyph.h"
#include "SkMask.h"
// #include "SkOTUtils.h"
#include "SkScalerContext.h"
#include "SkTestScalerContext.h"
#include "SkTypefaceCache.h"

SkTestFont::SkTestFont(const SkTestFontData& fontData)
    : INHERITED()
    , fCharCodes(fontData.fCharCodes)
    , fCharCodesCount(fontData.fCharCodesCount)
    , fWidths(fontData.fWidths)
    , fMetrics(fontData.fMetrics)
    , fName(fontData.fName)
    , fPaths(NULL)
{
    init(fontData.fPoints, fontData.fVerbs);
#ifdef SK_DEBUG
    sk_bzero(fDebugBits, sizeof(fDebugBits));
    sk_bzero(fDebugOverage, sizeof(fDebugOverage));
#endif
}

SkTestFont::~SkTestFont() {
    for (unsigned index = 0; index < fCharCodesCount; ++index) {
        SkDELETE(fPaths[index]);
    }
    SkDELETE_ARRAY(fPaths);
}

#ifdef SK_DEBUG

#include "SkThread.h"
SK_DECLARE_STATIC_MUTEX(gUsedCharsMutex);

#endif

int SkTestFont::codeToIndex(SkUnichar charCode) const {
#ifdef SK_DEBUG  // detect missing test font data
    {
        SkAutoMutexAcquire ac(gUsedCharsMutex);
        if (charCode >= ' ' && charCode <= '~') {
            int bitOffset = charCode - ' ';
            fDebugBits[bitOffset >> 3] |= 1 << (bitOffset & 7);
        } else {
            int index = 0;
            while (fDebugOverage[index] != 0 && fDebugOverage[index] != charCode
                    && index < (int) sizeof(fDebugOverage)) {
                ++index;
            }
            SkASSERT(index < (int) sizeof(fDebugOverage));
            if (fDebugOverage[index] == 0) {
                fDebugOverage[index] = charCode;
            }
        }
    }
#endif
    for (unsigned index = 0; index < fCharCodesCount; ++index) {
        if (fCharCodes[index] == (unsigned) charCode) {
            return (int) index;
        }
    }
    SkDEBUGF(("missing '%c' (%d) from %s %d\n", (char) charCode, charCode,
            fDebugName, fDebugStyle));
    return 0;
}

void SkTestFont::init(const SkScalar* pts, const unsigned char* verbs) {
    fPaths = SkNEW_ARRAY(SkPath*, fCharCodesCount);
    for (unsigned index = 0; index < fCharCodesCount; ++index) {
        SkPath* path = SkNEW(SkPath);
        SkPath::Verb verb;
        while ((verb = (SkPath::Verb) *verbs++) != SkPath::kDone_Verb) {
            switch (verb) {
                case SkPath::kMove_Verb:
                    path->moveTo(pts[0], pts[1]);
                    pts += 2;
                    break;
                case SkPath::kLine_Verb:
                    path->lineTo(pts[0], pts[1]);
                    pts += 2;
                    break;
                case SkPath::kQuad_Verb:
                    path->quadTo(pts[0], pts[1], pts[2], pts[3]);
                    pts += 4;
                    break;
                case SkPath::kCubic_Verb:
                    path->cubicTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
                    pts += 6;
                    break;
                case SkPath::kClose_Verb:
                    path->close();
                    break;
                default:
                    SkDEBUGFAIL("bad verb");
                    return;
            }
        }
        fPaths[index] = path;
    }
}

SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style)
    : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
    , fTestFont(testFont) {
}

void SkTestTypeface::getAdvance(SkGlyph* glyph) {
    glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()];
    glyph->fAdvanceY = 0;
}

void SkTestTypeface::getFontMetrics(SkPaint::FontMetrics* metrics) {
    *metrics = fTestFont->fMetrics;
}

void SkTestTypeface::getMetrics(SkGlyph* glyph) {
    glyph->fAdvanceX = fTestFont->fWidths[glyph->getGlyphID()];
    glyph->fAdvanceY = 0;
}

void SkTestTypeface::getPath(const SkGlyph& glyph, SkPath* path) {
    *path = *fTestFont->fPaths[glyph.getGlyphID()];
}

void SkTestTypeface::onFilterRec(SkScalerContextRec* rec) const {
    rec->setHinting(SkPaint::kNo_Hinting);
}

SkAdvancedTypefaceMetrics* SkTestTypeface::onGetAdvancedTypefaceMetrics(
                                PerGlyphInfo ,
                                const uint32_t* glyphIDs,
                                uint32_t glyphIDsCount) const {
// pdf only
    SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
    info->fFontName.set(fTestFont->fName);
    info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
    info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag;
    info->fLastGlyphID = SkToU16(onCountGlyphs() - 1);
    info->fEmSize = 0;
    info->fStyle = 0;
    info->fItalicAngle = 0;
    info->fAscent = 0;
    info->fDescent = 0;
    info->fStemV = 0;
    info->fCapHeight = 0;
    info->fBBox = SkIRect::MakeEmpty();
    return info;
}

void SkTestTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
    desc->setFamilyName(fTestFont->fName);
    *isLocal = false;
}

int SkTestTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
                            uint16_t glyphs[], int glyphCount) const {
    SkASSERT(encoding == kUTF16_Encoding);
    for (int index = 0; index < glyphCount; ++index) {
        SkUnichar ch = ((SkUnichar*) chars)[index];
        glyphs[index] = fTestFont->codeToIndex(ch);
    }
    return glyphCount;
}

void SkTestTypeface::onGetFamilyName(SkString* familyName) const {
    *familyName = fTestFont->fName;
}

SkTypeface::LocalizedStrings* SkTestTypeface::onCreateFamilyNameIterator() const {
    SkString familyName(fTestFont->fName);
    SkString language("und"); //undetermined
SkASSERT(0);  // incomplete
    return NULL;
//     return new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
}

class SkTestScalerContext : public SkScalerContext {
public:
    SkTestScalerContext(SkTestTypeface* face, const SkDescriptor* desc)
        : SkScalerContext(face, desc)
        , fFace(face)
    {
        fRec.getSingleMatrix(&fMatrix);
        this->forceGenerateImageFromPath();
    }

    virtual ~SkTestScalerContext() {
    }

protected:
    unsigned generateGlyphCount() override {
        return fFace->onCountGlyphs();
    }

    uint16_t generateCharToGlyph(SkUnichar uni) override {
        uint16_t glyph;
        (void) fFace->onCharsToGlyphs((const void *) &uni, SkTypeface::kUTF16_Encoding, &glyph, 1);
        return glyph;
    }

    void generateAdvance(SkGlyph* glyph) override {
        fFace->getAdvance(glyph);

        const SkVector advance = fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
                                               SkFixedToScalar(glyph->fAdvanceY));
        glyph->fAdvanceX = SkScalarToFixed(advance.fX);
        glyph->fAdvanceY = SkScalarToFixed(advance.fY);
    }

    void generateMetrics(SkGlyph* glyph) override {
        fFace->getMetrics(glyph);

        const SkVector advance = fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
                                               SkFixedToScalar(glyph->fAdvanceY));
        glyph->fAdvanceX = SkScalarToFixed(advance.fX);
        glyph->fAdvanceY = SkScalarToFixed(advance.fY);

        SkPath path;
        fFace->getPath(*glyph, &path);
        path.transform(fMatrix);

        SkRect storage;
        const SkPaint paint;
        const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
                                                            &storage,
                                                            SkPaint::kFill_Style);
        SkIRect ibounds;
        newBounds.roundOut(&ibounds);
        glyph->fLeft = ibounds.fLeft;
        glyph->fTop = ibounds.fTop;
        glyph->fWidth = ibounds.width();
        glyph->fHeight = ibounds.height();
    }

    void generateImage(const SkGlyph& glyph) override {
        SkPath path;
        fFace->getPath(glyph, &path);

        SkBitmap bm;
        bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight),
                            glyph.fImage, glyph.rowBytes());
        bm.eraseColor(0);

        SkCanvas canvas(bm);
        canvas.translate(-SkIntToScalar(glyph.fLeft),
                            -SkIntToScalar(glyph.fTop));
        canvas.concat(fMatrix);
        SkPaint paint;
        paint.setAntiAlias(true);
        canvas.drawPath(path, paint);
    }

    void generatePath(const SkGlyph& glyph, SkPath* path) override {
        fFace->getPath(glyph, path);
        path->transform(fMatrix);
    }

    void generateFontMetrics(SkPaint::FontMetrics* metrics) override {
        fFace->getFontMetrics(metrics);
        if (metrics) {
            SkScalar scale = fMatrix.getScaleY();
            metrics->fTop = SkScalarMul(metrics->fTop, scale);
            metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
            metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
            metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
            metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
            metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
            metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
            metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
            metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
        }
    }

private:
    SkTestTypeface*  fFace;
    SkMatrix         fMatrix;
};

SkScalerContext* SkTestTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
    return SkNEW_ARGS(SkTestScalerContext, (const_cast<SkTestTypeface*>(this), desc));
}
<|endoftext|>


<commit_before>#include "motion.h"
#include "util.h"
#include "godot_vim.h"

Motion::Pos Motion::_move_forward(Motion::matchFunction function, bool accept_empty) {
    int next_cc = vim->_cursor_get_column() + 1;
    int next_cl = vim->_cursor_get_line();

    String line_text = vim->_get_line(next_cl);

    for (int i = next_cl; i < vim->_get_line_count(); i++) {
        line_text = vim->_get_line(i);

        if (line_text.length() == 0 || next_cc >= line_text.length()) {
            if (line_text.length() == 0 && accept_empty && i > vim->_cursor_get_line()) return Pos(i, 0);
            next_cc = 0;
            continue;
        }

        for (int j = next_cc; j < line_text.length(); j++) {
            if ((function)(j, line_text)) {
                print_line("setting cursor to " + itos(j) + ", " + itos(i));
                return Pos(i, j);
            }
        }
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::_move_backward(Motion::matchFunction function, bool accept_empty) {
    int next_cc = vim->_cursor_get_column() - 1;
    int next_cl = vim->_cursor_get_line();

    String line_text = vim->_get_line(next_cl);

    bool needs_cc = false;

    for (int i = next_cl; i >= 0; i--) {
        line_text = vim->_get_line(i);

        if (needs_cc) next_cc = line_text.length() - 1;

        if (line_text.length() == 0) {
            if (accept_empty && i < vim->_cursor_get_line()) return Pos(i, 0);

            needs_cc = true;
            continue;
        }

        for (int j = next_cc; j >= 0; j--) {
            if ((function)(j, line_text)) {
                print_line("setting cursor to " + itos(j) + ", " + itos(i));
                vim->_cursor_set_line(i);
                vim->_cursor_set_column(j);
                return Pos(i, j);
            }
        }

        needs_cc = true;
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::_move_to_first_non_blank(int line) {
    String line_text = vim->_get_line(line);
    if (vim->_cursor_get_line() != line)
        vim->_cursor_set_line(line);
    for (int i = 0; i < line_text.length(); i++) {
        CharType c = line_text[i];
        if (!_is_space(c)) {
                vim->_cursor_set_column(i);
                return Pos(line, i);
        }
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::_move_by_columns(int cols) {
    int col = CLAMP(vim->_cursor_get_column() + cols, 0, vim->_get_current_line_length() - 1);
    return Pos(vim->_cursor_get_line(), col);
}

Motion::Pos Motion::_move_by_lines(int lines) {
    int line = CLAMP(vim->_cursor_get_line() + lines, 0, vim->_get_line_count() - 1);
    return Pos(line, vim->_cursor_get_column());
}

Motion::Pos Motion::_move_left() {
    return _move_by_columns(-1);
}

Motion::Pos Motion::_move_right() {
    return _move_by_columns(1);
}

Motion::Pos Motion::_move_down() {
    return _move_by_lines(1);
}

Motion::Pos Motion::_move_up() {
    return _move_by_lines(-1);
}

Motion::Pos Motion::_move_to_line_start() {
    return Pos(vim->_cursor_get_line(), 0);
}

Motion::Pos Motion::_move_to_line_end() {
    return Pos(vim->_cursor_get_line(), vim->_get_current_line_length() - 1);
}

Motion::Pos Motion::_move_word_right() {
    return _move_forward(&_is_beginning_of_word, true);
}

Motion::Pos Motion::_move_word_right_big() {
    return _move_forward(&_is_beginning_of_big_word, true);
}

Motion::Pos Motion::_move_word_end() {
    return _move_forward(&_is_end_of_word);
}

Motion::Pos Motion::_move_word_end_big() {
    return _move_forward(&_is_end_of_big_word);
}

Motion::Pos Motion::_move_word_end_backward() {
    return _move_backward(&_is_end_of_word);
}

Motion::Pos Motion::_move_word_end_big_backward() {
    return _move_backward(&_is_end_of_big_word);
}

Motion::Pos Motion::_move_word_beginning() {
    return _move_backward(&_is_beginning_of_word, true);
}

Motion::Pos Motion::_move_word_beginning_big() {
    return _move_backward(&_is_beginning_of_big_word, true);
}

Motion::Pos Motion::_move_paragraph_up() {
    int next_cl = vim->_cursor_get_line();

    bool has_text = false;

    for (int i = next_cl; i >= 0; i--) {
        String line_text = vim->_get_line(i);
        if (line_text.size() == 0) {
            if (has_text) {
                return Pos(i, 0);
            }
        } else {
            has_text = true;
        }
    }

    return Pos(0, 0);
}

Motion::Pos Motion::_move_paragraph_down() {
    int next_cl = vim->_cursor_get_line();

    bool has_text = false;

    for (int i = next_cl; i < vim->_get_line_count(); i++) {
        String line_text = vim->_get_line(i);
        if (line_text.size() == 0) {
            if (has_text) {
                return Pos(i, 0);
            }
        } else {
            has_text = true;
        }
    }

    int last_line = vim->_get_line_count() - 1;
    return Pos(last_line, vim->_get_line(last_line).length()  - 1);
}

Motion::Pos Motion::_move_to_matching_pair() {
    String line_text = vim->_get_line(vim->_cursor_get_line());
    int col = vim->_cursor_get_column();
    CharType c = line_text[col];
    if (_is_pair_left_symbol(c)) {
        CharType m = _get_right_pair_symbol(c);

        col++;
        int count = 1;

        for (int i = vim->_cursor_get_line(); i < vim->_get_line_count(); i++) {
            line_text = vim->_get_line(i);
            for (int j = col; j < line_text.length(); j++) {
                CharType cur = line_text[j];
                if (cur == c) {
                    count++;
                } else if (cur == m) {
                    count--;
                    if (count == 0) {
                        return Pos(i, j);
                    }
                }
            }
            col = 0;
        }
    } else if (_is_pair_right_symbol(c)) {
        CharType m = _get_left_pair_symbol(c);

        col--;
        int count = 1;
        bool needs_col = false;

        for (int i = vim->_cursor_get_line(); i >= 0; i--) {
            line_text = vim->_get_line(i);

            if (needs_col) col = line_text.length();

            for (int j = col; j >= 0; j--) {
                CharType cur = line_text[j];
                if (cur == c) {
                    count++;
                } else if (cur == m) {
                    count--;
                    if (count == 0) {
                        return Pos(i, j);
                    }
                }
            }
            needs_col = true;
        }
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::_move_to_first_non_blank() {
    return _move_to_first_non_blank(vim->_cursor_get_line());
}

Motion::Pos Motion::_move_to_beginning_of_last_line() {
    return _move_to_first_non_blank(vim->_get_line_count() - 1);
}

Motion::Pos Motion::_move_to_beginning_of_first_line() {
    return _move_to_first_non_blank(0);
}

Motion::Pos Motion::_move_to_beginning_of_previous_line() {
    if (vim->_cursor_get_line() > 0) {
        return _move_to_first_non_blank(vim->_cursor_get_line() - 1);
    }
    return _move_to_first_non_blank();
}

Motion::Pos Motion::_move_to_beginning_of_next_line() {
    if (vim->_cursor_get_line() < vim->_get_line_count() - 1) {
        _move_to_first_non_blank(vim->_cursor_get_line() + 1);
    }
    return _move_to_first_non_blank();
}

Motion::Pos Motion::_move_to_last_searched_char() {

}

Motion::Pos Motion::_move_to_last_searched_char_backward() {

}

Motion::Pos Motion::_move_to_column() {
    String line_text = vim->_get_current_line();
    if (vim->get_input_state().repeat_count - 1 < line_text.length()) {
        vim->_cursor_set_column(vim->get_input_state().repeat_count - 1);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::search_word_under_cursor() {
    String word = vim->get_text_edit()->get_word_under_cursor();
    int r_l = vim->_cursor_get_line();
    int r_c = vim->_cursor_get_column();

    if (vim->get_text_edit()->search(word, 0, vim->_cursor_get_line(), vim->_cursor_get_column(), r_l, r_c)) {
        print_line("word found");
        return Pos(r_l, r_c);
    }
    return Pos(r_l, r_c);
}

Motion::Pos Motion::search_word_under_cursor_backward() {

}

Motion::Pos Motion::find_next() {
}

Motion::Pos Motion::find_previous() {
}

Motion::Pos Motion::find_char() {
    int n = find_in_line(vim->_get_current_line(), vim->get_input_state().input_char, vim->_cursor_get_column() + 1);

    if (n >= 0) {
        return Pos(vim->_cursor_get_line(), n);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::find_char_backward() {
    int n = find_in_line(vim->_get_current_line().substr(0, vim->_cursor_get_column()), vim->get_input_state().input_char);

    if (n >= 0) {
        return Pos(vim->_cursor_get_line(), n);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::find_till_char() {
    int n = find_in_line(vim->_get_current_line(), vim->get_input_state().input_char, vim->_cursor_get_column());

    if (n >= 0) {
        return Pos(vim->_cursor_get_line(), n - 1);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::find_till_char_backward() {
    int n = find_in_line(vim->_get_current_line().substr(0, vim->_cursor_get_column()), vim->get_input_state().input_char);

    if (n >= 0) {
        return Pos(vim->_cursor_get_line(), n + 1);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

bool Motion::is_inclusive() {
    return flags & INCLUSIVE;
}

bool Motion::is_linewise() {
    return flags & LINEWISE;
}

bool Motion::is_text_object() {
    return flags & TEXT_OBJECT;
}

Motion::Pos Motion::apply() {
    return (this->*fcn)();
}

Motion::Range Motion::get_range() {
    Pos cur_pos = Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
    Pos pos = apply();
    Range range = pos < cur_pos ? Range(pos, cur_pos) : Range(cur_pos, pos);
    range.inclusive = is_inclusive();
    range.linewise = is_linewise();
    range.text_object = is_text_object();
    return range;
}

void Motion::run() {
    Pos pos = apply();
    vim->_cursor_set_line(pos.row);
    vim->_cursor_set_column(pos.col);
}

Motion::Motion(GodotVim *vim, int flags, motionFcn fcn, int cmd_flags) : Command(vim, cmd_flags), flags(flags), fcn(fcn) {
}

Motion * Motion::create_motion(GodotVim *vim, int flags, Motion::motionFcn fcn, int cmd_flags) {
    Motion *motion = memnew(Motion(vim, flags, fcn, cmd_flags));
    return motion;
}
<commit_msg>Implement repeat count for motions<commit_after>#include "motion.h"
#include "util.h"
#include "godot_vim.h"

Motion::Pos Motion::_move_forward(Motion::matchFunction function, bool accept_empty) {
    int next_cc = vim->_cursor_get_column() + 1;
    int next_cl = vim->_cursor_get_line();

    String line_text = vim->_get_line(next_cl);

    for (int i = next_cl; i < vim->_get_line_count(); i++) {
        line_text = vim->_get_line(i);

        if (line_text.length() == 0 || next_cc >= line_text.length()) {
            if (line_text.length() == 0 && accept_empty && i > vim->_cursor_get_line()) return Pos(i, 0);
            next_cc = 0;
            continue;
        }

        for (int j = next_cc; j < line_text.length(); j++) {
            if ((function)(j, line_text)) {
                print_line("setting cursor to " + itos(j) + ", " + itos(i));
                return Pos(i, j);
            }
        }
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::_move_backward(Motion::matchFunction function, bool accept_empty) {
    int next_cc = vim->_cursor_get_column() - 1;
    int next_cl = vim->_cursor_get_line();

    String line_text = vim->_get_line(next_cl);

    bool needs_cc = false;

    for (int i = next_cl; i >= 0; i--) {
        line_text = vim->_get_line(i);

        if (needs_cc) next_cc = line_text.length() - 1;

        if (line_text.length() == 0) {
            if (accept_empty && i < vim->_cursor_get_line()) return Pos(i, 0);

            needs_cc = true;
            continue;
        }

        for (int j = next_cc; j >= 0; j--) {
            if ((function)(j, line_text)) {
                print_line("setting cursor to " + itos(j) + ", " + itos(i));
                vim->_cursor_set_line(i);
                vim->_cursor_set_column(j);
                return Pos(i, j);
            }
        }

        needs_cc = true;
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::_move_to_first_non_blank(int line) {
    String line_text = vim->_get_line(line);
    if (vim->_cursor_get_line() != line)
        vim->_cursor_set_line(line);
    for (int i = 0; i < line_text.length(); i++) {
        CharType c = line_text[i];
        if (!_is_space(c)) {
                vim->_cursor_set_column(i);
                return Pos(line, i);
        }
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::_move_by_columns(int cols) {
    int col = CLAMP(vim->_cursor_get_column() + cols, 0, vim->_get_current_line_length() - 1);
    return Pos(vim->_cursor_get_line(), col);
}

Motion::Pos Motion::_move_by_lines(int lines) {
    int line = CLAMP(vim->_cursor_get_line() + lines, 0, vim->_get_line_count() - 1);
    return Pos(line, vim->_cursor_get_column());
}

Motion::Pos Motion::_move_left() {
    return _move_by_columns(-1);
}

Motion::Pos Motion::_move_right() {
    return _move_by_columns(1);
}

Motion::Pos Motion::_move_down() {
    return _move_by_lines(1);
}

Motion::Pos Motion::_move_up() {
    return _move_by_lines(-1);
}

Motion::Pos Motion::_move_to_line_start() {
    return Pos(vim->_cursor_get_line(), 0);
}

Motion::Pos Motion::_move_to_line_end() {
    return Pos(vim->_cursor_get_line(), vim->_get_current_line_length() - 1);
}

Motion::Pos Motion::_move_word_right() {
    return _move_forward(&_is_beginning_of_word, true);
}

Motion::Pos Motion::_move_word_right_big() {
    return _move_forward(&_is_beginning_of_big_word, true);
}

Motion::Pos Motion::_move_word_end() {
    return _move_forward(&_is_end_of_word);
}

Motion::Pos Motion::_move_word_end_big() {
    return _move_forward(&_is_end_of_big_word);
}

Motion::Pos Motion::_move_word_end_backward() {
    return _move_backward(&_is_end_of_word);
}

Motion::Pos Motion::_move_word_end_big_backward() {
    return _move_backward(&_is_end_of_big_word);
}

Motion::Pos Motion::_move_word_beginning() {
    return _move_backward(&_is_beginning_of_word, true);
}

Motion::Pos Motion::_move_word_beginning_big() {
    return _move_backward(&_is_beginning_of_big_word, true);
}

Motion::Pos Motion::_move_paragraph_up() {
    int next_cl = vim->_cursor_get_line();

    bool has_text = false;

    for (int i = next_cl; i >= 0; i--) {
        String line_text = vim->_get_line(i);
        if (line_text.size() == 0) {
            if (has_text) {
                return Pos(i, 0);
            }
        } else {
            has_text = true;
        }
    }

    return Pos(0, 0);
}

Motion::Pos Motion::_move_paragraph_down() {
    int next_cl = vim->_cursor_get_line();

    bool has_text = false;

    for (int i = next_cl; i < vim->_get_line_count(); i++) {
        String line_text = vim->_get_line(i);
        if (line_text.size() == 0) {
            if (has_text) {
                return Pos(i, 0);
            }
        } else {
            has_text = true;
        }
    }

    int last_line = vim->_get_line_count() - 1;
    return Pos(last_line, vim->_get_line(last_line).length()  - 1);
}

Motion::Pos Motion::_move_to_matching_pair() {
    String line_text = vim->_get_line(vim->_cursor_get_line());
    int col = vim->_cursor_get_column();
    CharType c = line_text[col];
    if (_is_pair_left_symbol(c)) {
        CharType m = _get_right_pair_symbol(c);

        col++;
        int count = 1;

        for (int i = vim->_cursor_get_line(); i < vim->_get_line_count(); i++) {
            line_text = vim->_get_line(i);
            for (int j = col; j < line_text.length(); j++) {
                CharType cur = line_text[j];
                if (cur == c) {
                    count++;
                } else if (cur == m) {
                    count--;
                    if (count == 0) {
                        return Pos(i, j);
                    }
                }
            }
            col = 0;
        }
    } else if (_is_pair_right_symbol(c)) {
        CharType m = _get_left_pair_symbol(c);

        col--;
        int count = 1;
        bool needs_col = false;

        for (int i = vim->_cursor_get_line(); i >= 0; i--) {
            line_text = vim->_get_line(i);

            if (needs_col) col = line_text.length();

            for (int j = col; j >= 0; j--) {
                CharType cur = line_text[j];
                if (cur == c) {
                    count++;
                } else if (cur == m) {
                    count--;
                    if (count == 0) {
                        return Pos(i, j);
                    }
                }
            }
            needs_col = true;
        }
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::_move_to_first_non_blank() {
    return _move_to_first_non_blank(vim->_cursor_get_line());
}

Motion::Pos Motion::_move_to_beginning_of_last_line() {
    return _move_to_first_non_blank(vim->_get_line_count() - 1);
}

Motion::Pos Motion::_move_to_beginning_of_first_line() {
    return _move_to_first_non_blank(0);
}

Motion::Pos Motion::_move_to_beginning_of_previous_line() {
    if (vim->_cursor_get_line() > 0) {
        return _move_to_first_non_blank(vim->_cursor_get_line() - 1);
    }
    return _move_to_first_non_blank();
}

Motion::Pos Motion::_move_to_beginning_of_next_line() {
    if (vim->_cursor_get_line() < vim->_get_line_count() - 1) {
        _move_to_first_non_blank(vim->_cursor_get_line() + 1);
    }
    return _move_to_first_non_blank();
}

Motion::Pos Motion::_move_to_last_searched_char() {

}

Motion::Pos Motion::_move_to_last_searched_char_backward() {

}

Motion::Pos Motion::_move_to_column() {
    String line_text = vim->_get_current_line();
    if (vim->get_input_state().repeat_count - 1 < line_text.length()) {
        vim->_cursor_set_column(vim->get_input_state().repeat_count - 1);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::search_word_under_cursor() {
    String word = vim->get_text_edit()->get_word_under_cursor();
    int r_l = vim->_cursor_get_line();
    int r_c = vim->_cursor_get_column();

    if (vim->get_text_edit()->search(word, 0, vim->_cursor_get_line(), vim->_cursor_get_column(), r_l, r_c)) {
        print_line("word found");
        return Pos(r_l, r_c);
    }
    return Pos(r_l, r_c);
}

Motion::Pos Motion::search_word_under_cursor_backward() {

}

Motion::Pos Motion::find_next() {
}

Motion::Pos Motion::find_previous() {
}

Motion::Pos Motion::find_char() {
    int n = find_in_line(vim->_get_current_line(), vim->get_input_state().input_char, vim->_cursor_get_column() + 1);

    if (n >= 0) {
        return Pos(vim->_cursor_get_line(), n);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::find_char_backward() {
    int n = find_in_line(vim->_get_current_line().substr(0, vim->_cursor_get_column()), vim->get_input_state().input_char);

    if (n >= 0) {
        return Pos(vim->_cursor_get_line(), n);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::find_till_char() {
    int n = find_in_line(vim->_get_current_line(), vim->get_input_state().input_char, vim->_cursor_get_column());

    if (n >= 0) {
        return Pos(vim->_cursor_get_line(), n - 1);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

Motion::Pos Motion::find_till_char_backward() {
    int n = find_in_line(vim->_get_current_line().substr(0, vim->_cursor_get_column()), vim->get_input_state().input_char);

    if (n >= 0) {
        return Pos(vim->_cursor_get_line(), n + 1);
    }

    return Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
}

bool Motion::is_inclusive() {
    return flags & INCLUSIVE;
}

bool Motion::is_linewise() {
    return flags & LINEWISE;
}

bool Motion::is_text_object() {
    return flags & TEXT_OBJECT;
}

Motion::Pos Motion::apply() {
    Pos pos = Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
    int repeat = vim->get_input_state().repeat_count;
    if (repeat < 1) repeat = 1;
    for (int i = 0; i < repeat; i++) {
        vim->_cursor_set_line(pos.row);
        vim->_cursor_set_column(pos.col);
        pos = (this->*fcn)();
    }
    return pos;
}

Motion::Range Motion::get_range() {
    Pos cur_pos = Pos(vim->_cursor_get_line(), vim->_cursor_get_column());
    Pos pos = apply();
    Range range = pos < cur_pos ? Range(pos, cur_pos) : Range(cur_pos, pos);
    range.inclusive = is_inclusive();
    range.linewise = is_linewise();
    range.text_object = is_text_object();
    return range;
}

void Motion::run() {
    Pos pos = apply();
    vim->_cursor_set_line(pos.row);
    vim->_cursor_set_column(pos.col);
}

Motion::Motion(GodotVim *vim, int flags, motionFcn fcn, int cmd_flags) : Command(vim, cmd_flags), flags(flags), fcn(fcn) {
}

Motion * Motion::create_motion(GodotVim *vim, int flags, Motion::motionFcn fcn, int cmd_flags) {
    Motion *motion = memnew(Motion(vim, flags, fcn, cmd_flags));
    return motion;
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkImageToPointCloudFilter.h"

#include <itkImageIterator.h>
#include <itkImageRegionIterator.h>

#include <mitkDataNode.h>
#include <mitkImageAccessByItk.h>
#include <mitkImageCast.h>
#include <mitkITKImageImport.h>
#include <mitkImageStatisticsCalculator.h>

mitk::ImageToPointCloudFilter::ImageToPointCloudFilter():
  m_NumberOfExtractedPoints(0)
{
  m_PointSurface = mitk::Surface::New();
  m_Method = DetectConstant(0);
  m_EdgeImage = mitk::Image::New();
  m_EdgePoints = mitk::Image::New();

  this->SetNumberOfRequiredInputs(1);
  this->SetNumberOfRequiredOutputs(1);

  this->SetNthOutput(0, m_PointSurface);
}

mitk::ImageToPointCloudFilter::~ImageToPointCloudFilter(){}

void mitk::ImageToPointCloudFilter::GenerateData()
{
  mitk::Image::ConstPointer image = ImageToSurfaceFilter::GetInput();
  m_Geometry = image->GetGeometry();

  if ( image.IsNull() )
  {
    MITK_ERROR << "mitk::ImageToContourFilter: No input available. "
                  "Please set the input!" << std::endl;
    return;
  }

  switch(m_Method)
  {
  case 0:
    this->LaplacianStdDev(image, 2);
    break;

  case 1:
    this->LaplacianStdDev(image, 3);
    break;

  default:
    this->LaplacianStdDev(image, 2);
    break;
  }
}

void mitk::ImageToPointCloudFilter::
                    LaplacianStdDev(mitk::Image::ConstPointer image, int amount)
{
  mitk::Image::Pointer notConstImage = image->Clone();
  AccessByItk_1(notConstImage.GetPointer(), StdDeviations, amount)
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ImageToPointCloudFilter::
           StdDeviations(itk::Image<TPixel, VImageDimension>* image, int amount)
{
  typedef itk::Image<TPixel, VImageDimension> InputImageType;
  typedef itk::CastImageFilter< InputImageType, FloatImageType >
          ImagePTypeToFloatPTypeCasterType;
  typename LaplacianFilterType::Pointer lapFilter = LaplacianFilterType::New();

  typename ImagePTypeToFloatPTypeCasterType::Pointer caster =
           ImagePTypeToFloatPTypeCasterType::New();
  caster->SetInput( image );
  caster->Update();
  FloatImageType::Pointer fImage = caster->GetOutput();

  lapFilter->SetInput(fImage);
  lapFilter->UpdateLargestPossibleRegion();
  m_EdgeImage = mitk::ImportItkImage(lapFilter->GetOutput())->Clone();

  mitk::ImageStatisticsCalculator::Pointer statCalc =
                                         mitk::ImageStatisticsCalculator::New();
  statCalc->SetImage(m_EdgeImage);
  statCalc->ComputeStatistics();
  mitk::ImageStatisticsCalculator::Statistics stats = statCalc->GetStatistics();
  double mean = stats.GetMean();
  double stdDev = stats.GetSigma();

  double upperThreshold = mean + stdDev * amount;
  double lowerThreshold = mean - stdDev * amount;

  typename itk::ImageRegionIterator<FloatImageType> it(lapFilter->GetOutput(),
                                 lapFilter->GetOutput()->GetRequestedRegion());

  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

  it.GoToBegin();
  while( !it.IsAtEnd() )
  {
    if(it.Get() > lowerThreshold && it.Get() < upperThreshold)
    {
      it.Set(0);
    }
    else
    {
      it.Set(1);

      mitk::Point3D imagePoint;
      mitk::Point3D worldPoint;

      imagePoint[0] = it.GetIndex()[0];
      imagePoint[1] = it.GetIndex()[1];
      imagePoint[2] = it.GetIndex()[2];

      m_Geometry->IndexToWorld(imagePoint, worldPoint);

      points->InsertNextPoint(worldPoint[0],worldPoint[1],worldPoint[2]);
      m_NumberOfExtractedPoints++;
    }
    ++it;
  }

  m_EdgePoints = mitk::ImportItkImage(lapFilter->GetOutput())->Clone();

  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
  polyData->SetPoints(points);
  polyData->BuildCells();
  polyData->BuildLinks();
  m_PointSurface->SetVtkPolyData(polyData);
}

void mitk::ImageToPointCloudFilter::GenerateOutputInformation()
{
  Superclass::GenerateOutputInformation();
}
<commit_msg>added lines between the polydata points for correct visualization<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "mitkImageToPointCloudFilter.h"

#include <itkImageIterator.h>
#include <itkImageRegionIterator.h>
#include <vtkPolyLine.h>

#include <mitkDataNode.h>
#include <mitkImageAccessByItk.h>
#include <mitkImageCast.h>
#include <mitkITKImageImport.h>
#include <mitkImageStatisticsCalculator.h>
#include <vtkCellArray.h>

mitk::ImageToPointCloudFilter::ImageToPointCloudFilter():
  m_NumberOfExtractedPoints(0)
{
  m_PointSurface = mitk::Surface::New();
  m_Method = DetectConstant(0);
  m_EdgeImage = mitk::Image::New();
  m_EdgePoints = mitk::Image::New();

  this->SetNumberOfRequiredInputs(1);
  this->SetNumberOfRequiredOutputs(1);

  this->SetNthOutput(0, m_PointSurface);
}

mitk::ImageToPointCloudFilter::~ImageToPointCloudFilter(){}

void mitk::ImageToPointCloudFilter::GenerateData()
{
  mitk::Image::ConstPointer image = ImageToSurfaceFilter::GetInput();
  m_Geometry = image->GetGeometry();

  if ( image.IsNull() )
  {
    MITK_ERROR << "mitk::ImageToContourFilter: No input available. "
                  "Please set the input!" << std::endl;
    return;
  }

  switch(m_Method)
  {
  case 0:
    this->LaplacianStdDev(image, 2);
    break;

  case 1:
    this->LaplacianStdDev(image, 3);
    break;

  default:
    this->LaplacianStdDev(image, 2);
    break;
  }
}

void mitk::ImageToPointCloudFilter::
                    LaplacianStdDev(mitk::Image::ConstPointer image, int amount)
{
  mitk::Image::Pointer notConstImage = image->Clone();
  AccessByItk_1(notConstImage.GetPointer(), StdDeviations, amount)
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ImageToPointCloudFilter::
           StdDeviations(itk::Image<TPixel, VImageDimension>* image, int amount)
{
  typedef itk::Image<TPixel, VImageDimension> InputImageType;
  typedef itk::CastImageFilter< InputImageType, FloatImageType >
          ImagePTypeToFloatPTypeCasterType;
  typename LaplacianFilterType::Pointer lapFilter = LaplacianFilterType::New();

  typename ImagePTypeToFloatPTypeCasterType::Pointer caster =
           ImagePTypeToFloatPTypeCasterType::New();
  caster->SetInput( image );
  caster->Update();
  FloatImageType::Pointer fImage = caster->GetOutput();

  lapFilter->SetInput(fImage);
  lapFilter->UpdateLargestPossibleRegion();
  m_EdgeImage = mitk::ImportItkImage(lapFilter->GetOutput())->Clone();

  mitk::ImageStatisticsCalculator::Pointer statCalc =
                                         mitk::ImageStatisticsCalculator::New();
  statCalc->SetImage(m_EdgeImage);
  statCalc->ComputeStatistics();
  mitk::ImageStatisticsCalculator::Statistics stats = statCalc->GetStatistics();
  double mean = stats.GetMean();
  double stdDev = stats.GetSigma();

  double upperThreshold = mean + stdDev * amount;
  double lowerThreshold = mean - stdDev * amount;

  typename itk::ImageRegionIterator<FloatImageType> it(lapFilter->GetOutput(),
                                 lapFilter->GetOutput()->GetRequestedRegion());

  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

  it.GoToBegin();
  while( !it.IsAtEnd() )
  {
    if(it.Get() > lowerThreshold && it.Get() < upperThreshold)
    {
      it.Set(0);
    }
    else
    {
      it.Set(1);

      mitk::Point3D imagePoint;
      mitk::Point3D worldPoint;

      imagePoint[0] = it.GetIndex()[0];
      imagePoint[1] = it.GetIndex()[1];
      imagePoint[2] = it.GetIndex()[2];

      m_Geometry->IndexToWorld(imagePoint, worldPoint);

      points->InsertNextPoint(worldPoint[0],worldPoint[1],worldPoint[2]);
      m_NumberOfExtractedPoints++;
    }
    ++it;
  }

  vtkSmartPointer<vtkPolyLine> polyLine = vtkSmartPointer<vtkPolyLine>::New();
  polyLine->GetPointIds()->SetNumberOfIds(m_NumberOfExtractedPoints);

  for(unsigned int i = 0; i < m_NumberOfExtractedPoints; i++)
  {
    polyLine->GetPointIds()->SetId(i,i);
  }

  vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
  cells->InsertNextCell(polyLine);

  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
  polyData->SetPoints(points);
  polyData->SetLines(cells);

  m_EdgePoints = mitk::ImportItkImage(lapFilter->GetOutput())->Clone();

  polyData->BuildCells();
  polyData->BuildLinks();
  m_PointSurface->SetVtkPolyData(polyData);
}

void mitk::ImageToPointCloudFilter::GenerateOutputInformation()
{
  Superclass::GenerateOutputInformation();
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>

#include <curl/curl.h>

#include "fcgiapp.h"

#include "common/ceph_argparse.h"
#include "global/global_init.h"
#include "common/config.h"
#include "common/errno.h"
#include "common/Thread.h"
#include "rgw_common.h"
#include "rgw_access.h"
#include "rgw_acl.h"
#include "rgw_user.h"
#include "rgw_op.h"
#include "rgw_rest.h"
#include "rgw_os.h"
#include "rgw_log.h"

#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <sstream>

#include "include/types.h"
#include "common/BackTrace.h"

using namespace std;

static sighandler_t sighandler_usr1;
static sighandler_t sighandler_alrm;

static void godown_handler(int signum)
{
  FCGX_ShutdownPending();
  signal(signum, sighandler_usr1);
  alarm(5);
}

static void godown_alarm(int signum)
{
  _exit(0);
}

class RGWThread : public Thread {
  FCGX_Request *fcgx;
public:
  RGWThread(FCGX_Request *_f) : fcgx(_f) {}
  ~RGWThread() { delete fcgx; }
  void *entry();
};

class RGWProcess {
  vector<RGWThread *> m_threads;

public:
  RGWProcess() {}
  void start(int num_threads);
  void join();
};

void RGWProcess::start(int num_threads)
{
#if 0
  string sock = "/tmp/.radosgw.sock";
  int s = FCGX_OpenSocket(sock.c_str(), 100);
  if (s < 0) {
    RGW_LOG(0) << "ERROR: FCGX_OpenSocket (" << sock << ") returned " << s << dendl;
    return;
  }
#endif

  for (;;) {
    FCGX_Request *fcgx = new FCGX_Request;
//    FCGX_InitRequest(fcgx, s, 0);
    FCGX_InitRequest(fcgx, 0, 0);
    int ret = FCGX_Accept_r(fcgx);
    if (ret < 0)
      return;

    RGWThread *thread = new RGWThread(fcgx);
    m_threads.push_back(thread);
    thread->create();
  }
}

void RGWProcess::join()
{
  vector<RGWThread *>::iterator iter;
  for (iter = m_threads.begin(); iter != m_threads.end(); ++iter) {
    RGWThread *thr = *iter;
    int ret = thr->join();
    delete thr;
    if (ret < 0) {
      cerr << "WARNING: thread join returned " << ret << std::endl;
    }
  }
}

void *RGWThread::entry()
{
  RGWRESTMgr rest;

  RGW_LOG(0) << "thread started thread_id=" << hex << (uint64_t)get_thread_id() << dec << dendl;

  int ret;

  {
    rgw_env.reinit(fcgx->envp);

    struct req_state *s = new req_state;

    RGWOp *op = NULL;
    int init_error = 0;
    RGWHandler *handler = rest.get_handler(s, fcgx, &init_error);

    if (init_error != 0) {
      abort_early(s, init_error);
      goto done;
    }

    if (!handler->authorize()) {
      RGW_LOG(10) << "failed to authorize request" << dendl;
      abort_early(s, -EPERM);
      goto done;
    }
    if (s->user.suspended) {
      RGW_LOG(10) << "user is suspended, uid=" << s->user.user_id << dendl;
      abort_early(s, -ERR_USER_SUSPENDED);
      goto done;
    }
    ret = handler->read_permissions();
    if (ret < 0) {
      abort_early(s, ret);
      goto done;
    }

    op = handler->get_op();
    if (op) {
      ret = op->verify_permission();
      if (ret < 0) {
        abort_early(s, ret);
        goto done;
      }

      if (s->expect_cont)
        dump_continue(s);

      op->execute();
    } else {
      abort_early(s, -ERR_METHOD_NOT_ALLOWED);
    }
done:
    rgw_log_op(s);

    handler->put_op(op);
    delete s;
    FCGX_Finish_r(fcgx);
  }

  return NULL;
}

/*
 * start up the RADOS connection and then handle HTTP messages as they come in
 */
int main(int argc, const char **argv)
{
  curl_global_init(CURL_GLOBAL_ALL);

  // dout() messages will be sent to stderr, but FCGX wants messages on stdout
  // Redirect stderr to stdout.
  TEMP_FAILURE_RETRY(close(STDERR_FILENO));
  if (TEMP_FAILURE_RETRY(dup2(STDOUT_FILENO, STDERR_FILENO) < 0)) {
    int err = errno;
    cout << "failed to redirect stderr to stdout: " << cpp_strerror(err)
	 << std::endl;
    return ENOSYS;
  }

  vector<const char*> args;
  argv_to_vec(argc, argv, args);
  env_to_vec(args);
  global_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
  common_init_finish(g_ceph_context);

  sighandler_usr1 = signal(SIGUSR1, godown_handler);
  sighandler_alrm = signal(SIGALRM, godown_alarm);

  FCGX_Init();

  RGWStoreManager store_manager;

  if (!store_manager.init("rados", g_ceph_context)) {
    derr << "Couldn't init storage provider (RADOS)" << dendl;
    return EIO;
  }

  RGWProcess process;
  process.start(20);
  process.join();

  return 0;
}

<commit_msg>rgw: use thread pool for rgw work<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>

#include <curl/curl.h>

#include "fcgiapp.h"

#include "common/ceph_argparse.h"
#include "global/global_init.h"
#include "common/config.h"
#include "common/errno.h"
#include "common/WorkQueue.h"
#include "rgw_common.h"
#include "rgw_access.h"
#include "rgw_acl.h"
#include "rgw_user.h"
#include "rgw_op.h"
#include "rgw_rest.h"
#include "rgw_os.h"
#include "rgw_log.h"

#include <map>
#include <string>
#include <vector>
#include <iostream>
#include <sstream>

#include "include/types.h"
#include "common/BackTrace.h"

using namespace std;

static sighandler_t sighandler_usr1;
static sighandler_t sighandler_alrm;

#define SOCKET_NAME "/tmp/.radosgw.sock"
#define SOCKET_BACKLOG 20

static void godown_handler(int signum)
{
  FCGX_ShutdownPending();
  signal(signum, sighandler_usr1);
  alarm(5);
}

static void godown_alarm(int signum)
{
  _exit(0);
}

class RGWProcess {
  deque<FCGX_Request*> m_fcgx_queue;
  ThreadPool m_tp;

  struct RGWWQ : public ThreadPool::WorkQueue<FCGX_Request> {
    RGWProcess *process;
    RGWWQ(RGWProcess *p, ThreadPool *tp) : ThreadPool::WorkQueue<FCGX_Request>("RGWWQ", tp), process(p) {}

    bool _enqueue(FCGX_Request *req) {
      process->m_fcgx_queue.push_back(req);
      return true;
    }
    void _dequeue(FCGX_Request *req) {
      assert(0);
    }
    bool _empty() {
      return process->m_fcgx_queue.empty();
    }
    FCGX_Request *_dequeue() {
      if (process->m_fcgx_queue.empty())
	return NULL;
      FCGX_Request *req = process->m_fcgx_queue.front();
      process->m_fcgx_queue.pop_front();
      return req;
    }
    void _process(FCGX_Request *fcgx) {
      process->handle_request(fcgx);
    }
    void _clear() {
      assert(process->m_fcgx_queue.empty());
    }
  } req_wq;

public:
  RGWProcess(CephContext *cct, int num_threads) : m_tp(cct, "RGWProcess::m_tp", num_threads), req_wq(this, &m_tp) {}
  void run();
  void handle_request(FCGX_Request *fcgx);
};

void RGWProcess::run()
{
  const char *sock = SOCKET_NAME;
  int s = FCGX_OpenSocket(sock, SOCKET_BACKLOG);
  if (s < 0) {
    RGW_LOG(0) << "ERROR: FCGX_OpenSocket (" << sock << ") returned " << s << dendl;
    return;
  }
  if (chmod(sock, 0777) < 0) {
    RGW_LOG(0) << "WARNING: couldn't set permissions on unix domain socket" << dendl;
  }

  m_tp.start();

  for (;;) {
    FCGX_Request *fcgx = new FCGX_Request;
    FCGX_InitRequest(fcgx, s, 0);
    int ret = FCGX_Accept_r(fcgx);
    if (ret < 0)
      return;

    req_wq.queue(fcgx);
  }
}

void RGWProcess::handle_request(FCGX_Request *fcgx)
{
  RGWRESTMgr rest;
  int ret;

  rgw_env.reinit(fcgx->envp);

  struct req_state *s = new req_state;

  RGWOp *op = NULL;
  int init_error = 0;
  RGWHandler *handler = rest.get_handler(s, fcgx, &init_error);

  if (init_error != 0) {
    abort_early(s, init_error);
    goto done;
  }

  if (!handler->authorize()) {
    RGW_LOG(10) << "failed to authorize request" << dendl;
    abort_early(s, -EPERM);
    goto done;
  }
  if (s->user.suspended) {
    RGW_LOG(10) << "user is suspended, uid=" << s->user.user_id << dendl;
    abort_early(s, -ERR_USER_SUSPENDED);
    goto done;
  }
  ret = handler->read_permissions();
  if (ret < 0) {
    abort_early(s, ret);
    goto done;
  }

  op = handler->get_op();
  if (op) {
    ret = op->verify_permission();
    if (ret < 0) {
      abort_early(s, ret);
      goto done;
    }

    if (s->expect_cont)
      dump_continue(s);

    op->execute();
  } else {
    abort_early(s, -ERR_METHOD_NOT_ALLOWED);
  }
done:
  rgw_log_op(s);

  handler->put_op(op);
  delete s;
  FCGX_Finish_r(fcgx);
  delete fcgx;
}

/*
 * start up the RADOS connection and then handle HTTP messages as they come in
 */
int main(int argc, const char **argv)
{
  curl_global_init(CURL_GLOBAL_ALL);

  // dout() messages will be sent to stderr, but FCGX wants messages on stdout
  // Redirect stderr to stdout.
  TEMP_FAILURE_RETRY(close(STDERR_FILENO));
  if (TEMP_FAILURE_RETRY(dup2(STDOUT_FILENO, STDERR_FILENO) < 0)) {
    int err = errno;
    cout << "failed to redirect stderr to stdout: " << cpp_strerror(err)
	 << std::endl;
    return ENOSYS;
  }

  vector<const char*> args;
  argv_to_vec(argc, argv, args);
  env_to_vec(args);
  global_init(args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
  common_init_finish(g_ceph_context);

  sighandler_usr1 = signal(SIGUSR1, godown_handler);
  sighandler_alrm = signal(SIGALRM, godown_alarm);

  FCGX_Init();

  RGWStoreManager store_manager;

  if (!store_manager.init("rados", g_ceph_context)) {
    derr << "Couldn't init storage provider (RADOS)" << dendl;
    return EIO;
  }

  RGWProcess process(g_ceph_context, 20);

  process.run();

  return 0;
}

<|endoftext|>


<commit_before>/*
 * File:   histograms.cpp
 * Author: claas
 *
 * Created on 9. Juli 2009, 13:40
 */

#include "Histograms.h"

// debug
#include "Tools/Debug/DebugRequest.h"
#include "Tools/Debug/DebugImageDrawings.h"

using namespace naoth;
using namespace std;

Histograms::Histograms()
{
  std::stringstream dbgString;
  std::stringstream descString;
  for(int color = 0; color < ColorClasses::numOfColors; color++)
  {
    dbgString.str("");
    dbgString << "ImageProcessor:Histogram:x:" << ColorClasses::getColorName((ColorClasses::Color) color);
    descString.str("");
    descString << "draw X axis histogram of " << ColorClasses::getColorName((ColorClasses::Color) color) << " pixels";
    DEBUG_REQUEST_REGISTER(dbgString.str(), descString.str(), false);
    dbgString.str("");
    dbgString << "ImageProcessor:Histogram:y:" << ColorClasses::getColorName((ColorClasses::Color) color);
    descString.str("");
    descString << "draw Y axis histogram of " << ColorClasses::getColorName((ColorClasses::Color) color) << " pixels";
    DEBUG_REQUEST_REGISTER(dbgString.str(), descString.str(), false);
  }

  //DEBUG_REQUEST_REGISTER("ImageProcessor:Histogram:colorChannelHistogramCr", "draw X axis rate histogram of the V (Cr) color channel from the field", false);
  DEBUG_REQUEST_REGISTER("ImageProcessor:Histogram:plotY", "plot Y channel histogram bottom image", false);
  DEBUG_REQUEST_REGISTER("ImageProcessor:Histogram:plotU", "plot U channel histogram bottom image", false);
  DEBUG_REQUEST_REGISTER("ImageProcessor:Histogram:plotV", "plot V channel histogram bottom image", false);

  init();
}

void Histograms::init()
{
  colorChannelIsUptodate = false;

  for(int c = 0; c < ColorClasses::numOfColors; c++)
  {
    xHistogram[c].clear();
    yHistogram[c].clear();
  }
}//end init

void Histograms::execute()
{
  init();
}

void Histograms::showDebugInfos(const UniformGrid& grid, const CameraInfo& cameraInfo) const
{
  std::stringstream dbgString;
  bool drawXHist = false;
  bool drawYHist = false;
  bool drawChannelHist = false;

  DEBUG_REQUEST("ImageProcessor:Histogram:plotY",
    histogramY.plot("Histograms:Y");
  );
  DEBUG_REQUEST("ImageProcessor:Histogram:plotU",
    histogramU.plot("Histograms:U");
  );
  DEBUG_REQUEST("ImageProcessor:Histogram:plotV",
    histogramV.plot("Histograms:V");
  );

  for(int color = 0; color < ColorClasses::numOfColors; color++)
  {
    dbgString.str("");
    dbgString << "ImageProcessor:Histogram:x:" << ColorClasses::getColorName( (ColorClasses::Color) color);
    DEBUG_REQUEST_GENERIC(dbgString.str(),
      drawXHist = true;
    Vector2<int> last(cameraInfo.resolutionWidth - (xHistogram[color].rawData[0] * 1), 0);
      for(unsigned int y = 1; y < (grid.height * 1); y += 1)
      {
        LINE_PX
        (
          (ColorClasses::Color) color,
          last.x,
          last.y,
          cameraInfo.resolutionWidth - (xHistogram[color].rawData[y] * 1),
          y
        );
        last.x = cameraInfo.resolutionWidth - (xHistogram[color].rawData[y] * 1);
        last.y = y;
      }
    );

    dbgString.str("");
    dbgString << "ImageProcessor:Histogram:y:" << ColorClasses::getColorName((ColorClasses::Color) color);
    DEBUG_REQUEST_GENERIC(dbgString.str(),
      drawYHist = true;
    Vector2<int> last(0, cameraInfo.resolutionHeight - (yHistogram[color].rawData[0] * 1) );
      for(unsigned int x = 1; x < (grid.width * 1); x += 1)
      {
        LINE_PX
        (
          (ColorClasses::Color) color,
          last.x,
          last.y,
          x,
          cameraInfo.resolutionHeight - (yHistogram[color].rawData[x] * 1)
        );
        last.x = x;
        last.y = cameraInfo.resolutionHeight - (yHistogram[color].rawData[x] * 1);
      }
    );
  }

  //DEBUG_REQUEST("ImageProcessor:Histogram:colorChannelHistogramCr",
  //  drawChannelHist = true;
  //  Vector2<int> last(0, Math::clamp((int)cameraInfo.resolutionHeight - (int) colorChannelHistogramCr[0], 0, (int)cameraInfo.resolutionHeight));
  //  for(unsigned int x = 1; x < COLOR_CHANNEL_VALUE_COUNT; x ++)
  //  {
  //    LINE_PX
  //    (
  //      ColorClasses::red,
  //      last.x,
  //      last.y,
  //      x,
  //      Math::clamp((int)cameraInfo.resolutionHeight - (int) colorChannelHistogramCr[x], 0, (int)cameraInfo.resolutionHeight)
  //    );
  //    last.x = x;
  //    last.y = Math::clamp((int)cameraInfo.resolutionHeight - (int) colorChannelHistogramCr[x], 0, (int)cameraInfo.resolutionHeight);
  //  }
  //);

  //if(drawChannelHist)
  //{
  //  RECT_PX
  //  (
  //    ColorClasses::black,
  //    0,
  //    cameraInfo.resolutionHeight,
  //    COLOR_CHANNEL_VALUE_COUNT,
  //    0
  //  );
  //}

  if(drawXHist)
  {
    RECT_PX(
      ColorClasses::black,
      cameraInfo.resolutionWidth - (grid.width * 1),
      0,
      cameraInfo.resolutionWidth,
      grid.height * 1
    );
  }

  if(drawYHist)
  {
    RECT_PX
    (
      ColorClasses::black,
      0,
      cameraInfo.resolutionHeight - (grid.height * 1),
      (grid.width * 1),
      cameraInfo.resolutionHeight
    );
  }

}//end showDebugInfos

inline void Histograms::createFromColoredGrid(const ColoredGrid& coloredGrid)
{
  for(int color = 0; color < ColorClasses::numOfColors; color++)
  {
    for (unsigned int pixelIndex = 0; pixelIndex < coloredGrid.numberOfColorPoints[color]; pixelIndex++)
    {
      const Vector2<int>& gridPoint = coloredGrid.uniformGrid.getGridCoordinates(pixelIndex);
      increaseValue(gridPoint, (ColorClasses::Color) color);
    }
  }
}//end createFromColoredGrid

void Histograms::print(ostream& stream) const
{
  stream << "Histogram";
}//end print

<commit_msg>fixed build error<commit_after>/*
 * File:   histograms.cpp
 * Author: claas
 *
 * Created on 9. Juli 2009, 13:40
 */

#include "Histograms.h"

// debug
#include "Tools/Debug/DebugRequest.h"
#include "Tools/Debug/DebugImageDrawings.h"

using namespace naoth;
using namespace std;

Histograms::Histograms()
{
  std::stringstream dbgString;
  std::stringstream descString;
  for(int color = 0; color < ColorClasses::numOfColors; color++)
  {
    dbgString.str("");
    dbgString << "ImageProcessor:Histogram:x:" << ColorClasses::getColorName((ColorClasses::Color) color);
    descString.str("");
    descString << "draw X axis histogram of " << ColorClasses::getColorName((ColorClasses::Color) color) << " pixels";
    DEBUG_REQUEST_REGISTER(dbgString.str(), descString.str(), false);
    dbgString.str("");
    dbgString << "ImageProcessor:Histogram:y:" << ColorClasses::getColorName((ColorClasses::Color) color);
    descString.str("");
    descString << "draw Y axis histogram of " << ColorClasses::getColorName((ColorClasses::Color) color) << " pixels";
    DEBUG_REQUEST_REGISTER(dbgString.str(), descString.str(), false);
  }

  //DEBUG_REQUEST_REGISTER("ImageProcessor:Histogram:colorChannelHistogramCr", "draw X axis rate histogram of the V (Cr) color channel from the field", false);
  DEBUG_REQUEST_REGISTER("ImageProcessor:Histogram:plotY", "plot Y channel histogram bottom image", false);
  DEBUG_REQUEST_REGISTER("ImageProcessor:Histogram:plotU", "plot U channel histogram bottom image", false);
  DEBUG_REQUEST_REGISTER("ImageProcessor:Histogram:plotV", "plot V channel histogram bottom image", false);

  init();
}

void Histograms::init()
{
  colorChannelIsUptodate = false;

  for(int c = 0; c < ColorClasses::numOfColors; c++)
  {
    xHistogram[c].clear();
    yHistogram[c].clear();
  }
}//end init

void Histograms::execute()
{
  init();
}

void Histograms::showDebugInfos(const UniformGrid& grid, const CameraInfo& cameraInfo) const
{
  std::stringstream dbgString;
  bool drawXHist = false;
  bool drawYHist = false;
  //bool drawChannelHist = false;

  DEBUG_REQUEST("ImageProcessor:Histogram:plotY",
    histogramY.plot("Histograms:Y");
  );
  DEBUG_REQUEST("ImageProcessor:Histogram:plotU",
    histogramU.plot("Histograms:U");
  );
  DEBUG_REQUEST("ImageProcessor:Histogram:plotV",
    histogramV.plot("Histograms:V");
  );

  for(int color = 0; color < ColorClasses::numOfColors; color++)
  {
    dbgString.str("");
    dbgString << "ImageProcessor:Histogram:x:" << ColorClasses::getColorName( (ColorClasses::Color) color);
    DEBUG_REQUEST_GENERIC(dbgString.str(),
      drawXHist = true;
    Vector2<int> last(cameraInfo.resolutionWidth - (xHistogram[color].rawData[0] * 1), 0);
      for(unsigned int y = 1; y < (grid.height * 1); y += 1)
      {
        LINE_PX
        (
          (ColorClasses::Color) color,
          last.x,
          last.y,
          cameraInfo.resolutionWidth - (xHistogram[color].rawData[y] * 1),
          y
        );
        last.x = cameraInfo.resolutionWidth - (xHistogram[color].rawData[y] * 1);
        last.y = y;
      }
    );

    dbgString.str("");
    dbgString << "ImageProcessor:Histogram:y:" << ColorClasses::getColorName((ColorClasses::Color) color);
    DEBUG_REQUEST_GENERIC(dbgString.str(),
      drawYHist = true;
    Vector2<int> last(0, cameraInfo.resolutionHeight - (yHistogram[color].rawData[0] * 1) );
      for(unsigned int x = 1; x < (grid.width * 1); x += 1)
      {
        LINE_PX
        (
          (ColorClasses::Color) color,
          last.x,
          last.y,
          x,
          cameraInfo.resolutionHeight - (yHistogram[color].rawData[x] * 1)
        );
        last.x = x;
        last.y = cameraInfo.resolutionHeight - (yHistogram[color].rawData[x] * 1);
      }
    );
  }

  //DEBUG_REQUEST("ImageProcessor:Histogram:colorChannelHistogramCr",
  //  drawChannelHist = true;
  //  Vector2<int> last(0, Math::clamp((int)cameraInfo.resolutionHeight - (int) colorChannelHistogramCr[0], 0, (int)cameraInfo.resolutionHeight));
  //  for(unsigned int x = 1; x < COLOR_CHANNEL_VALUE_COUNT; x ++)
  //  {
  //    LINE_PX
  //    (
  //      ColorClasses::red,
  //      last.x,
  //      last.y,
  //      x,
  //      Math::clamp((int)cameraInfo.resolutionHeight - (int) colorChannelHistogramCr[x], 0, (int)cameraInfo.resolutionHeight)
  //    );
  //    last.x = x;
  //    last.y = Math::clamp((int)cameraInfo.resolutionHeight - (int) colorChannelHistogramCr[x], 0, (int)cameraInfo.resolutionHeight);
  //  }
  //);

  //if(drawChannelHist)
  //{
  //  RECT_PX
  //  (
  //    ColorClasses::black,
  //    0,
  //    cameraInfo.resolutionHeight,
  //    COLOR_CHANNEL_VALUE_COUNT,
  //    0
  //  );
  //}

  if(drawXHist)
  {
    RECT_PX(
      ColorClasses::black,
      cameraInfo.resolutionWidth - (grid.width * 1),
      0,
      cameraInfo.resolutionWidth,
      grid.height * 1
    );
  }

  if(drawYHist)
  {
    RECT_PX
    (
      ColorClasses::black,
      0,
      cameraInfo.resolutionHeight - (grid.height * 1),
      (grid.width * 1),
      cameraInfo.resolutionHeight
    );
  }

}//end showDebugInfos

inline void Histograms::createFromColoredGrid(const ColoredGrid& coloredGrid)
{
  for(int color = 0; color < ColorClasses::numOfColors; color++)
  {
    for (unsigned int pixelIndex = 0; pixelIndex < coloredGrid.numberOfColorPoints[color]; pixelIndex++)
    {
      const Vector2<int>& gridPoint = coloredGrid.uniformGrid.getGridCoordinates(pixelIndex);
      increaseValue(gridPoint, (ColorClasses::Color) color);
    }
  }
}//end createFromColoredGrid

void Histograms::print(ostream& stream) const
{
  stream << "Histogram";
}//end print

<|endoftext|>