<commit_before>/*
 * Copyright (C) 2006-2013  Music Technology Group - Universitat Pompeu Fabra
 *
 * This file is part of Essentia
 *
 * Essentia is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation (FSF), either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the Affero GNU General Public License
 * version 3 along with this program.  If not, see http://www.gnu.org/licenses/
 */

#include "FreesoundSfxDescriptors.h"
using namespace std;
using namespace essentia;
using namespace essentia::streaming;

using namespace std;

const string FreesoundSfxDescriptors::nameSpace="sfx.";

  // TODO: normalization of centroids requires array size or duration,
  // not directly available in streaming mode.
  // Can be done at the client for the moment

void  FreesoundSfxDescriptors::createNetwork(SourceBase& source, Pool& pool){

  AlgorithmFactory& factory = AlgorithmFactory::instance();

  // Envelope
  Algorithm* envelope = factory.create("Envelope");
  source >> envelope->input("signal");

  // Temporal Statistics
  Algorithm* decrease = factory.create("Decrease");
  Algorithm* accu = factory.create("RealAccumulator");
  envelope->output("signal") >> accu->input("data");
  accu->output("array") >> decrease->input("array");
  decrease->output("decrease") >> PC(pool, nameSpace + "temporal_decrease");

  // Audio Central Moments Statistics
  Algorithm* cm = factory.create("CentralMoments");
  Algorithm* ds = factory.create("DistributionShape");
  accu->output("array") >> cm->input("array");
  cm->output("centralMoments") >> ds->input("centralMoments");
  ds->output("kurtosis") >> PC(pool, nameSpace + "temporal_kurtosis");
  ds->output("spread") >> PC(pool, nameSpace + "temporal_spread");
  ds->output("skewness") >> PC(pool, nameSpace + "temporal_skewness");

  // Temporal Centroid
  Algorithm* centroid = factory.create("Centroid");
  accu->output("array") >> centroid->input("array");
  centroid->output("centroid") >> PC(pool, nameSpace + "temporal_centroid");

  // Effective Duration
  Algorithm* duration = factory.create("EffectiveDuration");
  accu->output("array") >> duration->input("signal");
  duration->output("effectiveDuration") >> PC(pool, nameSpace + "effective_duration");

  // Log Attack Time
  Algorithm* log = factory.create("LogAttackTime");
  accu->output("array") >> log->input("signal");
  log->output("logAttackTime") >> PC(pool, nameSpace + "logattacktime");

  // Strong Decay
  Algorithm* decay = factory.create("StrongDecay");
  envelope->output("signal") >> decay->input("signal");
  decay->output("strongDecay") >> PC(pool, nameSpace + "strongdecay");

  // Flatness
  Algorithm* flatness = factory.create("FlatnessSFX");
  accu->output("array") >> flatness->input("envelope");
  flatness->output("flatness") >> PC(pool, nameSpace + "flatness");

  // Morphological Descriptors
  Algorithm* max1 = factory.create("MaxToTotal");
  envelope->output("signal") >> max1->input("envelope");
  max1->output("maxToTotal") >> PC(pool, nameSpace + "max_to_total");

  Algorithm* tc = factory.create("TCToTotal");
  envelope->output("signal") >> tc->input("envelope");
  tc->output("TCToTotal") >> PC(pool, nameSpace + "tc_to_total");

  Algorithm* der = factory.create("DerivativeSFX");
  accu->output("array") >> der->input("envelope");
  der->output("derAvAfterMax") >> PC(pool, nameSpace + "der_av_after_max");
  der->output("maxDerBeforeMax") >>  PC(pool, nameSpace + "max_der_before_max");
}

void  FreesoundSfxDescriptors::createPitchNetwork(VectorInput<Real>& pitch, Pool& pool){

  AlgorithmFactory& factory = AlgorithmFactory::instance();

  Algorithm* maxtt = factory.create("MaxToTotal");
  pitch >> maxtt->input("envelope"); // TODO: should we use Envelope?
  maxtt->output("maxToTotal") >>  PC(pool, nameSpace + "pitch_max_to_total");

  Algorithm* mintt = factory.create("MinToTotal");
  pitch >> mintt->input("envelope"); // TODO: should we use Envelope?
  mintt->output("minToTotal") >>  PC(pool, nameSpace + "pitch_min_to_total");

  Algorithm* accu = factory.create("RealAccumulator");
  pitch >> accu->input("data");

  Algorithm* pc = factory.create("Centroid");

  accu->output("array") >> pc->input("array");
  pc->output("centroid") >>  PC(pool, nameSpace + "pitch_centroid");

  Algorithm* amt = factory.create("AfterMaxToBeforeMaxEnergyRatio");
  pitch >> amt->input("pitch");
  amt->output("afterMaxToBeforeMaxEnergyRatio") >>  PC(pool, nameSpace + "pitch_after_max_to_before_max_energy_ratio");

}

void  FreesoundSfxDescriptors::createHarmonicityNetwork(SourceBase& source, Pool& pool){

  AlgorithmFactory& factory = AlgorithmFactory::instance();

  //Real sampleRate = 44100;
  int frameSize =   2048;
  int hopSize =     1024;
  int zeroPadding = 0;
  string silentFrames ="noise";
  string windowType = "blackmanharris62";

  // FrameCutter
  Algorithm* fc = factory.create("FrameCutter",
                                 "frameSize", frameSize,
                                 "hopSize", hopSize,
                                 "silentFrames", silentFrames);

  source >> fc->input("signal");

  // Windowing
  Algorithm* w = factory.create("Windowing",
                                "type", windowType,
                                "zeroPadding", zeroPadding);

  fc->output("frame") >> w->input("frame");

  // Spectrum
  Algorithm* spec = factory.create("Spectrum");
  w->output("frame") >> spec->input("frame");

  Algorithm* harmPeaks = factory.create("HarmonicPeaks");
  Algorithm* peaks = factory.create("SpectralPeaks",
                                    "orderBy", "frequency","minFrequency", 20);
  spec->output("spectrum") >> peaks->input("spectrum");

  // Pitch Detection
  Algorithm* pitch = factory.create("PitchYinFFT",
                                    "frameSize", frameSize);
  spec->output("spectrum") >> pitch->input("spectrum");
  pitch->output("pitchConfidence") >> NOWHERE;

  peaks->output("frequencies") >> harmPeaks->input("frequencies");

  peaks->output("magnitudes") >> harmPeaks->input("magnitudes");
  pitch->output("pitch") >> harmPeaks->input("pitch");

  Algorithm* odd2even = factory.create("OddToEvenHarmonicEnergyRatio");
  Algorithm* tristimulus = factory.create("Tristimulus");
  Algorithm* inharmonicity = factory.create("Inharmonicity");

  // inputs
  harmPeaks->output("harmonicFrequencies") >> tristimulus->input("frequencies");
  harmPeaks->output("harmonicMagnitudes")  >>  tristimulus->input("magnitudes");
  harmPeaks->output("harmonicFrequencies") >> odd2even->input("frequencies");
  harmPeaks->output("harmonicMagnitudes")  >> odd2even->input("magnitudes");
  harmPeaks->output("harmonicFrequencies") >> inharmonicity->input("frequencies");
  harmPeaks->output("harmonicMagnitudes")  >> inharmonicity->input("magnitudes");

  // outputs
  inharmonicity->output("inharmonicity") >> PC(pool, nameSpace + "inharmonicity");
  odd2even->output("oddToEvenHarmonicEnergyRatio") >> PC(pool, nameSpace + "oddtoevenharmonicenergyratio");
  tristimulus->output("tristimulus") >> PC(pool, nameSpace + "tristimulus");
}<commit_msg>added duration descriptor<commit_after>/*
 * Copyright (C) 2006-2013  Music Technology Group - Universitat Pompeu Fabra
 *
 * This file is part of Essentia
 *
 * Essentia is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation (FSF), either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the Affero GNU General Public License
 * version 3 along with this program.  If not, see http://www.gnu.org/licenses/
 */

#include "FreesoundSfxDescriptors.h"
using namespace std;
using namespace essentia;
using namespace essentia::streaming;

using namespace std;

const string FreesoundSfxDescriptors::nameSpace="sfx.";

  // TODO: normalization of centroids requires array size or duration,
  // not directly available in streaming mode.
  // Can be done at the client for the moment

void  FreesoundSfxDescriptors::createNetwork(SourceBase& source, Pool& pool){

  AlgorithmFactory& factory = AlgorithmFactory::instance();

  // Envelope
  Algorithm* envelope = factory.create("Envelope");
  source >> envelope->input("signal");

  // Temporal Statistics
  Algorithm* decrease = factory.create("Decrease");
  Algorithm* accu = factory.create("RealAccumulator");
  envelope->output("signal") >> accu->input("data");
  accu->output("array") >> decrease->input("array");
  decrease->output("decrease") >> PC(pool, nameSpace + "temporal_decrease");

  // Audio Central Moments Statistics
  Algorithm* cm = factory.create("CentralMoments");
  Algorithm* ds = factory.create("DistributionShape");
  accu->output("array") >> cm->input("array");
  cm->output("centralMoments") >> ds->input("centralMoments");
  ds->output("kurtosis") >> PC(pool, nameSpace + "temporal_kurtosis");
  ds->output("spread") >> PC(pool, nameSpace + "temporal_spread");
  ds->output("skewness") >> PC(pool, nameSpace + "temporal_skewness");

  // Temporal Centroid
  Algorithm* centroid = factory.create("Centroid");
  accu->output("array") >> centroid->input("array");
  centroid->output("centroid") >> PC(pool, nameSpace + "temporal_centroid");

  // Duration
  Algorithm* duration = factory.create("Duration");
  source >> duration->input("signal");
  duration->output("duration") >> PC(pool, nameSpace + "duration");

  // Effective Duration
  Algorithm* effective_duration = factory.create("EffectiveDuration");
  accu->output("array") >> effective_duration->input("signal");
  effective_duration->output("effectiveDuration") >> PC(pool, nameSpace + "effective_duration");

  // Log Attack Time
  Algorithm* log = factory.create("LogAttackTime");
  accu->output("array") >> log->input("signal");
  log->output("logAttackTime") >> PC(pool, nameSpace + "logattacktime");

  // Strong Decay
  Algorithm* decay = factory.create("StrongDecay");
  envelope->output("signal") >> decay->input("signal");
  decay->output("strongDecay") >> PC(pool, nameSpace + "strongdecay");

  // Flatness
  Algorithm* flatness = factory.create("FlatnessSFX");
  accu->output("array") >> flatness->input("envelope");
  flatness->output("flatness") >> PC(pool, nameSpace + "flatness");

  // Morphological Descriptors
  Algorithm* max1 = factory.create("MaxToTotal");
  envelope->output("signal") >> max1->input("envelope");
  max1->output("maxToTotal") >> PC(pool, nameSpace + "max_to_total");

  Algorithm* tc = factory.create("TCToTotal");
  envelope->output("signal") >> tc->input("envelope");
  tc->output("TCToTotal") >> PC(pool, nameSpace + "tc_to_total");

  Algorithm* der = factory.create("DerivativeSFX");
  accu->output("array") >> der->input("envelope");
  der->output("derAvAfterMax") >> PC(pool, nameSpace + "der_av_after_max");
  der->output("maxDerBeforeMax") >>  PC(pool, nameSpace + "max_der_before_max");
}

void  FreesoundSfxDescriptors::createPitchNetwork(VectorInput<Real>& pitch, Pool& pool){

  AlgorithmFactory& factory = AlgorithmFactory::instance();

  Algorithm* maxtt = factory.create("MaxToTotal");
  pitch >> maxtt->input("envelope"); // TODO: should we use Envelope?
  maxtt->output("maxToTotal") >>  PC(pool, nameSpace + "pitch_max_to_total");

  Algorithm* mintt = factory.create("MinToTotal");
  pitch >> mintt->input("envelope"); // TODO: should we use Envelope?
  mintt->output("minToTotal") >>  PC(pool, nameSpace + "pitch_min_to_total");

  Algorithm* accu = factory.create("RealAccumulator");
  pitch >> accu->input("data");

  Algorithm* pc = factory.create("Centroid");

  accu->output("array") >> pc->input("array");
  pc->output("centroid") >>  PC(pool, nameSpace + "pitch_centroid");

  Algorithm* amt = factory.create("AfterMaxToBeforeMaxEnergyRatio");
  pitch >> amt->input("pitch");
  amt->output("afterMaxToBeforeMaxEnergyRatio") >>  PC(pool, nameSpace + "pitch_after_max_to_before_max_energy_ratio");

}

void  FreesoundSfxDescriptors::createHarmonicityNetwork(SourceBase& source, Pool& pool){

  AlgorithmFactory& factory = AlgorithmFactory::instance();

  //Real sampleRate = 44100;
  int frameSize =   2048;
  int hopSize =     1024;
  int zeroPadding = 0;
  string silentFrames ="noise";
  string windowType = "blackmanharris62";

  // FrameCutter
  Algorithm* fc = factory.create("FrameCutter",
                                 "frameSize", frameSize,
                                 "hopSize", hopSize,
                                 "silentFrames", silentFrames);

  source >> fc->input("signal");

  // Windowing
  Algorithm* w = factory.create("Windowing",
                                "type", windowType,
                                "zeroPadding", zeroPadding);

  fc->output("frame") >> w->input("frame");

  // Spectrum
  Algorithm* spec = factory.create("Spectrum");
  w->output("frame") >> spec->input("frame");

  Algorithm* harmPeaks = factory.create("HarmonicPeaks");
  Algorithm* peaks = factory.create("SpectralPeaks",
                                    "orderBy", "frequency","minFrequency", 20);
  spec->output("spectrum") >> peaks->input("spectrum");

  // Pitch Detection
  Algorithm* pitch = factory.create("PitchYinFFT",
                                    "frameSize", frameSize);
  spec->output("spectrum") >> pitch->input("spectrum");
  pitch->output("pitchConfidence") >> NOWHERE;

  peaks->output("frequencies") >> harmPeaks->input("frequencies");

  peaks->output("magnitudes") >> harmPeaks->input("magnitudes");
  pitch->output("pitch") >> harmPeaks->input("pitch");

  Algorithm* odd2even = factory.create("OddToEvenHarmonicEnergyRatio");
  Algorithm* tristimulus = factory.create("Tristimulus");
  Algorithm* inharmonicity = factory.create("Inharmonicity");

  // inputs
  harmPeaks->output("harmonicFrequencies") >> tristimulus->input("frequencies");
  harmPeaks->output("harmonicMagnitudes")  >>  tristimulus->input("magnitudes");
  harmPeaks->output("harmonicFrequencies") >> odd2even->input("frequencies");
  harmPeaks->output("harmonicMagnitudes")  >> odd2even->input("magnitudes");
  harmPeaks->output("harmonicFrequencies") >> inharmonicity->input("frequencies");
  harmPeaks->output("harmonicMagnitudes")  >> inharmonicity->input("magnitudes");

  // outputs
  inharmonicity->output("inharmonicity") >> PC(pool, nameSpace + "inharmonicity");
  odd2even->output("oddToEvenHarmonicEnergyRatio") >> PC(pool, nameSpace + "oddtoevenharmonicenergyratio");
  tristimulus->output("tristimulus") >> PC(pool, nameSpace + "tristimulus");
}<|endoftext|>


<commit_before>#ifndef SILICIUM_ERASED_OBSERVER_HPP
#define SILICIUM_ERASED_OBSERVER_HPP

#include <silicium/observable/observer.hpp>

namespace Si
{
	template <class Element>
	struct erased_observer
	{
		typedef Element element_type;

		erased_observer() BOOST_NOEXCEPT
		{
		}

		template <class Observer>
		explicit erased_observer(Observer &&observer)
			: m_original(Si::to_unique(Si::virtualize_observer(std::forward<Observer>(observer))))
		{
		}

#if SILICIUM_COMPILER_GENERATES_MOVES
		erased_observer(erased_observer &&) BOOST_NOEXCEPT = default;
		erased_observer &operator = (erased_observer &&) BOOST_NOEXCEPT = default;
#else
		erased_observer(erased_observer &&other) BOOST_NOEXCEPT
			: m_original(std::move(other.m_original))
		{
		}

		erased_observer &operator = (erased_observer &&other)BOOST_NOEXCEPT
		{
			m_original = std::move(other.m_original);
			return *this;
		}
#endif

		void got_element(Element element)
		{
			assert(m_original);
			m_original->got_element(std::move(element));
		}

		void ended()
		{
			assert(m_original);
			m_original->ended();
		}

		observer<Element> *get() const BOOST_NOEXCEPT
		{
			return m_original.get();
		}

	private:

		std::unique_ptr<observer<Element>> m_original;

		SILICIUM_DELETED_FUNCTION(erased_observer(erased_observer const &))
		SILICIUM_DELETED_FUNCTION(erased_observer &operator = (erased_observer const &))
	};
}

#endif
<commit_msg>add missing include<commit_after>#ifndef SILICIUM_ERASED_OBSERVER_HPP
#define SILICIUM_ERASED_OBSERVER_HPP

#include <silicium/observable/observer.hpp>
#include <silicium/to_unique.hpp>

namespace Si
{
	template <class Element>
	struct erased_observer
	{
		typedef Element element_type;

		erased_observer() BOOST_NOEXCEPT
		{
		}

		template <class Observer>
		explicit erased_observer(Observer &&observer)
			: m_original(to_unique(virtualize_observer(std::forward<Observer>(observer))))
		{
		}

#if SILICIUM_COMPILER_GENERATES_MOVES
		erased_observer(erased_observer &&) BOOST_NOEXCEPT = default;
		erased_observer &operator = (erased_observer &&) BOOST_NOEXCEPT = default;
#else
		erased_observer(erased_observer &&other) BOOST_NOEXCEPT
			: m_original(std::move(other.m_original))
		{
		}

		erased_observer &operator = (erased_observer &&other)BOOST_NOEXCEPT
		{
			m_original = std::move(other.m_original);
			return *this;
		}
#endif

		void got_element(Element element)
		{
			assert(m_original);
			m_original->got_element(std::move(element));
		}

		void ended()
		{
			assert(m_original);
			m_original->ended();
		}

		observer<Element> *get() const BOOST_NOEXCEPT
		{
			return m_original.get();
		}

	private:

		std::unique_ptr<observer<Element>> m_original;

		SILICIUM_DELETED_FUNCTION(erased_observer(erased_observer const &))
		SILICIUM_DELETED_FUNCTION(erased_observer &operator = (erased_observer const &))
	};
}

#endif
<|endoftext|>


<commit_before>#ifndef __Data__
#define __Data__

#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>    // has the for_each

using namespace std;

string tostring(int i) {
	ostringstream tmp;
	tmp << i;
	return tmp.str();
}

int stringToInt(string const& str) {
  istringstream i(str);
  int x;
  i >> x;
  return x;
}

float stringToFloat(string const& str) {
  istringstream i(str);
  float x;
  i >> x;
  return x;
}

vector<string> &split(const string &s, char delim, vector<string> &elems) {
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

vector<string> split(const string &s, char delim) {
	// taken from http://stackoverflow.com/a/236803
    vector<string> elems;
    split(s, delim, elems);
    return elems;
}

void removeAllQuotes(char *str) {
	// originally taken from http://stackoverflow.com/a/7144045
	int len = strlen(str);
	char lineWithoutQuotes[len];
	int i, j;
	if (str[0] != '"')
		lineWithoutQuotes[0] = str[0];
	for (i = j = 1; i < strlen(str); i++){
		if (str[i] == '"' && str[i-1] != '\\')
			continue;
		lineWithoutQuotes[j++] = str[i];
	}
	strcpy(str, lineWithoutQuotes);
}

enum GenEd {
	// Foundation Studies
	FYW,   // First-Year Writing
	WRI,   // Writing in Context
	FOL,   // Foreign Language
	ORC,   // Oral Communication
	AQR,   // Abstract and Quantitative Reasoning
	SPM,   // Studies in Physical Movement

	// Core Studies
	HWC,   // Historical Studies in Western Culture
	MCD,   // Multicultural Studies: Domestic
	MCG,   // Multicultural Studies: Global
	ALSA,  // Artistic and Literary Studies: Artistic Studies
	ALSL,  // Artistic and Literary Studies: Literary Studies
	BTSB,  // Biblical and Theological Studies: Bible
	BTST,  // Biblical and Theological Studies: Theology
	SED,   // Studies in Natural Science: Scientific Exploration and Discovery
	IST,   // Studies in Natural Science: Integrated Scientific Topics
	HBS,   // Studies in Human Behavior and Society

	// Integrative Studies
	EIN    // Ethical Issues and Normative Perspectives
};

struct Instructor {
	string name;
	string specialty;
};

struct Department {
	string name;
	string shorthand;
};

struct Major {
	string name;
	int difficulty;
};

struct Concentration {
	string name;
	int difficulty;
};

struct Conversation {
	string name;
	int difficulty;
};

class Course {
protected:
	string ID;
	int number;
	string title;
	string description;
	char section;

	vector<Major> majors;
	Department department;
	vector<Concentration> concentrations;
	vector<Conversation> conversations;
	vector<Instructor> professor;

	int half_semester;
	bool pass_fail;
	float credits;
	string location;

	bool lab;
	GenEd* geneds;

	bool days[7];
	float time[7];
public:
	Course(istream &is) {
		if (is == 0) return;
		string tmpLine;
		getline(is, tmpLine);
		vector<string> record = split(tmpLine, ',');

		// Ignore the first column;
		record.at(0);

		// Second column has the course ID,
		number = stringToInt(record.at(1));

		// Third column has the section,
		section = record.at(2)[0];

		// Fourth holds the lab boolean,
		if (record.at(3).empty())
			lab = false;
		else
			lab = true;

		// while Fifth contains the title of the course;
		title = record.at(4);

		// Sixth hands over the length (half semester or not)
		// it's actually an int that tells us how many times the course is offered per semester.
		half_semester = stringToInt(record.at(5));

		// Seventh tells us the number of credits,
		credits = stringToFloat(record.at(6));

		// Eighth shows us if it can be taken pass/no-pass,
		if (record.at(7) == "Y")
			pass_fail = true;
		else
			pass_fail = false;

		// while Nine gives us the GEs of the course,
		// GEreqs = record.at(9);

		// and Ten spits out the days and times;
		// Times = record.at(10);

		// Eleven holds the location,
		location = record.at(11);

		// and Twelve knows who teaches.
		// Instructors = record.at(12);
	}
	void parseID(char* str) {
		string tmp = str;
		ID = tmp;
		// TODO: do this.
	}
	void updateID() {
		ID = department.shorthand + tostring(number) + section;
	}
	string getID() {
		return ID;
	}

	ostream& getData(ostream &os) {
		os << ID << " ";
		os << title << "/";
		for (vector<Instructor>::iterator i = professor.begin(); i != professor.end(); ++i) {
			os << i->name << " ";
		}
		return os;
	}
	void display();
};

ostream &operator<<(ostream &os, Course &item) { return item.getData(os); }
void Course::display() { cout << *this << endl; }

void spit(Course n) {
	n.display();
}

class Student {
public:
	string name;
	vector<Course> takenCourses;
	vector<Major> majors;
	vector<Concentration> concentrations;
	vector<Conversation> conversations;
	vector<Instructor> favInstructors;

	string interests;
	double gradYear;

	ostream& getData(ostream &os) {
		os << name << " ";

		for (vector<Course>::iterator i = takenCourses.begin(); i != takenCourses.end(); ++i)
			os << i->getID() << " ";

		for (vector<Major>::iterator i = majors.begin(); i != majors.end(); ++i)
			os << i->name << " ";

		return os;
	}
	void display();
};

#endif
<commit_msg>Apparently removeAllQuotes doesn't like strcpy or strlen.<commit_after>#ifndef __Data__
#define __Data__

#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>    // has the for_each

using namespace std;

string tostring(int i) {
	ostringstream tmp;
	tmp << i;
	return tmp.str();
}

int stringToInt(string const& str) {
  istringstream i(str);
  int x;
  i >> x;
  return x;
}

float stringToFloat(string const& str) {
  istringstream i(str);
  float x;
  i >> x;
  return x;
}

vector<string> &split(const string &s, char delim, vector<string> &elems) {
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

vector<string> split(const string &s, char delim) {
	// taken from http://stackoverflow.com/a/236803
    vector<string> elems;
    split(s, delim, elems);
    return elems;
}

// void removeAllQuotes(char *str) {
// 	// originally taken from http://stackoverflow.com/a/7144045
// 	int len = strlen(str);
// 	char lineWithoutQuotes[len];
// 	int i, j;
// 	if (str[0] != '"')
// 		lineWithoutQuotes[0] = str[0];
// 	for (i = j = 1; i < strlen(str); i++){
// 		if (str[i] == '"' && str[i-1] != '\\')
// 			continue;
// 		lineWithoutQuotes[j++] = str[i];
// 	}
// 	strcpy(str, lineWithoutQuotes);
// }

enum GenEd {
	// Foundation Studies
	FYW,   // First-Year Writing
	WRI,   // Writing in Context
	FOL,   // Foreign Language
	ORC,   // Oral Communication
	AQR,   // Abstract and Quantitative Reasoning
	SPM,   // Studies in Physical Movement

	// Core Studies
	HWC,   // Historical Studies in Western Culture
	MCD,   // Multicultural Studies: Domestic
	MCG,   // Multicultural Studies: Global
	ALSA,  // Artistic and Literary Studies: Artistic Studies
	ALSL,  // Artistic and Literary Studies: Literary Studies
	BTSB,  // Biblical and Theological Studies: Bible
	BTST,  // Biblical and Theological Studies: Theology
	SED,   // Studies in Natural Science: Scientific Exploration and Discovery
	IST,   // Studies in Natural Science: Integrated Scientific Topics
	HBS,   // Studies in Human Behavior and Society

	// Integrative Studies
	EIN    // Ethical Issues and Normative Perspectives
};

struct Instructor {
	string name;
	string specialty;
};

struct Department {
	string name;
	string shorthand;
};

struct Major {
	string name;
	int difficulty;
};

struct Concentration {
	string name;
	int difficulty;
};

struct Conversation {
	string name;
	int difficulty;
};

class Course {
protected:
	string ID;
	int number;
	string title;
	string description;
	char section;

	vector<Major> majors;
	Department department;
	vector<Concentration> concentrations;
	vector<Conversation> conversations;
	vector<Instructor> professor;

	int half_semester;
	bool pass_fail;
	float credits;
	string location;

	bool lab;
	GenEd* geneds;

	bool days[7];
	float time[7];
public:
	Course(istream &is) {
		if (is == 0) return;
		string tmpLine;
		getline(is, tmpLine);
		vector<string> record = split(tmpLine, ',');

		// Ignore the first column;
		record.at(0);

		// Second column has the course ID,
		number = stringToInt(record.at(1));

		// Third column has the section,
		section = record.at(2)[0];

		// Fourth holds the lab boolean,
		if (record.at(3).empty())
			lab = false;
		else
			lab = true;

		// while Fifth contains the title of the course;
		title = record.at(4);

		// Sixth hands over the length (half semester or not)
		// it's actually an int that tells us how many times the course is offered per semester.
		half_semester = stringToInt(record.at(5));

		// Seventh tells us the number of credits,
		credits = stringToFloat(record.at(6));

		// Eighth shows us if it can be taken pass/no-pass,
		if (record.at(7) == "Y")
			pass_fail = true;
		else
			pass_fail = false;

		// while Nine gives us the GEs of the course,
		// GEreqs = record.at(9);

		// and Ten spits out the days and times;
		// Times = record.at(10);

		// Eleven holds the location,
		location = record.at(11);

		// and Twelve knows who teaches.
		// Instructors = record.at(12);
	}
	void parseID(char* str) {
		string tmp = str;
		ID = tmp;
		// TODO: do this.
	}
	void updateID() {
		ID = department.shorthand + tostring(number) + section;
	}
	string getID() {
		return ID;
	}

	ostream& getData(ostream &os) {
		os << ID << " ";
		os << title << "/";
		for (vector<Instructor>::iterator i = professor.begin(); i != professor.end(); ++i) {
			os << i->name << " ";
		}
		return os;
	}
	void display();
};

ostream &operator<<(ostream &os, Course &item) { return item.getData(os); }
void Course::display() { cout << *this << endl; }

void spit(Course n) {
	n.display();
}

class Student {
public:
	string name;
	vector<Course> takenCourses;
	vector<Major> majors;
	vector<Concentration> concentrations;
	vector<Conversation> conversations;
	vector<Instructor> favInstructors;

	string interests;
	double gradYear;

	ostream& getData(ostream &os) {
		os << name << " ";

		for (vector<Course>::iterator i = takenCourses.begin(); i != takenCourses.end(); ++i)
			os << i->getID() << " ";

		for (vector<Major>::iterator i = majors.begin(); i != majors.end(); ++i)
			os << i->name << " ";

		return os;
	}
	void display();
};

#endif
<|endoftext|>


<commit_before>// Copyright Daniel Wallin, Arvid Norberg 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/session.hpp>
#include <libtorrent/torrent.hpp>
#include <libtorrent/storage.hpp>
#include <boost/python.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

extern char const* session_status_doc;
extern char const* session_status_has_incoming_connections_doc;
extern char const* session_status_upload_rate_doc;
extern char const* session_status_download_rate_doc;
extern char const* session_status_payload_upload_rate_doc;
extern char const* session_status_payload_download_rate_doc;
extern char const* session_status_total_download_doc;
extern char const* session_status_total_upload_doc;
extern char const* session_status_total_payload_download_doc;
extern char const* session_status_total_payload_upload_doc;
extern char const* session_status_num_peers_doc;
extern char const* session_status_dht_nodes_doc;
extern char const* session_status_cache_nodes_doc;
extern char const* session_status_dht_torrents_doc;

extern char const* session_doc;
extern char const* session_init_doc;
extern char const* session_listen_on_doc;
extern char const* session_is_listening_doc;
extern char const* session_listen_port_doc;
extern char const* session_status_m_doc;
extern char const* session_start_dht_doc;
extern char const* session_stop_dht_doc;
extern char const* session_dht_state_doc;
extern char const* session_add_torrent_doc;
extern char const* session_remove_torrent_doc;
extern char const* session_set_download_rate_limit_doc;
extern char const* session_download_rate_limit_doc;
extern char const* session_set_upload_rate_limit_doc;
extern char const* session_upload_rate_limit_doc;
extern char const* session_set_max_uploads_doc;
extern char const* session_set_max_connections_doc;
extern char const* session_set_max_half_open_connections_doc;
extern char const* session_num_connections_doc;
extern char const* session_set_settings_doc;
extern char const* session_set_pe_settings_doc;
extern char const* session_get_pe_settings_doc;
extern char const* session_set_severity_level_doc;
extern char const* session_pop_alert_doc;
extern char const* session_start_upnp_doc;
extern char const* session_stop_upnp_doc;
extern char const* session_start_natpmp_doc;
extern char const* session_stop_natpmp_doc;

namespace
{

  bool listen_on(session& s, int min_, int max_, char const* interface)
  {
      allow_threading_guard guard;
      return s.listen_on(std::make_pair(min_, max_), interface);
  }

  struct invoke_extension_factory
  {
      invoke_extension_factory(object const& callback)
        : cb(callback)
      {}

      boost::shared_ptr<torrent_plugin> operator()(torrent* t, void*)
      {
          lock_gil lock;
          return extract<boost::shared_ptr<torrent_plugin> >(cb(ptr(t)))();
      }

      object cb;
  };

  void add_extension(session& s, object const& e)
  {
      allow_threading_guard guard;
      s.add_extension(invoke_extension_factory(e));
  }

  torrent_handle add_torrent(session& s, torrent_info const& ti
    , boost::filesystem::path const& save, entry const& resume
    , storage_mode_t storage_mode, bool paused)
  {
    allow_threading_guard guard;
    return s.add_torrent(ti, save, resume, storage_mode, paused, default_storage_constructor);
  }

} // namespace unnamed

void bind_session()
{
    class_<session_status>("session_status", session_status_doc)
        .def_readonly(
            "has_incoming_connections", &session_status::has_incoming_connections
          , session_status_has_incoming_connections_doc
        )
        .def_readonly(
            "upload_rate", &session_status::upload_rate
          , session_status_upload_rate_doc
        )
        .def_readonly(
            "download_rate", &session_status::download_rate
          , session_status_download_rate_doc
        )
        .def_readonly(
            "payload_upload_rate", &session_status::payload_upload_rate
          , session_status_payload_upload_rate_doc
        )
        .def_readonly(
            "payload_download_rate", &session_status::payload_download_rate
          , session_status_payload_download_rate_doc
        )
        .def_readonly(
            "total_download", &session_status::total_download
          , session_status_total_download_doc
        )
        .def_readonly(
            "total_upload", &session_status::total_upload
          , session_status_total_upload_doc
        )
        .def_readonly(
            "total_payload_download", &session_status::total_payload_download
          , session_status_total_payload_download_doc
        )
        .def_readonly(
            "total_payload_upload", &session_status::total_payload_upload
          , session_status_total_payload_upload_doc
        )
        .def_readonly(
            "num_peers", &session_status::num_peers
          , session_status_num_peers_doc
        )
#ifndef TORRENT_DISABLE_DHT
        .def_readonly(
            "dht_nodes", &session_status::dht_nodes
          , session_status_dht_nodes_doc
        )
        .def_readonly(
            "dht_cache_nodes", &session_status::dht_node_cache
          , session_status_cache_nodes_doc
        )
        .def_readonly(
            "dht_torrents", &session_status::dht_torrents
          , session_status_dht_torrents_doc
        )
#endif
        ;

    enum_<storage_mode_t>("storage_mode_t")
        .value("storage_mode_allocate", storage_mode_allocate)
        .value("storage_mode_compact", storage_mode_compact)
        .value("storage_mode_sparse", storage_mode_sparse)
    ;

    enum_<session::options_t>("options_t")
        .value("none", session::none)
        .value("delete_files", session::delete_files)
    ;

    class_<session, boost::noncopyable>("session", session_doc, no_init)
        .def(
            init<fingerprint>(arg("fingerprint")=fingerprint("LT",0,1,0,0), session_init_doc)
        )
        .def(
            "listen_on", &listen_on
          , (arg("min"), "max", arg("interface") = (char const*)0)
          , session_listen_on_doc
        )
        .def("is_listening", allow_threads(&session::is_listening), session_is_listening_doc)
        .def("listen_port", allow_threads(&session::listen_port), session_listen_port_doc)
        .def("status", allow_threads(&session::status), session_status_m_doc)
#ifndef TORRENT_DISABLE_DHT
        .def("start_dht", allow_threads(&session::start_dht), session_start_dht_doc)
        .def("stop_dht", allow_threads(&session::stop_dht), session_stop_dht_doc)
        .def("dht_state", allow_threads(&session::dht_state), session_dht_state_doc)
#endif
        .def(
            "add_torrent", &add_torrent
          , (
                arg("resume_data") = entry(), arg("compact_mode") = true
                , arg("paused") = false
            )
          , session_add_torrent_doc
        )
        .def("remove_torrent", allow_threads(&session::remove_torrent), session_remove_torrent_doc)
        .def(
            "set_download_rate_limit", allow_threads(&session::set_download_rate_limit)
          , session_set_download_rate_limit_doc
        )
        .def(
            "download_rate_limit", allow_threads(&session::download_rate_limit)
          , session_download_rate_limit_doc
        )

        .def(
            "set_upload_rate_limit", allow_threads(&session::set_upload_rate_limit)
          , session_set_upload_rate_limit_doc
        )
        .def(
            "upload_rate_limit", allow_threads(&session::upload_rate_limit)
          , session_upload_rate_limit_doc
        )

        .def(
            "set_max_uploads", allow_threads(&session::set_max_uploads)
          , session_set_max_uploads_doc
        )
        .def(
            "set_max_connections", allow_threads(&session::set_max_connections)
          , session_set_max_connections_doc
        )
        .def(
            "set_max_half_open_connections", allow_threads(&session::set_max_half_open_connections)
          , session_set_max_half_open_connections_doc
        )
        .def(
            "num_connections", allow_threads(&session::num_connections)
          , session_num_connections_doc
        )
        .def("set_settings", allow_threads(&session::set_settings), session_set_settings_doc)
        .def("set_pe_settings", allow_threads(&session::set_pe_settings), session_set_pe_settings_doc)
        .def("get_pe_settings", allow_threads(&session::get_pe_settings), return_value_policy<copy_const_reference>())
        .def(
            "set_severity_level", allow_threads(&session::set_severity_level)
          , session_set_severity_level_doc
        )
        .def("pop_alert", allow_threads(&session::pop_alert), session_pop_alert_doc)
        .def("add_extension", &add_extension)
        .def("set_peer_proxy", allow_threads(&session::set_peer_proxy))
        .def("set_tracker_proxy", allow_threads(&session::set_tracker_proxy))
        .def("set_web_seed_proxy", allow_threads(&session::set_web_seed_proxy))
#ifndef TORRENT_DISABLE_DHT
        .def("set_dht_proxy", allow_threads(&session::set_dht_proxy))
#endif
        .def("start_upnp", allow_threads(&session::start_upnp), session_start_upnp_doc)
        .def("stop_upnp", allow_threads(&session::stop_upnp), session_stop_upnp_doc)
        .def("start_natpmp", allow_threads(&session::start_natpmp), session_start_natpmp_doc)
        .def("stop_natpmp", allow_threads(&session::stop_natpmp), session_stop_natpmp_doc)
        ;

    register_ptr_to_python<std::auto_ptr<alert> >();
}

<commit_msg>python binding fix<commit_after>// Copyright Daniel Wallin, Arvid Norberg 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <libtorrent/session.hpp>
#include <libtorrent/torrent.hpp>
#include <libtorrent/storage.hpp>
#include <boost/python.hpp>
#include "gil.hpp"

using namespace boost::python;
using namespace libtorrent;

extern char const* session_status_doc;
extern char const* session_status_has_incoming_connections_doc;
extern char const* session_status_upload_rate_doc;
extern char const* session_status_download_rate_doc;
extern char const* session_status_payload_upload_rate_doc;
extern char const* session_status_payload_download_rate_doc;
extern char const* session_status_total_download_doc;
extern char const* session_status_total_upload_doc;
extern char const* session_status_total_payload_download_doc;
extern char const* session_status_total_payload_upload_doc;
extern char const* session_status_num_peers_doc;
extern char const* session_status_dht_nodes_doc;
extern char const* session_status_cache_nodes_doc;
extern char const* session_status_dht_torrents_doc;

extern char const* session_doc;
extern char const* session_init_doc;
extern char const* session_listen_on_doc;
extern char const* session_is_listening_doc;
extern char const* session_listen_port_doc;
extern char const* session_status_m_doc;
extern char const* session_start_dht_doc;
extern char const* session_stop_dht_doc;
extern char const* session_dht_state_doc;
extern char const* session_add_torrent_doc;
extern char const* session_remove_torrent_doc;
extern char const* session_set_download_rate_limit_doc;
extern char const* session_download_rate_limit_doc;
extern char const* session_set_upload_rate_limit_doc;
extern char const* session_upload_rate_limit_doc;
extern char const* session_set_max_uploads_doc;
extern char const* session_set_max_connections_doc;
extern char const* session_set_max_half_open_connections_doc;
extern char const* session_num_connections_doc;
extern char const* session_set_settings_doc;
extern char const* session_set_pe_settings_doc;
extern char const* session_get_pe_settings_doc;
extern char const* session_set_severity_level_doc;
extern char const* session_pop_alert_doc;
extern char const* session_start_upnp_doc;
extern char const* session_stop_upnp_doc;
extern char const* session_start_natpmp_doc;
extern char const* session_stop_natpmp_doc;

namespace
{

  bool listen_on(session& s, int min_, int max_, char const* interface)
  {
      allow_threading_guard guard;
      return s.listen_on(std::make_pair(min_, max_), interface);
  }

  struct invoke_extension_factory
  {
      invoke_extension_factory(object const& callback)
        : cb(callback)
      {}

      boost::shared_ptr<torrent_plugin> operator()(torrent* t, void*)
      {
          lock_gil lock;
          return extract<boost::shared_ptr<torrent_plugin> >(cb(ptr(t)))();
      }

      object cb;
  };

  void add_extension(session& s, object const& e)
  {
      allow_threading_guard guard;
      s.add_extension(invoke_extension_factory(e));
  }

  torrent_handle add_torrent(session& s, torrent_info const& ti
    , boost::filesystem::path const& save, entry const& resume
    , storage_mode_t storage_mode, bool paused)
  {
    allow_threading_guard guard;
    return s.add_torrent(ti, save, resume, storage_mode, paused, default_storage_constructor);
  }

} // namespace unnamed

void bind_session()
{
    class_<session_status>("session_status", session_status_doc)
        .def_readonly(
            "has_incoming_connections", &session_status::has_incoming_connections
          , session_status_has_incoming_connections_doc
        )
        .def_readonly(
            "upload_rate", &session_status::upload_rate
          , session_status_upload_rate_doc
        )
        .def_readonly(
            "download_rate", &session_status::download_rate
          , session_status_download_rate_doc
        )
        .def_readonly(
            "payload_upload_rate", &session_status::payload_upload_rate
          , session_status_payload_upload_rate_doc
        )
        .def_readonly(
            "payload_download_rate", &session_status::payload_download_rate
          , session_status_payload_download_rate_doc
        )
        .def_readonly(
            "total_download", &session_status::total_download
          , session_status_total_download_doc
        )
        .def_readonly(
            "total_upload", &session_status::total_upload
          , session_status_total_upload_doc
        )
        .def_readonly(
            "total_payload_download", &session_status::total_payload_download
          , session_status_total_payload_download_doc
        )
        .def_readonly(
            "total_payload_upload", &session_status::total_payload_upload
          , session_status_total_payload_upload_doc
        )
        .def_readonly(
            "num_peers", &session_status::num_peers
          , session_status_num_peers_doc
        )
#ifndef TORRENT_DISABLE_DHT
        .def_readonly(
            "dht_nodes", &session_status::dht_nodes
          , session_status_dht_nodes_doc
        )
        .def_readonly(
            "dht_cache_nodes", &session_status::dht_node_cache
          , session_status_cache_nodes_doc
        )
        .def_readonly(
            "dht_torrents", &session_status::dht_torrents
          , session_status_dht_torrents_doc
        )
#endif
        ;

    enum_<storage_mode_t>("storage_mode_t")
        .value("storage_mode_allocate", storage_mode_allocate)
        .value("storage_mode_compact", storage_mode_compact)
        .value("storage_mode_sparse", storage_mode_sparse)
    ;

    enum_<session::options_t>("options_t")
        .value("none", session::none)
        .value("delete_files", session::delete_files)
    ;

    class_<session, boost::noncopyable>("session", session_doc, no_init)
        .def(
            init<fingerprint>(arg("fingerprint")=fingerprint("LT",0,1,0,0), session_init_doc)
        )
        .def(
            "listen_on", &listen_on
          , (arg("min"), "max", arg("interface") = (char const*)0)
          , session_listen_on_doc
        )
        .def("is_listening", allow_threads(&session::is_listening), session_is_listening_doc)
        .def("listen_port", allow_threads(&session::listen_port), session_listen_port_doc)
        .def("status", allow_threads(&session::status), session_status_m_doc)
#ifndef TORRENT_DISABLE_DHT
        .def("start_dht", allow_threads(&session::start_dht), session_start_dht_doc)
        .def("stop_dht", allow_threads(&session::stop_dht), session_stop_dht_doc)
        .def("dht_state", allow_threads(&session::dht_state), session_dht_state_doc)
#endif
        .def(
            "add_torrent", &add_torrent
          , (
                arg("resume_data") = entry(), arg("storage_mode") = storage_mode_sparse,
                arg("paused") = false
            )
          , session_add_torrent_doc
        )
        .def("remove_torrent", allow_threads(&session::remove_torrent), session_remove_torrent_doc)
        .def(
            "set_download_rate_limit", allow_threads(&session::set_download_rate_limit)
          , session_set_download_rate_limit_doc
        )
        .def(
            "download_rate_limit", allow_threads(&session::download_rate_limit)
          , session_download_rate_limit_doc
        )

        .def(
            "set_upload_rate_limit", allow_threads(&session::set_upload_rate_limit)
          , session_set_upload_rate_limit_doc
        )
        .def(
            "upload_rate_limit", allow_threads(&session::upload_rate_limit)
          , session_upload_rate_limit_doc
        )

        .def(
            "set_max_uploads", allow_threads(&session::set_max_uploads)
          , session_set_max_uploads_doc
        )
        .def(
            "set_max_connections", allow_threads(&session::set_max_connections)
          , session_set_max_connections_doc
        )
        .def(
            "set_max_half_open_connections", allow_threads(&session::set_max_half_open_connections)
          , session_set_max_half_open_connections_doc
        )
        .def(
            "num_connections", allow_threads(&session::num_connections)
          , session_num_connections_doc
        )
        .def("set_settings", allow_threads(&session::set_settings), session_set_settings_doc)
        .def("set_pe_settings", allow_threads(&session::set_pe_settings), session_set_pe_settings_doc)
        .def("get_pe_settings", allow_threads(&session::get_pe_settings), return_value_policy<copy_const_reference>())
        .def(
            "set_severity_level", allow_threads(&session::set_severity_level)
          , session_set_severity_level_doc
        )
        .def("pop_alert", allow_threads(&session::pop_alert), session_pop_alert_doc)
        .def("add_extension", &add_extension)
        .def("set_peer_proxy", allow_threads(&session::set_peer_proxy))
        .def("set_tracker_proxy", allow_threads(&session::set_tracker_proxy))
        .def("set_web_seed_proxy", allow_threads(&session::set_web_seed_proxy))
#ifndef TORRENT_DISABLE_DHT
        .def("set_dht_proxy", allow_threads(&session::set_dht_proxy))
#endif
        .def("start_upnp", allow_threads(&session::start_upnp), session_start_upnp_doc)
        .def("stop_upnp", allow_threads(&session::stop_upnp), session_stop_upnp_doc)
        .def("start_natpmp", allow_threads(&session::start_natpmp), session_start_natpmp_doc)
        .def("stop_natpmp", allow_threads(&session::stop_natpmp), session_stop_natpmp_doc)
        ;

    register_ptr_to_python<std::auto_ptr<alert> >();
}

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkImageMedian3D.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to C. Charles Law who developed this class.

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkImageMedian3D.h"

//----------------------------------------------------------------------------
// Description:
// Construct an instance of vtkImageMedian3D fitler.
vtkImageMedian3D::vtkImageMedian3D()
{
  this->SetKernelSize(1,1,1);
  this->HandleBoundaries = 1;
}

//----------------------------------------------------------------------------
// Description:
// This method sets the size of the neighborhood.  It also sets the
// default middle of the neighborhood
void vtkImageMedian3D::SetKernelSize(int size0, int size1, int size2)
{
  int volume;

  if (this->KernelSize[0] == size0 && this->KernelSize[1] == size1 &&
      this->KernelSize[2] == size2)
    {
    return;
    }

  // Set the kernel size and middle
  volume = 1;
  this->KernelSize[0] = size0;
  this->KernelMiddle[0] = size0 / 2;
  volume *= size0;
  this->KernelSize[1] = size1;
  this->KernelMiddle[1] = size1 / 2;
  volume *= size1;
  this->KernelSize[2] = size2;
  this->KernelMiddle[2] = size2 / 2;
  volume *= size2;

  this->NumberOfElements = volume;
  this->Modified();
}

//----------------------------------------------------------------------------
// Description:
// Add a sample to the median computation
double *vtkImageMedian3DAccumulateMedian(int &UpNum, int &DownNum,
					 int &UpMax, int &DownMax,
					 int &NumNeighborhood,
					 double *Median, double val)
{
  int idx, max;
  double temp, *ptr;

  // special case: no samples yet
  if (UpNum == 0)
    {
    *(Median) = val;
    // length of up and down arrays inclusive of current
    UpNum = DownNum = 1;
    // median is gaurenteed to be in this range (length of array)
    DownMax = UpMax = (NumNeighborhood + 1) / 2;
    return Median;
    }

  // Case: value is above median
  if (val >= *(Median))
    {
    // move the median if necessary
    if (UpNum > DownNum)
      {
      // Move the median Up one
      ++Median;
      --UpNum;
      ++DownNum;
      --UpMax;
      ++DownMax;
      }
    // find the position for val in the sorted array
    max = (UpNum < UpMax) ? UpNum : UpMax;
    ptr = Median;
    idx = 0;
    while (val >= *ptr && idx < max)
      {
      ++ptr;
      ++idx;
      }
    // place val and move all others up
    while (idx <= max)
      {
      temp = *ptr;
      *ptr = val;
      val = temp;
      ++ptr;
      ++idx;
      }
    // Update counts
    ++UpNum;
    --DownMax;
    return Median;
    }

  // Case: value is below median
  if (val <= *(Median))
    {
    // move the median if necessary
    if (DownNum > UpNum)
      {
      // Move the median Down one
      --Median;
      --DownNum;
      ++UpNum;
      --DownMax;
      ++UpMax;
      }
    // find the position for val in the sorted array
    max = (DownNum < DownMax) ? DownNum : DownMax;
    ptr = Median;
    idx = 0;
    while (val <= *ptr && idx < max)
      {
      --ptr;
      ++idx;
      }
    // place val and move all others up
    while (idx <= max)
      {
      temp = *ptr;
      *ptr = val;
      val = temp;
      --ptr;
      ++idx;
      }
    // Update counts
    ++DownNum;
    --UpMax;
    return Median;
    }
  return Median;
}

//----------------------------------------------------------------------------
// Description:
// This method contains the second switch statement that calls the correct
// templated function for the mask types.
template <class T>
static void vtkImageMedian3DExecute(vtkImageMedian3D *self,
				    vtkImageData *inData, T *inPtr,
				    vtkImageData *outData, T *outPtr,
				    int outExt[6], int id)
{
  int *kernelMiddle, *kernelSize;
  // For looping though output (and input) pixels.
  int outIdx0, outIdx1, outIdx2;
  int inInc0, inInc1, inInc2;
  int outIdxC, outIncX, outIncY, outIncZ;
  T *inPtr0, *inPtr1, *inPtr2;
  // For looping through hood pixels
  int hoodMin0, hoodMax0, hoodMin1, hoodMax1, hoodMin2, hoodMax2;
  int hoodStartMin0, hoodStartMax0, hoodStartMin1, hoodStartMax1;
  int hoodIdx0, hoodIdx1, hoodIdx2;
  T *tmpPtr0, *tmpPtr1, *tmpPtr2;
  // The portion of the out image that needs no boundary processing.
  int middleMin0, middleMax0, middleMin1, middleMax1, middleMin2, middleMax2;
  int numComp;
  // variables for the median calc
  int UpNum, DownNum, UpMax, DownMax;
  double *Median;
  double *Sort = new double[(self->NumberOfElements + 8)];
  int *inExt;
  unsigned long count = 0;
  unsigned long target;

  // Get information to march through data
  inData->GetIncrements(inInc0, inInc1, inInc2);
  outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
  kernelMiddle = self->KernelMiddle;
  kernelSize = self->KernelSize;

  numComp = inData->GetNumberOfScalarComponents();

  hoodMin0 = outExt[0] - kernelMiddle[0];
  hoodMin1 = outExt[2] - kernelMiddle[1];
  hoodMin2 = outExt[4] - kernelMiddle[2];
  hoodMax0 = kernelSize[0] + hoodMin0 - 1;
  hoodMax1 = kernelSize[1] + hoodMin1 - 1;
  hoodMax2 = kernelSize[2] + hoodMin2 - 1;

  // Clip by the input image extent
  inExt = inData->GetExtent();
  hoodMin0 = (hoodMin0 > inExt[0]) ? hoodMin0 : inExt[0];
  hoodMin1 = (hoodMin1 > inExt[2]) ? hoodMin1 : inExt[2];
  hoodMin2 = (hoodMin2 > inExt[4]) ? hoodMin2 : inExt[4];
  hoodMax0 = (hoodMax0 < inExt[1]) ? hoodMax0 : inExt[1];
  hoodMax1 = (hoodMax1 < inExt[3]) ? hoodMax1 : inExt[3];
  hoodMax2 = (hoodMax2 < inExt[5]) ? hoodMax2 : inExt[5];

  // Save the starting neighborhood dimensions (2 loops only once)
  hoodStartMin0 = hoodMin0;    hoodStartMax0 = hoodMax0;
  hoodStartMin1 = hoodMin1;    hoodStartMax1 = hoodMax1;

  // The portion of the output that needs no boundary computation.
  middleMin0 = inExt[0] + kernelMiddle[0];
  middleMax0 = inExt[1] - (kernelSize[0] - 1) + kernelMiddle[0];
  middleMin1 = inExt[2] + kernelMiddle[1];
  middleMax1 = inExt[3] - (kernelSize[1] - 1) + kernelMiddle[1];
  middleMin2 = inExt[4] + kernelMiddle[2];
  middleMax2 = inExt[5] - (kernelSize[2] - 1) + kernelMiddle[2];

  target = (unsigned long)((outExt[5] - outExt[4] + 1)*
    (outExt[3] - outExt[2] + 1)/50.0);
  target++;

  // loop through pixel of output
  inPtr = (T *)inData->GetScalarPointer(hoodMin0,hoodMin1,hoodMin2);
  inPtr2 = inPtr;
  for (outIdx2 = outExt[4]; outIdx2 <= outExt[5]; ++outIdx2)
    {
    inPtr1 = inPtr2;
    hoodMin1 = hoodStartMin1;
    hoodMax1 = hoodStartMax1;
    for (outIdx1 = outExt[2]; outIdx1 <= outExt[3]; ++outIdx1)
      {
      if (!id)
	{
	if (!(count%target)) self->UpdateProgress(count/(50.0*target));
	count++;
	}
      inPtr0 = inPtr1;
      hoodMin0 = hoodStartMin0;
      hoodMax0 = hoodStartMax0;
      for (outIdx0 = outExt[0]; outIdx0 <= outExt[1]; ++outIdx0)
	{
	for (outIdxC = 0; outIdxC < numComp; outIdxC++)
	  {
	  // Compute median of neighborhood
	  // Note: For boundary, NumNeighborhood could be changed for
	  // a faster sort.
	  DownNum = UpNum = 0;
          Median = Sort + (self->NumberOfElements / 2) + 4;
	  // loop through neighborhood pixels
	  tmpPtr2 = inPtr0 + outIdxC;
	  for (hoodIdx2 = hoodMin2; hoodIdx2 <= hoodMax2; ++hoodIdx2)
	    {
	    tmpPtr1 = tmpPtr2;
	    for (hoodIdx1 = hoodMin1; hoodIdx1 <= hoodMax1; ++hoodIdx1)
	      {
	      tmpPtr0 = tmpPtr1;
	      for (hoodIdx0 = hoodMin0; hoodIdx0 <= hoodMax0; ++hoodIdx0)
		{
		// Add this pixel to the median
		Median = vtkImageMedian3DAccumulateMedian(UpNum, DownNum,
							  UpMax, DownMax,
							  self->NumberOfElements,
							  Median,
							  double(*tmpPtr0));

		tmpPtr0 += inInc0;
		}
	      tmpPtr1 += inInc1;
	      }
	    tmpPtr2 += inInc2;
	    }

	  // Replace this pixel with the hood median
	  *outPtr = (T)(*Median);
	  outPtr++;
	  }

	// shift neighborhood considering boundaries
	if (outIdx0 >= middleMin0)
	  {
	  inPtr0 += inInc0;
	  ++hoodMin0;
	  }
	if (outIdx0 < middleMax0)
	  {
	  ++hoodMax0;
	  }
	}
      // shift neighborhood considering boundaries
      if (outIdx1 >= middleMin1)
	{
	inPtr1 += inInc1;
	++hoodMin1;
	}
      if (outIdx1 < middleMax1)
	{
	++hoodMax1;
	}
      outPtr += outIncY;
    }
    // shift neighborhood considering boundaries
    if (outIdx2 >= middleMin2)
      {
      inPtr2 += inInc2;
      ++hoodMin2;
      }
    if (outIdx2 < middleMax2)
      {
      ++hoodMax2;
      }
    outPtr += outIncZ;
    }

  delete [] Sort;

}

//----------------------------------------------------------------------------
// Description:
// This method contains the first switch statement that calls the correct
// templated function for the input and output region types.
void vtkImageMedian3D::ThreadedExecute(vtkImageData *inData,
				       vtkImageData *outData,
				       int outExt[6], int id)
{
  void *inPtr = inData->GetScalarPointerForExtent(outExt);
  void *outPtr = outData->GetScalarPointerForExtent(outExt);

  vtkDebugMacro(<< "Execute: inData = " << inData
  << ", outData = " << outData);

  // this filter expects that input is the same type as output.
  if (inData->GetScalarType() != outData->GetScalarType())
    {
    vtkErrorMacro(<< "Execute: input ScalarType, " << inData->GetScalarType()
                  << ", must match out ScalarType " << outData->GetScalarType());
    return;
    }

  switch (inData->GetScalarType())
    {
    case VTK_FLOAT:
      vtkImageMedian3DExecute(this, inData, (float *)(inPtr),
			      outData, (float *)(outPtr),outExt, id);
      break;
    case VTK_INT:
      vtkImageMedian3DExecute(this, inData, (int *)(inPtr),
			      outData, (int *)(outPtr),outExt, id);
      break;
    case VTK_SHORT:
      vtkImageMedian3DExecute(this, inData, (short *)(inPtr),
			      outData, (short *)(outPtr),outExt, id);
      break;
    case VTK_UNSIGNED_SHORT:
      vtkImageMedian3DExecute(this, inData, (unsigned short *)(inPtr),
			      outData, (unsigned short *)(outPtr),outExt, id);
      break;
    case VTK_UNSIGNED_CHAR:
      vtkImageMedian3DExecute(this, inData, (unsigned char *)(inPtr),
			      outData, (unsigned char *)(outPtr),outExt, id);
      break;
    default:
      vtkErrorMacro(<< "Execute: Unknown input ScalarType");
      return;
    }
}

<commit_msg>ERR: out of bounds read<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageMedian3D.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
  Thanks:    Thanks to C. Charles Law who developed this class.

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkImageMedian3D.h"

//----------------------------------------------------------------------------
// Description:
// Construct an instance of vtkImageMedian3D fitler.
vtkImageMedian3D::vtkImageMedian3D()
{
  this->SetKernelSize(1,1,1);
  this->HandleBoundaries = 1;
}

//----------------------------------------------------------------------------
// Description:
// This method sets the size of the neighborhood.  It also sets the
// default middle of the neighborhood
void vtkImageMedian3D::SetKernelSize(int size0, int size1, int size2)
{
  int volume;

  if (this->KernelSize[0] == size0 && this->KernelSize[1] == size1 &&
      this->KernelSize[2] == size2)
    {
    return;
    }

  // Set the kernel size and middle
  volume = 1;
  this->KernelSize[0] = size0;
  this->KernelMiddle[0] = size0 / 2;
  volume *= size0;
  this->KernelSize[1] = size1;
  this->KernelMiddle[1] = size1 / 2;
  volume *= size1;
  this->KernelSize[2] = size2;
  this->KernelMiddle[2] = size2 / 2;
  volume *= size2;

  this->NumberOfElements = volume;
  this->Modified();
}

//----------------------------------------------------------------------------
// Description:
// Add a sample to the median computation
double *vtkImageMedian3DAccumulateMedian(int &UpNum, int &DownNum,
					 int &UpMax, int &DownMax,
					 int &NumNeighborhood,
					 double *Median, double val)
{
  int idx, max;
  double temp, *ptr;

  // special case: no samples yet
  if (UpNum == 0)
    {
    *(Median) = val;
    // length of up and down arrays inclusive of current
    UpNum = DownNum = 1;
    // median is gaurenteed to be in this range (length of array)
    DownMax = UpMax = (NumNeighborhood + 1) / 2;
    return Median;
    }

  // Case: value is above median
  if (val >= *(Median))
    {
    // move the median if necessary
    if (UpNum > DownNum)
      {
      // Move the median Up one
      ++Median;
      --UpNum;
      ++DownNum;
      --UpMax;
      ++DownMax;
      }
    // find the position for val in the sorted array
    max = (UpNum < UpMax) ? UpNum : UpMax;
    ptr = Median;
    idx = 0;
    while (idx < max && val >= *ptr)
      {
      ++ptr;
      ++idx;
      }
    // place val and move all others up
    while (idx <= max)
      {
      temp = *ptr;
      *ptr = val;
      val = temp;
      ++ptr;
      ++idx;
      }
    // Update counts
    ++UpNum;
    --DownMax;
    return Median;
    }

  // Case: value is below median
  if (val <= *(Median))
    {
    // move the median if necessary
    if (DownNum > UpNum)
      {
      // Move the median Down one
      --Median;
      --DownNum;
      ++UpNum;
      --DownMax;
      ++UpMax;
      }
    // find the position for val in the sorted array
    max = (DownNum < DownMax) ? DownNum : DownMax;
    ptr = Median;
    idx = 0;
    while (idx < max && val <= *ptr)
      {
      --ptr;
      ++idx;
      }
    // place val and move all others up
    while (idx <= max)
      {
      temp = *ptr;
      *ptr = val;
      val = temp;
      --ptr;
      ++idx;
      }
    // Update counts
    ++DownNum;
    --UpMax;
    return Median;
    }
  return Median;
}

//----------------------------------------------------------------------------
// Description:
// This method contains the second switch statement that calls the correct
// templated function for the mask types.
template <class T>
static void vtkImageMedian3DExecute(vtkImageMedian3D *self,
				    vtkImageData *inData, T *inPtr,
				    vtkImageData *outData, T *outPtr,
				    int outExt[6], int id)
{
  int *kernelMiddle, *kernelSize;
  // For looping though output (and input) pixels.
  int outIdx0, outIdx1, outIdx2;
  int inInc0, inInc1, inInc2;
  int outIdxC, outIncX, outIncY, outIncZ;
  T *inPtr0, *inPtr1, *inPtr2;
  // For looping through hood pixels
  int hoodMin0, hoodMax0, hoodMin1, hoodMax1, hoodMin2, hoodMax2;
  int hoodStartMin0, hoodStartMax0, hoodStartMin1, hoodStartMax1;
  int hoodIdx0, hoodIdx1, hoodIdx2;
  T *tmpPtr0, *tmpPtr1, *tmpPtr2;
  // The portion of the out image that needs no boundary processing.
  int middleMin0, middleMax0, middleMin1, middleMax1, middleMin2, middleMax2;
  int numComp;
  // variables for the median calc
  int UpNum, DownNum, UpMax, DownMax;
  double *Median;
  double *Sort = new double[(self->NumberOfElements + 8)];
  int *inExt;
  unsigned long count = 0;
  unsigned long target;

  // Get information to march through data
  inData->GetIncrements(inInc0, inInc1, inInc2);
  outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
  kernelMiddle = self->KernelMiddle;
  kernelSize = self->KernelSize;

  numComp = inData->GetNumberOfScalarComponents();

  hoodMin0 = outExt[0] - kernelMiddle[0];
  hoodMin1 = outExt[2] - kernelMiddle[1];
  hoodMin2 = outExt[4] - kernelMiddle[2];
  hoodMax0 = kernelSize[0] + hoodMin0 - 1;
  hoodMax1 = kernelSize[1] + hoodMin1 - 1;
  hoodMax2 = kernelSize[2] + hoodMin2 - 1;

  // Clip by the input image extent
  inExt = inData->GetExtent();
  hoodMin0 = (hoodMin0 > inExt[0]) ? hoodMin0 : inExt[0];
  hoodMin1 = (hoodMin1 > inExt[2]) ? hoodMin1 : inExt[2];
  hoodMin2 = (hoodMin2 > inExt[4]) ? hoodMin2 : inExt[4];
  hoodMax0 = (hoodMax0 < inExt[1]) ? hoodMax0 : inExt[1];
  hoodMax1 = (hoodMax1 < inExt[3]) ? hoodMax1 : inExt[3];
  hoodMax2 = (hoodMax2 < inExt[5]) ? hoodMax2 : inExt[5];

  // Save the starting neighborhood dimensions (2 loops only once)
  hoodStartMin0 = hoodMin0;    hoodStartMax0 = hoodMax0;
  hoodStartMin1 = hoodMin1;    hoodStartMax1 = hoodMax1;

  // The portion of the output that needs no boundary computation.
  middleMin0 = inExt[0] + kernelMiddle[0];
  middleMax0 = inExt[1] - (kernelSize[0] - 1) + kernelMiddle[0];
  middleMin1 = inExt[2] + kernelMiddle[1];
  middleMax1 = inExt[3] - (kernelSize[1] - 1) + kernelMiddle[1];
  middleMin2 = inExt[4] + kernelMiddle[2];
  middleMax2 = inExt[5] - (kernelSize[2] - 1) + kernelMiddle[2];

  target = (unsigned long)((outExt[5] - outExt[4] + 1)*
    (outExt[3] - outExt[2] + 1)/50.0);
  target++;

  // loop through pixel of output
  inPtr = (T *)inData->GetScalarPointer(hoodMin0,hoodMin1,hoodMin2);
  inPtr2 = inPtr;
  for (outIdx2 = outExt[4]; outIdx2 <= outExt[5]; ++outIdx2)
    {
    inPtr1 = inPtr2;
    hoodMin1 = hoodStartMin1;
    hoodMax1 = hoodStartMax1;
    for (outIdx1 = outExt[2]; outIdx1 <= outExt[3]; ++outIdx1)
      {
      if (!id)
	{
	if (!(count%target)) self->UpdateProgress(count/(50.0*target));
	count++;
	}
      inPtr0 = inPtr1;
      hoodMin0 = hoodStartMin0;
      hoodMax0 = hoodStartMax0;
      for (outIdx0 = outExt[0]; outIdx0 <= outExt[1]; ++outIdx0)
	{
	for (outIdxC = 0; outIdxC < numComp; outIdxC++)
	  {
	  // Compute median of neighborhood
	  // Note: For boundary, NumNeighborhood could be changed for
	  // a faster sort.
	  DownNum = UpNum = 0;
          Median = Sort + (self->NumberOfElements / 2) + 4;
	  // loop through neighborhood pixels
	  tmpPtr2 = inPtr0 + outIdxC;
	  for (hoodIdx2 = hoodMin2; hoodIdx2 <= hoodMax2; ++hoodIdx2)
	    {
	    tmpPtr1 = tmpPtr2;
	    for (hoodIdx1 = hoodMin1; hoodIdx1 <= hoodMax1; ++hoodIdx1)
	      {
	      tmpPtr0 = tmpPtr1;
	      for (hoodIdx0 = hoodMin0; hoodIdx0 <= hoodMax0; ++hoodIdx0)
		{
		// Add this pixel to the median
		Median = vtkImageMedian3DAccumulateMedian(UpNum, DownNum,
							  UpMax, DownMax,
							  self->NumberOfElements,
							  Median,
							  double(*tmpPtr0));

		tmpPtr0 += inInc0;
		}
	      tmpPtr1 += inInc1;
	      }
	    tmpPtr2 += inInc2;
	    }

	  // Replace this pixel with the hood median
	  *outPtr = (T)(*Median);
	  outPtr++;
	  }

	// shift neighborhood considering boundaries
	if (outIdx0 >= middleMin0)
	  {
	  inPtr0 += inInc0;
	  ++hoodMin0;
	  }
	if (outIdx0 < middleMax0)
	  {
	  ++hoodMax0;
	  }
	}
      // shift neighborhood considering boundaries
      if (outIdx1 >= middleMin1)
	{
	inPtr1 += inInc1;
	++hoodMin1;
	}
      if (outIdx1 < middleMax1)
	{
	++hoodMax1;
	}
      outPtr += outIncY;
    }
    // shift neighborhood considering boundaries
    if (outIdx2 >= middleMin2)
      {
      inPtr2 += inInc2;
      ++hoodMin2;
      }
    if (outIdx2 < middleMax2)
      {
      ++hoodMax2;
      }
    outPtr += outIncZ;
    }

  delete [] Sort;

}

//----------------------------------------------------------------------------
// Description:
// This method contains the first switch statement that calls the correct
// templated function for the input and output region types.
void vtkImageMedian3D::ThreadedExecute(vtkImageData *inData,
				       vtkImageData *outData,
				       int outExt[6], int id)
{
  void *inPtr = inData->GetScalarPointerForExtent(outExt);
  void *outPtr = outData->GetScalarPointerForExtent(outExt);

  vtkDebugMacro(<< "Execute: inData = " << inData
  << ", outData = " << outData);

  // this filter expects that input is the same type as output.
  if (inData->GetScalarType() != outData->GetScalarType())
    {
    vtkErrorMacro(<< "Execute: input ScalarType, " << inData->GetScalarType()
                  << ", must match out ScalarType " << outData->GetScalarType());
    return;
    }

  switch (inData->GetScalarType())
    {
    case VTK_FLOAT:
      vtkImageMedian3DExecute(this, inData, (float *)(inPtr),
			      outData, (float *)(outPtr),outExt, id);
      break;
    case VTK_INT:
      vtkImageMedian3DExecute(this, inData, (int *)(inPtr),
			      outData, (int *)(outPtr),outExt, id);
      break;
    case VTK_SHORT:
      vtkImageMedian3DExecute(this, inData, (short *)(inPtr),
			      outData, (short *)(outPtr),outExt, id);
      break;
    case VTK_UNSIGNED_SHORT:
      vtkImageMedian3DExecute(this, inData, (unsigned short *)(inPtr),
			      outData, (unsigned short *)(outPtr),outExt, id);
      break;
    case VTK_UNSIGNED_CHAR:
      vtkImageMedian3DExecute(this, inData, (unsigned char *)(inPtr),
			      outData, (unsigned char *)(outPtr),outExt, id);
      break;
    default:
      vtkErrorMacro(<< "Execute: Unknown input ScalarType");
      return;
    }
}

<|endoftext|>


<commit_before>/***********************************************************************
 * Software License Agreement (BSD License)
 *
 * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
 * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
 *
 * THE BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *************************************************************************/

#ifndef _IZENELIB_AM_INTERVAL_HEAP_HPP
#define _IZENELIB_AM_INTERVAL_HEAP_HPP

#include <assert.h>
#include <algorithm>
#include <vector>

NS_IZENELIB_AM_BEGIN

template <class T, class Compare = std::less<T> >
class interval_heap
{
public:
    typedef T value_type;
    typedef std::vector<std::pair<T, T> > container_type;
    typedef typename container_type::size_type size_type;

    /**
     * Constructor.
     *
     * Params:
     *     size = heap size
     */
    explicit interval_heap(size_type capacity, const Compare& compare = Compare())
        : compare_(compare)
        , container_((capacity + 1) / 2 + 1) // 1-based indexing
        , capacity_(capacity)
        , size_(0)
    {
    }

    /**
     * @return Heap size
     */
    size_type size() const
    {
        return size_;
    }

    /**
     * Tests if the heap is empty
     * @return true is heap empty, false otherwise
     */
    bool empty() const
    {
        return size_ == 0;
    }

    size_type capacity() const
    {
        return capacity_;
    }

    /**
     * Clears the heap.
     */
    void clear()
    {
        size_ = 0;
    }

    void reserve(size_type capacity)
    {
        if (capacity > capacity_)
        {
            container_.resize((capacity + 1) / 2 + 1);
            capacity_ = capacity;
        }
    }

    container_type& get_container()
    {
        return container_;
    }

    const container_type& get_container() const
    {
        return container_;
    }

    void insert(const value_type& value)
    {
        if (size_ == capacity_) return;

        // insert into the root
        if (size_ < 2)
        {
            if (size_ == 0)
            {
                container_[1].first = container_[1].second = value;
            }
            else
            {
                if (compare_(value, container_[1].first))
                {
                    container_[1].first = value;
                }
                else
                {
                    container_[1].second = value;
                }
            }
            ++size_;
            return;
        }

        size_type last_pos = (size_ + 1) / 2;
        bool min_heap;

        if (size_ % 2) // odd number of elements
        {
            min_heap = compare_(value, container_[last_pos].first);
        }
        else
        {
            min_heap = compare_(value, container_[++last_pos / 2].first);
        }

        if (min_heap)
        {
            size_type pos = last_pos;
            size_type par = pos / 2;
            while (pos > 1 && compare_(value, container_[par].first))
            {
                container_[pos].first = container_[par].first;
                pos = par;
                par /= 2;
            }
            container_[pos].first = value;

            if (++size_ % 2) // duplicate element in last position if size is odd
            {
                container_[last_pos].second = container_[last_pos].first;
            }
        }
        else
        {
            size_type pos = last_pos;
            size_type par = pos / 2;
            while (pos > 1 && compare_(container_[par].second, value))
            {
                container_[pos].second = container_[par].second;
                pos = par;
                par /= 2;
            }
            container_[pos].second = value;

            if (++size_ % 2) // duplicate element in last position if size is odd
            {
                container_[last_pos].first = container_[last_pos].second;
            }
        }
    }

    void replace_min(const value_type& value)
    {
        assert(size_ > 0);
        if (size_ == 1)
        {
            container_[1].first = container_[1].second = value;
            return;
        }

        size_type last_pos = (size_ + 1) / 2;
        value_type elem = value;

        size_type crt = 1; // root node
        size_type child = 2;

        while (child <= last_pos)
        {
            child += child < last_pos && compare_(container_[child + 1].first, container_[child].first);

            if (!compare_(container_[child].first, elem)) break;

            container_[crt].first = container_[child].first;
            if (compare_(container_[child].second, elem))
                std::swap(elem, container_[child].second);

            crt = child;
            child *= 2;
        }

        container_[crt].first = (crt <= size / 2) ? elem : container_[crt].second;
    }

    void replace_max(const value_type& value)
    {
        assert(size_ > 0);
        if (size_ == 1)
        {
            container_[1].first = container_[1].second = value;
            return;
        }

        size_type last_pos = (size_ + 1) / 2;
        value_type elem = value;

        size_type crt = 1; // root node
        size_type child = 2;

        while (child <= last_pos)
        {
            child += child < last_pos && compare_(container_[child].second, container_[child + 1].second);

            if (!compare_(elem, container_[child].second)) break;

            container_[crt].second = container_[child].second;
            if (compare_(elem, container_[child].first))
                std::swap(elem, container_[child].first);

            crt = child;
            child *= 2;
        }

        container_[crt].second = (crt <= size / 2) ? elem : container_[crt].first;
    }

    void pop_min()
    {
        assert(size_ > 0);
        size_type last_pos = (size_ + 1) / 2;
        value_type elem = container_[last_pos].first;

        if (size_ % 2) // odd number of elements
        {
            --last_pos;
        }
        else
        {
            container_[last_pos].first = container_[last_pos].second;
        }
        if (--size_ < 2) return;

        size_type crt = 1; // root node
        size_type child = 2;

        while (child <= last_pos)
        {
            child += child < last_pos && compare_(container_[child + 1].first, container_[child].first);

            if (!compare_(container_[child].first, elem)) break;

            container_[crt].first = container_[child].first;
            if (compare_(container_[child].second, elem))
                std::swap(elem, container_[child].second);

            crt = child;
            child *= 2;
        }

        container_[crt].first = elem;
    }

    void pop_max()
    {
        assert(size_ > 0);
        size_type last_pos = (size_ + 1) / 2;
        value_type elem = container_[last_pos].second;

        if (size_ % 2) // odd number of elements
        {
            --last_pos;
        }
        else
        {
            container_[last_pos].second = container_[last_pos].first;
        }
        if (--size_ < 2) return;

        size_type crt = 1; // root node
        size_type child = 2;

        while (child <= last_pos)
        {
            child += child < last_pos && compare_(container_[child].second, container_[child + 1].second);

            if (!compare_(elem, container_[child].second)) break;

            container_[crt].second = container_[child].second;
            if (compare_(elem, container_[child].first))
                std::swap(elem, container_[child].first);

            crt = child;
            child *= 2;
        }

        container_[crt].second = elem;
    }

    value_type& get_min()
    {
        assert(size_ > 0);
        return container_[1].first;
    }

    const value_type& get_min() const
    {
        assert(size_ > 0);
        return container_[1].first;
    }

    value_type& get_max()
    {
        assert(size_ > 0);
        return container_[1].second;
    }

    const value_type& get_max() const
    {
        assert(size_ > 0);
        return container_[1].second;
    }

private:
    /**
     * Storage array for the heap.
     * Type T must be comparable.
     */
    Compare compare_;
    container_type container_;
    size_type capacity_;
    size_type size_;
};

NS_IZENELIB_AM_END

#endif
<commit_msg>fix last commit<commit_after>/***********************************************************************
 * Software License Agreement (BSD License)
 *
 * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
 * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
 *
 * THE BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *************************************************************************/

#ifndef _IZENELIB_AM_INTERVAL_HEAP_HPP
#define _IZENELIB_AM_INTERVAL_HEAP_HPP

#include <assert.h>
#include <algorithm>
#include <vector>

NS_IZENELIB_AM_BEGIN

template <class T, class Compare = std::less<T> >
class interval_heap
{
public:
    typedef T value_type;
    typedef std::vector<std::pair<T, T> > container_type;
    typedef typename container_type::size_type size_type;

    /**
     * Constructor.
     *
     * Params:
     *     size = heap size
     */
    explicit interval_heap(size_type capacity, const Compare& compare = Compare())
        : compare_(compare)
        , container_((capacity + 1) / 2 + 1) // 1-based indexing
        , capacity_(capacity)
        , size_(0)
    {
    }

    /**
     * @return Heap size
     */
    size_type size() const
    {
        return size_;
    }

    /**
     * Tests if the heap is empty
     * @return true is heap empty, false otherwise
     */
    bool empty() const
    {
        return size_ == 0;
    }

    size_type capacity() const
    {
        return capacity_;
    }

    /**
     * Clears the heap.
     */
    void clear()
    {
        size_ = 0;
    }

    void reserve(size_type capacity)
    {
        if (capacity > capacity_)
        {
            container_.resize((capacity + 1) / 2 + 1);
            capacity_ = capacity;
        }
    }

    container_type& get_container()
    {
        return container_;
    }

    const container_type& get_container() const
    {
        return container_;
    }

    void insert(const value_type& value)
    {
        if (size_ == capacity_) return;

        // insert into the root
        if (size_ < 2)
        {
            if (size_ == 0)
            {
                container_[1].first = container_[1].second = value;
            }
            else
            {
                if (compare_(value, container_[1].first))
                {
                    container_[1].first = value;
                }
                else
                {
                    container_[1].second = value;
                }
            }
            ++size_;
            return;
        }

        size_type last_pos = (size_ + 1) / 2;
        bool min_heap;

        if (size_ % 2) // odd number of elements
        {
            min_heap = compare_(value, container_[last_pos].first);
        }
        else
        {
            min_heap = compare_(value, container_[++last_pos / 2].first);
        }

        if (min_heap)
        {
            size_type pos = last_pos;
            size_type par = pos / 2;
            while (pos > 1 && compare_(value, container_[par].first))
            {
                container_[pos].first = container_[par].first;
                pos = par;
                par /= 2;
            }
            container_[pos].first = value;

            if (++size_ % 2) // duplicate element in last position if size is odd
            {
                container_[last_pos].second = container_[last_pos].first;
            }
        }
        else
        {
            size_type pos = last_pos;
            size_type par = pos / 2;
            while (pos > 1 && compare_(container_[par].second, value))
            {
                container_[pos].second = container_[par].second;
                pos = par;
                par /= 2;
            }
            container_[pos].second = value;

            if (++size_ % 2) // duplicate element in last position if size is odd
            {
                container_[last_pos].first = container_[last_pos].second;
            }
        }
    }

    void replace_min(const value_type& value)
    {
        assert(size_ > 0);
        if (size_ == 1)
        {
            container_[1].first = container_[1].second = value;
            return;
        }

        size_type last_pos = (size_ + 1) / 2;
        value_type elem = value;

        size_type crt = 1; // root node
        size_type child = 2;

        while (child <= last_pos)
        {
            child += child < last_pos && compare_(container_[child + 1].first, container_[child].first);

            if (!compare_(container_[child].first, elem)) break;

            container_[crt].first = container_[child].first;
            if (compare_(container_[child].second, elem))
                std::swap(elem, container_[child].second);

            crt = child;
            child *= 2;
        }

        container_[crt].first = (crt <= size_ / 2) ? elem : container_[crt].second;
    }

    void replace_max(const value_type& value)
    {
        assert(size_ > 0);
        if (size_ == 1)
        {
            container_[1].first = container_[1].second = value;
            return;
        }

        size_type last_pos = (size_ + 1) / 2;
        value_type elem = value;

        size_type crt = 1; // root node
        size_type child = 2;

        while (child <= last_pos)
        {
            child += child < last_pos && compare_(container_[child].second, container_[child + 1].second);

            if (!compare_(elem, container_[child].second)) break;

            container_[crt].second = container_[child].second;
            if (compare_(elem, container_[child].first))
                std::swap(elem, container_[child].first);

            crt = child;
            child *= 2;
        }

        container_[crt].second = (crt <= size / 2) ? elem : container_[crt].first;
    }

    void pop_min()
    {
        assert(size_ > 0);
        size_type last_pos = (size_ + 1) / 2;
        value_type elem = container_[last_pos].first;

        if (size_ % 2) // odd number of elements
        {
            --last_pos;
        }
        else
        {
            container_[last_pos].first = container_[last_pos].second;
        }
        if (--size_ < 2) return;

        size_type crt = 1; // root node
        size_type child = 2;

        while (child <= last_pos)
        {
            child += child < last_pos && compare_(container_[child + 1].first, container_[child].first);

            if (!compare_(container_[child].first, elem)) break;

            container_[crt].first = container_[child].first;
            if (compare_(container_[child].second, elem))
                std::swap(elem, container_[child].second);

            crt = child;
            child *= 2;
        }

        container_[crt].first = elem;
    }

    void pop_max()
    {
        assert(size_ > 0);
        size_type last_pos = (size_ + 1) / 2;
        value_type elem = container_[last_pos].second;

        if (size_ % 2) // odd number of elements
        {
            --last_pos;
        }
        else
        {
            container_[last_pos].second = container_[last_pos].first;
        }
        if (--size_ < 2) return;

        size_type crt = 1; // root node
        size_type child = 2;

        while (child <= last_pos)
        {
            child += child < last_pos && compare_(container_[child].second, container_[child + 1].second);

            if (!compare_(elem, container_[child].second)) break;

            container_[crt].second = container_[child].second;
            if (compare_(elem, container_[child].first))
                std::swap(elem, container_[child].first);

            crt = child;
            child *= 2;
        }

        container_[crt].second = elem;
    }

    value_type& get_min()
    {
        assert(size_ > 0);
        return container_[1].first;
    }

    const value_type& get_min() const
    {
        assert(size_ > 0);
        return container_[1].first;
    }

    value_type& get_max()
    {
        assert(size_ > 0);
        return container_[1].second;
    }

    const value_type& get_max() const
    {
        assert(size_ > 0);
        return container_[1].second;
    }

private:
    /**
     * Storage array for the heap.
     * Type T must be comparable.
     */
    Compare compare_;
    container_type container_;
    size_type capacity_;
    size_type size_;
};

NS_IZENELIB_AM_END

#endif
<|endoftext|>


<commit_before>#pragma once

#include <xcb/xcb.h>

#include <string>
#include <unordered_map>

#include "common.hpp"

POLYBAR_NS

// fwd {{{
struct randr_output;
using monitor_t = shared_ptr<randr_output>;
// }}}

struct enum_hash {
  template <typename T>
  inline typename std::enable_if<std::is_enum<T>::value, size_t>::type operator()(T const value) const {
    return static_cast<size_t>(value);
  }
};

enum class edge { NONE = 0, TOP, BOTTOM, LEFT, RIGHT, ALL };

enum class alignment { NONE = 0, LEFT, CENTER, RIGHT };

enum class attribute { NONE = 0, UNDERLINE, OVERLINE };

enum class syntaxtag {
  NONE = 0,
  A,  // mouse action
  B,  // background color
  F,  // foreground color
  T,  // font index
  O,  // pixel offset
  R,  // flip colors
  o,  // overline color
  u,  // underline color
};

enum class mousebtn { NONE = 0, LEFT, MIDDLE, RIGHT, SCROLL_UP, SCROLL_DOWN, DOUBLE_LEFT, DOUBLE_MIDDLE, DOUBLE_RIGHT };

enum class strut {
  LEFT = 0,
  RIGHT,
  TOP,
  BOTTOM,
  LEFT_START_Y,
  LEFT_END_Y,
  RIGHT_START_Y,
  RIGHT_END_Y,
  TOP_START_X,
  TOP_END_X,
  BOTTOM_START_X,
  BOTTOM_END_X,
};

struct position {
  int x{0};
  int y{0};
};

struct size {
  unsigned int w{1U};
  unsigned int h{1U};
};

struct side_values {
  unsigned int left{0U};
  unsigned int right{0U};
};

struct edge_values {
  unsigned int left{0U};
  unsigned int right{0U};
  unsigned int top{0U};
  unsigned int bottom{0U};
};

struct radius {
  double top{0.0};
  double bottom{0.0};

  operator bool() const {
    return top != 0.0 || bottom != 0.0;
  }
};

struct border_settings {
  unsigned int color{0xFF000000};
  unsigned int size{0U};
};

struct line_settings {
  unsigned int color{0xFF000000};
  unsigned int size{0U};
};

struct action {
  mousebtn button{mousebtn::NONE};
  string command{};
};

struct action_block : public action {
  alignment align{alignment::NONE};
  double start_x{0.0};
  double end_x{0.0};
  bool active{true};

  unsigned int width() const {
    return static_cast<unsigned int>(end_x - start_x + 0.5);
  }

  bool test(int point) const {
    return static_cast<int>(start_x) < point && static_cast<int>(end_x) >= point;
  }
};

struct bar_settings {
  explicit bar_settings() = default;
  bar_settings(const bar_settings& other) = default;

  xcb_window_t window{XCB_NONE};
  monitor_t monitor{};
  edge origin{edge::TOP};
  struct size size {
    1U, 1U
  };
  position pos{0, 0};
  position offset{0, 0};
  position center{0, 0};
  side_values padding{0U, 0U};
  side_values margin{0U, 0U};
  side_values module_margin{0U, 0U};
  edge_values strut{0U, 0U, 0U, 0U};

  unsigned int background{0xFF000000};
  unsigned int foreground{0xFFFFFFFF};
  vector<unsigned int> background_steps;

  line_settings underline{};
  line_settings overline{};

  std::unordered_map<edge, border_settings, enum_hash> borders{};

  struct radius radius {};
  int spacing{0};
  string separator{};

  string wmname{};
  string locale{};

  bool override_redirect{false};

  vector<action> actions{};

  bool dimmed{false};
  double dimvalue{1.0};

  bool shaded{false};
  struct size shade_size {
    1U, 1U
  };
  position shade_pos{1U, 1U};

  const xcb_rectangle_t inner_area(bool abspos = false) const {
    xcb_rectangle_t rect{0, 0, 0, 0};
    rect.width += size.w;
    rect.height += size.h;

    if (abspos) {
      rect.x = pos.x;
      rect.y = pos.y;
    }
    if (borders.find(edge::TOP) != borders.end()) {
      rect.y += borders.at(edge::TOP).size;
      rect.height -= borders.at(edge::TOP).size;
    }
    if (borders.find(edge::BOTTOM) != borders.end()) {
      rect.height -= borders.at(edge::BOTTOM).size;
    }
    if (borders.find(edge::LEFT) != borders.end()) {
      rect.x += borders.at(edge::LEFT).size;
      rect.width -= borders.at(edge::LEFT).size;
    }
    if (borders.find(edge::RIGHT) != borders.end()) {
      rect.width -= borders.at(edge::RIGHT).size;
    }
    return rect;
  }
};

struct event_timer {
  xcb_timestamp_t event{0L};
  xcb_timestamp_t offset{1L};

  bool allow(xcb_timestamp_t time) {
    bool pass = time >= event + offset;
    event = time;
    return pass;
  };

  bool deny(xcb_timestamp_t time) {
    return !allow(time);
  };
};

POLYBAR_NS_END
<commit_msg>Fix off by one error for action area (#663)<commit_after>#pragma once

#include <xcb/xcb.h>

#include <string>
#include <unordered_map>

#include "common.hpp"

POLYBAR_NS

// fwd {{{
struct randr_output;
using monitor_t = shared_ptr<randr_output>;
// }}}

struct enum_hash {
  template <typename T>
  inline typename std::enable_if<std::is_enum<T>::value, size_t>::type operator()(T const value) const {
    return static_cast<size_t>(value);
  }
};

enum class edge { NONE = 0, TOP, BOTTOM, LEFT, RIGHT, ALL };

enum class alignment { NONE = 0, LEFT, CENTER, RIGHT };

enum class attribute { NONE = 0, UNDERLINE, OVERLINE };

enum class syntaxtag {
  NONE = 0,
  A,  // mouse action
  B,  // background color
  F,  // foreground color
  T,  // font index
  O,  // pixel offset
  R,  // flip colors
  o,  // overline color
  u,  // underline color
};

enum class mousebtn { NONE = 0, LEFT, MIDDLE, RIGHT, SCROLL_UP, SCROLL_DOWN, DOUBLE_LEFT, DOUBLE_MIDDLE, DOUBLE_RIGHT };

enum class strut {
  LEFT = 0,
  RIGHT,
  TOP,
  BOTTOM,
  LEFT_START_Y,
  LEFT_END_Y,
  RIGHT_START_Y,
  RIGHT_END_Y,
  TOP_START_X,
  TOP_END_X,
  BOTTOM_START_X,
  BOTTOM_END_X,
};

struct position {
  int x{0};
  int y{0};
};

struct size {
  unsigned int w{1U};
  unsigned int h{1U};
};

struct side_values {
  unsigned int left{0U};
  unsigned int right{0U};
};

struct edge_values {
  unsigned int left{0U};
  unsigned int right{0U};
  unsigned int top{0U};
  unsigned int bottom{0U};
};

struct radius {
  double top{0.0};
  double bottom{0.0};

  operator bool() const {
    return top != 0.0 || bottom != 0.0;
  }
};

struct border_settings {
  unsigned int color{0xFF000000};
  unsigned int size{0U};
};

struct line_settings {
  unsigned int color{0xFF000000};
  unsigned int size{0U};
};

struct action {
  mousebtn button{mousebtn::NONE};
  string command{};
};

struct action_block : public action {
  alignment align{alignment::NONE};
  double start_x{0.0};
  double end_x{0.0};
  bool active{true};

  unsigned int width() const {
    return static_cast<unsigned int>(end_x - start_x + 0.5);
  }

  bool test(int point) const {
    return static_cast<int>(start_x) <= point && static_cast<int>(end_x) > point;
  }
};

struct bar_settings {
  explicit bar_settings() = default;
  bar_settings(const bar_settings& other) = default;

  xcb_window_t window{XCB_NONE};
  monitor_t monitor{};
  edge origin{edge::TOP};
  struct size size {
    1U, 1U
  };
  position pos{0, 0};
  position offset{0, 0};
  position center{0, 0};
  side_values padding{0U, 0U};
  side_values margin{0U, 0U};
  side_values module_margin{0U, 0U};
  edge_values strut{0U, 0U, 0U, 0U};

  unsigned int background{0xFF000000};
  unsigned int foreground{0xFFFFFFFF};
  vector<unsigned int> background_steps;

  line_settings underline{};
  line_settings overline{};

  std::unordered_map<edge, border_settings, enum_hash> borders{};

  struct radius radius {};
  int spacing{0};
  string separator{};

  string wmname{};
  string locale{};

  bool override_redirect{false};

  vector<action> actions{};

  bool dimmed{false};
  double dimvalue{1.0};

  bool shaded{false};
  struct size shade_size {
    1U, 1U
  };
  position shade_pos{1U, 1U};

  const xcb_rectangle_t inner_area(bool abspos = false) const {
    xcb_rectangle_t rect{0, 0, 0, 0};
    rect.width += size.w;
    rect.height += size.h;

    if (abspos) {
      rect.x = pos.x;
      rect.y = pos.y;
    }
    if (borders.find(edge::TOP) != borders.end()) {
      rect.y += borders.at(edge::TOP).size;
      rect.height -= borders.at(edge::TOP).size;
    }
    if (borders.find(edge::BOTTOM) != borders.end()) {
      rect.height -= borders.at(edge::BOTTOM).size;
    }
    if (borders.find(edge::LEFT) != borders.end()) {
      rect.x += borders.at(edge::LEFT).size;
      rect.width -= borders.at(edge::LEFT).size;
    }
    if (borders.find(edge::RIGHT) != borders.end()) {
      rect.width -= borders.at(edge::RIGHT).size;
    }
    return rect;
  }
};

struct event_timer {
  xcb_timestamp_t event{0L};
  xcb_timestamp_t offset{1L};

  bool allow(xcb_timestamp_t time) {
    bool pass = time >= event + offset;
    event = time;
    return pass;
  };

  bool deny(xcb_timestamp_t time) {
    return !allow(time);
  };
};

POLYBAR_NS_END
<|endoftext|>