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

#include "repo_controller_internal.cpp.inl" //Inner class implementation

using namespace repo;

RepoController::RepoController(
	std::vector<lib::RepoAbstractListener*> listeners,
	const uint32_t &numConcurrentOps,
	const uint32_t &numDbConn)
{
	//RepoController follows the Pimpl idiom http://www.gotw.ca/gotw/028.htm
	//This is done to avoid high dependencies on other headers for library users
	//Actual implementations are in _RepoControllerImpl
	impl = new RepoController::_RepoControllerImpl(listeners, numConcurrentOps, numDbConn);
}

RepoController::~RepoController()
{
	if (impl) delete impl;
}

RepoController::RepoToken* RepoController::authenticateToAdminDatabaseMongo(
	std::string       &errMsg,
	const std::string &address,
	const int         &port,
	const std::string &username,
	const std::string &password,
	const bool        &pwDigested
	)
{
	return impl->authenticateToAdminDatabaseMongo(errMsg, address, port, username, password, pwDigested);
}

RepoController::RepoToken* RepoController::authenticateMongo(
	std::string       &errMsg,
	const std::string &address,
	const uint32_t    &port,
	const std::string &dbName,
	const std::string &username,
	const std::string &password,
	const bool        &pwDigested
	)
{
	return impl->authenticateMongo(errMsg, address, port, dbName, username, password, pwDigested);
}

bool RepoController::testConnection(const repo::RepoCredentials &credentials)
{
	return impl->testConnection(credentials);
}

void RepoController::commitScene(
	const RepoController::RepoToken    *token,
	repo::core::model::RepoScene        *scene,
	const std::string                   &owner)
{
	impl->commitScene(token, scene, owner);
}

uint64_t RepoController::countItemsInCollection(
	const RepoController::RepoToken            *token,
	const std::string    &database,
	const std::string    &collection)
{
	return impl->countItemsInCollection(token, database, collection);
}

void RepoController::disconnectFromDatabase(const RepoController::RepoToken* token)
{
	impl->disconnectFromDatabase(token);
}

repo::core::model::RepoScene* RepoController::fetchScene(
	const RepoController::RepoToken      *token,
	const std::string    &database,
	const std::string    &collection,
	const std::string    &uuid,
	const bool           &headRevision,
	const bool           &lightFetch)
{
	return impl->fetchScene(token, database, collection, uuid, headRevision, lightFetch);
}

bool RepoController::generateAndCommitSelectionTree(
	const RepoController::RepoToken                         *token,
	repo::core::model::RepoScene            *scene)
{
	return impl->generateAndCommitSelectionTree(token, scene);
}

bool RepoController::generateAndCommitStashGraph(
	const RepoController::RepoToken              *token,
	repo::core::model::RepoScene* scene
	)
{
	return impl->generateAndCommitStashGraph(token, scene);
}

std::vector < repo::core::model::RepoBSON >
RepoController::getAllFromCollectionContinuous(
const RepoController::RepoToken      *token,
const std::string    &database,
const std::string    &collection,
const uint64_t       &skip,
const uint32_t       &limit)
{
	return impl->getAllFromCollectionContinuous(token, database, collection, skip, limit);
}

std::vector < repo::core::model::RepoBSON >
RepoController::getAllFromCollectionContinuous(
const RepoController::RepoToken              *token,
const std::string            &database,
const std::string            &collection,
const std::list<std::string> &fields,
const std::string            &sortField,
const int                    &sortOrder,
const uint64_t               &skip,
const uint32_t               &limit)
{
	return impl->getAllFromCollectionContinuous(token, database, collection, fields, sortField, sortOrder, skip, limit);
}

std::vector < repo::core::model::RepoRole > RepoController::getRolesFromDatabase(
	const RepoController::RepoToken              *token,
	const std::string            &database,
	const uint64_t               &skip,
	const uint32_t               &limit)
{
	return impl->getRolesFromDatabase(token, database, skip, limit);
}

std::vector < repo::core::model::RepoRoleSettings > RepoController::getRoleSettingsFromDatabase(
	const RepoController::RepoToken              *token,
	const std::string            &database,
	const uint64_t               &skip,
	const uint32_t               &limit)
{
	return impl->getRoleSettingsFromDatabase(token, database, skip, limit);
}

repo::core::model::RepoRoleSettings RepoController::getRoleSettings(
	const RepoController::RepoToken *token,
	const repo::core::model::RepoRole &role)
{
	return getRoleSettings(token, role.getDatabase(), role.getName());
}

repo::core::model::RepoRoleSettings RepoController::getRoleSettings(
	const RepoController::RepoToken *token,
	const std::string &database,
	const std::string &uniqueRoleName)
{
	return impl->getRoleSettings(token, database, uniqueRoleName);
}

std::list<std::string> RepoController::getDatabases(const RepoController::RepoToken *token)
{
	return impl->getDatabases(token);
}

std::list<std::string>  RepoController::getCollections(
	const RepoController::RepoToken       *token,
	const std::string     &databaseName
	)
{
	return impl->getCollections(token, databaseName);
}

repo::core::model::CollectionStats RepoController::getCollectionStats(
	const RepoController::RepoToken      *token,
	const std::string                    &database,
	const std::string                    &collection)
{
	return impl->getCollectionStats(token, database, collection);
}

std::string RepoController::getHostAndPort(const RepoController::RepoToken *token)
{
	return token->getDatabaseHostPort();
}

std::map<std::string, std::list<std::string>>
RepoController::getDatabasesWithProjects(
const RepoController::RepoToken  *token,
const std::list<std::string>     &databases)
{
	return impl->getDatabasesWithProjects(token, databases);
}

void RepoController::insertBinaryFileToDatabase(
	const RepoController::RepoToken            *token,
	const std::string          &database,
	const std::string          &collection,
	const std::string          &name,
	const std::vector<uint8_t> &rawData,
	const std::string          &mimeType)
{
	impl->insertBinaryFileToDatabase(token, database, collection, name, rawData, mimeType);
}

void RepoController::insertRole(
	const RepoController::RepoToken   *token,
	const repo::core::model::RepoRole &role
	)
{
	impl->insertRole(token, role);
}

void RepoController::insertUser(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoUser  &user)
{
	impl->insertUser(token, user);
}

bool RepoController::removeCollection(
	const RepoController::RepoToken             *token,
	const std::string     &databaseName,
	const std::string     &collectionName,
	std::string			  &errMsg
	)
{
	return impl->removeCollection(token, databaseName, collectionName, errMsg);
}

bool RepoController::removeDatabase(
	const RepoController::RepoToken       *token,
	const std::string     &databaseName,
	std::string			  &errMsg
	)
{
	return impl->removeDatabase(token, databaseName, errMsg);
}

void RepoController::removeDocument(
	const RepoController::RepoToken          *token,
	const std::string                        &databaseName,
	const std::string                        &collectionName,
	const repo::core::model::RepoBSON        &bson)
{
	impl->removeDocument(token, databaseName, collectionName, bson);
}

bool RepoController::removeProject(
	const RepoController::RepoToken          *token,
	const std::string                        &databaseName,
	const std::string                        &projectName,
	std::string								 &errMsg)
{
	return impl->removeProject(token, databaseName, projectName, errMsg);
}

void RepoController::removeRole(
	const RepoController::RepoToken          *token,
	const repo::core::model::RepoRole        &role)
{
	impl->removeRole(token, role);
}

void RepoController::removeUser(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoUser  &user)
{
	impl->removeUser(token, user);
}

void RepoController::updateRole(
	const RepoController::RepoToken          *token,
	const repo::core::model::RepoRole        &role)
{
	impl->updateRole(token, role);
}

void RepoController::updateUser(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoUser  &user)
{
	impl->updateUser(token, user);
}

void RepoController::upsertDocument(
	const RepoController::RepoToken          *token,
	const std::string                        &databaseName,
	const std::string                        &collectionName,
	const repo::core::model::RepoBSON        &bson)
{
	impl->upsertDocument(token, databaseName, collectionName, bson);
}

void RepoController::setLoggingLevel(const repo::lib::RepoLog::RepoLogLevel &level)
{
	impl->setLoggingLevel(level);
}

void RepoController::logToFile(const std::string &filePath)
{
	impl->logToFile(filePath);
}

repo::core::model::RepoScene* RepoController::createFederatedScene(
	const std::map<repo::core::model::TransformationNode, repo::core::model::ReferenceNode> &fedMap)
{
	return impl->createFederatedScene(fedMap);
}

repo::core::model::RepoScene* RepoController::createMapScene(
	const repo::core::model::MapNode &mapNode)
{
	return impl->createMapScene(mapNode);
}

bool RepoController::generateAndCommitGLTFBuffer(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoScene *scene)
{
	return impl->generateAndCommitGLTFBuffer(token, scene);
}

bool RepoController::generateAndCommitSRCBuffer(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoScene *scene)
{
	return impl->generateAndCommitSRCBuffer(token, scene);
}

repo_web_buffers_t RepoController::generateGLTFBuffer(
	const repo::core::model::RepoScene *scene)
{
	return impl->generateGLTFBuffer(scene);
}

repo_web_buffers_t RepoController::generateSRCBuffer(
	const repo::core::model::RepoScene *scene)
{
	return impl->generateSRCBuffer(scene);
}

std::list<std::string> RepoController::getAdminDatabaseRoles(const RepoController::RepoToken *token)
{
	return impl->getAdminDatabaseRoles(token);
}

std::string RepoController::getNameOfAdminDatabase(const RepoController::RepoToken *token)
{
	return impl->getNameOfAdminDatabase(token);
}

std::shared_ptr<repo_partitioning_tree_t>
RepoController::getScenePartitioning(
const repo::core::model::RepoScene *scene,
const uint32_t                     &maxDepth
)
{
	return impl->getScenePartitioning(scene, maxDepth);
}

std::list<std::string> RepoController::getStandardDatabaseRoles(const RepoController::RepoToken *token)
{
	return impl->getStandardDatabaseRoles(token);
}

std::string RepoController::getSupportedExportFormats()
{
	return impl->getSupportedExportFormats();
}

repo::core::model::RepoNodeSet RepoController::loadMetadataFromFile(
	const std::string &filePath,
	const char        &delimiter)
{
	return impl->loadMetadataFromFile(filePath, delimiter);
}

repo::core::model::RepoScene*
RepoController::loadSceneFromFile(
const std::string                                          &filePath,
const bool                                                 &applyReduction,
const bool                                                 &rotateModel,
const repo::manipulator::modelconvertor::ModelImportConfig *config)
{
	return impl->loadSceneFromFile(filePath, applyReduction, rotateModel, config);
}

void RepoController::saveOriginalFiles(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoScene *scene,
	const std::string                   &directory)
{
	return impl->saveOriginalFiles(token, scene, directory);
}

void RepoController::saveOriginalFiles(
	const RepoController::RepoToken     *token,
	const std::string                   &database,
	const std::string                   &project,
	const std::string                   &directory)
{
	return impl->saveOriginalFiles(token, database, project, directory);
}

bool RepoController::saveSceneToFile(
	const std::string &filePath,
	const repo::core::model::RepoScene* scene)
{
	return impl->saveSceneToFile(filePath, scene);
}

void RepoController::reduceTransformations(
	const RepoController::RepoToken              *token,
	repo::core::model::RepoScene *scene)
{
	impl->reduceTransformations(token, scene);
}

void RepoController::compareScenes(
	const RepoController::RepoToken    *token,
	repo::core::model::RepoScene       *base,
	repo::core::model::RepoScene       *compare,
	repo_diff_result_t                         &baseResults,
	repo_diff_result_t                         &compResults,
	const repo::DiffMode                     &diffMode
	)
{
	impl->compareScenes(token, base, compare, baseResults, compResults, diffMode);
}

std::string RepoController::getVersion()
{
	return impl->getVersion();
}<commit_msg>#108 missing function<commit_after>/**
*  Copyright (C) 2015 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "repo_controller_internal.cpp.inl" //Inner class implementation

using namespace repo;

RepoController::RepoController(
	std::vector<lib::RepoAbstractListener*> listeners,
	const uint32_t &numConcurrentOps,
	const uint32_t &numDbConn)
{
	//RepoController follows the Pimpl idiom http://www.gotw.ca/gotw/028.htm
	//This is done to avoid high dependencies on other headers for library users
	//Actual implementations are in _RepoControllerImpl
	impl = new RepoController::_RepoControllerImpl(listeners, numConcurrentOps, numDbConn);
}

RepoController::~RepoController()
{
	if (impl) delete impl;
}

RepoController::RepoToken* RepoController::authenticateToAdminDatabaseMongo(
	std::string       &errMsg,
	const std::string &address,
	const int         &port,
	const std::string &username,
	const std::string &password,
	const bool        &pwDigested
	)
{
	return impl->authenticateToAdminDatabaseMongo(errMsg, address, port, username, password, pwDigested);
}

RepoController::RepoToken* RepoController::authenticateMongo(
	std::string       &errMsg,
	const std::string &address,
	const uint32_t    &port,
	const std::string &dbName,
	const std::string &username,
	const std::string &password,
	const bool        &pwDigested
	)
{
	return impl->authenticateMongo(errMsg, address, port, dbName, username, password, pwDigested);
}

bool RepoController::testConnection(const repo::RepoCredentials &credentials)
{
	return impl->testConnection(credentials);
}

void RepoController::commitScene(
	const RepoController::RepoToken    *token,
	repo::core::model::RepoScene        *scene,
	const std::string                   &owner)
{
	impl->commitScene(token, scene, owner);
}

uint64_t RepoController::countItemsInCollection(
	const RepoController::RepoToken            *token,
	const std::string    &database,
	const std::string    &collection)
{
	return impl->countItemsInCollection(token, database, collection);
}

void RepoController::disconnectFromDatabase(const RepoController::RepoToken* token)
{
	impl->disconnectFromDatabase(token);
}

repo::core::model::RepoScene* RepoController::fetchScene(
	const RepoController::RepoToken      *token,
	const std::string    &database,
	const std::string    &collection,
	const std::string    &uuid,
	const bool           &headRevision,
	const bool           &lightFetch)
{
	return impl->fetchScene(token, database, collection, uuid, headRevision, lightFetch);
}

bool RepoController::generateAndCommitSelectionTree(
	const RepoController::RepoToken                         *token,
	repo::core::model::RepoScene            *scene)
{
	return impl->generateAndCommitSelectionTree(token, scene);
}

bool RepoController::generateAndCommitStashGraph(
	const RepoController::RepoToken              *token,
	repo::core::model::RepoScene* scene
	)
{
	return impl->generateAndCommitStashGraph(token, scene);
}

std::vector < repo::core::model::RepoBSON >
RepoController::getAllFromCollectionContinuous(
const RepoController::RepoToken      *token,
const std::string    &database,
const std::string    &collection,
const uint64_t       &skip,
const uint32_t       &limit)
{
	return impl->getAllFromCollectionContinuous(token, database, collection, skip, limit);
}

std::vector < repo::core::model::RepoBSON >
RepoController::getAllFromCollectionContinuous(
const RepoController::RepoToken              *token,
const std::string            &database,
const std::string            &collection,
const std::list<std::string> &fields,
const std::string            &sortField,
const int                    &sortOrder,
const uint64_t               &skip,
const uint32_t               &limit)
{
	return impl->getAllFromCollectionContinuous(token, database, collection, fields, sortField, sortOrder, skip, limit);
}

std::vector < repo::core::model::RepoRole > RepoController::getRolesFromDatabase(
	const RepoController::RepoToken              *token,
	const std::string            &database,
	const uint64_t               &skip,
	const uint32_t               &limit)
{
	return impl->getRolesFromDatabase(token, database, skip, limit);
}

std::vector < repo::core::model::RepoRoleSettings > RepoController::getRoleSettingsFromDatabase(
	const RepoController::RepoToken              *token,
	const std::string            &database,
	const uint64_t               &skip,
	const uint32_t               &limit)
{
	return impl->getRoleSettingsFromDatabase(token, database, skip, limit);
}

repo::core::model::RepoRoleSettings RepoController::getRoleSettings(
	const RepoController::RepoToken *token,
	const repo::core::model::RepoRole &role)
{
	return getRoleSettings(token, role.getDatabase(), role.getName());
}

repo::core::model::RepoRoleSettings RepoController::getRoleSettings(
	const RepoController::RepoToken *token,
	const std::string &database,
	const std::string &uniqueRoleName)
{
	return impl->getRoleSettings(token, database, uniqueRoleName);
}

std::list<std::string> RepoController::getDatabases(const RepoController::RepoToken *token)
{
	return impl->getDatabases(token);
}

std::list<std::string>  RepoController::getCollections(
	const RepoController::RepoToken       *token,
	const std::string     &databaseName
	)
{
	return impl->getCollections(token, databaseName);
}

repo::core::model::CollectionStats RepoController::getCollectionStats(
	const RepoController::RepoToken      *token,
	const std::string                    &database,
	const std::string                    &collection)
{
	return impl->getCollectionStats(token, database, collection);
}

std::string RepoController::getHostAndPort(const RepoController::RepoToken *token)
{
	return token->getDatabaseHostPort();
}

std::map<std::string, std::list<std::string>>
RepoController::getDatabasesWithProjects(
const RepoController::RepoToken  *token,
const std::list<std::string>     &databases)
{
	return impl->getDatabasesWithProjects(token, databases);
}

void RepoController::insertBinaryFileToDatabase(
	const RepoController::RepoToken            *token,
	const std::string          &database,
	const std::string          &collection,
	const std::string          &name,
	const std::vector<uint8_t> &rawData,
	const std::string          &mimeType)
{
	impl->insertBinaryFileToDatabase(token, database, collection, name, rawData, mimeType);
}

void RepoController::insertRole(
	const RepoController::RepoToken   *token,
	const repo::core::model::RepoRole &role
	)
{
	impl->insertRole(token, role);
}

void RepoController::insertUser(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoUser  &user)
{
	impl->insertUser(token, user);
}

bool RepoController::removeCollection(
	const RepoController::RepoToken             *token,
	const std::string     &databaseName,
	const std::string     &collectionName,
	std::string			  &errMsg
	)
{
	return impl->removeCollection(token, databaseName, collectionName, errMsg);
}

bool RepoController::removeDatabase(
	const RepoController::RepoToken       *token,
	const std::string     &databaseName,
	std::string			  &errMsg
	)
{
	return impl->removeDatabase(token, databaseName, errMsg);
}

void RepoController::removeDocument(
	const RepoController::RepoToken          *token,
	const std::string                        &databaseName,
	const std::string                        &collectionName,
	const repo::core::model::RepoBSON        &bson)
{
	impl->removeDocument(token, databaseName, collectionName, bson);
}

bool RepoController::removeProject(
	const RepoController::RepoToken          *token,
	const std::string                        &databaseName,
	const std::string                        &projectName,
	std::string								 &errMsg)
{
	return impl->removeProject(token, databaseName, projectName, errMsg);
}

void RepoController::removeRole(
	const RepoController::RepoToken          *token,
	const repo::core::model::RepoRole        &role)
{
	impl->removeRole(token, role);
}

void RepoController::removeUser(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoUser  &user)
{
	impl->removeUser(token, user);
}

void RepoController::updateRole(
	const RepoController::RepoToken          *token,
	const repo::core::model::RepoRole        &role)
{
	impl->updateRole(token, role);
}

void RepoController::updateUser(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoUser  &user)
{
	impl->updateUser(token, user);
}

void RepoController::upsertDocument(
	const RepoController::RepoToken          *token,
	const std::string                        &databaseName,
	const std::string                        &collectionName,
	const repo::core::model::RepoBSON        &bson)
{
	impl->upsertDocument(token, databaseName, collectionName, bson);
}

void RepoController::setLoggingLevel(const repo::lib::RepoLog::RepoLogLevel &level)
{
	impl->setLoggingLevel(level);
}

void RepoController::logToFile(const std::string &filePath)
{
	impl->logToFile(filePath);
}

repo::core::model::RepoScene* RepoController::createFederatedScene(
	const std::map<repo::core::model::TransformationNode, repo::core::model::ReferenceNode> &fedMap)
{
	return impl->createFederatedScene(fedMap);
}

repo::core::model::RepoScene* RepoController::createMapScene(
	const repo::core::model::MapNode &mapNode)
{
	return impl->createMapScene(mapNode);
}

bool RepoController::generateAndCommitGLTFBuffer(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoScene *scene)
{
	return impl->generateAndCommitGLTFBuffer(token, scene);
}

bool RepoController::generateAndCommitSRCBuffer(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoScene *scene)
{
	return impl->generateAndCommitSRCBuffer(token, scene);
}

repo_web_buffers_t RepoController::generateGLTFBuffer(
	const repo::core::model::RepoScene *scene)
{
	return impl->generateGLTFBuffer(scene);
}

repo_web_buffers_t RepoController::generateSRCBuffer(
	const repo::core::model::RepoScene *scene)
{
	return impl->generateSRCBuffer(scene);
}

std::list<std::string> RepoController::getAdminDatabaseRoles(const RepoController::RepoToken *token)
{
	return impl->getAdminDatabaseRoles(token);
}

std::string RepoController::getNameOfAdminDatabase(const RepoController::RepoToken *token)
{
	return impl->getNameOfAdminDatabase(token);
}

std::shared_ptr<repo_partitioning_tree_t>
RepoController::getScenePartitioning(
const repo::core::model::RepoScene *scene,
const uint32_t                     &maxDepth
)
{
	return impl->getScenePartitioning(scene, maxDepth);
}

std::list<std::string> RepoController::getStandardDatabaseRoles(const RepoController::RepoToken *token)
{
	return impl->getStandardDatabaseRoles(token);
}

std::string RepoController::getSupportedImportFormats()
{
	return impl->getSupportedImportFormats();
}

std::string RepoController::getSupportedExportFormats()
{
	return impl->getSupportedExportFormats();
}

repo::core::model::RepoNodeSet RepoController::loadMetadataFromFile(
	const std::string &filePath,
	const char        &delimiter)
{
	return impl->loadMetadataFromFile(filePath, delimiter);
}

repo::core::model::RepoScene*
RepoController::loadSceneFromFile(
const std::string                                          &filePath,
const bool                                                 &applyReduction,
const bool                                                 &rotateModel,
const repo::manipulator::modelconvertor::ModelImportConfig *config)
{
	return impl->loadSceneFromFile(filePath, applyReduction, rotateModel, config);
}

void RepoController::saveOriginalFiles(
	const RepoController::RepoToken    *token,
	const repo::core::model::RepoScene *scene,
	const std::string                   &directory)
{
	return impl->saveOriginalFiles(token, scene, directory);
}

void RepoController::saveOriginalFiles(
	const RepoController::RepoToken     *token,
	const std::string                   &database,
	const std::string                   &project,
	const std::string                   &directory)
{
	return impl->saveOriginalFiles(token, database, project, directory);
}

bool RepoController::saveSceneToFile(
	const std::string &filePath,
	const repo::core::model::RepoScene* scene)
{
	return impl->saveSceneToFile(filePath, scene);
}

void RepoController::reduceTransformations(
	const RepoController::RepoToken              *token,
	repo::core::model::RepoScene *scene)
{
	impl->reduceTransformations(token, scene);
}

void RepoController::compareScenes(
	const RepoController::RepoToken    *token,
	repo::core::model::RepoScene       *base,
	repo::core::model::RepoScene       *compare,
	repo_diff_result_t                         &baseResults,
	repo_diff_result_t                         &compResults,
	const repo::DiffMode                     &diffMode
	)
{
	impl->compareScenes(token, base, compare, baseResults, compResults, diffMode);
}

std::string RepoController::getVersion()
{
	return impl->getVersion();
}<|endoftext|>


<commit_before>#include <phypp.hpp>
#include <iomanip>
#include "fast++-ssp.hpp"

int phypp_main(int argc, char* argv[]) {
    if (argc <= 1) {
        print("usage: fast++-sfh2sed sfh=... tobs=... ssp=... out=... "
            "[Av=... z=... H0=... omega_L=... omega_m=...]");
        return 0;
    }

    // Read command line arguments
    std::string sfh_file, library_file, out_file;
    double tobs = dnan;
    double z = dnan;
    double Av = 0.0; // [mag]
    double sfh_step = 1.0; // [Myr]
    double H0 = 70.0;
    double omega_L = 0.7;
    double omega_m = 0.3;
    bool lookback = false;

    read_args(argc, argv, arg_list(name(sfh_file, "sfh"), name(library_file, "ssp"),
        name(out_file, "out"), tobs, z, Av, sfh_step, H0, omega_m, omega_L, lookback));

    // Check arguments
    if (!is_finite(tobs) && !lookback) {
        error("please provide the time of observation in 'tobs=...' (in Myr), "
            "or specify 'lookback' if time is in lookback unit (tobs=0)");
        return 1;
    }
    if (sfh_file.empty()) {
        error("please provide the path to the file containing the SFH in 'sfh=...'");
        return 1;
    }
    if (library_file.empty()) {
        error("please provide the path to the SSP library in 'ssp=...'");
        return 1;
    }
    if (out_file.empty()) {
        error("please provide the path to the output file in 'out=...'");
        return 1;
    }

    cosmo_t cosmo;
    cosmo.H0 = H0;
    cosmo.wL = omega_L;
    cosmo.wm = omega_m;

    // Read SSP library
    ssp_bc03 ssp;
    ssp.read(file::get_directory(library_file)+file::get_basename(library_file));
    ssp.age /= 1e6; // yr to Myr
    double max_age = max(ssp.age);

    // Read SFH
    vec1d input_t, input_sfr;
    if (ends_with(sfh_file, ".fits")) {
        fits::read_table(sfh_file, "t", input_t, "sfr", input_sfr);
    } else {
        ascii::read_table(sfh_file, input_t, input_sfr);
    }

    // Check input
    double min_t = min(input_t), max_t = max(input_t);
    if (max_t > 1e5) {
        error("time axis must be given in Myr, found too high values (", max_t, ")");
        return 1;
    }
    if (min_t < 0) {
        error("time axis contains negative values");
        return 1;
    }
    if (!lookback && tobs > max_t) {
        error("requested observation time (", tobs, ") is larger than maximum time in SFH (",
            max_t, ")");
        return 1;
    }
    if (lookback && min_t > 0) {
        error("when 'lookback' is set, time axis must reach zero (found minimum: ", min_t, ")");
        return 1;
    }
    if ((lookback && max_t > max_age) || (!lookback && tobs - min_t > max_age)) {
        error("SFH goes beyond the maximum age of the library (", max_age/1e3, " Gyr)");
        return 1;
    }
    if (min(input_sfr) < 0) {
        error("input SFR is negative");
        return 1;
    }
    if (input_t.size() > 1 && input_t[1] < input_t[0]) {
        error("time axis must be sorted by increasing value");
        return 1;
    }

    // Resample SFH on grid
    double tt0 = min_t;
    double tt1 = tobs;
    if (lookback) {
        tt0 = 0.0;
        tt1 = max_t;
    }

    vec1d t = rgen_step(tt0, tt1, sfh_step);
    vec1d sfr;

    input_sfr *= 1e6;

    double orig_step = median(input_t[1-_] - input_t[_-(input_t.size()-2)]);
    if (orig_step < sfh_step) {
        // Average
        sfr.resize(t.size());
        for (uint_t i : range(t)) {
            double t0 = max(min_t, t[i] - 0.5*sfh_step);
            double t1 = min(max_t, t[i] + 0.5*sfh_step);
            if (t0 >= t1) break;
            sfr[i] = integrate(input_t, input_sfr, t0, t1)/(t1 - t0);
        }
    } else {
        // Interpolate
        sfr = interpolate(input_sfr, input_t, t);
    }

    // Put in lookback unit
    if (!lookback) {
        t = reverse(tobs - t);
        sfr = reverse(sfr);
    }

    fits::write_table("tmp.fits", ftable(t, sfr));

    // Sum SSPs
    vec1d tpl_flux(ssp.lambda.size());
    ssp.integrate(t, sfr, [&](uint_t it, double formed) {
        tpl_flux += formed*ssp.sed.safe(it,_);
    });

    if (Av > 0) {
        // Apply dust attenuation
        auto calzetti2000 = [](double l) {
            // http://adsabs.harvard.edu/abs/2000ApJ...533..682C

            const double iRv = 1.0/4.05;

            l *= 1e-4; // Angstrom to um
            if (l <= 0.63) {
                l = (2.659*iRv)*(-2.156 + 1.509/l - 0.198*pow(l, -2) + 0.011*pow(l, -3)) + 1.0;
            } else {
                l = (2.659*iRv)*(-1.857 + 1.040/l) + 1.0;
            }

            if (l < 0) l = 0;

            return l;
        };

        for (uint_t il : range(tpl_flux)) {
            tpl_flux.safe[il] *= e10(-0.4*Av*calzetti2000(ssp.lambda.safe[il]));
        }
    }

    if (is_finite(z)) {
        // Apply redshift
        const double dist_Mpc_to_cgs = 3.0856e24; // [cm/Mpc]
        const double lum_sol_to_cgs  = 3.839e33;  // [erg/s/Lsol]
        const double factor = 1e19*lum_sol_to_cgs/sqr(dist_Mpc_to_cgs);
        double lum2fl = factor/(4.0*dpi*(1.0+z)*sqr(astro::lumdist(z, cosmo)));

        auto madau1995 = [](double tz, vec1d lam) {
            // http://adsabs.harvard.edu/abs/1995ApJ...441...18M
            // TODO: check this implementation someday, I suspect this is wrong or
            // very approximate (taken directly from FAST)

            double da; {
                double l0 = 1050.0*(1.0 + tz);
                double l1 = 1170.0*(1.0 + tz);
                uint_t nstep = 100;
                vec1d tl = rgen(l0, l1, nstep);
                vec1d ptau = exp(-3.6e-3*pow(tl/1216.0, 3.46));
                da = total(ptau)*(l1-l0)/nstep/(120.0*(1.0 + tz));
            }

            double db; {
                double l0 = 920.0*(1.0 + tz);
                double l1 = 1015.0*(1.0 + tz);
                uint_t nstep = 100;
                vec1d tl = rgen(l0, l1, nstep);
                vec1d ptau = exp(-1.7e-3*pow(tl/1026.0, 3.46) - 1.2e-3*pow(tl/972.5, 3.46) -
                    9.3e-4*pow(tl/950.0, 3.46));
                db = total(ptau)*(l1-l0)/nstep/(95.0*(1.0 + tz));
            }

            for (auto& l : lam) {
                if (l < 912) {
                    l = 0.0;
                } else if (l < 1026) {
                    l = db;
                } else if (l < 1216) {
                    l = da;
                } else {
                    l = 1.0;
                }
            }

            return lam;
        };

        ssp.lambda *= (1.0 + z);
        tpl_flux *= lum2fl*madau1995(z, ssp.lambda);
    }

    // Save SED
    file::mkdir(file::get_directory(out_file));
    std::ofstream fout(out_file);
    if (is_finite(z)) {
        fout << "# wl fl (x 10^-19 ergs s^-1 cm^-2 Angstrom^-1)\n";
    } else {
        fout << "# wl fl (Lsol Angstrom^-1)\n";
    }

    for (uint_t il : range(ssp.lambda)) {
        fout << std::setw(13) << ssp.lambda.safe[il] << std::setw(13) << tpl_flux.safe[il] << "\n";
    }
    fout.close();

    return 0;
}
<commit_msg>Simplified IGM formula<commit_after>#include <phypp.hpp>
#include <iomanip>
#include "fast++-ssp.hpp"

int phypp_main(int argc, char* argv[]) {
    if (argc <= 1) {
        print("usage: fast++-sfh2sed sfh=... tobs=... ssp=... out=... "
            "[Av=... z=... H0=... omega_L=... omega_m=...]");
        return 0;
    }

    // Read command line arguments
    std::string sfh_file, library_file, out_file;
    double tobs = dnan;
    double z = dnan;
    double Av = 0.0; // [mag]
    double sfh_step = 1.0; // [Myr]
    double H0 = 70.0;
    double omega_L = 0.7;
    double omega_m = 0.3;
    bool lookback = false;

    read_args(argc, argv, arg_list(name(sfh_file, "sfh"), name(library_file, "ssp"),
        name(out_file, "out"), tobs, z, Av, sfh_step, H0, omega_m, omega_L, lookback));

    // Check arguments
    if (!is_finite(tobs) && !lookback) {
        error("please provide the time of observation in 'tobs=...' (in Myr), "
            "or specify 'lookback' if time is in lookback unit (tobs=0)");
        return 1;
    }
    if (sfh_file.empty()) {
        error("please provide the path to the file containing the SFH in 'sfh=...'");
        return 1;
    }
    if (library_file.empty()) {
        error("please provide the path to the SSP library in 'ssp=...'");
        return 1;
    }
    if (out_file.empty()) {
        error("please provide the path to the output file in 'out=...'");
        return 1;
    }

    cosmo_t cosmo;
    cosmo.H0 = H0;
    cosmo.wL = omega_L;
    cosmo.wm = omega_m;

    // Read SSP library
    ssp_bc03 ssp;
    ssp.read(file::get_directory(library_file)+file::get_basename(library_file));
    ssp.age /= 1e6; // yr to Myr
    double max_age = max(ssp.age);

    // Read SFH
    vec1d input_t, input_sfr;
    if (ends_with(sfh_file, ".fits")) {
        fits::read_table(sfh_file, "t", input_t, "sfr", input_sfr);
    } else {
        ascii::read_table(sfh_file, input_t, input_sfr);
    }

    // Check input
    double min_t = min(input_t), max_t = max(input_t);
    if (max_t > 1e5) {
        error("time axis must be given in Myr, found too high values (", max_t, ")");
        return 1;
    }
    if (min_t < 0) {
        error("time axis contains negative values");
        return 1;
    }
    if (!lookback && tobs > max_t) {
        error("requested observation time (", tobs, ") is larger than maximum time in SFH (",
            max_t, ")");
        return 1;
    }
    if (lookback && min_t > 0) {
        error("when 'lookback' is set, time axis must reach zero (found minimum: ", min_t, ")");
        return 1;
    }
    if ((lookback && max_t > max_age) || (!lookback && tobs - min_t > max_age)) {
        error("SFH goes beyond the maximum age of the library (", max_age/1e3, " Gyr)");
        return 1;
    }
    if (min(input_sfr) < 0) {
        error("input SFR is negative");
        return 1;
    }
    if (input_t.size() > 1 && input_t[1] < input_t[0]) {
        error("time axis must be sorted by increasing value");
        return 1;
    }

    // Resample SFH on grid
    double tt0 = min_t;
    double tt1 = tobs;
    if (lookback) {
        tt0 = 0.0;
        tt1 = max_t;
    }

    vec1d t = rgen_step(tt0, tt1, sfh_step);
    vec1d sfr;

    input_sfr *= 1e6;

    double orig_step = median(input_t[1-_] - input_t[_-(input_t.size()-2)]);
    if (orig_step < sfh_step) {
        // Average
        sfr.resize(t.size());
        for (uint_t i : range(t)) {
            double t0 = max(min_t, t[i] - 0.5*sfh_step);
            double t1 = min(max_t, t[i] + 0.5*sfh_step);
            if (t0 >= t1) break;
            sfr[i] = integrate(input_t, input_sfr, t0, t1)/(t1 - t0);
        }
    } else {
        // Interpolate
        sfr = interpolate(input_sfr, input_t, t);
    }

    // Put in lookback unit
    if (!lookback) {
        t = reverse(tobs - t);
        sfr = reverse(sfr);
    }

    fits::write_table("tmp.fits", ftable(t, sfr));

    // Sum SSPs
    vec1d tpl_flux(ssp.lambda.size());
    ssp.integrate(t, sfr, [&](uint_t it, double formed) {
        tpl_flux += formed*ssp.sed.safe(it,_);
    });

    if (Av > 0) {
        // Apply dust attenuation
        auto calzetti2000 = [](double l) {
            // http://adsabs.harvard.edu/abs/2000ApJ...533..682C

            const double iRv = 1.0/4.05;

            l *= 1e-4; // Angstrom to um
            if (l <= 0.63) {
                l = (2.659*iRv)*(-2.156 + 1.509/l - 0.198*pow(l, -2) + 0.011*pow(l, -3)) + 1.0;
            } else {
                l = (2.659*iRv)*(-1.857 + 1.040/l) + 1.0;
            }

            if (l < 0) l = 0;

            return l;
        };

        for (uint_t il : range(tpl_flux)) {
            tpl_flux.safe[il] *= e10(-0.4*Av*calzetti2000(ssp.lambda.safe[il]));
        }
    }

    if (is_finite(z)) {
        // Apply redshift
        const double dist_Mpc_to_cgs = 3.0856e24; // [cm/Mpc]
        const double lum_sol_to_cgs  = 3.839e33;  // [erg/s/Lsol]
        const double factor = 1e19*lum_sol_to_cgs/sqr(dist_Mpc_to_cgs);
        double lum2fl = factor/(4.0*dpi*(1.0+z)*sqr(astro::lumdist(z, cosmo)));

        auto madau1995 = [](double tz, vec1d lam) {
            // http://adsabs.harvard.edu/abs/1995ApJ...441...18M
            // TODO: check this implementation someday, I suspect this is wrong or
            // very approximate (taken directly from FAST)

            double da; {
                double l0 = 1050.0*(1.0 + tz);
                double l1 = 1170.0*(1.0 + tz);
                uint_t nstep = 100;
                vec1d tl = rgen(l0, l1, nstep);
                vec1d ptau = exp(-3.6e-3*pow(tl/1216.0, 3.46));
                da = mean(ptau);
            }

            double db; {
                double l0 = 920.0*(1.0 + tz);
                double l1 = 1015.0*(1.0 + tz);
                uint_t nstep = 100;
                vec1d tl = rgen(l0, l1, nstep);
                vec1d ptau = exp(-1.7e-3*pow(tl/1026.0, 3.46) - 1.2e-3*pow(tl/972.5, 3.46) -
                    9.3e-4*pow(tl/950.0, 3.46));
                db = mean(ptau);
            }

            for (auto& l : lam) {
                if (l < 912) {
                    l = 0.0;
                } else if (l < 1026) {
                    l = db;
                } else if (l < 1216) {
                    l = da;
                } else {
                    l = 1.0;
                }
            }

            return lam;
        };

        ssp.lambda *= (1.0 + z);
        tpl_flux *= lum2fl*madau1995(z, ssp.lambda);
    }

    // Save SED
    file::mkdir(file::get_directory(out_file));
    std::ofstream fout(out_file);
    if (is_finite(z)) {
        fout << "# wl fl (x 10^-19 ergs s^-1 cm^-2 Angstrom^-1)\n";
    } else {
        fout << "# wl fl (Lsol Angstrom^-1)\n";
    }

    for (uint_t il : range(ssp.lambda)) {
        fout << std::setw(13) << ssp.lambda.safe[il] << std::setw(13) << tpl_flux.safe[il] << "\n";
    }
    fout.close();

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2014, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "SubsystemLibrary.h"
#include "NamedElementBuilderTemplate.h"
#include "SkeletonSubsystem.h"

extern "C"
{
void getSkeletonSusbystemBuilder(CSubsystemLibrary* pSubsystemLibrary)
{
    pSubsystemLibrary->addElementBuilder("Skeleton", new TNamedElementBuilderTemplate<CSkeletonSubsystem>());
}
}
<commit_msg>Fixed SubsystemBuilder function in Skeleton plugin<commit_after>/*
 * Copyright (c) 2011-2014, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "SubsystemLibrary.h"
#include "NamedElementBuilderTemplate.h"
#include "SkeletonSubsystem.h"

extern "C"
{
void getSKELETONSubsystemBuilder(CSubsystemLibrary* pSubsystemLibrary)
{
    pSubsystemLibrary->addElementBuilder("Skeleton", new TNamedElementBuilderTemplate<CSkeletonSubsystem>());
}
}
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. 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

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

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

#include "paddle/fluid/operators/linear_chain_crf_op.h"

namespace paddle {
namespace operators {

class LinearChainCRFOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("Emission",
             "(LoDTensor, default LoDTensor<float>) "
             "A 2-D LoDTensor with shape [N x D], where N is the size of the "
             "mini-batch and D is the total tag number. The unscaled emission "
             "weight matrix for the linear chain CRF. ");
    AddInput("Transition",
             "(Tensor, default Tensor<float>) A 2-D Tensor with shape "
             "[(D + 2) x D]. The learnable parameter for the linear_chain_crf "
             "operator. See more details in the operator's comments.");
    AddInput("Label",
             "(LoDTensor, default LoDTensor<int64_t>) A LoDTensor with shape "
             "[N x 1], where N is the total element number in a mini-batch. "
             "The ground truth.");
    AddOutput(
        "Alpha",
        "(Tensor, default Tensor<float>) A 2-D Tensor with shape [N x D]. "
        "The forward vectors for the entire batch. Denote it as $\alpha$. "
        "$\alpha$ is a memo table used to calculate the normalization "
        "factor in CRF. $\alpha[k, v]$ stores the unnormalized "
        "probabilites of all possible unfinished sequences of tags that end at "
        "position $k$ with tag $v$. For each $k$, "
        "$\alpha[k, v]$ is a vector of length $D$ with a component for "
        "each tag value $v$. This vector is called a forward vecotr and "
        "will also be used in backward computations.")
        .AsIntermediate();
    AddOutput(
        "EmissionExps",
        "(Tensor, default Tensor<float>) A 2-D Tensor with shape [N x D]. "
        "The exponentials of Input(Emission). This is an intermediate "
        "computational result in forward computation, and will be reused in "
        "backward computation.")
        .AsIntermediate();
    AddOutput(
        "TransitionExps",
        "(Tensor, default Tensor<float>) A 2-D Tensor with shape "
        "[(D + 2) x D]. The exponentials of Input(Transition). This is an "
        "intermediate computational result in forward computation, and "
        "will be reused in backward computation.")
        .AsIntermediate();
    AddOutput(
        "LogLikelihood",
        "(Tensor, default Tensor<float>) The logarithm of the conditional "
        "likelihood of each training sample in a mini-batch. This is a 2-D "
        "tensor with shape [S x 1], where S is the sequence number in a "
        "mini-batch. Note: S is equal to the sequence number in a mini-batch. "
        "The output is no longer a LoDTensor.");
    AddComment(R"DOC(
Conditional Random Field defines an undirected probabilistic graph with nodes
denoting random variables and edges denoting dependencies between these
variables. CRF learns the conditional probability $P(Y|X)$, where
$X = (x_1, x_2, ... , x_n)$ are structured inputs and
$Y = (y_1, y_2, ... , y_n)$ are labels for the inputs.

Linear chain CRF is a special case of CRF that is useful for sequence labeling
task. Sequence labeling tasks do not assume a lot of conditional
independences among inputs. The only constraint they impose is that the input
and output must be linear sequences. Thus, the graph of such a CRF is a simple
chain or a line, which results in the linear chain CRF.

This operator implements the Forward-Backward algorithm for the linear chain
CRF. Please refer to http://www.cs.columbia.edu/~mcollins/fb.pdf and
http://cseweb.ucsd.edu/~elkan/250Bwinter2012/loglinearCRFs.pdf for details.

Equation:

1. Denote Input(Emission) to this operator as $x$ here.
2. The first D values of Input(Transition) to this operator are for starting
weights, denoted as $a$ here.
3. The next D values of Input(Transition) of this operator are for ending
weights, denoted as $b$ here.
4. The remaning values of Input(Transition) are for transition weights,
denoted as $w$ here.
5. Denote Input(Label) as $s$ here.

The probability of a sequence $s$ of length $L$ is defined as:
$$P(s) = (1/Z) \exp(a_{s_1} + b_{s_L}
                + \sum_{l=1}^L x_{s_l}
                + \sum_{l=2}^L w_{s_{l-1},s_l})$$

where $Z$ is a normalization value so that the sum of $P(s)$ over
all possible sequences is 1, and $x$ is the emission feature weight
to the linear chain CRF.

Finally, the linear chain CRF operator outputs the logarithm of the conditional
likelihood of each training sample in a mini-batch.

NOTE:

1. The feature function for a CRF is made up of the emission features and the
transition features. The emission feature weights are NOT computed in
this operator. They MUST be computed first before this operator is called.

2. Because this operator performs global normalization over all possible
sequences internally, it expects UNSCALED emission feature weights.
Please do not call this op with the emission feature being output of any
nonlinear activation.

3. The 2nd dimension of Input(Emission) MUST be equal to the tag number.

)DOC");
  }
};

class LinearChainCRFOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("Emission"),
                   "Input(Emission) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("Transition"),
                   "Input(Transition) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("Label"), "Input(Label) should be not null.");

    PADDLE_ENFORCE(ctx->HasOutput("Alpha"),
                   "Output(Alpha) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput("EmissionExps"),
                   "Output(EmissionExps) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput("TransitionExps"),
                   "Output(TransitionExps) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput("LogLikelihood"),
                   "Output(LogLikelihood) should be not null.");

    auto emission_dims = ctx->GetInputDim("Emission");
    PADDLE_ENFORCE_EQ(emission_dims.size(), 2,
                      "The Input(Emission) should be a 2-D tensor.");
    PADDLE_ENFORCE(emission_dims[0], "An empty mini-batch is not allowed.");

    auto transition_dims = ctx->GetInputDim("Transition");
    PADDLE_ENFORCE_EQ(transition_dims.size(), 2,
                      "The Input(Transition) should be a 2-D tensor.");
    bool check = true;
    if ((!ctx->IsRuntime()) &&
        (transition_dims[0] <= 0 || transition_dims[1] <= 0)) {
      check = false;
    }
    if (check) {
      PADDLE_ENFORCE_EQ(
          transition_dims[0] - 2, transition_dims[1],
          "An invalid dimension for the Input(Transition), which should "
          "be a 2-D tensor with shape [(D + 2) x D].");
    }
    PADDLE_INFERSHAPE_ENFORCE_EQ(
        ctx, emission_dims[1], transition_dims[1],
        "The 2nd dimension of the Input(Emission) and the Input(Transition) "
        "should be equal to the tag number.");

    auto label_dims = ctx->GetInputDim("Label");
    PADDLE_ENFORCE(label_dims.size() == 2UL && label_dims[1] == 1UL,
                   "The Input(Label) should be a 2-D tensor with the 2nd "
                   "dimensions fixed to 1.");
    PADDLE_INFERSHAPE_ENFORCE_EQ(
        ctx, emission_dims[0], label_dims[0],
        "The height of Input(Emission) and the height of Input(Label) "
        "should be the same.");

    ctx->SetOutputDim("Alpha", emission_dims);
    ctx->SetOutputDim("EmissionExps", emission_dims);
    ctx->SetOutputDim("TransitionExps", transition_dims);
    // TODO(caoying) This is tricky. The 1st dimension of Output(LogLikelihood)
    // is the sequence number in a mini-batch. The dimension set here should be
    // resized to its correct size in the function Compute. Fix this once we can
    // get LoD information in the InferShape interface.
    ctx->SetOutputDim("LogLikelihood", {emission_dims[0], 1});
  }

 protected:
  // Explicitly set that the data type of computation kernel of linear_chain_crf
  // is determined by its input "Emission".
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
    return framework::OpKernelType(ctx.Input<LoDTensor>("Emission")->type(),
                                   platform::CPUPlace());
  }
};

class LinearChainCRFGradOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("EmissionExps"),
                   "Input(EmissionExps) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("TransitionExps"),
                   "Input(TransitionExps) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("LogLikelihood")),
                   "Input(LogLikelihood@GRAD) shoudl be not null.");

    auto emission_exps_dims = ctx->GetInputDim("EmissionExps");
    PADDLE_ENFORCE_EQ(emission_exps_dims.size(), 2,
                      "The Input(EmissionExps) should be a 2-D tensor.");
    PADDLE_ENFORCE(emission_exps_dims[0],
                   "An empty mini-batch is not allowed.");

    auto transition_exps_dims = ctx->GetInputDim("TransitionExps");
    PADDLE_ENFORCE_EQ(transition_exps_dims.size(), 2,
                      "The Input(TransitionExps) should be a 2-D tensor.");
    bool check = true;
    if ((!ctx->IsRuntime()) &&
        (transition_exps_dims[0] <= 0 || transition_exps_dims[1] <= 0)) {
      check = false;
    }
    if (check) {
      PADDLE_ENFORCE_EQ(
          transition_exps_dims[0] - 2, transition_exps_dims[1],
          "An invalid dimension for the Input(TransitionExps), which should "
          "be a 2-D tensor with shape [(D + 2) x D].");
    }
    PADDLE_INFERSHAPE_ENFORCE_EQ(
        ctx, emission_exps_dims[1], transition_exps_dims[1],
        "The 2nd dimension of the Input(EmissionExps) and the "
        "Input(TransitionExps) should be equal to the tag number.");

    auto label_dims = ctx->GetInputDim("Label");
    PADDLE_ENFORCE(label_dims.size() == 2UL && label_dims[1] == 1UL,
                   "The Input(Label) should be a 2-D tensor with the 2nd "
                   "dimensions fixed to 1.");
    PADDLE_INFERSHAPE_ENFORCE_EQ(
        ctx, emission_exps_dims[0], label_dims[0],
        "The height of Input(EmissionExps) and the height of Input(Label) "
        "should be the same.");

    if (ctx->HasOutput(framework::GradVarName("Emission"))) {
      ctx->SetOutputDim(framework::GradVarName("Emission"), emission_exps_dims);
      ctx->ShareLoD("Emission", framework::GradVarName("Emission"));
    }
    if (ctx->HasOutput(framework::GradVarName("Transition"))) {
      ctx->SetOutputDim(framework::GradVarName("Transition"),
                        transition_exps_dims);
      ctx->ShareLoD("Transition", framework::GradVarName("Transition"));
    }
  }

 protected:
  // Explicitly set that the data type of output of the linear_chain_crf_grad
  // operator is determined by its input: gradients of LogLikelihood.
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
    return framework::OpKernelType(
        ctx.Input<LoDTensor>(framework::GradVarName("LogLikelihood"))->type(),
        platform::CPUPlace());
  }
};

class LinearChainCRFGradDescMaker : public framework::SingleGradOpDescMaker {
 public:
  using framework::SingleGradOpDescMaker::SingleGradOpDescMaker;

 protected:
  std::unique_ptr<framework::OpDesc> Apply() const override {
    std::unique_ptr<framework::OpDesc> op(new framework::OpDesc());
    op->SetType("linear_chain_crf_grad");
    op->SetAttrMap(Attrs());

    op->SetInput("Emission", Input("Emission"));
    op->SetInput("Transition", Input("Transition"));
    op->SetInput("Label", Input("Label"));

    op->SetInput("Alpha", Output("Alpha"));
    op->SetInput("EmissionExps", Output("EmissionExps"));
    op->SetInput("TransitionExps", Output("TransitionExps"));

    op->SetInput(framework::GradVarName("LogLikelihood"),
                 OutputGrad("LogLikelihood"));

    op->SetOutput(framework::GradVarName("Emission"), InputGrad("Emission"));
    op->SetOutput(framework::GradVarName("Transition"),
                  InputGrad("Transition"));

    return op;
  }
};

DECLARE_NO_NEED_BUFFER_VARS_INFERENCE(
    LinearChainCRFGradNoNeedBufferVarsInference, "Transition", "Emission");

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
REGISTER_OPERATOR(linear_chain_crf, ops::LinearChainCRFOp,
                  ops::LinearChainCRFOpMaker, ops::LinearChainCRFGradDescMaker);
REGISTER_OPERATOR(linear_chain_crf_grad, ops::LinearChainCRFGradOp,
                  ops::LinearChainCRFGradNoNeedBufferVarsInference);
REGISTER_OP_CPU_KERNEL(
    linear_chain_crf,
    ops::LinearChainCRFOpKernel<paddle::platform::CPUDeviceContext, float>,
    ops::LinearChainCRFOpKernel<paddle::platform::CPUDeviceContext, double>);
REGISTER_OP_CPU_KERNEL(
    linear_chain_crf_grad,
    ops::LinearChainCRFGradOpKernel<paddle::platform::CPUDeviceContext, float>,
    ops::LinearChainCRFGradOpKernel<paddle::platform::CPUDeviceContext,
                                    double>);
<commit_msg>add <memory> test=develop<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. 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

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

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

#include "paddle/fluid/operators/linear_chain_crf_op.h"

#include <memory>

namespace paddle {
namespace operators {

class LinearChainCRFOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("Emission",
             "(LoDTensor, default LoDTensor<float>) "
             "A 2-D LoDTensor with shape [N x D], where N is the size of the "
             "mini-batch and D is the total tag number. The unscaled emission "
             "weight matrix for the linear chain CRF. ");
    AddInput("Transition",
             "(Tensor, default Tensor<float>) A 2-D Tensor with shape "
             "[(D + 2) x D]. The learnable parameter for the linear_chain_crf "
             "operator. See more details in the operator's comments.");
    AddInput("Label",
             "(LoDTensor, default LoDTensor<int64_t>) A LoDTensor with shape "
             "[N x 1], where N is the total element number in a mini-batch. "
             "The ground truth.");
    AddOutput(
        "Alpha",
        "(Tensor, default Tensor<float>) A 2-D Tensor with shape [N x D]. "
        "The forward vectors for the entire batch. Denote it as $\alpha$. "
        "$\alpha$ is a memo table used to calculate the normalization "
        "factor in CRF. $\alpha[k, v]$ stores the unnormalized "
        "probabilites of all possible unfinished sequences of tags that end at "
        "position $k$ with tag $v$. For each $k$, "
        "$\alpha[k, v]$ is a vector of length $D$ with a component for "
        "each tag value $v$. This vector is called a forward vecotr and "
        "will also be used in backward computations.")
        .AsIntermediate();
    AddOutput(
        "EmissionExps",
        "(Tensor, default Tensor<float>) A 2-D Tensor with shape [N x D]. "
        "The exponentials of Input(Emission). This is an intermediate "
        "computational result in forward computation, and will be reused in "
        "backward computation.")
        .AsIntermediate();
    AddOutput(
        "TransitionExps",
        "(Tensor, default Tensor<float>) A 2-D Tensor with shape "
        "[(D + 2) x D]. The exponentials of Input(Transition). This is an "
        "intermediate computational result in forward computation, and "
        "will be reused in backward computation.")
        .AsIntermediate();
    AddOutput(
        "LogLikelihood",
        "(Tensor, default Tensor<float>) The logarithm of the conditional "
        "likelihood of each training sample in a mini-batch. This is a 2-D "
        "tensor with shape [S x 1], where S is the sequence number in a "
        "mini-batch. Note: S is equal to the sequence number in a mini-batch. "
        "The output is no longer a LoDTensor.");
    AddComment(R"DOC(
Conditional Random Field defines an undirected probabilistic graph with nodes
denoting random variables and edges denoting dependencies between these
variables. CRF learns the conditional probability $P(Y|X)$, where
$X = (x_1, x_2, ... , x_n)$ are structured inputs and
$Y = (y_1, y_2, ... , y_n)$ are labels for the inputs.

Linear chain CRF is a special case of CRF that is useful for sequence labeling
task. Sequence labeling tasks do not assume a lot of conditional
independences among inputs. The only constraint they impose is that the input
and output must be linear sequences. Thus, the graph of such a CRF is a simple
chain or a line, which results in the linear chain CRF.

This operator implements the Forward-Backward algorithm for the linear chain
CRF. Please refer to http://www.cs.columbia.edu/~mcollins/fb.pdf and
http://cseweb.ucsd.edu/~elkan/250Bwinter2012/loglinearCRFs.pdf for details.

Equation:

1. Denote Input(Emission) to this operator as $x$ here.
2. The first D values of Input(Transition) to this operator are for starting
weights, denoted as $a$ here.
3. The next D values of Input(Transition) of this operator are for ending
weights, denoted as $b$ here.
4. The remaning values of Input(Transition) are for transition weights,
denoted as $w$ here.
5. Denote Input(Label) as $s$ here.

The probability of a sequence $s$ of length $L$ is defined as:
$$P(s) = (1/Z) \exp(a_{s_1} + b_{s_L}
                + \sum_{l=1}^L x_{s_l}
                + \sum_{l=2}^L w_{s_{l-1},s_l})$$

where $Z$ is a normalization value so that the sum of $P(s)$ over
all possible sequences is 1, and $x$ is the emission feature weight
to the linear chain CRF.

Finally, the linear chain CRF operator outputs the logarithm of the conditional
likelihood of each training sample in a mini-batch.

NOTE:

1. The feature function for a CRF is made up of the emission features and the
transition features. The emission feature weights are NOT computed in
this operator. They MUST be computed first before this operator is called.

2. Because this operator performs global normalization over all possible
sequences internally, it expects UNSCALED emission feature weights.
Please do not call this op with the emission feature being output of any
nonlinear activation.

3. The 2nd dimension of Input(Emission) MUST be equal to the tag number.

)DOC");
  }
};

class LinearChainCRFOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("Emission"),
                   "Input(Emission) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("Transition"),
                   "Input(Transition) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("Label"), "Input(Label) should be not null.");

    PADDLE_ENFORCE(ctx->HasOutput("Alpha"),
                   "Output(Alpha) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput("EmissionExps"),
                   "Output(EmissionExps) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput("TransitionExps"),
                   "Output(TransitionExps) should be not null.");
    PADDLE_ENFORCE(ctx->HasOutput("LogLikelihood"),
                   "Output(LogLikelihood) should be not null.");

    auto emission_dims = ctx->GetInputDim("Emission");
    PADDLE_ENFORCE_EQ(emission_dims.size(), 2,
                      "The Input(Emission) should be a 2-D tensor.");
    PADDLE_ENFORCE(emission_dims[0], "An empty mini-batch is not allowed.");

    auto transition_dims = ctx->GetInputDim("Transition");
    PADDLE_ENFORCE_EQ(transition_dims.size(), 2,
                      "The Input(Transition) should be a 2-D tensor.");
    bool check = true;
    if ((!ctx->IsRuntime()) &&
        (transition_dims[0] <= 0 || transition_dims[1] <= 0)) {
      check = false;
    }
    if (check) {
      PADDLE_ENFORCE_EQ(
          transition_dims[0] - 2, transition_dims[1],
          "An invalid dimension for the Input(Transition), which should "
          "be a 2-D tensor with shape [(D + 2) x D].");
    }
    PADDLE_INFERSHAPE_ENFORCE_EQ(
        ctx, emission_dims[1], transition_dims[1],
        "The 2nd dimension of the Input(Emission) and the Input(Transition) "
        "should be equal to the tag number.");

    auto label_dims = ctx->GetInputDim("Label");
    PADDLE_ENFORCE(label_dims.size() == 2UL && label_dims[1] == 1UL,
                   "The Input(Label) should be a 2-D tensor with the 2nd "
                   "dimensions fixed to 1.");
    PADDLE_INFERSHAPE_ENFORCE_EQ(
        ctx, emission_dims[0], label_dims[0],
        "The height of Input(Emission) and the height of Input(Label) "
        "should be the same.");

    ctx->SetOutputDim("Alpha", emission_dims);
    ctx->SetOutputDim("EmissionExps", emission_dims);
    ctx->SetOutputDim("TransitionExps", transition_dims);
    // TODO(caoying) This is tricky. The 1st dimension of Output(LogLikelihood)
    // is the sequence number in a mini-batch. The dimension set here should be
    // resized to its correct size in the function Compute. Fix this once we can
    // get LoD information in the InferShape interface.
    ctx->SetOutputDim("LogLikelihood", {emission_dims[0], 1});
  }

 protected:
  // Explicitly set that the data type of computation kernel of linear_chain_crf
  // is determined by its input "Emission".
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
    return framework::OpKernelType(ctx.Input<LoDTensor>("Emission")->type(),
                                   platform::CPUPlace());
  }
};

class LinearChainCRFGradOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("EmissionExps"),
                   "Input(EmissionExps) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput("TransitionExps"),
                   "Input(TransitionExps) should be not null.");
    PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("LogLikelihood")),
                   "Input(LogLikelihood@GRAD) shoudl be not null.");

    auto emission_exps_dims = ctx->GetInputDim("EmissionExps");
    PADDLE_ENFORCE_EQ(emission_exps_dims.size(), 2,
                      "The Input(EmissionExps) should be a 2-D tensor.");
    PADDLE_ENFORCE(emission_exps_dims[0],
                   "An empty mini-batch is not allowed.");

    auto transition_exps_dims = ctx->GetInputDim("TransitionExps");
    PADDLE_ENFORCE_EQ(transition_exps_dims.size(), 2,
                      "The Input(TransitionExps) should be a 2-D tensor.");
    bool check = true;
    if ((!ctx->IsRuntime()) &&
        (transition_exps_dims[0] <= 0 || transition_exps_dims[1] <= 0)) {
      check = false;
    }
    if (check) {
      PADDLE_ENFORCE_EQ(
          transition_exps_dims[0] - 2, transition_exps_dims[1],
          "An invalid dimension for the Input(TransitionExps), which should "
          "be a 2-D tensor with shape [(D + 2) x D].");
    }
    PADDLE_INFERSHAPE_ENFORCE_EQ(
        ctx, emission_exps_dims[1], transition_exps_dims[1],
        "The 2nd dimension of the Input(EmissionExps) and the "
        "Input(TransitionExps) should be equal to the tag number.");

    auto label_dims = ctx->GetInputDim("Label");
    PADDLE_ENFORCE(label_dims.size() == 2UL && label_dims[1] == 1UL,
                   "The Input(Label) should be a 2-D tensor with the 2nd "
                   "dimensions fixed to 1.");
    PADDLE_INFERSHAPE_ENFORCE_EQ(
        ctx, emission_exps_dims[0], label_dims[0],
        "The height of Input(EmissionExps) and the height of Input(Label) "
        "should be the same.");

    if (ctx->HasOutput(framework::GradVarName("Emission"))) {
      ctx->SetOutputDim(framework::GradVarName("Emission"), emission_exps_dims);
      ctx->ShareLoD("Emission", framework::GradVarName("Emission"));
    }
    if (ctx->HasOutput(framework::GradVarName("Transition"))) {
      ctx->SetOutputDim(framework::GradVarName("Transition"),
                        transition_exps_dims);
      ctx->ShareLoD("Transition", framework::GradVarName("Transition"));
    }
  }

 protected:
  // Explicitly set that the data type of output of the linear_chain_crf_grad
  // operator is determined by its input: gradients of LogLikelihood.
  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext& ctx) const override {
    return framework::OpKernelType(
        ctx.Input<LoDTensor>(framework::GradVarName("LogLikelihood"))->type(),
        platform::CPUPlace());
  }
};

class LinearChainCRFGradDescMaker : public framework::SingleGradOpDescMaker {
 public:
  using framework::SingleGradOpDescMaker::SingleGradOpDescMaker;

 protected:
  std::unique_ptr<framework::OpDesc> Apply() const override {
    std::unique_ptr<framework::OpDesc> op(new framework::OpDesc());
    op->SetType("linear_chain_crf_grad");
    op->SetAttrMap(Attrs());

    op->SetInput("Emission", Input("Emission"));
    op->SetInput("Transition", Input("Transition"));
    op->SetInput("Label", Input("Label"));

    op->SetInput("Alpha", Output("Alpha"));
    op->SetInput("EmissionExps", Output("EmissionExps"));
    op->SetInput("TransitionExps", Output("TransitionExps"));

    op->SetInput(framework::GradVarName("LogLikelihood"),
                 OutputGrad("LogLikelihood"));

    op->SetOutput(framework::GradVarName("Emission"), InputGrad("Emission"));
    op->SetOutput(framework::GradVarName("Transition"),
                  InputGrad("Transition"));

    return op;
  }
};

DECLARE_NO_NEED_BUFFER_VARS_INFERENCE(
    LinearChainCRFGradNoNeedBufferVarsInference, "Transition", "Emission");

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
REGISTER_OPERATOR(linear_chain_crf, ops::LinearChainCRFOp,
                  ops::LinearChainCRFOpMaker, ops::LinearChainCRFGradDescMaker);
REGISTER_OPERATOR(linear_chain_crf_grad, ops::LinearChainCRFGradOp,
                  ops::LinearChainCRFGradNoNeedBufferVarsInference);
REGISTER_OP_CPU_KERNEL(
    linear_chain_crf,
    ops::LinearChainCRFOpKernel<paddle::platform::CPUDeviceContext, float>,
    ops::LinearChainCRFOpKernel<paddle::platform::CPUDeviceContext, double>);
REGISTER_OP_CPU_KERNEL(
    linear_chain_crf_grad,
    ops::LinearChainCRFGradOpKernel<paddle::platform::CPUDeviceContext, float>,
    ops::LinearChainCRFGradOpKernel<paddle::platform::CPUDeviceContext,
                                    double>);
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: bitmap.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:30:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CGM_BITMAP_HXX_
#define CGM_BITMAP_HXX_

#include "cgm.hxx"
#include <vcl/bmpacc.hxx>

class CGM;

class CGMBitmapDescriptor
{
    public:
        sal_uInt8*              mpBuf;
        Bitmap*                 mpBitmap;
        BitmapWriteAccess*      mpAcc;
        sal_Bool                mbStatus;
        sal_Bool                mbVMirror;
        sal_Bool                mbHMirror;
        sal_uInt32              mnDstBitsPerPixel;
        sal_uInt32              mnScanSize;         // bytes per line
        FloatPoint              mnP, mnQ, mnR;

        FloatPoint              mnOrigin;
        double                  mndx, mndy;
        double                  mnOrientation;

        sal_uInt32              mnX, mnY;
        long                    mnLocalColorPrecision;
        sal_uInt32              mnCompressionMode;
                                CGMBitmapDescriptor() :
                                mpAcc       ( NULL ),
                                mbStatus    ( sal_False ),
                                mbVMirror   ( sal_False ),
                                mbHMirror   ( sal_False ),
                                mpBitmap    ( NULL ),
                                mpBuf       ( NULL ) { };
                                ~CGMBitmapDescriptor()
                                {
                                    if ( mpAcc )
                                        mpBitmap->ReleaseAccess( mpAcc );
                                    if ( mpBitmap )
                                        delete mpBitmap;
                                };
};

class CGMBitmap
{
        CGM*                    mpCGM;
        CGMBitmapDescriptor*    pCGMBitmapDescriptor;
        sal_Bool                ImplGetDimensions( CGMBitmapDescriptor& );
        void                    ImplSetCurrentPalette( CGMBitmapDescriptor& );
        void                    ImplGetBitmap( CGMBitmapDescriptor& );
        void                    ImplInsert( CGMBitmapDescriptor& rSource, CGMBitmapDescriptor& rDest );
    public:
                                CGMBitmap( CGM& rCGM );
                                ~CGMBitmap();
        CGMBitmapDescriptor*    GetBitmap();
        CGMBitmap*              GetNext();
};
#endif

<commit_msg>INTEGRATION: CWS ooo20040815 (1.1.1.1.240); FILE MERGED 2004/08/04 12:45:15 waratah 1.1.1.1.240.1: #i32569# Order declarations to match header file<commit_after>/*************************************************************************
 *
 *  $RCSfile: bitmap.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-09-09 11:30:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CGM_BITMAP_HXX_
#define CGM_BITMAP_HXX_

#include "cgm.hxx"
#include <vcl/bmpacc.hxx>

class CGM;

class CGMBitmapDescriptor
{
    public:
        sal_uInt8*              mpBuf;
        Bitmap*                 mpBitmap;
        BitmapWriteAccess*      mpAcc;
        sal_Bool                mbStatus;
        sal_Bool                mbVMirror;
        sal_Bool                mbHMirror;
        sal_uInt32              mnDstBitsPerPixel;
        sal_uInt32              mnScanSize;         // bytes per line
        FloatPoint              mnP, mnQ, mnR;

        FloatPoint              mnOrigin;
        double                  mndx, mndy;
        double                  mnOrientation;

        sal_uInt32              mnX, mnY;
        long                    mnLocalColorPrecision;
        sal_uInt32              mnCompressionMode;
                                CGMBitmapDescriptor() :
                                mpBuf       ( NULL ),
                                mpBitmap    ( NULL ),
                                mpAcc       ( NULL ),
                                mbStatus    ( sal_False ),
                                mbVMirror   ( sal_False ),
                                mbHMirror   ( sal_False ) { };
                                ~CGMBitmapDescriptor()
                                {
                                    if ( mpAcc )
                                        mpBitmap->ReleaseAccess( mpAcc );
                                    if ( mpBitmap )
                                        delete mpBitmap;
                                };
};

class CGMBitmap
{
        CGM*                    mpCGM;
        CGMBitmapDescriptor*    pCGMBitmapDescriptor;
        sal_Bool                ImplGetDimensions( CGMBitmapDescriptor& );
        void                    ImplSetCurrentPalette( CGMBitmapDescriptor& );
        void                    ImplGetBitmap( CGMBitmapDescriptor& );
        void                    ImplInsert( CGMBitmapDescriptor& rSource, CGMBitmapDescriptor& rDest );
    public:
                                CGMBitmap( CGM& rCGM );
                                ~CGMBitmap();
        CGMBitmapDescriptor*    GetBitmap();
        CGMBitmap*              GetNext();
};
#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: transformer.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2008-01-10 13:23:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_goodies.hxx"

#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX_
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_IMAGE_HXX_
#include <vcl/image.hxx>
#endif
#ifndef _SV_METAACT_HXX
#include <vcl/metaact.hxx>
#endif
#include <tools/rcid.h>
#include <tools/resid.hxx>
#include <tools/resmgr.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <svtools/solar.hrc>
#include <vcl/salbtype.hxx>
#include <vcl/virdev.hxx>
#include <vcl/bmpacc.hxx>

#ifndef _COM_SUN_STAR_TEXT_GRAPHICCROP_HPP_
#include <com/sun/star/text/GraphicCrop.hpp>
#endif

#include "graphic.hxx"
#include "transformer.hxx"

using namespace com::sun::star;

namespace unographic {

// ----------------------
// - GraphicTransformer -
// ----------------------

GraphicTransformer::GraphicTransformer()
{
}

// ------------------------------------------------------------------------------

GraphicTransformer::~GraphicTransformer()
{
}

// ------------------------------------------------------------------------------

void setAlpha( Bitmap& rBitmap, AlphaMask& rAlpha, sal_Int32 nColorFrom, sal_Int8 nAlphaTo )
{
    BitmapWriteAccess* pWriteAccess = rAlpha.AcquireWriteAccess();
    BitmapReadAccess* pReadAccess = rBitmap.AcquireReadAccess();
    BitmapColor aColorFrom( static_cast< sal_uInt8 >( nColorFrom >> 16 ),
        static_cast< sal_uInt8 >( nColorFrom >> 8 ),
        static_cast< sal_uInt8 >( nColorFrom ) );
    if ( pReadAccess && pWriteAccess )
    {
        for ( sal_Int32 nY = 0; nY < pReadAccess->Height(); nY++ )
        {
            for ( sal_Int32 nX = 0; nX < pReadAccess->Width(); nX++ )
            {
                BitmapColor aColor( pReadAccess->GetPixel( nY, nX ) );
                if ( aColor == aColorFrom )
                    pWriteAccess->SetPixel( nY, nX, nAlphaTo );
            }
        }
    }
    rBitmap.ReleaseAccess( pReadAccess );
    rAlpha.ReleaseAccess( pWriteAccess );
}

// XGraphicTransformer
uno::Reference< graphic::XGraphic > SAL_CALL GraphicTransformer::colorChange(
    const uno::Reference< graphic::XGraphic >& rxGraphic, sal_Int32 nColorFrom, sal_Int8 nTolerance, sal_Int32 nColorTo, sal_Int8 nAlphaTo )
        throw ( lang::IllegalArgumentException, uno::RuntimeException)
{
    const uno::Reference< uno::XInterface > xIFace( rxGraphic, uno::UNO_QUERY );
    ::Graphic aGraphic( *::unographic::Graphic::getImplementation( xIFace ) );

    BitmapColor aColorFrom( static_cast< sal_uInt8 >( nColorFrom ), static_cast< sal_uInt8 >( nColorFrom >> 16 ), static_cast< sal_uInt8 >( nColorFrom >> 24 ) );
    BitmapColor aColorTo( static_cast< sal_uInt8 >( nColorTo ), static_cast< sal_uInt8 >( nColorTo >> 16 ), static_cast< sal_uInt8 >( nColorTo  >> 24 ) );

    if ( aGraphic.GetType() == GRAPHIC_BITMAP )
    {
        BitmapEx    aBitmapEx( aGraphic.GetBitmapEx() );
        Bitmap      aBitmap( aBitmapEx.GetBitmap() );

        if ( aBitmapEx.IsAlpha() )
        {
            AlphaMask aAlphaMask( aBitmapEx.GetAlpha() );
            setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
            aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
            aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
        }
        else if ( aBitmapEx.IsTransparent() )
        {
            if ( ( nAlphaTo == 0 ) || ( nAlphaTo == sal::static_int_cast<sal_Int8>(0xff) ) )
            {
                Bitmap aMask( aBitmapEx.GetMask() );
                Bitmap aMask2( aBitmap.CreateMask( aColorFrom, nTolerance ) );
                aMask.CombineSimple( aMask2, BMP_COMBINE_OR );
                aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
                aGraphic = ::Graphic( BitmapEx( aBitmap, aMask ) );
            }
            else
            {
                AlphaMask aAlphaMask( aBitmapEx.GetMask() );
                setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
                aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
                aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
            }
        }
        else
        {
            if ( ( nAlphaTo == 0 ) || ( nAlphaTo == sal::static_int_cast<sal_Int8>(0xff) ) )
            {
                Bitmap aMask( aBitmap.CreateMask( aColorFrom, nTolerance ) );
                aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
                aGraphic = ::Graphic( BitmapEx( aBitmap, aMask ) );
            }
            else
            {
                AlphaMask aAlphaMask( aBitmapEx.GetSizePixel() );
                setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
                aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
                aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
            }
        }
    }
    ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic();
    pUnoGraphic->init( aGraphic );
    uno::Reference< graphic::XGraphic > xRet( pUnoGraphic );
    return xRet;
}

}
<commit_msg>INTEGRATION: CWS changefileheader (1.2.24); FILE MERGED 2008/04/01 15:19:37 thb 1.2.24.3: #i85898# Stripping all external header guards 2008/04/01 12:31:05 thb 1.2.24.2: #i85898# Stripping all external header guards 2008/03/31 13:39:44 rt 1.2.24.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: transformer.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_goodies.hxx"
#include <rtl/uuid.h>
#include <vos/mutex.hxx>
#ifndef _SV_SVAPP_HXX_
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_IMAGE_HXX_
#include <vcl/image.hxx>
#endif
#include <vcl/metaact.hxx>
#include <tools/rcid.h>
#include <tools/resid.hxx>
#include <tools/resmgr.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <svtools/solar.hrc>
#include <vcl/salbtype.hxx>
#include <vcl/virdev.hxx>
#include <vcl/bmpacc.hxx>
#include <com/sun/star/text/GraphicCrop.hpp>

#include "graphic.hxx"
#include "transformer.hxx"

using namespace com::sun::star;

namespace unographic {

// ----------------------
// - GraphicTransformer -
// ----------------------

GraphicTransformer::GraphicTransformer()
{
}

// ------------------------------------------------------------------------------

GraphicTransformer::~GraphicTransformer()
{
}

// ------------------------------------------------------------------------------

void setAlpha( Bitmap& rBitmap, AlphaMask& rAlpha, sal_Int32 nColorFrom, sal_Int8 nAlphaTo )
{
    BitmapWriteAccess* pWriteAccess = rAlpha.AcquireWriteAccess();
    BitmapReadAccess* pReadAccess = rBitmap.AcquireReadAccess();
    BitmapColor aColorFrom( static_cast< sal_uInt8 >( nColorFrom >> 16 ),
        static_cast< sal_uInt8 >( nColorFrom >> 8 ),
        static_cast< sal_uInt8 >( nColorFrom ) );
    if ( pReadAccess && pWriteAccess )
    {
        for ( sal_Int32 nY = 0; nY < pReadAccess->Height(); nY++ )
        {
            for ( sal_Int32 nX = 0; nX < pReadAccess->Width(); nX++ )
            {
                BitmapColor aColor( pReadAccess->GetPixel( nY, nX ) );
                if ( aColor == aColorFrom )
                    pWriteAccess->SetPixel( nY, nX, nAlphaTo );
            }
        }
    }
    rBitmap.ReleaseAccess( pReadAccess );
    rAlpha.ReleaseAccess( pWriteAccess );
}

// XGraphicTransformer
uno::Reference< graphic::XGraphic > SAL_CALL GraphicTransformer::colorChange(
    const uno::Reference< graphic::XGraphic >& rxGraphic, sal_Int32 nColorFrom, sal_Int8 nTolerance, sal_Int32 nColorTo, sal_Int8 nAlphaTo )
        throw ( lang::IllegalArgumentException, uno::RuntimeException)
{
    const uno::Reference< uno::XInterface > xIFace( rxGraphic, uno::UNO_QUERY );
    ::Graphic aGraphic( *::unographic::Graphic::getImplementation( xIFace ) );

    BitmapColor aColorFrom( static_cast< sal_uInt8 >( nColorFrom ), static_cast< sal_uInt8 >( nColorFrom >> 16 ), static_cast< sal_uInt8 >( nColorFrom >> 24 ) );
    BitmapColor aColorTo( static_cast< sal_uInt8 >( nColorTo ), static_cast< sal_uInt8 >( nColorTo >> 16 ), static_cast< sal_uInt8 >( nColorTo  >> 24 ) );

    if ( aGraphic.GetType() == GRAPHIC_BITMAP )
    {
        BitmapEx    aBitmapEx( aGraphic.GetBitmapEx() );
        Bitmap      aBitmap( aBitmapEx.GetBitmap() );

        if ( aBitmapEx.IsAlpha() )
        {
            AlphaMask aAlphaMask( aBitmapEx.GetAlpha() );
            setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
            aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
            aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
        }
        else if ( aBitmapEx.IsTransparent() )
        {
            if ( ( nAlphaTo == 0 ) || ( nAlphaTo == sal::static_int_cast<sal_Int8>(0xff) ) )
            {
                Bitmap aMask( aBitmapEx.GetMask() );
                Bitmap aMask2( aBitmap.CreateMask( aColorFrom, nTolerance ) );
                aMask.CombineSimple( aMask2, BMP_COMBINE_OR );
                aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
                aGraphic = ::Graphic( BitmapEx( aBitmap, aMask ) );
            }
            else
            {
                AlphaMask aAlphaMask( aBitmapEx.GetMask() );
                setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
                aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
                aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
            }
        }
        else
        {
            if ( ( nAlphaTo == 0 ) || ( nAlphaTo == sal::static_int_cast<sal_Int8>(0xff) ) )
            {
                Bitmap aMask( aBitmap.CreateMask( aColorFrom, nTolerance ) );
                aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
                aGraphic = ::Graphic( BitmapEx( aBitmap, aMask ) );
            }
            else
            {
                AlphaMask aAlphaMask( aBitmapEx.GetSizePixel() );
                setAlpha( aBitmap, aAlphaMask, aColorFrom, nAlphaTo );
                aBitmap.Replace( aColorFrom, aColorTo, nTolerance );
                aGraphic = ::Graphic( BitmapEx( aBitmap, aAlphaMask ) );
            }
        }
    }
    ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic();
    pUnoGraphic->init( aGraphic );
    uno::Reference< graphic::XGraphic > xRet( pUnoGraphic );
    return xRet;
}

}
<|endoftext|>