<commit_before>//===-- Reproducer.cpp ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/LLDBAssert.h"

#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"

using namespace lldb_private;
using namespace lldb_private::repro;
using namespace llvm;
using namespace llvm::yaml;

Reproducer &Reproducer::Instance() { return *InstanceImpl(); }

llvm::Error Reproducer::Initialize(ReproducerMode mode,
                                   llvm::Optional<FileSpec> root) {
  lldbassert(!InstanceImpl() && "Already initialized.");
  InstanceImpl().emplace();

  switch (mode) {
  case ReproducerMode::Capture: {
    if (!root) {
      SmallString<128> repro_dir;
      auto ec = sys::fs::createUniqueDirectory("reproducer", repro_dir);
      if (ec)
        return make_error<StringError>(
            "unable to create unique reproducer directory", ec);
      root.emplace(repro_dir);
    } else {
      auto ec = sys::fs::create_directory(root->GetPath());
      if (ec)
        return make_error<StringError>("unable to create reproducer directory",
                                       ec);
    }
    return Instance().SetCapture(root);
  } break;
  case ReproducerMode::Replay:
    return Instance().SetReplay(root);
  case ReproducerMode::Off:
    break;
  };

  return Error::success();
}

bool Reproducer::Initialized() { return InstanceImpl().operator bool(); }

void Reproducer::Terminate() {
  lldbassert(InstanceImpl() && "Already terminated.");
  InstanceImpl().reset();
}

Optional<Reproducer> &Reproducer::InstanceImpl() {
  static Optional<Reproducer> g_reproducer;
  return g_reproducer;
}

const Generator *Reproducer::GetGenerator() const {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_generator)
    return &(*m_generator);
  return nullptr;
}

const Loader *Reproducer::GetLoader() const {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_loader)
    return &(*m_loader);
  return nullptr;
}

Generator *Reproducer::GetGenerator() {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_generator)
    return &(*m_generator);
  return nullptr;
}

Loader *Reproducer::GetLoader() {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_loader)
    return &(*m_loader);
  return nullptr;
}

llvm::Error Reproducer::SetCapture(llvm::Optional<FileSpec> root) {
  std::lock_guard<std::mutex> guard(m_mutex);

  if (root && m_loader)
    return make_error<StringError>(
        "cannot generate a reproducer when replay one",
        inconvertibleErrorCode());

  if (!root) {
    m_generator.reset();
    return Error::success();
  }

  m_generator.emplace(*root);
  return Error::success();
}

llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root) {
  std::lock_guard<std::mutex> guard(m_mutex);

  if (root && m_generator)
    return make_error<StringError>(
        "cannot replay a reproducer when generating one",
        inconvertibleErrorCode());

  if (!root) {
    m_loader.reset();
    return Error::success();
  }

  m_loader.emplace(*root);
  if (auto e = m_loader->LoadIndex())
    return e;

  return Error::success();
}

FileSpec Reproducer::GetReproducerPath() const {
  if (auto g = GetGenerator())
    return g->GetRoot();
  if (auto l = GetLoader())
    return l->GetRoot();
  return {};
}

Generator::Generator(const FileSpec &root) : m_root(root), m_done(false) {}

Generator::~Generator() {}

ProviderBase *Generator::Register(std::unique_ptr<ProviderBase> provider) {
  std::lock_guard<std::mutex> lock(m_providers_mutex);
  std::pair<const void *, std::unique_ptr<ProviderBase>> key_value(
      provider->DynamicClassID(), std::move(provider));
  auto e = m_providers.insert(std::move(key_value));
  return e.first->getSecond().get();
}

void Generator::Keep() {
  assert(!m_done);
  m_done = true;

  for (auto &provider : m_providers)
    provider.second->Keep();

  AddProvidersToIndex();
}

void Generator::Discard() {
  assert(!m_done);
  m_done = true;

  for (auto &provider : m_providers)
    provider.second->Discard();

  llvm::sys::fs::remove_directories(m_root.GetPath());
}

const FileSpec &Generator::GetRoot() const { return m_root; }

void Generator::AddProvidersToIndex() {
  FileSpec index = m_root;
  index.AppendPathComponent("index.yaml");

  std::error_code EC;
  auto strm = llvm::make_unique<raw_fd_ostream>(index.GetPath(), EC,
                                                sys::fs::OpenFlags::F_None);
  yaml::Output yout(*strm);

  std::vector<std::string> files;
  files.reserve(m_providers.size());
  for (auto &provider : m_providers) {
    files.emplace_back(provider.second->GetFile());
  }

  yout << files;
}

Loader::Loader(const FileSpec &root) : m_root(root), m_loaded(false) {}

llvm::Error Loader::LoadIndex() {
  if (m_loaded)
    return llvm::Error::success();

  FileSpec index = m_root.CopyByAppendingPathComponent("index.yaml");

  auto error_or_file = MemoryBuffer::getFile(index.GetPath());
  if (auto err = error_or_file.getError())
    return make_error<StringError>("unable to load reproducer index", err);

  yaml::Input yin((*error_or_file)->getBuffer());
  yin >> m_files;
  if (auto err = yin.error())
    return make_error<StringError>("unable to read reproducer index", err);

  // Sort files to speed up search.
  llvm::sort(m_files);

  // Remember that we've loaded the index.
  m_loaded = true;

  return llvm::Error::success();
}

bool Loader::HasFile(StringRef file) {
  assert(m_loaded);
  auto it = std::lower_bound(m_files.begin(), m_files.end(), file.str());
  return (it != m_files.end()) && (*it == file);
}

llvm::Expected<std::unique_ptr<DataRecorder>>
DataRecorder::Create(FileSpec filename) {
  std::error_code ec;
  auto recorder = llvm::make_unique<DataRecorder>(std::move(filename), ec);
  if (ec)
    return llvm::errorCodeToError(ec);
  return recorder;
}

DataRecorder *CommandProvider::GetNewDataRecorder() {
  std::size_t i = m_data_recorders.size() + 1;
  std::string filename = (llvm::Twine(info::name) + llvm::Twine("-") +
                          llvm::Twine(i) + llvm::Twine(".txt"))
                             .str();
  auto recorder_or_error =
      DataRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename));
  if (!recorder_or_error) {
    llvm::consumeError(recorder_or_error.takeError());
    return nullptr;
  }

  m_data_recorders.push_back(std::move(*recorder_or_error));
  return m_data_recorders.back().get();
}

void CommandProvider::Keep() {
  std::vector<std::string> files;
  for (auto &recorder : m_data_recorders)
    files.push_back(recorder->GetFilename().GetPath());

  FileSpec file = GetRoot().CopyByAppendingPathComponent(info::file);
  std::error_code ec;
  llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::F_Text);
  if (ec)
    return;
  yaml::Output yout(os);
  yout << files;

  m_data_recorders.clear();
}

void CommandProvider::Discard() { m_data_recorders.clear(); }

void ProviderBase::anchor() {}
char ProviderBase::ID = 0;
char FileProvider::ID = 0;
char CommandProvider::ID = 0;
const char *FileInfo::name = "files";
const char *FileInfo::file = "files.yaml";
const char *CommandInfo::name = "command-interpreter";
const char *CommandInfo::file = "command-interpreter.yaml";
<commit_msg>Fix gcc build for r355249<commit_after>//===-- Reproducer.cpp ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/LLDBAssert.h"

#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"

using namespace lldb_private;
using namespace lldb_private::repro;
using namespace llvm;
using namespace llvm::yaml;

Reproducer &Reproducer::Instance() { return *InstanceImpl(); }

llvm::Error Reproducer::Initialize(ReproducerMode mode,
                                   llvm::Optional<FileSpec> root) {
  lldbassert(!InstanceImpl() && "Already initialized.");
  InstanceImpl().emplace();

  switch (mode) {
  case ReproducerMode::Capture: {
    if (!root) {
      SmallString<128> repro_dir;
      auto ec = sys::fs::createUniqueDirectory("reproducer", repro_dir);
      if (ec)
        return make_error<StringError>(
            "unable to create unique reproducer directory", ec);
      root.emplace(repro_dir);
    } else {
      auto ec = sys::fs::create_directory(root->GetPath());
      if (ec)
        return make_error<StringError>("unable to create reproducer directory",
                                       ec);
    }
    return Instance().SetCapture(root);
  } break;
  case ReproducerMode::Replay:
    return Instance().SetReplay(root);
  case ReproducerMode::Off:
    break;
  };

  return Error::success();
}

bool Reproducer::Initialized() { return InstanceImpl().operator bool(); }

void Reproducer::Terminate() {
  lldbassert(InstanceImpl() && "Already terminated.");
  InstanceImpl().reset();
}

Optional<Reproducer> &Reproducer::InstanceImpl() {
  static Optional<Reproducer> g_reproducer;
  return g_reproducer;
}

const Generator *Reproducer::GetGenerator() const {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_generator)
    return &(*m_generator);
  return nullptr;
}

const Loader *Reproducer::GetLoader() const {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_loader)
    return &(*m_loader);
  return nullptr;
}

Generator *Reproducer::GetGenerator() {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_generator)
    return &(*m_generator);
  return nullptr;
}

Loader *Reproducer::GetLoader() {
  std::lock_guard<std::mutex> guard(m_mutex);
  if (m_loader)
    return &(*m_loader);
  return nullptr;
}

llvm::Error Reproducer::SetCapture(llvm::Optional<FileSpec> root) {
  std::lock_guard<std::mutex> guard(m_mutex);

  if (root && m_loader)
    return make_error<StringError>(
        "cannot generate a reproducer when replay one",
        inconvertibleErrorCode());

  if (!root) {
    m_generator.reset();
    return Error::success();
  }

  m_generator.emplace(*root);
  return Error::success();
}

llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root) {
  std::lock_guard<std::mutex> guard(m_mutex);

  if (root && m_generator)
    return make_error<StringError>(
        "cannot replay a reproducer when generating one",
        inconvertibleErrorCode());

  if (!root) {
    m_loader.reset();
    return Error::success();
  }

  m_loader.emplace(*root);
  if (auto e = m_loader->LoadIndex())
    return e;

  return Error::success();
}

FileSpec Reproducer::GetReproducerPath() const {
  if (auto g = GetGenerator())
    return g->GetRoot();
  if (auto l = GetLoader())
    return l->GetRoot();
  return {};
}

Generator::Generator(const FileSpec &root) : m_root(root), m_done(false) {}

Generator::~Generator() {}

ProviderBase *Generator::Register(std::unique_ptr<ProviderBase> provider) {
  std::lock_guard<std::mutex> lock(m_providers_mutex);
  std::pair<const void *, std::unique_ptr<ProviderBase>> key_value(
      provider->DynamicClassID(), std::move(provider));
  auto e = m_providers.insert(std::move(key_value));
  return e.first->getSecond().get();
}

void Generator::Keep() {
  assert(!m_done);
  m_done = true;

  for (auto &provider : m_providers)
    provider.second->Keep();

  AddProvidersToIndex();
}

void Generator::Discard() {
  assert(!m_done);
  m_done = true;

  for (auto &provider : m_providers)
    provider.second->Discard();

  llvm::sys::fs::remove_directories(m_root.GetPath());
}

const FileSpec &Generator::GetRoot() const { return m_root; }

void Generator::AddProvidersToIndex() {
  FileSpec index = m_root;
  index.AppendPathComponent("index.yaml");

  std::error_code EC;
  auto strm = llvm::make_unique<raw_fd_ostream>(index.GetPath(), EC,
                                                sys::fs::OpenFlags::F_None);
  yaml::Output yout(*strm);

  std::vector<std::string> files;
  files.reserve(m_providers.size());
  for (auto &provider : m_providers) {
    files.emplace_back(provider.second->GetFile());
  }

  yout << files;
}

Loader::Loader(const FileSpec &root) : m_root(root), m_loaded(false) {}

llvm::Error Loader::LoadIndex() {
  if (m_loaded)
    return llvm::Error::success();

  FileSpec index = m_root.CopyByAppendingPathComponent("index.yaml");

  auto error_or_file = MemoryBuffer::getFile(index.GetPath());
  if (auto err = error_or_file.getError())
    return make_error<StringError>("unable to load reproducer index", err);

  yaml::Input yin((*error_or_file)->getBuffer());
  yin >> m_files;
  if (auto err = yin.error())
    return make_error<StringError>("unable to read reproducer index", err);

  // Sort files to speed up search.
  llvm::sort(m_files);

  // Remember that we've loaded the index.
  m_loaded = true;

  return llvm::Error::success();
}

bool Loader::HasFile(StringRef file) {
  assert(m_loaded);
  auto it = std::lower_bound(m_files.begin(), m_files.end(), file.str());
  return (it != m_files.end()) && (*it == file);
}

llvm::Expected<std::unique_ptr<DataRecorder>>
DataRecorder::Create(FileSpec filename) {
  std::error_code ec;
  auto recorder = llvm::make_unique<DataRecorder>(std::move(filename), ec);
  if (ec)
    return llvm::errorCodeToError(ec);
  return std::move(recorder);
}

DataRecorder *CommandProvider::GetNewDataRecorder() {
  std::size_t i = m_data_recorders.size() + 1;
  std::string filename = (llvm::Twine(info::name) + llvm::Twine("-") +
                          llvm::Twine(i) + llvm::Twine(".txt"))
                             .str();
  auto recorder_or_error =
      DataRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename));
  if (!recorder_or_error) {
    llvm::consumeError(recorder_or_error.takeError());
    return nullptr;
  }

  m_data_recorders.push_back(std::move(*recorder_or_error));
  return m_data_recorders.back().get();
}

void CommandProvider::Keep() {
  std::vector<std::string> files;
  for (auto &recorder : m_data_recorders)
    files.push_back(recorder->GetFilename().GetPath());

  FileSpec file = GetRoot().CopyByAppendingPathComponent(info::file);
  std::error_code ec;
  llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::F_Text);
  if (ec)
    return;
  yaml::Output yout(os);
  yout << files;

  m_data_recorders.clear();
}

void CommandProvider::Discard() { m_data_recorders.clear(); }

void ProviderBase::anchor() {}
char ProviderBase::ID = 0;
char FileProvider::ID = 0;
char CommandProvider::ID = 0;
const char *FileInfo::name = "files";
const char *FileInfo::file = "files.yaml";
const char *CommandInfo::name = "command-interpreter";
const char *CommandInfo::file = "command-interpreter.yaml";
<|endoftext|>


<commit_before>#include <iostream>
#include <time.h>
#include <array>
#include <SDL_mixer.h>
#include "GameManager.h"
#include "Log.h"
#include "Menu.h"
#include "Timer.h"
#include "levelLoader.h"

GameManager::GameManager(Window* window):
    window(window)
{
    currentState = STATE_MENU;
    _quit = false;
}

void GameManager::runGame()
{
    Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 4096);
    Mix_Music *music = NULL;
    std::string resPath = "res";
    std::string filePath = "";
    filePath = resPath + PATH_SEP + "backgroundmusic.wav";

    music = Mix_LoadMUS(filePath.c_str());

    if(!music)
        // TODO: Adapt this to
        printf("Mix_LoadMUS(\"backgroundmusic.wav\"): %s\n", Mix_GetError());

    Mix_PlayMusic(music, -1);

    Entity* paddle = new Entity(window, "paddle.bmp", 305, 490);
    paddle->setMoveRate(5);
    entities.push_back(paddle);

    ball = new Ball(window, "ball.bmp", window->getWidth() / 2, window->getHeight() / 2, paddle);
    ball->setOnPaddle(true);

    ball2 = new Ball(window, "ball2.bmp", window->getWidth() / 2, window->getHeight() / 2, paddle);
    ball2->setOnPaddle(true);
	levelLoader* loader = new levelLoader(window, entities);

    //used for random powerup spwaning
    srand(time(NULL));
    randNum = rand() % 4;
    mod = new Mods(window, "PowerUP.bmp", 305, 0 );//makes a new power down object

    upNum = rand() % 2;
	downNum = rand() % 2;

    Timer fpsTimer;
    Timer capTimer;

    uint32_t frameCount = 0;
    fpsTimer.start();

    Menu mainMenu(this);
    mainMenu.addEntry("Play");
    mainMenu.addEntry("Settings");
    mainMenu.addEntry("Exit");

    Menu settingsMenu(this);
    settingsMenu.addEntry("Back");

    while (!_quit)
    {
        window->clear();

        capTimer.start();

        switch (currentState)
        {
        case STATE_MENU:
        {
            SDL_Texture* bgTexture = window->loadTexture("bg.bmp");
            window->renderTexture(bgTexture, 0, 0);
            mainMenu.tick();
            break;
        }
        case STATE_SETTINGS:
            break;
        case STATE_PLAYING:
            gameTick();
            break;
        default:
            Log::warn("Recieved unhandled gamestate: " + std::to_string(currentState));
            break;
        }

        // divide the amount of frames displayed by the runtime in seconds to get the average fps
        float avgFps = frameCount / (fpsTimer.getTicks() / 1000.f);
        if (avgFps > 2000000)
            avgFps = 0;

        window->renderText(std::to_string((int)avgFps), window->getWidth()-30, 0, { 0, 0, 0 }, 25, FONT_RENDER_BLENDED, { 0, 0, 0 });

        window->render();

        frameCount++;

        // if our fps it too high, wait here until we're back to ~60fps
        if (capTimer.getTicks() < (1000 / window->getMaxFps()))
        {
            int waitTime = (1000 / window->getMaxFps()) - capTimer.getTicks();
            //Log::info("Waiting " + std::to_string(waitTime) + " MS");
            SDL_Delay(waitTime);
        }
    }
}

void GameManager::gameTick()
{
    SDL_PollEvent(&event);

    // paddle is always added to the entities vector first, so this is fine
    Entity* paddle = entities[0];

    switch (event.type)
    {
    // if user clicks the red X
    case SDL_QUIT:
        _quit = true;
        break;

    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_LEFT:
            paddle->startMoving(MOVE_LEFT);
            break;
        case SDLK_RIGHT:
            paddle->startMoving(MOVE_RIGHT);
            break;
        case SDLK_SPACE:
            if (ball->isOnPaddle())
                ball->detach();
            break;
        }
        break;

    case SDL_KEYUP:
        switch (event.key.keysym.sym)
        {
        case SDLK_LEFT:
            paddle->stopMoving(MOVE_LEFT);
            break;
        case SDLK_RIGHT:
            paddle->stopMoving(MOVE_RIGHT);
            break;
        }
        break;
    }

    for (Entity* e : entities)
    {
        // don't think this is that cpu intensive but I guess it could be
        if (ball->collidedWith(e))
        {
            ball->handleCollision(e);

        }

        if(ball2->collidedWith(e))
            ball2->handleCollision(e);

        e->update();
    }

/************** Code segment used for powerup implementation ***************/
if(randNum == 0)    //anthony is gay
{
    mod->update();
        if(mod->collidedWith(paddle))
        {
         mod->fastPaddle();
         paddle->setMoveRate(7);
         mod->remove();
        }
}

if(randNum == 1)
{
  mod->update();
  if(mod->collidedWith(paddle))
  {
    mod->largePaddle();
    mod->remove();
  }
}

if(randNum == 2)
{
    mod->update();
        if(mod->collidedWith(paddle))
        {
            mod->slowerPaddle();
            paddle->setMoveRate(3);
            mod->remove();
        }
    }
  if(randNum == 3)
  {
      mod->update();
        if(mod->collidedWith(paddle))
        {
            mod->smallPaddle();
            mod->remove();
        }
    }
/***************************************************************************/

    ball->update();
}
<commit_msg>Fixed LevelLoader<commit_after>#include <iostream>
#include <time.h>
#include <array>
#include <SDL_mixer.h>
#include "GameManager.h"
#include "Log.h"
#include "Menu.h"
#include "Timer.h"
#include "levelLoader.h"

GameManager::GameManager(Window* window):
    window(window)
{
    currentState = STATE_MENU;
    _quit = false;
}

void GameManager::runGame()
{
    Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 4096);
    Mix_Music *music = NULL;
    std::string resPath = "res";
    std::string filePath = "";
    filePath = resPath + PATH_SEP + "backgroundmusic.wav";

    music = Mix_LoadMUS(filePath.c_str());

    if(!music)
        // TODO: Adapt this to
        printf("Mix_LoadMUS(\"backgroundmusic.wav\"): %s\n", Mix_GetError());

    Mix_PlayMusic(music, -1);

    Entity* paddle = new Entity(window, "paddle.bmp", 305, 490);
    paddle->setMoveRate(5);
    entities.push_back(paddle);

    ball = new Ball(window, "ball.bmp", window->getWidth() / 2, window->getHeight() / 2, paddle);
    ball->setOnPaddle(true);

    ball2 = new Ball(window, "ball2.bmp", window->getWidth() / 2, window->getHeight() / 2, paddle);
    ball2->setOnPaddle(true);
	LevelLoader* loader = new LevelLoader(window, entities);

    //used for random powerup spwaning
    srand(time(NULL));
    randNum = rand() % 4;
    mod = new Mods(window, "PowerUP.bmp", 305, 0 );//makes a new power down object

    upNum = rand() % 2;
	downNum = rand() % 2;

    Timer fpsTimer;
    Timer capTimer;

    uint32_t frameCount = 0;
    fpsTimer.start();

    Menu mainMenu(this);
    mainMenu.addEntry("Play");
    mainMenu.addEntry("Settings");
    mainMenu.addEntry("Exit");

    Menu settingsMenu(this);
    settingsMenu.addEntry("Back");

    while (!_quit)
    {
        window->clear();

        capTimer.start();

        switch (currentState)
        {
        case STATE_MENU:
        {
            SDL_Texture* bgTexture = window->loadTexture("bg.bmp");
            window->renderTexture(bgTexture, 0, 0);
            mainMenu.tick();
            break;
        }
        case STATE_SETTINGS:
            break;
        case STATE_PLAYING:
            gameTick();
            break;
        default:
            Log::warn("Recieved unhandled gamestate: " + std::to_string(currentState));
            break;
        }

        // divide the amount of frames displayed by the runtime in seconds to get the average fps
        float avgFps = frameCount / (fpsTimer.getTicks() / 1000.f);
        if (avgFps > 2000000)
            avgFps = 0;

        window->renderText(std::to_string((int)avgFps), window->getWidth()-30, 0, { 0, 0, 0 }, 25, FONT_RENDER_BLENDED, { 0, 0, 0 });

        window->render();

        frameCount++;

        // if our fps it too high, wait here until we're back to ~60fps
        if (capTimer.getTicks() < (1000 / window->getMaxFps()))
        {
            int waitTime = (1000 / window->getMaxFps()) - capTimer.getTicks();
            //Log::info("Waiting " + std::to_string(waitTime) + " MS");
            SDL_Delay(waitTime);
        }
    }
}

void GameManager::gameTick()
{
    SDL_PollEvent(&event);

    // paddle is always added to the entities vector first, so this is fine
    Entity* paddle = entities[0];

    switch (event.type)
    {
    // if user clicks the red X
    case SDL_QUIT:
        _quit = true;
        break;

    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_LEFT:
            paddle->startMoving(MOVE_LEFT);
            break;
        case SDLK_RIGHT:
            paddle->startMoving(MOVE_RIGHT);
            break;
        case SDLK_SPACE:
            if (ball->isOnPaddle())
                ball->detach();
            break;
        }
        break;

    case SDL_KEYUP:
        switch (event.key.keysym.sym)
        {
        case SDLK_LEFT:
            paddle->stopMoving(MOVE_LEFT);
            break;
        case SDLK_RIGHT:
            paddle->stopMoving(MOVE_RIGHT);
            break;
        }
        break;
    }

    for (Entity* e : entities)
    {
        // don't think this is that cpu intensive but I guess it could be
        if (ball->collidedWith(e))
        {
            ball->handleCollision(e);

        }

        if(ball2->collidedWith(e))
            ball2->handleCollision(e);

        e->update();
    }

/************** Code segment used for powerup implementation ***************/
if(randNum == 0)    //anthony is gay
{
    mod->update();
        if(mod->collidedWith(paddle))
        {
         mod->fastPaddle();
         paddle->setMoveRate(7);
         mod->remove();
        }
}

if(randNum == 1)
{
  mod->update();
  if(mod->collidedWith(paddle))
  {
    mod->largePaddle();
    mod->remove();
  }
}

if(randNum == 2)
{
    mod->update();
        if(mod->collidedWith(paddle))
        {
            mod->slowerPaddle();
            paddle->setMoveRate(3);
            mod->remove();
        }
    }
  if(randNum == 3)
  {
      mod->update();
        if(mod->collidedWith(paddle))
        {
            mod->smallPaddle();
            mod->remove();
        }
    }
/***************************************************************************/

    ball->update();
}
<|endoftext|>


<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real
    Copyright (C) 2017 Roman Lebedev

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

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

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

#include "decompressors/SamsungV2Decompressor.h"
#include "common/Common.h"                // for uint32, ushort16, int32
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h"              // for BitPumpMSB32
#include "io/ByteStream.h"                // for ByteStream
#include <algorithm>                      // for max
#include <cassert>                        // for assert

namespace rawspeed {

// Seriously Samsung just use lossless jpeg already, it compresses better too :)

// Thanks to Michael Reichmann (Luminous Landscape) for putting Pedro Côrte-Real
// in contact and Loring von Palleske (Samsung) for pointing to the open-source
// code of Samsung's DNG converter at http://opensource.samsung.com/

enum struct SamsungV2Decompressor::OptFlags : uint32 {
  NONE = 0U,       // no flags
  SKIP = 1U << 0U, // Skip checking if we need differences from previous line
  MV = 1U << 1U,   // Simplify motion vector definition
  QP = 1U << 2U,   // Don't scale the diff values

  // all possible flags
  ALL = SKIP | MV | QP,
};

constexpr SamsungV2Decompressor::OptFlags
operator|(SamsungV2Decompressor::OptFlags lhs,
          SamsungV2Decompressor::OptFlags rhs) {
  return static_cast<SamsungV2Decompressor::OptFlags>(
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          lhs) |
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          rhs));
}

constexpr bool operator&(SamsungV2Decompressor::OptFlags lhs,
                         SamsungV2Decompressor::OptFlags rhs) {
  const auto intersect = static_cast<SamsungV2Decompressor::OptFlags>(
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          lhs) &
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          rhs));
  return intersect != SamsungV2Decompressor::OptFlags::NONE;
}

SamsungV2Decompressor::SamsungV2Decompressor(const RawImage& image,
                                             const ByteStream& bs, int bit)
    : AbstractSamsungDecompressor(image), bits(bit) {
  BitPumpMSB32 startpump(bs);

  // Process the initial metadata bits, we only really use initVal, width and
  // height (the last two match the TIFF values anyway)
  startpump.getBits(16); // NLCVersion
  startpump.getBits(4);  // ImgFormat
  bitDepth = startpump.getBits(4) + 1;
  startpump.getBits(4); // NumBlkInRCUnit
  startpump.getBits(4); // CompressionRatio
  width = startpump.getBits(16);
  height = startpump.getBits(16);
  startpump.getBits(16); // TileWidth
  startpump.getBits(4);  // reserved

  // The format includes an optimization code that sets 3 flags to change the
  // decoding parameters
  const uint32 optflags = startpump.getBits(4);
  if (optflags > static_cast<uint32>(OptFlags::ALL))
    ThrowRDE("Invalid opt flags %x", optflags);
  _flags = static_cast<OptFlags>(optflags);

  startpump.getBits(8); // OverlapWidth
  startpump.getBits(8); // reserved
  startpump.getBits(8); // Inc
  startpump.getBits(2); // reserved
  initVal = startpump.getBits(14);

  if (width == 0 || height == 0 || width % 16 != 0 || width > 6496 ||
      height > 4336)
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);

  if (width != static_cast<uint32>(mRaw->dim.x) ||
      height != static_cast<uint32>(mRaw->dim.y))
    ThrowRDE("EXIF image dimensions do not match dimensions from raw header");

  data = startpump.getStream(startpump.getRemainSize());
}

void SamsungV2Decompressor::decompress() {
  switch (_flags) {
  case OptFlags::NONE:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::NONE>(row);
    break;
  case OptFlags::ALL:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::ALL>(row);
    break;

  case OptFlags::SKIP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP>(row);
    break;
  case OptFlags::MV:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::MV>(row);
    break;
  case OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::QP>(row);
    break;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
  case OptFlags::SKIP | OptFlags::MV:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::MV>(row);
    break;
  case OptFlags::SKIP | OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::QP>(row);
    break;

  case OptFlags::MV | OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::MV | OptFlags::QP>(row);
    break;
#pragma GCC diagnostic pop

  default:
    __builtin_unreachable();
  }
}

template <SamsungV2Decompressor::OptFlags optflags>
void SamsungV2Decompressor::decompressRow(uint32 row) {
  // The format is relatively straightforward. Each line gets encoded as a set
  // of differences from pixels from another line. Pixels are grouped in blocks
  // of 16 (8 green, 8 red or blue). Each block is encoded in three sections.
  // First 1 or 4 bits to specify which reference pixels to use, then a section
  // that specifies for each pixel the number of bits in the difference, then
  // the actual difference bits

  // Align pump to 16byte boundary
  const auto line_offset = data.getPosition();
  if ((line_offset & 0xf) != 0)
    data.skipBytes(16 - (line_offset & 0xf));

  BitPumpMSB32 pump(data);

  auto* img = reinterpret_cast<ushort16*>(mRaw->getData(0, row));
  ushort16* img_up = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(row) - 1)));
  ushort16* img_up2 = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(row) - 2)));

  // Initialize the motion and diff modes at the start of the line
  uint32 motion = 7;
  // By default we are not scaling values at all
  int32 scale = 0;

  uint32 diffBitsMode[3][2] = {{0}};
  for (auto& i : diffBitsMode)
    i[0] = i[1] = (row == 0 || row == 1) ? 7 : 4;

  assert(width >= 16);
  for (uint32 col = 0; col < width; col += 16) {
    if (!(optflags & OptFlags::QP) && !(col & 63)) {
      int32 scalevals[] = {0, -2, 2};
      uint32 i = pump.getBits(2);
      scale = i < 3 ? scale + scalevals[i] : pump.getBits(12);
    }

    // First we figure out which reference pixels mode we're in
    if (optflags & OptFlags::MV)
      motion = pump.getBits(1) ? 3 : 7;
    else if (!pump.getBits(1))
      motion = pump.getBits(3);

    if ((row == 0 || row == 1) && (motion != 7))
      ThrowRDE("At start of image and motion isn't 7. File corrupted?");

    if (motion == 7) {
      // The base case, just set all pixels to the previous ones on the same
      // line If we're at the left edge we just start at the initial value
      for (uint32 i = 0; i < 16; i++)
        img[i] = (col == 0) ? initVal : *(img + i - 2);
    } else {
      // The complex case, we now need to actually lookup one or two lines
      // above
      if (row < 2)
        ThrowRDE(
            "Got a previous line lookup on first two lines. File corrupted?");

      int32 motionOffset[7] = {-4, -2, -2, 0, 0, 2, 4};
      int32 motionDoAverage[7] = {0, 0, 1, 0, 1, 0, 0};

      int32 slideOffset = motionOffset[motion];
      int32 doAverage = motionDoAverage[motion];

      for (uint32 i = 0; i < 16; i++) {
        ushort16* refpixel;

        if ((row + i) & 0x1) // Red or blue pixels use same color two lines up
          refpixel = img_up2 + i + slideOffset;
        else // Green pixel N uses Green pixel N from row above (top left or
             // top right)
          refpixel = img_up + i + slideOffset + (((i % 2) != 0) ? -1 : 1);

        // In some cases we use as reference interpolation of this pixel and
        // the next
        if (doAverage)
          img[i] = (*refpixel + *(refpixel + 2) + 1) >> 1;
        else
          img[i] = *refpixel;
      }
    }

    // Figure out how many difference bits we have to read for each pixel
    uint32 diffBits[4] = {0};
    if (optflags & OptFlags::SKIP || !pump.getBits(1)) {
      uint32 flags[4];
      for (unsigned int& flag : flags)
        flag = pump.getBits(2);

      for (uint32 i = 0; i < 4; i++) {
        // The color is 0-Green 1-Blue 2-Red
        uint32 colornum = (row % 2 != 0) ? i >> 1 : ((i >> 1) + 2) % 3;

        assert(flags[i] <= 3);
        switch (flags[i]) {
        case 0:
          diffBits[i] = diffBitsMode[colornum][0];
          break;
        case 1:
          diffBits[i] = diffBitsMode[colornum][0] + 1;
          break;
        case 2:
          diffBits[i] = diffBitsMode[colornum][0] - 1;
          break;
        case 3:
          diffBits[i] = pump.getBits(4);
          break;
        default:
          __builtin_unreachable();
        }

        diffBitsMode[colornum][0] = diffBitsMode[colornum][1];
        diffBitsMode[colornum][1] = diffBits[i];

        if (diffBits[i] > bitDepth + 1)
          ThrowRDE("Too many difference bits. File corrupted?");
      }
    }

    // Actually read the differences and write them to the pixels
    for (uint32 i = 0; i < 16; i++) {
      uint32 len = diffBits[i >> 2];
      int32 diff = pump.getBits(len);

      // If the first bit is 1 we need to turn this into a negative number
      if (len != 0 && diff >> (len - 1))
        diff -= (1 << len);

      ushort16* value = nullptr;
      // Apply the diff to pixels 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
      if (row % 2)
        value = &img[((i & 0x7) << 1) + 1 - (i >> 3)];
      else
        value = &img[((i & 0x7) << 1) + (i >> 3)];

      diff = diff * (scale * 2 + 1) + scale;
      *value = clampBits(static_cast<int>(*value) + diff, bits);
    }

    img += 16;
    img_up += 16;
    img_up2 += 16;
  }

  data.skipBytes(pump.getBufferPosition());
}

} // namespace rawspeed
<commit_msg>SamsungV2Decompressor: OptFlags operator&: damn gcc4.9<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009-2010 Klaus Post
    Copyright (C) 2014-2015 Pedro Côrte-Real
    Copyright (C) 2017 Roman Lebedev

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

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

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

#include "decompressors/SamsungV2Decompressor.h"
#include "common/Common.h"                // for uint32, ushort16, int32
#include "common/Point.h"                 // for iPoint2D
#include "common/RawImage.h"              // for RawImage, RawImageData
#include "decoders/RawDecoderException.h" // for ThrowRDE
#include "io/BitPumpMSB32.h"              // for BitPumpMSB32
#include "io/ByteStream.h"                // for ByteStream
#include <algorithm>                      // for max
#include <cassert>                        // for assert

namespace rawspeed {

// Seriously Samsung just use lossless jpeg already, it compresses better too :)

// Thanks to Michael Reichmann (Luminous Landscape) for putting Pedro Côrte-Real
// in contact and Loring von Palleske (Samsung) for pointing to the open-source
// code of Samsung's DNG converter at http://opensource.samsung.com/

enum struct SamsungV2Decompressor::OptFlags : uint32 {
  NONE = 0U,       // no flags
  SKIP = 1U << 0U, // Skip checking if we need differences from previous line
  MV = 1U << 1U,   // Simplify motion vector definition
  QP = 1U << 2U,   // Don't scale the diff values

  // all possible flags
  ALL = SKIP | MV | QP,
};

constexpr SamsungV2Decompressor::OptFlags
operator|(SamsungV2Decompressor::OptFlags lhs,
          SamsungV2Decompressor::OptFlags rhs) {
  return static_cast<SamsungV2Decompressor::OptFlags>(
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          lhs) |
      static_cast<std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
          rhs));
}

constexpr bool operator&(SamsungV2Decompressor::OptFlags lhs,
                         SamsungV2Decompressor::OptFlags rhs) {
  return SamsungV2Decompressor::OptFlags::NONE !=
         static_cast<SamsungV2Decompressor::OptFlags>(
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 lhs) &
             static_cast<
                 std::underlying_type<SamsungV2Decompressor::OptFlags>::type>(
                 rhs));
}

SamsungV2Decompressor::SamsungV2Decompressor(const RawImage& image,
                                             const ByteStream& bs, int bit)
    : AbstractSamsungDecompressor(image), bits(bit) {
  BitPumpMSB32 startpump(bs);

  // Process the initial metadata bits, we only really use initVal, width and
  // height (the last two match the TIFF values anyway)
  startpump.getBits(16); // NLCVersion
  startpump.getBits(4);  // ImgFormat
  bitDepth = startpump.getBits(4) + 1;
  startpump.getBits(4); // NumBlkInRCUnit
  startpump.getBits(4); // CompressionRatio
  width = startpump.getBits(16);
  height = startpump.getBits(16);
  startpump.getBits(16); // TileWidth
  startpump.getBits(4);  // reserved

  // The format includes an optimization code that sets 3 flags to change the
  // decoding parameters
  const uint32 optflags = startpump.getBits(4);
  if (optflags > static_cast<uint32>(OptFlags::ALL))
    ThrowRDE("Invalid opt flags %x", optflags);
  _flags = static_cast<OptFlags>(optflags);

  startpump.getBits(8); // OverlapWidth
  startpump.getBits(8); // reserved
  startpump.getBits(8); // Inc
  startpump.getBits(2); // reserved
  initVal = startpump.getBits(14);

  if (width == 0 || height == 0 || width % 16 != 0 || width > 6496 ||
      height > 4336)
    ThrowRDE("Unexpected image dimensions found: (%u; %u)", width, height);

  if (width != static_cast<uint32>(mRaw->dim.x) ||
      height != static_cast<uint32>(mRaw->dim.y))
    ThrowRDE("EXIF image dimensions do not match dimensions from raw header");

  data = startpump.getStream(startpump.getRemainSize());
}

void SamsungV2Decompressor::decompress() {
  switch (_flags) {
  case OptFlags::NONE:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::NONE>(row);
    break;
  case OptFlags::ALL:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::ALL>(row);
    break;

  case OptFlags::SKIP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP>(row);
    break;
  case OptFlags::MV:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::MV>(row);
    break;
  case OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::QP>(row);
    break;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
  case OptFlags::SKIP | OptFlags::MV:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::MV>(row);
    break;
  case OptFlags::SKIP | OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::SKIP | OptFlags::QP>(row);
    break;

  case OptFlags::MV | OptFlags::QP:
    for (uint32 row = 0; row < height; row++)
      decompressRow<OptFlags::MV | OptFlags::QP>(row);
    break;
#pragma GCC diagnostic pop

  default:
    __builtin_unreachable();
  }
}

template <SamsungV2Decompressor::OptFlags optflags>
void SamsungV2Decompressor::decompressRow(uint32 row) {
  // The format is relatively straightforward. Each line gets encoded as a set
  // of differences from pixels from another line. Pixels are grouped in blocks
  // of 16 (8 green, 8 red or blue). Each block is encoded in three sections.
  // First 1 or 4 bits to specify which reference pixels to use, then a section
  // that specifies for each pixel the number of bits in the difference, then
  // the actual difference bits

  // Align pump to 16byte boundary
  const auto line_offset = data.getPosition();
  if ((line_offset & 0xf) != 0)
    data.skipBytes(16 - (line_offset & 0xf));

  BitPumpMSB32 pump(data);

  auto* img = reinterpret_cast<ushort16*>(mRaw->getData(0, row));
  ushort16* img_up = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(row) - 1)));
  ushort16* img_up2 = reinterpret_cast<ushort16*>(
      mRaw->getData(0, std::max(0, static_cast<int>(row) - 2)));

  // Initialize the motion and diff modes at the start of the line
  uint32 motion = 7;
  // By default we are not scaling values at all
  int32 scale = 0;

  uint32 diffBitsMode[3][2] = {{0}};
  for (auto& i : diffBitsMode)
    i[0] = i[1] = (row == 0 || row == 1) ? 7 : 4;

  assert(width >= 16);
  for (uint32 col = 0; col < width; col += 16) {
    if (!(optflags & OptFlags::QP) && !(col & 63)) {
      int32 scalevals[] = {0, -2, 2};
      uint32 i = pump.getBits(2);
      scale = i < 3 ? scale + scalevals[i] : pump.getBits(12);
    }

    // First we figure out which reference pixels mode we're in
    if (optflags & OptFlags::MV)
      motion = pump.getBits(1) ? 3 : 7;
    else if (!pump.getBits(1))
      motion = pump.getBits(3);

    if ((row == 0 || row == 1) && (motion != 7))
      ThrowRDE("At start of image and motion isn't 7. File corrupted?");

    if (motion == 7) {
      // The base case, just set all pixels to the previous ones on the same
      // line If we're at the left edge we just start at the initial value
      for (uint32 i = 0; i < 16; i++)
        img[i] = (col == 0) ? initVal : *(img + i - 2);
    } else {
      // The complex case, we now need to actually lookup one or two lines
      // above
      if (row < 2)
        ThrowRDE(
            "Got a previous line lookup on first two lines. File corrupted?");

      int32 motionOffset[7] = {-4, -2, -2, 0, 0, 2, 4};
      int32 motionDoAverage[7] = {0, 0, 1, 0, 1, 0, 0};

      int32 slideOffset = motionOffset[motion];
      int32 doAverage = motionDoAverage[motion];

      for (uint32 i = 0; i < 16; i++) {
        ushort16* refpixel;

        if ((row + i) & 0x1) // Red or blue pixels use same color two lines up
          refpixel = img_up2 + i + slideOffset;
        else // Green pixel N uses Green pixel N from row above (top left or
             // top right)
          refpixel = img_up + i + slideOffset + (((i % 2) != 0) ? -1 : 1);

        // In some cases we use as reference interpolation of this pixel and
        // the next
        if (doAverage)
          img[i] = (*refpixel + *(refpixel + 2) + 1) >> 1;
        else
          img[i] = *refpixel;
      }
    }

    // Figure out how many difference bits we have to read for each pixel
    uint32 diffBits[4] = {0};
    if (optflags & OptFlags::SKIP || !pump.getBits(1)) {
      uint32 flags[4];
      for (unsigned int& flag : flags)
        flag = pump.getBits(2);

      for (uint32 i = 0; i < 4; i++) {
        // The color is 0-Green 1-Blue 2-Red
        uint32 colornum = (row % 2 != 0) ? i >> 1 : ((i >> 1) + 2) % 3;

        assert(flags[i] <= 3);
        switch (flags[i]) {
        case 0:
          diffBits[i] = diffBitsMode[colornum][0];
          break;
        case 1:
          diffBits[i] = diffBitsMode[colornum][0] + 1;
          break;
        case 2:
          diffBits[i] = diffBitsMode[colornum][0] - 1;
          break;
        case 3:
          diffBits[i] = pump.getBits(4);
          break;
        default:
          __builtin_unreachable();
        }

        diffBitsMode[colornum][0] = diffBitsMode[colornum][1];
        diffBitsMode[colornum][1] = diffBits[i];

        if (diffBits[i] > bitDepth + 1)
          ThrowRDE("Too many difference bits. File corrupted?");
      }
    }

    // Actually read the differences and write them to the pixels
    for (uint32 i = 0; i < 16; i++) {
      uint32 len = diffBits[i >> 2];
      int32 diff = pump.getBits(len);

      // If the first bit is 1 we need to turn this into a negative number
      if (len != 0 && diff >> (len - 1))
        diff -= (1 << len);

      ushort16* value = nullptr;
      // Apply the diff to pixels 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
      if (row % 2)
        value = &img[((i & 0x7) << 1) + 1 - (i >> 3)];
      else
        value = &img[((i & 0x7) << 1) + (i >> 3)];

      diff = diff * (scale * 2 + 1) + scale;
      *value = clampBits(static_cast<int>(*value) + diff, bits);
    }

    img += 16;
    img_up += 16;
    img_up2 += 16;
  }

  data.skipBytes(pump.getBufferPosition());
}

} // namespace rawspeed
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2015, Göteborg Bit Factory.
//
// 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.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <iostream>
#include <utf8.h>
#include <test.h>

////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
  UnitTest t (17);

  std::string ascii_text      = "This is a test";
  std::string utf8_text       = "más sábado miércoles";
  std::string utf8_wide_text  = "改变各种颜色";

  std::string ascii_text_color      = "This is a test";
  std::string utf8_text_color       = "más sábado miércoles";
  std::string utf8_wide_text_color  = "改变各种颜色";

  // unsigned int utf8_codepoint (const std::string&);
  t.is ((int) utf8_codepoint ("\\u0020"), 32, "\\u0020 --> ' '");
  t.is ((int) utf8_codepoint ("U+0020"),  32, "U+0020 --> ' '");

  // TODO unsigned int utf8_next_char (const std::string&, std::string::size_type&);
  // TODO std::string utf8_character (unsigned int);
  // TODO int utf8_sequence (unsigned int);

  // unsigned int utf8_length (const std::string&);
  t.is ((int) utf8_length (ascii_text),     14, "ASCII utf8_length");
  t.is ((int) utf8_length (utf8_text),      20, "UTF8 utf8_length");
  t.is ((int) utf8_length (utf8_wide_text),  6, "UTF8 wide utf8_length");

  // unsigned int utf8_width (const std::string&);
  t.is ((int) utf8_width (ascii_text),     14, "ASCII utf8_width");
  t.is ((int) utf8_width (utf8_text),      20, "UTF8 utf8_width");
  t.is ((int) utf8_width (utf8_wide_text), 12, "UTF8 wide utf8_width");

  // unsigned int utf8_text_length (const std::string&);
  t.is ((int) utf8_text_length (ascii_text_color),     14, "ASCII utf8_text_length");
  t.is ((int) utf8_text_length (utf8_text_color),      20, "UTF8 utf8_text_length");
  t.is ((int) utf8_text_length (utf8_wide_text_color),  6, "UTF8 wide utf8_text_length");

  // unsigned int utf8_text_width (const std::string&);
  t.is ((int) utf8_text_width (ascii_text_color),     14, "ASCII utf8_text_width");
  t.is ((int) utf8_text_width (utf8_text_color),      20, "UTF8 utf8_text_width");
  t.is ((int) utf8_text_width (utf8_wide_text_color), 12, "UTF8 wide utf8_text_width");

  // const std::string utf8_substr (const std::string&, unsigned int, unsigned int length = 0);
  t.is (utf8_substr (ascii_text, 0, 2),      "Th", "ASCII utf8_substr");
  t.is (utf8_substr (utf8_text, 0, 2),       "má", "UTF8 utf8_substr");
  t.is (utf8_substr (utf8_wide_text, 0, 2),  "改变", "UTF8 wide utf8_substr");

  return 0;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Tests: Migrated improvements over from Taskwarrior<commit_after>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2015, Göteborg Bit Factory.
//
// 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.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <utf8.h>
#include <test.h>

////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
  UnitTest t (33);

  std::string ascii_text      = "This is a test";
  std::string utf8_text       = "más sábado miércoles";
  std::string utf8_wide_text  = "改变各种颜色";

  std::string ascii_text_color      = "This is a test";
  std::string utf8_text_color       = "más sábado miércoles";
  std::string utf8_wide_text_color  = "改变各种颜色";

  // unsigned int utf8_codepoint (const std::string&);
  t.is ((int) utf8_codepoint ("\\u0020"), 32, "\\u0020 --> ' '");
  t.is ((int) utf8_codepoint ("U+0020"),  32, "U+0020 --> ' '");

  // TODO unsigned int utf8_next_char (const std::string&, std::string::size_type&);
  // TODO std::string utf8_character (unsigned int);
  // TODO int utf8_sequence (unsigned int);

  // unsigned int utf8_length (const std::string&);
  t.is ((int) utf8_length (ascii_text),     14, "ASCII utf8_length");
  t.is ((int) utf8_length (utf8_text),      20, "UTF8 utf8_length");
  t.is ((int) utf8_length (utf8_wide_text),  6, "UTF8 wide utf8_length");

  // unsigned int utf8_width (const std::string&);
  t.is ((int) utf8_width (ascii_text),     14, "ASCII utf8_width");
  t.is ((int) utf8_width (utf8_text),      20, "UTF8 utf8_width");
  t.is ((int) utf8_width (utf8_wide_text), 12, "UTF8 wide utf8_width");

  // unsigned int utf8_text_length (const std::string&);
  t.is ((int) utf8_text_length (ascii_text_color),     14, "ASCII utf8_text_length");
  t.is ((int) utf8_text_length (utf8_text_color),      20, "UTF8 utf8_text_length");
  t.is ((int) utf8_text_length (utf8_wide_text_color),  6, "UTF8 wide utf8_text_length");

  // unsigned int utf8_text_width (const std::string&);
  t.is ((int) utf8_text_width (ascii_text_color),     14, "ASCII utf8_text_width");
  t.is ((int) utf8_text_width (utf8_text_color),      20, "UTF8 utf8_text_width");
  t.is ((int) utf8_text_width (utf8_wide_text_color), 12, "UTF8 wide utf8_text_width");

  // const std::string utf8_substr (const std::string&, unsigned int, unsigned int length = 0);
  t.is (utf8_substr (ascii_text, 0, 2),      "Th", "ASCII utf8_substr");
  t.is (utf8_substr (utf8_text, 0, 2),       "má", "UTF8 utf8_substr");
  t.is (utf8_substr (utf8_wide_text, 0, 2),  "改变", "UTF8 wide utf8_substr");

  // int mk_wcwidth (wchar_t);
  t.is (mk_wcwidth ('a'),                               1, "mk_wcwidth U+0061 --> 1");
  t.is (mk_wcwidth (0x5149),                            2, "mk_wcwidth U+5149 --> 2");
  t.is (mk_wcwidth (0x9a8c),                            2, "mk_wcwidth U+9a8c --> 2");
  t.is (mk_wcwidth (0x4e70),                            2, "mk_wcwidth U+4e70 --> 2");
  t.is (mk_wcwidth (0x94b1),                            2, "mk_wcwidth U+94b1 --> 2");
  t.is (mk_wcwidth (0x5305),                            2, "mk_wcwidth U+5305 --> 2");
  t.is (mk_wcwidth (0x91cd),                            2, "mk_wcwidth U+91cd --> 2");
  t.is (mk_wcwidth (0x65b0),                            2, "mk_wcwidth U+65b0 --> 2");
  t.is (mk_wcwidth (0x8bbe),                            2, "mk_wcwidth U+8bbe --> 2");
  t.is (mk_wcwidth (0x8ba1),                            2, "mk_wcwidth U+8ba1 --> 2");
  t.is (mk_wcwidth (0x5411),                            2, "mk_wcwidth U+5411 --> 2");
  t.is (mk_wcwidth (0x4e0a),                            2, "mk_wcwidth U+4e0a --> 2");
  t.is (mk_wcwidth (0x4e0b),                            2, "mk_wcwidth U+4e0b --> 2");
  t.is (mk_wcwidth (0x7bad),                            2, "mk_wcwidth U+7bad --> 2");
  t.is (mk_wcwidth (0x5934),                            2, "mk_wcwidth U+5934 --> 2");
  t.is (mk_wcwidth (0xff0c),                            2, "mk_wcwidth U+ff0c --> 2"); // comma

  return 0;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

#include <iostream>
#include <boost/thread.hpp>
#include <Dataflow/Engine/Controller/NetworkEditorController.h>

#include <Dataflow/Network/Connection.h>
#include <Dataflow/Network/Network.h>
#include <Dataflow/Network/ModuleDescription.h>
#include <Dataflow/Network/Module.h>
#include <Dataflow/Serialization/Network/NetworkXMLSerializer.h>
#include <Dataflow/Serialization/Network/NetworkDescriptionSerialization.h>
#ifdef BUILD_WITH_PYTHON
#include <Dataflow/Engine/Python/NetworkEditorPythonAPI.h>
#include <Dataflow/Engine/Controller/PythonImpl.h>
#endif

#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/Layout.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/Priority.hh>

using namespace SCIRun;
using namespace SCIRun::Dataflow::Engine;
using namespace SCIRun::Dataflow::Networks;

NetworkEditorController::NetworkEditorController(ModuleFactoryHandle mf, ModuleStateFactoryHandle sf, ExecutionStrategyFactoryHandle executorFactory, ModulePositionEditor* mpg) :
  theNetwork_(new Network(mf, sf)),
  moduleFactory_(mf),
  stateFactory_(sf),
  executorFactory_(executorFactory),
  modulePositionEditor_(mpg)
{
  //TODO should this class own the network or just keep a reference?

#ifdef BUILD_WITH_PYTHON
  NetworkEditorPythonAPI::setImpl(boost::make_shared<PythonImpl>(*this));
#endif

  log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout);
  auto layout1 = new log4cpp::PatternLayout();
  layout1->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p] %m%n");
  appender1->setLayout(layout1);

  log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "scirun5.log");
  auto layout2 = new log4cpp::PatternLayout();
  layout2->setConversionPattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p] %m%n");
  appender2->setLayout(layout2);

  log4cpp::Category& root = log4cpp::Category::getRoot();
  //root.setPriority(log4cpp::Priority::WARN);
  root.addAppender(appender1);
  root.addAppender(appender2);
}

NetworkEditorController::NetworkEditorController(SCIRun::Dataflow::Networks::NetworkHandle network, ExecutionStrategyFactoryHandle executorFactory, ModulePositionEditor* mpg)
  : theNetwork_(network), executorFactory_(executorFactory), modulePositionEditor_(mpg)
{
}

ModuleHandle NetworkEditorController::addModule(const std::string& moduleName)
{
  auto realModule = addModuleImpl(moduleName);
  /*emit*/ moduleAdded_(moduleName, realModule);
  printNetwork();
  return realModule;
}

ModuleHandle NetworkEditorController::addModuleImpl(const std::string& moduleName)
{
  //TODO: should pass in entire info struct
  ModuleLookupInfo info;
  info.module_name_ = moduleName;
  ModuleHandle realModule = theNetwork_->add_module(info);
  return realModule;
}

void NetworkEditorController::removeModule(const ModuleId& id)
{
  theNetwork_->remove_module(id);
  //before or after?
  // deciding on after: ProvenanceWindow/Manager wants the state *after* removal.
  /*emit*/ moduleRemoved_(id);

  printNetwork();
}

ModuleHandle NetworkEditorController::duplicateModule(const ModuleHandle& module)
{
  ENSURE_NOT_NULL(module, "Cannot duplicate null module");
  ModuleId id(module->get_id());
  auto newModule = addModuleImpl(id.name_);
  newModule->set_state(module->get_state()->clone());
  moduleAdded_(id.name_, newModule);

  //TODO: probably a pretty poor way to deal with what I think is a race condition with signaling the GUI to place the module widget.
  boost::this_thread::sleep(boost::posix_time::milliseconds(1));

  for (size_t i = 0; i < module->num_input_ports(); ++i)
  {
    auto input = module->get_input_port(i);
    if (input->nconnections() == 1)
    {
      auto conn = input->connection(0);
      auto source = conn->oport_;
      requestConnection(source.get(), newModule->get_input_port(i).get());
    }
  }

  return newModule;
}

void NetworkEditorController::printNetwork() const
{
  //TODO: and make this switchable
  if (false)
  {
    //TODO: use real logger here
    if (theNetwork_)
      std::cout << theNetwork_->toString() << std::endl;
  }
}

void NetworkEditorController::requestConnection(const SCIRun::Dataflow::Networks::PortDescriptionInterface* from, const SCIRun::Dataflow::Networks::PortDescriptionInterface* to)
{
  ENSURE_NOT_NULL(from, "from port");
  ENSURE_NOT_NULL(to, "to port");

  auto out = from->isInput() ? to : from;
  auto in = from->isInput() ? from : to;

  ConnectionDescription desc(
    OutgoingConnectionDescription(out->getUnderlyingModuleId(), out->getIndex()),
    IncomingConnectionDescription(in->getUnderlyingModuleId(), in->getIndex()));

  PortConnectionDeterminer q;
  if (q.canBeConnected(*from, *to))
  {
    ConnectionId id = theNetwork_->connect(ConnectionOutputPort(theNetwork_->lookupModule(desc.out_.moduleId_), desc.out_.port_),
      ConnectionInputPort(theNetwork_->lookupModule(desc.in_.moduleId_), desc.in_.port_));
    if (!id.id_.empty())
      connectionAdded_(desc);

    printNetwork();
  }
  else
  {
    //TODO: use real logger
    std::cout << "Invalid Connection request: input port is full, or ports are different datatype or same i/o type, or on the same module." << std::endl;
    invalidConnection_(desc);
  }
}

void NetworkEditorController::removeConnection(const ConnectionId& id)
{
  if (theNetwork_->disconnect(id))
    connectionRemoved_(id);
  printNetwork();
}

boost::signals2::connection NetworkEditorController::connectModuleAdded(const ModuleAddedSignalType::slot_type& subscriber)
{
  return moduleAdded_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectModuleRemoved(const ModuleRemovedSignalType::slot_type& subscriber)
{
  return moduleRemoved_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectConnectionAdded(const ConnectionAddedSignalType::slot_type& subscriber)
{
  return connectionAdded_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectConnectionRemoved(const ConnectionRemovedSignalType::slot_type& subscriber)
{
  return connectionRemoved_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectInvalidConnection(const InvalidConnectionSignalType::slot_type& subscriber)
{
  return invalidConnection_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectNetworkExecutionStarts(const ExecuteAllStartsSignalType::slot_type& subscriber)
{
  return ExecutionStrategy::connectNetworkExecutionStarts(subscriber);
}

boost::signals2::connection NetworkEditorController::connectNetworkExecutionFinished(const ExecuteAllFinishesSignalType::slot_type& subscriber)
{
  return ExecutionStrategy::connectNetworkExecutionFinished(subscriber);
}

NetworkFileHandle NetworkEditorController::saveNetwork() const
{
  NetworkToXML conv(modulePositionEditor_);
  return conv.to_xml_data(theNetwork_);
}

void NetworkEditorController::loadNetwork(const NetworkFileHandle& xml)
{
  if (xml)
  {
    NetworkXMLConverter conv(moduleFactory_, stateFactory_);
    theNetwork_ = conv.from_xml_data(xml->network);
    for (size_t i = 0; i < theNetwork_->nmodules(); ++i)
    {
      ModuleHandle module = theNetwork_->module(i);
      moduleAdded_(module->get_module_name(), module);
    }
    BOOST_FOREACH(const ConnectionDescription& cd, theNetwork_->connections())
    {
      ConnectionId id = ConnectionId::create(cd);
      connectionAdded_(cd);
    }
    if (modulePositionEditor_)
      modulePositionEditor_->moveModules(xml->modulePositions);
    else
      std::cout << "module position editor is null" << std::endl;
  }
}

void NetworkEditorController::clear()
{
  //std::cout << "NetworkEditorController::clear()" << std::endl;
}

void NetworkEditorController::executeAll(const ExecutableLookup* lookup)
{
  if (!currentExecutor_)
    currentExecutor_ = executorFactory_->create(ExecutionStrategy::BASIC_PARALLEL); //TODO: read some setting for default executor type

  currentExecutor_->executeAll(*theNetwork_, lookup ? *lookup : *theNetwork_);
}

NetworkHandle NetworkEditorController::getNetwork() const
{
  return theNetwork_;
}

NetworkGlobalSettings& NetworkEditorController::getSettings()
{
  return theNetwork_->settings();
}

void NetworkEditorController::setExecutorType(int type)
{
  currentExecutor_ = executorFactory_->create((ExecutionStrategy::Type)type);
}

<commit_msg>There seems to be a log4cpp parsing bug on OS X 10.7, where even the default pattern specified in the log4cpp::PatternLayout class is failing. This is a preliminary attempt to report and recover, allowing the GUI to start up.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2012 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

#include <iostream>
#include <boost/thread.hpp>
#include <Dataflow/Engine/Controller/NetworkEditorController.h>

#include <Dataflow/Network/Connection.h>
#include <Dataflow/Network/Network.h>
#include <Dataflow/Network/ModuleDescription.h>
#include <Dataflow/Network/Module.h>
#include <Dataflow/Serialization/Network/NetworkXMLSerializer.h>
#include <Dataflow/Serialization/Network/NetworkDescriptionSerialization.h>
#ifdef BUILD_WITH_PYTHON
#include <Dataflow/Engine/Python/NetworkEditorPythonAPI.h>
#include <Dataflow/Engine/Controller/PythonImpl.h>
#endif

#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/Layout.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/Priority.hh>

using namespace SCIRun;
using namespace SCIRun::Dataflow::Engine;
using namespace SCIRun::Dataflow::Networks;

NetworkEditorController::NetworkEditorController(ModuleFactoryHandle mf, ModuleStateFactoryHandle sf, ExecutionStrategyFactoryHandle executorFactory, ModulePositionEditor* mpg) :
  theNetwork_(new Network(mf, sf)),
  moduleFactory_(mf),
  stateFactory_(sf),
  executorFactory_(executorFactory),
  modulePositionEditor_(mpg)
{
  //TODO should this class own the network or just keep a reference?

#ifdef BUILD_WITH_PYTHON
  NetworkEditorPythonAPI::setImpl(boost::make_shared<PythonImpl>(*this));
#endif

  std::string pattern("%d{%Y-%m-%d %H:%M:%S.%l} [%p] %m%n");

  log4cpp::Appender *appender1 = new log4cpp::OstreamAppender("console", &std::cout);
  auto layout1 = new log4cpp::PatternLayout();
  std::string backupPattern1 = layout1->getConversionPattern();
  try
  {
    layout1->setConversionPattern(pattern);
  }
  catch (log4cpp::ConfigureFailure& exception)
  {
    // TODO: log?
    std::cerr << "Caught ConfigureFailure exception: " << exception.what() << std::endl
              << "Restoring original pattern: (" << backupPattern1 << ")" << std::endl;
    layout1->setConversionPattern(backupPattern1);
  }
  appender1->setLayout(layout1);

  log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "scirun5.log");
  auto layout2 = new log4cpp::PatternLayout();
  std::string backupPattern2 = layout1->getConversionPattern();
  try
  {
    layout2->setConversionPattern(pattern);
  }
  catch (log4cpp::ConfigureFailure& exception)
  {
    // TODO: log?
    std::cerr << "Caught ConfigureFailure exception: " << exception.what() << std::endl
    << "Restoring original pattern: (" << backupPattern2 << ")" << std::endl;
    layout2->setConversionPattern(backupPattern2);
  }
  appender2->setLayout(layout2);

  log4cpp::Category& root = log4cpp::Category::getRoot();
  //root.setPriority(log4cpp::Priority::WARN);
  root.addAppender(appender1);
  root.addAppender(appender2);
}

NetworkEditorController::NetworkEditorController(SCIRun::Dataflow::Networks::NetworkHandle network, ExecutionStrategyFactoryHandle executorFactory, ModulePositionEditor* mpg)
  : theNetwork_(network), executorFactory_(executorFactory), modulePositionEditor_(mpg)
{
}

ModuleHandle NetworkEditorController::addModule(const std::string& moduleName)
{
  auto realModule = addModuleImpl(moduleName);
  /*emit*/ moduleAdded_(moduleName, realModule);
  printNetwork();
  return realModule;
}

ModuleHandle NetworkEditorController::addModuleImpl(const std::string& moduleName)
{
  //TODO: should pass in entire info struct
  ModuleLookupInfo info;
  info.module_name_ = moduleName;
  ModuleHandle realModule = theNetwork_->add_module(info);
  return realModule;
}

void NetworkEditorController::removeModule(const ModuleId& id)
{
  theNetwork_->remove_module(id);
  //before or after?
  // deciding on after: ProvenanceWindow/Manager wants the state *after* removal.
  /*emit*/ moduleRemoved_(id);

  printNetwork();
}

ModuleHandle NetworkEditorController::duplicateModule(const ModuleHandle& module)
{
  ENSURE_NOT_NULL(module, "Cannot duplicate null module");
  ModuleId id(module->get_id());
  auto newModule = addModuleImpl(id.name_);
  newModule->set_state(module->get_state()->clone());
  moduleAdded_(id.name_, newModule);

  //TODO: probably a pretty poor way to deal with what I think is a race condition with signaling the GUI to place the module widget.
  boost::this_thread::sleep(boost::posix_time::milliseconds(1));

  for (size_t i = 0; i < module->num_input_ports(); ++i)
  {
    auto input = module->get_input_port(i);
    if (input->nconnections() == 1)
    {
      auto conn = input->connection(0);
      auto source = conn->oport_;
      requestConnection(source.get(), newModule->get_input_port(i).get());
    }
  }

  return newModule;
}

void NetworkEditorController::printNetwork() const
{
  //TODO: and make this switchable
  if (false)
  {
    //TODO: use real logger here
    if (theNetwork_)
      std::cout << theNetwork_->toString() << std::endl;
  }
}

void NetworkEditorController::requestConnection(const SCIRun::Dataflow::Networks::PortDescriptionInterface* from, const SCIRun::Dataflow::Networks::PortDescriptionInterface* to)
{
  ENSURE_NOT_NULL(from, "from port");
  ENSURE_NOT_NULL(to, "to port");

  auto out = from->isInput() ? to : from;
  auto in = from->isInput() ? from : to;

  ConnectionDescription desc(
    OutgoingConnectionDescription(out->getUnderlyingModuleId(), out->getIndex()),
    IncomingConnectionDescription(in->getUnderlyingModuleId(), in->getIndex()));

  PortConnectionDeterminer q;
  if (q.canBeConnected(*from, *to))
  {
    ConnectionId id = theNetwork_->connect(ConnectionOutputPort(theNetwork_->lookupModule(desc.out_.moduleId_), desc.out_.port_),
      ConnectionInputPort(theNetwork_->lookupModule(desc.in_.moduleId_), desc.in_.port_));
    if (!id.id_.empty())
      connectionAdded_(desc);

    printNetwork();
  }
  else
  {
    //TODO: use real logger
    std::cout << "Invalid Connection request: input port is full, or ports are different datatype or same i/o type, or on the same module." << std::endl;
    invalidConnection_(desc);
  }
}

void NetworkEditorController::removeConnection(const ConnectionId& id)
{
  if (theNetwork_->disconnect(id))
    connectionRemoved_(id);
  printNetwork();
}

boost::signals2::connection NetworkEditorController::connectModuleAdded(const ModuleAddedSignalType::slot_type& subscriber)
{
  return moduleAdded_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectModuleRemoved(const ModuleRemovedSignalType::slot_type& subscriber)
{
  return moduleRemoved_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectConnectionAdded(const ConnectionAddedSignalType::slot_type& subscriber)
{
  return connectionAdded_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectConnectionRemoved(const ConnectionRemovedSignalType::slot_type& subscriber)
{
  return connectionRemoved_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectInvalidConnection(const InvalidConnectionSignalType::slot_type& subscriber)
{
  return invalidConnection_.connect(subscriber);
}

boost::signals2::connection NetworkEditorController::connectNetworkExecutionStarts(const ExecuteAllStartsSignalType::slot_type& subscriber)
{
  return ExecutionStrategy::connectNetworkExecutionStarts(subscriber);
}

boost::signals2::connection NetworkEditorController::connectNetworkExecutionFinished(const ExecuteAllFinishesSignalType::slot_type& subscriber)
{
  return ExecutionStrategy::connectNetworkExecutionFinished(subscriber);
}

NetworkFileHandle NetworkEditorController::saveNetwork() const
{
  NetworkToXML conv(modulePositionEditor_);
  return conv.to_xml_data(theNetwork_);
}

void NetworkEditorController::loadNetwork(const NetworkFileHandle& xml)
{
  if (xml)
  {
    NetworkXMLConverter conv(moduleFactory_, stateFactory_);
    theNetwork_ = conv.from_xml_data(xml->network);
    for (size_t i = 0; i < theNetwork_->nmodules(); ++i)
    {
      ModuleHandle module = theNetwork_->module(i);
      moduleAdded_(module->get_module_name(), module);
    }
    BOOST_FOREACH(const ConnectionDescription& cd, theNetwork_->connections())
    {
      ConnectionId id = ConnectionId::create(cd);
      connectionAdded_(cd);
    }
    if (modulePositionEditor_)
      modulePositionEditor_->moveModules(xml->modulePositions);
    else
      std::cout << "module position editor is null" << std::endl;
  }
}

void NetworkEditorController::clear()
{
  //std::cout << "NetworkEditorController::clear()" << std::endl;
}

void NetworkEditorController::executeAll(const ExecutableLookup* lookup)
{
  if (!currentExecutor_)
    currentExecutor_ = executorFactory_->create(ExecutionStrategy::BASIC_PARALLEL); //TODO: read some setting for default executor type

  currentExecutor_->executeAll(*theNetwork_, lookup ? *lookup : *theNetwork_);
}

NetworkHandle NetworkEditorController::getNetwork() const
{
  return theNetwork_;
}

NetworkGlobalSettings& NetworkEditorController::getSettings()
{
  return theNetwork_->settings();
}

void NetworkEditorController::setExecutorType(int type)
{
  currentExecutor_ = executorFactory_->create((ExecutionStrategy::Type)type);
}

<|endoftext|>


<commit_before>// $Id$
//***************************************************************************
// File:
//	MachineInstr.cpp
//
// Purpose:
//
//
// Strategy:
//
// History:
//	7/2/01	 -  Vikram Adve  -  Created
//**************************************************************************/

#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Value.h"
#include <iostream>
using std::cerr;

//************************ Class Implementations **************************/

// Constructor for instructions with fixed #operands (nearly all)
MachineInstr::MachineInstr(MachineOpCode _opCode,
			   OpCodeMask    _opCodeMask)
  : opCode(_opCode),
    opCodeMask(_opCodeMask),
    operands(TargetInstrDescriptors[_opCode].numOperands)
{
  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
}

// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(MachineOpCode _opCode,
			   unsigned	 numOperands,
			   OpCodeMask    _opCodeMask)
  : opCode(_opCode),
    opCodeMask(_opCodeMask),
    operands(numOperands)
{
}

void
MachineInstr::SetMachineOperandVal(unsigned int i,
                                   MachineOperand::MachineOperandType opType,
                                   Value* _val,
                                   bool isdef=false,
                                   bool isDefAndUse=false)
{
  assert(i < operands.size());
  operands[i].Initialize(opType, _val);
  operands[i].isDef = isdef ||
    TargetInstrDescriptors[opCode].resultPos == (int) i;
  operands[i].isDefAndUse = isDefAndUse;
}

void
MachineInstr::SetMachineOperandConst(unsigned int i,
				MachineOperand::MachineOperandType operandType,
                                     int64_t intValue)
{
  assert(i < operands.size());
  assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
         "immed. constant cannot be defined");
  operands[i].InitializeConst(operandType, intValue);
  operands[i].isDef = false;
  operands[i].isDefAndUse = false;
}

void
MachineInstr::SetMachineOperandReg(unsigned int i,
                                   int regNum,
                                   bool isdef=false,
                                   bool isDefAndUse=false,
                                   bool isCCReg=false)
{
  assert(i < operands.size());
  operands[i].InitializeReg(regNum, isCCReg);
  operands[i].isDef = isdef ||
    TargetInstrDescriptors[opCode].resultPos == (int) i;
  operands[i].isDefAndUse = isDefAndUse;
  regsUsed.insert(regNum);
}

void
MachineInstr::SetRegForOperand(unsigned i, int regNum)
{
  operands[i].setRegForValue(regNum);
  regsUsed.insert(regNum);
}

void
MachineInstr::dump() const
{
  cerr << "  " << *this;
}

static inline std::ostream &OutputValue(std::ostream &os,
                                        const Value* val)
{
  os << "(val ";
  if (val && val->hasName())
    return os << val->getName();
  else
    return os << (void*) val;              // print address only
  os << ")";
}

std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
{
  os << TargetInstrDescriptors[minstr.opCode].opCodeString;

  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
    os << "\t" << minstr.getOperand(i);
    if( minstr.operandIsDefined(i) )
      os << "*";
    if( minstr.operandIsDefinedAndUsed(i) )
      os << "*";
  }

  // code for printing implict references
  unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
  if(  NumOfImpRefs > 0 ) {
    os << "\tImplicit: ";
    for(unsigned z=0; z < NumOfImpRefs; z++) {
      OutputValue(os, minstr.getImplicitRef(z));
      if( minstr.implicitRefIsDefined(z)) os << "*";
      if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*";
      os << "\t";
    }
  }

  return os << "\n";
}

static inline std::ostream &OutputOperand(std::ostream &os,
                                          const MachineOperand &mop)
{
  Value* val;
  switch (mop.getOperandType())
    {
    case MachineOperand::MO_CCRegister:
    case MachineOperand::MO_VirtualRegister:
      return OutputValue(os, mop.getVRegValue());
    case MachineOperand::MO_MachineRegister:
      return os << "(" << mop.getMachineRegNum() << ")";
    default:
      assert(0 && "Unknown operand type");
      return os;
    }
}

std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
{
  switch(mop.opType)
    {
    case MachineOperand::MO_VirtualRegister:
    case MachineOperand::MO_MachineRegister:
      os << "%reg";
      return OutputOperand(os, mop);
    case MachineOperand::MO_CCRegister:
      os << "%ccreg";
      return OutputOperand(os, mop);
    case MachineOperand::MO_SignExtendedImmed:
      return os << (long)mop.immedVal;
    case MachineOperand::MO_UnextendedImmed:
      return os << (long)mop.immedVal;
    case MachineOperand::MO_PCRelativeDisp:
      {
        const Value* opVal = mop.getVRegValue();
        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
        os << "%disp(" << (isLabel? "label " : "addr-of-val ");
        if (opVal->hasName())
          os << opVal->getName();
        else
          os << (const void*) opVal;
        return os << ")";
      }
    default:
      assert(0 && "Unrecognized operand type");
      break;
    }

  return os;
}
<commit_msg>Add support for marking each operand as a %hh, %hm, %lm or %lo. Represent previous bools and these ones with flags in a single byte per operand.<commit_after>// $Id$
//***************************************************************************
// File:
//	MachineInstr.cpp
//
// Purpose:
//
//
// Strategy:
//
// History:
//	7/2/01	 -  Vikram Adve  -  Created
//**************************************************************************/

#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Value.h"
#include <iostream>
using std::cerr;

//************************ Class Implementations **************************/

// Constructor for instructions with fixed #operands (nearly all)
MachineInstr::MachineInstr(MachineOpCode _opCode,
			   OpCodeMask    _opCodeMask)
  : opCode(_opCode),
    opCodeMask(_opCodeMask),
    operands(TargetInstrDescriptors[_opCode].numOperands)
{
  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
}

// Constructor for instructions with variable #operands
MachineInstr::MachineInstr(MachineOpCode _opCode,
			   unsigned	 numOperands,
			   OpCodeMask    _opCodeMask)
  : opCode(_opCode),
    opCodeMask(_opCodeMask),
    operands(numOperands)
{
}

void
MachineInstr::SetMachineOperandVal(unsigned int i,
                                   MachineOperand::MachineOperandType opType,
                                   Value* _val,
                                   bool isdef=false,
                                   bool isDefAndUse=false)
{
  assert(i < operands.size());
  operands[i].Initialize(opType, _val);
  if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
    operands[i].markDef();
  if (isDefAndUse)
    operands[i].markDefAndUse();
}

void
MachineInstr::SetMachineOperandConst(unsigned int i,
				MachineOperand::MachineOperandType operandType,
                                     int64_t intValue)
{
  assert(i < operands.size());
  assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
         "immed. constant cannot be defined");
  operands[i].InitializeConst(operandType, intValue);
}

void
MachineInstr::SetMachineOperandReg(unsigned int i,
                                   int regNum,
                                   bool isdef=false,
                                   bool isDefAndUse=false,
                                   bool isCCReg=false)
{
  assert(i < operands.size());
  operands[i].InitializeReg(regNum, isCCReg);
  if (isdef || TargetInstrDescriptors[opCode].resultPos == (int) i)
    operands[i].markDef();
  if (isDefAndUse)
    operands[i].markDefAndUse();
  regsUsed.insert(regNum);
}

void
MachineInstr::SetRegForOperand(unsigned i, int regNum)
{
  operands[i].setRegForValue(regNum);
  regsUsed.insert(regNum);
}

void
MachineInstr::dump() const
{
  cerr << "  " << *this;
}

static inline std::ostream &OutputValue(std::ostream &os,
                                        const Value* val)
{
  os << "(val ";
  if (val && val->hasName())
    return os << val->getName() << ")";
  else
    return os << (void*) val << ")";              // print address only
}

std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
{
  os << TargetInstrDescriptors[minstr.opCode].opCodeString;

  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
    os << "\t" << minstr.getOperand(i);
    if( minstr.operandIsDefined(i) )
      os << "*";
    if( minstr.operandIsDefinedAndUsed(i) )
      os << "*";
  }

  // code for printing implict references
  unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
  if(  NumOfImpRefs > 0 ) {
    os << "\tImplicit: ";
    for(unsigned z=0; z < NumOfImpRefs; z++) {
      OutputValue(os, minstr.getImplicitRef(z));
      if( minstr.implicitRefIsDefined(z)) os << "*";
      if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*";
      os << "\t";
    }
  }

  return os << "\n";
}

std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
{
  if (mop.opHiBits32())
    os << "%lm(";
  else if (mop.opLoBits32())
    os << "%lo(";
  else if (mop.opHiBits64())
    os << "%hh(";
  else if (mop.opLoBits64())
    os << "%hm(";

  switch(mop.opType)
    {
    case MachineOperand::MO_VirtualRegister:
      os << "%reg";
      OutputValue(os, mop.getVRegValue());
      break;
    case MachineOperand::MO_CCRegister:
      os << "%ccreg";
      OutputValue(os, mop.getVRegValue());
      break;
    case MachineOperand::MO_MachineRegister:
      os << "%reg";
      os << "(" << mop.getMachineRegNum() << ")";
      break;
    case MachineOperand::MO_SignExtendedImmed:
      os << (long)mop.immedVal;
      break;
    case MachineOperand::MO_UnextendedImmed:
      os << (long)mop.immedVal;
      break;
    case MachineOperand::MO_PCRelativeDisp:
      {
        const Value* opVal = mop.getVRegValue();
        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
        os << "%disp(" << (isLabel? "label " : "addr-of-val ");
        if (opVal->hasName())
          os << opVal->getName();
        else
          os << (const void*) opVal;
        os << ")";
        break;
      }
    default:
      assert(0 && "Unrecognized operand type");
      break;
    }

  if (mop.flags &
      (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 |
       MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
    os << ")";

  return os;
}
<|endoftext|>


<commit_before>
#include <ImageProcessor.hpp>

#define cimg_use_jpeg
#include <CImg.h>

using namespace cimg_library;

namespace VideoMatch {

static CImg<float>* ph_dct_matrix(const int N)
{
    CImg<float> *ptr_matrix = new CImg<float>(N,N,1,1,1/sqrt((float)N));
    const float c1 = sqrt(2.0/N);
    for (int x=0;x<N;x++){
    for (int y=1;y<N;y++){
        *ptr_matrix->data(x,y) = c1*cos((cimg::PI/2/N)*y*(2*x+1));
    }
    }
    return ptr_matrix;
}

int GetHashCode(const char *filename, uint64_t& result)
{
    if (!filename) {
	    return -1;
    }

    CImg<uint8_t> src;
    try {
	    src.load(filename);
    } catch (CImgIOException ex){
	    return -1;
    }

    CImg<float> meanfilter(7,7,1,1,1);
    CImg<float> img;

    if (src.spectrum() == 3){
        img = src.RGBtoYCbCr().channel(0).get_convolve(meanfilter);
    } else if (src.spectrum() == 4) {
	    int width = img.width();
        int height = img.height();
        int depth = img.depth();
	    img = src.crop(0,0,0,0,width-1,height-1,depth-1,2)
            .RGBtoYCbCr().channel(0).get_convolve(meanfilter);
    } else {
	    img = src.channel(0).get_convolve(meanfilter);
    }

    img.resize(32,32);
    CImg<float> *C  = ph_dct_matrix(32);
    CImg<float> Ctransp = C->get_transpose();
    CImg<float> dctImage = (*C)*img*Ctransp;
    CImg<float> subsec = dctImage.crop(1,1,8,8).unroll('x');;

    float median = subsec.median();
    uint64_t one = 0x0000000000000001;
    result = 0x0000000000000000;
    for (int i=0;i< 64;i++){
	    float current = subsec(i);
        if (current > median)
	        result |= one;
	    one = one << 1;
    }

    delete C;

    return 0;
}

}

<commit_msg>image border crop and mirror added<commit_after>
#include <ImageProcessor.hpp>

#define cimg_use_jpeg
#include <CImg.h>

using namespace cimg_library;

namespace VideoMatch {

static CImg<float>* ph_dct_matrix(const int N)
{
    CImg<float> *ptr_matrix = new CImg<float>(N,N,1,1,1/sqrt((float)N));
    const float c1 = sqrt(2.0/N);
    for (int x=0;x<N;x++){
    for (int y=1;y<N;y++){
        *ptr_matrix->data(x,y) = c1*cos((cimg::PI/2/N)*y*(2*x+1));
    }
    }
    return ptr_matrix;
}

static void crop_border(CImg<float>& img)
{
    static const float SD_DIFF_THRESHOLD = 10.0;
    static const float AVG_DIFF_THRESHOLD = 5.0;
    int x1, x2, y1, y2;
    float last_avg = 0;

    x1 = x2 = y1 = y2 = 0;
    for(int y = 0; y < img.height() / 4; y++) {
        float sum = 0, avg = 0;
        int count = img.width();
        for(int x = 0; x < img.width(); x++) {
            sum += *(img.data(x, y));
        }
        avg = sum / count;
        sum = 0;
        for(int x = 0; x < img.width(); x++) {
            sum += pow(avg - *(img.data(x, y)), 2);
        }
        sum /= count;
        sum = sqrt(sum);
        float avg_diff = avg - last_avg;
        if (avg_diff < 0) avg_diff = -avg_diff;
        if (sum > SD_DIFF_THRESHOLD ||
                (y != 0 && avg_diff > AVG_DIFF_THRESHOLD)) {
            y1 = y;
            break;
        }
        last_avg = avg;
    }

    for(int y = 0; y < img.height() / 4; y++) {
        float sum = 0, avg = 0;
        int count = img.width();
        for(int x = 0; x < img.width(); x++) {
            sum += *(img.data(x, img.height() - 1 - y));
        }
        avg = sum / count;
        sum = 0;
        for(int x = 0; x < img.width(); x++) {
            sum += pow(avg - *(img.data(x, img.height() - 1 - y)), 2);
        }
        sum /= count;
        sum = sqrt(sum);
        float avg_diff = avg - last_avg;
        if (avg_diff < 0) avg_diff = -avg_diff;
        if (sum > SD_DIFF_THRESHOLD ||
                (y != 0 && avg_diff > AVG_DIFF_THRESHOLD)) {
            y2 = img.height() - y;
            break;
        }
        last_avg = avg;
    }

    for(int x = 0; x < img.width() / 4; x++) {
        float sum = 0, avg = 0;
        int count = img.width();
        for(int y = 0; y < img.height(); y++) {
            sum += *(img.data(x, y));
        }
        avg = sum / count;
        sum = 0;
        for(int y = 0; y < img.height(); y++) {
            sum += pow(avg - *(img.data(x, y)), 2);
        }
        sum /= count;
        sum = sqrt(sum);
        float avg_diff = avg - last_avg;
        if (avg_diff < 0) avg_diff = -avg_diff;
        if (sum > SD_DIFF_THRESHOLD ||
                (x != 0 && avg_diff > AVG_DIFF_THRESHOLD)) {
            x1 = x;
            break;
        }
        last_avg = avg;
    }

    for(int x = 0; x < img.width() / 4; x++) {
        float sum = 0, avg = 0;
        int count = img.width();
        for(int y = 0; y < img.height(); y++) {
            sum += *(img.data(img.width() - 1 - x, y));
        }
        avg = sum / count;
        sum = 0;
        for(int y = 0; y < img.height(); y++) {
            sum += pow(avg - *(img.data(img.width() - 1 - x, y)), 2);
        }
        sum /= count;
        sum = sqrt(sum);
        float avg_diff = avg - last_avg;
        if (avg_diff < 0) avg_diff = -avg_diff;
        if (sum > SD_DIFF_THRESHOLD ||
                (x != 0 && avg_diff > AVG_DIFF_THRESHOLD)) {
            x2 = img.width() - x;
            break;
        }
        last_avg = avg;
    }

    int nw = x2 - x1;
    int nh = y2 - y1;
    x1 += nw * 0.1;
    x2 -= nw * 0.1;
    y1 += nh * 0.1;
    y2 -= nh * 0.1;

    img.crop(x1, y1, 0, x2, y2, 0);
}

static void mirror(CImg<float>& img)
{
    float suma, sumb;
    /*
    suma = sumb = 0;
    for(int y = 0; y < img.height() / 2; y++) {
        for(int x = 0; x < img.width(); x++) {
            suma += *(img.data(x, y));
            sumb += *(img.data(x, img.height() - 1 - y));
        }
    }
    if (suma < sumb)
        img.mirror('y');
    */

    suma = sumb = 0;
    for(int x = 0; x < img.width() / 2; x++) {
        for(int y = 0; y < img.height(); y++) {
            suma += *(img.data(x, y));
            sumb += *(img.data(img.width() - 1 - x, y));
        }
    }
    if (suma < sumb)
        img.mirror('x');
}

int GetHashCode(const char *filename, uint64_t& result)
{
    if (!filename) {
	    return -1;
    }

    CImg<uint8_t> src;
    try {
	    src.load(filename);
    } catch (CImgIOException ex){
	    return -1;
    }

    CImg<float> meanfilter(7,7,1,1,1);
    CImg<float> img;
    CImg<float> c0;

    if (src.spectrum() == 3){
        c0 = src.RGBtoYCbCr().channel(0);
    } else if (src.spectrum() == 4) {
	    int width = img.width();
        int height = img.height();
        int depth = img.depth();
	    c0 = src.crop(0,0,0,0,width-1,height-1,depth-1,2)
            .RGBtoYCbCr().channel(0);
    } else {
	    c0 = src.channel(0);
    }

    crop_border(c0);
    mirror(c0);
    img = c0.get_convolve(meanfilter);
    img.resize(32,32);
    CImg<float> *C  = ph_dct_matrix(32);
    CImg<float> Ctransp = C->get_transpose();
    CImg<float> dctImage = (*C)*img*Ctransp;
    CImg<float> subsec = dctImage.crop(1,1,8,8).unroll('x');;

    float median = subsec.median();
    uint64_t one = 0x0000000000000001;
    result = 0x0000000000000000;
    for (int i=0;i< 64;i++){
	    float current = subsec(i);
        if (current > median)
	        result |= one;
	    one = one << 1;
    }

    delete C;

    return 0;
}

}

<|endoftext|>