<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* bzflag special common - 1st one */
#include "common.h"

#include <iostream>
#include <string>

#include "ActionBinding.h"
#include "CommandManager.h"
#include "KeyManager.h"

// initialize the singleton
template <>
ActionBinding* Singleton<ActionBinding>::_instance = (ActionBinding*)0;

ActionBinding::ActionBinding() {
  wayToBindActions.insert(std::make_pair(std::string("quit"), press));
  wayToBindActions.insert(std::make_pair(std::string("fire"), both));
  wayToBindActions.insert(std::make_pair(std::string("drop"), press));
  wayToBindActions.insert(std::make_pair(std::string("identify"), press));
  wayToBindActions.insert(std::make_pair(std::string("jump"), press));
  wayToBindActions.insert(std::make_pair(std::string("send all"), press));
  wayToBindActions.insert(std::make_pair(std::string("send team"), press));
  wayToBindActions.insert(std::make_pair(std::string("send nemesis"), press));
  wayToBindActions.insert(std::make_pair(std::string("send recipient"), press));
  wayToBindActions.insert(std::make_pair(std::string("send admin"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayScore"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayBinoculars"), press));
  wayToBindActions.insert(std::make_pair(std::string("pause"), press));
  wayToBindActions.insert(std::make_pair(std::string("fullscreen"), press));
  wayToBindActions.insert(std::make_pair(std::string("iconify"), press));
#ifdef SNAPPING
  wayToBindActions.insert(std::make_pair(std::string("screenshot"), press));
#endif
  wayToBindActions.insert(std::make_pair(std::string("time backward"), press));
  wayToBindActions.insert(std::make_pair(std::string("time forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleConsoleAndRadar"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleFlags radar"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleFlags main"), press));
  wayToBindActions.insert(std::make_pair(std::string("silence"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayLabels"), press));
  wayToBindActions.insert(std::make_pair(std::string("destruct"), press));

  // Movement keys
  wayToBindActions.insert(std::make_pair(std::string("turn left"), both));
  wayToBindActions.insert(std::make_pair(std::string("turn right"), both));
  wayToBindActions.insert(std::make_pair(std::string("drive forward"), both));
  wayToBindActions.insert(std::make_pair(std::string("drive reverse"), both));
  // End movement keys

  wayToBindActions.insert(std::make_pair(std::string("roam cycle subject backward"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("roam cycle subject forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("roam cycle type forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom in"), both));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom out"), both));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom normal"), both));
  wayToBindActions.insert(std::make_pair(std::string("servercommand"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayFlagHelp"), press));
  wayToBindActions.insert(std::make_pair(std::string("scrollpanel up"), press));
  wayToBindActions.insert(std::make_pair(std::string("scrollpanel down"), press));
  wayToBindActions.insert(std::make_pair(std::string("radarZoom in"), press));
  wayToBindActions.insert(std::make_pair(std::string("radarZoom out"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 0.25"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 0.5"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 1.0"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle slowKeyboard"), press));
  wayToBindActions.insert(std::make_pair(std::string("hunt"), press));
  wayToBindActions.insert(std::make_pair(std::string("restart"), release));
  wayToBindActions.insert(std::make_pair(std::string("autopilot"), press));

  wayToBindActions.insert(std::make_pair(std::string("messagepanel all"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel chat"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel server"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel misc"),
					 press));

  defaultBinding.insert(std::make_pair(std::string("F12"), std::string("quit")));
  defaultBinding.insert(std::make_pair(std::string("Left Mouse"), std::string("fire")));
  defaultBinding.insert(std::make_pair(std::string("Enter"), std::string("fire")));
  defaultBinding.insert(std::make_pair(std::string("Middle Mouse"), std::string("drop")));
  defaultBinding.insert(std::make_pair(std::string("Space"), std::string("drop")));
  defaultBinding.insert(std::make_pair(std::string("Right Mouse"), std::string("identify")));
  defaultBinding.insert(std::make_pair(std::string("I"), std::string("identify")));
  defaultBinding.insert(std::make_pair(std::string("Tab"), std::string("jump")));
  defaultBinding.insert(std::make_pair(std::string("N"), std::string("send all")));
  defaultBinding.insert(std::make_pair(std::string("M"), std::string("send team")));
  defaultBinding.insert(std::make_pair(std::string(","), std::string("send nemesis")));
  defaultBinding.insert(std::make_pair(std::string("."), std::string("send recipient")));
  defaultBinding.insert(std::make_pair(std::string("Z"), std::string("send admin")));
  defaultBinding.insert(std::make_pair(std::string("S"), std::string("toggle displayScore")));
  defaultBinding.insert(std::make_pair(std::string("B"), std::string("toggle displayBinoculars")));
  defaultBinding.insert(std::make_pair(std::string("Pause"), std::string("pause")));
  defaultBinding.insert(std::make_pair(std::string("P"), std::string("pause")));
  defaultBinding.insert(std::make_pair(std::string("F1"), std::string("fullscreen")));
  defaultBinding.insert(std::make_pair(std::string("F3"), std::string("toggleConsoleAndRadar")));
  defaultBinding.insert(std::make_pair(std::string("F4"), std::string("iconify")));
#ifdef SNAPPING
  defaultBinding.insert(std::make_pair(std::string("F5"), std::string("screenshot")));
#endif
  defaultBinding.insert(std::make_pair(std::string("-"), std::string("time backward")));
  defaultBinding.insert(std::make_pair(std::string("="), std::string("time forward")));
  defaultBinding.insert(std::make_pair(std::string("H"), std::string("toggleFlags radar")));
  defaultBinding.insert(std::make_pair(std::string("J"), std::string("toggleFlags main")));
  defaultBinding.insert(std::make_pair(std::string("K"), std::string("silence")));
  defaultBinding.insert(std::make_pair(std::string("L"), std::string("toggle displayLabels")));
  defaultBinding.insert(std::make_pair(std::string("Delete"), std::string("destruct")));

  // Default movement keys
  defaultBinding.insert(std::make_pair(std::string("Left Arrow"),
				       std::string("turn left")));
  defaultBinding.insert(std::make_pair(std::string("Right Arrow"),
				       std::string("turn right")));
  defaultBinding.insert(std::make_pair(std::string("Up Arrow"),
				       std::string("drive forward")));
  defaultBinding.insert(std::make_pair(std::string("Down Arrow"),
				       std::string("drive reverse")));
  // End default movement keys

  defaultBinding.insert(std::make_pair(std::string("Wheel Up"),
				       std::string("radarZoom in")));
  defaultBinding.insert(std::make_pair(std::string("Wheel Down"),
				       std::string("radarZoom out")));

  defaultBinding.insert(std::make_pair(std::string("F6"), std::string("roam cycle subject backward")));
  defaultBinding.insert(std::make_pair(std::string("F7"), std::string("roam cycle subject forward")));
  defaultBinding.insert(std::make_pair(std::string("F8"), std::string("roam cycle type forward")));
  defaultBinding.insert(std::make_pair(std::string("F9"), std::string("roam zoom in")));
  defaultBinding.insert(std::make_pair(std::string("F10"), std::string("roam zoom out")));
  defaultBinding.insert(std::make_pair(std::string("F11"), std::string("roam zoom normal")));
  defaultBinding.insert(std::make_pair(std::string("O"), std::string("servercommand")));
  defaultBinding.insert(std::make_pair(std::string("F"), std::string("toggle displayFlagHelp")));
  defaultBinding.insert(std::make_pair(std::string("Page Up"), std::string("scrollpanel up")));
  defaultBinding.insert(std::make_pair(std::string("Page Down"), std::string("scrollpanel down")));
  defaultBinding.insert(std::make_pair(std::string("1"), std::string("set displayRadarRange 0.25")));
  defaultBinding.insert(std::make_pair(std::string("2"), std::string("set displayRadarRange 0.5")));
  defaultBinding.insert(std::make_pair(std::string("3"), std::string("set displayRadarRange 1.0")));
  defaultBinding.insert(std::make_pair(std::string("A"), std::string("toggle slowKeyboard")));
  defaultBinding.insert(std::make_pair(std::string("U"), std::string("hunt")));
  defaultBinding.insert(std::make_pair(std::string("Right Mouse"), std::string("restart")));
  defaultBinding.insert(std::make_pair(std::string("I"), std::string("restart")));
  defaultBinding.insert(std::make_pair(std::string("9"), std::string("autopilot")));

  defaultBinding.insert(std::make_pair(std::string("Shift+F1"),
				       std::string("messagepanel all")));
  defaultBinding.insert(std::make_pair(std::string("Shift+F2"),
				       std::string("messagepanel chat")));
  defaultBinding.insert(std::make_pair(std::string("Shift+F3"),
				       std::string("messagepanel server")));
  defaultBinding.insert(std::make_pair(std::string("Shift+F4"),
				       std::string("messagepanel misc")));
}

void ActionBinding::resetBindings() {
  BindingTable::const_iterator index;

  for (index = bindingTable.begin();
       index != bindingTable.end();
       ++index)
    unbind(index->second, index->first);

  bindingTable = defaultBinding;

  for (index = bindingTable.begin();
       index != bindingTable.end();
       ++index)
    bind(index->second, index->first);
}

void ActionBinding::getFromBindings() {
  bindingTable.clear();
  KEYMGR.iterate(&onScanCB, this);
}

void ActionBinding::onScanCB(const std::string& name, bool,
			     const std::string& cmd, void*)
{
  ActionBinding::instance().associate(name, cmd, false);
}

void ActionBinding::associate(std::string key,
			      std::string action,
			      bool        keyBind) {
  BindingTable::iterator index, next;
  if (!wayToBindActions.count(action))
    return;
  PressStatusBind newStatusBind = wayToBindActions[action];
  for (index = bindingTable.lower_bound( key ); index != bindingTable.upper_bound( key ); index = next) {
    next = index;
    ++next;
    if (newStatusBind == both) {
      if (keyBind)
	unbind(index->second, key);
      bindingTable.erase(index);
    } else if (newStatusBind == press) {
      if (wayToBindActions[index->second] != release) {
	if (keyBind)
	  unbind(index->second, key);
	bindingTable.erase(index);
      }
    } else {
      if (wayToBindActions[index->second] != press) {
	if (keyBind)
	  unbind(index->second, key);
	bindingTable.erase(index);
      }
    }
  }
  bindingTable.insert(std::make_pair(key, action));
  if (keyBind)
    bind(action, key);
};

void ActionBinding::deassociate(std::string action) {
  BindingTable::iterator index, next;
  for (index = bindingTable.begin();
       index != bindingTable.end();
       index = next) {
    next = index;
    ++next;
    if (index->second == action) {
      unbind(action, index->first);
      bindingTable.erase(index);
    }
  }
};

void ActionBinding::bind(std::string action, std::string key) {
  PressStatusBind statusBind = wayToBindActions[action];
  std::string command;
  if (statusBind == press || statusBind == both) {
    command = "bind \"" + key + "\" down \"" + action + "\"";
    CMDMGR.run(command);
  };
  if (statusBind == release || statusBind == both) {
    command = "bind \"" + key + "\" up \"" + action + "\"";
    CMDMGR.run(command);
  };
}

void ActionBinding::unbind(std::string action, std::string key) {
  PressStatusBind statusBind = wayToBindActions[action];
  std::string command;
  if (statusBind == press || statusBind == both) {
    command = "unbind \"" + key + "\" down";
    CMDMGR.run(command);
  };
  if (statusBind == release || statusBind == both) {
    command = "unbind \"" + key + "\" up";
    CMDMGR.run(command);
  };
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>Using wheel to scroll chat area, moving RadarZoom to Wheel+Shift<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* bzflag special common - 1st one */
#include "common.h"

#include <iostream>
#include <string>

#include "ActionBinding.h"
#include "CommandManager.h"
#include "KeyManager.h"

// initialize the singleton
template <>
ActionBinding* Singleton<ActionBinding>::_instance = (ActionBinding*)0;

ActionBinding::ActionBinding() {
  wayToBindActions.insert(std::make_pair(std::string("quit"), press));
  wayToBindActions.insert(std::make_pair(std::string("fire"), both));
  wayToBindActions.insert(std::make_pair(std::string("drop"), press));
  wayToBindActions.insert(std::make_pair(std::string("identify"), press));
  wayToBindActions.insert(std::make_pair(std::string("jump"), press));
  wayToBindActions.insert(std::make_pair(std::string("send all"), press));
  wayToBindActions.insert(std::make_pair(std::string("send team"), press));
  wayToBindActions.insert(std::make_pair(std::string("send nemesis"), press));
  wayToBindActions.insert(std::make_pair(std::string("send recipient"), press));
  wayToBindActions.insert(std::make_pair(std::string("send admin"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayScore"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayBinoculars"), press));
  wayToBindActions.insert(std::make_pair(std::string("pause"), press));
  wayToBindActions.insert(std::make_pair(std::string("fullscreen"), press));
  wayToBindActions.insert(std::make_pair(std::string("iconify"), press));
#ifdef SNAPPING
  wayToBindActions.insert(std::make_pair(std::string("screenshot"), press));
#endif
  wayToBindActions.insert(std::make_pair(std::string("time backward"), press));
  wayToBindActions.insert(std::make_pair(std::string("time forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleConsoleAndRadar"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleFlags radar"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleFlags main"), press));
  wayToBindActions.insert(std::make_pair(std::string("silence"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayLabels"), press));
  wayToBindActions.insert(std::make_pair(std::string("destruct"), press));

  // Movement keys
  wayToBindActions.insert(std::make_pair(std::string("turn left"), both));
  wayToBindActions.insert(std::make_pair(std::string("turn right"), both));
  wayToBindActions.insert(std::make_pair(std::string("drive forward"), both));
  wayToBindActions.insert(std::make_pair(std::string("drive reverse"), both));
  // End movement keys

  wayToBindActions.insert(std::make_pair(std::string("roam cycle subject backward"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("roam cycle subject forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("roam cycle type forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom in"), both));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom out"), both));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom normal"), both));
  wayToBindActions.insert(std::make_pair(std::string("servercommand"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayFlagHelp"), press));
  wayToBindActions.insert(std::make_pair(std::string("scrollpanel up"), press));
  wayToBindActions.insert(std::make_pair(std::string("scrollpanel down"), press));
  wayToBindActions.insert(std::make_pair(std::string("radarZoom in"), press));
  wayToBindActions.insert(std::make_pair(std::string("radarZoom out"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 0.25"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 0.5"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 1.0"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle slowKeyboard"), press));
  wayToBindActions.insert(std::make_pair(std::string("hunt"), press));
  wayToBindActions.insert(std::make_pair(std::string("restart"), release));
  wayToBindActions.insert(std::make_pair(std::string("autopilot"), press));

  wayToBindActions.insert(std::make_pair(std::string("messagepanel all"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel chat"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel server"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel misc"),
					 press));

  defaultBinding.insert(std::make_pair(std::string("F12"), std::string("quit")));
  defaultBinding.insert(std::make_pair(std::string("Left Mouse"), std::string("fire")));
  defaultBinding.insert(std::make_pair(std::string("Enter"), std::string("fire")));
  defaultBinding.insert(std::make_pair(std::string("Middle Mouse"), std::string("drop")));
  defaultBinding.insert(std::make_pair(std::string("Space"), std::string("drop")));
  defaultBinding.insert(std::make_pair(std::string("Right Mouse"), std::string("identify")));
  defaultBinding.insert(std::make_pair(std::string("I"), std::string("identify")));
  defaultBinding.insert(std::make_pair(std::string("Tab"), std::string("jump")));
  defaultBinding.insert(std::make_pair(std::string("N"), std::string("send all")));
  defaultBinding.insert(std::make_pair(std::string("M"), std::string("send team")));
  defaultBinding.insert(std::make_pair(std::string(","), std::string("send nemesis")));
  defaultBinding.insert(std::make_pair(std::string("."), std::string("send recipient")));
  defaultBinding.insert(std::make_pair(std::string("Z"), std::string("send admin")));
  defaultBinding.insert(std::make_pair(std::string("S"), std::string("toggle displayScore")));
  defaultBinding.insert(std::make_pair(std::string("B"), std::string("toggle displayBinoculars")));
  defaultBinding.insert(std::make_pair(std::string("Pause"), std::string("pause")));
  defaultBinding.insert(std::make_pair(std::string("P"), std::string("pause")));
  defaultBinding.insert(std::make_pair(std::string("F1"), std::string("fullscreen")));
  defaultBinding.insert(std::make_pair(std::string("F3"), std::string("toggleConsoleAndRadar")));
  defaultBinding.insert(std::make_pair(std::string("F4"), std::string("iconify")));
#ifdef SNAPPING
  defaultBinding.insert(std::make_pair(std::string("F5"), std::string("screenshot")));
#endif
  defaultBinding.insert(std::make_pair(std::string("-"), std::string("time backward")));
  defaultBinding.insert(std::make_pair(std::string("="), std::string("time forward")));
  defaultBinding.insert(std::make_pair(std::string("H"), std::string("toggleFlags radar")));
  defaultBinding.insert(std::make_pair(std::string("J"), std::string("toggleFlags main")));
  defaultBinding.insert(std::make_pair(std::string("K"), std::string("silence")));
  defaultBinding.insert(std::make_pair(std::string("L"), std::string("toggle displayLabels")));
  defaultBinding.insert(std::make_pair(std::string("Delete"), std::string("destruct")));

  // Default movement keys
  defaultBinding.insert(std::make_pair(std::string("Left Arrow"),
				       std::string("turn left")));
  defaultBinding.insert(std::make_pair(std::string("Right Arrow"),
				       std::string("turn right")));
  defaultBinding.insert(std::make_pair(std::string("Up Arrow"),
				       std::string("drive forward")));
  defaultBinding.insert(std::make_pair(std::string("Down Arrow"),
				       std::string("drive reverse")));
  // End default movement keys

  defaultBinding.insert(std::make_pair(std::string("Shift+Wheel Up"),
				       std::string("radarZoom in")));
  defaultBinding.insert(std::make_pair(std::string("Shift+Wheel Down"),
				       std::string("radarZoom out")));

  defaultBinding.insert(std::make_pair(std::string("F6"), std::string("roam cycle subject backward")));
  defaultBinding.insert(std::make_pair(std::string("F7"), std::string("roam cycle subject forward")));
  defaultBinding.insert(std::make_pair(std::string("F8"), std::string("roam cycle type forward")));
  defaultBinding.insert(std::make_pair(std::string("F9"), std::string("roam zoom in")));
  defaultBinding.insert(std::make_pair(std::string("F10"), std::string("roam zoom out")));
  defaultBinding.insert(std::make_pair(std::string("F11"), std::string("roam zoom normal")));
  defaultBinding.insert(std::make_pair(std::string("O"), std::string("servercommand")));
  defaultBinding.insert(std::make_pair(std::string("F"), std::string("toggle displayFlagHelp")));
  defaultBinding.insert(std::make_pair(std::string("Page Up"),
				       std::string("scrollpanel up")));
  defaultBinding.insert(std::make_pair(std::string("Wheel Up"),
				       std::string("scrollpanel up")));
  defaultBinding.insert(std::make_pair(std::string("Wheel Down"),
				       std::string("scrollpanel down")));
  defaultBinding.insert(std::make_pair(std::string("1"), std::string("set displayRadarRange 0.25")));
  defaultBinding.insert(std::make_pair(std::string("2"), std::string("set displayRadarRange 0.5")));
  defaultBinding.insert(std::make_pair(std::string("3"), std::string("set displayRadarRange 1.0")));
  defaultBinding.insert(std::make_pair(std::string("A"), std::string("toggle slowKeyboard")));
  defaultBinding.insert(std::make_pair(std::string("U"), std::string("hunt")));
  defaultBinding.insert(std::make_pair(std::string("Right Mouse"), std::string("restart")));
  defaultBinding.insert(std::make_pair(std::string("I"), std::string("restart")));
  defaultBinding.insert(std::make_pair(std::string("9"), std::string("autopilot")));

  defaultBinding.insert(std::make_pair(std::string("Shift+F1"),
				       std::string("messagepanel all")));
  defaultBinding.insert(std::make_pair(std::string("Shift+F2"),
				       std::string("messagepanel chat")));
  defaultBinding.insert(std::make_pair(std::string("Shift+F3"),
				       std::string("messagepanel server")));
  defaultBinding.insert(std::make_pair(std::string("Shift+F4"),
				       std::string("messagepanel misc")));
}

void ActionBinding::resetBindings() {
  BindingTable::const_iterator index;

  for (index = bindingTable.begin();
       index != bindingTable.end();
       ++index)
    unbind(index->second, index->first);

  bindingTable = defaultBinding;

  for (index = bindingTable.begin();
       index != bindingTable.end();
       ++index)
    bind(index->second, index->first);
}

void ActionBinding::getFromBindings() {
  bindingTable.clear();
  KEYMGR.iterate(&onScanCB, this);
}

void ActionBinding::onScanCB(const std::string& name, bool,
			     const std::string& cmd, void*)
{
  ActionBinding::instance().associate(name, cmd, false);
}

void ActionBinding::associate(std::string key,
			      std::string action,
			      bool        keyBind) {
  BindingTable::iterator index, next;
  if (!wayToBindActions.count(action))
    return;
  PressStatusBind newStatusBind = wayToBindActions[action];
  for (index = bindingTable.lower_bound( key ); index != bindingTable.upper_bound( key ); index = next) {
    next = index;
    ++next;
    if (newStatusBind == both) {
      if (keyBind)
	unbind(index->second, key);
      bindingTable.erase(index);
    } else if (newStatusBind == press) {
      if (wayToBindActions[index->second] != release) {
	if (keyBind)
	  unbind(index->second, key);
	bindingTable.erase(index);
      }
    } else {
      if (wayToBindActions[index->second] != press) {
	if (keyBind)
	  unbind(index->second, key);
	bindingTable.erase(index);
      }
    }
  }
  bindingTable.insert(std::make_pair(key, action));
  if (keyBind)
    bind(action, key);
};

void ActionBinding::deassociate(std::string action) {
  BindingTable::iterator index, next;
  for (index = bindingTable.begin();
       index != bindingTable.end();
       index = next) {
    next = index;
    ++next;
    if (index->second == action) {
      unbind(action, index->first);
      bindingTable.erase(index);
    }
  }
};

void ActionBinding::bind(std::string action, std::string key) {
  PressStatusBind statusBind = wayToBindActions[action];
  std::string command;
  if (statusBind == press || statusBind == both) {
    command = "bind \"" + key + "\" down \"" + action + "\"";
    CMDMGR.run(command);
  };
  if (statusBind == release || statusBind == both) {
    command = "bind \"" + key + "\" up \"" + action + "\"";
    CMDMGR.run(command);
  };
}

void ActionBinding::unbind(std::string action, std::string key) {
  PressStatusBind statusBind = wayToBindActions[action];
  std::string command;
  if (statusBind == press || statusBind == both) {
    command = "unbind \"" + key + "\" down";
    CMDMGR.run(command);
  };
  if (statusBind == release || statusBind == both) {
    command = "unbind \"" + key + "\" up";
    CMDMGR.run(command);
  };
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include <crpcut.hpp>
#include <stdio.h>
#include <pthread.h>

#include <coincident/coincident.h>

/*
 * The code below is not stupid, but VERY stupid.
 *
 * However, it's just for testing coincident.
 */
int global;

int add_val(int v)
{
	global += v;

	return global;
}

static int test_race(void *params)
{
	global = 1;

	ASSERT_TRUE(global == 1);

	int v = add_val(1);
	ASSERT_TRUE(v == 2);

	ASSERT_TRUE(v == global);

	return 0;
}

static int test_pthreads_non_race(void *params)
{
	pthread_mutex_t *mutex = (pthread_mutex_t *)params;

	pthread_mutex_lock(mutex);
	global = 1;

	ASSERT_TRUE(global == 1);

	int v = add_val(1);
	ASSERT_TRUE(v == 2);

	ASSERT_TRUE(v == global);
	pthread_mutex_unlock(mutex);

	return 0;
}

static int test_pthreads_race(void *params)
{
	pthread_mutex_t *mutex = (pthread_mutex_t *)params;

	pthread_mutex_lock(mutex);
	global = 1;

	ASSERT_TRUE(global == 1);
	pthread_mutex_unlock(mutex);

	pthread_mutex_lock(mutex);
	int v = add_val(1);
	ASSERT_TRUE(v == 2);

	ASSERT_TRUE(v == global);
	pthread_mutex_unlock(mutex);

	return 0;
}

// Same as above, but without races (stack allocated stuff)
int add_val_non_race(int *src, int v)
{
	*src += v;

	return *src;
}

static int test_non_race(void *params)
{
	int src = 1;

	ASSERT_TRUE(src == 1);

	int v = add_val_non_race(&src, 1);
	ASSERT_TRUE(v == 2);

	ASSERT_TRUE(v == src);

	return 0;
}

TESTSUITE(coincident)
{
	TEST(basic_race)
	{
		coincident_add_thread(test_race, NULL);
		coincident_add_thread(test_race, NULL);

		coincident_set_run_limit(10);

		int result = coincident_run();
		ASSERT_TRUE(result == 0);
	}

	TEST(basic_non_race)
	{
		coincident_add_thread(test_race, NULL);
		coincident_add_thread(test_non_race, NULL);
		coincident_add_thread(test_non_race, NULL);

		// Stop after 500 ms
		coincident_set_time_limit(500);

		int result = coincident_run();
		ASSERT_TRUE(result == 0);
	}

	TEST(pthreads_non_race)
	{
		pthread_mutex_t mutex;

		pthread_mutex_init(&mutex, NULL);

		coincident_add_thread(test_pthreads_non_race, &mutex);
		coincident_add_thread(test_pthreads_non_race, &mutex);

		coincident_set_time_limit(1000);

		int result = coincident_run();
		ASSERT_TRUE(result == 0);
	}

	TEST(pthreads_race)
	{
		pthread_mutex_t mutex;

		pthread_mutex_init(&mutex, NULL);

		coincident_add_thread(test_pthreads_race, &mutex);
		coincident_add_thread(test_pthreads_race, &mutex);

		coincident_set_time_limit(1000);

		int result = coincident_run();
		ASSERT_TRUE(result == 0);
	}
}

int main(int argc, const char *argv[])
{
	// We use random scheduling here, so this actually affects
	// the result
	srand(time(NULL));

	coincident_init();

	return crpcut::run(argc, argv);
}
<commit_msg>self-test: Add gmock tests (to catch a pthread_self() error)<commit_after>#include <stdio.h>
#include <pthread.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <crpcut.hpp>

#include <coincident/coincident.h>
#include <coincident/controller.hh>

using namespace testing;

/*
 * The code below is not stupid, but VERY stupid.
 *
 * However, it's just for testing coincident.
 */
int global;

int add_val(int v)
{
	global += v;

	return global;
}

static int test_race(void *params)
{
	global = 1;

	ASSERT_TRUE(global == 1);

	int v = add_val(1);
	ASSERT_TRUE(v == 2);

	ASSERT_TRUE(v == global);

	return 0;
}

static int test_pthreads_non_race(void *params)
{
	pthread_mutex_t *mutex = (pthread_mutex_t *)params;

	pthread_mutex_lock(mutex);
	global = 1;

	ASSERT_TRUE(global == 1);

	int v = add_val(1);
	ASSERT_TRUE(v == 2);

	ASSERT_TRUE(v == global);
	pthread_mutex_unlock(mutex);

	return 0;
}

static int test_pthreads_race(void *params)
{
	pthread_mutex_t *mutex = (pthread_mutex_t *)params;

	pthread_mutex_lock(mutex);
	global = 1;

	ASSERT_TRUE(global == 1);
	pthread_mutex_unlock(mutex);

	pthread_mutex_lock(mutex);
	int v = add_val(1);
	ASSERT_TRUE(v == 2);

	ASSERT_TRUE(v == global);
	pthread_mutex_unlock(mutex);

	return 0;
}

// Same as above, but without races (stack allocated stuff)
int add_val_non_race(int *src, int v)
{
	*src += v;

	return *src;
}

static int test_non_race(void *params)
{
	int src = 1;

	ASSERT_TRUE(src == 1);

	int v = add_val_non_race(&src, 1);
	ASSERT_TRUE(v == 2);

	ASSERT_TRUE(v == src);

	return 0;
}

class GMockTest
{
public:
	MOCK_METHOD1(test1, void(int a));
	MOCK_METHOD0(test2, int());
};

static int test_gmock_mock_in_function(void *p)
{
	GMockTest mock;

	EXPECT_CALL(mock, test1(_))
	.Times(AtLeast(1));
	EXPECT_CALL(mock, test2())
	.Times(AtLeast(1));

	mock.test1(5);
	mock.test2();

	return 0;
}

static int test_gmock(void *p)
{
	GMockTest *mock = (GMockTest *)p;

	mock->test1(5);
	mock->test2();

	return 0;
}

static int test_gmock_expect_in_function(void *p)
{
	GMockTest *mock = (GMockTest *)p;

	EXPECT_CALL(*mock, test1(_))
	.Times(AtLeast(1));

	mock->test1(5);

	return 0;
}

TESTSUITE(coincident)
{
	TEST(basic_race)
	{
		coincident_add_thread(test_race, NULL);
		coincident_add_thread(test_race, NULL);

		coincident_set_run_limit(10);

		int result = coincident_run();
		ASSERT_TRUE(result == 0);
	}

	TEST(basic_non_race)
	{
		coincident_add_thread(test_race, NULL);
		coincident_add_thread(test_non_race, NULL);
		coincident_add_thread(test_non_race, NULL);

		// Stop after 500 ms
		coincident_set_time_limit(500);

		int result = coincident_run();
		ASSERT_TRUE(result == 0);
	}

	TEST(pthreads_non_race)
	{
		pthread_mutex_t mutex;

		pthread_mutex_init(&mutex, NULL);

		coincident_add_thread(test_pthreads_non_race, &mutex);
		coincident_add_thread(test_pthreads_non_race, &mutex);

		coincident_set_time_limit(1000);

		int result = coincident_run();
		ASSERT_TRUE(result == 0);
	}

	TEST(pthreads_race)
	{
		pthread_mutex_t mutex;

		pthread_mutex_init(&mutex, NULL);

		coincident_add_thread(test_pthreads_race, &mutex);
		coincident_add_thread(test_pthreads_race, &mutex);

		coincident_set_time_limit(1000);

		int result = coincident_run();
		ASSERT_TRUE(result == 0);
	}

	TEST(gmock_expectations_in_test_function)
	{
		GMockTest mock;

		test_gmock_expect_in_function((void *)&mock);

		coincident_add_thread(test_gmock_expect_in_function, (void *)&mock);
		coincident_set_time_limit(1000);

		int result = coincident_run();
		if (result != 0)
			printf("ERROR: %s\n", coincident::IController::getInstance().getError());
		ASSERT_TRUE(result == 0);
	}

	TEST(gmock_expectations)
	{
		GMockTest mock;

		EXPECT_CALL(mock, test1(_))
		.Times(AtLeast(1));

		coincident_add_thread(test_gmock, (void *)&mock);
		coincident_set_time_limit(1000);

		int result = coincident_run();
		if (result != 0)
			printf("ERROR: %s\n", coincident::IController::getInstance().getError());
		ASSERT_TRUE(result == 0);
	}

	TEST(gmock_mock_in_function)
	{
		coincident_add_thread(test_gmock_mock_in_function, NULL);
		coincident_set_time_limit(1000);

		int result = coincident_run();
		if (result != 0)
			printf("ERROR: %s\n", coincident::IController::getInstance().getError());
		ASSERT_TRUE(result == 0);
	}
}

int main(int argc, const char *argv[])
{
	// We use random scheduling here, so this actually affects
	// the result
	srand(time(NULL));

	coincident_init();

	return crpcut::run(argc, argv);
}
<|endoftext|>


<commit_before>#include <isl/set.h>
#include <isl/union_map.h>
#include <isl/union_set.h>
#include <isl/ast_build.h>
#include <isl/schedule.h>
#include <isl/schedule_node.h>

#include <coli/debug.h>
#include <coli/core.h>

#include <String.h>
#include <Halide.h>

int main(int argc, char **argv)
{
	// Declare a library.  A library is composed of a set of functions.
	coli::library lib("library0");

	// Declare a function in the library lib.
	coli::function fct("function0", &lib);

	// Declare the computations of the function fct.
	// To declare a computation, you need to provide:
	// (1) a Halide expression that represents the computation,
	// (2) an isl set representing the iteration space of the computation, and
	// (3) an isl context (which will be used by the ISL library calls).
	coli::computation computation0(Halide::Expr((uint8_t) 3), "{S0[i,j]: 0<=i<=1000 and 0<=j<=1000}", &fct);

	// Create a memory buffer (2 dimensional).
	coli::buffer buf0("buf0", 2, {10,10}, Halide::Int(8), NULL, &fct);

	// Add the buffer as an argument to the function fct.
	fct.add_argument(buf0);

	// Map the computations to the buffers (i.e. where each computation
	// should be stored in the buffer).
	computation0.SetWriteAccess("{S0[i,j]->buf0[i, j]}");

	// Set the schedule of each computation.
	computation0.tile(0,1,32,32);
	computation0.tag_parallel_dimension(1);

	// Generate an AST (abstract Syntax Tree)
	lib.gen_isl_ast();

	// Generate Halide statement for each function in the library.
	lib.gen_halide_stmt();

	// If you want to get the generated halide statement, call
	// lib.get_halide_stmts().  This will return a vector of
	// Halide::Internal::Stmt*.  Each one among these statements
	// represents a function in the library.

	// Dump the iteration space IR (input) and the the Halide IR (output)
	// for each function in the library.
	lib.dump_iteration_space_IR();
	lib.dump_halide_IR();

	// Generate an object file from the library lib.
	lib.gen_halide_obj("build/generated_lib_tutorial_01.o");

	return 0;
}
<commit_msg>Update tutorial_01.cpp<commit_after>#include <isl/set.h>
#include <isl/union_map.h>
#include <isl/union_set.h>
#include <isl/ast_build.h>
#include <isl/schedule.h>
#include <isl/schedule_node.h>

#include <coli/debug.h>
#include <coli/core.h>

#include <String.h>
#include <Halide.h>

int main(int argc, char **argv)
{
	// Declare a library.  A library is composed of a set of functions.
	coli::library lib("library0");

	// Declare a function in the library lib.
	coli::function fct("function0", &lib);

	// Declare the computations of the function fct.
	// To declare a computation, you need to provide:
	// (1) a Halide expression that represents the computation,
	// (2) an isl set representing the iteration space of the computation, and
	// (3) an isl context (which will be used by the ISL library calls).
	coli::computation computation0(Halide::Expr((uint8_t) 3), "{S0[i,j]: 0<=i<=1000 and 0<=j<=1000}", &fct);

	// Create a memory buffer (2 dimensional).
	coli::buffer buf0("buf0", 2, {10,10}, Halide::Int(8), NULL, &fct);

	// Add the buffer as an argument to the function fct.
	fct.add_argument(buf0);

	// Map the computations to the buffers (i.e. where each computation
	// should be stored in the buffer).
	computation0.SetWriteAccess("{S0[i,j]->buf0[i, j]}");

	// Set the schedule of each computation.
	computation0.tile(0,1,32,32);
	computation0.tag_parallel_dimension(1);

	// Generate an AST (abstract Syntax Tree)
	lib.gen_isl_ast();

	// Generate Halide statement for each function in the library.
	lib.gen_halide_stmt();

	// If you want to get the generated halide statements, call
	// lib.get_halide_stmts().  This will return a vector of
	// Halide::Internal::Stmt*.  Each one among these statements
	// represents a function in the library.

	// Dump the iteration space IR (input) and the the Halide IR (output)
	// for each function in the library.
	lib.dump_iteration_space_IR();
	lib.dump_halide_IR();

	// Generate an object file from the library lib.
	lib.gen_halide_obj("build/generated_lib_tutorial_01.o");

	return 0;
}
<|endoftext|>


<commit_before>//
// Amity - cross-platform game engine
// https://github.com/aduros/amity/blob/master/LICENSE.txt

#include "canvas/CanvasContext.h"

#include "AmityContext.h"

CanvasContext::CanvasContext (AmityContext* amityCtx) : _amityCtx(amityCtx)
{
    CanvasState state;
    state.alpha = 1;
    state.blendMode = BLEND_DEFAULT;

    // FIXME: Detect if this extension is supported.
    // SDL_GL_ExtensionSupported("GL_OES_draw_texture") appears to return false on the N1 even
    // though it works fine.
    state.canDrawTexture = true;

    state.translateX = 0;
    state.translateY = 0;
    state.scaleX = 1;
    state.scaleY = 1;

    _states.push(state);
}

void CanvasContext::save ()
{
    glPushMatrix();
    _states.push(_states.top());
}

void CanvasContext::restore ()
{
    glPopMatrix();
    _states.pop();
}

void CanvasContext::scale (float x, float y)
{
    CanvasState& state = _states.top();
    if (state.canDrawTexture) {
        state.scaleX *= x;
        state.scaleY *= y;
    }
    glScalef(x, y, 0); // TODO: Usually no need to modify GL matrix if using draw_texture
}

void CanvasContext::rotate (float angle)
{
    CanvasState& state = _states.top();
    state.canDrawTexture = false;

    glRotatef(angle, 0, 0, 1);
}

void CanvasContext::translate (float x, float y)
{
    CanvasState& state = _states.top();
    if (state.canDrawTexture) {
        state.translateX += x*state.scaleX;
        state.translateY += y*state.scaleY;
    }
    glTranslatef(x, y, 0); // TODO: Usually no need to modify GL matrix if using draw_texture
}

void CanvasContext::multiplyAlpha (float factor)
{
    _states.top().alpha *= factor;
}

void CanvasContext::setBlendMode (CanvasBlendMode blendMode)
{
}

void CanvasContext::drawImage (const Texture* texture,
    float destX, float destY, float sourceX, float sourceY, float sourceW, float sourceH)
{
    const CanvasState& state = _states.top();

    prepare(texture);

    if (state.canDrawTexture) {
        // Use GL draw_texture
        int windowHeight;
        getSize(NULL, &windowHeight);
        float destW = state.scaleX * sourceW;
        float destH = state.scaleY * sourceH;
        GLfloat cropRect[] = {
            sourceX, sourceY + texture->getHeight(), sourceW, -sourceH
        };
        glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
        glDrawTexfOES(state.translateX + destX,
            windowHeight - destY - destH - state.translateY,
            0, destW, destH);

    } else {
        // Use GL vertex arrays
        GLfloat verts[] = {
            destX, destY,
            destX + sourceW, destY,
            destX, destY + sourceH,
            destX + sourceW, destY + sourceH,
        };

        float inverseMaxU = texture->getMaxU();
        float inverseMaxV = texture->getMaxV();
        float x1 = sourceX/texture->getWidth() * inverseMaxU;
        float y1 = sourceY/texture->getHeight() * inverseMaxV;
        float x2 = x1 + sourceW/texture->getWidth() * inverseMaxU;
        float y2 = y1 + sourceH/texture->getHeight() * inverseMaxV;
        GLfloat uv[] = {
            x1, y1,
            x2, y1,
            x1, y2,
            x2, y2,
        };
        glVertexPointer(2, GL_FLOAT, 0, verts);
        glTexCoordPointer(2, GL_FLOAT, 0, uv);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
}

void CanvasContext::drawPattern (
    const Texture* texture, float destX, float destY, float destW, float destH)
{
    prepare(texture);

    float w = texture->getWidth();
    float h = texture->getHeight();

    GLfloat verts[] = {
        destX, destY,
        destX + destW, destY,
        destX, destY + destH,
        destX + destW, destY + destH,
    };
    GLfloat uv[] = {
        0, 0,
        destW/w, 0,
        0, destH/h,
        destW/w, destH/h,
    };

    glVertexPointer(2, GL_FLOAT, 0, verts);
    glTexCoordPointer(2, GL_FLOAT, 0, uv);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

void CanvasContext::fillRect (uint32_t color, float x, float y, float width, float height)
{
    const CanvasState& state = _states.top();
    GLfloat verts[] = {
        x, y,
        x + width, y,
        x, y + height,
        x + width, y + height,
    };

    glDisable(GL_TEXTURE_2D);
    glColor4ub(
        color >> 16,
        color >> 8,
        color >> 0,
        0xff * state.alpha);
    glVertexPointer(2, GL_FLOAT, 0, verts);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glEnable(GL_TEXTURE_2D);
}

void CanvasContext::getSize (int* width, int* height) const
{
#if SDL_VERSION_ATLEAST(1,3,0)
    SDL_GetWindowSize(_amityCtx->window, width, height);
#else
    if (width != NULL) {
        *width = _amityCtx->screen->w;
    }
    if (height != NULL) {
        *height = _amityCtx->screen->h;
    }
#endif
}

void CanvasContext::prepare (const Texture* texture)
{
    const CanvasState& state = _states.top();

    glBindTexture(GL_TEXTURE_2D, texture->getId());

    // TODO: Only bother turning on blending for textures with an alpha channel
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glColor4f(1, 1, 1, state.alpha);
}
<commit_msg>Disable GL_OES_draw_texture rendering.<commit_after>//
// Amity - cross-platform game engine
// https://github.com/aduros/amity/blob/master/LICENSE.txt

#include "canvas/CanvasContext.h"

#include "AmityContext.h"

CanvasContext::CanvasContext (AmityContext* amityCtx) : _amityCtx(amityCtx)
{
    CanvasState state;
    state.alpha = 1;
    state.blendMode = BLEND_DEFAULT;

    // FIXME: Detect if this extension is supported.
    // SDL_GL_ExtensionSupported("GL_OES_draw_texture") appears to return false on the N1 even
    // though it works fine.
    // TODO: Setting this to true doesn't seem to be a performance win. Think about removing it.
    state.canDrawTexture = false;

    state.translateX = 0;
    state.translateY = 0;
    state.scaleX = 1;
    state.scaleY = 1;

    _states.push(state);
}

void CanvasContext::save ()
{
    glPushMatrix();
    _states.push(_states.top());
}

void CanvasContext::restore ()
{
    glPopMatrix();
    _states.pop();
}

void CanvasContext::scale (float x, float y)
{
    CanvasState& state = _states.top();
    if (state.canDrawTexture) {
        state.scaleX *= x;
        state.scaleY *= y;
    }
    glScalef(x, y, 0); // TODO: Usually no need to modify GL matrix if using draw_texture
}

void CanvasContext::rotate (float angle)
{
    CanvasState& state = _states.top();
    state.canDrawTexture = false;

    glRotatef(angle, 0, 0, 1);
}

void CanvasContext::translate (float x, float y)
{
    CanvasState& state = _states.top();
    if (state.canDrawTexture) {
        state.translateX += x*state.scaleX;
        state.translateY += y*state.scaleY;
    }
    glTranslatef(x, y, 0); // TODO: Usually no need to modify GL matrix if using draw_texture
}

void CanvasContext::multiplyAlpha (float factor)
{
    _states.top().alpha *= factor;
}

void CanvasContext::setBlendMode (CanvasBlendMode blendMode)
{
}

void CanvasContext::drawImage (const Texture* texture,
    float destX, float destY, float sourceX, float sourceY, float sourceW, float sourceH)
{
    const CanvasState& state = _states.top();

    prepare(texture);

    if (state.canDrawTexture) {
        // Use GL draw_texture
        int windowHeight;
        getSize(NULL, &windowHeight);
        float destW = state.scaleX * sourceW;
        float destH = state.scaleY * sourceH;
        GLfloat cropRect[] = {
            sourceX, sourceY + sourceH, sourceW, -sourceH
        };
        glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
        glDrawTexfOES(state.translateX + destX,
            windowHeight - destY - destH - state.translateY,
            0, destW, destH);

    } else {
        // Use GL vertex arrays
        GLfloat verts[] = {
            destX, destY,
            destX + sourceW, destY,
            destX, destY + sourceH,
            destX + sourceW, destY + sourceH,
        };

        float inverseMaxU = texture->getMaxU();
        float inverseMaxV = texture->getMaxV();
        float x1 = sourceX/texture->getWidth() * inverseMaxU;
        float y1 = sourceY/texture->getHeight() * inverseMaxV;
        float x2 = x1 + sourceW/texture->getWidth() * inverseMaxU;
        float y2 = y1 + sourceH/texture->getHeight() * inverseMaxV;
        GLfloat uv[] = {
            x1, y1,
            x2, y1,
            x1, y2,
            x2, y2,
        };
        glVertexPointer(2, GL_FLOAT, 0, verts);
        glTexCoordPointer(2, GL_FLOAT, 0, uv);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
}

void CanvasContext::drawPattern (
    const Texture* texture, float destX, float destY, float destW, float destH)
{
    prepare(texture);

    float w = texture->getWidth();
    float h = texture->getHeight();

    GLfloat verts[] = {
        destX, destY,
        destX + destW, destY,
        destX, destY + destH,
        destX + destW, destY + destH,
    };
    GLfloat uv[] = {
        0, 0,
        destW/w, 0,
        0, destH/h,
        destW/w, destH/h,
    };

    glVertexPointer(2, GL_FLOAT, 0, verts);
    glTexCoordPointer(2, GL_FLOAT, 0, uv);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

void CanvasContext::fillRect (uint32_t color, float x, float y, float width, float height)
{
    const CanvasState& state = _states.top();
    GLfloat verts[] = {
        x, y,
        x + width, y,
        x, y + height,
        x + width, y + height,
    };

    glDisable(GL_TEXTURE_2D);
    glColor4ub(
        color >> 16,
        color >> 8,
        color >> 0,
        0xff * state.alpha);
    glVertexPointer(2, GL_FLOAT, 0, verts);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glEnable(GL_TEXTURE_2D);
}

void CanvasContext::getSize (int* width, int* height) const
{
#if SDL_VERSION_ATLEAST(1,3,0)
    SDL_GetWindowSize(_amityCtx->window, width, height);
#else
    if (width != NULL) {
        *width = _amityCtx->screen->w;
    }
    if (height != NULL) {
        *height = _amityCtx->screen->h;
    }
#endif
}

void CanvasContext::prepare (const Texture* texture)
{
    const CanvasState& state = _states.top();

    glBindTexture(GL_TEXTURE_2D, texture->getId());

    // TODO: Only bother turning on blending for textures with an alpha channel
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glColor4f(1, 1, 1, state.alpha);
}
<|endoftext|>


<commit_before>#include <isl/set.h>
#include <isl/union_map.h>
#include <isl/union_set.h>
#include <isl/ast_build.h>
#include <isl/schedule.h>
#include <isl/schedule_node.h>

#include <tiramisu/debug.h>
#include <tiramisu/core.h>

#include <string.h>
#include <Halide.h>

#include "wrapper_tutorial_09.h"

using namespace tiramisu;

/**
 * A more complicated reduction.
 *
 * We want to represent the following program
 *
 * for y = 0 to 19
 *   for x = 0 to 9
 *     f(x, y) = 1
 *
 * for y = 0 to 19
 *   g(y) = 0
 * for y = 0 to 19
 *   for rx = 0 to 9
 *     g(y) += f(y, rx)
 *
 *
 * In order to implement this program, we create the following
 * computations
 *
 * {f[x,y]: 0<=x<19 and 0<=y<9}: 1
 * {g[y,-1]: 0<=y<19}: 0
 * {g[y,rx]: 0<=y<19 and 0<=rx<9}: g(y,rx-1) + f(y,rx)
 *
 */

void generate_function(std::string name, int size, int val0)
{
    tiramisu::global::set_default_tiramisu_options();
    global::set_loop_iterator_type(p_int32);

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------

    tiramisu::function function0(name);

    tiramisu::var x = tiramisu::var("x");
    tiramisu::var y = tiramisu::var("y");
    tiramisu::var rx = tiramisu::var("rx");

    tiramisu::computation f("{f[y,x]: 0<=y<19 and 0<=x<9}", tiramisu::expr((uint8_t) 1), true, p_uint8, &function0);
    tiramisu::computation g("{g[y,-1]: 0<=y<19}",           tiramisu::expr((uint8_t) 0), true, p_uint8, &function0);
    g.add_definitions("{g[y,rx]: 0<=y<19 and 0<=rx<9}", g(y,rx-1) + f(y,rx), true, p_uint8, &function0);

    // -------------------------------------------------------
    // Layer II
    // -------------------------------------------------------

    g.after(f, computation::root);
    g.get_update(1).after(g, computation::root);

    // -------------------------------------------------------
    // Layer III
    // -------------------------------------------------------

    tiramisu::buffer f_buff("f_buff", {19,size}, tiramisu::p_uint8, a_temporary, &function0);
    tiramisu::buffer g_buff("g_buff", {size}, tiramisu::p_uint8, a_output, &function0);
    // Important: note that the access relations of the two computation C and C2 are identical.
    // The Tiramisu code generator assumes that the access relations of computations that have the same
    // name are identical.  In this case, the two relations are equal to "{C[j,i]->C_buff[i]}".
    f.set_access("{f[y,x]->f_buff[y,x]}");
    g.set_access("{g[y,rx]->g_buff[y]}");
    g.get_update(1).set_access("{g[y,rx]->g_buff[y]}");

    // -------------------------------------------------------
    // Code Generation
    // -------------------------------------------------------

    function0.set_arguments({&g_buff});
    function0.gen_time_space_domain();
    function0.gen_isl_ast();
    function0.gen_halide_stmt();
    function0.gen_c_code();
    function0.gen_halide_obj("build/generated_fct_tutorial_09.o");
}

int main(int argc, char **argv)
{
    generate_function("tiramisu_generated_code", SIZE1, 0);

    return 0;
}
<commit_msg>Update tutorial_09.cpp<commit_after>#include <isl/set.h>
#include <isl/union_map.h>
#include <isl/union_set.h>
#include <isl/ast_build.h>
#include <isl/schedule.h>
#include <isl/schedule_node.h>

#include <tiramisu/debug.h>
#include <tiramisu/core.h>

#include <string.h>
#include <Halide.h>

#include "wrapper_tutorial_09.h"

using namespace tiramisu;

/**
 * A more complicated reduction.
 *
 * We want to represent the following program
 *
 * for y = 0 to 19
 *   for x = 0 to 9
 *     f(x, y) = 1
 *
 * for y = 0 to 19
 *   g(y) = 0
 * for y = 0 to 19
 *   for rx = 0 to 9
 *     g(y) += f(y, rx)
 *
 *
 * In order to implement this program, we create the following
 * computations
 *
 * {f[x,y]: 0<=x<19 and 0<=y<9}: 1
 * {g[y,-1]: 0<=y<19}: 0
 * {g[y,rx]: 0<=y<19 and 0<=rx<9}: g(y,rx-1) + f(y,rx)
 *
 */

void generate_function(std::string name, int size, int val0)
{
    tiramisu::global::set_default_tiramisu_options();

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------

    tiramisu::function function0(name);

    tiramisu::var x = tiramisu::var("x");
    tiramisu::var y = tiramisu::var("y");
    tiramisu::var rx = tiramisu::var("rx");

    tiramisu::computation f("{f[y,x]: 0<=y<19 and 0<=x<9}", tiramisu::expr((uint8_t) 1), true, p_uint8, &function0);
    tiramisu::computation g("{g[y,-1]: 0<=y<19}",           tiramisu::expr((uint8_t) 0), true, p_uint8, &function0);
    g.add_definitions("{g[y,rx]: 0<=y<19 and 0<=rx<9}", g(y,rx-1) + f(y,rx), true, p_uint8, &function0);

    // -------------------------------------------------------
    // Layer II
    // -------------------------------------------------------

    g.after(f, computation::root);
    g.get_update(1).after(g, computation::root);

    // -------------------------------------------------------
    // Layer III
    // -------------------------------------------------------

    tiramisu::buffer f_buff("f_buff", {19,size}, tiramisu::p_uint8, a_temporary, &function0);
    tiramisu::buffer g_buff("g_buff", {size}, tiramisu::p_uint8, a_output, &function0);
    // Important: note that the access relations of the two computation C and C2 are identical.
    // The Tiramisu code generator assumes that the access relations of computations that have the same
    // name are identical.  In this case, the two relations are equal to "{C[j,i]->C_buff[i]}".
    f.set_access("{f[y,x]->f_buff[y,x]}");
    g.set_access("{g[y,rx]->g_buff[y]}");
    g.get_update(1).set_access("{g[y,rx]->g_buff[y]}");

    // -------------------------------------------------------
    // Code Generation
    // -------------------------------------------------------

    function0.set_arguments({&g_buff});
    function0.gen_time_space_domain();
    function0.gen_isl_ast();
    function0.gen_halide_stmt();
    function0.gen_c_code();
    function0.gen_halide_obj("build/generated_fct_tutorial_09.o");
}

int main(int argc, char **argv)
{
    generate_function("tiramisu_generated_code", SIZE1, 0);

    return 0;
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX621/RX62N S12AD 定義
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2022 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/device.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  S12AD ベース定義
		@param[in]	base	ベース・アドレス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <uint32_t base>
	struct s12ad_base_t {

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D コントロールレジスタ（ADCSR）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adcsr_t : public rw8_t<ofs> {
			typedef rw8_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     EXTRG;
			bit_rw_t <io_, bitpos::B1>     TRGE;
			bits_rw_t<io_, bitpos::B2, 2>  CKS;
			bit_rw_t <io_, bitpos::B4>     ADIE;

			bit_rw_t <io_, bitpos::B6>     ADCS;
			bit_rw_t <io_, bitpos::B7>     ADST;
		};
		typedef adcsr_t<base + 0x00>  ADCSR_;
		static  ADCSR_ ADCSR;

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D 変換値加算モード選択レジスタ（ADADS）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adads_t : public rw16_t<ofs> {
			typedef rw16_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 8>  ADS;
		};
		typedef adads_t<base + 0x08>  ADADS_;
		static  ADADS_ ADADS;

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D 変換値加算 / 平均回数選択レジスタ（ADADC）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adadc_t : public rw8_t<ofs> {
			typedef rw8_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 2>  ADC;
		};
		typedef adadc_t<base + 0x0C>  ADADC_;
		static  ADADC_ ADADC;

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D コントロール拡張レジスタ（ADCER）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adcer_t : public rw16_t<ofs> {
			typedef rw16_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B5>     ACE;

			bit_rw_t <io_, bitpos::B15>    ADRFMT;
		};
		typedef adcer_t<base + 0x0E>  ADCER_;
		static  ADCER_ ADCER;

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D 変換開始トリガ選択レジスタ（ADSTRGR）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adstrgr_t : public rw16_t<ofs> {
			typedef rw16_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 4>  ADSTRS;
		};
		typedef adstrgr_t<base + 0x10>  ADSTRGR_;
		static  ADSTRGR_ ADSTRGR;
	};
	template <uint32_t base> typename s12ad_base_t<base>::ADADS_ s12ad_base_t<base>::ADADS;
	template <uint32_t base> typename s12ad_base_t<base>::ADADC_ s12ad_base_t<base>::ADADC;
	template <uint32_t base> typename s12ad_base_t<base>::ADCER_ s12ad_base_t<base>::ADCER;
	template <uint32_t base> typename s12ad_base_t<base>::ADSTRGR_ s12ad_base_t<base>::ADSTRGR;

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  S12AD 定義
		@param[in]	base	ベース・アドレス
		@param[in]	per		ペリフェラル型
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <uint32_t base, peripheral per>
	struct s12ad_t : public s12ad_base_t<base> {

		static constexpr auto PERIPHERAL = per;  				///< ペリフェラル型
		static constexpr auto S12ADI = ICU::VECTOR::S12ADI0;	///< スキャン終了割り込みベクター
		static constexpr uint32_t ANALOG_NUM = 8;	///< アナログ入力数

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  アナログ入力型
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class ANALOG : uint8_t {
			AIN000,
			AIN001,
			AIN002,
			AIN003,
			AIN004,
			AIN005,
			AIN006,
			AIN007,
		};

		//-----------------------------------------------------------------//
		/*!
			@brief	ポート設定と解除
			@param[in]	an	アナログ入力型
			@param[in]	f	ポート無効の場合「false」
		*/
		//-----------------------------------------------------------------//
		static void enable(ANALOG an, bool f = true)
		{
			switch(an) {
			case ANALOG::AIN000:
				PORT4::ICR.B0 = f;
				break;
			case ANALOG::AIN001:
				PORT4::ICR.B1 = f;
				break;
			case ANALOG::AIN002:
				PORT4::ICR.B2 = f;
				break;
			case ANALOG::AIN003:
				PORT4::ICR.B3 = f;
				break;
			case ANALOG::AIN004:
				PORT4::ICR.B4 = f;
				break;
			case ANALOG::AIN005:
				PORT4::ICR.B5 = f;
				break;
			case ANALOG::AIN006:
				PORT4::ICR.B6 = f;
				break;
			case ANALOG::AIN007:
				PORT4::ICR.B7 = f;
				break;
			default:
				break;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  A/D データレジスタ（ADDR）
		*/
		//-----------------------------------------------------------------//
		struct addr_t {

			//-------------------------------------------------------------//
			/*!
				@brief  データレジスタアクセスオペレーター
				@param[in]	an	アナログ入力型
				@return A/D データレジスタ値
			*/
			//-------------------------------------------------------------//
			uint16_t operator() (ANALOG an) {
				return rd16_(base + 0x20 + static_cast<uint32_t>(an) * 2);
			}
		};
		typedef addr_t ADDR_;
		static  ADDR_ ADDR;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  A/D チャネル選択レジスタ定義 (ADANS)
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		template <uint32_t ofs>
		struct adans_t {
			void set(ANALOG an, bool f = true) {
				auto n = static_cast<uint32_t>(an);
				if(f) {
					wr16_(ofs, rd16_(ofs) |  (static_cast<uint16_t>(1) << n));
				} else {
					wr16_(ofs, rd16_(ofs) & ~(static_cast<uint16_t>(1) << n));
				}
			}

			// チャネルビット取得
			bool operator() (ANALOG an) const {
				auto n = static_cast<uint32_t>(an);
				return (rd16_(ofs) >> n) & 1;
			}
		};
		typedef adans_t<base + 0x04> ADANS_;
		static  ADANS_ ADANS;
	};
	 template <uint32_t base, peripheral per> typename s12ad_t<base, per>::ADDR_  s12ad_t<base, per>::ADDR;
	 template <uint32_t base, peripheral per> typename s12ad_t<base, per>::ADANS_ s12ad_t<base, per>::ADANS;

	typedef s12ad_t<0x00089000, peripheral::S12AD>  S12AD;
}
<commit_msg>Update: cleanup<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	RX621/RX62N S12AD 定義
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2022 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include "common/device.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  S12AD ベース定義
		@param[in]	base	ベース・アドレス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <uint32_t base>
	struct s12ad_base_t {

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D コントロールレジスタ（ADCSR）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adcsr_t : public rw8_t<ofs> {
			typedef rw8_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B0>     EXTRG;
			bit_rw_t <io_, bitpos::B1>     TRGE;
			bits_rw_t<io_, bitpos::B2, 2>  CKS;
			bit_rw_t <io_, bitpos::B4>     ADIE;

			bit_rw_t <io_, bitpos::B6>     ADCS;
			bit_rw_t <io_, bitpos::B7>     ADST;
		};
		typedef adcsr_t<base + 0x00>  ADCSR_;
		static  ADCSR_ ADCSR;

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D 変換値加算モード選択レジスタ（ADADS）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adads_t : public rw16_t<ofs> {
			typedef rw16_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 8>  ADS;
		};
		typedef adads_t<base + 0x08>  ADADS_;
		static  ADADS_ ADADS;

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D 変換値加算 / 平均回数選択レジスタ（ADADC）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adadc_t : public rw8_t<ofs> {
			typedef rw8_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 2>  ADC;
		};
		typedef adadc_t<base + 0x0C>  ADADC_;
		static  ADADC_ ADADC;

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D コントロール拡張レジスタ（ADCER）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adcer_t : public rw16_t<ofs> {
			typedef rw16_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bit_rw_t <io_, bitpos::B5>     ACE;

			bit_rw_t <io_, bitpos::B15>    ADRFMT;
		};
		typedef adcer_t<base + 0x0E>  ADCER_;
		static  ADCER_ ADCER;

		//-----------------------------------------------------------------//
		/*!
			@brief	A/D 変換開始トリガ選択レジスタ（ADSTRGR）
			@param[in]	ofs	オフセット
		*/
		//-----------------------------------------------------------------//
		template <uint32_t ofs>
		struct adstrgr_t : public rw16_t<ofs> {
			typedef rw16_t<ofs> io_;
			using io_::operator =;
			using io_::operator ();
			using io_::operator |=;
			using io_::operator &=;

			bits_rw_t<io_, bitpos::B0, 4>  ADSTRS;
		};
		typedef adstrgr_t<base + 0x10>  ADSTRGR_;
		static  ADSTRGR_ ADSTRGR;
	};
	template <uint32_t base> typename s12ad_base_t<base>::ADADS_ s12ad_base_t<base>::ADADS;
	template <uint32_t base> typename s12ad_base_t<base>::ADADC_ s12ad_base_t<base>::ADADC;
	template <uint32_t base> typename s12ad_base_t<base>::ADCER_ s12ad_base_t<base>::ADCER;
	template <uint32_t base> typename s12ad_base_t<base>::ADSTRGR_ s12ad_base_t<base>::ADSTRGR;

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  S12AD 定義
		@param[in]	base	ベース・アドレス
		@param[in]	per		ペリフェラル型
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <uint32_t base, peripheral per>
	struct s12ad_t : public s12ad_base_t<base> {

		static constexpr auto PERIPHERAL = per;  				///< ペリフェラル型
		static constexpr auto S12ADI = ICU::VECTOR::S12ADI0;	///< スキャン終了割り込みベクター
		static constexpr uint32_t ANALOG_NUM = 8;	///< アナログ入力数

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  アナログ入力型
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class ANALOG : uint8_t {
			AIN000,
			AIN001,
			AIN002,
			AIN003,
			AIN004,
			AIN005,
			AIN006,
			AIN007,
		};

		//-----------------------------------------------------------------//
		/*!
			@brief	ポート設定と解除
			@param[in]	an	アナログ入力型
			@param[in]	f	ポート無効の場合「false」
		*/
		//-----------------------------------------------------------------//
		static void enable(ANALOG an, bool f = true)
		{
			switch(an) {
			case ANALOG::AIN000:
				PORT4::ICR.B0 = f;
				break;
			case ANALOG::AIN001:
				PORT4::ICR.B1 = f;
				break;
			case ANALOG::AIN002:
				PORT4::ICR.B2 = f;
				break;
			case ANALOG::AIN003:
				PORT4::ICR.B3 = f;
				break;
			case ANALOG::AIN004:
				PORT4::ICR.B4 = f;
				break;
			case ANALOG::AIN005:
				PORT4::ICR.B5 = f;
				break;
			case ANALOG::AIN006:
				PORT4::ICR.B6 = f;
				break;
			case ANALOG::AIN007:
				PORT4::ICR.B7 = f;
				break;
			default:
				break;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  A/D データレジスタ（ADDR）
		*/
		//-----------------------------------------------------------------//
		struct addr_t {

			//-------------------------------------------------------------//
			/*!
				@brief  データレジスタアクセスオペレーター
				@param[in]	an	アナログ入力型
				@return A/D データレジスタ値
			*/
			//-------------------------------------------------------------//
			uint16_t operator() (ANALOG an) {
				return rd16_(base + 0x20 + static_cast<uint32_t>(an) * 2);
			}
		};
		typedef addr_t ADDR_;
		static  ADDR_ ADDR;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief  A/D チャネル選択レジスタ定義 (ADANS)
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		template <uint32_t ofs>
		struct adans_t {
			void set(ANALOG an, bool f = true) {
				auto n = static_cast<uint32_t>(an);
				if(f) {
					wr16_(ofs, rd16_(ofs) |  (static_cast<uint16_t>(1) << n));
				} else {
					wr16_(ofs, rd16_(ofs) & ~(static_cast<uint16_t>(1) << n));
				}
			}

			// チャネルビット取得
			bool operator() (ANALOG an) const {
				auto n = static_cast<uint32_t>(an);
				return (rd16_(ofs) >> n) & 1;
			}
		};
		typedef adans_t<base + 0x04> ADANS_;
		static  ADANS_ ADANS;
	};
	template <uint32_t base, peripheral per> typename s12ad_t<base, per>::ADDR_  s12ad_t<base, per>::ADDR;
	template <uint32_t base, peripheral per> typename s12ad_t<base, per>::ADANS_ s12ad_t<base, per>::ADANS;

	typedef s12ad_t<0x0008'9000, peripheral::S12AD>  S12AD;
}
<|endoftext|>


<commit_before>#include <qif>
#include <string>

using namespace qif;
using namespace qif::measure;
using namespace std;

int usage() {
	cout
		<< "Usage: geo-optimal <goal> <width> <height> <cell_size> <constraint> <hard_max_loss> [<prior_file>|uniform|random]\n\n"
		<< "goal:          one of\n"
		<< "                 min_loss_given_min_bayesrisk\n"
		<< "                 min_loss_given_min_georisk\n"
		<< "                 max_bayesrisk_given_max_loss\n"
		<< "                 max_georisk_given_max_loss\n"
		<< "width:         width of grid\n"
		<< "height:        height of grid\n"
		<< "cell_size:     length of each cell\n"
		<< "constraint:    the bayesrisk, georisk or loss constraint, depending on the goal\n"
		<< "hard_max_loss: C_xy is forced to 0 when loss(x,y) > hard_max_loss (can greatly reduce the problem size)\n"
		<< "prior_file:    file with a single line containing the prior. 'uniform' or 'random' prior can also be used\n";
	return -1;
}

int main(int argc, char* argv[]) {
	qif::rng::set_seed_random();		// RNG initialization

	if(argc != 8) return usage();

	string goal = argv[1];
	uint width = std::stoi(argv[2]);
	uint height = std::stoi(argv[3]);
	uint n = width * height;
	double cell_size = std::stod(argv[4]);

	auto euclid = metric::euclidean<double, point>();
	auto loss = cell_size * metric::compose(euclid, geo::cell_to_point(width));

	double constraint = std::stod(argv[5]);
	double hard_max_loss = std::stod(argv[6]);
	string pi_file = argv[7];

	prob pi;
	if(pi_file == "uniform")
		pi = probab::uniform(n);
	else if(pi_file == "random")
		pi = probab::randu(n);
	else {
		if(!pi.load(pi_file)) {
			cerr << "cannot open " << pi_file << "\n";
			return 1;
		}
		if(pi.n_elem != n) {
			cerr << "prior should have size " << n << "\n";
			return 1;
		}
		if(!probab::is_proper(pi))
			cerr << "warning: prior is not a proper distribution\n";
	}

	lp::Defaults::msg_level = lp::MsgLevel::ALL;

	cout << "computing optimal mechanism\n";

	chan C;

	if(goal == "min_loss_given_min_bayesrisk")
		C = mechanism::bayes_risk::min_loss_given_min_risk(pi, n, constraint, loss, hard_max_loss);
	else if(goal == "min_loss_given_min_georisk")
		C = mechanism::l_risk::min_loss_given_min_risk(pi, n, n, constraint, loss, loss, hard_max_loss);
	else if(goal == "max_bayesrisk_given_max_loss")
		C = mechanism::bayes_risk::max_risk_given_max_loss(pi, n, constraint, loss, hard_max_loss);
	else if(goal == "max_georisk_given_max_loss")
		C = mechanism::l_risk::max_risk_given_max_loss(pi, n, n, constraint, loss, loss, hard_max_loss);
	else
		return usage();

	cout << "done\n";

	if(C.is_empty()) {
		cout << "no solution for given constraints\n";
		return -1;
	}

	C.save("C", arma::raw_ascii);

	cout << "Channel size: " << C.n_rows << "x" << C.n_cols << "\n";
	cout << "BayesRisk: " << bayes_risk::posterior(pi, C) << "\n";
	cout << "GeoRisk: " << l_risk::posterior(loss, pi, C) << "\n";
	cout << "Exp Util Loss: " << utility::expected_distance(loss, pi, C) << "\n";
}
<commit_msg>geo-optimal: add solver param<commit_after>#include <qif>
#include <string>

using namespace qif;
using namespace qif::measure;
using namespace std;

int usage() {
	cout
		<< "Usage: geo-optimal <goal> <width> <height> <cell_size> <constraint> <hard_max_loss> <prior> <solver>\n\n"
		<< "goal:          one of\n"
		<< "                 min_loss_given_min_bayesrisk\n"
		<< "                 min_loss_given_min_georisk\n"
		<< "                 max_bayesrisk_given_max_loss\n"
		<< "                 max_georisk_given_max_loss\n"
		<< "width:         width of grid\n"
		<< "height:        height of grid\n"
		<< "cell_size:     length of each cell\n"
		<< "constraint:    the bayesrisk, georisk or loss constraint, depending on the goal\n"
		<< "hard_max_loss: C_xy is forced to 0 when loss(x,y) > hard_max_loss (can greatly reduce the problem size)\n"
		<< "prior:         file with a single line containing the prior | uniform | random\n"
		<< "solver:        CLP | GLOP | GLPK\n";
	return -1;
}

int main(int argc, char* argv[]) {
	qif::rng::set_seed_random();		// RNG initialization

	if(argc != 9) return usage();

	string goal = argv[1];
	uint width = std::stoi(argv[2]);
	uint height = std::stoi(argv[3]);
	uint n = width * height;
	double cell_size = std::stod(argv[4]);

	auto euclid = metric::euclidean<double, point>();
	auto loss = cell_size * metric::compose(euclid, geo::cell_to_point(width));

	double constraint = std::stod(argv[5]);
	double hard_max_loss = std::stod(argv[6]);
	string pi_file = argv[7];
	string solver = argv[8];

	prob pi;
	if(pi_file == "uniform")
		pi = probab::uniform(n);
	else if(pi_file == "random")
		pi = probab::randu(n);
	else {
		if(!pi.load(pi_file)) {
			cerr << "cannot open " << pi_file << "\n";
			return 1;
		}
		if(pi.n_elem != n) {
			cerr << "prior should have size " << n << "\n";
			return 1;
		}
		if(!probab::is_proper(pi))
			cerr << "warning: prior is not a proper distribution\n";
	}

	lp::Defaults::msg_level = lp::MsgLevel::ALL;
	lp::Defaults::solver = solver;

	cout << "computing optimal mechanism\n";

	chan C;

	if(goal == "min_loss_given_min_bayesrisk")
		C = mechanism::bayes_risk::min_loss_given_min_risk(pi, n, constraint, loss, hard_max_loss);
	else if(goal == "min_loss_given_min_georisk")
		C = mechanism::l_risk::min_loss_given_min_risk(pi, n, n, constraint, loss, loss, hard_max_loss);
	else if(goal == "max_bayesrisk_given_max_loss")
		C = mechanism::bayes_risk::max_risk_given_max_loss(pi, n, constraint, loss, hard_max_loss);
	else if(goal == "max_georisk_given_max_loss")
		C = mechanism::l_risk::max_risk_given_max_loss(pi, n, n, constraint, loss, loss, hard_max_loss);
	else
		return usage();

	cout << "done\n";

	if(C.is_empty()) {
		cout << "no solution for given constraints\n";
		return -1;
	}

	// C.save("C", arma::raw_ascii);

	cout << "Channel size: " << C.n_rows << "x" << C.n_cols << "\n";
	return 0;
	cout << "BayesRisk: " << bayes_risk::posterior(pi, C) << "\n";
	cout << "GeoRisk: " << l_risk::posterior(loss, pi, C) << "\n";
	cout << "Exp Util Loss: " << utility::expected_distance(loss, pi, C) << "\n";
}
<|endoftext|>


<commit_before><commit_msg>~30fps version<commit_after><|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkPNGImageIO.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "itkPNGImageIO.h"
#include "png.h"

namespace itk
{

// simple class to call fopen on construct and
// fclose on destruct
struct PNGFileWrapper
{
  PNGFileWrapper(const char* fname)
    {
      m_FilePointer = fopen(fname, "rb");
    }
  FILE* m_FilePointer;
  ~PNGFileWrapper()
    {
      if(m_FilePointer)
        {
        fclose(m_FilePointer);
        }
    }
};

bool PNGImageIO::CanReadFile(const char* file)
{
  PNGFileWrapper pngfp(file);
  FILE* fp = pngfp.m_FilePointer;
  if(!fp)
    {
    return false;
    }
  unsigned char header[8];
  fread(header, 1, 8, fp);
  bool is_png = !png_sig_cmp(header, 0, 8);
  if(!is_png)
    {
    return false;
    }
  png_structp png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
     NULL, NULL);
  if (!png_ptr)
    {
    return false;
    }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
    {
    png_destroy_read_struct(&png_ptr,
                            (png_infopp)NULL, (png_infopp)NULL);
    return false;
    }

  png_infop end_info = png_create_info_struct(png_ptr);
  if (!end_info)
    {
    png_destroy_read_struct(&png_ptr, &info_ptr,
                            (png_infopp)NULL);
    return false;
    }
  png_destroy_read_struct(&png_ptr, &info_ptr,
                          (png_infopp)NULL);

  return true;
}

const std::type_info& PNGImageIO::GetPixelType() const
{
  switch(m_PixelType)
    {
    case UCHAR:
      return typeid(unsigned char);
    case USHORT:
      return typeid(unsigned short);
    case CHAR:
    case SHORT:
    case UINT:
    case INT:
    case ULONG:
    case LONG:
    case FLOAT:
    case DOUBLE:
      {
      itkErrorMacro ("Invalid type: " << m_PixelType << ", only unsigned char and unsigned short are allowed.");
      return this->ConvertToTypeInfo(m_PixelType);
      }
    default:
      return typeid(unsigned char);
    }
}

unsigned int PNGImageIO::GetComponentSize() const
{
  switch(m_PixelType)
    {
    case UCHAR:
      return sizeof(unsigned char);
    case USHORT:
      return sizeof(unsigned short);
    case CHAR:
    case SHORT:
    case UINT:
    case INT:
    case ULONG:
    case LONG:
    case FLOAT:
    case DOUBLE:
      {
      itkErrorMacro ("Invalid type: " << m_PixelType << ", only unsigned char and unsigned short are allowed.");
      return 0;
      }
    }
  return 1;
}

void PNGImageIO::Read(void* buffer)
{
  // use this class so return will call close
  PNGFileWrapper pngfp(this->GetFileName());
  FILE* fp = pngfp.m_FilePointer;
  if(!fp)
    {
    itkErrorMacro("Error PNGImageIO could not open file: "
                  << this->GetFileName());
    return;
    }
  unsigned char header[8];
  fread(header, 1, 8, fp);
  bool is_png = !png_sig_cmp(header, 0, 8);
  if(!is_png)
    {
    itkErrorMacro("Error File is not png type" << this->GetFileName());
    return;
    }
  png_structp png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
     NULL, NULL);
  if (!png_ptr)
    {
    itkErrorMacro("Error File is not png type" << this->GetFileName());
    return;
    }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
    {
    png_destroy_read_struct(&png_ptr,
                            (png_infopp)NULL, (png_infopp)NULL);
    itkErrorMacro("Error File is not png type" << this->GetFileName());
    return;
    }

  png_infop end_info = png_create_info_struct(png_ptr);
  if (!end_info)
    {
    png_destroy_read_struct(&png_ptr, &info_ptr,
                            (png_infopp)NULL);
    itkErrorMacro("Error File is not png type" << this->GetFileName());
    return;
    }

  png_init_io(png_ptr, fp);
  png_set_sig_bytes(png_ptr, 8);

  png_read_info(png_ptr, info_ptr);

  png_uint_32 width, height;
  int bit_depth, color_type, interlace_type;
  int compression_type, filter_method;
  png_get_IHDR(png_ptr, info_ptr,
               &width, &height,
               &bit_depth, &color_type, &interlace_type,
               &compression_type, &filter_method);

  // convert palettes to RGB
  if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
    png_set_palette_to_rgb(png_ptr);
    }

  // minimum of a byte per pixel
  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
    png_set_gray_1_2_4_to_8(png_ptr);
    }

  // add alpha if any alpha found
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
    png_set_tRNS_to_alpha(png_ptr);
    }

  if (bit_depth > 8)
    {
#ifndef ITK_WORDS_BIGENDIAN
    png_set_swap(png_ptr);
#endif
    }

   // have libpng handle interlacing
  //int number_of_passes = png_set_interlace_handling(png_ptr);
  // update the info now that we have defined the filters
  png_read_update_info(png_ptr, info_ptr);

  unsigned long rowbytes = png_get_rowbytes(png_ptr, info_ptr);
  unsigned char *tempImage = static_cast<unsigned char*>(buffer);
  png_bytep *row_pointers = new png_bytep [height];
  for (unsigned int ui = 0; ui < height; ++ui)
    {
    row_pointers[ui] = tempImage + rowbytes*ui;
    }
  png_read_image(png_ptr, row_pointers);
  delete [] row_pointers;
  // close the file
  png_read_end(png_ptr, NULL);
  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);

  m_Spacing[0] = 1.0;  // Is there any spacing information
  m_Spacing[1] = 1.0;  // in PNG ?

  m_Origin[0] = 0.0;
  m_Origin[1] = 0.0;
}

PNGImageIO::PNGImageIO()
{
  this->SetNumberOfDimensions(2);
  m_PixelType = UCHAR;
}

PNGImageIO::~PNGImageIO()
{
}

void PNGImageIO::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
  os << indent << "PixelType " << m_PixelType << "\n";
}

void PNGImageIO::ReadImageInformation()
{
  // use this class so return will call close
  PNGFileWrapper pngfp(m_FileName.c_str());
  FILE* fp = pngfp.m_FilePointer;
  if(!fp)
    {
    return;
    }
  unsigned char header[8];
  fread(header, 1, 8, fp);
  bool is_png = !png_sig_cmp(header, 0, 8);
  if(!is_png)
    {
    return;
    }
  png_structp png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
     NULL, NULL);
  if (!png_ptr)
    {
    return;
    }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
    {
    png_destroy_read_struct(&png_ptr,
                            (png_infopp)NULL, (png_infopp)NULL);
    return;
    }

  png_infop end_info = png_create_info_struct(png_ptr);
  if (!end_info)
    {
    png_destroy_read_struct(&png_ptr, &info_ptr,
                            (png_infopp)NULL);
    return;
    }

  png_init_io(png_ptr, fp);
  png_set_sig_bytes(png_ptr, 8);

  png_read_info(png_ptr, info_ptr);

  png_uint_32 width, height;
  int bit_depth, color_type, interlace_type;
  int compression_type, filter_method;
  png_get_IHDR(png_ptr, info_ptr,
               &width, &height,
               &bit_depth, &color_type, &interlace_type,
               &compression_type, &filter_method);

  // convert palettes to RGB
  if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
    png_set_palette_to_rgb(png_ptr);
    }

  // minimum of a byte per pixel
  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
    png_set_gray_1_2_4_to_8(png_ptr);
    }

  // add alpha if any alpha found
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
    png_set_tRNS_to_alpha(png_ptr);
    }

  // update the info now that we have defined the filters
  png_read_update_info(png_ptr, info_ptr);
  this->SetNumberOfDimensions(2);
  this->m_Dimensions[0] = width;
  this->m_Dimensions[1] = height;
  if (bit_depth <= 8)
    {
    m_PixelType = UCHAR;
    }
  else
    {
    m_PixelType = USHORT;
    }
  this->SetNumberOfComponents(png_get_channels(png_ptr, info_ptr));
  png_destroy_read_struct(&png_ptr, &info_ptr,
                          (png_infopp)NULL);
  return;
}

} // end namespace itk
<commit_msg>ERR: switches missing enums.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkPNGImageIO.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "itkPNGImageIO.h"
#include "png.h"

namespace itk
{

// simple class to call fopen on construct and
// fclose on destruct
struct PNGFileWrapper
{
  PNGFileWrapper(const char* fname)
    {
      m_FilePointer = fopen(fname, "rb");
    }
  FILE* m_FilePointer;
  ~PNGFileWrapper()
    {
      if(m_FilePointer)
        {
        fclose(m_FilePointer);
        }
    }
};

bool PNGImageIO::CanReadFile(const char* file)
{
  PNGFileWrapper pngfp(file);
  FILE* fp = pngfp.m_FilePointer;
  if(!fp)
    {
    return false;
    }
  unsigned char header[8];
  fread(header, 1, 8, fp);
  bool is_png = !png_sig_cmp(header, 0, 8);
  if(!is_png)
    {
    return false;
    }
  png_structp png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
     NULL, NULL);
  if (!png_ptr)
    {
    return false;
    }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
    {
    png_destroy_read_struct(&png_ptr,
                            (png_infopp)NULL, (png_infopp)NULL);
    return false;
    }

  png_infop end_info = png_create_info_struct(png_ptr);
  if (!end_info)
    {
    png_destroy_read_struct(&png_ptr, &info_ptr,
                            (png_infopp)NULL);
    return false;
    }
  png_destroy_read_struct(&png_ptr, &info_ptr,
                          (png_infopp)NULL);

  return true;
}

const std::type_info& PNGImageIO::GetPixelType() const
{
  switch(m_PixelType)
    {
    case UCHAR:
      return typeid(unsigned char);
    case USHORT:
      return typeid(unsigned short);
    case CHAR:
    case SHORT:
    case UINT:
    case INT:
    case ULONG:
    case LONG:
    case FLOAT:
    case DOUBLE:
      {
      itkErrorMacro ("Invalid type: " << m_PixelType << ", only unsigned char and unsigned short are allowed.");
      return this->ConvertToTypeInfo(m_PixelType);
      }
    case UNKNOWN:
      itkErrorMacro ("Unknown pixel type: " << m_PixelType);
    }
  return typeid(ImageIOBase::UnknownType);
}

unsigned int PNGImageIO::GetComponentSize() const
{
  switch(m_PixelType)
    {
    case UCHAR:
      return sizeof(unsigned char);
    case USHORT:
      return sizeof(unsigned short);
    case CHAR:
    case SHORT:
    case UINT:
    case INT:
    case ULONG:
    case LONG:
    case FLOAT:
    case DOUBLE:
    case UNKNOWN:
      {
      itkErrorMacro ("Invalid type: " << m_PixelType << ", only unsigned char and unsigned short are allowed.");
      return 0;
      }
    }
  return 1;
}

void PNGImageIO::Read(void* buffer)
{
  // use this class so return will call close
  PNGFileWrapper pngfp(this->GetFileName());
  FILE* fp = pngfp.m_FilePointer;
  if(!fp)
    {
    itkErrorMacro("Error PNGImageIO could not open file: "
                  << this->GetFileName());
    return;
    }
  unsigned char header[8];
  fread(header, 1, 8, fp);
  bool is_png = !png_sig_cmp(header, 0, 8);
  if(!is_png)
    {
    itkErrorMacro("Error File is not png type" << this->GetFileName());
    return;
    }
  png_structp png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
     NULL, NULL);
  if (!png_ptr)
    {
    itkErrorMacro("Error File is not png type" << this->GetFileName());
    return;
    }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
    {
    png_destroy_read_struct(&png_ptr,
                            (png_infopp)NULL, (png_infopp)NULL);
    itkErrorMacro("Error File is not png type" << this->GetFileName());
    return;
    }

  png_infop end_info = png_create_info_struct(png_ptr);
  if (!end_info)
    {
    png_destroy_read_struct(&png_ptr, &info_ptr,
                            (png_infopp)NULL);
    itkErrorMacro("Error File is not png type" << this->GetFileName());
    return;
    }

  png_init_io(png_ptr, fp);
  png_set_sig_bytes(png_ptr, 8);

  png_read_info(png_ptr, info_ptr);

  png_uint_32 width, height;
  int bit_depth, color_type, interlace_type;
  int compression_type, filter_method;
  png_get_IHDR(png_ptr, info_ptr,
               &width, &height,
               &bit_depth, &color_type, &interlace_type,
               &compression_type, &filter_method);

  // convert palettes to RGB
  if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
    png_set_palette_to_rgb(png_ptr);
    }

  // minimum of a byte per pixel
  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
    png_set_gray_1_2_4_to_8(png_ptr);
    }

  // add alpha if any alpha found
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
    png_set_tRNS_to_alpha(png_ptr);
    }

  if (bit_depth > 8)
    {
#ifndef ITK_WORDS_BIGENDIAN
    png_set_swap(png_ptr);
#endif
    }

   // have libpng handle interlacing
  //int number_of_passes = png_set_interlace_handling(png_ptr);
  // update the info now that we have defined the filters
  png_read_update_info(png_ptr, info_ptr);

  unsigned long rowbytes = png_get_rowbytes(png_ptr, info_ptr);
  unsigned char *tempImage = static_cast<unsigned char*>(buffer);
  png_bytep *row_pointers = new png_bytep [height];
  for (unsigned int ui = 0; ui < height; ++ui)
    {
    row_pointers[ui] = tempImage + rowbytes*ui;
    }
  png_read_image(png_ptr, row_pointers);
  delete [] row_pointers;
  // close the file
  png_read_end(png_ptr, NULL);
  png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);

  m_Spacing[0] = 1.0;  // Is there any spacing information
  m_Spacing[1] = 1.0;  // in PNG ?

  m_Origin[0] = 0.0;
  m_Origin[1] = 0.0;
}

PNGImageIO::PNGImageIO()
{
  this->SetNumberOfDimensions(2);
  m_PixelType = UCHAR;
}

PNGImageIO::~PNGImageIO()
{
}

void PNGImageIO::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os, indent);
  os << indent << "PixelType " << m_PixelType << "\n";
}

void PNGImageIO::ReadImageInformation()
{
  // use this class so return will call close
  PNGFileWrapper pngfp(m_FileName.c_str());
  FILE* fp = pngfp.m_FilePointer;
  if(!fp)
    {
    return;
    }
  unsigned char header[8];
  fread(header, 1, 8, fp);
  bool is_png = !png_sig_cmp(header, 0, 8);
  if(!is_png)
    {
    return;
    }
  png_structp png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
     NULL, NULL);
  if (!png_ptr)
    {
    return;
    }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
    {
    png_destroy_read_struct(&png_ptr,
                            (png_infopp)NULL, (png_infopp)NULL);
    return;
    }

  png_infop end_info = png_create_info_struct(png_ptr);
  if (!end_info)
    {
    png_destroy_read_struct(&png_ptr, &info_ptr,
                            (png_infopp)NULL);
    return;
    }

  png_init_io(png_ptr, fp);
  png_set_sig_bytes(png_ptr, 8);

  png_read_info(png_ptr, info_ptr);

  png_uint_32 width, height;
  int bit_depth, color_type, interlace_type;
  int compression_type, filter_method;
  png_get_IHDR(png_ptr, info_ptr,
               &width, &height,
               &bit_depth, &color_type, &interlace_type,
               &compression_type, &filter_method);

  // convert palettes to RGB
  if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
    png_set_palette_to_rgb(png_ptr);
    }

  // minimum of a byte per pixel
  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
    png_set_gray_1_2_4_to_8(png_ptr);
    }

  // add alpha if any alpha found
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    {
    png_set_tRNS_to_alpha(png_ptr);
    }

  // update the info now that we have defined the filters
  png_read_update_info(png_ptr, info_ptr);
  this->SetNumberOfDimensions(2);
  this->m_Dimensions[0] = width;
  this->m_Dimensions[1] = height;
  if (bit_depth <= 8)
    {
    m_PixelType = UCHAR;
    }
  else
    {
    m_PixelType = USHORT;
    }
  this->SetNumberOfComponents(png_get_channels(png_ptr, info_ptr));
  png_destroy_read_struct(&png_ptr, &info_ptr,
                          (png_infopp)NULL);
  return;
}

} // end namespace itk
<|endoftext|>