<commit_before>/*-------------------------------
PASA LA CALCULADORA
Autores:
Jaime Sevilla Molina
Victor Gonzalez
Fecha
2014/11
Version: 1.0
---------------------------------*/

//BIBLIOTECAS
#include <iostream>
#include <cstdlib>
#include <string>
#include <ctime>
#include <cmath>

using namespace std;

typedef enum tJugador
{
	Nadie,
	Jugador,
	Automata
};

//FUNCIONES
//FUNCIONES DE JUEGO

void saludar ();//Implementada

//Dependiendo de quien gane, la despedida sera distinta
void despedirse (tJugador ganador);//Implementada

//Conduce el desarrollo del juego y devuelve el ganador.
//Si se abandona devuelve Nadie.
tJugador pasaCalculadora();

//Decide aleatoriamente quien empieza.
tJugador quienEmpieza();//Implementada
//Devuelve true si nuevo está en la misma fila que ultimo
bool mismaFila(int ultimo, int nuevo);//Implementada

//Devuelve true si nuevo está en la misma columna que ultimo
bool mismaColumna(int ultimo, int nuevo);//Implementada

//Devuelve true si nuevo cumple las reglas del juego con respecto a ultimo
//Si ultimo == 0, este es el primer digito de la partida, y devuelve true
bool digitoValido(int ultimo, int nuevo);//Implementada

//FUNCIONES DE IA NIVEL 1
//Devuelve un dígito del 1 al 9
int digitoAleatorio();//Implementada

//Devuelve un digito que cumpla las reglas del juego con respecto a ultimo.
int digitoAutomata(int ultimo);

//FUNCIONES DE JUGADOR
//Pide un dígito al jugador. Sólo devolverá un valor válido (entre 0 y 9).
//Para un valor no válido, mostrará un error.
int digitoPersona(); //to do Jaime

//Pide un digito al jugador mostrando el teclado. Solo devolvera un valor
//que cumpla las reglas del juego o 0. Para un valor no valido, mostrara un error.
int digitoPersona(int ultimo); //to do Jaime

//Determina si el numero de la calculadora se muestra o no, en funcion de si es valido
char mNumero(int ultimo, int n);

//Muestra los botones de la calculadora (solo los que se pueden pulsar en cada turno)
void mostrarCalculadora(ultimo);

/* Las funciones a continuacion se implementaran en un futuro
//FUNCIONES DE MENÚ
//Muestra el menu, pide la opcion y la devuelve como resultado. Solo
//devolvera una opción valida. Para cada valor no valido, mostrará un error.
int menu();

//Muestra en la consola el contenido del archivo de texto nombArch.
//Si el archivo no se encuentra, devuelve false, en otro caso true.
bool mostrar(string nombArch);

//FUNCIONES DE INFORME
//Actualiza el archivo informePC.txt con los tres argumentos. En caso de no encontrar
//el archivo, lo crea y devuelve false; en otro caso devuelve true.
bool actInforme(int jugadas, int ganadas, int abandonos);

//FUNCIONES DE DIFICULTAD AVANZADA
int botDificil(int ultimo);

-----------------------------------------------------------------------------------*/

int main(){
	tJugador ganador;

	saludar();
	ganador = pasaCalculadora();
	despedirse(ganador)
	return 0;
	}
//Saluda al jugador y le pregunta su nombre
void saludar{
	string nombre;
	cout << "¡Bienvenido a Pasa la calculadora!" << endl;
	cout << "¿Como te llamas?";
	cin >> nombre;
	cout << "Hola" << nombre;
}
//Se despide del jugador, la despedida varia segun gane el jugador, el autómata o ninguno de ellos (el jugador abandone)
void despedirse{
	string nombre;
	if (ganador == Nadie){
		cout << "¿Abandonas? Ohhh..." << endl;
		cout << "Hasta la proxima " << nombre << "(pulsa una tecla)";
	}
	else if (ganador == jugador){
		cout << "Enhorabuena, has ganado" << endl;
		cout << "Hasta la proxima " << nombre << "(pulsa una tecla)";
	}
	else{
		cout << "Lo siento, he ganado" << endl;
		cout << "Hasta la proxima " << nombre << "(pulsa una tecla)";
	}
}
//Conduce el desarrollo del juego y devuelve el ganador.
//Si se abandona devuelve Nadie.
tJugador pasaCalculadora(){
	//Variables
	tJugador turno;
	int total = 0, ultimoDigito = 0;
	const int META=31;
		//Inicializar partida
	srand(time(NULL))//Semilla
	turno = quienEmpieza();

	//Bucle de juego
	do{
		//Turno jugador
		if (turno == Jugador){
			ultimoDigito = digitoPersona(ultimoDigito);
			turno = Automata;
		}
		//Turno bot
		else /*if (turno == Automata)*/{
			ultimoDigito = digitoAutomata(ultimoDigito);
			turno = Jugador;
		}
		total += ultimoDigito;
		cout << "Total = " << total;
	}while ((total < META) && (ultimoDigito != 0));

	if (ultimoDigito == 0) turno = Nadie;
	//Si el jugador abandona, no gana nadie

	return turno;
}

//Decide aleatoriamente quien empieza la partida, si el automata o el jugador
tJugador quienEmpieza(){
	if (rand() % 2){
		cout << "Tu empiezas";
		return Jugador;
	}
	else{
		cout"Empiezo yo";
		return Automata;
	}
}
//Define que números se encuentran en la misma fila que el ultimo pulsado
bool mismaFila(int ultimo, int nuevo){
	double filaUltimo, filaNuevo;
	filaUltimo = (ultimo/3);
	filaNuevo = (nuevo/3);
	return ceil(filaUltimo) == ceil(filaNuevo);
}
//Define que números se encuentran en la misma columna que el ultimo
bool mismaColumna(int ultimo, int nuevo){
	int columnaUltimo, columnaNuevo;
	columnaUltimo = (ultimo % 3);
	columnaNuevo = (nuevo % 3);
	return columnaUltimo == columnaNuevo;
}
//Determina que digitos se pueden pulsar en función de las reglas del juego
bool digitoValido(int ultimo, int nuevo){
	return ((mismaFila(int ultimo, int nuevo))||(mismaColumna(int ultimo, int nuevo)))&&(ultimo!=nuevo);
}
//Genera un dígito aleatorio
int digitoAleatorio(){
	return (rand() % 9) + 1;
}
//Devuelve un digito que cumpla las reglas del juego con respecto a ultimo.
int digitoAutomata(int ultimo){
	int digito;

	do{
	digito = digitoAleatorio();
	}while (!digitoValido(ultimo, digito));

	cout << "Elijo el numero " << digito;

	return digito;
}

//Pide un digito al jugador. Solo devolvera un valor valido (entre 0 y 9).
//Para un valor no válido, mostrará un error.
int digitoPersona(){
	int digito;

	do{
		try{
			cin.sync(); //Por si quedan datos basura en el buffer
			cin >> digito;
			if (digito < 0 || digito > 9) throw;
		}catch(...){
			cout << "Error! Introduce un digito entre 0-9";
			digito = -1;
		}
	}while (digito == -1);

	return digito;
}

//Pide un digito al jugador mostrando el teclado. Solo devolvera un valor
//que cumpla las reglas del juego o 0. Para un valor no valido, mostrara un error.
int digitoPersona(int ultimo){
	int digito; //-1 es mi error flag

	mostrarCalculadora(ultimo);

	do{
		try{
			digito = digitoPersona();
			if (!digitoValido(ultimo, digito)) throw;
		}catch(...){
			cout << "Error! El digito debe estar en la misma fila y columna que el ultimo";
			digito = -1;
		}
	}while (digito == -1);

	cout << "Has elegido el" << digito;

	return digito;
}

char mNumero(int ultimo, int n){
	if(digitoValido(ultimo, n) return char (n+int('0'));
	else return ' ';
}

void mostrarCalculadora(ultimo){
	for (int i = 7; i<10; i++){
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
	for (int i = 4; i<7; i++){
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
	for (int i = 1; i<4; i++){
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
}
<commit_msg>Minor debugging<commit_after>/*-------------------------------
PASA LA CALCULADORA
Autores:
Jaime Sevilla Molina
Victor Gonzalez
Fecha
2014/11
Version: 1.0
---------------------------------*/

//BIBLIOTECAS
#include <iostream>
#include <cstdlib>
#include <string>
#include <ctime>
#include <cmath>

using namespace std;

typedef enum tJugador
{
	Nadie,
	Jugador,
	Automata
};

//FUNCIONES
//FUNCIONES DE JUEGO

void saludar ();//Implementada

//Dependiendo de quien gane, la despedida sera distinta
void despedirse (tJugador ganador);//Implementada

//Conduce el desarrollo del juego y devuelve el ganador.
//Si se abandona devuelve Nadie.
tJugador pasaCalculadora();

//Decide aleatoriamente quien empieza.
tJugador quienEmpieza();//Implementada
//Devuelve true si nuevo está en la misma fila que ultimo
bool mismaFila(int ultimo, int nuevo);//Implementada

//Devuelve true si nuevo está en la misma columna que ultimo
bool mismaColumna(int ultimo, int nuevo);//Implementada

//Devuelve true si nuevo cumple las reglas del juego con respecto a ultimo
//Si ultimo == 0, este es el primer digito de la partida, y devuelve true
bool digitoValido(int ultimo, int nuevo);//Implementada

//FUNCIONES DE IA NIVEL 1
//Devuelve un dígito del 1 al 9
int digitoAleatorio();//Implementada

//Devuelve un digito que cumpla las reglas del juego con respecto a ultimo.
int digitoAutomata(int ultimo);

//FUNCIONES DE JUGADOR
//Pide un dígito al jugador. Sólo devolverá un valor válido (entre 0 y 9).
//Para un valor no válido, mostrará un error.
int digitoPersona(); //to do Jaime

//Pide un digito al jugador mostrando el teclado. Solo devolvera un valor
//que cumpla las reglas del juego o 0. Para un valor no valido, mostrara un error.
int digitoPersona(int ultimo); //to do Jaime

//Determina si el numero de la calculadora se muestra o no, en funcion de si es valido
char mNumero(int ultimo, int n);

//Muestra los botones de la calculadora (solo los que se pueden pulsar en cada turno)
void mostrarCalculadora(int ultimo);

/* Las funciones a continuacion se implementaran en un futuro
//FUNCIONES DE MENÚ
//Muestra el menu, pide la opcion y la devuelve como resultado. Solo
//devolvera una opción valida. Para cada valor no valido, mostrará un error.
int menu();

//Muestra en la consola el contenido del archivo de texto nombArch.
//Si el archivo no se encuentra, devuelve false, en otro caso true.
bool mostrar(string nombArch);

//FUNCIONES DE INFORME
//Actualiza el archivo informePC.txt con los tres argumentos. En caso de no encontrar
//el archivo, lo crea y devuelve false; en otro caso devuelve true.
bool actInforme(int jugadas, int ganadas, int abandonos);

//FUNCIONES DE DIFICULTAD AVANZADA
int botDificil(int ultimo);

-----------------------------------------------------------------------------------*/

int main(){
	tJugador ganador;

	saludar();
	ganador = pasaCalculadora();
	despedirse(ganador);
	return 0;
	}
//Saluda al jugador y le pregunta su nombre
void saludar(){
	string nombre;
	cout << "¡Bienvenido a Pasa la calculadora!" << endl;
	cout << "¿Como te llamas?";
	cin >> nombre;
	cout << "Hola" << nombre;
}
//Se despide del jugador, la despedida varia segun gane el jugador, el autómata o ninguno de ellos (el jugador abandone)
void despedirse(tJugador ganador){
	string nombre;
	if (ganador == Nadie){
		cout << "¿Abandonas? Ohhh..." << endl;
		cout << "Hasta la proxima " << nombre << "(pulsa una tecla)";
	}
	else if (ganador == jugador){
		cout << "Enhorabuena, has ganado" << endl;
		cout << "Hasta la proxima " << nombre << "(pulsa una tecla)";
	}
	else{
		cout << "Lo siento, he ganado" << endl;
		cout << "Hasta la proxima " << nombre << "(pulsa una tecla)";
	}
}
//Conduce el desarrollo del juego y devuelve el ganador.
//Si se abandona devuelve Nadie.
tJugador pasaCalculadora(){
	//Variables
	tJugador turno;
	int total = 0, ultimoDigito = 0;
	const int META=31;
		//Inicializar partida
	srand(time(NULL))//Semilla
	turno = quienEmpieza();

	//Bucle de juego
	do{
		//Turno jugador
		if (turno == Jugador){
			ultimoDigito = digitoPersona(ultimoDigito);
			turno = Automata;
		}
		//Turno bot
		else /*if (turno == Automata)*/{
			ultimoDigito = digitoAutomata(ultimoDigito);
			turno = Jugador;
		}
		total += ultimoDigito;
		cout << "Total = " << total;
	}while ((total < META) && (ultimoDigito != 0));

	if (ultimoDigito == 0) turno = Nadie;
	//Si el jugador abandona, no gana nadie

	return turno;
}

//Decide aleatoriamente quien empieza la partida, si el automata o el jugador
tJugador quienEmpieza(){
	if (rand() % 2){
		cout << "Tu empiezas";
		return Jugador;
	}
	else{
		cout"Empiezo yo";
		return Automata;
	}
}
//Define que números se encuentran en la misma fila que el ultimo pulsado
bool mismaFila(int ultimo, int nuevo){
	double filaUltimo, filaNuevo;
	filaUltimo = (ultimo/3);
	filaNuevo = (nuevo/3);
	return ceil(filaUltimo) == ceil(filaNuevo);
}
//Define que números se encuentran en la misma columna que el ultimo
bool mismaColumna(int ultimo, int nuevo){
	int columnaUltimo, columnaNuevo;
	columnaUltimo = (ultimo % 3);
	columnaNuevo = (nuevo % 3);
	return columnaUltimo == columnaNuevo;
}
//Determina que digitos se pueden pulsar en función de las reglas del juego
bool digitoValido(int ultimo, int nuevo){
	return ((mismaFila(int ultimo, int nuevo))||(mismaColumna(int ultimo, int nuevo)))&&(ultimo!=nuevo);
}
//Genera un dígito aleatorio
int digitoAleatorio(){
	return (rand() % 9) + 1;
}
//Devuelve un digito que cumpla las reglas del juego con respecto a ultimo.
int digitoAutomata(int ultimo){
	int digito;

	do{
	digito = digitoAleatorio();
	}while (!digitoValido(ultimo, digito));

	cout << "Elijo el numero " << digito;

	return digito;
}

//Pide un digito al jugador. Solo devolvera un valor valido (entre 0 y 9).
//Para un valor no válido, mostrará un error.
int digitoPersona(){
	int digito;

	do{
		try{
			cin.sync(); //Por si quedan datos basura en el buffer
			cin >> digito;
			if (digito < 0 || digito > 9) throw;
		}catch(...){
			cout << "Error! Introduce un digito entre 0-9";
			digito = -1;
		}
	}while (digito == -1);

	return digito;
}

//Pide un digito al jugador mostrando el teclado. Solo devolvera un valor
//que cumpla las reglas del juego o 0. Para un valor no valido, mostrara un error.
int digitoPersona(int ultimo){
	int digito; //-1 es mi error flag

	mostrarCalculadora(ultimo);

	do{
		try{
			digito = digitoPersona();
			if (!digitoValido(ultimo, digito)) throw;
		}catch(...){
			cout << "Error! El digito debe estar en la misma fila y columna que el ultimo";
			digito = -1;
		}
	}while (digito == -1);

	cout << "Has elegido el" << digito;

	return digito;
}

char mNumero(int ultimo, int n){
	if(digitoValido(ultimo, n) return char (n+int('0'));
	else return ' ';
}

void mostrarCalculadora(ultimo){
	for (int i = 7; i<10; i++){
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
	for (int i = 4; i<7; i++){
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
	for (int i = 1; i<4; i++){
		cout << setw(3) << mNumero(ultimo, i);
	}
	cout << endl;
}
<|endoftext|>


<commit_before><commit_msg>Emit event on all Xiaomi special reports<commit_after><|endoftext|>


<commit_before><commit_msg>Update xiaomi.cpp<commit_after><|endoftext|>


<commit_before>/*
 * ConnectedComponents.cpp
 *
 *  Created on: Dec 16, 2013
 *      Author: cls
 */

#include <set>

#include "ParallelConnectedComponents.h"
#include "../structures/Partition.h"
#include "../coarsening/PartitionCoarsening.h"
#include "../auxiliary/Log.h"

namespace NetworKit {

ParallelConnectedComponents::ParallelConnectedComponents(const Graph& G, bool coarsening) : G(G), coarsening(coarsening) {

}

void ParallelConnectedComponents::run() {
	if (G.isDirected()) {
		throw std::runtime_error("algorithm does not accept directed graphs");
	}

	// calculate connected components by label propagation
	count z = G.numberOfNodes();

	DEBUG("initializing labels");
	component = Partition(G.upperNodeIdBound());
	component.allToSingletons();

	DEBUG("initializing active nodes");
	const char INACTIVE = 0;
	const char ACTIVE = 1;
	std::vector<char> activeNodes(z); // record if node must be processed
	std::vector<char> nextActiveNodes(z, ACTIVE); // for next iteration
	nextActiveNodes.assign(z, ACTIVE);
	G.forNodes([&](node u) { // NOTE: not in parallel due to implementation of bit vector
		if (G.degree(u) == 0) {
			nextActiveNodes[u] = INACTIVE;
		}
	});

	DEBUG("main loop");
//	count numActive = 0; // for debugging purposes only
	count numIterations = 0;
	bool change = false;
	do {
//		TRACE("label propagation iteration");
		activeNodes = nextActiveNodes;
		nextActiveNodes.assign(z, INACTIVE);
		change = false;
//		numActive = 0;
		G.parallelForNodes([&](node u) {
			if (activeNodes[u] == ACTIVE) {
//				++numActive;
				// get smallest
				index smallest = component[u];
				G.forNeighborsOf(u, [&](node v) {
					smallest = std::min(smallest, component[v]);
				});

				if (component[u] != smallest) {
					component.moveToSubset(smallest, u);
					change = true;
					G.forNeighborsOf(u, [&](node v) {
						nextActiveNodes[v] = ACTIVE;
					});
				}
//				else {
//					nextActiveNodes[u] = INACTIVE; // current node becomes inactive
//				}
			}
		});
//		TRACE("num active: ", numActive);
		++numIterations;
		if (coarsening && (numIterations % 8) == 0) { // TODO: externalize constant
			// coarsen and make recursive call
			PartitionCoarsening con;
			std::pair<Graph, std::vector<node> > coarse = con.run(G, component);
			ParallelConnectedComponents cc(coarse.first);
			cc.run();

			// apply to current graph
			G.forNodes([&](node u) {
				component[u] = cc.componentOfNode(coarse.second[u]);
			});
		}
	} while (change);
}

void ParallelConnectedComponents::runSequential() {
	if (G.isDirected()) {
		throw std::runtime_error("algorithm does not accept directed graphs");
	}
	// calculate connected components by label propagation
	count z = G.numberOfNodes();
	DEBUG("initializing labels");
	component = Partition(G.upperNodeIdBound());
	component.allToSingletons();
	DEBUG("initializing active nodes");
	std::vector<bool> activeNodes(z); // record if node must be processed
	activeNodes.assign(z, true);
	G.forNodes([&](node u) { // NOTE: not in parallel due to implementation of bit vector
		if (G.degree(u) == 0) {
			activeNodes[u] = false;
		}
	});
	DEBUG("main loop");
	// count numActive = 0; // for debugging purposes only
	count numIterations = 0;
	bool change = false;
	do {
		// TRACE("label propagation iteration");
		change = false;
		// numActive = 0;
		G.forNodes([&](node u) {
			if (activeNodes[u]) {
				// ++numActive;
				std::vector<index> neighborLabels;
				G.forNeighborsOf(u, [&](node v) {
					// neighborLabels.push_back(component[v]);
					neighborLabels.push_back(component[v]);
				});
				// get smallest
				index smallest = *std::min_element(neighborLabels.begin(), neighborLabels.end());
				if (component[u] != smallest) {
					component.moveToSubset(smallest, u);
					change = true;
					G.forNeighborsOf(u, [&](node v) {
						activeNodes[v] = true;
					});
				} else {
					activeNodes[u] = false; // current node becomes inactive
				}
			}
		});
		// TRACE("num active: ", numActive);
		++numIterations;
		if ((numIterations % 8) == 0) { // TODO: externalize constant
			// coarsen and make recursive call
			PartitionCoarsening con;
			std::pair<Graph, std::vector<node> > coarse = con.run(G, component);
			ParallelConnectedComponents cc(coarse.first);
			cc.run();
			// apply to current graph
			G.forNodes([&](node u) {
				component[u] = cc.componentOfNode(coarse.second[u]);
			});
		}
	} while (change);
}

Partition ParallelConnectedComponents::getPartition() {
	return this->component;
}

count ParallelConnectedComponents::numberOfComponents() {
	return this->component.numberOfSubsets();
}

count ParallelConnectedComponents::componentOfNode(node u) {
	assert (component[u] != none);
	return component[u];
}

}
<commit_msg>ParallelConnectedComponents: optimized and restructured the code<commit_after>/*
 * ConnectedComponents.cpp
 *
 *  Created on: Dec 16, 2013
 *      Author: cls
 */

#include <set>

#include "ParallelConnectedComponents.h"
#include "../structures/Partition.h"
#include "../coarsening/PartitionCoarsening.h"
#include "../auxiliary/Log.h"

namespace NetworKit {

ParallelConnectedComponents::ParallelConnectedComponents(const Graph& G, bool coarsening) : G(G), coarsening(coarsening) {

}

void ParallelConnectedComponents::run() {
	if (G.isDirected()) {
		throw std::runtime_error("algorithm does not accept directed graphs");
	}

	// calculate connected components by label propagation
	count z = G.numberOfNodes();

	DEBUG("initializing labels");
	component = Partition(G.upperNodeIdBound());
	component.allToSingletons();

	DEBUG("initializing active nodes");
	const char INACTIVE = 0;
	const char ACTIVE = 1;
	std::vector<char> activeNodes(z); // record if node must be processed
	std::vector<char> nextActiveNodes(z, ACTIVE); // for next iteration

	DEBUG("main loop");
//	count numActive = 0; // for debugging purposes only
	count numIterations = 0;
	bool change = true;
	// only 8 iterations when coarsening is on, otherwise till no more changes happened
	while (change && (!coarsening || numIterations < 8)) {
//		TRACE("label propagation iteration");
		activeNodes.swap(nextActiveNodes);
		nextActiveNodes.assign(z, INACTIVE);
		change = false;
//		numActive = 0;
		G.balancedParallelForNodes([&](node u) {
			if (activeNodes[u] == ACTIVE) {
//				++numActive;
				// get smallest
				index smallest = component[u];
				G.forNeighborsOf(u, [&](node v) {
					smallest = std::min(smallest, component[v]);
				});

				if (component[u] != smallest) {
					component.moveToSubset(smallest, u);
					change = true;
					G.forNeighborsOf(u, [&](node v) {
						// only nodes that do not have the smallest component label
						// will see a new component label because of the change of u,
						// only they need to be activated
						if (component[v] != smallest) {
							nextActiveNodes[v] = ACTIVE;
						}
					});
				}
			}
		});
//		TRACE("num active: ", numActive);
		++numIterations;
	}
	if (coarsening && numIterations == 8) { // TODO: externalize constant
		// coarsen and make recursive call
		PartitionCoarsening con;
		std::pair<Graph, std::vector<node> > coarse = con.run(G, component);
		ParallelConnectedComponents cc(coarse.first);
		cc.run();

		// apply to current graph
		G.parallelForNodes([&](node u) {
			component[u] = cc.componentOfNode(coarse.second[u]);
		});
	}
}

void ParallelConnectedComponents::runSequential() {
	if (G.isDirected()) {
		throw std::runtime_error("algorithm does not accept directed graphs");
	}
	// calculate connected components by label propagation
	count z = G.numberOfNodes();
	DEBUG("initializing labels");
	component = Partition(G.upperNodeIdBound());
	component.allToSingletons();
	DEBUG("initializing active nodes");
	std::vector<bool> activeNodes(z); // record if node must be processed
	activeNodes.assign(z, true);
	G.forNodes([&](node u) { // NOTE: not in parallel due to implementation of bit vector
		if (G.degree(u) == 0) {
			activeNodes[u] = false;
		}
	});
	DEBUG("main loop");
	// count numActive = 0; // for debugging purposes only
	count numIterations = 0;
	bool change = false;
	do {
		// TRACE("label propagation iteration");
		change = false;
		// numActive = 0;
		G.forNodes([&](node u) {
			if (activeNodes[u]) {
				// ++numActive;
				std::vector<index> neighborLabels;
				G.forNeighborsOf(u, [&](node v) {
					// neighborLabels.push_back(component[v]);
					neighborLabels.push_back(component[v]);
				});
				// get smallest
				index smallest = *std::min_element(neighborLabels.begin(), neighborLabels.end());
				if (component[u] != smallest) {
					component.moveToSubset(smallest, u);
					change = true;
					G.forNeighborsOf(u, [&](node v) {
						activeNodes[v] = true;
					});
				} else {
					activeNodes[u] = false; // current node becomes inactive
				}
			}
		});
		// TRACE("num active: ", numActive);
		++numIterations;
		if ((numIterations % 8) == 0) { // TODO: externalize constant
			// coarsen and make recursive call
			PartitionCoarsening con;
			std::pair<Graph, std::vector<node> > coarse = con.run(G, component);
			ParallelConnectedComponents cc(coarse.first);
			cc.run();
			// apply to current graph
			G.forNodes([&](node u) {
				component[u] = cc.componentOfNode(coarse.second[u]);
			});
		}
	} while (change);
}

Partition ParallelConnectedComponents::getPartition() {
	return this->component;
}

count ParallelConnectedComponents::numberOfComponents() {
	return this->component.numberOfSubsets();
}

count ParallelConnectedComponents::componentOfNode(node u) {
	assert (component[u] != none);
	return component[u];
}

}
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "statespace_testfixture.h"

#include "gtest/gtest.h"

#if defined(__AVX512F__) && !defined(_WIN32) && !defined(__SANITIZE_ADDRESS__)

#ifdef _OPENMP
#include "../lib/parfor.h"
#endif
#include "../lib/seqfor.h"
#include "../lib/simulator_avx512.h"
#include "../lib/statespace_avx512.h"

namespace qsim {

template <class T>
class StateSpaceAVX512Test : public testing::Test {};

using ::testing::Types;
#ifdef _OPENMP
typedef Types<ParallelFor, SequentialFor> for_impl;
#else
typedef Types<SequentialFor> for_impl;
#endif

template <typename For>
struct Factory {
  using Simulator = SimulatorAVX512<For>;
  using StateSpace = typename Simulator::StateSpace;

  static StateSpace CreateStateSpace() {
    return StateSpace(2);
  }

  static Simulator CreateSimulator() {
    return Simulator(2);
  }
};

TYPED_TEST_SUITE(StateSpaceAVX512Test, for_impl);

TYPED_TEST(StateSpaceAVX512Test, Add) {
  TestAdd(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, NormSmall) {
  TestNormSmall(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, NormAndInnerProductSmall) {
  TestNormAndInnerProductSmall(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, NormAndInnerProduct) {
  TestNormAndInnerProduct(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, SamplingSmall) {
  TestSamplingSmall(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, SamplingCrossEntropyDifference) {
  TestSamplingCrossEntropyDifference(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, Ordering) {
  TestOrdering(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, MeasurementSmall) {
  TestMeasurementSmall(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, MeasurementLarge) {
  TestMeasurementLarge(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, Collapse) {
  TestCollapse(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, InvalidStateSize) {
  TestInvalidStateSize(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, BulkSetAmpl) {
  TestBulkSetAmplitude(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, BulkSetAmplExclude) {
  TestBulkSetAmplitudeExclusion(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, BulkSetAmplDefault) {
  TestBulkSetAmplitudeDefault(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, ThreadThrashing) {
  TestThreadThrashing<StateSpaceAVX512<TypeParam>>();
}

}  // namespace qsim

#endif  // defined(__AVX512F__) && !defined(_WIN32) && !defined(__SANITIZE_ADDRESS__)

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>Allow AVX512 + sanitizer, part 2/4<commit_after>// Copyright 2019 Google LLC. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "statespace_testfixture.h"

#include "gtest/gtest.h"

#if defined(__AVX512F__) && !defined(_WIN32)

#ifdef _OPENMP
#include "../lib/parfor.h"
#endif
#include "../lib/seqfor.h"
#include "../lib/simulator_avx512.h"
#include "../lib/statespace_avx512.h"

namespace qsim {

template <class T>
class StateSpaceAVX512Test : public testing::Test {};

using ::testing::Types;
#ifdef _OPENMP
typedef Types<ParallelFor, SequentialFor> for_impl;
#else
typedef Types<SequentialFor> for_impl;
#endif

template <typename For>
struct Factory {
  using Simulator = SimulatorAVX512<For>;
  using StateSpace = typename Simulator::StateSpace;

  static StateSpace CreateStateSpace() {
    return StateSpace(2);
  }

  static Simulator CreateSimulator() {
    return Simulator(2);
  }
};

TYPED_TEST_SUITE(StateSpaceAVX512Test, for_impl);

TYPED_TEST(StateSpaceAVX512Test, Add) {
  TestAdd(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, NormSmall) {
  TestNormSmall(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, NormAndInnerProductSmall) {
  TestNormAndInnerProductSmall(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, NormAndInnerProduct) {
  TestNormAndInnerProduct(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, SamplingSmall) {
  TestSamplingSmall(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, SamplingCrossEntropyDifference) {
  TestSamplingCrossEntropyDifference(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, Ordering) {
  TestOrdering(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, MeasurementSmall) {
  TestMeasurementSmall(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, MeasurementLarge) {
  TestMeasurementLarge(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, Collapse) {
  TestCollapse(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, InvalidStateSize) {
  TestInvalidStateSize(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, BulkSetAmpl) {
  TestBulkSetAmplitude(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, BulkSetAmplExclude) {
  TestBulkSetAmplitudeExclusion(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, BulkSetAmplDefault) {
  TestBulkSetAmplitudeDefault(Factory<TypeParam>());
}

TYPED_TEST(StateSpaceAVX512Test, ThreadThrashing) {
  TestThreadThrashing<StateSpaceAVX512<TypeParam>>();
}

}  // namespace qsim

#endif  // defined(__AVX512F__) && !defined(_WIN32)

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>//===--- extra/modularize/ModularizeUtilities.cpp -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a class for loading and validating a module map or
// header list by checking that all headers in the corresponding directories
// are accounted for.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/SourceManager.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "CoverageChecker.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "ModularizeUtilities.h"

using namespace clang;
using namespace llvm;
using namespace Modularize;

// Subclass TargetOptions so we can construct it inline with
// the minimal option, the triple.
class ModuleMapTargetOptions : public clang::TargetOptions {
public:
  ModuleMapTargetOptions() { Triple = llvm::sys::getDefaultTargetTriple(); }
};

// ModularizeUtilities class implementation.

// Constructor.
ModularizeUtilities::ModularizeUtilities(std::vector<std::string> &InputPaths,
                                         llvm::StringRef Prefix)
  : InputFilePaths(InputPaths),
    HeaderPrefix(Prefix),
    HasModuleMap(false),
    // Init clang stuff needed for loading the module map and preprocessing.
    LangOpts(new LangOptions()), DiagIDs(new DiagnosticIDs()),
    DiagnosticOpts(new DiagnosticOptions()),
    DC(llvm::errs(), DiagnosticOpts.get()),
    Diagnostics(
    new DiagnosticsEngine(DiagIDs, DiagnosticOpts.get(), &DC, false)),
    TargetOpts(new ModuleMapTargetOptions()),
    Target(TargetInfo::CreateTargetInfo(*Diagnostics, TargetOpts)),
    FileMgr(new FileManager(FileSystemOpts)),
    SourceMgr(new SourceManager(*Diagnostics, *FileMgr, false)),
    HeaderSearchOpts(new HeaderSearchOptions()),
    HeaderInfo(new HeaderSearch(HeaderSearchOpts, *SourceMgr, *Diagnostics,
    *LangOpts, Target.get())) {
}

// Create instance of ModularizeUtilities, to simplify setting up
// subordinate objects.
ModularizeUtilities *ModularizeUtilities::createModularizeUtilities(
    std::vector<std::string> &InputPaths, llvm::StringRef Prefix) {

  return new ModularizeUtilities(InputPaths, Prefix);
}

// Load all header lists and dependencies.
std::error_code ModularizeUtilities::loadAllHeaderListsAndDependencies() {
  typedef std::vector<std::string>::iterator Iter;
  // For each input file.
  for (Iter I = InputFilePaths.begin(), E = InputFilePaths.end(); I != E; ++I) {
    llvm::StringRef InputPath = *I;
    // If it's a module map.
    if (InputPath.endswith(".modulemap")) {
      // Load the module map.
      if (std::error_code EC = loadModuleMap(InputPath))
        return EC;
    }
    else {
      // Else we assume it's a header list and load it.
      if (std::error_code EC = loadSingleHeaderListsAndDependencies(InputPath)) {
        errs() << "modularize: error: Unable to get header list '" << InputPath
          << "': " << EC.message() << '\n';
        return EC;
      }
    }
  }
  return std::error_code();
}

// Do coverage checks.
// For each loaded module map, do header coverage check.
// Starting from the directory of the module.map file,
// Find all header files, optionally looking only at files
// covered by the include path options, and compare against
// the headers referenced by the module.map file.
// Display warnings for unaccounted-for header files.
// Returns 0 if there were no errors or warnings, 1 if there
// were warnings, 2 if any other problem, such as a bad
// module map path argument was specified.
std::error_code ModularizeUtilities::doCoverageCheck(
    std::vector<std::string> &IncludePaths,
    llvm::ArrayRef<std::string> CommandLine) {
  int ModuleMapCount = ModuleMaps.size();
  int ModuleMapIndex;
  std::error_code EC;
  for (ModuleMapIndex = 0; ModuleMapIndex < ModuleMapCount; ++ModuleMapIndex) {
    std::unique_ptr<clang::ModuleMap> &ModMap = ModuleMaps[ModuleMapIndex];
    CoverageChecker *Checker = CoverageChecker::createCoverageChecker(
      InputFilePaths[ModuleMapIndex], IncludePaths, CommandLine, ModMap.get());
    std::error_code LocalEC = Checker->doChecks();
    if (LocalEC.value() > 0)
      EC = LocalEC;
  }
  return EC;
}

// Load single header list and dependencies.
std::error_code ModularizeUtilities::loadSingleHeaderListsAndDependencies(
    llvm::StringRef InputPath) {

  // By default, use the path component of the list file name.
  SmallString<256> HeaderDirectory(InputPath);
  llvm::sys::path::remove_filename(HeaderDirectory);
  SmallString<256> CurrentDirectory;
  llvm::sys::fs::current_path(CurrentDirectory);

  // Get the prefix if we have one.
  if (HeaderPrefix.size() != 0)
    HeaderDirectory = HeaderPrefix;

  // Read the header list file into a buffer.
  ErrorOr<std::unique_ptr<MemoryBuffer>> listBuffer =
    MemoryBuffer::getFile(InputPath);
  if (std::error_code EC = listBuffer.getError())
    return EC;

  // Parse the header list into strings.
  SmallVector<StringRef, 32> Strings;
  listBuffer.get()->getBuffer().split(Strings, "\n", -1, false);

  // Collect the header file names from the string list.
  for (SmallVectorImpl<StringRef>::iterator I = Strings.begin(),
    E = Strings.end();
    I != E; ++I) {
    StringRef Line = I->trim();
    // Ignore comments and empty lines.
    if (Line.empty() || (Line[0] == '#'))
      continue;
    std::pair<StringRef, StringRef> TargetAndDependents = Line.split(':');
    SmallString<256> HeaderFileName;
    // Prepend header file name prefix if it's not absolute.
    if (llvm::sys::path::is_absolute(TargetAndDependents.first))
      llvm::sys::path::native(TargetAndDependents.first, HeaderFileName);
    else {
      if (HeaderDirectory.size() != 0)
        HeaderFileName = HeaderDirectory;
      else
        HeaderFileName = CurrentDirectory;
      llvm::sys::path::append(HeaderFileName, TargetAndDependents.first);
      llvm::sys::path::native(HeaderFileName);
    }
    // Handle optional dependencies.
    DependentsVector Dependents;
    SmallVector<StringRef, 4> DependentsList;
    TargetAndDependents.second.split(DependentsList, " ", -1, false);
    int Count = DependentsList.size();
    for (int Index = 0; Index < Count; ++Index) {
      SmallString<256> Dependent;
      if (llvm::sys::path::is_absolute(DependentsList[Index]))
        Dependent = DependentsList[Index];
      else {
        if (HeaderDirectory.size() != 0)
          Dependent = HeaderDirectory;
        else
          Dependent = CurrentDirectory;
        llvm::sys::path::append(Dependent, DependentsList[Index]);
      }
      llvm::sys::path::native(Dependent);
      Dependents.push_back(getCanonicalPath(Dependent.str()));
    }
    // Get canonical form.
    HeaderFileName = getCanonicalPath(HeaderFileName);
    // Save the resulting header file path and dependencies.
    HeaderFileNames.push_back(HeaderFileName.str());
    Dependencies[HeaderFileName.str()] = Dependents;
  }
  return std::error_code();
}

// Load single module map and extract header file list.
std::error_code ModularizeUtilities::loadModuleMap(
    llvm::StringRef InputPath) {
  // Get file entry for module.modulemap file.
  const FileEntry *ModuleMapEntry =
    SourceMgr->getFileManager().getFile(InputPath);

  // return error if not found.
  if (!ModuleMapEntry) {
    llvm::errs() << "error: File \"" << InputPath << "\" not found.\n";
    return std::error_code(1, std::generic_category());
  }

  // Because the module map parser uses a ForwardingDiagnosticConsumer,
  // which doesn't forward the BeginSourceFile call, we do it explicitly here.
  DC.BeginSourceFile(*LangOpts, nullptr);

  // Figure out the home directory for the module map file.
  const DirectoryEntry *Dir = ModuleMapEntry->getDir();
  StringRef DirName(Dir->getName());
  if (llvm::sys::path::filename(DirName) == "Modules") {
    DirName = llvm::sys::path::parent_path(DirName);
    if (DirName.endswith(".framework"))
      Dir = FileMgr->getDirectory(DirName);
    // FIXME: This assert can fail if there's a race between the above check
    // and the removal of the directory.
    assert(Dir && "parent must exist");
  }

  std::unique_ptr<ModuleMap> ModMap;
  ModMap.reset(new ModuleMap(*SourceMgr, *Diagnostics, *LangOpts,
    Target.get(), *HeaderInfo));

  // Parse module.modulemap file into module map.
  if (ModMap->parseModuleMapFile(ModuleMapEntry, false, Dir)) {
    return std::error_code(1, std::generic_category());
  }

  // Do matching end call.
  DC.EndSourceFile();

  if (!collectModuleMapHeaders(ModMap.get()))
    return std::error_code(1, std::generic_category());

  // Save module map.
  ModuleMaps.push_back(std::move(ModMap));

  // Indicate we are using module maps.
  HasModuleMap = true;

  return std::error_code();
}

// Collect module map headers.
// Walks the modules and collects referenced headers into
// HeaderFileNames.
bool ModularizeUtilities::collectModuleMapHeaders(clang::ModuleMap *ModMap) {
  for (ModuleMap::module_iterator I = ModMap->module_begin(),
    E = ModMap->module_end();
    I != E; ++I) {
    if (!collectModuleHeaders(*I->second))
      return false;
  }
  return true;
}

// Collect referenced headers from one module.
// Collects the headers referenced in the given module into
// HeaderFileNames.
bool ModularizeUtilities::collectModuleHeaders(const Module &Mod) {

  // Ignore explicit modules because they often have dependencies
  // we can't know.
  if (Mod.IsExplicit)
    return true;

  // Treat headers in umbrella directory as dependencies.
  DependentsVector UmbrellaDependents;

  // Recursively do submodules.
  for (Module::submodule_const_iterator MI = Mod.submodule_begin(),
      MIEnd = Mod.submodule_end();
      MI != MIEnd; ++MI)
    collectModuleHeaders(**MI);

  if (const FileEntry *UmbrellaHeader = Mod.getUmbrellaHeader()) {
    std::string HeaderPath = getCanonicalPath(UmbrellaHeader->getName());
    // Collect umbrella header.
    HeaderFileNames.push_back(HeaderPath);

    // FUTURE: When needed, umbrella header header collection goes here.
  }
  else if (const DirectoryEntry *UmbrellaDir = Mod.getUmbrellaDir()) {
    // If there normal headers, assume these are umbrellas and skip collection.
    if (Mod.Headers->size() == 0) {
      // Collect headers in umbrella directory.
      if (!collectUmbrellaHeaders(UmbrellaDir->getName(), UmbrellaDependents))
        return false;
    }
  }

  // We ignore HK_Private, HK_Textual, HK_PrivateTextual, and HK_Excluded,
  // assuming they are marked as such either because of unsuitability for
  // modules or because they are meant to be included by another header,
  // and thus should be ignored by modularize.

  int NormalHeaderCount = Mod.Headers[clang::Module::HK_Normal].size();

  for (int Index = 0; Index < NormalHeaderCount; ++Index) {
    DependentsVector NormalDependents;
    // Collect normal header.
    const clang::Module::Header &Header(
      Mod.Headers[clang::Module::HK_Normal][Index]);
    std::string HeaderPath = getCanonicalPath(Header.Entry->getName());
    HeaderFileNames.push_back(HeaderPath);
  }

  return true;
}

// Collect headers from an umbrella directory.
bool ModularizeUtilities::collectUmbrellaHeaders(StringRef UmbrellaDirName,
  DependentsVector &Dependents) {
  // Initialize directory name.
  SmallString<256> Directory(UmbrellaDirName);
  // Walk the directory.
  std::error_code EC;
  llvm::sys::fs::file_status Status;
  for (llvm::sys::fs::directory_iterator I(Directory.str(), EC), E; I != E;
    I.increment(EC)) {
    if (EC)
      return false;
    std::string File(I->path());
    I->status(Status);
    llvm::sys::fs::file_type Type = Status.type();
    // If the file is a directory, ignore the name and recurse.
    if (Type == llvm::sys::fs::file_type::directory_file) {
      if (!collectUmbrellaHeaders(File, Dependents))
        return false;
      continue;
    }
    // If the file does not have a common header extension, ignore it.
    if (!isHeader(File))
      continue;
    // Save header name.
    std::string HeaderPath = getCanonicalPath(File);
    Dependents.push_back(HeaderPath);
  }
  return true;
}

std::string normalize(StringRef Path) {
  SmallString<128> Buffer;
  llvm::sys::path::const_iterator B = llvm::sys::path::begin(Path),
    E = llvm::sys::path::end(Path);
  while (B != E) {
    if (B->compare(".") == 0) {
    }
    else if (B->compare("..") == 0)
      llvm::sys::path::remove_filename(Buffer);
    else
      llvm::sys::path::append(Buffer, *B);
    ++B;
  }
  if (Path.endswith("/") || Path.endswith("\\"))
    Buffer.append(1, Path.back());
  return Buffer.c_str();
}

// Convert header path to canonical form.
// The canonical form is basically just use forward slashes, and remove "./".
// \param FilePath The file path, relative to the module map directory.
// \returns The file path in canonical form.
std::string ModularizeUtilities::getCanonicalPath(StringRef FilePath) {
  std::string Tmp(normalize(FilePath));
  std::replace(Tmp.begin(), Tmp.end(), '\\', '/');
  StringRef Tmp2(Tmp);
  if (Tmp2.startswith("./"))
    Tmp = Tmp2.substr(2);
  return Tmp;
}

// Check for header file extension.
// If the file extension is .h, .inc, or missing, it's
// assumed to be a header.
// \param FileName The file name.  Must not be a directory.
// \returns true if it has a header extension or no extension.
bool ModularizeUtilities::isHeader(StringRef FileName) {
  StringRef Extension = llvm::sys::path::extension(FileName);
  if (Extension.size() == 0)
    return false;
  if (Extension.equals_lower(".h"))
    return true;
  if (Extension.equals_lower(".inc"))
    return true;
  return false;
}

// Get directory path component from file path.
// \returns the component of the given path, which will be
// relative if the given path is relative, absolute if the
// given path is absolute, or "." if the path has no leading
// path component.
std::string ModularizeUtilities::getDirectoryFromPath(StringRef Path) {
  SmallString<256> Directory(Path);
  sys::path::remove_filename(Directory);
  if (Directory.size() == 0)
    return ".";
  return Directory.str();
}
<commit_msg>Renamed function to avoid confusion about purpose.<commit_after>//===--- extra/modularize/ModularizeUtilities.cpp -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a class for loading and validating a module map or
// header list by checking that all headers in the corresponding directories
// are accounted for.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/SourceManager.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "CoverageChecker.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "ModularizeUtilities.h"

using namespace clang;
using namespace llvm;
using namespace Modularize;

// Subclass TargetOptions so we can construct it inline with
// the minimal option, the triple.
class ModuleMapTargetOptions : public clang::TargetOptions {
public:
  ModuleMapTargetOptions() { Triple = llvm::sys::getDefaultTargetTriple(); }
};

// ModularizeUtilities class implementation.

// Constructor.
ModularizeUtilities::ModularizeUtilities(std::vector<std::string> &InputPaths,
                                         llvm::StringRef Prefix)
  : InputFilePaths(InputPaths),
    HeaderPrefix(Prefix),
    HasModuleMap(false),
    // Init clang stuff needed for loading the module map and preprocessing.
    LangOpts(new LangOptions()), DiagIDs(new DiagnosticIDs()),
    DiagnosticOpts(new DiagnosticOptions()),
    DC(llvm::errs(), DiagnosticOpts.get()),
    Diagnostics(
    new DiagnosticsEngine(DiagIDs, DiagnosticOpts.get(), &DC, false)),
    TargetOpts(new ModuleMapTargetOptions()),
    Target(TargetInfo::CreateTargetInfo(*Diagnostics, TargetOpts)),
    FileMgr(new FileManager(FileSystemOpts)),
    SourceMgr(new SourceManager(*Diagnostics, *FileMgr, false)),
    HeaderSearchOpts(new HeaderSearchOptions()),
    HeaderInfo(new HeaderSearch(HeaderSearchOpts, *SourceMgr, *Diagnostics,
    *LangOpts, Target.get())) {
}

// Create instance of ModularizeUtilities, to simplify setting up
// subordinate objects.
ModularizeUtilities *ModularizeUtilities::createModularizeUtilities(
    std::vector<std::string> &InputPaths, llvm::StringRef Prefix) {

  return new ModularizeUtilities(InputPaths, Prefix);
}

// Load all header lists and dependencies.
std::error_code ModularizeUtilities::loadAllHeaderListsAndDependencies() {
  typedef std::vector<std::string>::iterator Iter;
  // For each input file.
  for (Iter I = InputFilePaths.begin(), E = InputFilePaths.end(); I != E; ++I) {
    llvm::StringRef InputPath = *I;
    // If it's a module map.
    if (InputPath.endswith(".modulemap")) {
      // Load the module map.
      if (std::error_code EC = loadModuleMap(InputPath))
        return EC;
    }
    else {
      // Else we assume it's a header list and load it.
      if (std::error_code EC = loadSingleHeaderListsAndDependencies(InputPath)) {
        errs() << "modularize: error: Unable to get header list '" << InputPath
          << "': " << EC.message() << '\n';
        return EC;
      }
    }
  }
  return std::error_code();
}

// Do coverage checks.
// For each loaded module map, do header coverage check.
// Starting from the directory of the module.map file,
// Find all header files, optionally looking only at files
// covered by the include path options, and compare against
// the headers referenced by the module.map file.
// Display warnings for unaccounted-for header files.
// Returns 0 if there were no errors or warnings, 1 if there
// were warnings, 2 if any other problem, such as a bad
// module map path argument was specified.
std::error_code ModularizeUtilities::doCoverageCheck(
    std::vector<std::string> &IncludePaths,
    llvm::ArrayRef<std::string> CommandLine) {
  int ModuleMapCount = ModuleMaps.size();
  int ModuleMapIndex;
  std::error_code EC;
  for (ModuleMapIndex = 0; ModuleMapIndex < ModuleMapCount; ++ModuleMapIndex) {
    std::unique_ptr<clang::ModuleMap> &ModMap = ModuleMaps[ModuleMapIndex];
    CoverageChecker *Checker = CoverageChecker::createCoverageChecker(
      InputFilePaths[ModuleMapIndex], IncludePaths, CommandLine, ModMap.get());
    std::error_code LocalEC = Checker->doChecks();
    if (LocalEC.value() > 0)
      EC = LocalEC;
  }
  return EC;
}

// Load single header list and dependencies.
std::error_code ModularizeUtilities::loadSingleHeaderListsAndDependencies(
    llvm::StringRef InputPath) {

  // By default, use the path component of the list file name.
  SmallString<256> HeaderDirectory(InputPath);
  llvm::sys::path::remove_filename(HeaderDirectory);
  SmallString<256> CurrentDirectory;
  llvm::sys::fs::current_path(CurrentDirectory);

  // Get the prefix if we have one.
  if (HeaderPrefix.size() != 0)
    HeaderDirectory = HeaderPrefix;

  // Read the header list file into a buffer.
  ErrorOr<std::unique_ptr<MemoryBuffer>> listBuffer =
    MemoryBuffer::getFile(InputPath);
  if (std::error_code EC = listBuffer.getError())
    return EC;

  // Parse the header list into strings.
  SmallVector<StringRef, 32> Strings;
  listBuffer.get()->getBuffer().split(Strings, "\n", -1, false);

  // Collect the header file names from the string list.
  for (SmallVectorImpl<StringRef>::iterator I = Strings.begin(),
    E = Strings.end();
    I != E; ++I) {
    StringRef Line = I->trim();
    // Ignore comments and empty lines.
    if (Line.empty() || (Line[0] == '#'))
      continue;
    std::pair<StringRef, StringRef> TargetAndDependents = Line.split(':');
    SmallString<256> HeaderFileName;
    // Prepend header file name prefix if it's not absolute.
    if (llvm::sys::path::is_absolute(TargetAndDependents.first))
      llvm::sys::path::native(TargetAndDependents.first, HeaderFileName);
    else {
      if (HeaderDirectory.size() != 0)
        HeaderFileName = HeaderDirectory;
      else
        HeaderFileName = CurrentDirectory;
      llvm::sys::path::append(HeaderFileName, TargetAndDependents.first);
      llvm::sys::path::native(HeaderFileName);
    }
    // Handle optional dependencies.
    DependentsVector Dependents;
    SmallVector<StringRef, 4> DependentsList;
    TargetAndDependents.second.split(DependentsList, " ", -1, false);
    int Count = DependentsList.size();
    for (int Index = 0; Index < Count; ++Index) {
      SmallString<256> Dependent;
      if (llvm::sys::path::is_absolute(DependentsList[Index]))
        Dependent = DependentsList[Index];
      else {
        if (HeaderDirectory.size() != 0)
          Dependent = HeaderDirectory;
        else
          Dependent = CurrentDirectory;
        llvm::sys::path::append(Dependent, DependentsList[Index]);
      }
      llvm::sys::path::native(Dependent);
      Dependents.push_back(getCanonicalPath(Dependent.str()));
    }
    // Get canonical form.
    HeaderFileName = getCanonicalPath(HeaderFileName);
    // Save the resulting header file path and dependencies.
    HeaderFileNames.push_back(HeaderFileName.str());
    Dependencies[HeaderFileName.str()] = Dependents;
  }
  return std::error_code();
}

// Load single module map and extract header file list.
std::error_code ModularizeUtilities::loadModuleMap(
    llvm::StringRef InputPath) {
  // Get file entry for module.modulemap file.
  const FileEntry *ModuleMapEntry =
    SourceMgr->getFileManager().getFile(InputPath);

  // return error if not found.
  if (!ModuleMapEntry) {
    llvm::errs() << "error: File \"" << InputPath << "\" not found.\n";
    return std::error_code(1, std::generic_category());
  }

  // Because the module map parser uses a ForwardingDiagnosticConsumer,
  // which doesn't forward the BeginSourceFile call, we do it explicitly here.
  DC.BeginSourceFile(*LangOpts, nullptr);

  // Figure out the home directory for the module map file.
  const DirectoryEntry *Dir = ModuleMapEntry->getDir();
  StringRef DirName(Dir->getName());
  if (llvm::sys::path::filename(DirName) == "Modules") {
    DirName = llvm::sys::path::parent_path(DirName);
    if (DirName.endswith(".framework"))
      Dir = FileMgr->getDirectory(DirName);
    // FIXME: This assert can fail if there's a race between the above check
    // and the removal of the directory.
    assert(Dir && "parent must exist");
  }

  std::unique_ptr<ModuleMap> ModMap;
  ModMap.reset(new ModuleMap(*SourceMgr, *Diagnostics, *LangOpts,
    Target.get(), *HeaderInfo));

  // Parse module.modulemap file into module map.
  if (ModMap->parseModuleMapFile(ModuleMapEntry, false, Dir)) {
    return std::error_code(1, std::generic_category());
  }

  // Do matching end call.
  DC.EndSourceFile();

  if (!collectModuleMapHeaders(ModMap.get()))
    return std::error_code(1, std::generic_category());

  // Save module map.
  ModuleMaps.push_back(std::move(ModMap));

  // Indicate we are using module maps.
  HasModuleMap = true;

  return std::error_code();
}

// Collect module map headers.
// Walks the modules and collects referenced headers into
// HeaderFileNames.
bool ModularizeUtilities::collectModuleMapHeaders(clang::ModuleMap *ModMap) {
  for (ModuleMap::module_iterator I = ModMap->module_begin(),
    E = ModMap->module_end();
    I != E; ++I) {
    if (!collectModuleHeaders(*I->second))
      return false;
  }
  return true;
}

// Collect referenced headers from one module.
// Collects the headers referenced in the given module into
// HeaderFileNames.
bool ModularizeUtilities::collectModuleHeaders(const Module &Mod) {

  // Ignore explicit modules because they often have dependencies
  // we can't know.
  if (Mod.IsExplicit)
    return true;

  // Treat headers in umbrella directory as dependencies.
  DependentsVector UmbrellaDependents;

  // Recursively do submodules.
  for (Module::submodule_const_iterator MI = Mod.submodule_begin(),
      MIEnd = Mod.submodule_end();
      MI != MIEnd; ++MI)
    collectModuleHeaders(**MI);

  if (const FileEntry *UmbrellaHeader = Mod.getUmbrellaHeader()) {
    std::string HeaderPath = getCanonicalPath(UmbrellaHeader->getName());
    // Collect umbrella header.
    HeaderFileNames.push_back(HeaderPath);

    // FUTURE: When needed, umbrella header header collection goes here.
  }
  else if (const DirectoryEntry *UmbrellaDir = Mod.getUmbrellaDir()) {
    // If there normal headers, assume these are umbrellas and skip collection.
    if (Mod.Headers->size() == 0) {
      // Collect headers in umbrella directory.
      if (!collectUmbrellaHeaders(UmbrellaDir->getName(), UmbrellaDependents))
        return false;
    }
  }

  // We ignore HK_Private, HK_Textual, HK_PrivateTextual, and HK_Excluded,
  // assuming they are marked as such either because of unsuitability for
  // modules or because they are meant to be included by another header,
  // and thus should be ignored by modularize.

  int NormalHeaderCount = Mod.Headers[clang::Module::HK_Normal].size();

  for (int Index = 0; Index < NormalHeaderCount; ++Index) {
    DependentsVector NormalDependents;
    // Collect normal header.
    const clang::Module::Header &Header(
      Mod.Headers[clang::Module::HK_Normal][Index]);
    std::string HeaderPath = getCanonicalPath(Header.Entry->getName());
    HeaderFileNames.push_back(HeaderPath);
  }

  return true;
}

// Collect headers from an umbrella directory.
bool ModularizeUtilities::collectUmbrellaHeaders(StringRef UmbrellaDirName,
  DependentsVector &Dependents) {
  // Initialize directory name.
  SmallString<256> Directory(UmbrellaDirName);
  // Walk the directory.
  std::error_code EC;
  llvm::sys::fs::file_status Status;
  for (llvm::sys::fs::directory_iterator I(Directory.str(), EC), E; I != E;
    I.increment(EC)) {
    if (EC)
      return false;
    std::string File(I->path());
    I->status(Status);
    llvm::sys::fs::file_type Type = Status.type();
    // If the file is a directory, ignore the name and recurse.
    if (Type == llvm::sys::fs::file_type::directory_file) {
      if (!collectUmbrellaHeaders(File, Dependents))
        return false;
      continue;
    }
    // If the file does not have a common header extension, ignore it.
    if (!isHeader(File))
      continue;
    // Save header name.
    std::string HeaderPath = getCanonicalPath(File);
    Dependents.push_back(HeaderPath);
  }
  return true;
}

// Replace .. embedded in path for purposes of having
// a canonical path.
std::string replaceDotDot(StringRef Path) {
  SmallString<128> Buffer;
  llvm::sys::path::const_iterator B = llvm::sys::path::begin(Path),
    E = llvm::sys::path::end(Path);
  while (B != E) {
    if (B->compare(".") == 0) {
    }
    else if (B->compare("..") == 0)
      llvm::sys::path::remove_filename(Buffer);
    else
      llvm::sys::path::append(Buffer, *B);
    ++B;
  }
  if (Path.endswith("/") || Path.endswith("\\"))
    Buffer.append(1, Path.back());
  return Buffer.c_str();
}

// Convert header path to canonical form.
// The canonical form is basically just use forward slashes, and remove "./".
// \param FilePath The file path, relative to the module map directory.
// \returns The file path in canonical form.
std::string ModularizeUtilities::getCanonicalPath(StringRef FilePath) {
  std::string Tmp(replaceDotDot(FilePath));
  std::replace(Tmp.begin(), Tmp.end(), '\\', '/');
  StringRef Tmp2(Tmp);
  if (Tmp2.startswith("./"))
    Tmp = Tmp2.substr(2);
  return Tmp;
}

// Check for header file extension.
// If the file extension is .h, .inc, or missing, it's
// assumed to be a header.
// \param FileName The file name.  Must not be a directory.
// \returns true if it has a header extension or no extension.
bool ModularizeUtilities::isHeader(StringRef FileName) {
  StringRef Extension = llvm::sys::path::extension(FileName);
  if (Extension.size() == 0)
    return false;
  if (Extension.equals_lower(".h"))
    return true;
  if (Extension.equals_lower(".inc"))
    return true;
  return false;
}

// Get directory path component from file path.
// \returns the component of the given path, which will be
// relative if the given path is relative, absolute if the
// given path is absolute, or "." if the path has no leading
// path component.
std::string ModularizeUtilities::getDirectoryFromPath(StringRef Path) {
  SmallString<256> Directory(Path);
  sys::path::remove_filename(Directory);
  if (Directory.size() == 0)
    return ".";
  return Directory.str();
}
<|endoftext|>


<commit_before>#include "Bmrk.hpp"
#include "Bookmark.hpp"
#include "PageDownloader.hpp"
#include "PageParser.hpp"
#include "Library.hpp"

Bmrk::Bmrk(PageDownloaderPtr downloader, DatabasePtr db)
		: downloader_{downloader}
		, db_{db} {
			library_.reset(new Library);
			library_->connect(db);
}

std::future<BookmarkPtr> Bmrk::createBookmarkFromUrl(const std::string& url) const {
	return std::async(std::launch::async,
			[url, this]() {
				auto page = downloader_->load(url).get();
				auto properties = PageParser(page);
				return BookmarkPtr(
						new Bookmark{url, properties.getTitle(), Tags(), "note"});
			});
}

void Bmrk::add(BookmarkPtr bookmark) {
	library_->add(bookmark);
}
<commit_msg>fix Bmrk wrong notes<commit_after>#include "Bmrk.hpp"
#include "Bookmark.hpp"
#include "PageDownloader.hpp"
#include "PageParser.hpp"
#include "Library.hpp"

Bmrk::Bmrk(PageDownloaderPtr downloader, DatabasePtr db)
		: downloader_{downloader}
		, db_{db} {
			library_.reset(new Library);
			library_->connect(db);
}

std::future<BookmarkPtr> Bmrk::createBookmarkFromUrl(const std::string& url) const {
	return std::async(std::launch::async,
			[url, this]() {
				auto page = downloader_->load(url).get();
				auto properties = PageParser(page);
				return BookmarkPtr(
						new Bookmark{url, properties.getTitle(), Tags(), ""});
			});
}

void Bmrk::add(BookmarkPtr bookmark) {
	library_->add(bookmark);
}
<|endoftext|>


<commit_before>/*
  RF_Sniffer

  Hacked from http://code.google.com/p/rc-switch/

  by @justy to provide a handy RF code sniffer
*/

#include "RCSwitch.h"
#include <stdlib.h>
#include <stdio.h>

RCSwitch mySwitch;

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

     // This pin is not the first pin on the RPi GPIO header!
     // Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/
     // for more information.
     int PIN = 2;

     if(wiringPiSetup() == -1)
       return 0;

     mySwitch = RCSwitch();
     mySwitch.enableReceive(PIN);  // Receiver on inerrupt 0 => that is pin #2

     while(1) {

      if (mySwitch.available()) {

        int value = mySwitch.getReceivedValue();

        if (value == 0) {
          printf("Unknown encoding\n");
        } else {

          printf("Received %i\n", mySwitch.getReceivedValue() );
        }

        mySwitch.resetAvailable();

      }

  }

  exit(0);

}

<commit_msg>Added optional pulse length argument for RFSniffer<commit_after>/*
  RFSniffer

  Usage: ./RFSniffer [<pulseLength>]
  [] = optional

  Hacked from http://code.google.com/p/rc-switch/
  by @justy to provide a handy RF code sniffer
*/

#include "RCSwitch.h"
#include <stdlib.h>
#include <stdio.h>

RCSwitch mySwitch;

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

     // This pin is not the first pin on the RPi GPIO header!
     // Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/
     // for more information.
     int PIN = 2;

     if(wiringPiSetup() == -1) {
       printf("wiringPiSetup failed, exiting...");
       return 0;
     }

     int pulseLength = 0;
     if (argv[1] != NULL) pulseLength = atoi(argv[1]);

     mySwitch = RCSwitch();
	 if (pulseLength != 0) mySwitch.setPulseLength(pulseLength);
     mySwitch.enableReceive(PIN);  // Receiver on interrupt 0 => that is pin #2

     while(1) {

      if (mySwitch.available()) {

        int value = mySwitch.getReceivedValue();

        if (value == 0) {
          printf("Unknown encoding\n");
        } else {

          printf("Received %i\n", mySwitch.getReceivedValue() );
        }

        mySwitch.resetAvailable();

      }

  }

  exit(0);

}

<|endoftext|>


<commit_before>#include "StdAfx.h"
#include "MosDecoder.h"
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

namespace RawSpeed {

MosDecoder::MosDecoder(TiffIFD *rootIFD, FileMap* file)  :
    RawDecoder(file), mRootIFD(rootIFD) {
  decoderVersion = 0;
  black_level = 0;

  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MAKE);
  if (!data.empty()) {
    make = data[0]->getEntry(MAKE)->getString();
    model = data[0]->getEntry(MODEL)->getString();
  } else {
    TiffEntry *xmp = mRootIFD->getEntryRecursive(XMP);
    if (!xmp)
      ThrowRDE("MOS Decoder: Couldn't find the XMP");
    string xmpText = xmp->getString();
    make = getXMPTag(xmpText, "Make");
    model = getXMPTag(xmpText, "Model");
  }
}

MosDecoder::~MosDecoder(void) {
}

string MosDecoder::getXMPTag(string xmp, string tag) {
  string::size_type start = xmp.find("<tiff:"+tag+">");
  string::size_type end = xmp.find("</tiff:"+tag+">");
  if (start == string::npos || end == string::npos || end <= start)
    ThrowRDE("MOS Decoder: Couldn't find tag '%s' in the XMP", tag.c_str());
  int startlen = tag.size()+7;
  return xmp.substr(start+startlen, end-start-startlen);
}

RawImage MosDecoder::decodeRawInternal() {
  vector<TiffIFD*> data;
  TiffIFD* raw = NULL;
  uint32 off = 0;

  uint32 base = 8;
  const uchar8 *insideTiff = mFile->getData(base);
  if (get4LE(insideTiff, 0) == 0x49494949) {
    uint32 offset = get4LE(insideTiff, 8);
    if (offset+base+4 > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC offset out of bounds");

    uint32 entries = get4LE(insideTiff, offset);
    uint32 pos = 8; // Skip another 4 bytes

    uint32 width=0, height=0, strip_offset=0, data_offset=0;
    while (entries--) {
      if (offset+base+pos+16 > mFile->getSize())
        ThrowRDE("MOS: PhaseOneC offset out of bounds");

      uint32 tag  = get4LE(insideTiff, offset+pos);
      //uint32 type = get4LE(insideTiff, offset+pos+4);
      //uint32 len  = get4LE(insideTiff, offset+pos+8);
      uint32 data = get4LE(insideTiff, offset+pos+12);
      pos += 16;
      switch(tag) {
      case 0x108: width        = data;      break;
      case 0x109: height       = data;      break;
      case 0x10f: data_offset  = data+base; break;
      case 0x21c: strip_offset = data+base; break;
      case 0x21d: black_level  = data>>2;   break;
      }
    }
    if (width <= 0 || height <= 0)
      ThrowRDE("MOS: PhaseOneC couldn't find width and height");
    if (strip_offset+height*4 > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC strip offsets out of bounds");
    if (data_offset > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC data offset out of bounds");

    mRaw->dim = iPoint2D(width, height);
    mRaw->createData();

    DecodePhaseOneC(data_offset, strip_offset, width, height);

    return mRaw;
  } else {
    data = mRootIFD->getIFDsWithTag(TILEOFFSETS);
    if (!data.empty()) {
      raw = data[0];
      off = raw->getEntry(TILEOFFSETS)->getInt();
    } else {
      data = mRootIFD->getIFDsWithTag(CFAPATTERN);
      if (!data.empty()) {
        raw = data[0];
        off = raw->getEntry(STRIPOFFSETS)->getInt();
      } else
        ThrowRDE("MOS Decoder: No image data found");
    }
  }

  uint32 width = raw->getEntry(IMAGEWIDTH)->getInt();
  uint32 height = raw->getEntry(IMAGELENGTH)->getInt();
  mRaw->dim = iPoint2D(width, height);
  mRaw->createData();

  ByteStream input(mFile->getData(off), mFile->getSize()-off);
  int compression = raw->getEntry(COMPRESSION)->getInt();
  if (1 == compression) {
    if (mRootIFD->endian == big)
      Decode16BitRawBEunpacked(input, width, height);
    else
      Decode16BitRawUnpacked(input, width, height);
  }
  else if (99 == compression || 7 == compression) {
    ThrowRDE("MOS Decoder: Leaf LJpeg not yet supported");
    //LJpegPlain l(mFile, mRaw);
    //l.startDecoder(off, mFile->getSize()-off, 0, 0);
  } else
    ThrowRDE("MOS Decoder: Unsupported compression: %d", compression);

  return mRaw;
}

void MosDecoder::DecodePhaseOneC(uint32 data_offset, uint32 strip_offset, uint32 width, uint32 height)
{
  const int length[] = { 8,7,6,9,11,10,5,12,14,13 };

  for (uint32 row=0; row < height; row++) {
    uint32 off = data_offset + get4LE(mFile->getData(strip_offset), row*4);

    BitPumpMSB32 pump(mFile->getData(off),mFile->getSize()-off);
    uint32 pred[2], len[2];
    pred[0] = pred[1] = 0;
    ushort16* img = (ushort16*)mRaw->getData(0, row);
    for (uint32 col=0; col < width; col++) {
      if (col >= (width & -8))
        len[0] = len[1] = 14;
      else if ((col & 7) == 0)
        for (uint32 i=0; i < 2; i++) {
          uint32 j = 0;
          for (; j < 5 && !pump.getBitsSafe(1); j++);
          if (j--) len[i] = length[j*2 + pump.getBitsSafe(1)];
        }
      int i = len[col & 1];
      if (i == 14)
        img[col] = pred[col & 1] = pump.getBitsSafe(16);
      else
        img[col] = pred[col & 1] += pump.getBitsSafe(i) + 1 - (1 << (i - 1));
    }
  }
}

void MosDecoder::checkSupportInternal(CameraMetaData *meta) {
  this->checkCameraSupported(meta, make, model, "");
}

void MosDecoder::decodeMetaDataInternal(CameraMetaData *meta) {
  setMetaData(meta, make, model, "", 0);

  // Fetch the white balance (see dcraw.c parse_mos for more metadata that can be gotten)
  if (mRootIFD->hasEntryRecursive(LEAFMETADATA)) {
    TiffEntry *meta = mRootIFD->getEntryRecursive(LEAFMETADATA);
    uchar8 *buffer = meta->getDataWrt();
    uint32 size = meta->count;
    //Make sure the data is NUL terminated so that scanf never reads beyond limits
    //This is not a string though, it will have other NUL's in the middle
    buffer[size-1] = 0;

    // dcraw does actual parsing, since we just want one field we bruteforce it
    uchar8 *neutobj = (uchar8 *) memmem(buffer, size, "NeutObj_neutrals", 16);
    if (neutobj && neutobj+44 < buffer+size) {
      uint32 tmp[4] = {0};
      sscanf((const char *)neutobj+44, "%u %u %u %u", &tmp[0], &tmp[1], &tmp[2], &tmp[3]);
      if (tmp[0] > 0 && tmp[1] > 0 && tmp[2] > 0 && tmp[3] > 0) {
        mRaw->metadata.wbCoeffs[0] = (float) tmp[0]/tmp[1];
        mRaw->metadata.wbCoeffs[1] = (float) tmp[0]/tmp[2];
        mRaw->metadata.wbCoeffs[2] = (float) tmp[0]/tmp[3];
      }
    }
  }

  if (black_level)
    mRaw->blackLevel = black_level;
}

} // namespace RawSpeed
<commit_msg>Replace memmem() with portable strncmp() loop<commit_after>#include "StdAfx.h"
#include "MosDecoder.h"
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2014 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

namespace RawSpeed {

MosDecoder::MosDecoder(TiffIFD *rootIFD, FileMap* file)  :
    RawDecoder(file), mRootIFD(rootIFD) {
  decoderVersion = 0;
  black_level = 0;

  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MAKE);
  if (!data.empty()) {
    make = data[0]->getEntry(MAKE)->getString();
    model = data[0]->getEntry(MODEL)->getString();
  } else {
    TiffEntry *xmp = mRootIFD->getEntryRecursive(XMP);
    if (!xmp)
      ThrowRDE("MOS Decoder: Couldn't find the XMP");
    string xmpText = xmp->getString();
    make = getXMPTag(xmpText, "Make");
    model = getXMPTag(xmpText, "Model");
  }
}

MosDecoder::~MosDecoder(void) {
}

string MosDecoder::getXMPTag(string xmp, string tag) {
  string::size_type start = xmp.find("<tiff:"+tag+">");
  string::size_type end = xmp.find("</tiff:"+tag+">");
  if (start == string::npos || end == string::npos || end <= start)
    ThrowRDE("MOS Decoder: Couldn't find tag '%s' in the XMP", tag.c_str());
  int startlen = tag.size()+7;
  return xmp.substr(start+startlen, end-start-startlen);
}

RawImage MosDecoder::decodeRawInternal() {
  vector<TiffIFD*> data;
  TiffIFD* raw = NULL;
  uint32 off = 0;

  uint32 base = 8;
  const uchar8 *insideTiff = mFile->getData(base);
  if (get4LE(insideTiff, 0) == 0x49494949) {
    uint32 offset = get4LE(insideTiff, 8);
    if (offset+base+4 > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC offset out of bounds");

    uint32 entries = get4LE(insideTiff, offset);
    uint32 pos = 8; // Skip another 4 bytes

    uint32 width=0, height=0, strip_offset=0, data_offset=0;
    while (entries--) {
      if (offset+base+pos+16 > mFile->getSize())
        ThrowRDE("MOS: PhaseOneC offset out of bounds");

      uint32 tag  = get4LE(insideTiff, offset+pos);
      //uint32 type = get4LE(insideTiff, offset+pos+4);
      //uint32 len  = get4LE(insideTiff, offset+pos+8);
      uint32 data = get4LE(insideTiff, offset+pos+12);
      pos += 16;
      switch(tag) {
      case 0x108: width        = data;      break;
      case 0x109: height       = data;      break;
      case 0x10f: data_offset  = data+base; break;
      case 0x21c: strip_offset = data+base; break;
      case 0x21d: black_level  = data>>2;   break;
      }
    }
    if (width <= 0 || height <= 0)
      ThrowRDE("MOS: PhaseOneC couldn't find width and height");
    if (strip_offset+height*4 > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC strip offsets out of bounds");
    if (data_offset > mFile->getSize())
      ThrowRDE("MOS: PhaseOneC data offset out of bounds");

    mRaw->dim = iPoint2D(width, height);
    mRaw->createData();

    DecodePhaseOneC(data_offset, strip_offset, width, height);

    return mRaw;
  } else {
    data = mRootIFD->getIFDsWithTag(TILEOFFSETS);
    if (!data.empty()) {
      raw = data[0];
      off = raw->getEntry(TILEOFFSETS)->getInt();
    } else {
      data = mRootIFD->getIFDsWithTag(CFAPATTERN);
      if (!data.empty()) {
        raw = data[0];
        off = raw->getEntry(STRIPOFFSETS)->getInt();
      } else
        ThrowRDE("MOS Decoder: No image data found");
    }
  }

  uint32 width = raw->getEntry(IMAGEWIDTH)->getInt();
  uint32 height = raw->getEntry(IMAGELENGTH)->getInt();
  mRaw->dim = iPoint2D(width, height);
  mRaw->createData();

  ByteStream input(mFile->getData(off), mFile->getSize()-off);
  int compression = raw->getEntry(COMPRESSION)->getInt();
  if (1 == compression) {
    if (mRootIFD->endian == big)
      Decode16BitRawBEunpacked(input, width, height);
    else
      Decode16BitRawUnpacked(input, width, height);
  }
  else if (99 == compression || 7 == compression) {
    ThrowRDE("MOS Decoder: Leaf LJpeg not yet supported");
    //LJpegPlain l(mFile, mRaw);
    //l.startDecoder(off, mFile->getSize()-off, 0, 0);
  } else
    ThrowRDE("MOS Decoder: Unsupported compression: %d", compression);

  return mRaw;
}

void MosDecoder::DecodePhaseOneC(uint32 data_offset, uint32 strip_offset, uint32 width, uint32 height)
{
  const int length[] = { 8,7,6,9,11,10,5,12,14,13 };

  for (uint32 row=0; row < height; row++) {
    uint32 off = data_offset + get4LE(mFile->getData(strip_offset), row*4);

    BitPumpMSB32 pump(mFile->getData(off),mFile->getSize()-off);
    uint32 pred[2], len[2];
    pred[0] = pred[1] = 0;
    ushort16* img = (ushort16*)mRaw->getData(0, row);
    for (uint32 col=0; col < width; col++) {
      if (col >= (width & -8))
        len[0] = len[1] = 14;
      else if ((col & 7) == 0)
        for (uint32 i=0; i < 2; i++) {
          uint32 j = 0;
          for (; j < 5 && !pump.getBitsSafe(1); j++);
          if (j--) len[i] = length[j*2 + pump.getBitsSafe(1)];
        }
      int i = len[col & 1];
      if (i == 14)
        img[col] = pred[col & 1] = pump.getBitsSafe(16);
      else
        img[col] = pred[col & 1] += pump.getBitsSafe(i) + 1 - (1 << (i - 1));
    }
  }
}

void MosDecoder::checkSupportInternal(CameraMetaData *meta) {
  this->checkCameraSupported(meta, make, model, "");
}

void MosDecoder::decodeMetaDataInternal(CameraMetaData *meta) {
  setMetaData(meta, make, model, "", 0);

  // Fetch the white balance (see dcraw.c parse_mos for more metadata that can be gotten)
  if (mRootIFD->hasEntryRecursive(LEAFMETADATA)) {
    TiffEntry *meta = mRootIFD->getEntryRecursive(LEAFMETADATA);
    uchar8 *buffer = meta->getDataWrt();
    uint32 size = meta->count;
    //Make sure the data is NUL terminated so that scanf never reads beyond limits
    //This is not a string though, it will have other NUL's in the middle
    buffer[size-1] = 0;

    // dcraw does actual parsing, since we just want one field we bruteforce it
    uchar8 *neutobj = NULL;
    // We need at least 17+44 bytes for the NeutObj_neutrals section itself
    for(uint32 i=0; i<size-17-44; i++) {
      if (!strncmp("NeutObj_neutrals", (const char *) buffer+i, 16)) {
        neutobj = buffer+i;
        break;
      }
    }
    if (neutobj) {
      uint32 tmp[4] = {0};
      sscanf((const char *)neutobj+44, "%u %u %u %u", &tmp[0], &tmp[1], &tmp[2], &tmp[3]);
      if (tmp[0] > 0 && tmp[1] > 0 && tmp[2] > 0 && tmp[3] > 0) {
        mRaw->metadata.wbCoeffs[0] = (float) tmp[0]/tmp[1];
        mRaw->metadata.wbCoeffs[1] = (float) tmp[0]/tmp[2];
        mRaw->metadata.wbCoeffs[2] = (float) tmp[0]/tmp[3];
      }
    }
  }

  if (black_level)
    mRaw->blackLevel = black_level;
}

} // namespace RawSpeed
<|endoftext|>


<commit_before>#include "StdAfx.h"
#include "RawDecoder.h"
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009 Klaus Post

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

RawDecoder::RawDecoder(FileMap* file) : mFile(file), mRaw(RawImage::create())
{
}

RawDecoder::~RawDecoder(void)
{
  for (guint i = 0 ; i < errors.size(); i++) {
    free((void*)errors[i]);
  }
  errors.clear();
}

void RawDecoder::readUncompressedRaw(ByteStream &input, iPoint2D& size, iPoint2D& offset, int inputPitch, int bitPerPixel, gboolean MSBOrder) {
  guchar* data = mRaw->getData();
  guint outPitch = mRaw->pitch;
  guint w = size.x;
  guint h = size.y;
  guint cpp = mRaw->getCpp();

  if (input.getRemainSize()< (inputPitch*h) ) {
    h = input.getRemainSize() / inputPitch - 1;
  }
  if (bitPerPixel>16)
    ThrowRDE("readUncompressedRaw: Unsupported bit depth");

  guint skipBits = inputPitch - w*bitPerPixel/8;  // Skip per line
  if (offset.y>mRaw->dim.y)
    ThrowRDE("readUncompressedRaw: Invalid y offset");
  if (offset.x+size.x>mRaw->dim.x)
    ThrowRDE("readUncompressedRaw: Invalid x offset");

  guint y = offset.y;
  h = MIN(h+(guint)offset.y,(guint)mRaw->dim.y);

  if (MSBOrder) {
    BitPumpMSB bits(&input);
    w *= cpp;
    for (; y < h; y++) {
      gushort* dest = (gushort*)&data[offset.x*sizeof(gushort)*cpp+y*outPitch];
      for(guint x =0 ; x < w; x++) {
        guint b = bits.getBits(bitPerPixel);
        dest[x] = b;
      }
      bits.skipBits(skipBits);
    }

  } else {

    if (bitPerPixel==16)  {
      BitBlt(&data[offset.x*sizeof(gushort)*cpp+y*outPitch],outPitch,
        input.getData(),inputPitch,w*mRaw->bpp,h-y);
      return;
    }
    BitPumpPlain bits(&input);
    w *= cpp;
    for (; y < h; y++) {
      gushort* dest = (gushort*)&data[offset.x*sizeof(gushort)+y*outPitch];
      for(guint x =0 ; x < w; x++) {
        guint b = bits.getBits(bitPerPixel);
        dest[x] = b;
      }
      bits.skipBits(skipBits);
    }
  }
}

void RawDecoder::Decode12BitRaw(ByteStream &input, guint w, guint h) {
  guchar* data = mRaw->getData();
  guint pitch = mRaw->pitch;
  const guchar *in = input.getData();
  if (input.getRemainSize()< (w*h*3/2) ) {
    h = input.getRemainSize() / (w*3/2) - 1;
  }
  for (guint y=0; y < h; y++) {
    gushort* dest = (gushort*)&data[y*pitch];
    for(guint x =0 ; x < w; x+=2) {
      guint g1 = *in++;
      guint g2 = *in++;
      dest[x] = g1 | ((g2&0xf)<<8);
      guint g3 = *in++;
      dest[x+1] = (g2>>4) | (g3<<4);
    }
  }
}

  void RawDecoder::checkCameraSupported(CameraMetaData *meta, string make, string model, string mode) {
  TrimSpaces(make);
  TrimSpaces(model);
  Camera* cam = meta->getCamera(make, model, mode);
  if (!cam) {
    if (mode.length() == 0)
      printf("Unable to find camera in database: %s %s %s\n", make.c_str(), model.c_str(), mode.c_str());

    return;    // Assume true.
  }

  if (!cam->supported)
    ThrowRDE("Camera not supported (explicit). Sorry.");
}

void RawDecoder::setMetaData( CameraMetaData *meta, string make, string model, string mode )
{
  TrimSpaces(make);
  TrimSpaces(model);
  Camera *cam = meta->getCamera(make, model, mode);
  if (!cam) {
    printf("Unable to find camera in database: %s %s %s\n", make.c_str(), model.c_str(), mode.c_str());
    return;
  }
  mRaw->subFrame(cam->cropPos, cam->cropSize);
  mRaw->cfa = cam->cfa;
  if (cam->cropPos.x & 1)
    mRaw->cfa.shiftLeft();
  if (cam->cropPos.y & 1)
    mRaw->cfa.shiftDown();

  mRaw->blackLevel = cam->black;
  mRaw->whitePoint = cam->white;
}
void RawDecoder::TrimSpaces( string& str)
{
  // Trim Both leading and trailing spaces
  size_t startpos = str.find_first_not_of(" \t"); // Find the first character position after excluding leading blank spaces
  size_t endpos = str.find_last_not_of(" \t"); // Find the first character position from reverse af

  // if all spaces or empty return an empty string
  if(( string::npos == startpos ) || ( string::npos == endpos))
  {
    str = "";
  }
  else
    str = str.substr( startpos, endpos-startpos+1 );

}
<commit_msg>Allow negative values in crop size to be used as relative crop values.<commit_after>#include "StdAfx.h"
#include "RawDecoder.h"
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009 Klaus Post

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

RawDecoder::RawDecoder(FileMap* file) : mFile(file), mRaw(RawImage::create())
{
}

RawDecoder::~RawDecoder(void)
{
  for (guint i = 0 ; i < errors.size(); i++) {
    free((void*)errors[i]);
  }
  errors.clear();
}

void RawDecoder::readUncompressedRaw(ByteStream &input, iPoint2D& size, iPoint2D& offset, int inputPitch, int bitPerPixel, gboolean MSBOrder) {
  guchar* data = mRaw->getData();
  guint outPitch = mRaw->pitch;
  guint w = size.x;
  guint h = size.y;
  guint cpp = mRaw->getCpp();

  if (input.getRemainSize()< (inputPitch*h) ) {
    h = input.getRemainSize() / inputPitch - 1;
  }
  if (bitPerPixel>16)
    ThrowRDE("readUncompressedRaw: Unsupported bit depth");

  guint skipBits = inputPitch - w*bitPerPixel/8;  // Skip per line
  if (offset.y>mRaw->dim.y)
    ThrowRDE("readUncompressedRaw: Invalid y offset");
  if (offset.x+size.x>mRaw->dim.x)
    ThrowRDE("readUncompressedRaw: Invalid x offset");

  guint y = offset.y;
  h = MIN(h+(guint)offset.y,(guint)mRaw->dim.y);

  if (MSBOrder) {
    BitPumpMSB bits(&input);
    w *= cpp;
    for (; y < h; y++) {
      gushort* dest = (gushort*)&data[offset.x*sizeof(gushort)*cpp+y*outPitch];
      for(guint x =0 ; x < w; x++) {
        guint b = bits.getBits(bitPerPixel);
        dest[x] = b;
      }
      bits.skipBits(skipBits);
    }

  } else {

    if (bitPerPixel==16)  {
      BitBlt(&data[offset.x*sizeof(gushort)*cpp+y*outPitch],outPitch,
        input.getData(),inputPitch,w*mRaw->bpp,h-y);
      return;
    }
    BitPumpPlain bits(&input);
    w *= cpp;
    for (; y < h; y++) {
      gushort* dest = (gushort*)&data[offset.x*sizeof(gushort)+y*outPitch];
      for(guint x =0 ; x < w; x++) {
        guint b = bits.getBits(bitPerPixel);
        dest[x] = b;
      }
      bits.skipBits(skipBits);
    }
  }
}

void RawDecoder::Decode12BitRaw(ByteStream &input, guint w, guint h) {
  guchar* data = mRaw->getData();
  guint pitch = mRaw->pitch;
  const guchar *in = input.getData();
  if (input.getRemainSize()< (w*h*3/2) ) {
    h = input.getRemainSize() / (w*3/2) - 1;
  }
  for (guint y=0; y < h; y++) {
    gushort* dest = (gushort*)&data[y*pitch];
    for(guint x =0 ; x < w; x+=2) {
      guint g1 = *in++;
      guint g2 = *in++;
      dest[x] = g1 | ((g2&0xf)<<8);
      guint g3 = *in++;
      dest[x+1] = (g2>>4) | (g3<<4);
    }
  }
}

void RawDecoder::checkCameraSupported(CameraMetaData *meta, string make, string model, string mode) {
  TrimSpaces(make);
  TrimSpaces(model);
  Camera* cam = meta->getCamera(make, model, mode);
  if (!cam) {
    if (mode.length() == 0)
      printf("Unable to find camera in database: %s %s %s\nPlease upload file to ftp.rawstudio.org, thanks!\n", make.c_str(), model.c_str(), mode.c_str());

    return;    // Assume true.
  }

  if (!cam->supported)
    ThrowRDE("Camera not supported (explicit). Sorry.");
}

void RawDecoder::setMetaData( CameraMetaData *meta, string make, string model, string mode )
{
  TrimSpaces(make);
  TrimSpaces(model);
  Camera *cam = meta->getCamera(make, model, mode);
  if (!cam) {
    printf("Unable to find camera in database: %s %s %s\n", make.c_str(), model.c_str(), mode.c_str());
    return;
  }

  iPoint2D new_size = cam->cropSize;

	// If crop size is negative, use relative cropping
	if (new_size.x <= 0)
		new_size.x = mRaw->dim.x - cam->cropPos.x + new_size.x;

	if (new_size.y <= 0)
		new_size.y = mRaw->dim.y - cam->cropPos.y + new_size.y;

  mRaw->subFrame(cam->cropPos, new_size);
  mRaw->cfa = cam->cfa;

  // Shift CFA to match crop
  if (cam->cropPos.x & 1)
    mRaw->cfa.shiftLeft();
  if (cam->cropPos.y & 1)
    mRaw->cfa.shiftDown();

  mRaw->blackLevel = cam->black;
  mRaw->whitePoint = cam->white;
}

void RawDecoder::TrimSpaces( string& str)
{
  // Trim Both leading and trailing spaces
  size_t startpos = str.find_first_not_of(" \t"); // Find the first character position after excluding leading blank spaces
  size_t endpos = str.find_last_not_of(" \t"); // Find the first character position from reverse af

  // if all spaces or empty return an empty string
  if(( string::npos == startpos ) || ( string::npos == endpos))
  {
    str = "";
  }
  else
    str = str.substr( startpos, endpos-startpos+1 );

}
<|endoftext|>


<commit_before>#include "StdAfx.h"
#include "Rw2Decoder.h"

/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009 Klaus Post

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

Rw2Decoder::Rw2Decoder(TiffIFD *rootIFD, FileMap* file) :
RawDecoder(file), mRootIFD(rootIFD), input(0),vbits(0)
{

}
Rw2Decoder::~Rw2Decoder(void)
{
  if (input)
    delete input;
  input = 0;
}

RawImage Rw2Decoder::decodeRaw()
{

  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(PANASONIC_STRIPOFFSET);

  if (data.empty())
    ThrowRDE("RW2 Decoder: No image data found");

  TiffIFD* raw = data[0];

  TiffEntry *offsets = raw->getEntry(PANASONIC_STRIPOFFSET);

  if (offsets->count != 1) {
    ThrowRDE("RW2 Decoder: Multiple Strips found: %u",offsets->count);
  }

  guint height = raw->getEntry((TiffTag)3)->getShort();
  guint width = raw->getEntry((TiffTag)2)->getShort();

  mRaw->dim = iPoint2D(width, height);
  mRaw->bpp = 2;
  mRaw->createData();

  load_flags = 0x2008;
  gint off = offsets->getInt();

  input = new ByteStream(mFile->getData(off),mFile->getSize()-off);
  try {
    DecodeRw2();
  } catch (IOException e) {
    // We attempt to ignore, since truncated files may be ok.
    errors.push_back(e.what());
  }

  return mRaw;
}

void Rw2Decoder::DecodeRw2()
{
  int x, y, i, j, sh=0, pred[2], nonz[2];
  int w = mRaw->dim.x/14;
  int h = mRaw->dim.y;

  for (y=0; y < h; y++) {
    gushort* dest = (gushort*)mRaw->getData(0,y);
    for (x=0; x < w; x++) {
      pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
      for (i = 0; i < 14; i++) {
        // Even pixels
        if (i % 3 == 2)
          sh = 4 >> (3 - pana_bits(2));
        if (nonz[0]) {
          if ((j = pana_bits(8))) {
            if ((pred[0] -= 0x80 << sh) < 0 || sh == 4)
              pred[0] &= ~(-1 << sh);
            pred[0] += j << sh;
          }
        } else if ((nonz[0] = pana_bits(8)) || i > 11)
          pred[0] = nonz[0] << 4 | pana_bits(4);
        *dest++ = pred[0];

        // Odd pixels
        i++;
        if (i % 3 == 2)
          sh = 4 >> (3 - pana_bits(2));
        if (nonz[1]) {
          if ((j = pana_bits(8))) {
            if ((pred[1] -= 0x80 << sh) < 0 || sh == 4)
              pred[1] &= ~(-1 << sh);
            pred[1] += j << sh;
          }
        } else if ((nonz[1] = pana_bits(8)) || i > 11)
          pred[1] = nonz[1] << 4 | pana_bits(4);
        *dest++ = pred[1];
      }
    }
  }
}

guint Rw2Decoder::pana_bits (int nbits)
{
  int byte;

  if (!vbits) {
    if (input->getRemainSize() < 0x4000-load_flags) {
      memcpy (buf+load_flags, input->getData(), input->getRemainSize());
      input->skipBytes(input->getRemainSize());
    } else {
      memcpy (buf+load_flags, input->getData(), 0x4000-load_flags);
      input->skipBytes(0x4000-load_flags);
      if (input->getRemainSize()<load_flags) {
        memcpy (buf, input->getData(), input->getRemainSize());
        input->skipBytes(input->getRemainSize());
      } else {
        memcpy (buf, input->getData(), load_flags);
        input->skipBytes(load_flags);
      }
    }
  }
  vbits = (vbits - nbits) & 0x1ffff;
  byte = vbits >> 3 ^ 0x3ff0;
  return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
}

void Rw2Decoder::checkSupport(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
  if (data.empty())
    ThrowRDE("RW2 Support check: Model name found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, "");
}

void Rw2Decoder::decodeMetaData( CameraMetaData *meta )
{
  mRaw->cfa.setCFA(CFA_BLUE, CFA_GREEN, CFA_GREEN2, CFA_RED);
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("CR2 Meta Decoder: Model name not found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  string mode = getMode(model);

  setMetaData(meta, make, model, mode);
}

bool Rw2Decoder::almostEqualRelative(float A, float B, float maxRelativeError)
{
  if (A == B)
    return true;

  float relativeError = fabs((A - B) / B);
  if (relativeError <= maxRelativeError)
    return true;
  return false;
}

std::string Rw2Decoder::getMode( const string model )
{
  float ratio = 3.0f / 2.0f;  // Default
  if (mRaw->isAllocated()) {
    ratio = (float)mRaw->dim.x / (float)mRaw->dim.y;
  }

  if (!model.compare("DMC-LX3") || !model.compare("DMC-G1") || !model.compare("DMC-GH1") || !model.compare("DMC-GF1")) {
    if (almostEqualRelative(ratio,16.0f/9.0f,0.02f))
      return "16:9";
    if (almostEqualRelative(ratio,3.0f/2.0f,0.02f))
      return "3:2";
    if (almostEqualRelative(ratio,4.0f/3.0f,0.02f))
      return "4:3";
    if (almostEqualRelative(ratio,1.0f,0.02f))
      return "1:1";
  }

  return "";
}
<commit_msg>RW2Decoder: Use default aspect in checksupport to avoid error message.<commit_after>#include "StdAfx.h"
#include "Rw2Decoder.h"

/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009 Klaus Post

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

Rw2Decoder::Rw2Decoder(TiffIFD *rootIFD, FileMap* file) :
RawDecoder(file), mRootIFD(rootIFD), input(0),vbits(0)
{

}
Rw2Decoder::~Rw2Decoder(void)
{
  if (input)
    delete input;
  input = 0;
}

RawImage Rw2Decoder::decodeRaw()
{

  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(PANASONIC_STRIPOFFSET);

  if (data.empty())
    ThrowRDE("RW2 Decoder: No image data found");

  TiffIFD* raw = data[0];

  TiffEntry *offsets = raw->getEntry(PANASONIC_STRIPOFFSET);

  if (offsets->count != 1) {
    ThrowRDE("RW2 Decoder: Multiple Strips found: %u",offsets->count);
  }

  guint height = raw->getEntry((TiffTag)3)->getShort();
  guint width = raw->getEntry((TiffTag)2)->getShort();

  mRaw->dim = iPoint2D(width, height);
  mRaw->bpp = 2;
  mRaw->createData();

  load_flags = 0x2008;
  gint off = offsets->getInt();

  input = new ByteStream(mFile->getData(off),mFile->getSize()-off);
  try {
    DecodeRw2();
  } catch (IOException e) {
    // We attempt to ignore, since truncated files may be ok.
    errors.push_back(e.what());
  }

  return mRaw;
}

void Rw2Decoder::DecodeRw2()
{
  int x, y, i, j, sh=0, pred[2], nonz[2];
  int w = mRaw->dim.x/14;
  int h = mRaw->dim.y;

  for (y=0; y < h; y++) {
    gushort* dest = (gushort*)mRaw->getData(0,y);
    for (x=0; x < w; x++) {
      pred[0] = pred[1] = nonz[0] = nonz[1] = 0;
      for (i = 0; i < 14; i++) {
        // Even pixels
        if (i % 3 == 2)
          sh = 4 >> (3 - pana_bits(2));
        if (nonz[0]) {
          if ((j = pana_bits(8))) {
            if ((pred[0] -= 0x80 << sh) < 0 || sh == 4)
              pred[0] &= ~(-1 << sh);
            pred[0] += j << sh;
          }
        } else if ((nonz[0] = pana_bits(8)) || i > 11)
          pred[0] = nonz[0] << 4 | pana_bits(4);
        *dest++ = pred[0];

        // Odd pixels
        i++;
        if (i % 3 == 2)
          sh = 4 >> (3 - pana_bits(2));
        if (nonz[1]) {
          if ((j = pana_bits(8))) {
            if ((pred[1] -= 0x80 << sh) < 0 || sh == 4)
              pred[1] &= ~(-1 << sh);
            pred[1] += j << sh;
          }
        } else if ((nonz[1] = pana_bits(8)) || i > 11)
          pred[1] = nonz[1] << 4 | pana_bits(4);
        *dest++ = pred[1];
      }
    }
  }
}

guint Rw2Decoder::pana_bits (int nbits)
{
  int byte;

  if (!vbits) {
    /* On truncated files this routine will just return just for the truncated
     * part of the file. Since there is no chance of affecting output buffer
     * size we allow the decoder to decode this
     */
    if (input->getRemainSize() < 0x4000-load_flags) {
      memcpy (buf+load_flags, input->getData(), input->getRemainSize());
      input->skipBytes(input->getRemainSize());
    } else {
      memcpy (buf+load_flags, input->getData(), 0x4000-load_flags);
      input->skipBytes(0x4000-load_flags);
      if (input->getRemainSize()<load_flags) {
        memcpy (buf, input->getData(), input->getRemainSize());
        input->skipBytes(input->getRemainSize());
      } else {
        memcpy (buf, input->getData(), load_flags);
        input->skipBytes(load_flags);
      }
    }
  }
  vbits = (vbits - nbits) & 0x1ffff;
  byte = vbits >> 3 ^ 0x3ff0;
  return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits);
}

void Rw2Decoder::checkSupport(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
  if (data.empty())
    ThrowRDE("RW2 Support check: Model name found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, getMode(model));
}

void Rw2Decoder::decodeMetaData( CameraMetaData *meta )
{
  mRaw->cfa.setCFA(CFA_BLUE, CFA_GREEN, CFA_GREEN2, CFA_RED);
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("CR2 Meta Decoder: Model name not found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  string mode = getMode(model);

  setMetaData(meta, make, model, mode);
}

bool Rw2Decoder::almostEqualRelative(float A, float B, float maxRelativeError)
{
  if (A == B)
    return true;

  float relativeError = fabs((A - B) / B);
  if (relativeError <= maxRelativeError)
    return true;
  return false;
}

std::string Rw2Decoder::getMode( const string model )
{
  float ratio = 3.0f / 2.0f;  // Default
  if (mRaw->isAllocated()) {
    ratio = (float)mRaw->dim.x / (float)mRaw->dim.y;
  }

  if (!model.compare("DMC-LX3") || !model.compare("DMC-G1") || !model.compare("DMC-GH1") || !model.compare("DMC-GF1")) {
    if (almostEqualRelative(ratio,16.0f/9.0f,0.02f))
      return "16:9";
    if (almostEqualRelative(ratio,3.0f/2.0f,0.02f))
      return "3:2";
    if (almostEqualRelative(ratio,4.0f/3.0f,0.02f))
      return "4:3";
    if (almostEqualRelative(ratio,1.0f,0.02f))
      return "1:1";
  }

  return "";
}
<|endoftext|>