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

  Program:   Visualization Toolkit
  Module:    vtkExtractSelectedGraph.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkExtractSelectedGraph.h"

#include "vtkCellData.h"
#include "vtkCommand.h"
#include "vtkConvertSelection.h"
#include "vtkDataArray.h"
#include "vtkEventForwarderCommand.h"
#include "vtkExtractSelection.h"
#include "vtkGraph.h"
#include "vtkGraphIdList.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSelection.h"
#include "vtkSignedCharArray.h"
#include "vtkSmartPointer.h"
#include "vtkStringArray.h"

#include <vtksys/stl/map>
using vtksys_stl::map;

vtkCxxRevisionMacro(vtkExtractSelectedGraph, "1.11");
vtkStandardNewMacro(vtkExtractSelectedGraph);

vtkExtractSelectedGraph::vtkExtractSelectedGraph()
{
  this->SetNumberOfInputPorts(2);
  this->RemoveIsolatedVertices = true;
}

vtkExtractSelectedGraph::~vtkExtractSelectedGraph()
{
}

int vtkExtractSelectedGraph::FillInputPortInformation(int port, vtkInformation* info)
{
  if (port == 0)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkAbstractGraph");
    return 1;
    }
  else if (port == 1)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkSelection");
    return 1;
    }
  return 0;
}

void vtkExtractSelectedGraph::SetSelectionConnection(vtkAlgorithmOutput* in)
{
  this->SetInputConnection(1, in);
}

int vtkExtractSelectedGraph::RequestData(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  vtkAbstractGraph* input = vtkAbstractGraph::GetData(inputVector[0]);
  vtkSelection* selection = vtkSelection::GetData(inputVector[1]);

  // If there is nothing in the list, there is nothing to select.
  vtkAbstractArray* list = selection->GetSelectionList();
  if (!list || list->GetNumberOfTuples() == 0)
    {
    return 1;
    }

  // If it is a selection with multiple parts, find a point or cell
  // child selection, with preference to points.
  if (selection->GetContentType() == vtkSelection::SELECTIONS)
    {
    vtkSelection* child = 0;
    for (unsigned int i = 0; i < selection->GetNumberOfChildren(); i++)
      {
      vtkSelection* cur = selection->GetChild(i);
      if (cur->GetFieldType() == vtkSelection::POINT)
        {
        child = cur;
        break;
        }
      else if (cur->GetFieldType() == vtkSelection::CELL)
        {
        child = cur;
        }
      }
    selection = child;
    }

  // Convert the selection to an INDICES selection
  vtkSelection* indexSelection =
    vtkConvertSelection::ToIndexSelection(selection, input);
  if (!indexSelection)
    {
    vtkErrorMacro("Selection conversion to INDICES failed.");
    indexSelection->Delete();
    return 0;
    }

  vtkAbstractArray* arr = indexSelection->GetSelectionList();
  if (arr == NULL)
    {
    vtkErrorMacro("Selection list not found.");
    return 0;
    }
  vtkIdTypeArray* selectArr = vtkIdTypeArray::SafeDownCast(arr);
  if (selectArr == NULL)
    {
    vtkErrorMacro("Selection list must be of type vtkIdTypeArray.");
    return 0;
    }
  vtkIdType selectSize = selectArr->GetNumberOfTuples();

  vtkGraph* output = vtkGraph::GetData(outputVector);

  output->SetDirected(input->GetDirected());
  output->GetFieldData()->PassData(input->GetFieldData());

  if (selection->GetProperties()->Has(vtkSelection::FIELD_TYPE()) &&
      selection->GetProperties()->Get(vtkSelection::FIELD_TYPE()) == vtkSelection::CELL)
    {
    //
    // Edge selection
    //

    // Copy all vertices
    output->SetNumberOfVertices(input->GetNumberOfVertices());

    // Copy selected edges
    vtkCellData* inputEdgeData = input->GetEdgeData();
    vtkCellData* outputEdgeData = output->GetEdgeData();
    outputEdgeData->CopyAllocate(inputEdgeData);
    for (vtkIdType i = 0; i < selectSize; i++)
      {
      vtkIdType inputEdge = selectArr->GetValue(i);
      if (inputEdge < input->GetNumberOfEdges())
        {
        vtkIdType source = input->GetSourceVertex(inputEdge);
        vtkIdType target = input->GetTargetVertex(inputEdge);
        vtkIdType outputEdge = output->AddEdge(source, target);
        outputEdgeData->CopyData(inputEdgeData, inputEdge, outputEdge);
        }
      }

    // Remove isolated vertices
    if (this->RemoveIsolatedVertices)
      {
      output->GetVertexData()->DeepCopy(input->GetVertexData());
      output->GetPoints()->DeepCopy(input->GetPoints());
      vtkIdTypeArray* isolated = vtkIdTypeArray::New();
      for (vtkIdType i = 0; i < output->GetNumberOfVertices(); i++)
        {
        if (output->GetDegree(i) == 0)
          {
          isolated->InsertNextValue(i);
          }
        }
      output->RemoveVertices(isolated->GetPointer(0), isolated->GetNumberOfTuples());
      isolated->Delete();
      }
    else
      {
      output->GetVertexData()->PassData(input->GetVertexData());
      output->GetPoints()->ShallowCopy(input->GetPoints());
      }
    }
  else
    {
    //
    // Vertex selection
    //

    // Copy selected vertices
    double pt[3];
    vtkPoints* inputPoints = input->GetPoints();
    vtkPoints* outputPoints = vtkPoints::New();
    vtkPointData* inputVertexData = input->GetVertexData();
    vtkPointData* outputVertexData = output->GetVertexData();
    outputVertexData->CopyAllocate(inputVertexData);
    map<vtkIdType, vtkIdType> idMap;
    for (vtkIdType i = 0; i < selectSize; i++)
      {
      vtkIdType inputVertex = selectArr->GetValue(i);
      if (inputVertex < input->GetNumberOfVertices())
        {
        vtkIdType outputVertex = output->AddVertex();
        outputVertexData->CopyData(inputVertexData, inputVertex, outputVertex);
        idMap[inputVertex] = outputVertex;
        inputPoints->GetPoint(inputVertex, pt);
        outputPoints->InsertNextPoint(pt);
        }
      }
    output->SetPoints(outputPoints);
    outputPoints->Delete();

    // Make a directed shallow copy of the graph so GetOutEdges()
    // returns every edge no more than once.
    vtkAbstractGraph* copy = input;
    bool madeCopy = false;
    if (vtkGraph::SafeDownCast(input) && !input->GetDirected())
      {
      copy = vtkGraph::New();
      copy->ShallowCopy(input);
      vtkGraph::SafeDownCast(copy)->SetDirected(true);
      madeCopy = true;
      }

    // Copy any edges that connect selected vertices
    vtkCellData* inputEdgeData = input->GetEdgeData();
    vtkCellData* outputEdgeData = output->GetEdgeData();
    outputEdgeData->CopyAllocate(inputEdgeData);
    vtkGraphIdList* edgeList = vtkGraphIdList::New();
    for (vtkIdType i = 0; i < selectSize; i++)
      {
      vtkIdType inputVertex = selectArr->GetValue(i);
      if (idMap.count(inputVertex) > 0)
        {
        vtkIdType outputVertex = idMap[inputVertex];
        copy->GetOutEdges(inputVertex, edgeList);
        for (vtkIdType j = 0; j < edgeList->GetNumberOfIds(); j++)
          {
          vtkIdType inputEdge = edgeList->GetId(j);
          vtkIdType oppInputVertex = input->GetOppositeVertex(inputEdge, inputVertex);
          if (idMap.count(oppInputVertex) > 0)
            {
            vtkIdType oppOutputVertex = idMap[oppInputVertex];
            vtkIdType outputEdge = output->AddEdge(outputVertex, oppOutputVertex);
            outputEdgeData->CopyData(inputEdgeData, inputEdge, outputEdge);
            }
          }
        }
      }
    edgeList->Delete();

    // Clean up
    if (madeCopy)
      {
      copy->Delete();
      }
    }

  // Clean up
  output->Squeeze();
  indexSelection->Delete();

  return 1;
}

void vtkExtractSelectedGraph::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "RemoveIsolatedVertices: "
     << (this->RemoveIsolatedVertices ? "on" : "off") << endl;
}

<commit_msg>ENH: Support for extracting the unselected portion of a graph.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkExtractSelectedGraph.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkExtractSelectedGraph.h"

#include "vtkCellData.h"
#include "vtkCommand.h"
#include "vtkConvertSelection.h"
#include "vtkDataArray.h"
#include "vtkEventForwarderCommand.h"
#include "vtkExtractSelection.h"
#include "vtkGraph.h"
#include "vtkGraphIdList.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSelection.h"
#include "vtkSignedCharArray.h"
#include "vtkSmartPointer.h"
#include "vtkStringArray.h"

#include <vtksys/stl/map>
using vtksys_stl::map;

vtkCxxRevisionMacro(vtkExtractSelectedGraph, "1.12");
vtkStandardNewMacro(vtkExtractSelectedGraph);

vtkExtractSelectedGraph::vtkExtractSelectedGraph()
{
  this->SetNumberOfInputPorts(2);
  this->RemoveIsolatedVertices = true;
}

vtkExtractSelectedGraph::~vtkExtractSelectedGraph()
{
}

int vtkExtractSelectedGraph::FillInputPortInformation(int port, vtkInformation* info)
{
  if (port == 0)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkAbstractGraph");
    return 1;
    }
  else if (port == 1)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkSelection");
    return 1;
    }
  return 0;
}

void vtkExtractSelectedGraph::SetSelectionConnection(vtkAlgorithmOutput* in)
{
  this->SetInputConnection(1, in);
}

int vtkExtractSelectedGraph::RequestData(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  vtkAbstractGraph* input = vtkAbstractGraph::GetData(inputVector[0]);
  vtkSelection* selection = vtkSelection::GetData(inputVector[1]);

  // If there is nothing in the list, there is nothing to select.
  vtkAbstractArray* list = selection->GetSelectionList();
  if (!list || list->GetNumberOfTuples() == 0)
    {
    return 1;
    }

  bool inverse = false;
  if(selection->GetProperties()->Has(vtkSelection::INVERSE()))
    {
    inverse = selection->GetProperties()->Get(vtkSelection::INVERSE());
    }

  // If it is a selection with multiple parts, find a point or cell
  // child selection, with preference to points.
  if (selection->GetContentType() == vtkSelection::SELECTIONS)
    {
    vtkSelection* child = 0;
    for (unsigned int i = 0; i < selection->GetNumberOfChildren(); i++)
      {
      vtkSelection* cur = selection->GetChild(i);
      if (cur->GetFieldType() == vtkSelection::POINT)
        {
        child = cur;
        break;
        }
      else if (cur->GetFieldType() == vtkSelection::CELL)
        {
        child = cur;
        }
      }
    selection = child;
    }

  // Convert the selection to an INDICES selection
  vtkSelection* indexSelection =
    vtkConvertSelection::ToIndexSelection(selection, input);
  if (!indexSelection)
    {
    vtkErrorMacro("Selection conversion to INDICES failed.");
    indexSelection->Delete();
    return 0;
    }

  vtkAbstractArray* arr = indexSelection->GetSelectionList();
  if (arr == NULL)
    {
    vtkErrorMacro("Selection list not found.");
    return 0;
    }
  vtkIdTypeArray* selectArr = vtkIdTypeArray::SafeDownCast(arr);
  if (selectArr == NULL)
    {
    vtkErrorMacro("Selection list must be of type vtkIdTypeArray.");
    return 0;
    }
  vtkIdType selectSize = selectArr->GetNumberOfTuples();

  vtkGraph* output = vtkGraph::GetData(outputVector);

  output->SetDirected(input->GetDirected());
  output->GetFieldData()->PassData(input->GetFieldData());

  if (selection->GetProperties()->Has(vtkSelection::FIELD_TYPE()) &&
      selection->GetProperties()->Get(vtkSelection::FIELD_TYPE()) == vtkSelection::CELL)
    {
    //
    // Edge selection
    //

    // Copy all vertices
    output->SetNumberOfVertices(input->GetNumberOfVertices());

    vtkCellData* inputEdgeData = input->GetEdgeData();
    vtkCellData* outputEdgeData = output->GetEdgeData();
    outputEdgeData->CopyAllocate(inputEdgeData);

    // Copy unselected edges
    if(inverse)
      {
      for (vtkIdType i = 0; i < inputEdgeData->GetNumberOfTuples(); i++)
        {
        if(selectArr->LookupValue(i) < 0 )
          {
          vtkIdType source = input->GetSourceVertex(i);
          vtkIdType target = input->GetTargetVertex(i);
          vtkIdType outputEdge = output->AddEdge(source, target);
          outputEdgeData->CopyData(inputEdgeData, i, outputEdge);
          }
        }
      }
    // Copy selected edges
    else
      {
      for (vtkIdType i = 0; i < selectSize; i++)
        {
        vtkIdType inputEdge = selectArr->GetValue(i);
        if (inputEdge < input->GetNumberOfEdges())
          {
          vtkIdType source = input->GetSourceVertex(inputEdge);
          vtkIdType target = input->GetTargetVertex(inputEdge);
          vtkIdType outputEdge = output->AddEdge(source, target);
          outputEdgeData->CopyData(inputEdgeData, inputEdge, outputEdge);
          }
        }
      }

    // Remove isolated vertices
    if (this->RemoveIsolatedVertices)
      {
      output->GetVertexData()->DeepCopy(input->GetVertexData());
      output->GetPoints()->DeepCopy(input->GetPoints());
      vtkIdTypeArray* isolated = vtkIdTypeArray::New();
      for (vtkIdType i = 0; i < output->GetNumberOfVertices(); i++)
        {
        if (output->GetDegree(i) == 0)
          {
          isolated->InsertNextValue(i);
          }
        }
      output->RemoveVertices(isolated->GetPointer(0), isolated->GetNumberOfTuples());
      isolated->Delete();
      }
    else
      {
      output->GetVertexData()->PassData(input->GetVertexData());
      output->GetPoints()->ShallowCopy(input->GetPoints());
      }
    }
  else
    {
    //
    // Vertex selection
    //

    double pt[3];
    vtkPoints* inputPoints = input->GetPoints();
    vtkPoints* outputPoints = vtkPoints::New();
    vtkPointData* inputVertexData = input->GetVertexData();
    vtkPointData* outputVertexData = output->GetVertexData();
    outputVertexData->CopyAllocate(inputVertexData);
    map<vtkIdType, vtkIdType> idMap;

    // Copy unselected vertices
    if(inverse)
      {
      for (vtkIdType i = 0; i < inputVertexData->GetNumberOfTuples(); i++)
        {
        if(selectArr->LookupValue(i) < 0)
          {
          vtkIdType outputVertex = output->AddVertex();
          outputVertexData->CopyData(inputVertexData, i, outputVertex);
          idMap[i] = outputVertex;
          inputPoints->GetPoint(i, pt);
          outputPoints->InsertNextPoint(pt);
          }
        }
      }
    // Copy selected vertices
    else
      {
      for (vtkIdType i = 0; i < selectSize; i++)
        {
        vtkIdType inputVertex = selectArr->GetValue(i);
        if (inputVertex < input->GetNumberOfVertices())
          {
          vtkIdType outputVertex = output->AddVertex();
          outputVertexData->CopyData(inputVertexData, inputVertex, outputVertex);
          idMap[inputVertex] = outputVertex;
          inputPoints->GetPoint(inputVertex, pt);
          outputPoints->InsertNextPoint(pt);
          }
        }
      }
    output->SetPoints(outputPoints);
    outputPoints->Delete();

    // Make a directed shallow copy of the graph so GetOutEdges()
    // returns every edge no more than once.
    vtkAbstractGraph* copy = input;
    bool madeCopy = false;
    if (vtkGraph::SafeDownCast(input) && !input->GetDirected())
      {
      copy = vtkGraph::New();
      copy->ShallowCopy(input);
      vtkGraph::SafeDownCast(copy)->SetDirected(true);
      madeCopy = true;
      }

    vtkCellData* inputEdgeData = input->GetEdgeData();
    vtkCellData* outputEdgeData = output->GetEdgeData();
    outputEdgeData->CopyAllocate(inputEdgeData);
    vtkGraphIdList* edgeList = vtkGraphIdList::New();

    // Copy any edges that connect UNSELECTED vertices
    if(inverse)
      {
      map<vtkIdType, vtkIdType>::iterator mapIter = idMap.begin();
      while(mapIter != idMap.end())
        {
        vtkIdType inputVertex = mapIter->first;
        vtkIdType outputVertex = mapIter->second;
        copy->GetOutEdges(inputVertex, edgeList);
        for (vtkIdType j = 0; j < edgeList->GetNumberOfIds(); j++)
          {
          vtkIdType inputEdge = edgeList->GetId(j);
          vtkIdType oppInputVertex = input->GetOppositeVertex(inputEdge, inputVertex);
          if (idMap.count(oppInputVertex) > 0)
            {
            vtkIdType oppOutputVertex = idMap[oppInputVertex];
            vtkIdType outputEdge = output->AddEdge(outputVertex, oppOutputVertex);
            outputEdgeData->CopyData(inputEdgeData, inputEdge, outputEdge);
            }
          }
        mapIter++;
        }
      }
    // Copy any edges that connect SELECTED vertices
    else
      {
      for (vtkIdType i = 0; i < selectSize; i++)
        {
        vtkIdType inputVertex = selectArr->GetValue(i);
        if (idMap.count(inputVertex) > 0)
          {
          vtkIdType outputVertex = idMap[inputVertex];
          copy->GetOutEdges(inputVertex, edgeList);
          for (vtkIdType j = 0; j < edgeList->GetNumberOfIds(); j++)
            {
            vtkIdType inputEdge = edgeList->GetId(j);
            vtkIdType oppInputVertex = input->GetOppositeVertex(inputEdge, inputVertex);
            if (idMap.count(oppInputVertex) > 0)
              {
              vtkIdType oppOutputVertex = idMap[oppInputVertex];
              vtkIdType outputEdge = output->AddEdge(outputVertex, oppOutputVertex);
              outputEdgeData->CopyData(inputEdgeData, inputEdge, outputEdge);
              }
            }
          }
        }
      }
    edgeList->Delete();

    // Clean up
    if (madeCopy)
      {
      copy->Delete();
      }
    }

  // Clean up
  output->Squeeze();
  indexSelection->Delete();

  return 1;
}

void vtkExtractSelectedGraph::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "RemoveIsolatedVertices: "
     << (this->RemoveIsolatedVertices ? "on" : "off") << endl;
}

<|endoftext|>


<commit_before>//
//  Instruction.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 10/04/2022.
//  Copyright © 2022 Thomas Harte. All rights reserved.
//

#ifndef InstructionSets_68k_Instruction_hpp
#define InstructionSets_68k_Instruction_hpp

#include <cstdint>
#include "Model.hpp"

namespace InstructionSet {
namespace M68k {

enum class Operation: uint8_t {
	Undefined,

	NOP,

	ABCD,	SBCD,	NBCD,

	ADDb,	ADDw,	ADDl,
	ADDAw,	ADDAl,
	ADDXb,	ADDXw,	ADDXl,

	SUBb,	SUBw,	SUBl,
	SUBAw,	SUBAl,
	SUBXb,	SUBXw,	SUBXl,

	MOVEb,	MOVEw,	MOVEl,
	MOVEAw,	MOVEAl,
	LEA,	PEA,

	MOVEtoSR, MOVEfromSR,
	MOVEtoCCR,
	MOVEtoUSP, MOVEfromUSP,

	ORItoSR,	ORItoCCR,
	ANDItoSR,	ANDItoCCR,
	EORItoSR,	EORItoCCR,

	BTST,	BCLR,
	BCHG,	BSET,

	CMPb,	CMPw,	CMPl,
	CMPAw,	CMPAl,
	TSTb,	TSTw,	TSTl,

	JMP,
	JSR,	RTS,
	DBcc,
	Scc,

	Bccb,	Bccl,	Bccw,
	BSRb,	BSRl,	BSRw,

	CLRb, CLRw, CLRl,
	NEGXb, NEGXw, NEGXl,
	NEGb, NEGw, NEGl,

	ASLb, ASLw, ASLl, ASLm,
	ASRb, ASRw, ASRl, ASRm,
	LSLb, LSLw, LSLl, LSLm,
	LSRb, LSRw, LSRl, LSRm,
	ROLb, ROLw, ROLl, ROLm,
	RORb, RORw, RORl, RORm,
	ROXLb, ROXLw, ROXLl, ROXLm,
	ROXRb, ROXRw, ROXRl, ROXRm,

	MOVEMl, MOVEMw,
	MOVEPl, MOVEPw,

	ANDb,	ANDw,	ANDl,
	EORb,	EORw,	EORl,
	NOTb, 	NOTw, 	NOTl,
	ORb,	ORw,	ORl,

	MULU,	MULS,
	DIVU,	DIVS,

	RTE,	RTR,

	TRAP,	TRAPV,
	CHK,

	EXG,	SWAP,

	TAS,

	EXTbtow,	EXTwtol,

	LINKw,	UNLINK,

	STOP,	RESET,

	Max = RESET
};

template <Model model>
constexpr bool requires_supervisor(Operation op) {
	switch(op) {
		case Operation::MOVEfromSR:
			if constexpr (model == Model::M68000) {
				return false;
			}
			[[fallthrough]];
		case Operation::ORItoSR:	case Operation::ANDItoSR:
		case Operation::EORItoSR:	case Operation::RTE:
		case Operation::RESET:		case Operation::STOP:
		case Operation::MOVEtoUSP:	case Operation::MOVEfromUSP:
			return true;

		default:
			return false;
	}
}

constexpr int size(Operation operation) {
	// TODO: most of this table, once I've settled on what stays in
	// the Operation table and what doesn't.
	switch(operation) {
		case Operation::ADDb:	case Operation::ADDXb:
		case Operation::SUBb:	case Operation::SUBXb:
		case Operation::ORItoCCR:
		case Operation::ANDItoCCR:
		case Operation::EORItoCCR:
			return 1;

		case Operation::ORItoSR:
		case Operation::ANDItoSR:
		case Operation::EORItoSR:
			return 2;

		case Operation::EXG:
			return 4;

		default:	return 0;
	}
}

template <Operation op>
constexpr int8_t quick(uint16_t instruction) {
	switch(op) {
		case Operation::Bccb:
		case Operation::BSRb:
		case Operation::MOVEl:	return int8_t(instruction);
		case Operation::TRAP:	return int8_t(instruction & 15);
		default: {
			int8_t value = (instruction >> 9) & 7;
			value |= (value - 1)&8;
			return value;
		}
	}
}

constexpr int8_t quick(Operation op, uint16_t instruction) {
	switch(op) {
		case Operation::MOVEl:	return quick<Operation::MOVEl>(instruction);
		case Operation::Bccb:	return quick<Operation::Bccb>(instruction);
		case Operation::BSRb:	return quick<Operation::BSRb>(instruction);
		case Operation::TRAP:	return quick<Operation::TRAP>(instruction);

		default:
			// ADDw is arbitrary; anything other than those listed above will do.
			return quick<Operation::ADDw>(instruction);
	}
}

/// Indicates the addressing mode applicable to an operand.
///
/// Implementation notes:
///
/// Those entries starting 0b00 or 0b01 are mapped as per the 68000's native encoding;
/// those starting 0b00 are those which are indicated directly by a mode field and those starting
/// 0b01 are those which are indicated by a register field given a mode of 0b111. The only minor
/// exception is AddressRegisterDirect, which exists on a 68000  but isn't specifiable by a
/// mode and register, it's contextual based on the instruction.
///
/// Those modes starting in 0b10 are the various extended addressing modes introduced as
/// of the 68020, which can be detected only after interpreting an extension word. At the
/// Preinstruction stage:
///
///	* AddressRegisterIndirectWithIndexBaseDisplacement, MemoryIndirectPostindexed
///		and MemoryIndirectPreindexed will have been partially decoded as
///		AddressRegisterIndirectWithIndex8bitDisplacement; and
///	* ProgramCounterIndirectWithIndexBaseDisplacement,
///		ProgramCounterMemoryIndirectPostindexed and
///		ProgramCounterMemoryIndirectPreindexed will have been partially decoded
///		as ProgramCounterIndirectWithIndex8bitDisplacement.
enum class AddressingMode: uint8_t {
	/// No adddressing mode; this operand doesn't exist.
	None												= 0b01'101,

	/// Dn
	DataRegisterDirect									= 0b00'000,

	/// An
	AddressRegisterDirect								= 0b00'001,
	/// (An)
	AddressRegisterIndirect								= 0b00'010,
	/// (An)+
	AddressRegisterIndirectWithPostincrement			= 0b00'011,
	/// -(An)
	AddressRegisterIndirectWithPredecrement				= 0b00'100,
	/// (d16, An)
	AddressRegisterIndirectWithDisplacement				= 0b00'101,
	/// (d8, An, Xn)
	AddressRegisterIndirectWithIndex8bitDisplacement	= 0b00'110,
	/// (bd, An, Xn)
	AddressRegisterIndirectWithIndexBaseDisplacement	= 0b10'000,

	/// ([bd, An, Xn], od)
	MemoryIndirectPostindexed							= 0b10'001,
	/// ([bd, An], Xn, od)
	MemoryIndirectPreindexed							= 0b10'010,

	/// (d16, PC)
	ProgramCounterIndirectWithDisplacement				= 0b01'010,
	/// (d8, PC, Xn)
	ProgramCounterIndirectWithIndex8bitDisplacement		= 0b01'011,
	/// (bd, PC, Xn)
	ProgramCounterIndirectWithIndexBaseDisplacement		= 0b10'011,
	/// ([bd, PC, Xn], od)
	ProgramCounterMemoryIndirectPostindexed				= 0b10'100,
	/// ([bc, PC], Xn, od)
	ProgramCounterMemoryIndirectPreindexed				= 0b10'101,

	/// (xxx).W
	AbsoluteShort										= 0b01'000,
	/// (xxx).L
	AbsoluteLong										= 0b01'001,

	/// #
	ImmediateData										= 0b01'100,

	/// .q; value is embedded in the opcode.
	Quick												= 0b01'110,
};

/*!
	A preinstruction is as much of an instruction as can be decoded with
	only the first instruction word — i.e. an operation, and:

	* on the 68000 and 68010, the complete addressing modes;
	* on subsequent, a decent proportion of the addressing mode. See
		the notes on @c AddressingMode for potential aliasing.
*/
class Preinstruction {
	public:
		Operation operation = Operation::Undefined;

		// Instructions come with 0, 1 or 2 operands;
		// the getters below act to provide a list of operands
		// that is terminated by an AddressingMode::None.
		//
		// For two-operand instructions, argument 0 is a source
		// and argument 1 is a destination.
		//
		// For one-operand instructions, only argument 0 will
		// be provided, and will be a source and/or destination as
		// per the semantics of the operation.

		template <int index> AddressingMode mode() const {
			if constexpr (index > 1) {
				return AddressingMode::None;
			}
			return AddressingMode(operands_[index] & 0x1f);
		}
		template <int index> int reg() const {
			if constexpr (index > 1) {
				return 0;
			}
			return operands_[index] >> 5;
		}

	private:
		uint8_t operands_[2] = { uint8_t(AddressingMode::None), uint8_t(AddressingMode::None)};

	public:
		Preinstruction(
			Operation operation,
			AddressingMode op1_mode,	int op1_reg,
			AddressingMode op2_mode,	int op2_reg,
			[[maybe_unused]] bool is_supervisor = false) : operation(operation)
		{
			operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5);
			operands_[1] = uint8_t(op2_mode) | uint8_t(op2_reg << 5);
		}

		Preinstruction(Operation operation, [[maybe_unused]] bool is_supervisor = false) : operation(operation) {}

		Preinstruction(Operation operation, AddressingMode op1_mode, int op1_reg, [[maybe_unused]] bool is_supervisor = false) : operation(operation) {
			operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5);
		}

		// TODO: record is_supervisor.

		Preinstruction() {}
};

}
}

#endif /* InstructionSets_68k_Instruction_hpp */
<commit_msg>Fill in size table, define `quick` to return a `uint32_t`.<commit_after>//
//  Instruction.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 10/04/2022.
//  Copyright © 2022 Thomas Harte. All rights reserved.
//

#ifndef InstructionSets_68k_Instruction_hpp
#define InstructionSets_68k_Instruction_hpp

#include <cstdint>
#include "Model.hpp"

namespace InstructionSet {
namespace M68k {

enum class Operation: uint8_t {
	Undefined,

	NOP,

	ABCD,	SBCD,	NBCD,

	ADDb,	ADDw,	ADDl,
	ADDAw,	ADDAl,
	ADDXb,	ADDXw,	ADDXl,

	SUBb,	SUBw,	SUBl,
	SUBAw,	SUBAl,
	SUBXb,	SUBXw,	SUBXl,

	MOVEb,	MOVEw,	MOVEl,
	MOVEAw,	MOVEAl,
	LEA,	PEA,

	MOVEtoSR, MOVEfromSR,
	MOVEtoCCR,
	MOVEtoUSP, MOVEfromUSP,

	ORItoSR,	ORItoCCR,
	ANDItoSR,	ANDItoCCR,
	EORItoSR,	EORItoCCR,

	BTST,	BCLR,
	BCHG,	BSET,

	CMPb,	CMPw,	CMPl,
	CMPAw,	CMPAl,
	TSTb,	TSTw,	TSTl,

	JMP,
	JSR,	RTS,
	DBcc,
	Scc,

	Bccb,	Bccw,	Bccl,
	BSRb,	BSRw,	BSRl,

	CLRb, CLRw, CLRl,
	NEGXb, NEGXw, NEGXl,
	NEGb, NEGw, NEGl,

	ASLb, ASLw, ASLl, ASLm,
	ASRb, ASRw, ASRl, ASRm,
	LSLb, LSLw, LSLl, LSLm,
	LSRb, LSRw, LSRl, LSRm,
	ROLb, ROLw, ROLl, ROLm,
	RORb, RORw, RORl, RORm,
	ROXLb, ROXLw, ROXLl, ROXLm,
	ROXRb, ROXRw, ROXRl, ROXRm,

	MOVEMl, MOVEMw,
	MOVEPl, MOVEPw,

	ANDb,	ANDw,	ANDl,
	EORb,	EORw,	EORl,
	NOTb, 	NOTw, 	NOTl,
	ORb,	ORw,	ORl,

	MULU,	MULS,
	DIVU,	DIVS,

	RTE,	RTR,

	TRAP,	TRAPV,
	CHK,

	EXG,	SWAP,

	TAS,

	EXTbtow,	EXTwtol,

	LINKw,	UNLINK,

	STOP,	RESET,

	Max = RESET
};

template <Model model>
constexpr bool requires_supervisor(Operation op) {
	switch(op) {
		case Operation::MOVEfromSR:
			if constexpr (model == Model::M68000) {
				return false;
			}
			[[fallthrough]];
		case Operation::ORItoSR:	case Operation::ANDItoSR:
		case Operation::EORItoSR:	case Operation::RTE:
		case Operation::RESET:		case Operation::STOP:
		case Operation::MOVEtoUSP:	case Operation::MOVEfromUSP:
			return true;

		default:
			return false;
	}
}

enum class DataSize {
	Byte = 0,
	Word = 1,
	LongWord = 2,
};

/// Classifies operations by the size of their memory accesses, if any.
constexpr DataSize size(Operation operation) {
	switch(operation) {
		// These are given a value arbitrarily, to
		// complete the switch statement.
		case Operation::Undefined:
		case Operation::NOP:
		case Operation::STOP:
		case Operation::RESET:
		case Operation::RTE:	case Operation::RTR:
		case Operation::TRAP:
		case Operation::TRAPV:

		case Operation::ABCD:	case Operation::SBCD:
		case Operation::NBCD:
		case Operation::ADDb:	case Operation::ADDXb:
		case Operation::SUBb:	case Operation::SUBXb:
		case Operation::MOVEb:
		case Operation::ORItoCCR:
		case Operation::ANDItoCCR:
		case Operation::EORItoCCR:
		case Operation::BTST:	case Operation::BCLR:
		case Operation::BCHG:	case Operation::BSET:
		case Operation::CMPb:	case Operation::TSTb:
		case Operation::Bccb:	case Operation::BSRb:
		case Operation::CLRb:
		case Operation::NEGXb:	case Operation::NEGb:
		case Operation::ASLb:	case Operation::ASRb:
		case Operation::LSLb:	case Operation::LSRb:
		case Operation::ROLb:	case Operation::RORb:
		case Operation::ROXLb:	case Operation::ROXRb:
		case Operation::ANDb:	case Operation::EORb:
		case Operation::NOTb:	case Operation::ORb:
		case Operation::CHK:
		case Operation::TAS:
			return DataSize::Byte;

		case Operation::ADDw:	case Operation::ADDAw:
		case Operation::ADDXw:	case Operation::SUBw:
		case Operation::SUBAw:	case Operation::SUBXw:
		case Operation::MOVEw:	case Operation::MOVEAw:
		case Operation::ORItoSR:
		case Operation::ANDItoSR:
		case Operation::EORItoSR:
		case Operation::MOVEtoSR:
		case Operation::MOVEfromSR:
		case Operation::MOVEtoCCR:
		case Operation::CMPw:	case Operation::CMPAw:
		case Operation::TSTw:
		case Operation::DBcc:	case Operation::Scc:
		case Operation::Bccw:	case Operation::BSRw:
		case Operation::CLRw:
		case Operation::NEGXw:	case Operation::NEGw:
		case Operation::ASLw:	case Operation::ASLm:
		case Operation::ASRw:	case Operation::ASRm:
		case Operation::LSLw:	case Operation::LSLm:
		case Operation::LSRw:	case Operation::LSRm:
		case Operation::ROLw:	case Operation::ROLm:
		case Operation::RORw:	case Operation::RORm:
		case Operation::ROXLw:	case Operation::ROXLm:
		case Operation::ROXRw:	case Operation::ROXRm:
		case Operation::MOVEMw:
		case Operation::MOVEPw:
		case Operation::ANDw:	case Operation::EORw:
		case Operation::NOTw:	case Operation::ORw:
		case Operation::DIVU:	case Operation::DIVS:
		case Operation::MULU:	case Operation::MULS:
		case Operation::EXTbtow:
		case Operation::LINKw:
			return DataSize::Word;

		case Operation::ADDl:	case Operation::ADDAl:
		case Operation::ADDXl:	case Operation::SUBl:
		case Operation::SUBAl:	case Operation::SUBXl:
		case Operation::MOVEl:	case Operation::MOVEAl:
		case Operation::LEA:	case Operation::PEA:
		case Operation::EXG:	case Operation::SWAP:
		case Operation::MOVEtoUSP:
		case Operation::MOVEfromUSP:
		case Operation::CMPl:	case Operation::CMPAl:
		case Operation::TSTl:
		case Operation::JMP:	case Operation::JSR:
		case Operation::RTS:
		case Operation::Bccl:	case Operation::BSRl:
		case Operation::CLRl:
		case Operation::NEGXl:	case Operation::NEGl:
		case Operation::ASLl:	case Operation::ASRl:
		case Operation::LSLl:	case Operation::LSRl:
		case Operation::ROLl:	case Operation::RORl:
		case Operation::ROXLl:	case Operation::ROXRl:
		case Operation::MOVEMl:
		case Operation::MOVEPl:
		case Operation::ANDl:	case Operation::EORl:
		case Operation::NOTl:	case Operation::ORl:
		case Operation::EXTwtol:
		case Operation::UNLINK:
			return DataSize::LongWord;
	}
}

template <Operation op>
constexpr uint32_t quick(uint16_t instruction) {
	switch(op) {
		case Operation::Bccb:
		case Operation::BSRb:
		case Operation::MOVEl:	return uint32_t(int8_t(instruction));
		case Operation::TRAP:	return uint32_t(instruction & 15);
		default: {
			uint32_t value = (instruction >> 9) & 7;
			value |= (value - 1)&8;
			return value;
		}
	}
}

constexpr uint32_t quick(Operation op, uint16_t instruction) {
	switch(op) {
		case Operation::MOVEl:	return quick<Operation::MOVEl>(instruction);
		case Operation::Bccb:	return quick<Operation::Bccb>(instruction);
		case Operation::BSRb:	return quick<Operation::BSRb>(instruction);
		case Operation::TRAP:	return quick<Operation::TRAP>(instruction);

		default:
			// ADDw is arbitrary; anything other than those listed above will do.
			return quick<Operation::ADDw>(instruction);
	}
}

/// Indicates the addressing mode applicable to an operand.
///
/// Implementation notes:
///
/// Those entries starting 0b00 or 0b01 are mapped as per the 68000's native encoding;
/// those starting 0b00 are those which are indicated directly by a mode field and those starting
/// 0b01 are those which are indicated by a register field given a mode of 0b111. The only minor
/// exception is AddressRegisterDirect, which exists on a 68000  but isn't specifiable by a
/// mode and register, it's contextual based on the instruction.
///
/// Those modes starting in 0b10 are the various extended addressing modes introduced as
/// of the 68020, which can be detected only after interpreting an extension word. At the
/// Preinstruction stage:
///
///	* AddressRegisterIndirectWithIndexBaseDisplacement, MemoryIndirectPostindexed
///		and MemoryIndirectPreindexed will have been partially decoded as
///		AddressRegisterIndirectWithIndex8bitDisplacement; and
///	* ProgramCounterIndirectWithIndexBaseDisplacement,
///		ProgramCounterMemoryIndirectPostindexed and
///		ProgramCounterMemoryIndirectPreindexed will have been partially decoded
///		as ProgramCounterIndirectWithIndex8bitDisplacement.
enum class AddressingMode: uint8_t {
	/// No adddressing mode; this operand doesn't exist.
	None												= 0b01'101,

	/// Dn
	DataRegisterDirect									= 0b00'000,

	/// An
	AddressRegisterDirect								= 0b00'001,
	/// (An)
	AddressRegisterIndirect								= 0b00'010,
	/// (An)+
	AddressRegisterIndirectWithPostincrement			= 0b00'011,
	/// -(An)
	AddressRegisterIndirectWithPredecrement				= 0b00'100,
	/// (d16, An)
	AddressRegisterIndirectWithDisplacement				= 0b00'101,
	/// (d8, An, Xn)
	AddressRegisterIndirectWithIndex8bitDisplacement	= 0b00'110,
	/// (bd, An, Xn)
	AddressRegisterIndirectWithIndexBaseDisplacement	= 0b10'000,

	/// ([bd, An, Xn], od)
	MemoryIndirectPostindexed							= 0b10'001,
	/// ([bd, An], Xn, od)
	MemoryIndirectPreindexed							= 0b10'010,

	/// (d16, PC)
	ProgramCounterIndirectWithDisplacement				= 0b01'010,
	/// (d8, PC, Xn)
	ProgramCounterIndirectWithIndex8bitDisplacement		= 0b01'011,
	/// (bd, PC, Xn)
	ProgramCounterIndirectWithIndexBaseDisplacement		= 0b10'011,
	/// ([bd, PC, Xn], od)
	ProgramCounterMemoryIndirectPostindexed				= 0b10'100,
	/// ([bc, PC], Xn, od)
	ProgramCounterMemoryIndirectPreindexed				= 0b10'101,

	/// (xxx).W
	AbsoluteShort										= 0b01'000,
	/// (xxx).L
	AbsoluteLong										= 0b01'001,

	/// #
	ImmediateData										= 0b01'100,

	/// .q; value is embedded in the opcode.
	Quick												= 0b01'110,
};

/*!
	A preinstruction is as much of an instruction as can be decoded with
	only the first instruction word — i.e. an operation, and:

	* on the 68000 and 68010, the complete addressing modes;
	* on subsequent, a decent proportion of the addressing mode. See
		the notes on @c AddressingMode for potential aliasing.
*/
class Preinstruction {
	public:
		Operation operation = Operation::Undefined;

		// Instructions come with 0, 1 or 2 operands;
		// the getters below act to provide a list of operands
		// that is terminated by an AddressingMode::None.
		//
		// For two-operand instructions, argument 0 is a source
		// and argument 1 is a destination.
		//
		// For one-operand instructions, only argument 0 will
		// be provided, and will be a source and/or destination as
		// per the semantics of the operation.

		template <int index> AddressingMode mode() const {
			if constexpr (index > 1) {
				return AddressingMode::None;
			}
			return AddressingMode(operands_[index] & 0x1f);
		}
		template <int index> int reg() const {
			if constexpr (index > 1) {
				return 0;
			}
			return operands_[index] >> 5;
		}

	private:
		uint8_t operands_[2] = { uint8_t(AddressingMode::None), uint8_t(AddressingMode::None)};

	public:
		Preinstruction(
			Operation operation,
			AddressingMode op1_mode,	int op1_reg,
			AddressingMode op2_mode,	int op2_reg,
			[[maybe_unused]] bool is_supervisor = false) : operation(operation)
		{
			operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5);
			operands_[1] = uint8_t(op2_mode) | uint8_t(op2_reg << 5);
		}

		Preinstruction(Operation operation, [[maybe_unused]] bool is_supervisor = false) : operation(operation) {}

		Preinstruction(Operation operation, AddressingMode op1_mode, int op1_reg, [[maybe_unused]] bool is_supervisor = false) : operation(operation) {
			operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5);
		}

		// TODO: record is_supervisor.

		Preinstruction() {}
};

}
}

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


<commit_before>/* $Id$ */
# ifndef CPPAD_SUM_I_INV_WORK_INCLUDED
# define CPPAD_SUM_I_INV_WORK_INCLUDED
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-11 Bradley M. Bell

CppAD is distributed under multiple licenses. This distribution is under
the terms of the
                    Common Public License Version 1.0.

A copy of this license is included in the COPYING file of this distribution.
Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
-------------------------------------------------------------------------- */

# include <cppad/cppad.hpp>

extern void sum_i_inv_worker(void);
extern bool sum_i_inv_split(size_t num_sum, size_t num_threads);
extern bool sum_i_inv_combine(double& sum);

# endif
<commit_msg>sum_i_inv_work.hpp: Missing from prevous commit.<commit_after>/* $Id$ */
# ifndef CPPAD_SUM_I_INV_WORK_INCLUDED
# define CPPAD_SUM_I_INV_WORK_INCLUDED
/* --------------------------------------------------------------------------
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-11 Bradley M. Bell

CppAD is distributed under multiple licenses. This distribution is under
the terms of the
                    Common Public License Version 1.0.

A copy of this license is included in the COPYING file of this distribution.
Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
-------------------------------------------------------------------------- */

# include <cppad/cppad.hpp>

extern void sum_i_inv_worker(void);
extern bool sum_i_inv_setup(size_t num_sum, size_t num_threads);
extern bool sum_i_inv_combine(double& sum);

# endif
<|endoftext|>


<commit_before>/*
    KOrganizer Alarm Daemon Client.

    This file is part of KOrganizer.

    Copyright (c) 2002,2003 Cornelius Schumacher

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "koalarmclient.h"

#include "alarmdockwindow.h"
#include "alarmdialog.h"

#include <libkcal/calendarresources.h>

#include <kstandarddirs.h>
#include <kdebug.h>
#include <klocale.h>
#include <kapplication.h>
#include <kwin.h>

#include <qpushbutton.h>

KOAlarmClient::KOAlarmClient( QObject *parent, const char *name )
  : DCOPObject( "ac" ), QObject( parent, name )
{
  kdDebug(5890) << "KOAlarmClient::KOAlarmClient()" << endl;

  mDocker = new AlarmDockWindow;
  mDocker->show();
  connect( this, SIGNAL( reminderCount( int ) ), mDocker, SLOT( slotUpdate( int ) ) );
  connect( mDocker, SIGNAL( quitSignal() ), SLOT( slotQuit() ) );

  KConfig c( locate( "config", "korganizerrc" ) );
  c.setGroup( "Time & Date" );
  QString tz = c.readEntry( "TimeZoneId" );
  kdDebug(5890) << "TimeZone: " << tz << endl;

  mCalendar = new CalendarResources( tz );
  mCalendar->readConfig();
  mCalendar->load();

  connect( &mCheckTimer, SIGNAL( timeout() ), SLOT( checkAlarms() ) );

  KConfig *config = kapp->config();
  config->setGroup( "Alarms" );
  int interval = config->readNumEntry( "Interval", 60 );
  kdDebug(5890) << "KOAlarmClient check interval: " << interval << " seconds."
                << endl;
  mLastChecked = config->readDateTimeEntry( "CalendarsLastChecked" );

  // load reminders that were active when quitting
  config->setGroup( "General" );
  int numReminders = config->readNumEntry( "Reminders", 0 );
  for ( int i=1; i<=numReminders; ++i )
  {
    QString group( QString( "Incidence-%1" ).arg( i ) );
    config->setGroup( group );
    QString uid = config->readEntry( "UID" );
    QDateTime dt = config->readDateTimeEntry( "RemindAt" );
    if ( !uid.isEmpty() )
      createReminder( mCalendar->incidence( uid ), dt );
    config->deleteGroup( group );
  }
  config->setGroup( "General" );
  config->writeEntry( "Reminders", 0 );
  config->sync();

  checkAlarms();
  saveLastCheckTime();
  mCheckTimer.start( 1000 * interval );  // interval in seconds
}

KOAlarmClient::~KOAlarmClient()
{
  delete mCalendar;
  delete mDocker;
}

void KOAlarmClient::checkAlarms()
{
  KConfig *cfg = kapp->config();

  cfg->setGroup( "General" );
  if ( !cfg->readBoolEntry( "Enabled", true ) ) return;

  QDateTime from = mLastChecked.addSecs( 1 );
  mLastChecked = QDateTime::currentDateTime();

  kdDebug(5891) << "Check: " << from.toString() << " - " << mLastChecked.toString() << endl;

  QValueList<Alarm *> alarms = mCalendar->alarms( from, mLastChecked );

  QValueList<Alarm *>::ConstIterator it;
  for( it = alarms.begin(); it != alarms.end(); ++it ) {
    kdDebug(5891) << "ALARM: " << (*it)->parent()->summary() << endl;
    Incidence *incidence = mCalendar->incidence( (*it)->parent()->uid() );
    createReminder( incidence, QDateTime::currentDateTime() );
  }
}

void KOAlarmClient::createReminder( KCal::Incidence *incidence, QDateTime dt )
{
  if ( !incidence )
    return;

  AlarmDialog *dialog = new AlarmDialog();
  dialog->setIncidence( incidence );
  dialog->setRemindAt( dt );
  connect( dialog, SIGNAL( finishedSignal( AlarmDialog *) ), SLOT( slotRemove( AlarmDialog *) ) );
  connect( mDocker, SIGNAL( suspendAllSignal() ), dialog, SLOT( slotUser1() ) );
  connect( mDocker, SIGNAL( dismissAllSignal() ), dialog, SLOT( slotOk() ) );
  connect( this, SIGNAL( saveAllSignal() ), dialog, SLOT( slotSave() ) );
  dialog->wakeUp();
  mReminders.append( dialog );
  emit reminderCount( mReminders.count() );
}

void KOAlarmClient::slotQuit()
{
  emit saveAllSignal();
  saveLastCheckTime();
  quit();
}

void KOAlarmClient::saveLastCheckTime()
{
  KConfig *cfg = kapp->config();
  cfg->setGroup( "Alarms" );
  cfg->writeEntry( "CalendarsLastChecked", mLastChecked );
  cfg->sync();
}

void KOAlarmClient::quit()
{
  kdDebug(5890) << "KOAlarmClient::quit()" << endl;
  kapp->quit();
}

void KOAlarmClient::slotRemove( AlarmDialog *d )
{
  mReminders.remove( d );
  delete d;
  emit reminderCount( mReminders.count() );
}

bool KOAlarmClient::commitData( QSessionManager& )
{
  emit saveAllSignal();
  return true;
}

void KOAlarmClient::forceAlarmCheck()
{
  checkAlarms();
}

void KOAlarmClient::dumpDebug()
{
  KConfig *cfg = kapp->config();

  cfg->setGroup( "Alarms" );
  QDateTime lastChecked = cfg->readDateTimeEntry( "CalendarsLastChecked" );

  kdDebug(5890) << "Last Check: " << lastChecked << endl;
}

QStringList KOAlarmClient::dumpAlarms()
{
  QDateTime start = QDateTime( QDateTime::currentDateTime().date(),
                               QTime( 0, 0 ) );
  QDateTime end = start.addDays( 1 ).addSecs( -1 );

  QStringList lst;
  // Don't translate, this is for debugging purposes.
  lst << QString("AlarmDeamon::dumpAlarms() from ") + start.toString()+ " to " +
         end.toString();

  QValueList<Alarm*> alarms = mCalendar->alarms( start, end );
  QValueList<Alarm*>::ConstIterator it;
  for( it = alarms.begin(); it != alarms.end(); ++it ) {
    Alarm *a = *it;
    lst << QString("  ") + a->parent()->summary() + " ("
              + a->time().toString() + ")";
  }

  return lst;
}

void KOAlarmClient::debugShowDialog()
{
//   showAlarmDialog();
}

#include "koalarmclient.moc"
<commit_msg>- remember last check on logout BUG: 102489<commit_after>/*
    KOrganizer Alarm Daemon Client.

    This file is part of KOrganizer.

    Copyright (c) 2002,2003 Cornelius Schumacher

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "koalarmclient.h"

#include "alarmdockwindow.h"
#include "alarmdialog.h"

#include <libkcal/calendarresources.h>

#include <kstandarddirs.h>
#include <kdebug.h>
#include <klocale.h>
#include <kapplication.h>
#include <kwin.h>

#include <qpushbutton.h>

KOAlarmClient::KOAlarmClient( QObject *parent, const char *name )
  : DCOPObject( "ac" ), QObject( parent, name )
{
  kdDebug(5890) << "KOAlarmClient::KOAlarmClient()" << endl;

  mDocker = new AlarmDockWindow;
  mDocker->show();
  connect( this, SIGNAL( reminderCount( int ) ), mDocker, SLOT( slotUpdate( int ) ) );
  connect( mDocker, SIGNAL( quitSignal() ), SLOT( slotQuit() ) );

  KConfig c( locate( "config", "korganizerrc" ) );
  c.setGroup( "Time & Date" );
  QString tz = c.readEntry( "TimeZoneId" );
  kdDebug(5890) << "TimeZone: " << tz << endl;

  mCalendar = new CalendarResources( tz );
  mCalendar->readConfig();
  mCalendar->load();

  connect( &mCheckTimer, SIGNAL( timeout() ), SLOT( checkAlarms() ) );

  KConfig *config = kapp->config();
  config->setGroup( "Alarms" );
  int interval = config->readNumEntry( "Interval", 60 );
  kdDebug(5890) << "KOAlarmClient check interval: " << interval << " seconds."
                << endl;
  mLastChecked = config->readDateTimeEntry( "CalendarsLastChecked" );

  // load reminders that were active when quitting
  config->setGroup( "General" );
  int numReminders = config->readNumEntry( "Reminders", 0 );
  for ( int i=1; i<=numReminders; ++i )
  {
    QString group( QString( "Incidence-%1" ).arg( i ) );
    config->setGroup( group );
    QString uid = config->readEntry( "UID" );
    QDateTime dt = config->readDateTimeEntry( "RemindAt" );
    if ( !uid.isEmpty() )
      createReminder( mCalendar->incidence( uid ), dt );
    config->deleteGroup( group );
  }
  config->setGroup( "General" );
  config->writeEntry( "Reminders", 0 );
  config->sync();

  checkAlarms();
  saveLastCheckTime();
  mCheckTimer.start( 1000 * interval );  // interval in seconds
}

KOAlarmClient::~KOAlarmClient()
{
  delete mCalendar;
  delete mDocker;
}

void KOAlarmClient::checkAlarms()
{
  KConfig *cfg = kapp->config();

  cfg->setGroup( "General" );
  if ( !cfg->readBoolEntry( "Enabled", true ) ) return;

  QDateTime from = mLastChecked.addSecs( 1 );
  mLastChecked = QDateTime::currentDateTime();

  kdDebug(5891) << "Check: " << from.toString() << " - " << mLastChecked.toString() << endl;

  QValueList<Alarm *> alarms = mCalendar->alarms( from, mLastChecked );

  QValueList<Alarm *>::ConstIterator it;
  for( it = alarms.begin(); it != alarms.end(); ++it ) {
    kdDebug(5891) << "ALARM: " << (*it)->parent()->summary() << endl;
    Incidence *incidence = mCalendar->incidence( (*it)->parent()->uid() );
    createReminder( incidence, QDateTime::currentDateTime() );
  }
}

void KOAlarmClient::createReminder( KCal::Incidence *incidence, QDateTime dt )
{
  if ( !incidence )
    return;

  AlarmDialog *dialog = new AlarmDialog();
  dialog->setIncidence( incidence );
  dialog->setRemindAt( dt );
  connect( dialog, SIGNAL( finishedSignal( AlarmDialog *) ), SLOT( slotRemove( AlarmDialog *) ) );
  connect( mDocker, SIGNAL( suspendAllSignal() ), dialog, SLOT( slotUser1() ) );
  connect( mDocker, SIGNAL( dismissAllSignal() ), dialog, SLOT( slotOk() ) );
  connect( this, SIGNAL( saveAllSignal() ), dialog, SLOT( slotSave() ) );
  dialog->wakeUp();
  mReminders.append( dialog );
  emit reminderCount( mReminders.count() );
}

void KOAlarmClient::slotQuit()
{
  emit saveAllSignal();
  saveLastCheckTime();
  quit();
}

void KOAlarmClient::saveLastCheckTime()
{
  KConfig *cfg = kapp->config();
  cfg->setGroup( "Alarms" );
  cfg->writeEntry( "CalendarsLastChecked", mLastChecked );
  cfg->sync();
}

void KOAlarmClient::quit()
{
  kdDebug(5890) << "KOAlarmClient::quit()" << endl;
  kapp->quit();
}

void KOAlarmClient::slotRemove( AlarmDialog *d )
{
  mReminders.remove( d );
  delete d;
  emit reminderCount( mReminders.count() );
}

bool KOAlarmClient::commitData( QSessionManager& )
{
  emit saveAllSignal();
  saveLastCheckTime();
  return true;
}

void KOAlarmClient::forceAlarmCheck()
{
  checkAlarms();
}

void KOAlarmClient::dumpDebug()
{
  KConfig *cfg = kapp->config();

  cfg->setGroup( "Alarms" );
  QDateTime lastChecked = cfg->readDateTimeEntry( "CalendarsLastChecked" );

  kdDebug(5890) << "Last Check: " << lastChecked << endl;
}

QStringList KOAlarmClient::dumpAlarms()
{
  QDateTime start = QDateTime( QDateTime::currentDateTime().date(),
                               QTime( 0, 0 ) );
  QDateTime end = start.addDays( 1 ).addSecs( -1 );

  QStringList lst;
  // Don't translate, this is for debugging purposes.
  lst << QString("AlarmDeamon::dumpAlarms() from ") + start.toString()+ " to " +
         end.toString();

  QValueList<Alarm*> alarms = mCalendar->alarms( start, end );
  QValueList<Alarm*>::ConstIterator it;
  for( it = alarms.begin(); it != alarms.end(); ++it ) {
    Alarm *a = *it;
    lst << QString("  ") + a->parent()->summary() + " ("
              + a->time().toString() + ")";
  }

  return lst;
}

void KOAlarmClient::debugShowDialog()
{
//   showAlarmDialog();
}

#include "koalarmclient.moc"
<|endoftext|>


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

using namespace smath;

int main()
{
    // Constructor tests
    constexpr auto ratio = rational<int>(4, 2);
    static_assert(ratio.numerator() == 4, "");
    static_assert(ratio.denominator() == 2, "");

    constexpr auto ratio2 = rational<int>(5);
    static_assert(ratio2.numerator() == 5, "");
    static_assert(ratio2.denominator() == 1, "");

    constexpr auto r1 = rational<int>(1, 2);
    constexpr auto r2 = rational<int>(2, 4);
    constexpr auto r3 = rational<int>(1, 3);
    constexpr auto r4 = rational<int>(5, 1);

    // rational-rational comparison
    static_assert(r1 == r2, "");
    static_assert(r1 != r3, "");
    static_assert(r1 > r3, "");
    static_assert(r3 < r2, "");
    static_assert(r1 >= r2, "");
    static_assert(r3 <= r2, "");

    // rational-integral comparison
    static_assert(r4 == 5, "");
    static_assert(5 == r4, "");
    static_assert(r1 != 3, "");
    static_assert(8 != r2, "");
    static_assert(0 < r1, "");
    static_assert(r2 < 1, "");
    static_assert(8 > r4, "");
    static_assert(r2 > -1, "");
    static_assert(5 <= r4, "");
    static_assert(r3 <= 1, "");
    static_assert(1 >= r3, "");
    static_assert(r1 >= -8, "");

    // rational-rational arithmetic operations
    static_assert(r1 + r2 == 1, "");
    static_assert(r4 - r1 == rational<int>(9, 2), "");
    static_assert(r2 * r3 == rational<int>(1, 6), "");
    static_assert(r1 / r3 == rational<int>(3, 2), "");

    // rational-integral arithmetic operations
    static_assert(r1 + 1 == rational<int>(3, 2), "");
    static_assert(2 + r2 == rational<int>(5, 2), "");
    static_assert(r3 - 3 == rational<int>(-8, 3), "");
    static_assert(2 - r1 == rational<int>(3, 2), "");
    static_assert(r4 * 2 == 10, "");
    static_assert(6 * r2 == r1 * 6, "");
    static_assert(1 / r2 == 2, "");
    static_assert(r3 / 3 == rational<int>(1, 9), "");

    // _smath_r literal
    static_assert(2 / 3_static_r == rational<unsigned long long>(2, 3), "");

    return 0;
}
<commit_msg>Tests for casts, literals and abs function.<commit_after>/*
 * Copyright (C) 2011-2012 Morwenn
 *
 * static_math is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * static_math is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <static_math/rational.h>

using namespace smath;

int main()
{
    // Constructor tests
    constexpr auto ratio = rational<int>(4, 2);
    static_assert(ratio.numerator() == 4, "");
    static_assert(ratio.denominator() == 2, "");

    constexpr auto ratio2 = rational<int>(5);
    static_assert(ratio2.numerator() == 5, "");
    static_assert(ratio2.denominator() == 1, "");

    constexpr auto r1 = rational<int>(1, 2);
    constexpr auto r2 = rational<int>(2, 4);
    constexpr auto r3 = rational<int>(1, 3);
    constexpr auto r4 = rational<int>(5, 1);
    constexpr auto r5 = rational<int>(-1, 2);
    constexpr auto r6 = rational<int>(1, -2);

    // rational-rational comparison
    static_assert(r1 == r2, "");
    static_assert(r1 != r3, "");
    static_assert(r1 > r3, "");
    static_assert(r3 < r2, "");
    static_assert(r1 >= r2, "");
    static_assert(r3 <= r2, "");
    static_assert(r5 == r6, "");

    // rational-integral comparison
    static_assert(r4 == 5, "");
    static_assert(5 == r4, "");
    static_assert(r1 != 3, "");
    static_assert(8 != r2, "");
    static_assert(0 < r1, "");
    static_assert(r2 < 1, "");
    static_assert(8 > r4, "");
    static_assert(r2 > -1, "");
    static_assert(5 <= r4, "");
    static_assert(r3 <= 1, "");
    static_assert(1 >= r3, "");
    static_assert(r1 >= -8, "");
    static_assert(r5 <= 0, "");
    static_assert(r6 <= 0, "");

    // rational-rational arithmetic operations
    static_assert(r1 + r2 == 1, "");
    static_assert(r4 - r1 == rational<int>(9, 2), "");
    static_assert(r2 * r3 == rational<int>(1, 6), "");
    static_assert(r1 / r3 == rational<int>(3, 2), "");

    // rational-integral arithmetic operations
    static_assert(r1 + 1 == rational<int>(3, 2), "");
    static_assert(2 + r2 == rational<int>(5, 2), "");
    static_assert(r3 - 3 == rational<int>(-8, 3), "");
    static_assert(2 - r1 == rational<int>(3, 2), "");
    static_assert(r4 * 2 == 10, "");
    static_assert(6 * r2 == r1 * 6, "");
    static_assert(1 / r2 == 2, "");
    static_assert(r3 / 3 == rational<int>(1, 9), "");

    // cast
    static_assert(rational<int>(1, 2) == rational<long int>(1, 2), "");
    static_assert(rational<unsigned long long>(3, 2) == rational<short>(3, 2), "");

    // _smath_r literal
    static_assert(2 / 3_static_r == rational<unsigned long long>(2, 3), "");
    static_assert(1_static_r / 8 == rational<unsigned long long>(1, 8), "");
    static_assert(3 / 5_static_r == 3_static_r / 5, "");

    constexpr auto a1 = rational<int>(1, 2);
    constexpr auto a2 = rational<int>(-3, 8);
    constexpr auto a3 = rational<int>(6, -7);

    // Math functions
    static_assert(abs(a1) == 1 / 2_static_r, "");
    static_assert(abs(a2) == 3 / 8_static_r, "");
    static_assert(abs(a3) == 6 / 7_static_r, "");

    return 0;
}
<|endoftext|>


<commit_before>#include <mist/io/raw.h>
#include <mist/draw.h>
#include <iostream>
#include "ct_image_window.h"
#include <FL/Fl_File_Chooser.H>

#include <mist/filter/median_filter.h>
#include <mist/filter/distance.h>

void ct_draw_area::draw( )
{
	mist::draw_image( buff, w( ), h( ) );
}

void ct_draw_area::draw_image( )
{
	if( ct.empty( ) )
	{
		return;
	}

	if( draw_flag_ )
	{
		return;
	}

	draw_flag_ = true;

	if( buff.width( ) != ct.width( ) || buff.height( ) != ct.height( ) )
	{
		buff.resize( ct.width( ), ct.height( ) );
	}
	buff.reso1( ct.reso1( ) );
	buff.reso2( ct.reso2( ) );

	mist::array3< short >::size_type i, j;
	double pixel;
	for( j = 0 ; j < ct.height( ) ; j++ )
	{
		for( i = 0 ; i < ct.width( ) ; i++ )
		{
			pixel = ( ct( i, j, index_ ) - window_level_ ) / window_width_ * 256.0 + 128.0;
			pixel = pixel <   0.0 ?   0.0 : pixel;
			pixel = pixel > 255.0 ? 255.0 : pixel;
			buff( i, j ) = static_cast< unsigned char >( pixel );
		}
	}

	draw_flag_ = false;
}

void ct_draw_area::read_image( ct_image_window *wnd )
{
	const char *filename = fl_file_chooser( "Open", "*", "" );
	if( filename == NULL ) return;

	size_type w = 512;
	size_type h = 512;
	size_type d = 189;
	double x = 0.625;
	double y = 0.625;
	double z = 1.0;

	parameter_window window;
	window.width->value( w );
	window.height->value( h );
	window.depth->value( d );
	window.sizeX->value( x );
	window.sizeY->value( y );
	window.sizeZ->value( z );

	if( window.show( ) )
	{
		w = static_cast< size_type >( window.width->value( ) );
		h = static_cast< size_type >( window.height->value( ) );
		d = static_cast< size_type >( window.depth->value( ) );
		x = window.sizeX->value( );
		y = window.sizeY->value( );
		z = window.sizeZ->value( );

		if( mist::read_raw( ct, filename, w, h, d, x, y, z ) )
		{
			wnd->Indx->range( 0, ct.depth( ) - 1 );
		}
		else
		{
			wnd->Indx->range( 0, 0 );
		}
		wnd->Indx->value( 0 );
		change_index( 0 );
	}
}

void ct_draw_area::write_image( ct_image_window *w )
{
	const char *filename = fl_file_chooser( "Save", "*", "" );
	if( filename == NULL ) return;

	mist::write_raw_gz( ct, filename );
}

void ct_draw_area::change_index( size_type index )
{
	if( 0 <= index && index < ct.depth( ) )
	{
		index_ = index;
		draw_image( );
		redraw( );
		Fl::wait( 0 );
	}
}

void ct_draw_area::change_window_level( double wl )
{
	window_level_ = wl;
	draw_image( );
	redraw( );
	Fl::wait( 0 );
}

void ct_draw_area::change_window_width( double ww )
{
	window_width_ = ww;
	draw_image( );
	redraw( );
	Fl::wait( 0 );
}

void ct_draw_area::median_filter1D( ct_image_window *wnd )
{
	mist::array< int > a( 7 ), b( 7 );
	a[ 0 ] = 0;
	a[ 1 ] = 4;
	a[ 2 ] = 2;
	a[ 3 ] = 3;
	a[ 4 ] = 2;
	a[ 5 ] = 4;
	a[ 6 ] = 0;

	std::cout << a << std::endl;
	mist::median_filter( a, b, 3 );
	std::cout << b << std::endl;
}

void ct_draw_area::median_filter2D( ct_image_window *wnd )
{
	mist::array2< int > a( 5, 5 ), b( 5, 5 );
	a( 0, 0 ) = 0; a( 0, 1 ) = 0; a( 0, 2 ) = 0; a( 0, 3 ) = 0; a( 0, 4 ) = 0;
	a( 1, 0 ) = 0; a( 1, 1 ) = 4; a( 1, 2 ) = 5; a( 1, 3 ) = 4; a( 1, 4 ) = 0;
	a( 2, 0 ) = 0; a( 2, 1 ) = 3; a( 2, 2 ) = 2; a( 2, 3 ) = 3; a( 2, 4 ) = 0;
	a( 3, 0 ) = 0; a( 3, 1 ) = 4; a( 3, 2 ) = 5; a( 3, 3 ) = 4; a( 3, 4 ) = 0;
	a( 4, 0 ) = 0; a( 4, 1 ) = 0; a( 4, 2 ) = 0; a( 4, 3 ) = 0; a( 4, 4 ) = 0;

	std::cout << a << std::endl;
	mist::median_filter( a, b, 3, 3 );
	std::cout << b << std::endl;
}

void ct_draw_area::median_filter3D( ct_image_window *wnd )
{
	if( ct.empty( ) ) return;

	mist::array3< short > tmp = ct;
	mist::median_filter( tmp, ct, 3, 3, 3 );
	redraw( );
	Fl::wait( 0 );
}

void ct_draw_area::euclidean_distance_transform( ct_image_window *wnd )
{
	if( ct.empty( ) ) return;

	mist::array3< short > tmp = ct;
	mist::euclidean_distance_transform( tmp, ct );
	redraw( );
	Fl::wait( 0 );
}

int main( int argc, char *argv[] )
{
	ct_image_window window;
	Fl::gl_visual( FL_RGB );
	window.show( );
	Fl::background( 212, 208, 200 );
	Fl::run();
}
<commit_msg>メディアンフィルタの計算時間を表示<commit_after>#include <mist/io/raw.h>
#include <mist/draw.h>
#include <iostream>
#include "ct_image_window.h"
#include <FL/Fl_File_Chooser.H>

#include <mist/filter/median_filter.h>
#include <mist/filter/distance.h>
#include <mist/timer.h>

void ct_draw_area::draw( )
{
	mist::draw_image( buff, w( ), h( ) );
}

void ct_draw_area::draw_image( )
{
	if( ct.empty( ) )
	{
		return;
	}

	if( draw_flag_ )
	{
		return;
	}

	draw_flag_ = true;

	if( buff.width( ) != ct.width( ) || buff.height( ) != ct.height( ) )
	{
		buff.resize( ct.width( ), ct.height( ) );
	}
	buff.reso1( ct.reso1( ) );
	buff.reso2( ct.reso2( ) );

	mist::array3< short >::size_type i, j;
	double pixel;
	for( j = 0 ; j < ct.height( ) ; j++ )
	{
		for( i = 0 ; i < ct.width( ) ; i++ )
		{
			pixel = ( ct( i, j, index_ ) - window_level_ ) / window_width_ * 256.0 + 128.0;
			pixel = pixel <   0.0 ?   0.0 : pixel;
			pixel = pixel > 255.0 ? 255.0 : pixel;
			buff( i, j ) = static_cast< unsigned char >( pixel );
		}
	}

	draw_flag_ = false;
}

void ct_draw_area::read_image( ct_image_window *wnd )
{
	const char *filename = fl_file_chooser( "Open", "*", "" );
	if( filename == NULL ) return;

	size_type w = 512;
	size_type h = 512;
	size_type d = 189;
	double x = 0.625;
	double y = 0.625;
	double z = 1.0;

	parameter_window window;
	window.width->value( w );
	window.height->value( h );
	window.depth->value( d );
	window.sizeX->value( x );
	window.sizeY->value( y );
	window.sizeZ->value( z );

	if( window.show( ) )
	{
		w = static_cast< size_type >( window.width->value( ) );
		h = static_cast< size_type >( window.height->value( ) );
		d = static_cast< size_type >( window.depth->value( ) );
		x = window.sizeX->value( );
		y = window.sizeY->value( );
		z = window.sizeZ->value( );

		if( mist::read_raw( ct, filename, w, h, d, x, y, z ) )
		{
			wnd->Indx->range( 0, ct.depth( ) - 1 );
		}
		else
		{
			wnd->Indx->range( 0, 0 );
		}
		wnd->Indx->value( 0 );
		change_index( 0 );
	}
}

void ct_draw_area::write_image( ct_image_window *w )
{
	const char *filename = fl_file_chooser( "Save", "*", "" );
	if( filename == NULL ) return;

	mist::write_raw_gz( ct, filename );
}

void ct_draw_area::change_index( size_type index )
{
	if( 0 <= index && index < ct.depth( ) )
	{
		index_ = index;
		draw_image( );
		redraw( );
		Fl::wait( 0 );
	}
}

void ct_draw_area::change_window_level( double wl )
{
	window_level_ = wl;
	draw_image( );
	redraw( );
	Fl::wait( 0 );
}

void ct_draw_area::change_window_width( double ww )
{
	window_width_ = ww;
	draw_image( );
	redraw( );
	Fl::wait( 0 );
}

void ct_draw_area::median_filter1D( ct_image_window *wnd )
{
	mist::array< int > a( 7 ), b( 7 );
	a[ 0 ] = 0;
	a[ 1 ] = 4;
	a[ 2 ] = 2;
	a[ 3 ] = 3;
	a[ 4 ] = 2;
	a[ 5 ] = 4;
	a[ 6 ] = 0;

	std::cout << a << std::endl;
	mist::median_filter( a, b, 3 );
	std::cout << b << std::endl;
}

void ct_draw_area::median_filter2D( ct_image_window *wnd )
{
	mist::array2< int > a( 5, 5 ), b( 5, 5 );
	a( 0, 0 ) = 0; a( 0, 1 ) = 0; a( 0, 2 ) = 0; a( 0, 3 ) = 0; a( 0, 4 ) = 0;
	a( 1, 0 ) = 0; a( 1, 1 ) = 4; a( 1, 2 ) = 5; a( 1, 3 ) = 4; a( 1, 4 ) = 0;
	a( 2, 0 ) = 0; a( 2, 1 ) = 3; a( 2, 2 ) = 2; a( 2, 3 ) = 3; a( 2, 4 ) = 0;
	a( 3, 0 ) = 0; a( 3, 1 ) = 4; a( 3, 2 ) = 5; a( 3, 3 ) = 4; a( 3, 4 ) = 0;
	a( 4, 0 ) = 0; a( 4, 1 ) = 0; a( 4, 2 ) = 0; a( 4, 3 ) = 0; a( 4, 4 ) = 0;

	std::cout << a << std::endl;
	mist::median_filter( a, b, 3, 3 );
	std::cout << b << std::endl;
}

void ct_draw_area::median_filter3D( ct_image_window *wnd )
{
	if( ct.empty( ) ) return;

	mist::array3< short > tmp = ct;
	{
		mist::timer t;
		mist::median_filter( tmp, ct, 3, 3, 3 );
		std::cout << "Computation Time: " << t.elapse( ) << std::endl;
	}
	redraw( );
	Fl::wait( 0 );
}

void ct_draw_area::euclidean_distance_transform( ct_image_window *wnd )
{
	if( ct.empty( ) ) return;

	mist::array3< short > tmp = ct;
	mist::euclidean_distance_transform( tmp, ct );
	redraw( );
	Fl::wait( 0 );
}

int main( int argc, char *argv[] )
{
	ct_image_window window;
	Fl::gl_visual( FL_RGB );
	window.show( );
	Fl::background( 212, 208, 200 );
	Fl::run();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 Pelagicore AB
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 * For further information see LICENSE
 */

#include "softwarecontaineragentadaptor.h"

LOG_DEFINE_APP_IDS("SCAG", "SoftwareContainer agent");

namespace softwarecontainer {
    LOG_DECLARE_DEFAULT_CONTEXT(PAM_DefaultLogContext, "MAIN", "Main context");
}

void usage(const char *argv0)
{
    printf("SoftwareContainer agent, v.%s\n", PACKAGE_VERSION);
    printf("Usage: %s [options]\n", argv0);
    printf("Options:\n");
    printf("  -p, --preload <num>     : Number of containers to preload, defaults to 0\n");
    printf("  -u, --user <uid>        : Default user id to be used when starting processes in the container, defaults to 0\n");
    printf("  -s, --shutdown <bool>   : If false, containers will not be shutdown on exit. Useful for debugging. Defaults to true\n");
    printf("  -t, --timeout <seconds> : Timeout in seconds to wait for containers to shutdown, defaults to 1\n");
    printf("  -m, --manifest <path>   : Path to a file or directory where service manifest(s) exist, defaults to \"\"\n");
    printf("  -b, --session-bus       : Use the session bus instead of the system bus\n");
    printf("  -h, --help              : Prints this help message and exits.\n");
}

/*
 * When we get signals that can be trapped, we want the main loop to be quitted.
 */
int signalHandler(void *data) {
    log_debug() << "Caught signal, exiting!";
    Glib::RefPtr<Glib::MainLoop> *ml = static_cast<Glib::RefPtr<Glib::MainLoop> *>(data);
    (*ml)->quit();
    return 0;
}

/*
 * Tries to register the agent on the given bus. If the system bus is given and fails,
 * this tries to register to the session bus instead.
 *
 * Throws a ReturnCode on failure
 */
DBus::Connection getBusConnection(bool useSystemBus)
{
    std::string busStr = useSystemBus ? "system" : "session";
    try {
        DBus::Connection bus = useSystemBus ? DBus::Connection::SystemBus()
                                            : DBus::Connection::SessionBus();

        // Check if the name is available or not
        bool alreadyTaken = bus.has_name(AGENT_BUS_NAME);
        if (alreadyTaken) {
            log_error() << AGENT_BUS_NAME << " is already taken on the " << busStr << " bus.";
            throw ReturnCode::FAILURE;
        }

        DBus::Connection connection(bus);
        connection.request_name(AGENT_BUS_NAME);
        return connection;

    } catch (DBus::Error &err) {
        log_warning() << "Could not register " << AGENT_BUS_NAME << " to the " << busStr << " bus";
        throw ReturnCode::FAILURE;
    }
}

int main(int argc, char **argv)
{
    static struct option long_options[] =
    {
        { "preload",     required_argument, 0, 'p' },
        { "user",        required_argument, 0, 'u' },
        { "shutdown",    required_argument, 0, 's' },
        { "timeout",     required_argument, 0, 't' },
        { "manifest",    required_argument, 0, 'm' },
        { "session-bus", no_argument,       0, 'b' },
        { "help",        no_argument,       0, 'h' },
        { 0, 0, 0, 0 }
    };

    int preloadCount = 0;
    int userID = 0;
    bool shutdownContainers = true;
    int timeout = 1;
    std::string servicemanifest = "";
    bool useSystemBus = true;

    int option_index = 0;
    int c = 0;
    while((c = getopt_long(argc, argv, "p:u:s:t:m:hb", long_options, &option_index)) != -1) {
        switch(c) {
            case 'p':
                if (!parseInt(optarg, &preloadCount)) {
                    usage(argv[0]);
                    exit(1);
                }
                break;
            case 'u':
                if (!parseInt(optarg, &userID)) {
                    usage(argv[0]);
                    exit(1);
                }
                break;
            case 's':
                shutdownContainers = std::string(optarg).compare("true") == 0;
                break;
            case 't':
                if (!parseInt(optarg, &timeout)) {
                    usage(argv[0]);
                    exit(1);
                }
                break;
            case 'm':
                servicemanifest = std::string(optarg);
                break;
            case 'b':
                useSystemBus = false;
                break;
            case 'h':
                usage(argv[0]);
                exit(0);
                break;

            case '?':
                usage(argv[0]);
                exit(1);
                break;
        }
    }

    profilepoint("softwareContainerStart");
    log_debug() << "Starting softwarecontainer agent";

    Glib::RefPtr<Glib::MainContext> mainContext = Glib::MainContext::get_default();
    Glib::RefPtr<Glib::MainLoop> ml = Glib::MainLoop::create(mainContext);

    DBus::Glib::BusDispatcher dbusDispatcher;
    DBus::default_dispatcher = &dbusDispatcher;
    dbusDispatcher.attach(mainContext->gobj());

    try {
        DBus::Connection connection = getBusConnection(useSystemBus);
        SoftwareContainerAgent agent(mainContext,
                                     preloadCount,
                                     shutdownContainers,
                                     timeout,
                                     servicemanifest);
        std::unique_ptr<SoftwareContainerAgentAdaptor> adaptor =
            std::unique_ptr<SoftwareContainerAgentAdaptor>(
                new DBusCppAdaptor(connection, AGENT_OBJECT_PATH, agent)
            );

        // Register UNIX signal handler
        g_unix_signal_add(SIGINT, &signalHandler, &ml);
        g_unix_signal_add(SIGTERM, &signalHandler, &ml);
        ml->run();

        log_debug() << "Exiting softwarecontainer agent";
        return 0;
    } catch (ReturnCode failure) {
        log_error() << "Agent initialization failed";
        return 1;
    }

}
<commit_msg>Uses glibmm for cmdline option handling<commit_after>/*
 * Copyright (C) 2016 Pelagicore AB
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 * For further information see LICENSE
 */

#include "softwarecontaineragentadaptor.h"
#include <glibmm/optioncontext.h>

LOG_DEFINE_APP_IDS("SCAG", "SoftwareContainer agent");

namespace softwarecontainer {
    LOG_DECLARE_DEFAULT_CONTEXT(PAM_DefaultLogContext, "MAIN", "Main context");
}

/*
 * When we get signals that can be trapped, we want the main loop to be quitted.
 */
int signalHandler(void *data) {
    log_debug() << "Caught signal, exiting!";
    Glib::RefPtr<Glib::MainLoop> *ml = static_cast<Glib::RefPtr<Glib::MainLoop> *>(data);
    (*ml)->quit();
    return 0;
}

/*
 * Tries to register the agent on the given bus. If the system bus is given and fails,
 * this tries to register to the session bus instead.
 *
 * Throws a ReturnCode on failure
 */
DBus::Connection getBusConnection(bool useSessionBus)
{
    std::string busStr = useSessionBus ? "session" : "system";
    try {
        DBus::Connection bus = useSessionBus ? DBus::Connection::SessionBus()
                                             : DBus::Connection::SystemBus();

        // Check if the name is available or not
        bool alreadyTaken = bus.has_name(AGENT_BUS_NAME);
        if (alreadyTaken) {
            log_error() << AGENT_BUS_NAME << " is already taken on the " << busStr << " bus.";
            throw ReturnCode::FAILURE;
        }

        DBus::Connection connection(bus);
        connection.request_name(AGENT_BUS_NAME);
        log_debug() << "Registered " << AGENT_BUS_NAME << " on the " << busStr << " bus.";
        return connection;

    } catch (DBus::Error &err) {
        log_warning() << "Could not register " << AGENT_BUS_NAME << " to the " << busStr << " bus";
        throw ReturnCode::FAILURE;
    }
}

int main(int argc, char **argv)
{
    Glib::OptionEntry preloadOpt;
    preloadOpt.set_long_name("preload");
    preloadOpt.set_short_name('p');
    preloadOpt.set_arg_description("<number>");
    preloadOpt.set_description("Number of containers to preload, defaults to 0");

    Glib::OptionEntry userOpt;
    userOpt.set_long_name("user");
    userOpt.set_short_name('u');
    userOpt.set_arg_description("<uid>");
    userOpt.set_description("Default user id to be used when starting processes in the container, defaults to 0");

    Glib::OptionEntry shutdownOpt;
    shutdownOpt.set_long_name("shutdown");
    shutdownOpt.set_short_name('s');
    shutdownOpt.set_arg_description("<bool>");
    shutdownOpt.set_description("If false, containers will not be shutdown on exit. Useful for debugging. Defaults to true");

    Glib::OptionEntry timeoutOpt;
    timeoutOpt.set_long_name("timeout");
    timeoutOpt.set_short_name('t');
    timeoutOpt.set_arg_description("<seconds>");
    timeoutOpt.set_description("Timeout in seconds to wait for containers to shutdown, defaults to 1");

    Glib::OptionEntry manifestOpt;
    manifestOpt.set_long_name("manifest");
    manifestOpt.set_short_name('m');
    manifestOpt.set_arg_description("<filepath>");
    manifestOpt.set_description("Path to a file or directory where service manifest(s) exist, defaults to nothing");

    Glib::OptionEntry sessionBusOpt;
    sessionBusOpt.set_long_name("session-bus");
    sessionBusOpt.set_short_name('b');
    sessionBusOpt.set_description("Use the session bus instead of the system bus");

    int preloadCount = 0;
    int userID = 0;
    bool shutdownContainers = true;
    int timeout = 1;
    Glib::ustring servicemanifest = "";
    bool useSessionBus = false;

    Glib::OptionGroup mainGroup("Options", "Options for SoftwareContainer");
    mainGroup.add_entry(preloadOpt, preloadCount);
    mainGroup.add_entry(userOpt, userID);
    mainGroup.add_entry(shutdownOpt, shutdownContainers);
    mainGroup.add_entry(timeoutOpt, timeout);
    mainGroup.add_entry(manifestOpt, servicemanifest);
    mainGroup.add_entry(sessionBusOpt, useSessionBus);

    Glib::OptionContext optionContext;
    optionContext.set_help_enabled(true); // Automatic --help
    optionContext.set_ignore_unknown_options(false);
    optionContext.set_summary("SoftwareContainer Agent v" + std::string(PACKAGE_VERSION));
    optionContext.set_description("Documentation is available at http://pelagicore.github.io/softwarecontainer");
    optionContext.set_main_group(mainGroup);

    try {
        optionContext.parse(argc, argv);
    } catch (Glib::OptionError &err) {
        log_error() << err.what();
        exit(1);
    }

    profilepoint("softwareContainerStart");
    log_debug() << "Starting softwarecontainer agent";

    Glib::RefPtr<Glib::MainContext> mainContext = Glib::MainContext::get_default();
    Glib::RefPtr<Glib::MainLoop> ml = Glib::MainLoop::create(mainContext);

    DBus::Glib::BusDispatcher dbusDispatcher;
    DBus::default_dispatcher = &dbusDispatcher;
    dbusDispatcher.attach(mainContext->gobj());

    try {
        DBus::Connection connection = getBusConnection(useSessionBus);
        SoftwareContainerAgent agent(mainContext,
                                     preloadCount,
                                     shutdownContainers,
                                     timeout,
                                     servicemanifest);
        std::unique_ptr<SoftwareContainerAgentAdaptor> adaptor =
            std::unique_ptr<SoftwareContainerAgentAdaptor>(
                new DBusCppAdaptor(connection, AGENT_OBJECT_PATH, agent)
            );

        // Register UNIX signal handler
        g_unix_signal_add(SIGINT, &signalHandler, &ml);
        g_unix_signal_add(SIGTERM, &signalHandler, &ml);
        ml->run();

        log_debug() << "Exiting softwarecontainer agent";
        return 0;
    } catch (ReturnCode failure) {
        log_error() << "Agent initialization failed";
        return 1;
    }

}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: image_util.cpp 36 2005-04-05 14:32:18Z pavlenko $

// stl
#include <string>
// mapnik
#include <mapnik/graphics.hpp>
#include <mapnik/memory.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_view.hpp>
// jpeg png
extern "C"
{
#include <png.h>
#include <jpeglib.h>
}

namespace mapnik
{
    template <typename T>
    void save_to_file(std::string const& filename,
                      std::string const& type,
                      T const& image)
    {
        //all that should go into image_writer factory
        if (type=="png")
        {
            save_as_png(filename,image);
        }
        else if (type=="jpeg")
        {
            save_as_jpeg(filename,85,image);
        }
    }

    template <typename T>
    void save_as_png(std::string const& filename, T const& image)
    {
        FILE *fp=fopen(filename.c_str(), "wb");
        if (!fp) return;
        png_voidp error_ptr=0;
        png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                    error_ptr,0, 0);

        if (!png_ptr) return;

        // switch on optimization only if supported
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
        png_uint_32 mask, flags;

        flags = png_get_asm_flags(png_ptr);
        mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
        png_set_asm_flags(png_ptr, flags | mask);
#endif
        png_set_filter (png_ptr, 0, PNG_FILTER_NONE);
        png_infop info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_write_struct(&png_ptr,(png_infopp)0);
            fclose(fp);
            return;
        }
        if (setjmp(png_jmpbuf(png_ptr)))
        {
            png_destroy_write_struct(&png_ptr, &info_ptr);
            fclose(fp);
            return;
        }

        png_init_io(png_ptr, fp);
        //png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
        //png_set_compression_strategy(png_ptr, Z_FILTERED);
        png_set_IHDR(png_ptr, info_ptr,image.width(),image.height(),8,
                     PNG_COLOR_TYPE_RGB_ALPHA,PNG_INTERLACE_NONE,
                     PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
        png_write_info(png_ptr, info_ptr);
        for (unsigned i=0;i<image.height();i++)
        {
            png_write_row(png_ptr,(png_bytep)image.getRow(i));
        }

        png_write_end(png_ptr, info_ptr);
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fp);
    }

    template <typename T>
    void save_as_jpeg(std::string const& filename,int quality, T const& image)
    {
        FILE *fp=fopen(filename.c_str(), "wb");
        if (!fp) return;
        struct jpeg_compress_struct cinfo;
        struct jpeg_error_mgr jerr;

        int width=image.width();
        int height=image.height();

        cinfo.err = jpeg_std_error(&jerr);
        jpeg_create_compress(&cinfo);
        jpeg_stdio_dest(&cinfo, fp);
        cinfo.image_width = width;
        cinfo.image_height = height;
        cinfo.input_components = 3;
        cinfo.in_color_space = JCS_RGB;
        jpeg_set_defaults(&cinfo);
        jpeg_set_quality(&cinfo, quality,1);
        jpeg_start_compress(&cinfo, 1);
        JSAMPROW row_pointer[1];
        JSAMPLE* row=new JSAMPLE[width*3];

        while (cinfo.next_scanline < cinfo.image_height)
        {
            const unsigned* imageRow=image.getRow(cinfo.next_scanline);
            int index=0;
            for (int i=0;i<width;++i)
            {
                row[index++]=(imageRow[i])&0xff;
                row[index++]=(imageRow[i]>>8)&0xff;
                row[index++]=(imageRow[i]>>16)&0xff;
            }
            row_pointer[0] = &row[0];
            (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
        }
        delete [] row;
        jpeg_finish_compress(&cinfo);
        fclose(fp);
        jpeg_destroy_compress(&cinfo);
    }

    template void save_to_file<ImageData32>(std::string const&,
                                            std::string const& ,
                                            ImageData32 const&);

    template void save_to_file<image_view<ImageData32> > (std::string const&,
                                                          std::string const& ,
                                                          image_view<ImageData32> const&);

}
<commit_msg>use PNG_MMX_CODE_SUPPORTED instead of PNG_ASSEMBLER_CODE_SUPPORTED (mmx.patch from Dominic Hargreaves)<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: image_util.cpp 36 2005-04-05 14:32:18Z pavlenko $

// stl
#include <string>
// mapnik
#include <mapnik/graphics.hpp>
#include <mapnik/memory.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_view.hpp>
// jpeg png
extern "C"
{
#include <png.h>
#include <jpeglib.h>
}

namespace mapnik
{
    template <typename T>
    void save_to_file(std::string const& filename,
                      std::string const& type,
                      T const& image)
    {
        //all that should go into image_writer factory
        if (type=="png")
        {
            save_as_png(filename,image);
        }
        else if (type=="jpeg")
        {
            save_as_jpeg(filename,85,image);
        }
    }

    template <typename T>
    void save_as_png(std::string const& filename, T const& image)
    {
        FILE *fp=fopen(filename.c_str(), "wb");
        if (!fp) return;
        png_voidp error_ptr=0;
        png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                    error_ptr,0, 0);

        if (!png_ptr) return;

        // switch on optimization only if supported
#if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200) && defined(PNG_MMX_CODE_SUPPORTED)
        png_uint_32 mask, flags;

        flags = png_get_asm_flags(png_ptr);
        mask = png_get_asm_flagmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
        png_set_asm_flags(png_ptr, flags | mask);
#endif
        png_set_filter (png_ptr, 0, PNG_FILTER_NONE);
        png_infop info_ptr = png_create_info_struct(png_ptr);
        if (!info_ptr)
        {
            png_destroy_write_struct(&png_ptr,(png_infopp)0);
            fclose(fp);
            return;
        }
        if (setjmp(png_jmpbuf(png_ptr)))
        {
            png_destroy_write_struct(&png_ptr, &info_ptr);
            fclose(fp);
            return;
        }

        png_init_io(png_ptr, fp);
        //png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
        //png_set_compression_strategy(png_ptr, Z_FILTERED);
        png_set_IHDR(png_ptr, info_ptr,image.width(),image.height(),8,
                     PNG_COLOR_TYPE_RGB_ALPHA,PNG_INTERLACE_NONE,
                     PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
        png_write_info(png_ptr, info_ptr);
        for (unsigned i=0;i<image.height();i++)
        {
            png_write_row(png_ptr,(png_bytep)image.getRow(i));
        }

        png_write_end(png_ptr, info_ptr);
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fp);
    }

    template <typename T>
    void save_as_jpeg(std::string const& filename,int quality, T const& image)
    {
        FILE *fp=fopen(filename.c_str(), "wb");
        if (!fp) return;
        struct jpeg_compress_struct cinfo;
        struct jpeg_error_mgr jerr;

        int width=image.width();
        int height=image.height();

        cinfo.err = jpeg_std_error(&jerr);
        jpeg_create_compress(&cinfo);
        jpeg_stdio_dest(&cinfo, fp);
        cinfo.image_width = width;
        cinfo.image_height = height;
        cinfo.input_components = 3;
        cinfo.in_color_space = JCS_RGB;
        jpeg_set_defaults(&cinfo);
        jpeg_set_quality(&cinfo, quality,1);
        jpeg_start_compress(&cinfo, 1);
        JSAMPROW row_pointer[1];
        JSAMPLE* row=new JSAMPLE[width*3];

        while (cinfo.next_scanline < cinfo.image_height)
        {
            const unsigned* imageRow=image.getRow(cinfo.next_scanline);
            int index=0;
            for (int i=0;i<width;++i)
            {
                row[index++]=(imageRow[i])&0xff;
                row[index++]=(imageRow[i]>>8)&0xff;
                row[index++]=(imageRow[i]>>16)&0xff;
            }
            row_pointer[0] = &row[0];
            (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
        }
        delete [] row;
        jpeg_finish_compress(&cinfo);
        fclose(fp);
        jpeg_destroy_compress(&cinfo);
    }

    template void save_to_file<ImageData32>(std::string const&,
                                            std::string const& ,
                                            ImageData32 const&);

    template void save_to_file<image_view<ImageData32> > (std::string const&,
                                                          std::string const& ,
                                                          image_view<ImageData32> const&);

}
<|endoftext|>


<commit_before>#pragma once

#include <fstream>
#include <string>

namespace rltk {

template<class T>
inline void serialize(std::ostream &lbfile, const T &target) {
	lbfile.write(reinterpret_cast<const char *>(&target), sizeof(target));
}
template<>
inline void serialize(std::ostream &lbfile, const std::string &target) {
	std::size_t size = target.size();
	serialize<std::size_t>(lbfile, size);
	for (std::size_t i = 0; i < size; ++i)
	{
		serialize<char>(lbfile, target[i]);
	}
}

template<typename T>
inline void deserialize(std::istream &lbfile, T &target)
{
	lbfile.read(reinterpret_cast<char *>(&target), sizeof(target));
}
template<>
inline void deserialize(std::istream &lbfile, std::string &target)
{
	std::string result;
	std::size_t size = 0;
	deserialize<std::size_t>(lbfile, size);
	for (std::size_t i = 0; i < size; ++i)
	{
		char c;
		deserialize<char>(lbfile, c);
		result += c;
	}
	target = result;
}

}<commit_msg>Add specialized template for color_t serialization<commit_after>#pragma once

#include <fstream>
#include <string>
#include <rltk.hpp>

namespace rltk {

template<class T>
inline void serialize(std::ostream &lbfile, const T &target) {
	lbfile.write(reinterpret_cast<const char *>(&target), sizeof(target));
}
template<>
inline void serialize(std::ostream &lbfile, const std::string &target) {
	std::size_t size = target.size();
	serialize<std::size_t>(lbfile, size);
	for (std::size_t i = 0; i < size; ++i)
	{
		serialize<char>(lbfile, target[i]);
	}
}
template<>
inline void serialize(std::ostream &lbfile, const rltk::color_t &col) {
	serialize<uint8_t>(lbfile, col.r);
	serialize<uint8_t>(lbfile, col.g);
	serialize<uint8_t>(lbfile, col.b);
}

template<typename T>
inline void deserialize(std::istream &lbfile, T &target)
{
	lbfile.read(reinterpret_cast<char *>(&target), sizeof(target));
}
template<>
inline void deserialize(std::istream &lbfile, std::string &target)
{
	std::string result;
	std::size_t size = 0;
	deserialize<std::size_t>(lbfile, size);
	for (std::size_t i = 0; i < size; ++i)
	{
		char c;
		deserialize<char>(lbfile, c);
		result += c;
	}
	target = result;
}
template<>
inline void deserialize(std::istream &lbfile, rltk::color_t &target) {
	deserialize(lbfile, target.r);
	deserialize(lbfile, target.g);
	deserialize(lbfile, target.b);
}

}<|endoftext|>


<commit_before><commit_msg>Move "Delete current pattern" to drop-down menu<commit_after><|endoftext|>


<commit_before><commit_msg>host-condition: implement property read<commit_after><|endoftext|>