<commit_before>// Copyright (c) 2011-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif

#include "askpassphrasedialog.h"
#include "ui_askpassphrasedialog.h"

#include "guiconstants.h"
#include "walletmodel.h"

#include "support/allocators/secure.h"

#include <QKeyEvent>
#include <QMessageBox>
#include <QPushButton>

AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AskPassphraseDialog),
    mode(mode),
    model(0),
    fCapsLock(false)
{
    ui->setupUi(this);

    ui->passEdit1->setMinimumSize(ui->passEdit1->sizeHint());
    ui->passEdit2->setMinimumSize(ui->passEdit2->sizeHint());
    ui->passEdit3->setMinimumSize(ui->passEdit3->sizeHint());

    ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);

    // Setup Caps Lock detection.
    ui->passEdit1->installEventFilter(this);
    ui->passEdit2->installEventFilter(this);
    ui->passEdit3->installEventFilter(this);

    switch(mode)
    {
        case Encrypt: // Ask passphrase x2
            ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of ten or more random characters, or eight or more words."));
            ui->passLabel1->hide();
            ui->passEdit1->hide();
            setWindowTitle(tr("Encrypt wallet"));
            break;
        case Unlock: // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Unlock wallet"));
            break;
        case Decrypt:   // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Decrypt wallet"));
            break;
        case ChangePass: // Ask old passphrase + new passphrase x2
            setWindowTitle(tr("Change passphrase"));
            ui->warningLabel->setText(tr("Enter the old passphrase and new passphrase to the wallet."));
            break;
    }
    textChanged();
    connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
}

AskPassphraseDialog::~AskPassphraseDialog()
{
    secureClearPassFields();
    delete ui;
}

void AskPassphraseDialog::setModel(WalletModel *model)
{
    this->model = model;
}

void AskPassphraseDialog::accept()
{
    SecureString oldpass, newpass1, newpass2;
    if(!model)
        return;
    oldpass.reserve(MAX_PASSPHRASE_SIZE);
    newpass1.reserve(MAX_PASSPHRASE_SIZE);
    newpass2.reserve(MAX_PASSPHRASE_SIZE);
    // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
    // Alternately, find a way to make this input mlock()'d to begin with.
    oldpass.assign(ui->passEdit1->text().toStdString().c_str());
    newpass1.assign(ui->passEdit2->text().toStdString().c_str());
    newpass2.assign(ui->passEdit3->text().toStdString().c_str());

    secureClearPassFields();

    switch(mode)
    {
    case Encrypt: {
        if(newpass1.empty() || newpass2.empty())
        {
            // Cannot encrypt with empty passphrase
            break;
        }
        QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"),
                 tr("Warning: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR TERRACOIN!") + "

" + tr("Are you sure you wish to encrypt your wallet?"),
                 QMessageBox::Yes|QMessageBox::Cancel,
                 QMessageBox::Cancel);
        if(retval == QMessageBox::Yes)
        {
            if(newpass1 == newpass2)
            {
                if(model->setWalletEncrypted(true, newpass1))
                {
                    QMessageBox::warning(this, tr("Wallet encrypted"),
                                         "<qt>" +
                                         tr("%1 will close now to finish the encryption process. "
                                         "Remember that encrypting your wallet cannot fully protect "
                                         "your bitcoins from being stolen by malware infecting your computer.").arg(tr(PACKAGE_NAME)) +
                                         "

" +
                                         tr("IMPORTANT: Any previous backups you have made of your wallet file "
                                         "should be replaced with the newly generated, encrypted wallet file. "
                                         "For security reasons, previous backups of the unencrypted wallet file "
                                         "will become useless as soon as you start using the new, encrypted wallet.") +
                                         "</qt>");
                    QApplication::quit();
                }
                else
                {
                    QMessageBox::critical(this, tr("Wallet encryption failed"),
                                         tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
                }
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The supplied passphrases do not match."));
            }
        }
        else
        {
            QDialog::reject(); // Cancelled
        }
        } break;
    case Unlock:
        if(!model->setWalletLocked(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet unlock failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case Decrypt:
        if(!model->setWalletEncrypted(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet decryption failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case ChangePass:
        if(newpass1 == newpass2)
        {
            if(model->changePassphrase(oldpass, newpass1))
            {
                QMessageBox::information(this, tr("Wallet encrypted"),
                                     tr("Wallet passphrase was successfully changed."));
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The passphrase entered for the wallet decryption was incorrect."));
            }
        }
        else
        {
            QMessageBox::critical(this, tr("Wallet encryption failed"),
                                 tr("The supplied passphrases do not match."));
        }
        break;
    }
}

void AskPassphraseDialog::textChanged()
{
    // Validate input, set Ok button to enabled when acceptable
    bool acceptable = false;
    switch(mode)
    {
    case Encrypt: // New passphrase x2
        acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    case Unlock: // Old passphrase x1
    case Decrypt:
        acceptable = !ui->passEdit1->text().isEmpty();
        break;
    case ChangePass: // Old passphrase x1, new passphrase x2
        acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    }
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable);
}

bool AskPassphraseDialog::event(QEvent *event)
{
    // Detect Caps Lock key press.
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        if (ke->key() == Qt::Key_CapsLock) {
            fCapsLock = !fCapsLock;
        }
        if (fCapsLock) {
            ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
        } else {
            ui->capsLabel->clear();
        }
    }
    return QWidget::event(event);
}

bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event)
{
    /* Detect Caps Lock.
     * There is no good OS-independent way to check a key state in Qt, but we
     * can detect Caps Lock by checking for the following condition:
     * Shift key is down and the result is a lower case character, or
     * Shift key is not down and the result is an upper case character.
     */
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        QString str = ke->text();
        if (str.length() != 0) {
            const QChar *psz = str.unicode();
            bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
            if ((fShift && *psz >= 'a' && *psz <= 'z') || (!fShift && *psz >= 'A' && *psz <= 'Z')) {
                fCapsLock = true;
                ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
            } else if (psz->isLetter()) {
                fCapsLock = false;
                ui->capsLabel->clear();
            }
        }
    }
    return QDialog::eventFilter(object, event);
}

static void SecureClearQLineEdit(QLineEdit* edit)
{
    // Attempt to overwrite text so that they do not linger around in memory
    edit->setText(QString(" ").repeated(edit->text().size()));
    edit->clear();
}

void AskPassphraseDialog::secureClearPassFields()
{
    SecureClearQLineEdit(ui->passEdit1);
    SecureClearQLineEdit(ui->passEdit2);
    SecureClearQLineEdit(ui->passEdit3);
}
<commit_msg>Fixed bitcoin to terracoin<commit_after>// Copyright (c) 2011-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif

#include "askpassphrasedialog.h"
#include "ui_askpassphrasedialog.h"

#include "guiconstants.h"
#include "walletmodel.h"

#include "support/allocators/secure.h"

#include <QKeyEvent>
#include <QMessageBox>
#include <QPushButton>

AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AskPassphraseDialog),
    mode(mode),
    model(0),
    fCapsLock(false)
{
    ui->setupUi(this);

    ui->passEdit1->setMinimumSize(ui->passEdit1->sizeHint());
    ui->passEdit2->setMinimumSize(ui->passEdit2->sizeHint());
    ui->passEdit3->setMinimumSize(ui->passEdit3->sizeHint());

    ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);

    // Setup Caps Lock detection.
    ui->passEdit1->installEventFilter(this);
    ui->passEdit2->installEventFilter(this);
    ui->passEdit3->installEventFilter(this);

    switch(mode)
    {
        case Encrypt: // Ask passphrase x2
            ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of ten or more random characters, or eight or more words."));
            ui->passLabel1->hide();
            ui->passEdit1->hide();
            setWindowTitle(tr("Encrypt wallet"));
            break;
        case Unlock: // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Unlock wallet"));
            break;
        case Decrypt:   // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Decrypt wallet"));
            break;
        case ChangePass: // Ask old passphrase + new passphrase x2
            setWindowTitle(tr("Change passphrase"));
            ui->warningLabel->setText(tr("Enter the old passphrase and new passphrase to the wallet."));
            break;
    }
    textChanged();
    connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
}

AskPassphraseDialog::~AskPassphraseDialog()
{
    secureClearPassFields();
    delete ui;
}

void AskPassphraseDialog::setModel(WalletModel *model)
{
    this->model = model;
}

void AskPassphraseDialog::accept()
{
    SecureString oldpass, newpass1, newpass2;
    if(!model)
        return;
    oldpass.reserve(MAX_PASSPHRASE_SIZE);
    newpass1.reserve(MAX_PASSPHRASE_SIZE);
    newpass2.reserve(MAX_PASSPHRASE_SIZE);
    // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
    // Alternately, find a way to make this input mlock()'d to begin with.
    oldpass.assign(ui->passEdit1->text().toStdString().c_str());
    newpass1.assign(ui->passEdit2->text().toStdString().c_str());
    newpass2.assign(ui->passEdit3->text().toStdString().c_str());

    secureClearPassFields();

    switch(mode)
    {
    case Encrypt: {
        if(newpass1.empty() || newpass2.empty())
        {
            // Cannot encrypt with empty passphrase
            break;
        }
        QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"),
                 tr("Warning: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR TERRACOIN!") + "

" + tr("Are you sure you wish to encrypt your wallet?"),
                 QMessageBox::Yes|QMessageBox::Cancel,
                 QMessageBox::Cancel);
        if(retval == QMessageBox::Yes)
        {
            if(newpass1 == newpass2)
            {
                if(model->setWalletEncrypted(true, newpass1))
                {
                    QMessageBox::warning(this, tr("Wallet encrypted"),
                                         "<qt>" +
                                         tr("%1 will close now to finish the encryption process. "
                                         "Remember that encrypting your wallet cannot fully protect "
                                         "your terracoins from being stolen by malware infecting your computer.").arg(tr(PACKAGE_NAME)) +
                                         "

" +
                                         tr("IMPORTANT: Any previous backups you have made of your wallet file "
                                         "should be replaced with the newly generated, encrypted wallet file. "
                                         "For security reasons, previous backups of the unencrypted wallet file "
                                         "will become useless as soon as you start using the new, encrypted wallet.") +
                                         "</qt>");
                    QApplication::quit();
                }
                else
                {
                    QMessageBox::critical(this, tr("Wallet encryption failed"),
                                         tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
                }
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The supplied passphrases do not match."));
            }
        }
        else
        {
            QDialog::reject(); // Cancelled
        }
        } break;
    case Unlock:
        if(!model->setWalletLocked(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet unlock failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case Decrypt:
        if(!model->setWalletEncrypted(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet decryption failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case ChangePass:
        if(newpass1 == newpass2)
        {
            if(model->changePassphrase(oldpass, newpass1))
            {
                QMessageBox::information(this, tr("Wallet encrypted"),
                                     tr("Wallet passphrase was successfully changed."));
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The passphrase entered for the wallet decryption was incorrect."));
            }
        }
        else
        {
            QMessageBox::critical(this, tr("Wallet encryption failed"),
                                 tr("The supplied passphrases do not match."));
        }
        break;
    }
}

void AskPassphraseDialog::textChanged()
{
    // Validate input, set Ok button to enabled when acceptable
    bool acceptable = false;
    switch(mode)
    {
    case Encrypt: // New passphrase x2
        acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    case Unlock: // Old passphrase x1
    case Decrypt:
        acceptable = !ui->passEdit1->text().isEmpty();
        break;
    case ChangePass: // Old passphrase x1, new passphrase x2
        acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    }
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable);
}

bool AskPassphraseDialog::event(QEvent *event)
{
    // Detect Caps Lock key press.
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        if (ke->key() == Qt::Key_CapsLock) {
            fCapsLock = !fCapsLock;
        }
        if (fCapsLock) {
            ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
        } else {
            ui->capsLabel->clear();
        }
    }
    return QWidget::event(event);
}

bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event)
{
    /* Detect Caps Lock.
     * There is no good OS-independent way to check a key state in Qt, but we
     * can detect Caps Lock by checking for the following condition:
     * Shift key is down and the result is a lower case character, or
     * Shift key is not down and the result is an upper case character.
     */
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        QString str = ke->text();
        if (str.length() != 0) {
            const QChar *psz = str.unicode();
            bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
            if ((fShift && *psz >= 'a' && *psz <= 'z') || (!fShift && *psz >= 'A' && *psz <= 'Z')) {
                fCapsLock = true;
                ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
            } else if (psz->isLetter()) {
                fCapsLock = false;
                ui->capsLabel->clear();
            }
        }
    }
    return QDialog::eventFilter(object, event);
}

static void SecureClearQLineEdit(QLineEdit* edit)
{
    // Attempt to overwrite text so that they do not linger around in memory
    edit->setText(QString(" ").repeated(edit->text().size()));
    edit->clear();
}

void AskPassphraseDialog::secureClearPassFields()
{
    SecureClearQLineEdit(ui->passEdit1);
    SecureClearQLineEdit(ui->passEdit2);
    SecureClearQLineEdit(ui->passEdit3);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <sstream>
#include "ladybug.h"
#include "ladybugstream.h"
#include <stdexcept>
#include <unistd.h>
#include <signal.h>

#include <ros/ros.h>
#include <sensor_msgs/image_encodings.h>
#include <sensor_msgs/Image.h>

#include <sensor_msgs/CameraInfo.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_datatypes.h>

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/imgproc/imgproc.hpp>

#include "ladybug.h"

using namespace std;

static volatile int running_ = 1;

LadybugContext m_context;
LadybugDataFormat m_dataFormat;
//camera config settings
float m_frameRate;
bool m_isFrameRateAuto;
unsigned int m_jpegQualityPercentage;

ros::Publisher pub[LADYBUG_NUM_CAMERAS + 1];

static void signalHandler(int)
{
	running_ = 0;
	ros::shutdown();
}

void parseCameraInfo(const cv::Mat  &camMat,
						const cv::Mat  &disCoeff,
						const cv::Size &imgSize,
						sensor_msgs::CameraInfo &msg)
{
	msg.header.frame_id = "camera";

	msg.height = imgSize.height;
	msg.width  = imgSize.width;

	for (int row=0; row<3; row++)
	{
		for (int col=0; col<3; col++)
		{
			msg.K[row * 3 + col] = camMat.at<double>(row, col);
		}
	}

	for (int row=0; row<3; row++)
	{
		for (int col=0; col<4; col++)
		{
			if (col == 3)
			{
				msg.P[row * 4 + col] = 0.0f;
			} else
			{
				msg.P[row * 4 + col] = camMat.at<double>(row, col);
			}
		}
	}

	for (int row=0; row<disCoeff.rows; row++)
	{
		for (int col=0; col<disCoeff.cols; col++)
		{
			msg.D.push_back(disCoeff.at<double>(row, col));
		}
	}
}

void GetMatricesFromFile(ros::NodeHandle nh, sensor_msgs::CameraInfo &camerainfo_msg)
{
	//////////////////CAMERA INFO/////////////////////////////////////////
	cv::Mat  cameraExtrinsicMat;
	cv::Mat  cameraMat;
	cv::Mat  distCoeff;
	cv::Size imageSize;
	std::string filename;

	if (nh.getParam("calibrationfile", filename) && filename!="")
	{
		ROS_INFO("Trying to parse calibrationfile :");
		ROS_INFO("> %s", filename.c_str());
	}
	else
	{
		ROS_INFO("No calibrationfile param was received");
		return;
	}

	cv::FileStorage fs(filename, cv::FileStorage::READ);
	if (!fs.isOpened())
	{
		ROS_INFO("Cannot open %s", filename.c_str());;
		return;
	}
	else
	{
		fs["CameraMat"] >> cameraMat;
		fs["DistCoeff"] >> distCoeff;
		fs["ImageSize"] >> imageSize;
	}
	parseCameraInfo(cameraMat, distCoeff, imageSize, camerainfo_msg);
}

void publishImage(cv::Mat& image, ros::Publisher& image_pub, long int& count)
{
	sensor_msgs::Image msg;
	//publish*******************
	msg.header.seq = count;
	msg.header.frame_id = "camera";
	msg.header.stamp.sec = ros::Time::now().sec; msg.header.stamp.nsec = ros::Time::now().nsec;
	msg.height = image.size().height; msg.width  = image.size().width;
	msg.encoding = "rgb8";
	msg.step = image.cols * image.elemSize();
	size_t image_size = image.rows * image.cols * image.elemSize();

	msg.data.resize(image_size);
	memcpy(msg.data.data(), image.data, image_size);

	image_pub.publish(msg);
}

LadybugError init_camera()
{
	LadybugError error;
	error = ladybugCreateContext(&m_context);
	if (error != LADYBUG_OK)
	{
		throw std::runtime_error("Unable to create Ladybug context.");
	}

	LadybugCameraInfo enumeratedCameras[16];
	unsigned int numCameras = 16;

	error = ladybugBusEnumerateCameras(m_context, enumeratedCameras, &numCameras);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	cout << "Cameras detected: " << numCameras << endl << endl;

	if (numCameras == 0)
	{
		ROS_INFO("Insufficient number of cameras detected. ");
		return LADYBUG_FAILED;
	}

	error = ladybugInitializeFromIndex(m_context, 0);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	LadybugCameraInfo camInfo;
	error = ladybugGetCameraInfo(m_context, &camInfo);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	ROS_INFO("Camera information: ");

	ROS_INFO("Base s/n: %d", camInfo.serialBase );
	ROS_INFO("Head s/n: %d", camInfo.serialHead );
	ROS_INFO("Model: %s", camInfo.pszModelName );
	ROS_INFO("Sensor: %s", camInfo.pszSensorInfo);
	ROS_INFO("Vendor: %s", camInfo.pszVendorName);
	ROS_INFO("Bus / Node: %d ,%d" , camInfo.iBusNum , camInfo.iNodeNum );

	switch (camInfo.deviceType)
	{
		case LADYBUG_DEVICE_LADYBUG3:
		{
			m_dataFormat = LADYBUG_DATAFORMAT_RAW8;
			m_frameRate = 16.0f;
			m_isFrameRateAuto = true;
			m_jpegQualityPercentage = 80;
		}
		break;

		case LADYBUG_DEVICE_LADYBUG5:
		{
			m_dataFormat = LADYBUG_DATAFORMAT_RAW8;
			m_frameRate = 10.0f;
			m_isFrameRateAuto = true;
			m_jpegQualityPercentage = 80;
		}
		break;

		default: assert(false); break;
	}

	return error;
}

LadybugError start_camera()
{
	LadybugError error;
	error = ladybugStartLockNext(m_context, m_dataFormat);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	error = ladybugSetAbsPropertyEx(m_context, LADYBUG_FRAME_RATE, false, true, m_isFrameRateAuto, m_frameRate);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	error = ladybugSetJPEGQuality(m_context, m_jpegQualityPercentage);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	// Perform a quick test to make sure images can be successfully acquired
	for (int i=0; i < 10; i++)
	{
		LadybugImage tempImage;
		error = ladybugLockNext(m_context, &tempImage);
	}

	error = ladybugUnlockAll(m_context);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	return error;
}

LadybugError stop_camera()
{
    const LadybugError cameraError = ladybugStop(m_context);
    if (cameraError != LADYBUG_OK)
    {
        ROS_INFO("Error: Unable to stop camera (%s)", ladybugErrorToString(cameraError) );
    }
    return cameraError;
}

LadybugError acquire_image( LadybugImage& image )
{
    return ladybugLockNext(m_context, &image);
}

LadybugError unlock_image( unsigned int bufferIndex )
{
    return ladybugUnlock(m_context, bufferIndex);
}

int main (int argc, char **argv)
{
	////ROS STUFF
	ros::init(argc, argv, "ladybug_camera");
	ros::NodeHandle n;
	ros::NodeHandle private_nh("~");

	signal(SIGTERM, signalHandler);//detect closing

	/////////////////////////////
	//Config camera
	m_dataFormat = LADYBUG_DATAFORMAT_RAW8;
	m_frameRate = 10;
	m_isFrameRateAuto = true;
	m_jpegQualityPercentage = 80;

	// Initialize ladybug camera
	const LadybugError grabberInitError = init_camera();
	if (LADYBUG_OK != init_camera())
	{
		ROS_INFO("Error: Failed to initialize camera (%s). Terminating...", ladybugErrorToString(grabberInitError) );
		return -1;
	}

	LadybugCameraInfo camInfo;
	if (LADYBUG_OK != ladybugGetCameraInfo(m_context, &camInfo))
	{
		ROS_INFO("Error: Failed to get camera information. Terminating...");
		return -1;
	}

	const LadybugError startError = start_camera();
	if (startError != LADYBUG_OK)
	{
		ROS_INFO("Error: Failed to start camera (%s). Terminating...", ladybugErrorToString(startError) );
		return -1;
	}
	/////////////////////
	//ROS
	// Get the camera information
	///////calibration data
	sensor_msgs::CameraInfo camerainfo_msg;
	GetMatricesFromFile(private_nh, camerainfo_msg);
	int image_scale = 100;
	if (private_nh.getParam("scale", image_scale) && image_scale>0 && image_scale<100)
	{
		ROS_INFO("Ladybug ImageScale > %i%%", image_scale);
	}
	else
	{
		ROS_INFO("Ladybug ImageScale scale must be (0,100]. Defaulting to 20 ");
		image_scale=20;
	}

	ros::Publisher camera_info_pub;

	camera_info_pub = n.advertise<sensor_msgs::CameraInfo>("/camera/camera_info", 1, true);
	ROS_INFO("Successfully started ladybug camera and stream");
	for (int i = 0; i < LADYBUG_NUM_CAMERAS + 1; i++) {
		std::string topic(std::string("image_raw"));

			topic = "camera" + std::to_string(i) + "/" + topic;

		pub[i] = n.advertise<sensor_msgs::Image>(topic, 100);
		ROS_INFO("Publishing.. %s", topic.c_str());
	}
	//////////////////

	//start camera
	ros::Rate loop_rate(10); // Hz Ladybug works at 10fps
	long int count = 0;
	while (running_ && ros::ok())
	{
		LadybugImage currentImage;

		const LadybugError acquisitionError = acquire_image(currentImage);
		if (acquisitionError != LADYBUG_OK)
		{
			ROS_INFO("Failed to acquire image. Error (%s). Trying to continue..", ladybugErrorToString(acquisitionError) );
			continue;
		}

		// convert to OpenCV Mat
		//receive Bayer Image, convert to Color 3 channels
		cv::Size size(currentImage.uiFullCols, currentImage.uiFullRows);

		cv::Mat full_size;
		for(size_t i =0;i<LADYBUG_NUM_CAMERAS; i++)
		{
			std::ostringstream out;
			out << "image" << i;
			cv::Mat rawImage(size, CV_8UC1, currentImage.pData + (i * size.width*size.height));
			cv::Mat image(size, CV_8UC3);
			cv::cvtColor(rawImage, image, cv::COLOR_BayerBG2RGB);
			cv::resize(image,image,cv::Size(size.width*image_scale/100, size.height*image_scale/100));
			//
			cv::transpose(image, image);

			if (i==0)
				image.copyTo(full_size);
			else
				cv::hconcat(image, full_size, full_size);

			unlock_image(currentImage.uiBufferIndex);

			publishImage(image, pub[LADYBUG_NUM_CAMERAS - i], count);

		}
		//publish stitched one
		publishImage(full_size, pub[0], count);
		ros::spinOnce();
		loop_rate.sleep();
		count++;
	}

	cout << "Stopping ladybug_camera..." << endl;

	// Shutdown
	stop_camera();

	ROS_INFO("ladybug_camera stopped");

	return 0;
}
<commit_msg>Fixed mirrored images on Ladybug camera (#906)<commit_after>#include <iostream>
#include <string>
#include <sstream>
#include "ladybug.h"
#include "ladybugstream.h"
#include <stdexcept>
#include <unistd.h>
#include <signal.h>

#include <ros/ros.h>
#include <sensor_msgs/image_encodings.h>
#include <sensor_msgs/Image.h>

#include <sensor_msgs/CameraInfo.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_datatypes.h>

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/imgproc/imgproc.hpp>

#include "ladybug.h"

using namespace std;

static volatile int running_ = 1;

LadybugContext m_context;
LadybugDataFormat m_dataFormat;
//camera config settings
float m_frameRate;
bool m_isFrameRateAuto;
unsigned int m_jpegQualityPercentage;

ros::Publisher pub[LADYBUG_NUM_CAMERAS + 1];

static void signalHandler(int)
{
	running_ = 0;
	ros::shutdown();
}

void parseCameraInfo(const cv::Mat  &camMat,
						const cv::Mat  &disCoeff,
						const cv::Size &imgSize,
						sensor_msgs::CameraInfo &msg)
{
	msg.header.frame_id = "camera";

	msg.height = imgSize.height;
	msg.width  = imgSize.width;

	for (int row=0; row<3; row++)
	{
		for (int col=0; col<3; col++)
		{
			msg.K[row * 3 + col] = camMat.at<double>(row, col);
		}
	}

	for (int row=0; row<3; row++)
	{
		for (int col=0; col<4; col++)
		{
			if (col == 3)
			{
				msg.P[row * 4 + col] = 0.0f;
			} else
			{
				msg.P[row * 4 + col] = camMat.at<double>(row, col);
			}
		}
	}

	for (int row=0; row<disCoeff.rows; row++)
	{
		for (int col=0; col<disCoeff.cols; col++)
		{
			msg.D.push_back(disCoeff.at<double>(row, col));
		}
	}
}

void GetMatricesFromFile(ros::NodeHandle nh, sensor_msgs::CameraInfo &camerainfo_msg)
{
	//////////////////CAMERA INFO/////////////////////////////////////////
	cv::Mat  cameraExtrinsicMat;
	cv::Mat  cameraMat;
	cv::Mat  distCoeff;
	cv::Size imageSize;
	std::string filename;

	if (nh.getParam("calibrationfile", filename) && filename!="")
	{
		ROS_INFO("Trying to parse calibrationfile :");
		ROS_INFO("> %s", filename.c_str());
	}
	else
	{
		ROS_INFO("No calibrationfile param was received");
		return;
	}

	cv::FileStorage fs(filename, cv::FileStorage::READ);
	if (!fs.isOpened())
	{
		ROS_INFO("Cannot open %s", filename.c_str());;
		return;
	}
	else
	{
		fs["CameraMat"] >> cameraMat;
		fs["DistCoeff"] >> distCoeff;
		fs["ImageSize"] >> imageSize;
	}
	parseCameraInfo(cameraMat, distCoeff, imageSize, camerainfo_msg);
}

void publishImage(cv::Mat& image, ros::Publisher& image_pub, long int& count)
{
	sensor_msgs::Image msg;
	//publish*******************
	msg.header.seq = count;
	msg.header.frame_id = "camera";
	msg.header.stamp.sec = ros::Time::now().sec; msg.header.stamp.nsec = ros::Time::now().nsec;
	msg.height = image.size().height; msg.width  = image.size().width;
	msg.encoding = "rgb8";
	msg.step = image.cols * image.elemSize();
	size_t image_size = image.rows * image.cols * image.elemSize();

	msg.data.resize(image_size);
	memcpy(msg.data.data(), image.data, image_size);

	image_pub.publish(msg);
}

LadybugError init_camera()
{
	LadybugError error;
	error = ladybugCreateContext(&m_context);
	if (error != LADYBUG_OK)
	{
		throw std::runtime_error("Unable to create Ladybug context.");
	}

	LadybugCameraInfo enumeratedCameras[16];
	unsigned int numCameras = 16;

	error = ladybugBusEnumerateCameras(m_context, enumeratedCameras, &numCameras);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	cout << "Cameras detected: " << numCameras << endl << endl;

	if (numCameras == 0)
	{
		ROS_INFO("Insufficient number of cameras detected. ");
		return LADYBUG_FAILED;
	}

	error = ladybugInitializeFromIndex(m_context, 0);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	LadybugCameraInfo camInfo;
	error = ladybugGetCameraInfo(m_context, &camInfo);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	ROS_INFO("Camera information: ");

	ROS_INFO("Base s/n: %d", camInfo.serialBase );
	ROS_INFO("Head s/n: %d", camInfo.serialHead );
	ROS_INFO("Model: %s", camInfo.pszModelName );
	ROS_INFO("Sensor: %s", camInfo.pszSensorInfo);
	ROS_INFO("Vendor: %s", camInfo.pszVendorName);
	ROS_INFO("Bus / Node: %d ,%d" , camInfo.iBusNum , camInfo.iNodeNum );

	switch (camInfo.deviceType)
	{
		case LADYBUG_DEVICE_LADYBUG3:
		{
			m_dataFormat = LADYBUG_DATAFORMAT_RAW8;
			m_frameRate = 16.0f;
			m_isFrameRateAuto = true;
			m_jpegQualityPercentage = 80;
		}
		break;

		case LADYBUG_DEVICE_LADYBUG5:
		{
			m_dataFormat = LADYBUG_DATAFORMAT_RAW8;
			m_frameRate = 10.0f;
			m_isFrameRateAuto = true;
			m_jpegQualityPercentage = 80;
		}
		break;

		default: assert(false); break;
	}

	return error;
}

LadybugError start_camera()
{
	LadybugError error;
	error = ladybugStartLockNext(m_context, m_dataFormat);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	error = ladybugSetAbsPropertyEx(m_context, LADYBUG_FRAME_RATE, false, true, m_isFrameRateAuto, m_frameRate);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	error = ladybugSetJPEGQuality(m_context, m_jpegQualityPercentage);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	// Perform a quick test to make sure images can be successfully acquired
	for (int i=0; i < 10; i++)
	{
		LadybugImage tempImage;
		error = ladybugLockNext(m_context, &tempImage);
	}

	error = ladybugUnlockAll(m_context);
	if (error != LADYBUG_OK)
	{
		return error;
	}

	return error;
}

LadybugError stop_camera()
{
    const LadybugError cameraError = ladybugStop(m_context);
    if (cameraError != LADYBUG_OK)
    {
        ROS_INFO("Error: Unable to stop camera (%s)", ladybugErrorToString(cameraError) );
    }
    return cameraError;
}

LadybugError acquire_image( LadybugImage& image )
{
    return ladybugLockNext(m_context, &image);
}

LadybugError unlock_image( unsigned int bufferIndex )
{
    return ladybugUnlock(m_context, bufferIndex);
}

int main (int argc, char **argv)
{
	////ROS STUFF
	ros::init(argc, argv, "ladybug_camera");
	ros::NodeHandle n;
	ros::NodeHandle private_nh("~");

	signal(SIGTERM, signalHandler);//detect closing

	/////////////////////////////
	//Config camera
	m_dataFormat = LADYBUG_DATAFORMAT_RAW8;
	m_frameRate = 10;
	m_isFrameRateAuto = true;
	m_jpegQualityPercentage = 80;

	// Initialize ladybug camera
	const LadybugError grabberInitError = init_camera();
	if (LADYBUG_OK != init_camera())
	{
		ROS_INFO("Error: Failed to initialize camera (%s). Terminating...", ladybugErrorToString(grabberInitError) );
		return -1;
	}

	LadybugCameraInfo camInfo;
	if (LADYBUG_OK != ladybugGetCameraInfo(m_context, &camInfo))
	{
		ROS_INFO("Error: Failed to get camera information. Terminating...");
		return -1;
	}

	const LadybugError startError = start_camera();
	if (startError != LADYBUG_OK)
	{
		ROS_INFO("Error: Failed to start camera (%s). Terminating...", ladybugErrorToString(startError) );
		return -1;
	}
	/////////////////////
	//ROS
	// Get the camera information
	///////calibration data
	sensor_msgs::CameraInfo camerainfo_msg;
	GetMatricesFromFile(private_nh, camerainfo_msg);
	int image_scale = 100;
	if (private_nh.getParam("scale", image_scale) && image_scale>0 && image_scale<100)
	{
		ROS_INFO("Ladybug ImageScale > %i%%", image_scale);
	}
	else
	{
		ROS_INFO("Ladybug ImageScale scale must be (0,100]. Defaulting to 20 ");
		image_scale=20;
	}

	ros::Publisher camera_info_pub;

	camera_info_pub = n.advertise<sensor_msgs::CameraInfo>("/camera/camera_info", 1, true);
	ROS_INFO("Successfully started ladybug camera and stream");
	for (int i = 0; i < LADYBUG_NUM_CAMERAS + 1; i++) {
		std::string topic(std::string("image_raw"));

			topic = "camera" + std::to_string(i) + "/" + topic;

		pub[i] = n.advertise<sensor_msgs::Image>(topic, 100);
		ROS_INFO("Publishing.. %s", topic.c_str());
	}
	//////////////////

	//start camera
	ros::Rate loop_rate(10); // Hz Ladybug works at 10fps
	long int count = 0;
	while (running_ && ros::ok())
	{
		LadybugImage currentImage;

		const LadybugError acquisitionError = acquire_image(currentImage);
		if (acquisitionError != LADYBUG_OK)
		{
			ROS_INFO("Failed to acquire image. Error (%s). Trying to continue..", ladybugErrorToString(acquisitionError) );
			continue;
		}

		// convert to OpenCV Mat
		//receive Bayer Image, convert to Color 3 channels
		cv::Size size(currentImage.uiFullCols, currentImage.uiFullRows);

		cv::Mat full_size;
		for(size_t i =0;i<LADYBUG_NUM_CAMERAS; i++)
		{
			std::ostringstream out;
			out << "image" << i;
			cv::Mat rawImage(size, CV_8UC1, currentImage.pData + (i * size.width*size.height));
			cv::Mat image(size, CV_8UC3);
			cv::cvtColor(rawImage, image, cv::COLOR_BayerBG2RGB);
			cv::resize(image,image,cv::Size(size.width*image_scale/100, size.height*image_scale/100));
			//
			cv::transpose(image, image);
			cv::flip(image, image, 1);

			if (i==0)
				image.copyTo(full_size);
			else
				cv::hconcat(image, full_size, full_size);

			unlock_image(currentImage.uiBufferIndex);

			publishImage(image, pub[LADYBUG_NUM_CAMERAS - i], count);

		}
		//publish stitched one
		publishImage(full_size, pub[0], count);
		ros::spinOnce();
		loop_rate.sleep();
		count++;
	}

	cout << "Stopping ladybug_camera..." << endl;

	// Shutdown
	stop_camera();

	ROS_INFO("ladybug_camera stopped");

	return 0;
}
<|endoftext|>


<commit_before>/** @file

  Implementation of the Layout class.

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 "libts.h"
#include "I_Layout.h"

static Layout *layout = NULL;

Layout *
Layout::get()
{
  if (layout == NULL) {
    ink_assert("need to call create_default_layout before accessing" "default_layout()");
  }
  return layout;
}

void
Layout::create(const char *prefix)
{
  if (layout == NULL) {
    layout = NEW(new Layout(prefix));
  }
}

static char *
layout_relative(const char *root, const char *file)
{
  char path[PATH_NAME_MAX];

  if (ink_filepath_merge(path, PATH_NAME_MAX, root, file, INK_FILEPATH_TRUENAME)) {
    int err = errno;
    // Log error
    if (err == EACCES) {
      ink_error("Cannot merge path '%s' above the root '%s'\n", file, root);
    } else if (err == E2BIG) {
      ink_error("Excedding file name length limit of %d characters\n", PATH_NAME_MAX);
    }
    else {
      // TODO: Make some pretty errors.
      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, root, err);
    }
    return NULL;
  }
  return ats_strdup(path);
}

char *
Layout::relative(const char *file)
{
  return layout_relative(prefix, file);
}

void
Layout::relative(char *buf, size_t bufsz, const char *file)
{
  char path[PATH_NAME_MAX];

  if (ink_filepath_merge(path, PATH_NAME_MAX, prefix, file,
      INK_FILEPATH_TRUENAME)) {
    int err = errno;
    // Log error
    if (err == EACCES) {
      ink_error("Cannot merge path '%s' above the root '%s'\n", file, prefix);
    } else if (err == E2BIG) {
      ink_error("Excedding file name length limit of %d characters\n", PATH_NAME_MAX);
    }
    else {
      // TODO: Make some pretty errors.
      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, prefix, err);
    }
    return;
  }
  size_t path_len = strlen(path) + 1;
  if (path_len > bufsz) {
    ink_error("Provided buffer is too small: %d, required %d\n", bufsz, path_len);
  }
  else {
    ink_strlcpy(buf, path, bufsz);
  }
}

char *
Layout::relative_to(const char *dir, const char *file)
{
  return layout_relative(dir, file);
}

void
Layout::relative_to(char *buf, size_t bufsz, const char *dir, const char *file)
{
  char path[PATH_NAME_MAX];

  if (ink_filepath_merge(path, PATH_NAME_MAX, dir, file, INK_FILEPATH_TRUENAME)) {
    int err = errno;
    // Log error
    if (err == EACCES) {
      ink_error("Cannot merge path '%s' above the root '%s'\n", file, dir);
    } else if (err == E2BIG) {
      ink_error("Excedding file name length limit of %d characters\n", PATH_NAME_MAX);
    }
    else {
      // TODO: Make some pretty errors.
      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, dir, err);
    }
    return;
  }
  size_t path_len = strlen(path) + 1;
  if (path_len > bufsz) {
    ink_error("Provided buffer is too small: %d, required %d\n", bufsz, path_len);
  }
  else {
    ink_strlcpy(buf, path, bufsz);
  }
}

Layout::Layout(const char *_prefix)
{
  if (_prefix) {
    prefix = ats_strdup(_prefix);
  } else {
    char *env_path;
    char path[PATH_NAME_MAX];
    int  len;

    if ((env_path = getenv("TS_ROOT"))) {
      len = strlen(env_path);
      if ((len + 1) > PATH_NAME_MAX) {
        ink_error("TS_ROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX -1);
        return;
      }
      ink_strlcpy(path, env_path, sizeof(path));
      while (len > 1 && path[len - 1] == '/') {
        path[len - 1] = '\0';
        --len;
      }
    } else {
        // Use compile time --prefix
      ink_strlcpy(path, TS_BUILD_PREFIX, sizeof(path));
    }

    if (access(path, R_OK) == -1) {
      ink_error("unable to access() TS_ROOT '%s': %d, %s\n", path, errno, strerror(errno));
      return;
    }
    prefix = ats_strdup(path);
  }
  exec_prefix = layout_relative(prefix, TS_BUILD_EXEC_PREFIX);
  bindir = layout_relative(prefix, TS_BUILD_BINDIR);
  sbindir = layout_relative(prefix, TS_BUILD_SBINDIR);
  sysconfdir = layout_relative(prefix, TS_BUILD_SYSCONFDIR);
  datadir = layout_relative(prefix, TS_BUILD_DATADIR);
  includedir = layout_relative(prefix, TS_BUILD_INCLUDEDIR);
  libdir = layout_relative(prefix, TS_BUILD_LIBDIR);
  libexecdir = layout_relative(prefix, TS_BUILD_LIBEXECDIR);
  localstatedir = layout_relative(prefix, TS_BUILD_LOCALSTATEDIR);
  runtimedir = layout_relative(prefix, TS_BUILD_RUNTIMEDIR);
  logdir = layout_relative(prefix, TS_BUILD_LOGDIR);
  mandir = layout_relative(prefix, TS_BUILD_MANDIR);
  infodir = layout_relative(prefix, TS_BUILD_INFODIR);
  cachedir = layout_relative(prefix, TS_BUILD_CACHEDIR);

#ifdef DEBUG
// TODO: Use a propper Debug logging
//
#define PrintSTR(var) \
  fprintf(stdout, "%18s = '%s'\n", "--" #var, (var == NULL? "NULL" : var));

  fprintf(stdout, "Layout configuration\n");
  PrintSTR(prefix);
  PrintSTR(exec_prefix);
  PrintSTR(bindir);
  PrintSTR(sbindir);
  PrintSTR(sysconfdir);
  PrintSTR(datadir);
  PrintSTR(includedir);
  PrintSTR(libdir);
  PrintSTR(libexecdir);
  PrintSTR(localstatedir);
  PrintSTR(runtimedir);
  PrintSTR(logdir);
  PrintSTR(mandir);
  PrintSTR(infodir);
  PrintSTR(cachedir);
#endif

}

Layout::~Layout()
{
  ats_free(prefix);
  ats_free(exec_prefix);
  ats_free(bindir);
  ats_free(sbindir);
  ats_free(sysconfdir);
  ats_free(datadir);
  ats_free(includedir);
  ats_free(libdir);
  ats_free(libexecdir);
  ats_free(localstatedir);
  ats_free(runtimedir);
  ats_free(logdir);
  ats_free(mandir);
  ats_free(infodir);
  ats_free(cachedir);
}

<commit_msg>Fix typos, no code change<commit_after>/** @file

  Implementation of the Layout class.

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 "libts.h"
#include "I_Layout.h"

static Layout *layout = NULL;

Layout *
Layout::get()
{
  if (layout == NULL) {
    ink_assert("need to call create_default_layout before accessing" "default_layout()");
  }
  return layout;
}

void
Layout::create(const char *prefix)
{
  if (layout == NULL) {
    layout = NEW(new Layout(prefix));
  }
}

static char *
layout_relative(const char *root, const char *file)
{
  char path[PATH_NAME_MAX];

  if (ink_filepath_merge(path, PATH_NAME_MAX, root, file, INK_FILEPATH_TRUENAME)) {
    int err = errno;
    // Log error
    if (err == EACCES) {
      ink_error("Cannot merge path '%s' above the root '%s'\n", file, root);
    } else if (err == E2BIG) {
      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
    }
    else {
      // TODO: Make some pretty errors.
      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, root, err);
    }
    return NULL;
  }
  return ats_strdup(path);
}

char *
Layout::relative(const char *file)
{
  return layout_relative(prefix, file);
}

void
Layout::relative(char *buf, size_t bufsz, const char *file)
{
  char path[PATH_NAME_MAX];

  if (ink_filepath_merge(path, PATH_NAME_MAX, prefix, file,
      INK_FILEPATH_TRUENAME)) {
    int err = errno;
    // Log error
    if (err == EACCES) {
      ink_error("Cannot merge path '%s' above the root '%s'\n", file, prefix);
    } else if (err == E2BIG) {
      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
    }
    else {
      // TODO: Make some pretty errors.
      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, prefix, err);
    }
    return;
  }
  size_t path_len = strlen(path) + 1;
  if (path_len > bufsz) {
    ink_error("Provided buffer is too small: %d, required %d\n", bufsz, path_len);
  }
  else {
    ink_strlcpy(buf, path, bufsz);
  }
}

char *
Layout::relative_to(const char *dir, const char *file)
{
  return layout_relative(dir, file);
}

void
Layout::relative_to(char *buf, size_t bufsz, const char *dir, const char *file)
{
  char path[PATH_NAME_MAX];

  if (ink_filepath_merge(path, PATH_NAME_MAX, dir, file, INK_FILEPATH_TRUENAME)) {
    int err = errno;
    // Log error
    if (err == EACCES) {
      ink_error("Cannot merge path '%s' above the root '%s'\n", file, dir);
    } else if (err == E2BIG) {
      ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
    }
    else {
      // TODO: Make some pretty errors.
      ink_error("Cannot merge '%s' with '%s' error=%d\n", file, dir, err);
    }
    return;
  }
  size_t path_len = strlen(path) + 1;
  if (path_len > bufsz) {
    ink_error("Provided buffer is too small: %d, required %d\n", bufsz, path_len);
  }
  else {
    ink_strlcpy(buf, path, bufsz);
  }
}

Layout::Layout(const char *_prefix)
{
  if (_prefix) {
    prefix = ats_strdup(_prefix);
  } else {
    char *env_path;
    char path[PATH_NAME_MAX];
    int  len;

    if ((env_path = getenv("TS_ROOT"))) {
      len = strlen(env_path);
      if ((len + 1) > PATH_NAME_MAX) {
        ink_error("TS_ROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX -1);
        return;
      }
      ink_strlcpy(path, env_path, sizeof(path));
      while (len > 1 && path[len - 1] == '/') {
        path[len - 1] = '\0';
        --len;
      }
    } else {
        // Use compile time --prefix
      ink_strlcpy(path, TS_BUILD_PREFIX, sizeof(path));
    }

    if (access(path, R_OK) == -1) {
      ink_error("unable to access() TS_ROOT '%s': %d, %s\n", path, errno, strerror(errno));
      return;
    }
    prefix = ats_strdup(path);
  }
  exec_prefix = layout_relative(prefix, TS_BUILD_EXEC_PREFIX);
  bindir = layout_relative(prefix, TS_BUILD_BINDIR);
  sbindir = layout_relative(prefix, TS_BUILD_SBINDIR);
  sysconfdir = layout_relative(prefix, TS_BUILD_SYSCONFDIR);
  datadir = layout_relative(prefix, TS_BUILD_DATADIR);
  includedir = layout_relative(prefix, TS_BUILD_INCLUDEDIR);
  libdir = layout_relative(prefix, TS_BUILD_LIBDIR);
  libexecdir = layout_relative(prefix, TS_BUILD_LIBEXECDIR);
  localstatedir = layout_relative(prefix, TS_BUILD_LOCALSTATEDIR);
  runtimedir = layout_relative(prefix, TS_BUILD_RUNTIMEDIR);
  logdir = layout_relative(prefix, TS_BUILD_LOGDIR);
  mandir = layout_relative(prefix, TS_BUILD_MANDIR);
  infodir = layout_relative(prefix, TS_BUILD_INFODIR);
  cachedir = layout_relative(prefix, TS_BUILD_CACHEDIR);

#ifdef DEBUG
// TODO: Use a propper Debug logging
//
#define PrintSTR(var) \
  fprintf(stdout, "%18s = '%s'\n", "--" #var, (var == NULL? "NULL" : var));

  fprintf(stdout, "Layout configuration\n");
  PrintSTR(prefix);
  PrintSTR(exec_prefix);
  PrintSTR(bindir);
  PrintSTR(sbindir);
  PrintSTR(sysconfdir);
  PrintSTR(datadir);
  PrintSTR(includedir);
  PrintSTR(libdir);
  PrintSTR(libexecdir);
  PrintSTR(localstatedir);
  PrintSTR(runtimedir);
  PrintSTR(logdir);
  PrintSTR(mandir);
  PrintSTR(infodir);
  PrintSTR(cachedir);
#endif

}

Layout::~Layout()
{
  ats_free(prefix);
  ats_free(exec_prefix);
  ats_free(bindir);
  ats_free(sbindir);
  ats_free(sysconfdir);
  ats_free(datadir);
  ats_free(includedir);
  ats_free(libdir);
  ats_free(libexecdir);
  ats_free(localstatedir);
  ats_free(runtimedir);
  ats_free(logdir);
  ats_free(mandir);
  ats_free(infodir);
  ats_free(cachedir);
}

<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// File Stdexpansion.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Definition of methods in class StdExpansion which is
// the base class to all expansion shapes
//
///////////////////////////////////////////////////////////////////////////////

#include <StdRegions/StdExpansion.h>

namespace Nektar
{
    namespace StdRegions
    {

        /** define list of number of vertices corresponding to each ShapeType */
        const int g_shapenverts[SIZE_ShapeType] = {0,2,3,4,4,5,6,8};

        /** define list of number of edges corresponding to each ShapeType */
        const int g_shapenedges[SIZE_ShapeType] = {0,1,3,4,6,8,9,12};

        /** define list of number of faces corresponding to each ShapeType */
        const int g_shapenfaces[SIZE_ShapeType] = {0,0,0,0,4,5,5,6};

        StdExpansion::StdExpansion(void):
        m_numbases(0),
            m_ncoeffs(0)
        {
        }

        StdExpansion::StdExpansion(int numbases,
				   const LibUtilities::BasisKey &Ba,
				   const LibUtilities::BasisKey &Bb,
				   const LibUtilities::BasisKey &Bc,
				   int numcoeffs):
	    m_numbases(numbases)
	{
	    m_base = MemoryManager::AllocateArray<LibUtilities::BasisSharedPtr>(m_numbases);

            switch(m_numbases)
            {
            case 3:
                ASSERTL2(Bc==LibUtilities::NullBasisKey,
			 "NULL Basis attempting to be used.");
                m_base[2] = LibUtilities::BasisManager()[Bc];

            case 2:
                ASSERTL2(Bb==LibUtilities::NullBasisKey,
			 "NULL Basis attempting to be used.");

                m_base[1] = LibUtilities::BasisManager()[Bb];
            case 1:
                ASSERTL2(Ba==LibUtilities::NullBasisKey,
			 "NULL Basis attempting to be used.");
                m_base[0] = LibUtilities::BasisManager()[Ba];
                break;
            default:
                ASSERTL0(false, "numbases incorrectly specified");
            };

            //allocate memory for coeffs
            m_ncoeffs = numcoeffs;
            m_coeffs = MemoryManager::AllocateSharedArray<double>(m_ncoeffs);
            Vmath::Zero(m_ncoeffs,&m_coeffs[0],1);

            //allocate memory for phys
            m_phys = MemoryManager::AllocateSharedArray<double>(GetTotPoints());

	    //allocate memory for phys
	    m_phys = MemoryManager::AllocateSharedArray<double>(GetTotPoints());
        } //end constructor

        StdExpansion::StdExpansion(const StdExpansion &T):
        m_numbases(T.m_numbases)
        {
            int i,j;

            m_base = MemoryManager::AllocateArray<LibUtilities::BasisSharedPtr>(m_numbases);

            for(j=0; j<m_numbases; j++)
            {
                m_base[j] = T.m_base[j];
            }

            // NOTE: Copy Constructor produces a deep copy
            // allocate memory for coeffs
            // need to check allocation for variable order.
            m_ncoeffs = T.m_ncoeffs;
            m_coeffs = MemoryManager::AllocateSharedArray<double>(m_ncoeffs);
            for(i=0; i<m_ncoeffs; i++)
            {
                m_coeffs[i] = T.m_coeffs[i];
            }

            //allocate memory for phys
            int numphys = GetTotPoints();
            m_phys = MemoryManager::AllocateSharedArray<double>(GetTotPoints());
            for(j=0; j < numphys; j++)
            {
                m_phys[j] = T.m_phys[j];
            }
        }

        StdExpansion::~StdExpansion()
        {
        }

        double StdExpansion::Linf(const double *sol)
        {
            int     ntot;
            double  val;
            double *tmp;
            BstShrDArray  wsp;

            ntot =  GetTotPoints();

            wsp = GetDoubleTmpSpace(ntot);
            tmp = wsp.get();

            Vmath::Vsub(ntot,sol,1,&m_phys[0],1,tmp,1);
            Vmath::Vabs(ntot,tmp,1,tmp,1);
            val = Vmath::Vamax(ntot,tmp,1);

            return  val;
        }

        double StdExpansion::Linf()
        {
            return Vmath::Vamax(GetTotPoints(),&m_phys[0],1);
        }

        double StdExpansion::L2(const double *sol)
        {
            int     ntot = GetTotPoints();
            double  val;
            double *tmp;
            BstShrDArray wsp;

            wsp = GetDoubleTmpSpace(ntot);
            tmp = wsp.get();

            Vmath::Vsub(ntot, sol, 1, &m_phys[0], 1, tmp, 1);
            Vmath::Vmul(ntot, tmp, 1, tmp, 1, tmp, 1);

            val = sqrt(v_Integral(tmp));

            return val;
        }

        double StdExpansion::L2()
        {
            int     ntot = GetTotPoints();
            double  val;
            double *tmp;
            BstShrDArray wsp;

            wsp = GetDoubleTmpSpace(ntot);
            tmp = wsp.get();

            Vmath::Vmul(ntot, &m_phys[0], 1, &m_phys[0], 1, tmp, 1);
            val   = sqrt(v_Integral(tmp));

            return val;
        }

        DNekMatSharedPtr StdExpansion::GenerateMassMatrix()
        {
            int     i;
            BstShrDArray store = GetDoubleTmpSpace(m_ncoeffs);
            BstShrDArray tmp   = GetDoubleTmpSpace(GetTotPoints());

            DNekMatSharedPtr  Mat;

            Mat = MemoryManager::AllocateSharedPtr<DNekMat>(m_ncoeffs,m_ncoeffs);

            Blas::Dcopy(m_ncoeffs,&m_coeffs[0],1,&store[0],1);
            for(i=0; i<m_ncoeffs; ++i)
            {
                v_FillMode(i, &tmp[0]);
                v_IProductWRTBase(&tmp[0], &((*Mat).GetPtr())[0]+i*m_ncoeffs);
            }
            Blas::Dcopy(m_ncoeffs,&store[0],1,&m_coeffs[0],1);

            return Mat;
        }

        // 2D Interpolation
        void StdExpansion::Interp2D(const  LibUtilities::BasisKey *fbasis0,
            const LibUtilities::BasisKey *fbasis1, const double *from,
            const LibUtilities::BasisKey *tbasis0,
            const LibUtilities::BasisKey* tbasis1, double *to)
        {
            DNekMatSharedPtr I0,I1;
            double *tmp;
            BstShrDArray wsp = GetDoubleTmpSpace(tbasis1->GetNumPoints()*
                fbasis0->GetNumPoints());
            tmp = wsp.get();

            I0 = LibUtilities::PointsManager()[fbasis0->GetPointsKey()]
            ->GetI(tbasis0->GetPointsKey());
            I1 = LibUtilities::PointsManager()[fbasis1->GetPointsKey()]
            ->GetI(tbasis1->GetPointsKey());

            Blas::Dgemm('T', 'T', tbasis1->GetNumPoints(), fbasis0->GetNumPoints(),
                fbasis1->GetNumPoints(), 1.0, &((*I1).GetPtr())[0],
                fbasis1->GetNumPoints(),
                (double *) from,fbasis0->GetNumPoints(), 0.0, tmp,
                tbasis1->GetNumPoints());

            Blas::Dgemm('T', 'T',tbasis0->GetNumPoints(),tbasis1->GetNumPoints(),
                fbasis0->GetNumPoints(),1.0,&((*I0).GetPtr())[0],
                fbasis0->GetNumPoints(),tmp, tbasis1->GetNumPoints(),
                0.0,to, tbasis0->GetNumPoints());
        }

        // 1D Interpolation
        void StdExpansion::Interp1D(const  LibUtilities::BasisKey *fbasis0, const double *from,
            const LibUtilities::BasisKey *tbasis0, double *to)
        {
            DNekMatSharedPtr I0;

            I0 = LibUtilities::PointsManager()[fbasis0->GetPointsKey()]
            ->GetI(tbasis0->GetPointsKey());

            Blas::Dgemv('T', fbasis0->GetNumPoints(), tbasis0->GetNumPoints(),
                1.0, &((*I0).GetPtr())[0], fbasis0->GetNumPoints(),
                from, 1, 0.0, to, 1);
        }

        //   I/O routine
        void StdExpansion::WriteCoeffsToFile(std::ofstream &outfile)
        {
            int i;
            for(i=0; i<m_ncoeffs; ++i)
            {
                outfile << m_coeffs[i] << std::endl;
            }
        }

    }//end namespace
}//end namespace

/**
* $Log: StdExpansion.cpp,v $
* Revision 1.13  2007/02/07 12:51:52  sherwin
* Compiling version of Project1D
*
* Revision 1.12  2007/02/06 02:23:28  jfrazier
* Minor cleanup.
*
* Revision 1.11  2007/01/30 20:01:35  sherwin
* Update for first compiling Project1D routine
*
* Revision 1.10  2007/01/29 15:04:53  sherwin
* StdBasis.h moved to LibUtilities. Other minor mods
*
* Revision 1.9  2007/01/28 18:34:18  sherwin
* More modifications to make Demo Project1D compile
*
* Revision 1.8  2007/01/23 23:20:20  sherwin
* New version after Jan 07 update
*
* Revision 1.7  2007/01/20 22:35:20  sherwin
* Version with StdExpansion compiling
*
* Revision 1.6  2007/01/15 11:08:37  pvos
* Updating doxygen documentation
*
* Revision 1.5  2006/12/10 19:00:54  sherwin
* Modifications to handle nodal expansions
*
* Revision 1.4  2006/08/05 19:03:48  sherwin
* Update to make the multiregions 2D expansion in connected regions work
*
* Revision 1.3  2006/06/01 14:46:16  kirby
* *** empty log message ***
*
* Revision 1.2  2006/05/29 19:03:08  sherwin
* Modifications to wrap geometric information in shared_ptr
*
* Revision 1.1  2006/05/04 18:58:31  kirby
* *** empty log message ***
*
* Revision 1.54  2006/04/25 20:23:33  jfrazier
* Various fixes to correct bugs, calls to ASSERT, etc.
*
* Revision 1.53  2006/04/01 21:59:26  sherwin
* Sorted new definition of ASSERT
*
* Revision 1.52  2006/03/21 09:21:31  sherwin
* Introduced NekMemoryManager
*
* Revision 1.51  2006/03/12 14:20:44  sherwin
*
* First compiling version of SpatialDomains and associated modifications
*
* Revision 1.50  2006/03/06 12:39:59  sherwin
*
* Added NekConstants class for all constants in this library
*
* Revision 1.49  2006/03/05 22:11:02  sherwin
*
* Sorted out Project1D, Project2D and Project_Diff2D as well as some test scripts
*
* Revision 1.48  2006/03/03 23:04:54  sherwin
*
* Corrected Mistake in StdBasis.cpp to do with eModified_B
*
* Revision 1.47  2006/03/02 16:20:20  sherwin
*
* Introduced method GetPointsTot
*
* Revision 1.46  2006/03/01 08:25:03  sherwin
*
* First compiling version of StdRegions
*
* Revision 1.45  2006/02/26 23:37:29  sherwin
*
* Updates and compiling checks upto StdExpansions1D
*
* Revision 1.44  2006/02/26 21:23:20  bnelson
* Fixed a variety of compiler errors caused by updates to the coding standard.
*
* Revision 1.43  2006/02/15 08:06:36  sherwin
*
* Put files into coding standard (although they do not compile)
*
* Revision 1.42  2006/02/12 21:51:42  sherwin
*
* Added licence
*
* Revision 1.41  2006/02/10 16:44:10  sherwin
*
* Updated to comply with coding standard
*
**/
<commit_msg>Corrected an error in the code<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// File Stdexpansion.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Definition of methods in class StdExpansion which is
// the base class to all expansion shapes
//
///////////////////////////////////////////////////////////////////////////////

#include <StdRegions/StdExpansion.h>

namespace Nektar
{
    namespace StdRegions
    {

        /** define list of number of vertices corresponding to each ShapeType */
        const int g_shapenverts[SIZE_ShapeType] = {0,2,3,4,4,5,6,8};

        /** define list of number of edges corresponding to each ShapeType */
        const int g_shapenedges[SIZE_ShapeType] = {0,1,3,4,6,8,9,12};

        /** define list of number of faces corresponding to each ShapeType */
        const int g_shapenfaces[SIZE_ShapeType] = {0,0,0,0,4,5,5,6};

        StdExpansion::StdExpansion(void):
        m_numbases(0),
            m_ncoeffs(0)
        {
        }

        StdExpansion::StdExpansion(int numbases,
				   const LibUtilities::BasisKey &Ba,
				   const LibUtilities::BasisKey &Bb,
				   const LibUtilities::BasisKey &Bc,
				   int numcoeffs):
	    m_numbases(numbases)
	{
	    m_base = MemoryManager::AllocateArray<LibUtilities::BasisSharedPtr>(m_numbases);

            switch(m_numbases)
            {
            case 3:
                ASSERTL2(Bc==LibUtilities::NullBasisKey,
			 "NULL Basis attempting to be used.");
                m_base[2] = LibUtilities::BasisManager()[Bc];

            case 2:
                ASSERTL2(Bb==LibUtilities::NullBasisKey,
			 "NULL Basis attempting to be used.");

                m_base[1] = LibUtilities::BasisManager()[Bb];
            case 1:
                ASSERTL2(Ba==LibUtilities::NullBasisKey,
			 "NULL Basis attempting to be used.");
                m_base[0] = LibUtilities::BasisManager()[Ba];
                break;
            default:
                ASSERTL0(false, "numbases incorrectly specified");
            };

            //allocate memory for coeffs
            m_ncoeffs = numcoeffs;
            m_coeffs = MemoryManager::AllocateSharedArray<double>(m_ncoeffs);
            Vmath::Zero(m_ncoeffs,&m_coeffs[0],1);

	    //allocate memory for phys
	    m_phys = MemoryManager::AllocateSharedArray<double>(GetTotPoints());
        } //end constructor

        StdExpansion::StdExpansion(const StdExpansion &T):
        m_numbases(T.m_numbases)
        {
            int i,j;

            m_base = MemoryManager::AllocateArray<LibUtilities::BasisSharedPtr>(m_numbases);

            for(j=0; j<m_numbases; j++)
            {
                m_base[j] = T.m_base[j];
            }

            // NOTE: Copy Constructor produces a deep copy
            // allocate memory for coeffs
            // need to check allocation for variable order.
            m_ncoeffs = T.m_ncoeffs;
            m_coeffs = MemoryManager::AllocateSharedArray<double>(m_ncoeffs);
            for(i=0; i<m_ncoeffs; i++)
            {
                m_coeffs[i] = T.m_coeffs[i];
            }

            //allocate memory for phys
            int numphys = GetTotPoints();
            m_phys = MemoryManager::AllocateSharedArray<double>(GetTotPoints());
            for(j=0; j < numphys; j++)
            {
                m_phys[j] = T.m_phys[j];
            }
        }

        StdExpansion::~StdExpansion()
        {
        }

        double StdExpansion::Linf(const double *sol)
        {
            int     ntot;
            double  val;
            double *tmp;
            BstShrDArray  wsp;

            ntot =  GetTotPoints();

            wsp = GetDoubleTmpSpace(ntot);
            tmp = wsp.get();

            Vmath::Vsub(ntot,sol,1,&m_phys[0],1,tmp,1);
            Vmath::Vabs(ntot,tmp,1,tmp,1);
            val = Vmath::Vamax(ntot,tmp,1);

            return  val;
        }

        double StdExpansion::Linf()
        {
            return Vmath::Vamax(GetTotPoints(),&m_phys[0],1);
        }

        double StdExpansion::L2(const double *sol)
        {
            int     ntot = GetTotPoints();
            double  val;
            double *tmp;
            BstShrDArray wsp;

            wsp = GetDoubleTmpSpace(ntot);
            tmp = wsp.get();

            Vmath::Vsub(ntot, sol, 1, &m_phys[0], 1, tmp, 1);
            Vmath::Vmul(ntot, tmp, 1, tmp, 1, tmp, 1);

            val = sqrt(v_Integral(tmp));

            return val;
        }

        double StdExpansion::L2()
        {
            int     ntot = GetTotPoints();
            double  val;
            double *tmp;
            BstShrDArray wsp;

            wsp = GetDoubleTmpSpace(ntot);
            tmp = wsp.get();

            Vmath::Vmul(ntot, &m_phys[0], 1, &m_phys[0], 1, tmp, 1);
            val   = sqrt(v_Integral(tmp));

            return val;
        }

        DNekMatSharedPtr StdExpansion::GenerateMassMatrix()
        {
            int     i;
            BstShrDArray store = GetDoubleTmpSpace(m_ncoeffs);
            BstShrDArray tmp   = GetDoubleTmpSpace(GetTotPoints());

            DNekMatSharedPtr  Mat;

            Mat = MemoryManager::AllocateSharedPtr<DNekMat>(m_ncoeffs,m_ncoeffs);

            Blas::Dcopy(m_ncoeffs,&m_coeffs[0],1,&store[0],1);
            for(i=0; i<m_ncoeffs; ++i)
            {
                v_FillMode(i, &tmp[0]);
                v_IProductWRTBase(&tmp[0], &((*Mat).GetPtr())[0]+i*m_ncoeffs);
            }
            Blas::Dcopy(m_ncoeffs,&store[0],1,&m_coeffs[0],1);

            return Mat;
        }

        // 2D Interpolation
        void StdExpansion::Interp2D(const  LibUtilities::BasisKey *fbasis0,
            const LibUtilities::BasisKey *fbasis1, const double *from,
            const LibUtilities::BasisKey *tbasis0,
            const LibUtilities::BasisKey* tbasis1, double *to)
        {
            DNekMatSharedPtr I0,I1;
            double *tmp;
            BstShrDArray wsp = GetDoubleTmpSpace(tbasis1->GetNumPoints()*
                fbasis0->GetNumPoints());
            tmp = wsp.get();

            I0 = LibUtilities::PointsManager()[fbasis0->GetPointsKey()]
            ->GetI(tbasis0->GetPointsKey());
            I1 = LibUtilities::PointsManager()[fbasis1->GetPointsKey()]
            ->GetI(tbasis1->GetPointsKey());

            Blas::Dgemm('T', 'T', tbasis1->GetNumPoints(), fbasis0->GetNumPoints(),
                fbasis1->GetNumPoints(), 1.0, &((*I1).GetPtr())[0],
                fbasis1->GetNumPoints(),
                (double *) from,fbasis0->GetNumPoints(), 0.0, tmp,
                tbasis1->GetNumPoints());

            Blas::Dgemm('T', 'T',tbasis0->GetNumPoints(),tbasis1->GetNumPoints(),
                fbasis0->GetNumPoints(),1.0,&((*I0).GetPtr())[0],
                fbasis0->GetNumPoints(),tmp, tbasis1->GetNumPoints(),
                0.0,to, tbasis0->GetNumPoints());
        }

        // 1D Interpolation
        void StdExpansion::Interp1D(const  LibUtilities::BasisKey *fbasis0, const double *from,
            const LibUtilities::BasisKey *tbasis0, double *to)
        {
            DNekMatSharedPtr I0;

            I0 = LibUtilities::PointsManager()[fbasis0->GetPointsKey()]
            ->GetI(tbasis0->GetPointsKey());

            Blas::Dgemv('T', fbasis0->GetNumPoints(), tbasis0->GetNumPoints(),
                1.0, &((*I0).GetPtr())[0], fbasis0->GetNumPoints(),
                from, 1, 0.0, to, 1);
        }

        //   I/O routine
        void StdExpansion::WriteCoeffsToFile(std::ofstream &outfile)
        {
            int i;
            for(i=0; i<m_ncoeffs; ++i)
            {
                outfile << m_coeffs[i] << std::endl;
            }
        }

    }//end namespace
}//end namespace

/**
* $Log: StdExpansion.cpp,v $
* Revision 1.14  2007/02/13 09:52:27  sherwin
* Updates to fix mass matrix inverse issues
*
* Revision 1.13  2007/02/07 12:51:52  sherwin
* Compiling version of Project1D
*
* Revision 1.12  2007/02/06 02:23:28  jfrazier
* Minor cleanup.
*
* Revision 1.11  2007/01/30 20:01:35  sherwin
* Update for first compiling Project1D routine
*
* Revision 1.10  2007/01/29 15:04:53  sherwin
* StdBasis.h moved to LibUtilities. Other minor mods
*
* Revision 1.9  2007/01/28 18:34:18  sherwin
* More modifications to make Demo Project1D compile
*
* Revision 1.8  2007/01/23 23:20:20  sherwin
* New version after Jan 07 update
*
* Revision 1.7  2007/01/20 22:35:20  sherwin
* Version with StdExpansion compiling
*
* Revision 1.6  2007/01/15 11:08:37  pvos
* Updating doxygen documentation
*
* Revision 1.5  2006/12/10 19:00:54  sherwin
* Modifications to handle nodal expansions
*
* Revision 1.4  2006/08/05 19:03:48  sherwin
* Update to make the multiregions 2D expansion in connected regions work
*
* Revision 1.3  2006/06/01 14:46:16  kirby
* *** empty log message ***
*
* Revision 1.2  2006/05/29 19:03:08  sherwin
* Modifications to wrap geometric information in shared_ptr
*
* Revision 1.1  2006/05/04 18:58:31  kirby
* *** empty log message ***
*
* Revision 1.54  2006/04/25 20:23:33  jfrazier
* Various fixes to correct bugs, calls to ASSERT, etc.
*
* Revision 1.53  2006/04/01 21:59:26  sherwin
* Sorted new definition of ASSERT
*
* Revision 1.52  2006/03/21 09:21:31  sherwin
* Introduced NekMemoryManager
*
* Revision 1.51  2006/03/12 14:20:44  sherwin
*
* First compiling version of SpatialDomains and associated modifications
*
* Revision 1.50  2006/03/06 12:39:59  sherwin
*
* Added NekConstants class for all constants in this library
*
* Revision 1.49  2006/03/05 22:11:02  sherwin
*
* Sorted out Project1D, Project2D and Project_Diff2D as well as some test scripts
*
* Revision 1.48  2006/03/03 23:04:54  sherwin
*
* Corrected Mistake in StdBasis.cpp to do with eModified_B
*
* Revision 1.47  2006/03/02 16:20:20  sherwin
*
* Introduced method GetPointsTot
*
* Revision 1.46  2006/03/01 08:25:03  sherwin
*
* First compiling version of StdRegions
*
* Revision 1.45  2006/02/26 23:37:29  sherwin
*
* Updates and compiling checks upto StdExpansions1D
*
* Revision 1.44  2006/02/26 21:23:20  bnelson
* Fixed a variety of compiler errors caused by updates to the coding standard.
*
* Revision 1.43  2006/02/15 08:06:36  sherwin
*
* Put files into coding standard (although they do not compile)
*
* Revision 1.42  2006/02/12 21:51:42  sherwin
*
* Added licence
*
* Revision 1.41  2006/02/10 16:44:10  sherwin
*
* Updated to comply with coding standard
*
**/
<|endoftext|>


<commit_before>#include <QMessageBox>
#include <iostream>
#include <QByteArray>
#include "ltr_gui.h"
#include "webcam_ft_prefs.h"
#include "wc_driver_prefs.h"
#include "webcam_info.h"
#include "ltr_gui_prefs.h"

static QString currentId = QString("None");
static QString currentSection = QString();

void WebcamFtPrefs::Connect()
{
  QObject::connect(gui.WebcamFtFormats, SIGNAL(activated(int)),
    this, SLOT(on_WebcamFtFormats_activated(int)));
  QObject::connect(gui.WebcamFtResolutions, SIGNAL(activated(int)),
    this, SLOT(on_WebcamFtResolutions_activated(int)));
  QObject::connect(gui.FindCascade, SIGNAL(pressed()),
    this, SLOT(on_FindCascade_pressed()));
  QObject::connect(gui.CascadePath, SIGNAL(editingFinished()),
    this, SLOT(on_CascadePath_editingFinished()));
  QObject::connect(gui.ExpFilterFactor, SIGNAL(valueChanged(int)),
    this, SLOT(on_ExpFilterFactor_valueChanged(int)));
  QObject::connect(gui.OptimLevel, SIGNAL(valueChanged(int)),
    this, SLOT(on_OptimLevel_valueChanged(int)));
}

WebcamFtPrefs::WebcamFtPrefs(const Ui::LinuxtrackMainForm &ui) : gui(ui)
{
  Connect();
}

WebcamFtPrefs::~WebcamFtPrefs()
{
}

static WebcamInfo *wc_info = NULL;

void WebcamFtPrefs::on_WebcamFtFormats_activated(int index)
{
  gui.WebcamFtResolutions->clear();
  if(currentId == "None"){
    std::cout<<"None!"<<std::endl;
    return;
  }
  gui.WebcamFtResolutions->addItems(wc_info->getResolutions(index));
  int res_index = 0;
  int res_x, res_y;
  int fps_num, fps_den;
  if(ltr_int_wc_get_resolution(&res_x, &res_y) &&
    ltr_int_wc_get_fps(&fps_num, &fps_den)){
    res_index = wc_info->findRes(res_x, res_y, fps_num, fps_den,
				 wc_info->getFourcc(index));
    gui.WebcamFtResolutions->setCurrentIndex(res_index);
  }
  on_WebcamFtResolutions_activated(res_index);
}

void WebcamFtPrefs::on_WebcamFtResolutions_activated(int index)
{
  if(gui.WebcamFtFormats->currentIndex() == -1){
    return;
  }
  QString res, fps, fmt;
  if(wc_info->findFmtSpecs(gui.WebcamFtFormats->currentIndex(),
                           index, res, fps, fmt)){
    int x,y, num, den;
    WebcamInfo::decodeRes(res, x, y);
    WebcamInfo::decodeFps(fps, num, den);
    if(!initializing){
      ltr_int_wc_set_pixfmt(fmt.toAscii().data());
      ltr_int_wc_set_resolution(x, y);
      ltr_int_wc_set_fps(num, den);
    }
  }
}

bool WebcamFtPrefs::Activate(const QString &ID, bool init)
{
  bool res = false;
  QString sec;
  initializing = init;
  if(PREF.getFirstDeviceSection(QString("Webcam-face"), ID, sec)){
    if(!initializing) PREF.activateDevice(sec);
    currentSection = sec;
  }else{
    sec = "Webcam-face";
    if(PREF.createSection(sec)){
      PREF.addKeyVal(sec, (char *)"Capture-device", (char *)"Webcam-face");
      PREF.addKeyVal(sec, (char *)"Capture-device-id", ID);
      PREF.addKeyVal(sec, (char *)"Pixel-format", (char *)"");
      PREF.addKeyVal(sec, (char *)"Resolution", (char *)"");
      PREF.addKeyVal(sec, (char *)"Fps", (char *)"");
      PREF.activateDevice(sec);
      currentSection = sec;
    }else{
      initializing = false;
      return false;
    }
  }
  if(!ltr_int_wc_init_prefs()){
    initializing = false;
    return false;
  }
  currentId = ID;
  gui.WebcamFtFormats->clear();
  gui.WebcamFtResolutions->clear();
  if((currentId != "None") && (currentId.size() != 0)){
    if(wc_info != NULL){
      delete(wc_info);
    }
    wc_info = new WebcamInfo(currentId);

    gui.WebcamFtFormats->addItems(wc_info->getFormats());
    QString fourcc, thres, bmin, bmax, res, fps, flip;
    int fmt_index = 0;
    const char *tmp = ltr_int_wc_get_pixfmt();
    if(tmp != NULL){
      fourcc = tmp;
      fmt_index = wc_info->findFourcc(fourcc);
      gui.WebcamFtFormats->setCurrentIndex(fmt_index);
    }
    on_WebcamFtFormats_activated(fmt_index);
    const char *cascade = ltr_int_wc_get_cascade();
    QString cascadePath;
    if(cascade == NULL){
      cascadePath = PrefProxy::getDataPath("haarcascade_frontalface_alt2.xml");
    }else{
      cascadePath = cascade;
    }
    gui.CascadePath->setText(cascadePath);
    int n = (2.0 / ltr_int_wc_get_eff()) - 2;
    gui.ExpFilterFactor->setValue(n);
    on_ExpFilterFactor_valueChanged(n);
    gui.OptimLevel->setValue(ltr_int_wc_get_optim_level());
  }
  initializing = false;
  return res;
}

bool WebcamFtPrefs::AddAvailableDevices(QComboBox &combo)
{
  bool res = false;
  QString id;
  deviceType_t dt;
  bool webcam_selected = false;
  if(PREF.getActiveDevice(dt,id) && (dt == WEBCAM_FT)){
    webcam_selected = true;
    std::cout<<"Facetracker selected!"<<std::endl;
  }

  QStringList &webcams = WebcamInfo::EnumerateWebcams();
  QStringList::iterator i;
  PrefsLink *pl;
  QVariant v;
  for(i = webcams.begin(); i != webcams.end(); ++i){
    pl = new PrefsLink(WEBCAM_FT, *i);
    v.setValue(*pl);
    combo.addItem((*i)+" face tracker", v);
    if(webcam_selected && (*i == id)){
      combo.setCurrentIndex(combo.count() - 1);
      res = true;
    }
  }
  delete(&webcams);
  return res;
}

void WebcamFtPrefs::on_FindCascade_pressed()
{
  QString path = gui.CascadePath->text();
  if(path.isEmpty()){
    path = "/";
  }else{
    QDir tmp(path);
    path = tmp.filePath(path);
  }
  QString fileName = QFileDialog::getOpenFileName(NULL,
     "Find Harr/LBP cascade", path, "xml Files (*.xml)");
  gui.CascadePath->setText(fileName);
  on_CascadePath_editingFinished();
}

void WebcamFtPrefs::on_CascadePath_editingFinished()
{
  if(!initializing){
    ltr_int_wc_set_cascade(gui.CascadePath->text().toAscii().data());
  }
}

void WebcamFtPrefs::on_ExpFilterFactor_valueChanged(int value)
{
  float a = 2 / (value + 2.0); //EWMA window size
  gui.ExpFiltFactorVal->setText(QString("%1").arg(a, 0, 'g', 2));
  if(!initializing){
    ltr_int_wc_set_eff(a);
  }
}

void WebcamFtPrefs::on_OptimLevel_valueChanged(int value)
{
  if(!initializing){
    ltr_int_wc_set_optim_level(value);
  }
}

<commit_msg>Fixed problem with cascade initialization that was causing segfaults.<commit_after>#include <QMessageBox>
#include <iostream>
#include <QByteArray>
#include "ltr_gui.h"
#include "webcam_ft_prefs.h"
#include "wc_driver_prefs.h"
#include "webcam_info.h"
#include "ltr_gui_prefs.h"

static QString currentId = QString("None");
static QString currentSection = QString();

void WebcamFtPrefs::Connect()
{
  QObject::connect(gui.WebcamFtFormats, SIGNAL(activated(int)),
    this, SLOT(on_WebcamFtFormats_activated(int)));
  QObject::connect(gui.WebcamFtResolutions, SIGNAL(activated(int)),
    this, SLOT(on_WebcamFtResolutions_activated(int)));
  QObject::connect(gui.FindCascade, SIGNAL(pressed()),
    this, SLOT(on_FindCascade_pressed()));
  QObject::connect(gui.CascadePath, SIGNAL(editingFinished()),
    this, SLOT(on_CascadePath_editingFinished()));
  QObject::connect(gui.ExpFilterFactor, SIGNAL(valueChanged(int)),
    this, SLOT(on_ExpFilterFactor_valueChanged(int)));
  QObject::connect(gui.OptimLevel, SIGNAL(valueChanged(int)),
    this, SLOT(on_OptimLevel_valueChanged(int)));
}

WebcamFtPrefs::WebcamFtPrefs(const Ui::LinuxtrackMainForm &ui) : gui(ui)
{
  Connect();
}

WebcamFtPrefs::~WebcamFtPrefs()
{
}

static WebcamInfo *wc_info = NULL;

void WebcamFtPrefs::on_WebcamFtFormats_activated(int index)
{
  gui.WebcamFtResolutions->clear();
  if(currentId == "None"){
    std::cout<<"None!"<<std::endl;
    return;
  }
  gui.WebcamFtResolutions->addItems(wc_info->getResolutions(index));
  int res_index = 0;
  int res_x, res_y;
  int fps_num, fps_den;
  if(ltr_int_wc_get_resolution(&res_x, &res_y) &&
    ltr_int_wc_get_fps(&fps_num, &fps_den)){
    res_index = wc_info->findRes(res_x, res_y, fps_num, fps_den,
				 wc_info->getFourcc(index));
    gui.WebcamFtResolutions->setCurrentIndex(res_index);
  }
  on_WebcamFtResolutions_activated(res_index);
}

void WebcamFtPrefs::on_WebcamFtResolutions_activated(int index)
{
  if(gui.WebcamFtFormats->currentIndex() == -1){
    return;
  }
  QString res, fps, fmt;
  if(wc_info->findFmtSpecs(gui.WebcamFtFormats->currentIndex(),
                           index, res, fps, fmt)){
    int x,y, num, den;
    WebcamInfo::decodeRes(res, x, y);
    WebcamInfo::decodeFps(fps, num, den);
    if(!initializing){
      ltr_int_wc_set_pixfmt(fmt.toAscii().data());
      ltr_int_wc_set_resolution(x, y);
      ltr_int_wc_set_fps(num, den);
    }
  }
}

bool WebcamFtPrefs::Activate(const QString &ID, bool init)
{
  bool res = false;
  QString sec;
  initializing = init;
  if(PREF.getFirstDeviceSection(QString("Webcam-face"), ID, sec)){
    if(!initializing) PREF.activateDevice(sec);
    currentSection = sec;
  }else{
    sec = "Webcam-face";
    if(PREF.createSection(sec)){
      PREF.addKeyVal(sec, (char *)"Capture-device", (char *)"Webcam-face");
      PREF.addKeyVal(sec, (char *)"Capture-device-id", ID);
      PREF.addKeyVal(sec, (char *)"Pixel-format", (char *)"");
      PREF.addKeyVal(sec, (char *)"Resolution", (char *)"");
      PREF.addKeyVal(sec, (char *)"Fps", (char *)"");
      QString cascadePath = PrefProxy::getDataPath("haarcascade_frontalface_alt2.xml");
      QFileInfo finf = QFileInfo(cascadePath);
      PREF.addKeyVal(sec, (char *)"Cascade", qPrintable(finf.canonicalFilePath()));
      PREF.activateDevice(sec);
      currentSection = sec;
    }else{
      initializing = false;
      return false;
    }
  }
  if(!ltr_int_wc_init_prefs()){
    initializing = false;
    return false;
  }
  currentId = ID;
  gui.WebcamFtFormats->clear();
  gui.WebcamFtResolutions->clear();
  if((currentId != "None") && (currentId.size() != 0)){
    if(wc_info != NULL){
      delete(wc_info);
    }
    wc_info = new WebcamInfo(currentId);

    gui.WebcamFtFormats->addItems(wc_info->getFormats());
    QString fourcc, thres, bmin, bmax, res, fps, flip;
    int fmt_index = 0;
    const char *tmp = ltr_int_wc_get_pixfmt();
    if(tmp != NULL){
      fourcc = tmp;
      fmt_index = wc_info->findFourcc(fourcc);
      gui.WebcamFtFormats->setCurrentIndex(fmt_index);
    }
    on_WebcamFtFormats_activated(fmt_index);
    const char *cascade = ltr_int_wc_get_cascade();
    QString cascadePath = QString(cascade);
    gui.CascadePath->setText(cascadePath);
    int n = (2.0 / ltr_int_wc_get_eff()) - 2;
    gui.ExpFilterFactor->setValue(n);
    on_ExpFilterFactor_valueChanged(n);
    gui.OptimLevel->setValue(ltr_int_wc_get_optim_level());
  }
  initializing = false;
  return res;
}

bool WebcamFtPrefs::AddAvailableDevices(QComboBox &combo)
{
  bool res = false;
  QString id;
  deviceType_t dt;
  bool webcam_selected = false;
  if(PREF.getActiveDevice(dt,id) && (dt == WEBCAM_FT)){
    webcam_selected = true;
    std::cout<<"Facetracker selected!"<<std::endl;
  }

  QStringList &webcams = WebcamInfo::EnumerateWebcams();
  QStringList::iterator i;
  PrefsLink *pl;
  QVariant v;
  for(i = webcams.begin(); i != webcams.end(); ++i){
    pl = new PrefsLink(WEBCAM_FT, *i);
    v.setValue(*pl);
    combo.addItem((*i)+" face tracker", v);
    if(webcam_selected && (*i == id)){
      combo.setCurrentIndex(combo.count() - 1);
      res = true;
    }
  }
  delete(&webcams);
  return res;
}

void WebcamFtPrefs::on_FindCascade_pressed()
{
  QString path = gui.CascadePath->text();
  if(path.isEmpty()){
    path = "/";
  }else{
    QDir tmp(path);
    path = tmp.filePath(path);
  }
  QString fileName = QFileDialog::getOpenFileName(NULL,
     "Find Harr/LBP cascade", path, "xml Files (*.xml)");
  gui.CascadePath->setText(fileName);
  on_CascadePath_editingFinished();
}

void WebcamFtPrefs::on_CascadePath_editingFinished()
{
  if(!initializing){
    ltr_int_wc_set_cascade(gui.CascadePath->text().toAscii().data());
  }
}

void WebcamFtPrefs::on_ExpFilterFactor_valueChanged(int value)
{
  float a = 2 / (value + 2.0); //EWMA window size
  gui.ExpFiltFactorVal->setText(QString("%1").arg(a, 0, 'g', 2));
  if(!initializing){
    ltr_int_wc_set_eff(a);
  }
}

void WebcamFtPrefs::on_OptimLevel_valueChanged(int value)
{
  if(!initializing){
    ltr_int_wc_set_optim_level(value);
  }
}

<|endoftext|>


<commit_before>#include <cstdlib>
#include <cstring>

#include "cpu.hpp"
#include "../conversion.hpp"
#include "../opcodes.hpp"

#define VALIDATE_ARGS(val1, val2)\
VALIDATE_ARG(val1)\
VALIDATE_ARG(val2)

#define VALIDATE_ARG(value)\
{\
	if (((value) & ~0x80) > 0x12)\
		return ERR_INVALID_ARG;\
}

#define VALIDATE_PC()\
{\
	if (bytes2word(this->pc) >= mem_size)\
		return ERR_PC_BOUNDARY;\
}

static inline u32 opcode(u32 instruction)
{
	return instruction >> 24;
}

static inline u32 data(u32 instruction)
{
	return instruction & 0xffffff;
}

static inline u32 byte(u32 instruction, u8 number)
{
	return (instruction >> (8 * (3 - number))) & 0xff;
}

CPU::CPU() :
	lc(&this->registers[0x10 * sizeof(u32)]),
	sp(&this->registers[0x11 * sizeof(u32)]),
	pc(&this->registers[0x12 * sizeof(u32)]),
	mem_size(0), memory(NULL),
	registers({0}), stack({0}), flags({false, false, false, false}),
	extension({0})
{}

CPU::~CPU()
{
	free(this->memory);
}

u32
CPU::CurrentInstruction()
{
	return bytes2word(this->memory + bytes2word(this->pc) * sizeof(u32));
}

u32
CPU::LastInstruction()
{
	return bytes2word(this->memory + (bytes2word(this->pc) - 1) * sizeof(u32));
}

bool
CPU::Initialize(u32 mem_size)
{
	if ((this->memory = (u8 *)malloc(mem_size * sizeof(u32))))
		this->mem_size = mem_size;
	return (bool)this->memory;
}

bool
CPU::Load(FILE *input)
{
	int byte;
	u32 byte_num = 0;
	while ((byte = getc(input)) != EOF && byte_num < this->mem_size * sizeof(u32))
		this->memory[byte_num++] = byte;
	return byte == EOF;
}

u8*
CPU::WhichRegister(u8 value)
{
	u8 *reg_ptr;
	reg_ptr = &this->registers[(value & ~0x80) * sizeof(u32)];
	if (value & 0x80)
	{
		if (*reg_ptr < this->mem_size)
			return &this->memory[*reg_ptr * sizeof(u32)];
		else
			return NULL;
	}
	return reg_ptr;
}

CPU::ProgramState
CPU::Tick()
{
	VALIDATE_PC()
	u8 *ptr1, *ptr2;
	s64 result;
	u32 instruction = this->CurrentInstruction();
	bytes_add(this->pc, 1);
	switch (opcode(instruction))
	{
		case OP_NOP:
			break;
		case OP_HCF:
			return HALTED;
		case OP_MOV:
			if (byte(instruction, 3))
			{
				VALIDATE_ARG(byte(instruction, 1))
				VALIDATE_PC()
				ptr1 = this->WhichRegister(byte(instruction, 1));
				if (!ptr1)
					return ERR_ADDRESS_BOUNDARY;
				memcpy(
					ptr1,
					this->memory + bytes2word(this->pc) * sizeof(u32),
					sizeof(u32)
				);
				bytes_add(this->pc, 1);
			}
			else
			{
				VALIDATE_ARGS(byte(instruction, 1), byte(instruction, 2))
				ptr1 = this->WhichRegister(byte(instruction, 1));
				ptr2 = this->WhichRegister(byte(instruction, 2));
				if (!ptr1 || !ptr2)
					return ERR_ADDRESS_BOUNDARY;
				word2bytes(bytes2word(ptr2), ptr1);
			}
			break;
		case OP_ADD:
			VALIDATE_ARGS(byte(instruction, 1), byte(instruction, 2))
			ptr1 = this->WhichRegister(byte(instruction, 1));
			ptr2 = this->WhichRegister(byte(instruction, 2));
			if (!ptr1 || !ptr2)
				return ERR_ADDRESS_BOUNDARY;
			result = (s64)(s32)bytes2word(ptr1) + (s32)bytes2word(ptr2);
			word2bytes(result, ptr1);
			this->flags.carry = (bool)(result != (s32)result);
			break;
		// TODO: add remaining opcodes
		case _OP_SIZE:
			if (this->mem_size < data(instruction)) {
				this->extension.required_memory = data(instruction);
				return _ERR_SIZE;
			}
			break;
		case _OP_DEBUG:
			this->extension.debug_info = data(instruction);
			break;
		default:
			this->_SetErroredLine();
			return ERR_INVALID_OPCODE;
	}
	return OK;
}

void
CPU::_SetErroredLine()
{
	if (!this->extension.debug_info)
		return;
	DebugSymbol key;
	for (
		u32 word_index = this->extension.debug_info;
		word_index < this->mem_size;
		word_index += key.next()
	) {
		key.value = bytes2word(this->memory + word_index * sizeof(u32));
		if (word_index == bytes2word(this->pc))
		{
			this->extension.errored_line =
				(char *)(this->memory + word_index * sizeof(u32));
			return;
		}
		else if (key.word() > bytes2word(this->pc)) // instruction not present
		                                            // in the source file
			break;
		else if (!key.next())  // no more lines follows
			break;
	}
	this->extension.errored_line = NULL;
}
<commit_msg>vm: Conformed ADD to the documentation<commit_after>#include <cstdlib>
#include <cstring>

#include "cpu.hpp"
#include "../conversion.hpp"
#include "../opcodes.hpp"

#define VALIDATE_ARGS(val1, val2)\
VALIDATE_ARG(val1)\
VALIDATE_ARG(val2)

#define VALIDATE_ARG(value)\
{\
	if (((value) & ~0x80) > 0x12)\
		return ERR_INVALID_ARG;\
}

#define VALIDATE_PC()\
{\
	if (bytes2word(this->pc) >= mem_size)\
		return ERR_PC_BOUNDARY;\
}

static inline u32 opcode(u32 instruction)
{
	return instruction >> 24;
}

static inline u32 data(u32 instruction)
{
	return instruction & 0xffffff;
}

static inline u32 byte(u32 instruction, u8 number)
{
	return (instruction >> (8 * (3 - number))) & 0xff;
}

CPU::CPU() :
	lc(&this->registers[0x10 * sizeof(u32)]),
	sp(&this->registers[0x11 * sizeof(u32)]),
	pc(&this->registers[0x12 * sizeof(u32)]),
	mem_size(0), memory(NULL),
	registers({0}), stack({0}), flags({false, false, false, false}),
	extension({0})
{}

CPU::~CPU()
{
	free(this->memory);
}

u32
CPU::CurrentInstruction()
{
	return bytes2word(this->memory + bytes2word(this->pc) * sizeof(u32));
}

u32
CPU::LastInstruction()
{
	return bytes2word(this->memory + (bytes2word(this->pc) - 1) * sizeof(u32));
}

bool
CPU::Initialize(u32 mem_size)
{
	if ((this->memory = (u8 *)malloc(mem_size * sizeof(u32))))
		this->mem_size = mem_size;
	return (bool)this->memory;
}

bool
CPU::Load(FILE *input)
{
	int byte;
	u32 byte_num = 0;
	while ((byte = getc(input)) != EOF && byte_num < this->mem_size * sizeof(u32))
		this->memory[byte_num++] = byte;
	return byte == EOF;
}

u8*
CPU::WhichRegister(u8 value)
{
	u8 *reg_ptr;
	reg_ptr = &this->registers[(value & ~0x80) * sizeof(u32)];
	if (value & 0x80)
	{
		if (*reg_ptr < this->mem_size)
			return &this->memory[*reg_ptr * sizeof(u32)];
		else
			return NULL;
	}
	return reg_ptr;
}

CPU::ProgramState
CPU::Tick()
{
	VALIDATE_PC()
	u8 *ptr1, *ptr2;
	s64 result;
	u32 instruction = this->CurrentInstruction();
	bytes_add(this->pc, 1);
	switch (opcode(instruction))
	{
		case OP_NOP:
			break;
		case OP_HCF:
			return HALTED;
		case OP_MOV:
			if (byte(instruction, 3))
			{
				VALIDATE_ARG(byte(instruction, 1))
				VALIDATE_PC()
				ptr1 = this->WhichRegister(byte(instruction, 1));
				if (!ptr1)
					return ERR_ADDRESS_BOUNDARY;
				memcpy(
					ptr1,
					this->memory + bytes2word(this->pc) * sizeof(u32),
					sizeof(u32)
				);
				bytes_add(this->pc, 1);
			}
			else
			{
				VALIDATE_ARGS(byte(instruction, 1), byte(instruction, 2))
				ptr1 = this->WhichRegister(byte(instruction, 1));
				ptr2 = this->WhichRegister(byte(instruction, 2));
				if (!ptr1 || !ptr2)
					return ERR_ADDRESS_BOUNDARY;
				word2bytes(bytes2word(ptr2), ptr1);
			}
			break;
		case OP_ADD:
			VALIDATE_ARGS(byte(instruction, 1), byte(instruction, 2))
			ptr1 = this->WhichRegister(byte(instruction, 1));
			ptr2 = this->WhichRegister(byte(instruction, 2));
			if (!ptr1 || !ptr2)
				return ERR_ADDRESS_BOUNDARY;
			result = (s64)(s32)bytes2word(ptr1) + (s32)bytes2word(ptr2);
			word2bytes(result, ptr1);
			this->flags.carry =
				(bool)(result != (s32)result && (u64)result != (u32)result);
			break;
		// TODO: add remaining opcodes
		case _OP_SIZE:
			if (this->mem_size < data(instruction)) {
				this->extension.required_memory = data(instruction);
				return _ERR_SIZE;
			}
			break;
		case _OP_DEBUG:
			this->extension.debug_info = data(instruction);
			break;
		default:
			this->_SetErroredLine();
			return ERR_INVALID_OPCODE;
	}
	return OK;
}

void
CPU::_SetErroredLine()
{
	if (!this->extension.debug_info)
		return;
	DebugSymbol key;
	for (
		u32 word_index = this->extension.debug_info;
		word_index < this->mem_size;
		word_index += key.next()
	) {
		key.value = bytes2word(this->memory + word_index * sizeof(u32));
		if (word_index == bytes2word(this->pc))
		{
			this->extension.errored_line =
				(char *)(this->memory + word_index * sizeof(u32));
			return;
		}
		else if (key.word() > bytes2word(this->pc)) // instruction not present
		                                            // in the source file
			break;
		else if (!key.next())  // no more lines follows
			break;
	}
	this->extension.errored_line = NULL;
}
<|endoftext|>