<commit_before>// Copyright (c) 2016-2018 The Gulden developers
// Authored by: Malcolm MacLeod (mmacleod@webmail.co.za)
// Distributed under the GULDEN software license, see the accompanying
// file COPYING

#include "backupdialog.h"
#include <qt/_Gulden/forms/ui_backupdialog.h>

#include "wallet/wallet.h"
#include "walletmodel.h"
#include "guiconstants.h"
#include "unity/appmanager.h"

BackupDialog::BackupDialog(const QStyle* _platformStyle, QWidget* parent, WalletModel* model)
: QFrame( parent )
, ui( new Ui::BackupDialog )
, platformStyle( _platformStyle )
, walletModel(model)
{
    ui->setupUi(this);

    ui->labelBackupPhrase->setVisible(false);
    ui->labelShowBackupPhrase->setVisible(true);

    ui->labelShowBackupPhrase->setCursor(Qt::PointingHandCursor);
    ui->buttonShowBackupPhrase->setCursor(Qt::PointingHandCursor);
    ui->buttonSaveToFile->setCursor(Qt::PointingHandCursor);
    ui->buttonDone->setCursor(Qt::PointingHandCursor);

    ui->frameBackupDialogsButtons->setVisible(true);

    connect(ui->labelShowBackupPhrase, SIGNAL(clicked()), this, SLOT(showBackupPhrase()));
    connect(ui->buttonShowBackupPhrase, SIGNAL(clicked()), this, SLOT(showBackupPhrase()));
    connect(ui->buttonSaveToFile, SIGNAL(clicked()), this, SIGNAL(saveBackupFile()));
    connect(ui->buttonDone, SIGNAL(clicked()), this, SIGNAL(dismiss()));
}

void BackupDialog::showBackupPhrase()
{
    ui->labelBackupPhrase->setVisible(true);
    ui->labelShowBackupPhrase->setVisible(false);
    ui->buttonShowBackupPhrase->setVisible(false);

    LOCK(pactiveWallet->cs_wallet);
    WalletModel::UnlockContext ctx(walletModel->requestUnlock());
    if (ctx.isValid())
    {
        std::set<SecureString> allPhrases;
        for (const auto& seedIter : pactiveWallet->mapSeeds)
        {
            // fixme: (SPV) get real start time in here
            int64_t birthTime = 123456;
            SecureString phrase = GuldenAppManager::composeRecoveryPhrase(seedIter.second->getMnemonic(), birthTime);
            allPhrases.insert(phrase);
        }

        if (allPhrases.size() == 1)
        {
            ui->labelBackupPhraseHeading->setText(tr("Below is your secret recovery phrase, write it down and keep it safe. Lose phrase = lose Guldens. Someone else with access to the phrase = lose Guldens."));
            ui->labelBackupPhrase->setText(QString::fromStdString(allPhrases.begin()->c_str()));
        }
        else if (allPhrases.size() > 1)
        {
            ui->labelBackupPhraseHeading->setText(tr("Below are your secret recovery phrases, write them down and keep them safe. Lose phrase = lose Guldens. Someone else with access to the phrase = lose Guldens."));
            QString phrases;
            for (const auto& phrase : allPhrases)
            {
                phrases += QString::fromStdString((phrase + "\n").c_str());
            }
            ui->labelBackupPhrase->setText(phrases);
        }
        else
        {
            ui->labelBackupPhraseHeading->setText(tr("No recovery phrases present for this wallet."));
        }
    }

    bool haveNonHDAccounts = false;
    for (const auto& accountIter : pactiveWallet->mapAccounts)
    {
        if (!accountIter.second->IsHD())
        {
            haveNonHDAccounts = true;
        }
    }

    if (haveNonHDAccounts)
    {
        ui->labelSaveToDiskDescription->setText(tr("Your wallet contains some legacy non-HD accounts, these cannot be restored using recovery phrases and require regular disk backup. Please ensure you make regular disk backups of your wallet, or delete the legacy account in order to ensure your funds remain secured."));
        ui->labelSaveToDiskDescription->setStyleSheet(STYLE_INVALID);
    }
}

BackupDialog::~BackupDialog()
{
    //fixme: (2.1) - Burn visible phrase.
    delete ui;
}
<commit_msg>Compute recovery birth time from transactions<commit_after>// Copyright (c) 2016-2018 The Gulden developers
// Authored by: Malcolm MacLeod (mmacleod@webmail.co.za)
// Distributed under the GULDEN software license, see the accompanying
// file COPYING

#include "backupdialog.h"
#include <qt/_Gulden/forms/ui_backupdialog.h>

#include "wallet/wallet.h"
#include "walletmodel.h"
#include "guiconstants.h"
#include "unity/appmanager.h"

BackupDialog::BackupDialog(const QStyle* _platformStyle, QWidget* parent, WalletModel* model)
: QFrame( parent )
, ui( new Ui::BackupDialog )
, platformStyle( _platformStyle )
, walletModel(model)
{
    ui->setupUi(this);

    ui->labelBackupPhrase->setVisible(false);
    ui->labelShowBackupPhrase->setVisible(true);

    ui->labelShowBackupPhrase->setCursor(Qt::PointingHandCursor);
    ui->buttonShowBackupPhrase->setCursor(Qt::PointingHandCursor);
    ui->buttonSaveToFile->setCursor(Qt::PointingHandCursor);
    ui->buttonDone->setCursor(Qt::PointingHandCursor);

    ui->frameBackupDialogsButtons->setVisible(true);

    connect(ui->labelShowBackupPhrase, SIGNAL(clicked()), this, SLOT(showBackupPhrase()));
    connect(ui->buttonShowBackupPhrase, SIGNAL(clicked()), this, SLOT(showBackupPhrase()));
    connect(ui->buttonSaveToFile, SIGNAL(clicked()), this, SIGNAL(saveBackupFile()));
    connect(ui->buttonDone, SIGNAL(clicked()), this, SIGNAL(dismiss()));
}

void BackupDialog::showBackupPhrase()
{
    ui->labelBackupPhrase->setVisible(true);
    ui->labelShowBackupPhrase->setVisible(false);
    ui->buttonShowBackupPhrase->setVisible(false);

    LOCK(pactiveWallet->cs_wallet);
    WalletModel::UnlockContext ctx(walletModel->requestUnlock());
    if (ctx.isValid())
    {
        int64_t birthTime = 0;

        // determine block time of earliest transaction (if any)
        // if this cannot be determined for every transaction a phrase without birth time acceleration will be used
        int64_t firstTransactionTime = std::numeric_limits<int64_t>::max();
        for (CWallet::TxItems::const_iterator it = pactiveWallet->wtxOrdered.begin(); it != pactiveWallet->wtxOrdered.end(); ++it)
        {
            CWalletTx* wtx = it->second.first;
            if (!wtx->hashUnset())
            {
                CBlockIndex* index = mapBlockIndex[wtx->hashBlock];
                if (index && index->IsValid(BLOCK_VALID_HEADER))
                    firstTransactionTime = std::min(firstTransactionTime, std::max(int64_t(0), index->GetBlockTime()));
                else
                {
                    firstTransactionTime = 0;
                    break;
                }
            }
        }

        if (firstTransactionTime < std::numeric_limits<int64_t>::max())
            birthTime = firstTransactionTime;

        std::set<SecureString> allPhrases;
        for (const auto& seedIter : pactiveWallet->mapSeeds)
        {
            SecureString phrase = GuldenAppManager::composeRecoveryPhrase(seedIter.second->getMnemonic(), birthTime);
            allPhrases.insert(phrase);
        }

        if (allPhrases.size() == 1)
        {
            ui->labelBackupPhraseHeading->setText(tr("Below is your secret recovery phrase, write it down and keep it safe. Lose phrase = lose Guldens. Someone else with access to the phrase = lose Guldens."));
            ui->labelBackupPhrase->setText(QString::fromStdString(allPhrases.begin()->c_str()));
        }
        else if (allPhrases.size() > 1)
        {
            ui->labelBackupPhraseHeading->setText(tr("Below are your secret recovery phrases, write them down and keep them safe. Lose phrase = lose Guldens. Someone else with access to the phrase = lose Guldens."));
            QString phrases;
            for (const auto& phrase : allPhrases)
            {
                phrases += QString::fromStdString((phrase + "\n").c_str());
            }
            ui->labelBackupPhrase->setText(phrases);
        }
        else
        {
            ui->labelBackupPhraseHeading->setText(tr("No recovery phrases present for this wallet."));
        }
    }

    bool haveNonHDAccounts = false;
    for (const auto& accountIter : pactiveWallet->mapAccounts)
    {
        if (!accountIter.second->IsHD())
        {
            haveNonHDAccounts = true;
        }
    }

    if (haveNonHDAccounts)
    {
        ui->labelSaveToDiskDescription->setText(tr("Your wallet contains some legacy non-HD accounts, these cannot be restored using recovery phrases and require regular disk backup. Please ensure you make regular disk backups of your wallet, or delete the legacy account in order to ensure your funds remain secured."));
        ui->labelSaveToDiskDescription->setStyleSheet(STYLE_INVALID);
    }
}

BackupDialog::~BackupDialog()
{
    //fixme: (2.1) - Burn visible phrase.
    delete ui;
}
<|endoftext|>


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

#include "filepath.h"
#include "logging.h"
#include "functions.h"
#include <sstream>
#include <iostream>
#ifdef _MSC_VER
#include <Windows.h>
#else
#include <sys/stat.h>
#include <string.h>
#endif

// May need to fix later for POSIX
#include <direct.h>

#ifdef _WIN32
#define PATHSEPARATOR '\\'
#define MKDIR _mkdir
#else
#define PATHSEPARATOR '/'
#define MKDIR mkdir
#endif

namespace stadic{

bool isDir(const std::string &dir)
{
#ifdef _MSC_VER
    DWORD result = GetFileAttributes(dir.c_str());
    if(result != INVALID_FILE_ATTRIBUTES) {
        return result & FILE_ATTRIBUTE_DIRECTORY;
    }
    return false;
#else //POSIX
    struct stat path;

    if(stat(dir.c_str(), &path)==0 && S_ISDIR(path.st_mode)){
        return true;
    }
    return false;
#endif
}

bool isFile(const std::string &file)
{
#ifdef _MSC_VER
    DWORD result = GetFileAttributes(file.c_str());
    if(result != INVALID_FILE_ATTRIBUTES) {
        return !(result & FILE_ATTRIBUTE_DIRECTORY);
    }
    return false;
#else //POSIX
    struct stat path;

    if(stat(file.c_str(), &path)==0 && S_ISREG(path.st_mode)){
        return true;
    }
    return false;
#endif
}

bool exists(const std::string &path)
{
    if(isDir(path)){
        return true;
    }
    return isFile(path);
}

PathName::PathName(const std::string &path) : m_isFile(false)
{
    if(path.size() > 0) {
        m_parts = split(path, '/');
        if(m_parts.size() > 0) {
            if(*(path.end() - 1) != '/'){
                m_isFile = true;
                m_filename = *(m_parts.end() - 1);
                m_parts.pop_back();
            }
        }
    }
}

bool PathName::create() const
{
    if(m_parts.size() > 0){
        std::string current = m_parts[0];
        MKDIR(current.c_str());
        for(unsigned i = 1; i<m_parts.size(); ++i){
            current += PATHSEPARATOR + m_parts[i];
            if(!stadic::exists(current)) {
                MKDIR(current.c_str());
            }
        }
        if(m_isFile) {
            std::string name = toString();
            FILE* fp = fopen(name.c_str(), "w");
            fclose(fp);
        }
        return true;
    }
    return false;
}

bool PathName::remove() const
{
    std::vector<std::string> paths;
    std::string result;
    if(m_parts.size() > 0) {
        result = m_parts[0] + PATHSEPARATOR;
        paths.push_back(result);
        for(unsigned i = 1; i<m_parts.size(); ++i) {
            result += m_parts[i] + PATHSEPARATOR;
            paths.push_back(result);
        }
    }
    if(m_isFile) {
        result += m_filename;
#ifdef _WIN32
        if(!DeleteFile(result.c_str())) {
            return false;
        }
#else // POSIX
        if(!unlink(result.c_str())) {
            return false;
        }
#endif
    }
    //for(auto string : paths) {
    //    std::cout << string << std::endl;
    //}
    for(auto iter = paths.rbegin(); iter != paths.rend(); iter++) {
        //std::cout << *iter << std::endl;
#ifdef _WIN32
        if(!RemoveDirectory(iter->c_str())) {
            return false;
        }
#else  // POSIX
        if(!rmdir(iter->c_str())) {
            return false;
        }
#endif
        if(stadic::exists(*iter)) {
            return false;
        }
    }
    return true;
}

bool PathName::isFile() const
{
    return m_isFile;
}

std::string PathName::toString() const
{
    std::string result;
    if(m_parts.size() > 0) {
        result = m_parts[0] + PATHSEPARATOR;
        for(unsigned i = 1; i<m_parts.size(); ++i) {
            result += m_parts[i] + PATHSEPARATOR;
        }
    }
    if(m_isFile) {
        result += m_filename;
    }
    return result;
}

bool PathName::exists() const
{
    std::string file = toString();
    return stadic::exists(file);
}

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

#include "filepath.h"
#include "logging.h"
#include "functions.h"
#include <sstream>
#include <iostream>
#ifdef _MSC_VER
#include <Windows.h>
#else
#include <sys/stat.h>
#include <string.h>
#endif

// May need to fix later for POSIX
#include <direct.h>

#ifdef _WIN32
#define PATHSEPARATOR '\\'
#define MKDIR _mkdir
#else
#define PATHSEPARATOR '/'
#define MKDIR mkdir
#endif

namespace stadic{

bool isDir(const std::string &dir)
{
#ifdef _MSC_VER
    DWORD result = GetFileAttributes(dir.c_str());
    if(result != INVALID_FILE_ATTRIBUTES) {
        return result & FILE_ATTRIBUTE_DIRECTORY;
    }
    return false;
#else //POSIX
    struct stat path;

    if(stat(dir.c_str(), &path)==0 && S_ISDIR(path.st_mode)){
        return true;
    }
    return false;
#endif
}

bool isFile(const std::string &file)
{
#ifdef _MSC_VER
    DWORD result = GetFileAttributes(file.c_str());
    if(result != INVALID_FILE_ATTRIBUTES) {
        return !(result & FILE_ATTRIBUTE_DIRECTORY);
    }
    return false;
#else //POSIX
    struct stat path;

    if(stat(file.c_str(), &path)==0 && S_ISREG(path.st_mode)){
        return true;
    }
    return false;
#endif
}

bool exists(const std::string &path)
{
    if(isDir(path)){
        return true;
    }
    return isFile(path);
}

PathName::PathName(const std::string &path) : m_isFile(false)
{
    if(path.size() > 0) {
        m_parts = split(path, '/');
        if(m_parts.size() > 0) {
            if(*(path.end() - 1) != '/'){
                m_isFile = true;
                m_filename = *(m_parts.end() - 1);
                m_parts.pop_back();
            }
        }
    }
}

bool PathName::create() const
{
    if(m_parts.size() > 0){
        std::string current = m_parts[0];
        MKDIR(current.c_str());
        for(unsigned i = 1; i<m_parts.size(); ++i){
            current += PATHSEPARATOR + m_parts[i];
            if(!stadic::exists(current)) {
                MKDIR(current.c_str());
            }
        }
        if(m_isFile) {
            std::string name = toString();
            FILE* fp = fopen(name.c_str(), "w");
            fclose(fp);
        }
        return true;
    }
    return false;
}

bool PathName::remove() const
{
    std::vector<std::string> paths;
    std::string result;
    if(m_parts.size() > 0) {
        result = m_parts[0] + PATHSEPARATOR;
        paths.push_back(result);
        for(unsigned i = 1; i<m_parts.size(); ++i) {
            result += m_parts[i] + PATHSEPARATOR;
            paths.push_back(result);
        }
    }
    if(m_isFile) {
        result += m_filename;
#ifdef _MSC_VER
        if(!DeleteFile(result.c_str())) {
            return false;
        }
#else // POSIX
        if(unlink(result.c_str()) != 0) {
            return false;
        }
#endif
    }
    //for(auto string : paths) {
    //    std::cout << string << std::endl;
    //}
    for(auto iter = paths.rbegin(); iter != paths.rend(); iter++) {
        //std::cout << *iter << std::endl;
#ifdef _MSC_VER
        if(!RemoveDirectory(iter->c_str())) {
            return false;
        }
#else  // POSIX
        if(rmdir(iter->c_str()) != 0) {
            return false;
        }
#endif
        // Is this really necessary?
        //if(stadic::exists(*iter)) {
        //    return false;
        //}
    }
    return true;
}

bool PathName::isFile() const
{
    return m_isFile;
}

std::string PathName::toString() const
{
    std::string result;
    if(m_parts.size() > 0) {
        result = m_parts[0] + PATHSEPARATOR;
        for(unsigned i = 1; i<m_parts.size(); ++i) {
            result += m_parts[i] + PATHSEPARATOR;
        }
    }
    if(m_isFile) {
        result += m_filename;
    }
    return result;
}

bool PathName::exists() const
{
    std::string file = toString();
    return stadic::exists(file);
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * NaCl inter-module communication primitives.
 *
 * This file implements common parts of IMC for "UNIX like systems" (i.e. not
 * used on Windows).
 */

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>

#include "native_client/src/include/build_config.h"

#if NACL_ANDROID
#include <linux/ashmem.h>
#endif

#include <algorithm>

#include "native_client/src/include/atomic_ops.h"

#include "native_client/src/shared/imc/nacl_imc_c.h"
#include "native_client/src/shared/platform/nacl_check.h"

#if !NACL_ANDROID
static const char kNaClTempPrefixVar[] = "NACL_TMPFS_PREFIX";
#endif

/*
 * The pathname or SHM-namespace prefixes for memory objects created
 * by CreateMemoryObject().
 */
static const char kShmTempPrefix[] = "/tmp/google-nacl-shm-";
static const char kShmOpenPrefix[] = "/google-nacl-shm-";

static NaClCreateMemoryObjectFunc g_create_memory_object_func = NULL;

/* Duplicate a file descriptor. */
NaClHandle NaClDuplicateNaClHandle(NaClHandle handle) {
  return dup(handle);
}

void NaClSetCreateMemoryObjectFunc(NaClCreateMemoryObjectFunc func) {
  g_create_memory_object_func = func;
}

#if NACL_ANDROID
#define ASHMEM_DEVICE "/dev/ashmem"

static int AshmemCreateRegion(size_t size) {
  int fd;

  fd = open(ASHMEM_DEVICE, O_RDWR);
  if (fd < 0)
    return -1;

  if (ioctl(fd, ASHMEM_SET_SIZE, size) < 0) {
    close(fd);
    return -1;
  }

  return fd;
}
#endif

int NaClWouldBlock(void) {
  return errno == EAGAIN;
}

#if !NACL_ANDROID
static Atomic32 memory_object_count = 0;

static int TryShmOrTempOpen(size_t length, const char* prefix, bool use_temp) {
  char name[PATH_MAX];
  if (0 == length) {
    return -1;
  }

  for (;;) {
    int m;
    snprintf(name, sizeof name, "%s-%u.%u", prefix,
             getpid(),
             (int) AtomicIncrement(&memory_object_count, 1));
    if (use_temp) {
      m = open(name, O_RDWR | O_CREAT | O_EXCL, 0);
    } else {
      /*
       * Using 0 for the mode causes shm_unlink to fail with EACCES on Mac
       * OS X 10.8. As of 10.8, the kernel requires the user to have write
       * permission to successfully shm_unlink.
       */
      m = shm_open(name, O_RDWR | O_CREAT | O_EXCL, S_IWUSR);
    }
    if (0 <= m) {
      if (use_temp) {
        int rc = unlink(name);
        DCHECK(rc == 0);
      } else {
        int rc = shm_unlink(name);
        DCHECK(rc == 0);
      }
      if (ftruncate(m, length) == -1) {
        close(m);
        m = -1;
      }
      return m;
    }
    if (errno != EEXIST) {
      return -1;
    }
    /* Retry only if we got EEXIST. */
  }
}
#endif

NaClHandle NaClCreateMemoryObject(size_t length, int executable) {
  int fd;

  if (0 == length) {
    return -1;
  }

  if (g_create_memory_object_func != NULL) {
    fd = g_create_memory_object_func(length, executable);
    if (fd >= 0)
      return fd;
  }

#if NACL_ANDROID
  return AshmemCreateRegion(length);
#else
  /*
   * /dev/shm is not always available on Linux, and sometimes it's available
   * but mounted with "noexec".  To handle this case, we allow an alternative
   * temp directory to be specified via an environment variable.
   */
  const char* prefix = getenv(kNaClTempPrefixVar);
  if (prefix != NULL) {
    fd = TryShmOrTempOpen(length, prefix, true);
    if (fd >= 0) {
      return fd;
    }
  }

  if (NACL_OSX && executable) {
    /*
     * On Mac OS X, shm_open() gives us file descriptors that the OS
     * won't mmap() with PROT_EXEC, which is no good for the dynamic
     * code region, so we must use /tmp instead.
     */
    return TryShmOrTempOpen(length, kShmTempPrefix, true);
  }

  /* Try shm_open(). */
  return TryShmOrTempOpen(length, kShmOpenPrefix, false);
#endif  /* !NACL_ANDROID */
}

void* NaClMap(struct NaClDescEffector* effp,
              void* start, size_t length, int prot, int flags,
              NaClHandle memory, off_t offset) {
  static const int kPosixProt[] = {
    PROT_NONE,
    PROT_READ,
    PROT_WRITE,
    PROT_READ | PROT_WRITE,
    PROT_EXEC,
    PROT_READ | PROT_EXEC,
    PROT_WRITE | PROT_EXEC,
    PROT_READ | PROT_WRITE | PROT_EXEC
  };
  int adjusted = 0;
  UNREFERENCED_PARAMETER(effp);

  if (flags & NACL_MAP_SHARED) {
    adjusted |= MAP_SHARED;
  }
  if (flags & NACL_MAP_PRIVATE) {
    adjusted |= MAP_PRIVATE;
  }
  if (flags & NACL_MAP_FIXED) {
    adjusted |= MAP_FIXED;
  }
  return mmap(start, length, kPosixProt[prot & 7], adjusted, memory, offset);
}

int NaClUnmap(void* start, size_t length) {
  return munmap(start, length);
}
<commit_msg>Add runtime test for availability of PROT_EXEC with shm_open<commit_after>/*
 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * NaCl inter-module communication primitives.
 *
 * This file implements common parts of IMC for "UNIX like systems" (i.e. not
 * used on Windows).
 */

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>

#include "native_client/src/include/build_config.h"

#if NACL_ANDROID
#include <linux/ashmem.h>
#endif

#include <algorithm>

#include "native_client/src/include/atomic_ops.h"

#include "native_client/src/shared/imc/nacl_imc_c.h"
#include "native_client/src/shared/platform/nacl_check.h"

/*
 * The pathname or SHM-namespace prefixes for memory objects created
 * by CreateMemoryObject().
 */
static const char kShmTempPrefix[] = "/tmp/google-nacl-shm-";
static const char kShmOpenPrefix[] = "/google-nacl-shm-";

static NaClCreateMemoryObjectFunc g_create_memory_object_func = NULL;

/* Duplicate a file descriptor. */
NaClHandle NaClDuplicateNaClHandle(NaClHandle handle) {
  return dup(handle);
}

void NaClSetCreateMemoryObjectFunc(NaClCreateMemoryObjectFunc func) {
  g_create_memory_object_func = func;
}

#if NACL_ANDROID
#define ASHMEM_DEVICE "/dev/ashmem"

static int AshmemCreateRegion(size_t size) {
  int fd;

  fd = open(ASHMEM_DEVICE, O_RDWR);
  if (fd < 0)
    return -1;

  if (ioctl(fd, ASHMEM_SET_SIZE, size) < 0) {
    close(fd);
    return -1;
  }

  return fd;
}
#endif

int NaClWouldBlock(void) {
  return errno == EAGAIN;
}

#if !NACL_ANDROID
static Atomic32 memory_object_count = 0;

static int TryShmOrTempOpen(size_t length, bool use_temp) {
  const char* prefix = use_temp ? kShmTempPrefix : kShmOpenPrefix;
  char name[PATH_MAX];
  if (0 == length) {
    return -1;
  }

  for (;;) {
    int m;
    snprintf(name, sizeof name, "%s-%u.%u", prefix,
             getpid(),
             (int) AtomicIncrement(&memory_object_count, 1));
    if (use_temp) {
      m = open(name, O_RDWR | O_CREAT | O_EXCL, 0);
    } else {
      /*
       * Using 0 for the mode causes shm_unlink to fail with EACCES on Mac
       * OS X 10.8. As of 10.8, the kernel requires the user to have write
       * permission to successfully shm_unlink.
       */
      m = shm_open(name, O_RDWR | O_CREAT | O_EXCL, S_IWUSR);
    }
    if (0 <= m) {
      if (use_temp) {
        int rc = unlink(name);
        DCHECK(rc == 0);
      } else {
        int rc = shm_unlink(name);
        DCHECK(rc == 0);
      }
      if (ftruncate(m, length) == -1) {
        close(m);
        m = -1;
      }
      return m;
    }
    if (errno != EEXIST) {
      return -1;
    }
    /* Retry only if we got EEXIST. */
  }
}

#if NACL_LINUX
/*
 * Attempt to set PROT_EXEC on memory mapped from a shm_open fd, and return
 * true if this is successful, false otherwise.  On many linux installations
 * /dev/shm is mounted with 'noexec' which causes this to fail.
 */
static bool DetermineDevShmExecutable() {
  size_t pagesize = sysconf(_SC_PAGESIZE);
  int fd = TryShmOrTempOpen(pagesize, false);
  if (fd < 0)
    return false;

  bool result = false;
  void *mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0);
  if (mapping != MAP_FAILED) {
    if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0)
      result = true;
    CHECK(munmap(mapping, pagesize) == 0);
  }
  CHECK(close(fd) == 0);
  return result;
}
#endif
#endif

NaClHandle NaClCreateMemoryObject(size_t length, int executable) {
  int fd;

  if (0 == length) {
    return -1;
  }

  if (g_create_memory_object_func != NULL) {
    fd = g_create_memory_object_func(length, executable);
    if (fd >= 0)
      return fd;
  }

#if NACL_ANDROID
  return AshmemCreateRegion(length);
#else
  bool use_shm_open = true;
  if (executable) {
    /*
     * On Mac OS X, shm_open() gives us file descriptors that the OS
     * won't mmap() with PROT_EXEC, which is no good for the dynamic
     * code region, so we must use /tmp instead.
     */
    if (NACL_OSX)
      use_shm_open = false;
#if NACL_LINUX
    /*
     * On Linux this depends on how the system is configured (usually the
     * presence of noexec on the /dev/shm mount point) so we need to determine
     * this via am empirical test.
     */
    static bool s_dev_shm_executable = DetermineDevShmExecutable();
    if (!s_dev_shm_executable) {
      NaClLog(1, "NaClCreateMemoryObjectFunc: PROT_EXEC not supported by "
                 "shm_open(), falling back to /tmp for shared exectuable "
                 "memory.\n");
    }
    use_shm_open = s_dev_shm_executable;
#endif
  }

  return TryShmOrTempOpen(length, !use_shm_open);
#endif  /* !NACL_ANDROID */
}

void* NaClMap(struct NaClDescEffector* effp,
              void* start, size_t length, int prot, int flags,
              NaClHandle memory, off_t offset) {
  static const int kPosixProt[] = {
    PROT_NONE,
    PROT_READ,
    PROT_WRITE,
    PROT_READ | PROT_WRITE,
    PROT_EXEC,
    PROT_READ | PROT_EXEC,
    PROT_WRITE | PROT_EXEC,
    PROT_READ | PROT_WRITE | PROT_EXEC
  };
  int adjusted = 0;
  UNREFERENCED_PARAMETER(effp);

  if (flags & NACL_MAP_SHARED) {
    adjusted |= MAP_SHARED;
  }
  if (flags & NACL_MAP_PRIVATE) {
    adjusted |= MAP_PRIVATE;
  }
  if (flags & NACL_MAP_FIXED) {
    adjusted |= MAP_FIXED;
  }
  return mmap(start, length, kPosixProt[prot & 7], adjusted, memory, offset);
}

int NaClUnmap(void* start, size_t length) {
  return munmap(start, length);
}
<|endoftext|>


<commit_before>#ifndef GROUP__BY__HPP
#define GROUP__BY__HPP

#include "iterbase.hpp"

#include <utility>
#include <iterator>
#include <initializer_list>

namespace iter {

    template <typename Container, typename KeyFunc>
    class GroupBy;

    template <typename Container, typename KeyFunc>
    GroupBy<Container, KeyFunc> groupby(Container&&, KeyFunc);

    template <typename T, typename KeyFunc>
    GroupBy<std::initializer_list<T>, KeyFunc> groupby(
            std::initializer_list<T>, KeyFunc);

    template <typename Container, typename KeyFunc>
    class GroupBy  {
        private:
            Container container;
            KeyFunc key_func;

            friend GroupBy groupby<Container, KeyFunc>(Container&&, KeyFunc);

            template <typename T, typename KF>
            friend GroupBy<std::initializer_list<T>, KF> groupby(
                    std::initializer_list<T>, KF);

            using key_func_ret =
                decltype(std::declval<KeyFunc>()(
                            std::declval<iterator_deref<Container>>()));

            GroupBy(Container container, KeyFunc key_func)
                : container(std::forward<Container>(container)),
                key_func(key_func)
            { }

        public:
            GroupBy() = delete;
            GroupBy(const GroupBy&) = delete;
            GroupBy& operator=(const GroupBy&) = delete;
            GroupBy& operator=(GroupBy&&) = delete;

            GroupBy(GroupBy&&) = default;

            class Iterator;
            class Group;

            class Iterator {
                private:
                    iterator_type<Container> sub_iter;
                    iterator_type<Container> sub_iter_peek;
                    const iterator_type<Container> sub_end;
                    KeyFunc key_func;

                    using KeyGroupPair =
                        std::pair<key_func_ret, Group>;

                public:
                    Iterator (iterator_type<Container> si,
                              iterator_type<Container> end,
                              KeyFunc key_func)
                        : sub_iter{si},
                        sub_end{end},
                        key_func(key_func)
                    { }

                    KeyGroupPair operator*() {
                        return KeyGroupPair(
                                this->key_func(*this->sub_iter),
                                Group(
                                    *this,
                                    this->key_func(*this->sub_iter)));
                    }

                    Iterator& operator++() {
                        return *this;
                    }

                    bool operator!=(const Iterator&) const {
                        return !this->exhausted();
                    }

                    void increment_iterator() {
                        if (this->sub_iter != this->sub_end) {
                            ++this->sub_iter;
                        }
                    }

                    bool exhausted() const {
                        return this->sub_iter == this->sub_end;
                    }

                    iterator_deref<Container> current() {
                        return *this->sub_iter;
                    }

                    key_func_ret next_key() const {
                        return this->key_func(*this->sub_iter);
                    }
            };

            class Group {
                private:
                    friend Iterator;
                    friend class GroupIterator;
                    Iterator& owner;
                    key_func_ret key;

                    // completed is set if a Group is iterated through
                    // completely.  It is checked in the destructor, and
                    // if the Group has not been completed, the destructor
                    // exhausts it.  This ensures that the next Group starts
                    // at the correct position when the user short-circuits
                    // iteration over a Group.
                    // The move constructor sets the rvalue's completed
                    // attribute to true, so its destructor doesn't do anything
                    // when called.
                    mutable bool completed = false;

                    Group(Iterator& owner, key_func_ret key) :
                        owner(owner),
                        key(key)
                    { }

                public:
                    ~Group() {
                        if (!this->completed) {
                            for (auto iter = this->begin(), end = this->end();
                                    iter != end;
                                    ++iter) { }
                        }
                    }

                    // movable, non-copyable
                    Group() = delete;
                    Group(const Group&) = delete;
                    Group& operator=(const Group&) = delete;
                    Group& operator=(Group&&) = delete;

                    Group(Group&& other)
                            : owner{other.owner},
                            key{other.key},
                            completed{other.completed} {
                        other.completed = true;
                    }

                    class GroupIterator
                        : public std::iterator<std::input_iterator_tag,
                                iterator_traits_deref<Container>>
                    {
                        private:
                            const key_func_ret key;
                            const Group& group;

                            bool not_at_end() const {
                                return !this->group.owner.exhausted()&&
                                    this->group.owner.next_key() == this->key;
                            }

                        public:
                            GroupIterator(const Group& group,
                                          key_func_ret key)
                                : key{key},
                                group{group}
                            { }

                            GroupIterator(const GroupIterator&) = default;

                            bool operator!=(const GroupIterator&) const {
                                if (this->not_at_end()) {
                                    return true;
                                } else {
                                    this->group.completed = true;
                                    return false;
                                }
                            }

                            GroupIterator& operator++() {
                                this->group.owner.increment_iterator();
                                return *this;
                            }

                            iterator_deref<Container> operator*() {
                                return this->group.owner.current();
                            }
                    };

                    GroupIterator begin() {
                        return {*this, key};
                    }

                    GroupIterator end() {
                        return {*this, key};
                    }

            };

            Iterator begin() {
                return {std::begin(this->container),
                        std::end(this->container),
                        this->key_func};
            }

            Iterator end() {
                return {std::end(this->container),
                        std::end(this->container),
                        this->key_func};
            }

    };

    // Takes something and returns it, used for default key of comparing
    // items in the sequence directly
    template <typename Container>
    class ItemReturner {
        public:
            ItemReturner() = default;
            iterator_deref<Container> operator() (
                    iterator_deref<Container> item) const {
                return item;
            }
    };

    template <typename Container, typename KeyFunc>
    GroupBy<Container, KeyFunc> groupby(
            Container&& container, KeyFunc key_func) {
        return {std::forward<Container>(container), key_func};
    }

    template <typename Container>
    auto groupby(Container&& container) ->
            decltype(groupby(std::forward<Container>(container),
                        ItemReturner<Container>())) {
        return groupby(std::forward<Container>(container),
                ItemReturner<Container>());
    }

    template <typename T, typename KeyFunc>
    GroupBy<std::initializer_list<T>, KeyFunc> groupby(
            std::initializer_list<T> il, KeyFunc key_func) {
        return {std::move(il), key_func};
    }

    template <typename T>
    auto groupby(std::initializer_list<T> il) ->
            decltype(groupby(std::move(il),
                        ItemReturner<std::initializer_list<T>>())) {
        return groupby(
                std::move(il),
                ItemReturner<std::initializer_list<T>>());
    }

}

#endif //#ifndef GROUP__BY__HPP
<commit_msg>add GroupIterator == and postfix ++<commit_after>#ifndef GROUP__BY__HPP
#define GROUP__BY__HPP

#include "iterbase.hpp"

#include <utility>
#include <iterator>
#include <initializer_list>

namespace iter {

    template <typename Container, typename KeyFunc>
    class GroupBy;

    template <typename Container, typename KeyFunc>
    GroupBy<Container, KeyFunc> groupby(Container&&, KeyFunc);

    template <typename T, typename KeyFunc>
    GroupBy<std::initializer_list<T>, KeyFunc> groupby(
            std::initializer_list<T>, KeyFunc);

    template <typename Container, typename KeyFunc>
    class GroupBy  {
        private:
            Container container;
            KeyFunc key_func;

            friend GroupBy groupby<Container, KeyFunc>(Container&&, KeyFunc);

            template <typename T, typename KF>
            friend GroupBy<std::initializer_list<T>, KF> groupby(
                    std::initializer_list<T>, KF);

            using key_func_ret =
                decltype(std::declval<KeyFunc>()(
                            std::declval<iterator_deref<Container>>()));

            GroupBy(Container container, KeyFunc key_func)
                : container(std::forward<Container>(container)),
                key_func(key_func)
            { }

        public:
            GroupBy() = delete;
            GroupBy(const GroupBy&) = delete;
            GroupBy& operator=(const GroupBy&) = delete;
            GroupBy& operator=(GroupBy&&) = delete;

            GroupBy(GroupBy&&) = default;

            class Iterator;
            class Group;

            class Iterator {
                private:
                    iterator_type<Container> sub_iter;
                    iterator_type<Container> sub_iter_peek;
                    const iterator_type<Container> sub_end;
                    KeyFunc key_func;

                    using KeyGroupPair =
                        std::pair<key_func_ret, Group>;

                public:
                    Iterator (iterator_type<Container> si,
                              iterator_type<Container> end,
                              KeyFunc key_func)
                        : sub_iter{si},
                        sub_end{end},
                        key_func(key_func)
                    { }

                    KeyGroupPair operator*() {
                        return KeyGroupPair(
                                this->key_func(*this->sub_iter),
                                Group(
                                    *this,
                                    this->key_func(*this->sub_iter)));
                    }

                    Iterator& operator++() {
                        return *this;
                    }

                    bool operator!=(const Iterator&) const {
                        return !this->exhausted();
                    }

                    void increment_iterator() {
                        if (this->sub_iter != this->sub_end) {
                            ++this->sub_iter;
                        }
                    }

                    bool exhausted() const {
                        return this->sub_iter == this->sub_end;
                    }

                    iterator_deref<Container> current() {
                        return *this->sub_iter;
                    }

                    key_func_ret next_key() const {
                        return this->key_func(*this->sub_iter);
                    }
            };

            class Group {
                private:
                    friend Iterator;
                    friend class GroupIterator;
                    Iterator& owner;
                    key_func_ret key;

                    // completed is set if a Group is iterated through
                    // completely.  It is checked in the destructor, and
                    // if the Group has not been completed, the destructor
                    // exhausts it.  This ensures that the next Group starts
                    // at the correct position when the user short-circuits
                    // iteration over a Group.
                    // The move constructor sets the rvalue's completed
                    // attribute to true, so its destructor doesn't do anything
                    // when called.
                    mutable bool completed = false;

                    Group(Iterator& owner, key_func_ret key) :
                        owner(owner),
                        key(key)
                    { }

                public:
                    ~Group() {
                        if (!this->completed) {
                            for (auto iter = this->begin(), end = this->end();
                                    iter != end;
                                    ++iter) { }
                        }
                    }

                    // movable, non-copyable
                    Group() = delete;
                    Group(const Group&) = delete;
                    Group& operator=(const Group&) = delete;
                    Group& operator=(Group&&) = delete;

                    Group(Group&& other)
                            : owner{other.owner},
                            key{other.key},
                            completed{other.completed} {
                        other.completed = true;
                    }

                    class GroupIterator
                        : public std::iterator<std::input_iterator_tag,
                                iterator_traits_deref<Container>>
                    {
                        private:
                            const key_func_ret key;
                            const Group& group;

                            bool not_at_end() const {
                                return !this->group.owner.exhausted()&&
                                    this->group.owner.next_key() == this->key;
                            }

                        public:
                            GroupIterator(const Group& group,
                                          key_func_ret key)
                                : key{key},
                                group{group}
                            { }

                            GroupIterator(const GroupIterator&) = default;

                            bool operator!=(const GroupIterator&) const {
                                if (this->not_at_end()) {
                                    return true;
                                } else {
                                    this->group.completed = true;
                                    return false;
                                }
                            }

                            bool operator==(const GroupIterator& other) const {
                                return !(*this != other);
                            }

                            GroupIterator& operator++() {
                                this->group.owner.increment_iterator();
                                return *this;
                            }

                            GroupIterator operator++(int) {
                                auto ret = *this;
                                ++*this;
                                return ret;
                            }

                            iterator_deref<Container> operator*() {
                                return this->group.owner.current();
                            }
                    };

                    GroupIterator begin() {
                        return {*this, key};
                    }

                    GroupIterator end() {
                        return {*this, key};
                    }

            };

            Iterator begin() {
                return {std::begin(this->container),
                        std::end(this->container),
                        this->key_func};
            }

            Iterator end() {
                return {std::end(this->container),
                        std::end(this->container),
                        this->key_func};
            }

    };

    // Takes something and returns it, used for default key of comparing
    // items in the sequence directly
    template <typename Container>
    class ItemReturner {
        public:
            ItemReturner() = default;
            iterator_deref<Container> operator() (
                    iterator_deref<Container> item) const {
                return item;
            }
    };

    template <typename Container, typename KeyFunc>
    GroupBy<Container, KeyFunc> groupby(
            Container&& container, KeyFunc key_func) {
        return {std::forward<Container>(container), key_func};
    }

    template <typename Container>
    auto groupby(Container&& container) ->
            decltype(groupby(std::forward<Container>(container),
                        ItemReturner<Container>())) {
        return groupby(std::forward<Container>(container),
                ItemReturner<Container>());
    }

    template <typename T, typename KeyFunc>
    GroupBy<std::initializer_list<T>, KeyFunc> groupby(
            std::initializer_list<T> il, KeyFunc key_func) {
        return {std::move(il), key_func};
    }

    template <typename T>
    auto groupby(std::initializer_list<T> il) ->
            decltype(groupby(std::move(il),
                        ItemReturner<std::initializer_list<T>>())) {
        return groupby(
                std::move(il),
                ItemReturner<std::initializer_list<T>>());
    }

}

#endif //#ifndef GROUP__BY__HPP
<|endoftext|>


<commit_before>#ifndef TIMER_HPP_
#define TIMER_HPP_

#include <QObject>
#include <bb/cascades/CustomControl>

class QTimer;

class Timer : public bb::cascades::CustomControl
{
    Q_OBJECT

    Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
    Q_PROPERTY(int interval READ interval WRITE setInterval
               NOTIFY intervalChanged)

public:
    explicit Timer(QObject* parent = 0);

    bool isActive();
    void setInterval(int m_sec);
    int interval();

public slots:
    void start();
    void stop();

signals:
	void timeout();
	void intervalChanged();
	void activeChanged();

private:
    QTimer* _timer;
};

#endif /* TIMER_HPP_ */
<commit_msg>... comments<commit_after>#ifndef TIMER_HPP_
#define TIMER_HPP_

#include <QObject>
#include <bb/cascades/CustomControl>

class QTimer;

class Timer : public bb::cascades::CustomControl
{
    Q_OBJECT

    Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
    Q_PROPERTY(int interval READ interval WRITE setInterval
               NOTIFY intervalChanged)

public:
    explicit Timer(QObject* parent = 0);

    bool isActive();
    void setInterval(int m_sec);
    int interval();

public slots:
    void start();
    void stop();

signals:
	void timeout();
	void intervalChanged();
	void activeChanged();

private:
    QTimer* _timer;
};

#endif /* TIMER_HPP_ */
<|endoftext|>


<commit_before>#include <iostream>
#include "tools.h"

using Eigen::VectorXd;
using Eigen::MatrixXd;
using std::vector;

Tools::Tools() {}

Tools::~Tools() {}

VectorXd Tools::CalculateRMSE(const vector<VectorXd> &estimations,
                              const vector<VectorXd> &ground_truth) {
  /**
  TODO:
    * Calculate the RMSE here.
  */
}

MatrixXd Tools::CalculateJacobian(const VectorXd& x_state) {
  /**
  TODO:
    * Calculate a Jacobian here.
  */
}
<commit_msg>refactor: Added method definitions<commit_after>#include <iostream>
#include "tools.h"

using Eigen::VectorXd;
using Eigen::MatrixXd;
using std::vector;

Tools::Tools() {}

Tools::~Tools() {}

VectorXd Tools::CalculateRMSE(const vector<VectorXd> &estimations,
                              const vector<VectorXd> &ground_truth) {
  VectorXd rmse(4);
  rmse << 0, 0, 0, 0;

  // check the validity of the following inputs:
  //  * the estimation vector size should not be zero
  //  * the estimation vector size should equal ground truth vector size
  if(estimations.size() == 0 || estimations.size() != ground_truth.size()) {
    std::cout << "calculateRMSE() - Error - Invalid Estimations vector size" << std::endl;
    return rmse;
  }

  //accumulate squared residuals
  VectorXd sum(4);
  sum << 0, 0, 0, 0;

  for(int i = 0; i < estimations.size(); ++i) {
    VectorXd estimated = estimations[i];
    VectorXd actual = ground_truth[i];

    VectorXd diff = (estimated - actual);
    //coefficient-wise multiplication
    diff = diff.array() * diff.array();
    sum = sum + diff;
  }

  //calculate the mean
  Eigen::VectorXd mean = sum / estimations.size();

  //calculate the squared root
  rmse = mean.array().sqrt();

  return rmse;
}

MatrixXd Tools::CalculateJacobian(const VectorXd& x_state) {
  Eigen::MatrixXd Hj(3, 4);

  //state parameters
  float px = x_state(0);
  float py = x_state(1);
  float vx = x_state(2);
  float vy = x_state(3);

  //divsion by zero check
  if(px == 0 || py == 0 ) {
    std::cout << "calculateJacobian() - Error - Division by zero";
    return Hj;
  }

  // calculating common values used in Jacobian
  float px2 = px * px;
  float py2 = py * py;
  float px2_py2_sum = px2 + py2;
  float px2_py2_sqrt = sqrt(px2_py2_sum);
  float px2_py2_sum_3_by_2 = pow((px2_py2_sum), 3/2.0);

  if(fabs(px2_py2_sum) < 0.0001) {
    std::cout << "calculateJacobian() - Error - Division by zero";
    return Hj;
  }

  // calculating and inserting jacobian values
  Hj << (px / px2_py2_sqrt), (py / px2_py2_sqrt), 0, 0,
      (-py / px2_py2_sum), (px / px2_py2_sum), 0, 0,
      ((py * (vx * py - vy * px)) / px2_py2_sum_3_by_2), ((px * (vy * px - vx * py)) / px2_py2_sum_3_by_2), (px / px2_py2_sqrt), (py / px2_py2_sqrt);

  return Hj;
}
<|endoftext|>


<commit_before>#ifndef VOLE_VALUE
#define VOLE_VALUE

#include "slice.hpp"

namespace Vole {

  struct Value;
  using String = Slice<char>;
  using Vector = Slice<Value>;

  struct Value {
    enum Type {
      BOOLEAN,
      NUMBER,
      // SYMBOL,
      STRING,
      // REGEXP,
      VECTOR,
      // MAPPING
    } type;

    // for garbage collection
    enum Color {
      BLACK,
      GRAY,
      WHITE
    } color;

    union Content {
      bool    boolean;
      double  number;
      // wrapper around a String, every symbol with a name is unique
      // Symbol  symbol;
      String  string;
      // Regexp regexp;
      Vector  vector;
      // Mapping mapping;

      Content()                       { }
      Content(bool b)    : boolean(b) { }
      Content(double d)  : number(d)  { }
      // Content(Symbol s)  { new (&symbol) Symbol(s); }
      Content(String s)  : string(s)  { }
      Content(Vector v)  : vector(v)  { }
      // Content(Mapping m) { new (&mapping) Mapping(m); }
    } content;

    Value() { }

    template <typename T>
    Value(T thing, Color c = BLACK);

    template <typename IOS>
    IOS& serialize(IOS& ios);

    operator std::string();
  };

  template <>
  Value::Value(bool b, Color c)
  : type(BOOLEAN), color(c), content(b)
  { }

  template <>
  Value::Value(double d, Color c)
  : type(NUMBER), color(c), content(d)
  { }

  template <>
  Value::Value(String s, Color c)
  : type(STRING), color(c), content(s)
  { }

  template <>
  Value::Value(Vector v, Color c)
  : type(VECTOR), color(c), content(v)
  { }

  template <typename IOS>
  IOS& Value::serialize(IOS& ios) {
    switch (type) {
      case BOOLEAN: {
        ios << (content.boolean ? "#t" : "#f");
      } break;
      case NUMBER: {
        ios << content.number;
      } break;
      case STRING: {
        ios << content.string;
      } break;
      case VECTOR: {
        ios << content.vector;
      } break;
    }
    return ios;
  }

  template <typename IOS>
  IOS& operator<<(IOS& ios, Value val) {
    return val.serialize(ios);
  }

  Value::operator std::string() {
    std::stringstream ss;
    serialize(ss);
    return ss.str();
  }

}

#endif<commit_msg>removing some commented code<commit_after>#ifndef VOLE_VALUE
#define VOLE_VALUE

#include "slice.hpp"

namespace Vole {

  struct Value;
  using String = Slice<char>;
  using Vector = Slice<Value>;

  struct Value {
    enum Type {
      BOOLEAN,
      NUMBER,
      // SYMBOL,
      STRING,
      // REGEXP,
      VECTOR,
      // MAPPING
    } type;

    // for garbage collection
    enum Color {
      BLACK,
      GRAY,
      WHITE
    } color;

    union Content {
      bool    boolean;
      double  number;
      // wrapper around a String, every symbol with a name is unique
      // Symbol  symbol;
      String  string;
      // Regexp regexp;
      Vector  vector;
      // Mapping mapping;

      Content()                       { }
      Content(bool b)    : boolean(b) { }
      Content(double d)  : number(d)  { }
      Content(String s)  : string(s)  { }
      Content(Vector v)  : vector(v)  { }
    } content;

    Value() { }

    template <typename T>
    Value(T thing, Color c = BLACK);

    template <typename IOS>
    IOS& serialize(IOS& ios);

    operator std::string();
  };

  template <>
  Value::Value(bool b, Color c)
  : type(BOOLEAN), color(c), content(b)
  { }

  template <>
  Value::Value(double d, Color c)
  : type(NUMBER), color(c), content(d)
  { }

  template <>
  Value::Value(String s, Color c)
  : type(STRING), color(c), content(s)
  { }

  template <>
  Value::Value(Vector v, Color c)
  : type(VECTOR), color(c), content(v)
  { }

  template <typename IOS>
  IOS& Value::serialize(IOS& ios) {
    switch (type) {
      case BOOLEAN: {
        ios << (content.boolean ? "#t" : "#f");
      } break;
      case NUMBER: {
        ios << content.number;
      } break;
      case STRING: {
        ios << content.string;
      } break;
      case VECTOR: {
        ios << content.vector;
      } break;
    }
    return ios;
  }

  template <typename IOS>
  IOS& operator<<(IOS& ios, Value val) {
    return val.serialize(ios);
  }

  Value::operator std::string() {
    std::stringstream ss;
    serialize(ss);
    return ss.str();
  }

}

#endif<|endoftext|>


<commit_before>// viewer - shows the current results of the ray tracer..

#include <GL/glut.h>
#include <cstdio>
#include <cstdlib>
#ifdef _WIN32
# include <windows.h>
#else
# include <sys/time.h>
#endif

#include "RayTracer.h"

#define VIEWING_DISTANCE_MIN  0.1
#define TEXTURE_ID_SQUARE 1
enum {
  MENU_LIGHTING = 1,
  MENU_POLYMODE,
  MENU_TEXTURING,
  MENU_EXIT
};
typedef int BOOL;
#define TRUE 1
#define FALSE 0
static BOOL g_bButton1Down = FALSE;
static BOOL g_bButton2Down = FALSE;
static int g_Width = 600;                          // Initial window width
static int g_Height = 600;                         // Initial window height
static int g_xClick = 0;
static int g_yClick = 0;
static int g_zClick = 0;
#ifdef _WIN32
static DWORD last_idle_time;
#else
static struct timeval last_idle_time;
#endif

RayTracer * g_rayTracer = 0;
int g_patienceValue = 0;
// in space of ray tracer
vector3d g_eye(-5,-5,-5);
vector3d g_lookat(0,0,0);
vector3d g_nup(0,0,1);
double g_theta = 55;
double g_aspectRatio=1;
std::string g_nrrd_fn;
std::string g_cmap_fn;
float g_curvThick;
bool g_normFlipped;

void DrawSquare(float x, float y) {
  glBegin(GL_QUADS);
  glVertex2f(0, 0);    glTexCoord2f (0, 0);
  glVertex2f(0, y);     glTexCoord2f (0, 1);
  glVertex2f(x, y);      glTexCoord2f (1, 1);
  glVertex2f(x, 0);     glTexCoord2f (1, 0);
  glEnd();
}
void RenderObjects(void)
{
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  // draw single quad with the texture overlaid
  glBindTexture(GL_TEXTURE_2D, TEXTURE_ID_SQUARE);
  DrawSquare(g_Width,g_Height);
}
void display(void)
{
   // Clear frame buffer and depth buffer
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   // Set up viewing transformation - identity
   glLoadIdentity();
   // make sure lighting disabled
   glDisable(GL_LIGHTING);
   glEnable(GL_TEXTURE_2D);
   // Render the scene
   RenderObjects();
   // Make sure changes appear onscreen
   glutSwapBuffers();
}

void showResult()
{
  glBindTexture(GL_TEXTURE_2D, TEXTURE_ID_SQUARE);
  gluBuild2DMipmaps(GL_TEXTURE_2D,            // texture to specify
                    GL_RGBA,                  // internal texture storage format
                    g_rayTracer->getWidth(),  // texture width
                    g_rayTracer->getHeight(), // texture height
                    GL_RGBA,                  // pixel format
                    GL_UNSIGNED_BYTE,         // color component format
                    g_rayTracer->getBuffer());// pointer to texture image
  glutPostRedisplay();
}

void showProgress(int value)
{
  // TODO: may be able to do this automatically by removing swap buffer?
  //std::cerr << "showProgres()" << std::endl;
  showResult();
  if(g_rayTracer->getState() == RayTracer::RENDER)
  {
    glutTimerFunc(500, showProgress, 0); // call again, until state changes..
  }
}

// to prevent multiple unnecessary renderings:
void patience(int value)
{
  if( value == g_patienceValue ) // if this is the last call to render..
  {
    g_rayTracer->restartRender();
    g_patienceValue = 0;

    glutTimerFunc(500, showProgress, 0);
  }
}

// what to do when ray tracer is done rendering...
void doneRendering()
{
  std::cerr << "done rendering." << std::endl;
  showResult();
}
void reshape(GLint width, GLint height)
{
   g_Width = width;
   g_Height = height;
   glViewport(0, 0, g_Width, g_Height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.f, g_Width, g_Height, 0.f, 0.f, 1.f);
   glMatrixMode(GL_MODELVIEW);

   //if( g_rayTracer->getWidth() != g_Width || g_rayTracer->getHeight() != g_Height )
   //{
   //  g_rayTracer->setSize(g_Width,g_Height);
   //  glutTimerFunc(100, patience, ++g_patienceValue);
   //}
}
unsigned char *  makeTexture(int width, int height)
{
   if( !g_rayTracer )
   {
     g_rayTracer = new RayTracer(width,height);
     g_rayTracer->setDoneRenderingCB( & doneRendering );
     g_rayTracer->makeScene( g_nrrd_fn, g_cmap_fn, g_curvThick, g_normFlipped );
   }
   if( !(g_rayTracer->getWidth() == width && g_rayTracer->getHeight() == height) )
   {
     g_rayTracer->setSize(width,height);
   }

   g_rayTracer->restartRender();
   return g_rayTracer->getBuffer();
#if 0
   unsigned char * pCircle = new unsigned char[ width * height * 4 ];
   // make a texture image...
   for(size_t r=0; r<width; ++r)
   {
     for(size_t c=0; c<height; ++c)
     {
       size_t x_pos = 100;
       size_t y_pos = 100;
       size_t radius = 30;
       unsigned char red = static_cast<unsigned char>(0);
       unsigned char green = static_cast<unsigned char>(0);
       unsigned char blue = static_cast<unsigned char>(0);
       unsigned char alpha = static_cast<unsigned char>(255);
       if( (r-x_pos)*(r-x_pos) + (c-y_pos)*(c-y_pos) <= radius*radius )
       {
         red = (unsigned char) 255;
       }
       else
       {
         green = (unsigned char) 255;
       }
       pCircle[r*height*4+c*4+0] = red;
       pCircle[r*height*4+c*4+1] = green;
       pCircle[r*height*4+c*4+2] = blue;
       pCircle[r*height*4+c*4+3] = alpha;
     }
   }
   return pCircle;
#endif
}
void InitGraphics(void)
{
   int width, height;
   int nComponents;
   void* pTextureImage;
   width = g_Width;
   height = g_Height;
   pTextureImage = makeTexture(width, height);
   glBindTexture(GL_TEXTURE_2D, TEXTURE_ID_SQUARE);

   int tWidth = 1;
   int tHeight = 1;
   while (tWidth < width)
     tWidth <<= 1;
   while (tHeight < width)
     tHeight <<= 1;

/*
   glTexImage2D(GL_TEXTURE_2D,     // texture to specify
                0,                 // texture level
                GL_RGBA,           // internal texture storage format
                tWidth,             // texture width
                tHeight,            // texture height
                0,                 // texture border
                GL_RGBA,           // pixel format
                GL_UNSIGNED_BYTE,  // color component format
                0);                // pointer to texture image

   glTexSubImage2D(GL_TEXTURE_2D,
                   0,
                   0,
                   0,
                   width,
                   height,
                   GL_RGBA,
                   GL_UNSIGNED_BYTE,
                   pTextureImage);
*/

   gluBuild2DMipmaps(GL_TEXTURE_2D,     // texture to specify
                     GL_RGBA,           // internal texture storage format
                     width,             // texture width
                     height,            // texture height
                     GL_RGBA,           // pixel format
                     GL_UNSIGNED_BYTE,  // color component format
                     pTextureImage);    // pointer to texture image
}

void updateCameraDistance(float change_pct)
{
  vector3d direction = g_eye-g_lookat;
  ray to_eye( g_lookat, direction );
  g_eye = to_eye.eval(change_pct);
}

void rotateCamera(float pct_x, float pct_y)
{
  vector3d direction = g_eye-g_lookat;

  // "left/right" rotation:
  hpoint dir(direction,1);
  dir = makeRotateMatrix( pct_x * M_PI/4, g_nup.x(), g_nup.y(), g_nup.z() ) * dir;

  // "up/down" rotation:
  //hpoint nup(g_nup,1);
  //vector3d left = cross( direction, g_nup );
  //left.MakeUnitVector();
  //std::cerr << "left: " << left << std::endl;
  //matrix rotate = makeRotateMatrix( pct_y * M_PI/4 , left.x(), left.y(), left.z() );

  //dir = rotate * dir;
  //nup = rotate * nup;

  direction = dir.tovector3d();

  // hack - use translation to fake movement in z..
  float dist = direction.length();
  direction += g_nup * dist * pct_y;

  //g_nup = nup.tovector3d();
  //g_nup.MakeUnitVector(); // make sure it's still unit length

  ray to_eye( g_lookat, direction );
  g_eye = to_eye.eval(1.f);
}

void syncCamera()
{
  PinholeCamera * ph = dynamic_cast<PinholeCamera*>(g_rayTracer->getScene()->camera);
  if(ph)
  {
    std::cerr << "new eye:" << g_eye << std::endl;
    ph->initialize(g_eye,g_lookat,g_nup,g_theta,g_aspectRatio);
    glutTimerFunc(500, patience, ++g_patienceValue);
  }
  // else - do nothing
}

void MouseButton(int button, int state, int x, int y)
{
  // Respond to mouse button presses.
  // If button1 pressed, mark this state so we know in motion function.
  if (button == GLUT_LEFT_BUTTON)
    {
      g_bButton1Down = (state == GLUT_DOWN) ? TRUE : FALSE;
      g_xClick = x;
      g_yClick = y;
    }
  else if (button == GLUT_RIGHT_BUTTON)
    {
      g_bButton2Down = (state == GLUT_DOWN) ? TRUE : FALSE;
      g_zClick = y;
    }

}
void MouseMotion(int x, int y)
{
  // If button1 pressed, zoom in/out if mouse is moved up/down.
  if (g_bButton1Down)
  {
    float change_x = -(x - g_xClick) / 3.0;
    float pct_x = change_x/g_rayTracer->getWidth();
    float change_y = (y - g_yClick) / 3.0;
    float pct_y = change_y/g_rayTracer->getHeight();
    rotateCamera(pct_x,pct_y);
    syncCamera();
    //glutPostRedisplay();
  }
  else if (g_bButton2Down)
  {
    float distance_change = (y - g_zClick);
    float pct = 1-distance_change/g_rayTracer->getHeight();
    updateCameraDistance(pct);
    syncCamera();
    //glutPostRedisplay();
  }
}

void SelectFromMenu(int idCommand)
{
  switch (idCommand)
    {
    //case MENU_LIGHTING:
    //  g_bLightingEnabled = !g_bLightingEnabled;
    //  if (g_bLightingEnabled)
    //     glEnable(GL_LIGHTING);
    //  else
    //     glDisable(GL_LIGHTING);
    //  break;
    //case MENU_POLYMODE:
    //  g_bFillPolygons = !g_bFillPolygons;
    //  glPolygonMode (GL_FRONT_AND_BACK, g_bFillPolygons ? GL_FILL : GL_LINE);
    //  break;
    //case MENU_TEXTURING:
    //  g_bTexture = !g_bTexture;
    //  if (g_bTexture)
    //     glEnable(GL_TEXTURE_2D);
    //  else
    //     glDisable(GL_TEXTURE_2D);
    //  break;
    case MENU_EXIT:
      exit (0);
      break;
    }
  // Almost any menu selection requires a redraw
  glutPostRedisplay();
}
void Keyboard(unsigned char key, int x, int y)
{
  static const float STEP_SIZE = 1.0;
  vector3d right = cross(g_nup,(g_lookat-g_eye).MakeUnitVector());
  switch (key)
  {
  case 27:             // ESCAPE key
    exit (0);
    break;
  //case 'l':
  //  SelectFromMenu(MENU_LIGHTING);
  //  break;
  case 'p':
    SelectFromMenu(MENU_POLYMODE);
    break;
  case 't':
    SelectFromMenu(MENU_TEXTURING);
  case 'j': // down
    g_eye -= (g_nup * STEP_SIZE);
    g_lookat -= (g_nup * STEP_SIZE);
    syncCamera();
    break;
  case 'k': // up
    g_eye += (g_nup * STEP_SIZE);
    g_lookat += (g_nup * STEP_SIZE);
    syncCamera();
    break;
  case 'l': // right
    g_eye += (right * STEP_SIZE);
    g_lookat += (right * STEP_SIZE);
    syncCamera();
    break;
  case 'h': // left
    g_eye -= (right * STEP_SIZE);
    g_lookat -= (right * STEP_SIZE);
    syncCamera();
    break;
  }
}
int BuildPopupMenu (void)
{
  int menu;
  menu = glutCreateMenu (SelectFromMenu);
  glutAddMenuEntry ("Toggle lighting\tl", MENU_LIGHTING);
  glutAddMenuEntry ("Toggle polygon fill\tp", MENU_POLYMODE);
  glutAddMenuEntry ("Toggle texturing\tt", MENU_TEXTURING);
  glutAddMenuEntry ("Exit demo\tEsc", MENU_EXIT);
  return menu;
}
void idleFunction()
{
  g_rayTracer->checkProgress();
}
int main(int argc, char** argv)
{

  if( argc < 2 )
  {
    std::cerr << "usage: " << argv[0] << " <nrrd_fn> <cmap_fn> <curv-thickness> <norm-flipped>" << std::endl;
    exit(1);
  }

  g_nrrd_fn = argv[1];
  g_cmap_fn = argv[2];
  g_curvThick = atof(argv[3]);
  g_normFlipped = atoi(argv[4]) != 0;

  // GLUT Window Initialization:
  glutInit (&argc, argv);
  glutInitWindowPosition( 50, 50 );
  glutInitWindowSize (g_Width, g_Height);
  glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutCreateWindow ("rt");
  // Initialize OpenGL graphics state
  InitGraphics();
  // Register callbacks:
  glutDisplayFunc (display);
  glutReshapeFunc (reshape);
  glutKeyboardFunc (Keyboard);
  glutMouseFunc (MouseButton);
  glutMotionFunc (MouseMotion);
  glutIdleFunc (idleFunction);
  // Create our popup menu
  //BuildPopupMenu ();
  //glutAttachMenu (GLUT_RIGHT_BUTTON);
  // Get the initial time, for use by animation
#ifdef _WIN32
  last_idle_time = GetTickCount();
#else
  gettimeofday (&last_idle_time, NULL);
#endif
  // Turn the flow of control over to GLUT
  glutMainLoop ();
  return 0;
}

<commit_msg>added automatic view spin for screen capture<commit_after>// viewer - shows the current results of the ray tracer..

#include <GL/glut.h>
#include <cstdio>
#include <cstdlib>
#ifdef _WIN32
# include <windows.h>
#else
# include <sys/time.h>
#endif

#include "RayTracer.h"

#define VIEWING_DISTANCE_MIN  0.1
#define TEXTURE_ID_SQUARE 1
enum {
  MENU_LIGHTING = 1,
  MENU_POLYMODE,
  MENU_TEXTURING,
  MENU_EXIT
};
typedef int BOOL;
#define TRUE 1
#define FALSE 0
static BOOL g_bButton1Down = FALSE;
static BOOL g_bButton2Down = FALSE;
static int g_Width = 600;                          // Initial window width
static int g_Height = 600;                         // Initial window height
static int g_xClick = 0;
static int g_yClick = 0;
static int g_zClick = 0;
#ifdef _WIN32
static DWORD last_idle_time;
#else
static struct timeval last_idle_time;
#endif

RayTracer * g_rayTracer = 0;
int g_patienceValue = 0;
// in space of ray tracer
vector3d g_eye(-5,-5,-5);
vector3d g_lookat(0,0,0);
vector3d g_nup(0,0,1);
double g_theta = 55;
double g_aspectRatio=1;
std::string g_nrrd_fn;
std::string g_cmap_fn;
float g_curvThick;
bool g_normFlipped;
// auto mode:
bool g_automode = false;

void DrawSquare(float x, float y) {
  glBegin(GL_QUADS);
  glVertex2f(0, 0);    glTexCoord2f (0, 0);
  glVertex2f(0, y);     glTexCoord2f (0, 1);
  glVertex2f(x, y);      glTexCoord2f (1, 1);
  glVertex2f(x, 0);     glTexCoord2f (1, 0);
  glEnd();
}
void RenderObjects(void)
{
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  // draw single quad with the texture overlaid
  glBindTexture(GL_TEXTURE_2D, TEXTURE_ID_SQUARE);
  DrawSquare(g_Width,g_Height);
}
void display(void)
{
   // Clear frame buffer and depth buffer
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   // Set up viewing transformation - identity
   glLoadIdentity();
   // make sure lighting disabled
   glDisable(GL_LIGHTING);
   glEnable(GL_TEXTURE_2D);
   // Render the scene
   RenderObjects();
   // Make sure changes appear onscreen
   glutSwapBuffers();
}

void showResult()
{
  glBindTexture(GL_TEXTURE_2D, TEXTURE_ID_SQUARE);
  gluBuild2DMipmaps(GL_TEXTURE_2D,            // texture to specify
                    GL_RGBA,                  // internal texture storage format
                    g_rayTracer->getWidth(),  // texture width
                    g_rayTracer->getHeight(), // texture height
                    GL_RGBA,                  // pixel format
                    GL_UNSIGNED_BYTE,         // color component format
                    g_rayTracer->getBuffer());// pointer to texture image
  glutPostRedisplay();
}

void showProgress(int value)
{
  // TODO: may be able to do this automatically by removing swap buffer?
  //std::cerr << "showProgres()" << std::endl;
  showResult();
  if(g_rayTracer->getState() == RayTracer::RENDER)
  {
    glutTimerFunc(500, showProgress, 0); // call again, until state changes..
  }
}

// to prevent multiple unnecessary renderings:
void patience(int value)
{
  if( value == g_patienceValue ) // if this is the last call to render..
  {
    g_rayTracer->restartRender();
    g_patienceValue = 0;

    glutTimerFunc(500, showProgress, 0);
  }
}

// what to do when ray tracer is done rendering...
void doneRendering()
{
  std::cerr << "done rendering." << std::endl;
  showResult();
}
void reshape(GLint width, GLint height)
{
   g_Width = width;
   g_Height = height;
   glViewport(0, 0, g_Width, g_Height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.f, g_Width, g_Height, 0.f, 0.f, 1.f);
   glMatrixMode(GL_MODELVIEW);

   //if( g_rayTracer->getWidth() != g_Width || g_rayTracer->getHeight() != g_Height )
   //{
   //  g_rayTracer->setSize(g_Width,g_Height);
   //  glutTimerFunc(100, patience, ++g_patienceValue);
   //}
}
unsigned char *  makeTexture(int width, int height)
{
   if( !g_rayTracer )
   {
     g_rayTracer = new RayTracer(width,height);
     g_rayTracer->setDoneRenderingCB( & doneRendering );
     g_rayTracer->makeScene( g_nrrd_fn, g_cmap_fn, g_curvThick, g_normFlipped );
   }
   if( !(g_rayTracer->getWidth() == width && g_rayTracer->getHeight() == height) )
   {
     g_rayTracer->setSize(width,height);
   }

   g_rayTracer->restartRender();
   return g_rayTracer->getBuffer();
#if 0
   unsigned char * pCircle = new unsigned char[ width * height * 4 ];
   // make a texture image...
   for(size_t r=0; r<width; ++r)
   {
     for(size_t c=0; c<height; ++c)
     {
       size_t x_pos = 100;
       size_t y_pos = 100;
       size_t radius = 30;
       unsigned char red = static_cast<unsigned char>(0);
       unsigned char green = static_cast<unsigned char>(0);
       unsigned char blue = static_cast<unsigned char>(0);
       unsigned char alpha = static_cast<unsigned char>(255);
       if( (r-x_pos)*(r-x_pos) + (c-y_pos)*(c-y_pos) <= radius*radius )
       {
         red = (unsigned char) 255;
       }
       else
       {
         green = (unsigned char) 255;
       }
       pCircle[r*height*4+c*4+0] = red;
       pCircle[r*height*4+c*4+1] = green;
       pCircle[r*height*4+c*4+2] = blue;
       pCircle[r*height*4+c*4+3] = alpha;
     }
   }
   return pCircle;
#endif
}
void InitGraphics(void)
{
   int width, height;
   int nComponents;
   void* pTextureImage;
   width = g_Width;
   height = g_Height;
   pTextureImage = makeTexture(width, height);
   glBindTexture(GL_TEXTURE_2D, TEXTURE_ID_SQUARE);

   int tWidth = 1;
   int tHeight = 1;
   while (tWidth < width)
     tWidth <<= 1;
   while (tHeight < width)
     tHeight <<= 1;

/*
   glTexImage2D(GL_TEXTURE_2D,     // texture to specify
                0,                 // texture level
                GL_RGBA,           // internal texture storage format
                tWidth,             // texture width
                tHeight,            // texture height
                0,                 // texture border
                GL_RGBA,           // pixel format
                GL_UNSIGNED_BYTE,  // color component format
                0);                // pointer to texture image

   glTexSubImage2D(GL_TEXTURE_2D,
                   0,
                   0,
                   0,
                   width,
                   height,
                   GL_RGBA,
                   GL_UNSIGNED_BYTE,
                   pTextureImage);
*/

   gluBuild2DMipmaps(GL_TEXTURE_2D,     // texture to specify
                     GL_RGBA,           // internal texture storage format
                     width,             // texture width
                     height,            // texture height
                     GL_RGBA,           // pixel format
                     GL_UNSIGNED_BYTE,  // color component format
                     pTextureImage);    // pointer to texture image
}

void updateCameraDistance(float change_pct)
{
  vector3d direction = g_eye-g_lookat;
  ray to_eye( g_lookat, direction );
  g_eye = to_eye.eval(change_pct);
}

void rotateCamera(float pct_x, float pct_y)
{
  vector3d direction = g_eye-g_lookat;

  // "left/right" rotation:
  hpoint dir(direction,1);
  dir = makeRotateMatrix( pct_x * M_PI/4, g_nup.x(), g_nup.y(), g_nup.z() ) * dir;

  // "up/down" rotation:
  //hpoint nup(g_nup,1);
  //vector3d left = cross( direction, g_nup );
  //left.MakeUnitVector();
  //std::cerr << "left: " << left << std::endl;
  //matrix rotate = makeRotateMatrix( pct_y * M_PI/4 , left.x(), left.y(), left.z() );

  //dir = rotate * dir;
  //nup = rotate * nup;

  direction = dir.tovector3d();

  // hack - use translation to fake movement in z..
  float dist = direction.length();
  direction += g_nup * dist * pct_y;

  //g_nup = nup.tovector3d();
  //g_nup.MakeUnitVector(); // make sure it's still unit length

  ray to_eye( g_lookat, direction );
  g_eye = to_eye.eval(1.f);
}

void syncCamera()
{
  PinholeCamera * ph = dynamic_cast<PinholeCamera*>(g_rayTracer->getScene()->camera);
  if(ph)
  {
    std::cerr << "new eye:" << g_eye << std::endl;
    ph->initialize(g_eye,g_lookat,g_nup,g_theta,g_aspectRatio);
    glutTimerFunc(500, patience, ++g_patienceValue);
  }
  // else - do nothing
}

void updateAutomatic(int value)
{
  if( g_automode )
  {
    if(g_rayTracer->getState() == RayTracer::DONE)
    {
      rotateCamera( 0.5, 0 );
      syncCamera();
    }

    // try again in 4 seconds..
    glutTimerFunc(4000, updateAutomatic, 0);
  }
}

void runAutomatic()
{
  if(g_automode)
  {
    // position initial camera position:
    g_eye = Point(-2, -2, -0.5);
    g_lookat = Point(0.5,0, 0.8);
    g_nup = Vector(0, 0, 1);
    syncCamera();

    // start regular intervals of camera rotation:
    glutTimerFunc(4000, updateAutomatic, 0);
  }
}

void MouseButton(int button, int state, int x, int y)
{
  // Respond to mouse button presses.
  // If button1 pressed, mark this state so we know in motion function.
  if (button == GLUT_LEFT_BUTTON)
    {
      g_bButton1Down = (state == GLUT_DOWN) ? TRUE : FALSE;
      g_xClick = x;
      g_yClick = y;
    }
  else if (button == GLUT_RIGHT_BUTTON)
    {
      g_bButton2Down = (state == GLUT_DOWN) ? TRUE : FALSE;
      g_zClick = y;
    }

}
void MouseMotion(int x, int y)
{
  // If button1 pressed, zoom in/out if mouse is moved up/down.
  if (g_bButton1Down)
  {
    float change_x = -(x - g_xClick) / 3.0;
    float pct_x = change_x/g_rayTracer->getWidth();
    float change_y = (y - g_yClick) / 3.0;
    float pct_y = change_y/g_rayTracer->getHeight();
    rotateCamera(pct_x,pct_y);
    syncCamera();
    //glutPostRedisplay();
  }
  else if (g_bButton2Down)
  {
    float distance_change = (y - g_zClick);
    float pct = 1-distance_change/g_rayTracer->getHeight();
    updateCameraDistance(pct);
    syncCamera();
    //glutPostRedisplay();
  }
}

void SelectFromMenu(int idCommand)
{
  switch (idCommand)
    {
    //case MENU_LIGHTING:
    //  g_bLightingEnabled = !g_bLightingEnabled;
    //  if (g_bLightingEnabled)
    //     glEnable(GL_LIGHTING);
    //  else
    //     glDisable(GL_LIGHTING);
    //  break;
    //case MENU_POLYMODE:
    //  g_bFillPolygons = !g_bFillPolygons;
    //  glPolygonMode (GL_FRONT_AND_BACK, g_bFillPolygons ? GL_FILL : GL_LINE);
    //  break;
    //case MENU_TEXTURING:
    //  g_bTexture = !g_bTexture;
    //  if (g_bTexture)
    //     glEnable(GL_TEXTURE_2D);
    //  else
    //     glDisable(GL_TEXTURE_2D);
    //  break;
    case MENU_EXIT:
      exit (0);
      break;
    }
  // Almost any menu selection requires a redraw
  glutPostRedisplay();
}
void Keyboard(unsigned char key, int x, int y)
{
  static const float STEP_SIZE = 1.0;
  vector3d right = cross(g_nup,(g_lookat-g_eye).MakeUnitVector());
  switch (key)
  {
  case 27:             // ESCAPE key
    exit (0);
    break;
  //case 'l':
  //  SelectFromMenu(MENU_LIGHTING);
  //  break;
  case 'p':
    SelectFromMenu(MENU_POLYMODE);
    break;
  case 't':
    SelectFromMenu(MENU_TEXTURING);
  case 'j': // down
    g_eye -= (g_nup * STEP_SIZE);
    g_lookat -= (g_nup * STEP_SIZE);
    syncCamera();
    break;
  case 'k': // up
    g_eye += (g_nup * STEP_SIZE);
    g_lookat += (g_nup * STEP_SIZE);
    syncCamera();
    break;
  case 'l': // right
    g_eye += (right * STEP_SIZE);
    g_lookat += (right * STEP_SIZE);
    syncCamera();
    break;
  case 'h': // left
    g_eye -= (right * STEP_SIZE);
    g_lookat -= (right * STEP_SIZE);
    syncCamera();
    break;
  case 'A': // automatic mode
    g_automode = !g_automode;
    runAutomatic();
    break;
  }
}
int BuildPopupMenu (void)
{
  int menu;
  menu = glutCreateMenu (SelectFromMenu);
  glutAddMenuEntry ("Toggle lighting\tl", MENU_LIGHTING);
  glutAddMenuEntry ("Toggle polygon fill\tp", MENU_POLYMODE);
  glutAddMenuEntry ("Toggle texturing\tt", MENU_TEXTURING);
  glutAddMenuEntry ("Exit demo\tEsc", MENU_EXIT);
  return menu;
}
void idleFunction()
{
  g_rayTracer->checkProgress();
}
int main(int argc, char** argv)
{

  if( argc < 2 )
  {
    std::cerr << "usage: " << argv[0] << " <nrrd_fn> <cmap_fn> <curv-thickness> <norm-flipped>" << std::endl;
    exit(1);
  }

  g_nrrd_fn = argv[1];
  g_cmap_fn = argv[2];
  g_curvThick = atof(argv[3]);
  g_normFlipped = atoi(argv[4]) != 0;

  // GLUT Window Initialization:
  glutInit (&argc, argv);
  glutInitWindowPosition( 50, 50 );
  glutInitWindowSize (g_Width, g_Height);
  glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutCreateWindow ("rt");
  // Initialize OpenGL graphics state
  InitGraphics();
  // Register callbacks:
  glutDisplayFunc (display);
  glutReshapeFunc (reshape);
  glutKeyboardFunc (Keyboard);
  glutMouseFunc (MouseButton);
  glutMotionFunc (MouseMotion);
  glutIdleFunc (idleFunction);
  // Create our popup menu
  //BuildPopupMenu ();
  //glutAttachMenu (GLUT_RIGHT_BUTTON);
  // Get the initial time, for use by animation
#ifdef _WIN32
  last_idle_time = GetTickCount();
#else
  gettimeofday (&last_idle_time, NULL);
#endif
  // Turn the flow of control over to GLUT
  glutMainLoop ();
  return 0;
}

<|endoftext|>