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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 notices for more information.

=========================================================================*/

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {QB_Suburb.png}
//    OUTPUTS: {TutorialsScalingPipelineOutput.png}
//  Software Guide : EndCommandLineArgs

//  Software Guide : BeginLatex
//
//  This example illustrates the use of the
// \doxygen{itk}{RescaleIntensityImageFilter} to convert
// the result for proper display.
//
// We include the required header including the header
// for the \doxygen{itk}{CannyEdgeImageFilter} and the
// \doxygen{itk}{RescaleIntensityImageFilter}.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkCannyEdgeDetectionImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"

int main(int argc, char * argv[])
{
  if (argc != 3)
    {
    std::cerr << "Usage: "
        << argv[0]
        << " <input_filename> <output_filename>"
        << std::endl;
    }
// Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We need to declare two different image types, one for the internal
  // processing and one to output the results:
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef double                   PixelType;
  typedef otb::Image<PixelType, 2> ImageType;

  typedef unsigned char                  OutputPixelType;
  typedef otb::Image<OutputPixelType, 2> OutputImageType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We declare the reader with the image template using the pixel type
  // double. It is worth noticing that this instanciation does not imply
  // anything about the type of the input image. The original image can be
  // anything, the reader will just convert the result to double.
  //
  //  The writer is templated with the unsigned char image to be able to save
  // the result on one byte images (like png for example).
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::ImageFileReader<ImageType> ReaderType;
  ReaderType::Pointer reader = ReaderType::New();

  typedef otb::ImageFileWriter<OutputImageType> WriterType;
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName(argv[1]);
  writer->SetFileName(argv[2]);
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // Now we are declaring the edge detection filter which is going to work with
  // double input and output.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::CannyEdgeDetectionImageFilter
  <ImageType, ImageType> FilterType;
  FilterType::Pointer filter = FilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // Here comes the interesting part: we declare the
  // \doxygen{itk}{RescaleIntensityImageFilter}. The input
  // image type is the output type of the edge detection
  // filter. The output type is the same as the input type
  // of the writer.
  //
  // Desired minimum and maximum values for the output are
  // specified by the methods \code{SetOutputMinimum()} and
  // \code{SetOutputMaximum()}.
  //
  // This filter will actually rescale all the pixels of
  // the image but also cast the type of these pixels.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::RescaleIntensityImageFilter
  <ImageType, OutputImageType> RescalerType;
  RescalerType::Pointer rescaler = RescalerType::New();

  rescaler->SetOutputMinimum(0);
  rescaler->SetOutputMaximum(255);
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // Let's plug the pipeline:
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  filter->SetInput(reader->GetOutput());
  rescaler->SetInput(filter->GetOutput());
  writer->SetInput(rescaler->GetOutput());
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // And finally, we trigger the pipeline execution calling the Update()
  // method on the writer
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  writer->Update();

  return EXIT_SUCCESS;
}
// Software Guide : EndCodeSnippet
<commit_msg>Fix typo in ScalingPipeline example<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 notices for more information.

=========================================================================*/

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {QB_Suburb.png}
//    OUTPUTS: {TutorialsScalingPipelineOutput.png}
//  Software Guide : EndCommandLineArgs

//  Software Guide : BeginLatex
//
//  This example illustrates the use of the
// \doxygen{itk}{RescaleIntensityImageFilter} to convert
// the result for proper display.
//
// We include the required header including the header
// for the \doxygen{itk}{CannyEdgeDetectionImageFilter} and the
// \doxygen{itk}{RescaleIntensityImageFilter}.
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkCannyEdgeDetectionImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"

int main(int argc, char * argv[])
{
  if (argc != 3)
    {
    std::cerr << "Usage: "
        << argv[0]
        << " <input_filename> <output_filename>"
        << std::endl;
    }
// Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We need to declare two different image types, one for the internal
  // processing and one to output the results:
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef double                   PixelType;
  typedef otb::Image<PixelType, 2> ImageType;

  typedef unsigned char                  OutputPixelType;
  typedef otb::Image<OutputPixelType, 2> OutputImageType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We declare the reader with the image template using the pixel type
  // double. It is worth noticing that this instanciation does not imply
  // anything about the type of the input image. The original image can be
  // anything, the reader will just convert the result to double.
  //
  //  The writer is templated with the unsigned char image to be able to save
  // the result on one byte images (like png for example).
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::ImageFileReader<ImageType> ReaderType;
  ReaderType::Pointer reader = ReaderType::New();

  typedef otb::ImageFileWriter<OutputImageType> WriterType;
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName(argv[1]);
  writer->SetFileName(argv[2]);
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // Now we are declaring the edge detection filter which is going to work with
  // double input and output.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::CannyEdgeDetectionImageFilter
  <ImageType, ImageType> FilterType;
  FilterType::Pointer filter = FilterType::New();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // Here comes the interesting part: we declare the
  // \doxygen{itk}{RescaleIntensityImageFilter}. The input
  // image type is the output type of the edge detection
  // filter. The output type is the same as the input type
  // of the writer.
  //
  // Desired minimum and maximum values for the output are
  // specified by the methods \code{SetOutputMinimum()} and
  // \code{SetOutputMaximum()}.
  //
  // This filter will actually rescale all the pixels of
  // the image but also cast the type of these pixels.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::RescaleIntensityImageFilter
  <ImageType, OutputImageType> RescalerType;
  RescalerType::Pointer rescaler = RescalerType::New();

  rescaler->SetOutputMinimum(0);
  rescaler->SetOutputMaximum(255);
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // Let's plug the pipeline:
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  filter->SetInput(reader->GetOutput());
  rescaler->SetInput(filter->GetOutput());
  writer->SetInput(rescaler->GetOutput());
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  // And finally, we trigger the pipeline execution calling the Update()
  // method on the writer
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  writer->Update();

  return EXIT_SUCCESS;
}
// Software Guide : EndCodeSnippet
<|endoftext|>


<commit_before>/*
Copyright (c) 2017, Vadim Malyshev, lboss75@gmail.com
All rights reserved
*/

#include "stdafx.h"
#include "root_user_transaction.h"
#include "binary_serialize.h"

vds::root_user_transaction::root_user_transaction(
    const guid & id,
    const certificate & user_cert,
    const std::string & user_name,
    const const_data_buffer & user_private_key,
    const const_data_buffer & password_hash)
    : id_(id),
      user_cert_(user_cert),
      user_name_(user_name),
      user_private_key_(user_private_key),
      password_hash_(password_hash)
{
}

vds::root_user_transaction::root_user_transaction(struct binary_deserializer &b) {
  const_data_buffer cert_der;
  b >> this->id_ >> cert_der >> this->user_private_key_ >> this->password_hash_;
  this->user_cert_ = certificate::parse_der(cert_der);
}

void vds::root_user_transaction::serialize(vds::binary_serializer &b) const {
  b << this->id_ << this->user_cert_.der() << this->user_private_key_ << this->password_hash_;
}
<commit_msg>cryptochannel design<commit_after>/*
Copyright (c) 2017, Vadim Malyshev, lboss75@gmail.com
All rights reserved
*/

#include "stdafx.h"
#include "root_user_transaction.h"
#include "binary_serialize.h"

vds::root_user_transaction::root_user_transaction(
    const guid & id,
    const certificate & user_cert,
    const std::string & user_name,
    const const_data_buffer & user_private_key,
    const const_data_buffer & password_hash)
    : id_(id),
      user_cert_(user_cert),
      user_name_(user_name),
      user_private_key_(user_private_key),
      password_hash_(password_hash)
{
}

vds::root_user_transaction::root_user_transaction(struct binary_deserializer &b) {
  const_data_buffer cert_der;
  b >> this->id_ >> cert_der >> this->user_name_ >> this->user_private_key_ >> this->password_hash_;
  this->user_cert_ = certificate::parse_der(cert_der);
}

void vds::root_user_transaction::serialize(vds::binary_serializer &b) const {
  b << this->id_ << this->user_cert_.der() << this->user_name_ << this->user_private_key_ << this->password_hash_;
}
<|endoftext|>


<commit_before>#pragma once

#include <utility>
#include <memory>
#include <cassert>
#include <mutex>

#include "Stack.hpp"

namespace AO
{
	namespace Allocator
	{
		inline namespace Version_1
		{
			// Methods
			template <std::size_t Capacity>
			template <typename Type, typename... Args>
			inline Type *Stack<Capacity>::create(Args &&...args)
			{
				return new (allocate(sizeof(Type), alignof(Type))) Type(std::forward<Args>(args)...);
			}

			template <std::size_t Capacity>
			template <typename Type>
			inline void Stack<Capacity>::destroy(Type const *instance)
			{
				if (instance)
				{
					instance->~Type();
					deallocate(static_cast<void const *>(instance), sizeof(Type));
				}
			}

			// Inherited Methods
			template <std::size_t Capacity>
			inline bool Stack<Capacity>::empty(void) const noexcept
			{
				return size() == 0;
			}

			template <std::size_t Capacity>
			inline std::size_t Stack<Capacity>::size(void) const noexcept
			{
				return static_cast<std::uint8_t *>(bufferPointer) - buffer;
			}

			template <std::size_t Capacity>
			inline std::size_t Stack<Capacity>::capacity(void) const noexcept
			{
				return Capacity;
			}

			template <std::size_t Capacity>
			inline void Stack<Capacity>::reset(void) noexcept
			{
				bufferPointer = static_cast<void *>(buffer);
			}

			template <std::size_t Capacity>
			inline void *Stack<Capacity>::allocate(std::size_t numberOfBytes, std::size_t alignment)
			{
				std::size_t space = capacity() - size();
				if (std::align(alignment, numberOfBytes, bufferPointer, space))
				{
					void *allocatedMemory = bufferPointer;
					bufferPointer = static_cast<void *>(static_cast<std::uint8_t *>(bufferPointer) + numberOfBytes);
					return allocatedMemory;
				}
				else
				{
					void *allocatedMemory = std::malloc(numberOfBytes + alignment + sizeof(void *));
					void **pointerToAlignedMemory = reinterpret_cast<void **>(reinterpret_cast<std::uintptr_t>(static_cast<std::uint8_t *>(allocatedMemory) + alignment + sizeof(void *)) & ~(alignment - 1));
					pointerToAlignedMemory[-1] = allocatedMemory;
					return static_cast<void *>(pointerToAlignedMemory);
				}
			}

			template <std::size_t Capacity>
			inline void Stack<Capacity>::deallocate(void const *memory, std::size_t numberOfBytes)
			{
				std::uint8_t const *endOfMemory = static_cast<std::uint8_t const *>(memory) + numberOfBytes;
				if (buffer <= memory && endOfMemory <= buffer + Capacity)
				{
					assert(endOfMemory == bufferPointer && "Invalid memory");
					if (endOfMemory == bufferPointer)
					{
						bufferPointer = const_cast<void *>(memory);
					}
				}
				else
				{
					std::free(static_cast<void **>(const_cast<void *>(memory))[-1]);
				}
			}
		}
	}
}<commit_msg>Update Stack.inl<commit_after>#pragma once

#include <utility>
#include <cassert>
#include <mutex>

#include "Stack.hpp"

namespace AO
{
	namespace Allocator
	{
		inline namespace Version_1
		{
			// Methods
			template <std::size_t Capacity>
			template <typename Type, typename... Args>
			inline Type *Stack<Capacity>::create(Args &&...args)
			{
				return new (allocate(sizeof(Type), alignof(Type))) Type(std::forward<Args>(args)...);
			}

			template <std::size_t Capacity>
			template <typename Type>
			inline void Stack<Capacity>::destroy(Type const *instance)
			{
				if (instance)
				{
					instance->~Type();
					deallocate(static_cast<void const *>(instance), sizeof(Type));
				}
			}

			// Inherited Methods
			template <std::size_t Capacity>
			inline bool Stack<Capacity>::empty(void) const noexcept
			{
				return size() == 0;
			}

			template <std::size_t Capacity>
			inline std::size_t Stack<Capacity>::size(void) const noexcept
			{
				return static_cast<std::uint8_t *>(bufferPointer) - buffer;
			}

			template <std::size_t Capacity>
			inline std::size_t Stack<Capacity>::capacity(void) const noexcept
			{
				return Capacity;
			}

			template <std::size_t Capacity>
			inline void Stack<Capacity>::reset(void) noexcept
			{
				bufferPointer = static_cast<void *>(buffer);
			}

			template <std::size_t Capacity>
			inline void *Stack<Capacity>::allocate(std::size_t numberOfBytes, std::size_t alignment)
			{
				std::size_t space = capacity() - size();
				if (std::align(alignment, numberOfBytes, bufferPointer, space))
				{
					void *allocatedMemory = bufferPointer;
					bufferPointer = static_cast<void *>(static_cast<std::uint8_t *>(bufferPointer) + numberOfBytes);
					return allocatedMemory;
				}
				else
				{
					void *allocatedMemory = std::malloc(numberOfBytes + alignment + sizeof(void *));
					void **pointerToAlignedMemory = reinterpret_cast<void **>(reinterpret_cast<std::uintptr_t>(static_cast<std::uint8_t *>(allocatedMemory) + alignment + sizeof(void *)) & ~(alignment - 1));
					pointerToAlignedMemory[-1] = allocatedMemory;
					return static_cast<void *>(pointerToAlignedMemory);
				}
			}

			template <std::size_t Capacity>
			inline void Stack<Capacity>::deallocate(void const *memory, std::size_t numberOfBytes)
			{
				std::uint8_t const *endOfMemory = static_cast<std::uint8_t const *>(memory) + numberOfBytes;
				if (buffer <= memory && endOfMemory <= buffer + Capacity)
				{
					assert(endOfMemory == bufferPointer && "Invalid memory");
					if (endOfMemory == bufferPointer)
					{
						bufferPointer = const_cast<void *>(memory);
					}
				}
				else
				{
					std::free(static_cast<void **>(const_cast<void *>(memory))[-1]);
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////
//
// File:        ThreadGroup.C
// Description: This file contains the ThreadGroup class methods
// Rel:         01.00
// Created:     May, 2001
// Author:      Juan A. Caceres Exposito      ( caceres@tid.es   )
//
// Revised:
//
// (C) Copyright 2009 Telefonica Investigacion y Desarrollo
//     S.A.Unipersonal (Telefonica I+D)
//
// This file is part of Morfeo CORBA Platform.
//
// Morfeo CORBA Platform is free software: you can redistribute it and/or
// modify it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Morfeo CORBA Platform 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Morfeo CORBA Platform. If not, see
//
//   http://www.gnu.org/licenses
//
// Info about members and contributors of the MORFEO project
// is available at
//
//   http://morfeo-project.org
//
///////////////////////////////////////////////////////////////////////////

#include "TIDThr.h"
#include <pthread.h>

namespace TIDThr {

ThreadGroup::ThreadGroup(const char* name)
    throw(IllegalThreadStateException,
          IllegalArgumentException)
    : m_group_name(name),
      m_group_id(0),
      m_destroyed(false),
      m_group_father(NULL)
{
    pthread_attr_init(&m_group_attributes);
    pthread_attr_setscope(&m_group_attributes,PTHREAD_SCOPE_PROCESS);
    pthread_attr_setdetachstate(&m_group_attributes,PTHREAD_CREATE_DETACHED);

    m_state_mutex = new Mutex();
}

ThreadGroup::ThreadGroup(ThreadGroup *father,
                         const char* name,
                         const pthread_attr_t* attr)
      throw(IllegalThreadStateException,
            IllegalArgumentException)
      : m_group_name(name),
        m_group_id(0),
        m_destroyed(false),
        m_group_father(father)
{
    if(father != NULL){
        ThreadGroupHandle this_group(this);
        m_destroyed = father->m_destroyed;
        father->addGroup(this_group);
    }

    pthread_attr_init(&m_group_attributes);

    if (attr != NULL) {
        attrCopy(attr, &m_group_attributes);
    } else if(father != NULL) {
        attrCopy(father->getAttributes(), &m_group_attributes);
    }

    m_state_mutex = new Mutex();
}

ThreadGroup::~ThreadGroup()
    throw (SystemException)
{
    pthread_attr_destroy(&m_group_attributes);

    if(!m_group_father.is_null()) {
        m_group_father->removeGroup(getId());
    }
}

void ThreadGroup::destroy()
    throw (IllegalThreadStateException)
{
    Synchronized synchro(*m_state_mutex);

    if(m_destroyed) {
        throw IllegalThreadStateException("ThreadGroup Already destroyed");
    }

    if((activeCount() > 0) || (activeGroupCount() > 0)) {
        throw IllegalThreadStateException("ThreadGroup not empty");
    }

    m_destroyed = true;
}

void
ThreadGroup::addGroup(const ThreadGroupHandle& child)
    throw (IllegalThreadStateException)
{
    Synchronized syncrho(*m_state_mutex);

    if(m_destroyed) {
        throw IllegalThreadStateException("Destroyed ThreadGroup");
    }

    child->setId(m_last_child_id);

    m_groups_table.insert(ThreadGroupTable::value_type(m_last_child_id,child));

    ++m_last_child_id;
}

void
ThreadGroup::removeGroup(const ThreadGroupId& child_id)
{
    Synchronized syncrho(*m_state_mutex);
    m_groups_table.erase(child_id);
}

void ThreadGroup::addThread(const ThreadHandle& child)
    throw (IllegalThreadStateException)
{
    Synchronized synchro(*m_state_mutex);

    if(m_destroyed) {
        throw IllegalThreadStateException("Destroyed ThreadGroup");
    }

    m_threads_table.insert(ThreadTable::value_type(child->getId(),child));
}

void
ThreadGroup::removeThread(const ThreadId& child_id)
{
    Synchronized synchro(*m_state_mutex);
    m_threads_table.erase(child_id);
}

size_t
ThreadGroup::enumerate(ThreadHandle* list,
                       size_t list_size,
                       bool recurse) const
{
    Synchronized synchro(*m_state_mutex);

    // current group list

    ThreadTable::const_iterator thread_iter = m_threads_table.begin();

    size_t count = 0;

    size_t threads_table_size = m_threads_table.size();

    while((count < list_size) && (count < threads_table_size)) {
        list[count++] = (*thread_iter).second;
        thread_iter++;
    }

    // child groups list

    if((count > list_size) || (!recurse)) {
        return count;
    }

    ThreadGroupTable::const_iterator group_iter = m_groups_table.begin();

    while((count < list_size) && (group_iter != m_groups_table.end())) {
        count += ((*group_iter).second)->enumerate(&(list[count]),
                                                   list_size - count,
                                                   recurse);
        group_iter++;
    }

    return count;
}

void
ThreadGroup::list() const
{
    Synchronized synchro(*m_state_mutex);

    cout << *this << endl;

    // groups

    ThreadGroupTable::const_iterator group_iter = m_groups_table.begin();

    const ThreadGroup* group  = NULL;

    while(group_iter != m_groups_table.end()) {
        group = (const ThreadGroup *) ((*group_iter).second);
        if(group){
            cout << '\t'<< *group <<  endl;
        }
        group_iter++;
    }

    // threads

    ThreadTable::const_iterator thread_iter = m_threads_table.begin();

    const Thread* thread = NULL;

    while(thread_iter != m_threads_table.end()) {
        thread = (*thread_iter).second;
        if(thread){
            cout << '\t' << *thread << endl;
        }
        thread_iter++;
    }

}

size_t
ThreadGroup::enumerate(ThreadGroupHandle* list,
                       size_t list_size,
                       bool recurse) const
{
    Synchronized synchro(*m_state_mutex);

    // current group list

    ThreadGroupTable::const_iterator groups_iter = m_groups_table.begin();

    size_t count = 0;

    size_t groups_table_size = m_groups_table.size();

    while((count < list_size) && (count < groups_table_size)) {
        list[count++] = (*groups_iter).second;
        groups_iter++;
    }

    // child groups list

    if((count >= list_size) || (!recurse)) {
        return count;
    }

    ThreadGroupTable::const_iterator child_groups_iter = m_groups_table.begin();

    while((count < list_size) && (child_groups_iter != m_groups_table.end())) {
        count += ((*child_groups_iter).second)->enumerate(&(list[count]),
                                                          list_size - count,
                                                          recurse);
        child_groups_iter++;
    }

    return count;
}

void
ThreadGroup::attrCopy(const pthread_attr_t* from, pthread_attr_t* to)
    throw (IllegalArgumentException)
{
    if((from == NULL) || (to == NULL)) {
        throw IllegalArgumentException("Null pthread_attr_t pointer");
    }

    int ret = 0;

    int deatached;
    ret= pthread_attr_getdetachstate(from,&deatached);
    if(ret) {
        throw IllegalArgumentException("Null from pthread_attr_t pointer",ret);
    }
    ret= pthread_attr_setdetachstate(to,deatached);
    if(ret) {
        throw IllegalArgumentException("Null to pthread_attr_t pointer",ret);
    }

    size_t size;

// #if !defined(__linux__)
#if !defined(__CYGWIN__)
    pthread_attr_getguardsize(from, &size);
    pthread_attr_setguardsize(to, size);
#endif
// #endif
    pthread_attr_getstacksize(from, &size);
    pthread_attr_setstacksize(to, size);

    int scope;
    pthread_attr_getscope(from, &scope);
    pthread_attr_setscope(to, scope);

    int policy;
    pthread_attr_getschedpolicy(from, &policy);
    pthread_attr_setschedpolicy(to, policy);

    pthread_attr_getinheritsched(from, &policy);
    pthread_attr_setinheritsched(to, policy);

    sched_param param;

    pthread_attr_getschedparam(from, &param);
    pthread_attr_setschedparam(to, &param);
}

} // namespace TIDThr

ostream& operator<<(ostream& os, const TIDThr::ThreadGroup& group)
{
  os << "ThreadGroup " << group.getId() << " \"" << group.getName() << "\"";
  return os;
}
<commit_msg>Android NDK, MIPS and minimun CORBA support added<commit_after>///////////////////////////////////////////////////////////////////////////
//
// File:        ThreadGroup.C
// Description: This file contains the ThreadGroup class methods
// Rel:         01.00
// Created:     May, 2001
// Author:      Juan A. Caceres Exposito      ( caceres@tid.es   )
//
// Revised:
//
// (C) Copyright 2009 Telefonica Investigacion y Desarrollo
//     S.A.Unipersonal (Telefonica I+D)
//
// This file is part of Morfeo CORBA Platform.
//
// Morfeo CORBA Platform is free software: you can redistribute it and/or
// modify it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Morfeo CORBA Platform 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Morfeo CORBA Platform. If not, see
//
//   http://www.gnu.org/licenses
//
// Info about members and contributors of the MORFEO project
// is available at
//
//   http://morfeo-project.org
//
///////////////////////////////////////////////////////////////////////////

#include "TIDThr.h"
#include <pthread.h>

namespace TIDThr {

ThreadGroup::ThreadGroup(const char* name)
    throw(IllegalThreadStateException,
          IllegalArgumentException)
    : m_group_name(name),
      m_group_id(0),
      m_destroyed(false),
      m_group_father(NULL)
{
    pthread_attr_init(&m_group_attributes);
    pthread_attr_setscope(&m_group_attributes,PTHREAD_SCOPE_PROCESS);
    pthread_attr_setdetachstate(&m_group_attributes,PTHREAD_CREATE_DETACHED);

    m_state_mutex = new Mutex();
}

ThreadGroup::ThreadGroup(ThreadGroup *father,
                         const char* name,
                         const pthread_attr_t* attr)
      throw(IllegalThreadStateException,
            IllegalArgumentException)
      : m_group_name(name),
        m_group_id(0),
        m_destroyed(false),
        m_group_father(father)
{
    if(father != NULL){
        ThreadGroupHandle this_group(this);
        m_destroyed = father->m_destroyed;
        father->addGroup(this_group);
    }

    pthread_attr_init(&m_group_attributes);

    if (attr != NULL) {
        attrCopy(attr, &m_group_attributes);
    } else if(father != NULL) {
        attrCopy(father->getAttributes(), &m_group_attributes);
    }

    m_state_mutex = new Mutex();
}

ThreadGroup::~ThreadGroup()
    throw (SystemException)
{
    pthread_attr_destroy(&m_group_attributes);

    if(!m_group_father.is_null()) {
        m_group_father->removeGroup(getId());
    }
}

void ThreadGroup::destroy()
    throw (IllegalThreadStateException)
{
    Synchronized synchro(*m_state_mutex);

    if(m_destroyed) {
        throw IllegalThreadStateException("ThreadGroup Already destroyed");
    }

    if((activeCount() > 0) || (activeGroupCount() > 0)) {
        throw IllegalThreadStateException("ThreadGroup not empty");
    }

    m_destroyed = true;
}

void
ThreadGroup::addGroup(const ThreadGroupHandle& child)
    throw (IllegalThreadStateException)
{
    Synchronized syncrho(*m_state_mutex);

    if(m_destroyed) {
        throw IllegalThreadStateException("Destroyed ThreadGroup");
    }

    child->setId(m_last_child_id);

    m_groups_table.insert(ThreadGroupTable::value_type(m_last_child_id,child));

    ++m_last_child_id;
}

void
ThreadGroup::removeGroup(const ThreadGroupId& child_id)
{
    Synchronized syncrho(*m_state_mutex);
    m_groups_table.erase(child_id);
}

void ThreadGroup::addThread(const ThreadHandle& child)
    throw (IllegalThreadStateException)
{
    Synchronized synchro(*m_state_mutex);

    if(m_destroyed) {
        throw IllegalThreadStateException("Destroyed ThreadGroup");
    }

    m_threads_table.insert(ThreadTable::value_type(child->getId(),child));
}

void
ThreadGroup::removeThread(const ThreadId& child_id)
{
    Synchronized synchro(*m_state_mutex);
    m_threads_table.erase(child_id);
}

size_t
ThreadGroup::enumerate(ThreadHandle* list,
                       size_t list_size,
                       bool recurse) const
{
    Synchronized synchro(*m_state_mutex);

    // current group list

    ThreadTable::const_iterator thread_iter = m_threads_table.begin();

    size_t count = 0;

    size_t threads_table_size = m_threads_table.size();

    while((count < list_size) && (count < threads_table_size)) {
        list[count++] = (*thread_iter).second;
        thread_iter++;
    }

    // child groups list

    if((count > list_size) || (!recurse)) {
        return count;
    }

    ThreadGroupTable::const_iterator group_iter = m_groups_table.begin();

    while((count < list_size) && (group_iter != m_groups_table.end())) {
        count += ((*group_iter).second)->enumerate(&(list[count]),
                                                   list_size - count,
                                                   recurse);
        group_iter++;
    }

    return count;
}

void
ThreadGroup::list() const
{
    Synchronized synchro(*m_state_mutex);

    cout << *this << endl;

    // groups

    ThreadGroupTable::const_iterator group_iter = m_groups_table.begin();

    const ThreadGroup* group  = NULL;

    while(group_iter != m_groups_table.end()) {
        group = (const ThreadGroup *) ((*group_iter).second);
        if(group){
            cout << '\t'<< *group <<  endl;
        }
        group_iter++;
    }

    // threads

    ThreadTable::const_iterator thread_iter = m_threads_table.begin();

    const Thread* thread = NULL;

    while(thread_iter != m_threads_table.end()) {
        thread = (*thread_iter).second;
        if(thread){
            cout << '\t' << *thread << endl;
        }
        thread_iter++;
    }

}

size_t
ThreadGroup::enumerate(ThreadGroupHandle* list,
                       size_t list_size,
                       bool recurse) const
{
    Synchronized synchro(*m_state_mutex);

    // current group list

    ThreadGroupTable::const_iterator groups_iter = m_groups_table.begin();

    size_t count = 0;

    size_t groups_table_size = m_groups_table.size();

    while((count < list_size) && (count < groups_table_size)) {
        list[count++] = (*groups_iter).second;
        groups_iter++;
    }

    // child groups list

    if((count >= list_size) || (!recurse)) {
        return count;
    }

    ThreadGroupTable::const_iterator child_groups_iter = m_groups_table.begin();

    while((count < list_size) && (child_groups_iter != m_groups_table.end())) {
        count += ((*child_groups_iter).second)->enumerate(&(list[count]),
                                                          list_size - count,
                                                          recurse);
        child_groups_iter++;
    }

    return count;
}

void
ThreadGroup::attrCopy(const pthread_attr_t* from, pthread_attr_t* to)
    throw (IllegalArgumentException)
{
    if((from == NULL) || (to == NULL)) {
        throw IllegalArgumentException("Null pthread_attr_t pointer");
    }

    int ret = 0;

    int deatached;
    ret= pthread_attr_getdetachstate(from,&deatached);
    if(ret) {
        throw IllegalArgumentException("Null from pthread_attr_t pointer",ret);
    }
    ret= pthread_attr_setdetachstate(to,deatached);
    if(ret) {
        throw IllegalArgumentException("Null to pthread_attr_t pointer",ret);
    }

    size_t size;

// #if !defined(__linux__)
#if !defined(__CYGWIN__)
    pthread_attr_getguardsize(from, &size);
    pthread_attr_setguardsize(to, size);
#endif
// #endif
    pthread_attr_getstacksize(from, &size);
    pthread_attr_setstacksize(to, size);

#if !defined(__ANDROID__)
    int scope;
    pthread_attr_getscope(from, &scope);
    pthread_attr_setscope(to, scope);
#endif

#if !defined(__ANDROID__)
    int policy;
    pthread_attr_getschedpolicy(from, &policy);
    pthread_attr_setschedpolicy(to, policy);

    pthread_attr_getinheritsched(from, &policy);
    pthread_attr_setinheritsched(to, policy);
#endif

    sched_param param;

    pthread_attr_getschedparam(from, &param);
    pthread_attr_setschedparam(to, &param);
}

} // namespace TIDThr

ostream& operator<<(ostream& os, const TIDThr::ThreadGroup& group)
{
  os << "ThreadGroup " << group.getId() << " \"" << group.getName() << "\"";
  return os;
}
<|endoftext|>


<commit_before>/*
 * HLSLKeywords.cpp
 *
 * This file is part of the XShaderCompiler project (Copyright (c) 2014-2016 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include "HLSLKeywords.h"

namespace Xsc
{

static KeywordMapType GenerateKeywordMap()
{
    using Ty = Token::Types;

    return
    {
        { "true",                    Ty::BoolLiteral     },
        { "false",                   Ty::BoolLiteral     },

        { "void",                    Ty::Void            },

        { "bool",                    Ty::ScalarType      },
        { "bool1",                   Ty::ScalarType      },
        { "bool1x1",                 Ty::ScalarType      },
        { "int",                     Ty::ScalarType      },
        { "int1",                    Ty::ScalarType      },
        { "int1x1",                  Ty::ScalarType      },
        { "uint",                    Ty::ScalarType      },
        { "uint1",                   Ty::ScalarType      },
        { "uint1x1",                 Ty::ScalarType      },
        { "half",                    Ty::ScalarType      },
        { "half1",                   Ty::ScalarType      },
        { "half1x1",                 Ty::ScalarType      },
        { "float",                   Ty::ScalarType      },
        { "float1",                  Ty::ScalarType      },
        { "float1x1",                Ty::ScalarType      },
        { "double",                  Ty::ScalarType      },
        { "double1",                 Ty::ScalarType      },
        { "double1x1",               Ty::ScalarType      },

        { "bool2",                   Ty::VectorType      },
        { "bool3",                   Ty::VectorType      },
        { "bool4",                   Ty::VectorType      },
        { "int2",                    Ty::VectorType      },
        { "int3",                    Ty::VectorType      },
        { "int4",                    Ty::VectorType      },
        { "uint2",                   Ty::VectorType      },
        { "uint3",                   Ty::VectorType      },
        { "uint4",                   Ty::VectorType      },
        { "half2",                   Ty::VectorType      },
        { "half3",                   Ty::VectorType      },
        { "half4",                   Ty::VectorType      },
        { "float2",                  Ty::VectorType      },
        { "float3",                  Ty::VectorType      },
        { "float4",                  Ty::VectorType      },
        { "double2",                 Ty::VectorType      },
        { "double3",                 Ty::VectorType      },
        { "double4",                 Ty::VectorType      },

        { "bool2x2",                 Ty::MatrixType      },
        { "bool2x3",                 Ty::MatrixType      },
        { "bool2x4",                 Ty::MatrixType      },
        { "bool3x2",                 Ty::MatrixType      },
        { "bool3x3",                 Ty::MatrixType      },
        { "bool3x4",                 Ty::MatrixType      },
        { "bool4x2",                 Ty::MatrixType      },
        { "bool4x3",                 Ty::MatrixType      },
        { "bool4x4",                 Ty::MatrixType      },
        { "int2x2",                  Ty::MatrixType      },
        { "int2x3",                  Ty::MatrixType      },
        { "int2x4",                  Ty::MatrixType      },
        { "int3x2",                  Ty::MatrixType      },
        { "int3x3",                  Ty::MatrixType      },
        { "int3x4",                  Ty::MatrixType      },
        { "int4x2",                  Ty::MatrixType      },
        { "int4x3",                  Ty::MatrixType      },
        { "int4x4",                  Ty::MatrixType      },
        { "uint2x2",                 Ty::MatrixType      },
        { "uint2x3",                 Ty::MatrixType      },
        { "uint2x4",                 Ty::MatrixType      },
        { "uint3x2",                 Ty::MatrixType      },
        { "uint3x3",                 Ty::MatrixType      },
        { "uint3x4",                 Ty::MatrixType      },
        { "uint4x2",                 Ty::MatrixType      },
        { "uint4x3",                 Ty::MatrixType      },
        { "uint4x4",                 Ty::MatrixType      },
        { "half2x2",                 Ty::MatrixType      },
        { "half2x3",                 Ty::MatrixType      },
        { "half2x4",                 Ty::MatrixType      },
        { "half3x2",                 Ty::MatrixType      },
        { "half3x3",                 Ty::MatrixType      },
        { "half3x4",                 Ty::MatrixType      },
        { "half4x2",                 Ty::MatrixType      },
        { "half4x3",                 Ty::MatrixType      },
        { "half4x4",                 Ty::MatrixType      },
        { "float2x2",                Ty::MatrixType      },
        { "float2x3",                Ty::MatrixType      },
        { "float2x4",                Ty::MatrixType      },
        { "float3x2",                Ty::MatrixType      },
        { "float3x3",                Ty::MatrixType      },
        { "float3x4",                Ty::MatrixType      },
        { "float4x2",                Ty::MatrixType      },
        { "float4x3",                Ty::MatrixType      },
        { "float4x4",                Ty::MatrixType      },
        { "double2x2",               Ty::MatrixType      },
        { "double2x3",               Ty::MatrixType      },
        { "double2x4",               Ty::MatrixType      },
        { "double3x2",               Ty::MatrixType      },
        { "double3x3",               Ty::MatrixType      },
        { "double3x4",               Ty::MatrixType      },
        { "double4x2",               Ty::MatrixType      },
        { "double4x3",               Ty::MatrixType      },
        { "double4x4",               Ty::MatrixType      },

        { "do",                      Ty::Do              },
        { "while",                   Ty::While           },
        { "for",                     Ty::For             },

        { "if",                      Ty::If              },
        { "else",                    Ty::Else            },

        { "switch",                  Ty::Switch          },
        { "case",                    Ty::Case            },
        { "default",                 Ty::Default         },

        { "struct",                  Ty::Struct          },
        { "register",                Ty::Register        },
        { "packoffset",              Ty::PackOffset      },

        { "sampler",                 Ty::Sampler         },
        { "sampler1D",               Ty::Sampler         },
        { "sampler2D",               Ty::Sampler         },
        { "sampler3D",               Ty::Sampler         },
        { "samplerCUBE",             Ty::Sampler         },
        { "sampler_state",           Ty::Sampler         },
        { "SamplerState",            Ty::Sampler         },

        { "Texture1D",               Ty::Texture         },
        { "Texture1DArray",          Ty::Texture         },
        { "Texture2D",               Ty::Texture         },
        { "Texture2DArray",          Ty::Texture         },
        { "Texture3D",               Ty::Texture         },
        { "TextureCube",             Ty::Texture         },
        { "TextureCubeArray",        Ty::Texture         },
        { "Texture2DMS",             Ty::Texture         },
        { "Texture2DMSArray",        Ty::Texture         },
        { "RWTexture1D",             Ty::Texture         },
        { "RWTexture1DArray",        Ty::Texture         },
        { "RWTexture2D",             Ty::Texture         },
        { "RWTexture2DArray",        Ty::Texture         },
        { "RWTexture3D",             Ty::Texture         },

        { "AppendStructuredBuffer",  Ty::StorageBuffer   },
        { "Buffer",                  Ty::StorageBuffer   },
        { "ByteAddressBuffer",       Ty::StorageBuffer   },
        { "ConsumeStructuredBuffer", Ty::StorageBuffer   },
        { "StructuredBuffer",        Ty::StorageBuffer   },
        { "RWBuffer",                Ty::StorageBuffer   },
        { "RWByteAddressBuffer",     Ty::StorageBuffer   },
        { "RWStructuredBuffer",      Ty::StorageBuffer   },

        { "cbuffer",                 Ty::UniformBuffer   },
        { "tbuffer",                 Ty::UniformBuffer   },

        { "break",                   Ty::CtrlTransfer    },
        { "continue",                Ty::CtrlTransfer    },
        { "discard",                 Ty::CtrlTransfer    },

        { "return",                  Ty::Return          },

        { "uniform",                 Ty::InputModifier   },
        { "in",                      Ty::InputModifier   },
        { "out",                     Ty::InputModifier   },
        { "inout",                   Ty::InputModifier   },

        { "extern",                  Ty::StorageModifier },
        { "nointerpolation",         Ty::StorageModifier },
        { "precise",                 Ty::StorageModifier },
        { "shared",                  Ty::StorageModifier },
        { "groupshared",             Ty::StorageModifier },
        { "static",                  Ty::StorageModifier },
        //{ "uniform",                 Ty::StorageModifier }, // Already used as "InputModifier"
        { "volatile",                Ty::StorageModifier },
        { "linear",                  Ty::StorageModifier },
        { "centroid",                Ty::StorageModifier },
        { "noperspective",           Ty::StorageModifier },
        { "sample",                  Ty::StorageModifier },

        { "const",                   Ty::TypeModifier    },
        { "row_major",               Ty::TypeModifier    },
        { "column_major",            Ty::TypeModifier    },
    };
}

static KeywordMapType keywordMap = GenerateKeywordMap();

const KeywordMapType& HLSLKeywords()
{
    return keywordMap;
}

} // /namespace Xsc

// ================================================================================<commit_msg>Added "SamplerComparisonState" to HLSL keywords.<commit_after>/*
 * HLSLKeywords.cpp
 *
 * This file is part of the XShaderCompiler project (Copyright (c) 2014-2016 by Lukas Hermanns)
 * See "LICENSE.txt" for license information.
 */

#include "HLSLKeywords.h"

namespace Xsc
{

static KeywordMapType GenerateKeywordMap()
{
    using Ty = Token::Types;

    return
    {
        { "true",                    Ty::BoolLiteral     },
        { "false",                   Ty::BoolLiteral     },

        { "void",                    Ty::Void            },

        { "bool",                    Ty::ScalarType      },
        { "bool1",                   Ty::ScalarType      },
        { "bool1x1",                 Ty::ScalarType      },
        { "int",                     Ty::ScalarType      },
        { "int1",                    Ty::ScalarType      },
        { "int1x1",                  Ty::ScalarType      },
        { "uint",                    Ty::ScalarType      },
        { "uint1",                   Ty::ScalarType      },
        { "uint1x1",                 Ty::ScalarType      },
        { "half",                    Ty::ScalarType      },
        { "half1",                   Ty::ScalarType      },
        { "half1x1",                 Ty::ScalarType      },
        { "float",                   Ty::ScalarType      },
        { "float1",                  Ty::ScalarType      },
        { "float1x1",                Ty::ScalarType      },
        { "double",                  Ty::ScalarType      },
        { "double1",                 Ty::ScalarType      },
        { "double1x1",               Ty::ScalarType      },

        { "bool2",                   Ty::VectorType      },
        { "bool3",                   Ty::VectorType      },
        { "bool4",                   Ty::VectorType      },
        { "int2",                    Ty::VectorType      },
        { "int3",                    Ty::VectorType      },
        { "int4",                    Ty::VectorType      },
        { "uint2",                   Ty::VectorType      },
        { "uint3",                   Ty::VectorType      },
        { "uint4",                   Ty::VectorType      },
        { "half2",                   Ty::VectorType      },
        { "half3",                   Ty::VectorType      },
        { "half4",                   Ty::VectorType      },
        { "float2",                  Ty::VectorType      },
        { "float3",                  Ty::VectorType      },
        { "float4",                  Ty::VectorType      },
        { "double2",                 Ty::VectorType      },
        { "double3",                 Ty::VectorType      },
        { "double4",                 Ty::VectorType      },

        { "bool2x2",                 Ty::MatrixType      },
        { "bool2x3",                 Ty::MatrixType      },
        { "bool2x4",                 Ty::MatrixType      },
        { "bool3x2",                 Ty::MatrixType      },
        { "bool3x3",                 Ty::MatrixType      },
        { "bool3x4",                 Ty::MatrixType      },
        { "bool4x2",                 Ty::MatrixType      },
        { "bool4x3",                 Ty::MatrixType      },
        { "bool4x4",                 Ty::MatrixType      },
        { "int2x2",                  Ty::MatrixType      },
        { "int2x3",                  Ty::MatrixType      },
        { "int2x4",                  Ty::MatrixType      },
        { "int3x2",                  Ty::MatrixType      },
        { "int3x3",                  Ty::MatrixType      },
        { "int3x4",                  Ty::MatrixType      },
        { "int4x2",                  Ty::MatrixType      },
        { "int4x3",                  Ty::MatrixType      },
        { "int4x4",                  Ty::MatrixType      },
        { "uint2x2",                 Ty::MatrixType      },
        { "uint2x3",                 Ty::MatrixType      },
        { "uint2x4",                 Ty::MatrixType      },
        { "uint3x2",                 Ty::MatrixType      },
        { "uint3x3",                 Ty::MatrixType      },
        { "uint3x4",                 Ty::MatrixType      },
        { "uint4x2",                 Ty::MatrixType      },
        { "uint4x3",                 Ty::MatrixType      },
        { "uint4x4",                 Ty::MatrixType      },
        { "half2x2",                 Ty::MatrixType      },
        { "half2x3",                 Ty::MatrixType      },
        { "half2x4",                 Ty::MatrixType      },
        { "half3x2",                 Ty::MatrixType      },
        { "half3x3",                 Ty::MatrixType      },
        { "half3x4",                 Ty::MatrixType      },
        { "half4x2",                 Ty::MatrixType      },
        { "half4x3",                 Ty::MatrixType      },
        { "half4x4",                 Ty::MatrixType      },
        { "float2x2",                Ty::MatrixType      },
        { "float2x3",                Ty::MatrixType      },
        { "float2x4",                Ty::MatrixType      },
        { "float3x2",                Ty::MatrixType      },
        { "float3x3",                Ty::MatrixType      },
        { "float3x4",                Ty::MatrixType      },
        { "float4x2",                Ty::MatrixType      },
        { "float4x3",                Ty::MatrixType      },
        { "float4x4",                Ty::MatrixType      },
        { "double2x2",               Ty::MatrixType      },
        { "double2x3",               Ty::MatrixType      },
        { "double2x4",               Ty::MatrixType      },
        { "double3x2",               Ty::MatrixType      },
        { "double3x3",               Ty::MatrixType      },
        { "double3x4",               Ty::MatrixType      },
        { "double4x2",               Ty::MatrixType      },
        { "double4x3",               Ty::MatrixType      },
        { "double4x4",               Ty::MatrixType      },

        { "do",                      Ty::Do              },
        { "while",                   Ty::While           },
        { "for",                     Ty::For             },

        { "if",                      Ty::If              },
        { "else",                    Ty::Else            },

        { "switch",                  Ty::Switch          },
        { "case",                    Ty::Case            },
        { "default",                 Ty::Default         },

        { "struct",                  Ty::Struct          },
        { "register",                Ty::Register        },
        { "packoffset",              Ty::PackOffset      },

        { "sampler",                 Ty::Sampler         },
        { "sampler1D",               Ty::Sampler         },
        { "sampler2D",               Ty::Sampler         },
        { "sampler3D",               Ty::Sampler         },
        { "samplerCUBE",             Ty::Sampler         },
        { "sampler_state",           Ty::Sampler         },
        { "SamplerState",            Ty::Sampler         },
        { "SamplerComparisonState",  Ty::Sampler         }, // since D3D10+

        { "Texture1D",               Ty::Texture         },
        { "Texture1DArray",          Ty::Texture         },
        { "Texture2D",               Ty::Texture         },
        { "Texture2DArray",          Ty::Texture         },
        { "Texture3D",               Ty::Texture         },
        { "TextureCube",             Ty::Texture         },
        { "TextureCubeArray",        Ty::Texture         },
        { "Texture2DMS",             Ty::Texture         },
        { "Texture2DMSArray",        Ty::Texture         },
        { "RWTexture1D",             Ty::Texture         },
        { "RWTexture1DArray",        Ty::Texture         },
        { "RWTexture2D",             Ty::Texture         },
        { "RWTexture2DArray",        Ty::Texture         },
        { "RWTexture3D",             Ty::Texture         },

        { "AppendStructuredBuffer",  Ty::StorageBuffer   },
        { "Buffer",                  Ty::StorageBuffer   },
        { "ByteAddressBuffer",       Ty::StorageBuffer   },
        { "ConsumeStructuredBuffer", Ty::StorageBuffer   },
        { "StructuredBuffer",        Ty::StorageBuffer   },
        { "RWBuffer",                Ty::StorageBuffer   },
        { "RWByteAddressBuffer",     Ty::StorageBuffer   },
        { "RWStructuredBuffer",      Ty::StorageBuffer   },

        { "cbuffer",                 Ty::UniformBuffer   },
        { "tbuffer",                 Ty::UniformBuffer   },

        { "break",                   Ty::CtrlTransfer    },
        { "continue",                Ty::CtrlTransfer    },
        { "discard",                 Ty::CtrlTransfer    },

        { "return",                  Ty::Return          },

        { "uniform",                 Ty::InputModifier   },
        { "in",                      Ty::InputModifier   },
        { "out",                     Ty::InputModifier   },
        { "inout",                   Ty::InputModifier   },

        { "extern",                  Ty::StorageModifier },
        { "nointerpolation",         Ty::StorageModifier },
        { "precise",                 Ty::StorageModifier },
        { "shared",                  Ty::StorageModifier },
        { "groupshared",             Ty::StorageModifier },
        { "static",                  Ty::StorageModifier },
        //{ "uniform",                 Ty::StorageModifier }, // Already used as "InputModifier"
        { "volatile",                Ty::StorageModifier },
        { "linear",                  Ty::StorageModifier },
        { "centroid",                Ty::StorageModifier },
        { "noperspective",           Ty::StorageModifier },
        { "sample",                  Ty::StorageModifier },

        { "const",                   Ty::TypeModifier    },
        { "row_major",               Ty::TypeModifier    },
        { "column_major",            Ty::TypeModifier    },
    };
}

static KeywordMapType keywordMap = GenerateKeywordMap();

const KeywordMapType& HLSLKeywords()
{
    return keywordMap;
}

} // /namespace Xsc

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


<commit_before>/*
* Copyright (C) 2018 sysmocom - s.f.m.c. GmbH
*
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 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 Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <string.h>
#include <cstdio>
#include <fstream>
#include <string>
#include <stdarg.h>
#include <sys/time.h>	// For gettimeofday

#include "Logger.h"
#include "Threads.h"	// pat added

using namespace std;

Mutex gLogToLock;

std::ostream& operator<<(std::ostream& os, std::ostringstream& ss)
{
	return os << ss.str();
}

Log::~Log()
{
	int mlen = mStream.str().size();
	int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
	const char *fmt = neednl ? "%s\n" : "%s";
	ScopedLock lock(gLogToLock);
	// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
	// so just use std::cout.
	LOGPSRC(mCategory, mPriority, filename, line, fmt, mStream.str().c_str());
}

ostringstream& Log::get()
{
	return mStream;
}

// vim: ts=4 sw=4
<commit_msg>Logger: Disable pthread cancel point inside Logger destructor<commit_after>/*
* Copyright (C) 2018 sysmocom - s.f.m.c. GmbH
*
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 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 Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <string.h>
#include <cstdio>
#include <fstream>
#include <string>
#include <stdarg.h>
#include <sys/time.h>	// For gettimeofday

#include "Logger.h"
#include "Threads.h"	// pat added

using namespace std;

Mutex gLogToLock;

std::ostream& operator<<(std::ostream& os, std::ostringstream& ss)
{
	return os << ss.str();
}

Log::~Log()
{
	int old_state;
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
	int mlen = mStream.str().size();
	int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
	const char *fmt = neednl ? "%s\n" : "%s";
	ScopedLock lock(gLogToLock);
	// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
	// so just use std::cout.
	LOGPSRC(mCategory, mPriority, filename, line, fmt, mStream.str().c_str());
	pthread_setcancelstate(old_state, NULL);
}

ostringstream& Log::get()
{
	return mStream;
}

// vim: ts=4 sw=4
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */

#ifndef _Stroika_Foundation_Containers_Concrete_Stack_Factory_inl_
#define _Stroika_Foundation_Containers_Concrete_Stack_Factory_inl_

#include "../Concrete/Stack_LinkedList.h"

namespace Stroika::Foundation::Containers::Factory {

    /*
     ********************************************************************************
     ******************************* Stack_Factory<T> *******************************
     ********************************************************************************
     */
#if qCompiler_cpp17InlineStaticMemberOfClassDoubleDeleteAtExit_Buggy
    template <typename T>
    atomic<Stack<T> (*) ()> Stack_Factory<T>::sFactory_ (nullptr);
#endif
    template <typename T>
    inline Stack<T> Stack_Factory<T>::operator() () const
    {
        /*
         *  Would have been more performant to just and assure always properly set, but to initialize
         *  sFactory_ with a value other than nullptr requires waiting until after main() - so causes problems
         *  with containers constructed before main.
         *
         *  This works more generally (and with hopefully modest enough performance impact).
         */
        if (auto f = sFactory_.load ()) {
            return f ();
        }
        else {
            return Default_ ();
        }
    }
    template <typename T>
    inline void Stack_Factory<T>::Register (Stack<T> (*factory) ())
    {
        sFactory_ = factory;
    }
    template <typename T>
    inline Stack<T> Stack_Factory<T>::Default_ ()
    {
        return Concrete::Stack_LinkedList<T>{};
    }

}

#endif /* _Stroika_Foundation_Containers_Concrete_Stack_Factory_inl_ */
<commit_msg>cosmetic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */

#ifndef _Stroika_Foundation_Containers_Concrete_Stack_Factory_inl_
#define _Stroika_Foundation_Containers_Concrete_Stack_Factory_inl_

#include "../Concrete/Stack_LinkedList.h"

namespace Stroika::Foundation::Containers::Factory {

    /*
     ********************************************************************************
     ******************************* Stack_Factory<T> *******************************
     ********************************************************************************
     */
#if qCompiler_cpp17InlineStaticMemberOfClassDoubleDeleteAtExit_Buggy
    template <typename T>
    atomic<Stack<T> (*) ()> Stack_Factory<T>::sFactory_{nullptr};
#endif
    template <typename T>
    inline Stack<T> Stack_Factory<T>::operator() () const
    {
        /*
         *  Would have been more performant to just and assure always properly set, but to initialize
         *  sFactory_ with a value other than nullptr requires waiting until after main() - so causes problems
         *  with containers constructed before main.
         *
         *  This works more generally (and with hopefully modest enough performance impact).
         */
        if (auto f = sFactory_.load ()) {
            return f ();
        }
        else {
            return Default_ ();
        }
    }
    template <typename T>
    inline void Stack_Factory<T>::Register (Stack<T> (*factory) ())
    {
        sFactory_ = factory;
    }
    template <typename T>
    inline Stack<T> Stack_Factory<T>::Default_ ()
    {
        return Concrete::Stack_LinkedList<T>{};
    }

}

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


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkImageLiveWireContourModelFilter.h"

#include <itkImageRegionIterator.h>
#include <itkCastImageFilter.h>
#include <itkGradientMagnitudeImageFilter.h>

mitk::ImageLiveWireContourModelFilter::ImageLiveWireContourModelFilter()
{
  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
  this->SetNumberOfRequiredInputs(1);
  this->SetNumberOfIndexedOutputs( 1 );
  this->SetNthOutput(0, output.GetPointer());
  m_CostFunction = ImageLiveWireContourModelFilter::CostFunctionType::New();
  m_ShortestPathFilter = ShortestPathImageFilterType::New();
  m_ShortestPathFilter->SetCostFunction(m_CostFunction);
  m_UseDynamicCostMap = false;
  m_ImageModified = false;
  m_Timestep = 0;
}

mitk::ImageLiveWireContourModelFilter::~ImageLiveWireContourModelFilter()
{

}

mitk::ImageLiveWireContourModelFilter::OutputType* mitk::ImageLiveWireContourModelFilter::GetOutput()
{
  return Superclass::GetOutput();
}

void mitk::ImageLiveWireContourModelFilter::SetInput ( const mitk::ImageLiveWireContourModelFilter::InputType* input )
{
  this->SetInput( 0, input );
}

void mitk::ImageLiveWireContourModelFilter::SetInput ( unsigned int idx, const mitk::ImageLiveWireContourModelFilter::InputType* input )
{
  if ( idx + 1 > this->GetNumberOfInputs() )
  {
    this->SetNumberOfRequiredInputs(idx + 1);
  }
  if ( input != static_cast<InputType*> ( this->ProcessObject::GetInput ( idx ) ) )
  {
    this->ProcessObject::SetNthInput ( idx, const_cast<InputType*> ( input ) );
    this->Modified();
    this->m_ImageModified = true;
    m_ShortestPathFilter = ShortestPathImageFilterType::New();
    m_ShortestPathFilter->SetCostFunction(m_CostFunction);
  }
}

const mitk::ImageLiveWireContourModelFilter::InputType* mitk::ImageLiveWireContourModelFilter::GetInput( void )
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::ImageLiveWireContourModelFilter::InputType*>(this->ProcessObject::GetInput(0));
}

const mitk::ImageLiveWireContourModelFilter::InputType* mitk::ImageLiveWireContourModelFilter::GetInput( unsigned int idx )
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::ImageLiveWireContourModelFilter::InputType*>(this->ProcessObject::GetInput(idx));
}

void mitk::ImageLiveWireContourModelFilter::GenerateData()
{
  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());

  if(!input)
  {
    MITK_ERROR << "No input available.";
    itkExceptionMacro("mitk::ImageToLiveWireContourFilter: No input available. Please set the input!");
    return;
  }

  if( input->GetDimension() != 2 )
  {
    MITK_ERROR << "Filter is only working on 2D images.";
    itkExceptionMacro("mitk::ImageToLiveWireContourFilter: Filter is only working on 2D images.. Please make sure that the input is 2D!");
    return;
  }

  if( m_ImageModified )
  {
    AccessFixedDimensionByItk(input, ItkPreProcessImage, 2);
    m_ImageModified = false;
  }

  input->GetGeometry()->WorldToIndex(m_StartPoint, m_StartPointInIndex);
  input->GetGeometry()->WorldToIndex(m_EndPoint, m_EndPointInIndex);

  //only start calculating if both indices are inside image geometry
  if( input->GetGeometry()->IsIndexInside(this->m_StartPointInIndex) && input->GetGeometry()->IsIndexInside(this->m_EndPointInIndex) )
  {
      try
      {
        this->UpdateLiveWire();
      }
      catch( itk::ExceptionObject & e )
      {
        MITK_INFO << "Exception caught during live wiring calculation: " << e;
        m_ImageModified = true;
        return;
      }
  }
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ImageLiveWireContourModelFilter::ItkPreProcessImage (itk::Image<TPixel, VImageDimension>* inputImage)
{
  typedef itk::Image< TPixel, VImageDimension >                   InputImageType;
  typedef itk::CastImageFilter< InputImageType, FloatImageType >  CastFilterType;

  typename CastFilterType::Pointer castFilter = CastFilterType::New();
  castFilter->SetInput(inputImage);
  castFilter->Update();
  m_PreProcessedImage = castFilter->GetOutput();
  m_CostFunction->SetImage( m_PreProcessedImage );
  m_ShortestPathFilter->SetInput( m_PreProcessedImage );
}

void mitk::ImageLiveWireContourModelFilter::UpdateLiveWire()
{
// compute the requested region for itk filters
  FloatImageType::IndexType startPoint, endPoint;

  startPoint[0] = m_StartPointInIndex[0];
  startPoint[1] = m_StartPointInIndex[1];

  endPoint[0] = m_EndPointInIndex[0];
  endPoint[1] = m_EndPointInIndex[1];

  //minimum value in each direction for startRegion
  FloatImageType::IndexType startRegion;
  startRegion[0] = startPoint[0] < endPoint[0] ? startPoint[0] : endPoint[0];
  startRegion[1] = startPoint[1] < endPoint[1] ? startPoint[1] : endPoint[1];

  //maximum value in each direction for size
  FloatImageType::SizeType size;
  size[0] = abs( startPoint[0] - endPoint[0] );
  size[1] = abs( startPoint[1] - endPoint[1] );

  MITK_INFO << "start region: " << startRegion[0] << " " << startRegion[1];
  MITK_INFO << "size: " << size[0] << " " << size[1];

  CostFunctionType::RegionType region;
  region.SetSize( size );
  region.SetIndex( startRegion );

  //inputImage->SetRequestedRegion(region);

  // extracts features from image and calculates costs
  //m_CostFunction->SetImage(m_PreProcessedImage);
  m_CostFunction->SetStartIndex(startPoint);
  m_CostFunction->SetEndIndex(endPoint);
  m_CostFunction->SetRequestedRegion(region);
  m_CostFunction->SetUseCostMap(m_UseDynamicCostMap);

  // calculate shortest path between start and end point
  m_ShortestPathFilter->SetFullNeighborsMode(true);
  //m_ShortestPathFilter->SetInput( m_CostFunction->SetImage(m_PreProcessedImage) );
  m_ShortestPathFilter->SetMakeOutputImage(false);

  //m_ShortestPathFilter->SetCalcAllDistances(true);
  m_ShortestPathFilter->SetStartIndex(startPoint);
  m_ShortestPathFilter->SetEndIndex(endPoint);

  m_ShortestPathFilter->Update();

  // construct contour from path image
  //get the shortest path as vector
  ShortestPathType shortestPath = m_ShortestPathFilter->GetVectorPath();

  //fill the output contour with control points from the path
  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
  this->SetNthOutput(0, output.GetPointer());

//  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->GetOutput() );
  output->Expand(m_Timestep+1);

//  output->Clear();

  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());

  ShortestPathType::const_iterator pathIterator = shortestPath.begin();

  while(pathIterator != shortestPath.end())
  {
    mitk::Point3D currentPoint;
    currentPoint[0] = (*pathIterator)[0];
    currentPoint[1] = (*pathIterator)[1];
    currentPoint[2] = 0;

    input->GetGeometry()->IndexToWorld(currentPoint, currentPoint);
    output->AddVertex(currentPoint, false, m_Timestep);

    pathIterator++;
  }
}

bool mitk::ImageLiveWireContourModelFilter::CreateDynamicCostMap(mitk::ContourModel* path)
{
  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());
  if(input)
  {
    AccessFixedDimensionByItk_1(input,CreateDynamicCostMapByITK, 2, path);
    return true;
  }
  else
  {
    return false;
  }
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ImageLiveWireContourModelFilter::CreateDynamicCostMapByITK( itk::Image<TPixel, VImageDimension>* inputImage, mitk::ContourModel* path )
{
  /*++++++++++ create dynamic cost transfer map ++++++++++*/

  /* Compute  the costs of the gradient magnitude dynamically.
  * using a map of the histogram of gradient magnitude image.
  * Use the histogram gradient map to interpolate the costs
  * with gaussing function including next two bins right and left
  * to current position x. With the histogram gradient costs are interpolated
  * with a gaussing function summation of next two bins right and left
  * to current position x.
  */
  std::vector< itk::Index<VImageDimension> > shortestPath;

  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());
  if(path == NULL)
  {
    OutputType::Pointer output = this->GetOutput();
    mitk::ContourModel::VertexIterator it = output->IteratorBegin();
    while( it != output->IteratorEnd() )
    {
      itk::Index<VImageDimension> cur;
      mitk::Point3D c = (*it)->Coordinates;
      input->GetGeometry()->WorldToIndex(c, c);
      cur[0] = c[0];
      cur[1] = c[1];

      shortestPath.push_back( cur);
      it++;
    }
  }
  else
  {

    mitk::ContourModel::VertexIterator it = path->IteratorBegin();
    while( it != path->IteratorEnd() )
    {
      itk::Index<VImageDimension> cur;
      mitk::Point3D c = (*it)->Coordinates;
      input->GetGeometry()->WorldToIndex(c, c);
      cur[0] = c[0];
      cur[1] = c[1];

      shortestPath.push_back( cur);
      it++;
    }

  }

  /*+++ filter image gradient magnitude +++*/
  typedef  itk::GradientMagnitudeImageFilter< itk::Image<TPixel, VImageDimension>,  itk::Image<TPixel, VImageDimension> > GradientMagnitudeFilterType;
  typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New();
  gradientFilter->SetInput(inputImage);
  gradientFilter->Update();
  typename itk::Image<TPixel, VImageDimension>::Pointer gradientMagnImage = gradientFilter->GetOutput();

  //get the path

  //iterator of path
  typename std::vector< itk::Index<VImageDimension> >::iterator pathIterator = shortestPath.begin();

  std::map< int, int > histogram;

  //create histogram within path
  while(pathIterator != shortestPath.end())
  {
    //count pixel values
    //use scale factor to avoid mapping gradients between 0.0 and 1.0 to same bin
    histogram[ static_cast<int>( gradientMagnImage->GetPixel((*pathIterator)) * ImageLiveWireContourModelFilter::CostFunctionType::MAPSCALEFACTOR ) ] += 1;

    pathIterator++;
  }

  double max = 1.0;

  if( !histogram.empty() )
  {

    std::map< int, int >::iterator itMAX;

    //get max of histogramm
    int currentMaxValue = 0;
    std::map< int, int >::iterator it = histogram.begin();
    while( it != histogram.end())
    {
      if((*it).second > currentMaxValue)
      {
        itMAX = it;
        currentMaxValue = (*it).second;
      }
      it++;
    }

    std::map< int, int >::key_type keyOfMax = itMAX->first;

    /*+++++++++++++++++++++++++ compute the to max of gaussian summation ++++++++++++++++++++++++*/
    std::map< int, int >::iterator end = histogram.end();
    std::map< int, int >::iterator last = --(histogram.end());

    std::map< int, int >::iterator left2;
    std::map< int, int >::iterator left1;
    std::map< int, int >::iterator right1;
    std::map< int, int >::iterator right2;

    right1 = itMAX;

    if(right1 == end || right1 == last )
    {
      right2 = end;
    }
    else//( right1 <= last )
    {
      std::map< int, int >::iterator temp = right1;
      right2 = ++right1;//rght1 + 1
      right1 = temp;
    }

    if( right1 == histogram.begin() )
    {
      left1 = end;
      left2 = end;
    }
    else if( right1 == (++(histogram.begin())) )
    {
      std::map< int, int >::iterator temp = right1;
      left1  = --right1;//rght1 - 1
      right1 = temp;
      left2  = end;
    }
    else
    {
      std::map< int, int >::iterator temp = right1;
      left1 = --right1;//rght1 - 1
      left2 = --right1;//rght1 - 2
      right1 = temp;
    }

    double partRight1, partRight2, partLeft1, partLeft2;
    partRight1 = partRight2 = partLeft1 = partLeft2 = 0.0;

    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    f(x) = v(bin) * e^ ( -1/2 * (|x-k(bin)| / sigma)^2 )

    gaussian approximation

    where
    v(bin) is the value in the map
    k(bin) is the key
    */
    if( left2 != end )
    {
      partLeft2 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, left2->first, left2->second);
    }

    if( left1 != end )
    {
      partLeft1 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, left1->first, left1->second);
    }

    if( right1 != end )
    {
      partRight1 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, right1->first, right1->second);
    }

    if( right2 != end )
    {
      partRight2 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, right2->first, right2->second);
    }
    /*----------------------------------------------------------------------------*/

    max = (partRight1 + partRight2 + partLeft1 + partLeft2);

  }

  this->m_CostFunction->SetDynamicCostMap(histogram);
  this->m_CostFunction->SetCostMapMaximum(max);

}
<commit_msg>use a bigger region<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkImageLiveWireContourModelFilter.h"

#include <itkImageRegionIterator.h>
#include <itkCastImageFilter.h>
#include <itkGradientMagnitudeImageFilter.h>

mitk::ImageLiveWireContourModelFilter::ImageLiveWireContourModelFilter()
{
  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
  this->SetNumberOfRequiredInputs(1);
  this->SetNumberOfIndexedOutputs( 1 );
  this->SetNthOutput(0, output.GetPointer());
  m_CostFunction = ImageLiveWireContourModelFilter::CostFunctionType::New();
  m_ShortestPathFilter = ShortestPathImageFilterType::New();
  m_ShortestPathFilter->SetCostFunction(m_CostFunction);
  m_UseDynamicCostMap = false;
  m_ImageModified = false;
  m_Timestep = 0;
}

mitk::ImageLiveWireContourModelFilter::~ImageLiveWireContourModelFilter()
{

}

mitk::ImageLiveWireContourModelFilter::OutputType* mitk::ImageLiveWireContourModelFilter::GetOutput()
{
  return Superclass::GetOutput();
}

void mitk::ImageLiveWireContourModelFilter::SetInput ( const mitk::ImageLiveWireContourModelFilter::InputType* input )
{
  this->SetInput( 0, input );
}

void mitk::ImageLiveWireContourModelFilter::SetInput ( unsigned int idx, const mitk::ImageLiveWireContourModelFilter::InputType* input )
{
  if ( idx + 1 > this->GetNumberOfInputs() )
  {
    this->SetNumberOfRequiredInputs(idx + 1);
  }
  if ( input != static_cast<InputType*> ( this->ProcessObject::GetInput ( idx ) ) )
  {
    this->ProcessObject::SetNthInput ( idx, const_cast<InputType*> ( input ) );
    this->Modified();
    this->m_ImageModified = true;
    m_ShortestPathFilter = ShortestPathImageFilterType::New();
    m_ShortestPathFilter->SetCostFunction(m_CostFunction);
  }
}

const mitk::ImageLiveWireContourModelFilter::InputType* mitk::ImageLiveWireContourModelFilter::GetInput( void )
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::ImageLiveWireContourModelFilter::InputType*>(this->ProcessObject::GetInput(0));
}

const mitk::ImageLiveWireContourModelFilter::InputType* mitk::ImageLiveWireContourModelFilter::GetInput( unsigned int idx )
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::ImageLiveWireContourModelFilter::InputType*>(this->ProcessObject::GetInput(idx));
}

void mitk::ImageLiveWireContourModelFilter::GenerateData()
{
  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());

  if(!input)
  {
    MITK_ERROR << "No input available.";
    itkExceptionMacro("mitk::ImageToLiveWireContourFilter: No input available. Please set the input!");
    return;
  }

  if( input->GetDimension() != 2 )
  {
    MITK_ERROR << "Filter is only working on 2D images.";
    itkExceptionMacro("mitk::ImageToLiveWireContourFilter: Filter is only working on 2D images.. Please make sure that the input is 2D!");
    return;
  }

  if( m_ImageModified )
  {
    AccessFixedDimensionByItk(input, ItkPreProcessImage, 2);
    m_ImageModified = false;
  }

  input->GetGeometry()->WorldToIndex(m_StartPoint, m_StartPointInIndex);
  input->GetGeometry()->WorldToIndex(m_EndPoint, m_EndPointInIndex);

  //only start calculating if both indices are inside image geometry
  if( input->GetGeometry()->IsIndexInside(this->m_StartPointInIndex) && input->GetGeometry()->IsIndexInside(this->m_EndPointInIndex) )
  {
      try
      {
        this->UpdateLiveWire();
      }
      catch( itk::ExceptionObject & e )
      {
        MITK_INFO << "Exception caught during live wiring calculation: " << e;
        m_ImageModified = true;
        return;
      }
  }
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ImageLiveWireContourModelFilter::ItkPreProcessImage (itk::Image<TPixel, VImageDimension>* inputImage)
{
  typedef itk::Image< TPixel, VImageDimension >                   InputImageType;
  typedef itk::CastImageFilter< InputImageType, FloatImageType >  CastFilterType;

  typename CastFilterType::Pointer castFilter = CastFilterType::New();
  castFilter->SetInput(inputImage);
  castFilter->Update();
  m_PreProcessedImage = castFilter->GetOutput();
  m_CostFunction->SetImage( m_PreProcessedImage );
  m_ShortestPathFilter->SetInput( m_PreProcessedImage );
}

void mitk::ImageLiveWireContourModelFilter::UpdateLiveWire()
{
// compute the requested region for itk filters
  FloatImageType::IndexType startPoint, endPoint;

  startPoint[0] = m_StartPointInIndex[0];
  startPoint[1] = m_StartPointInIndex[1];

  endPoint[0] = m_EndPointInIndex[0];
  endPoint[1] = m_EndPointInIndex[1];

  //minimum value in each direction for startRegion
  FloatImageType::IndexType startRegion;
  startRegion[0] = startPoint[0] < endPoint[0] ? startPoint[0] : endPoint[0];
  startRegion[1] = startPoint[1] < endPoint[1] ? startPoint[1] : endPoint[1];

  //maximum value in each direction for size
  FloatImageType::SizeType size;
  size[0] = abs( startPoint[0] - endPoint[0] ) + 1;
  size[1] = abs( startPoint[1] - endPoint[1] ) + 1;

  MITK_INFO << "start region: " << startRegion[0] << " " << startRegion[1];
  MITK_INFO << "size: " << size[0] << " " << size[1];

  CostFunctionType::RegionType region;
  region.SetSize( size );
  region.SetIndex( startRegion );

  //inputImage->SetRequestedRegion(region);

  // extracts features from image and calculates costs
  //m_CostFunction->SetImage(m_PreProcessedImage);
  m_CostFunction->SetStartIndex(startPoint);
  m_CostFunction->SetEndIndex(endPoint);
  m_CostFunction->SetRequestedRegion(region);
  m_CostFunction->SetUseCostMap(m_UseDynamicCostMap);

  // calculate shortest path between start and end point
  m_ShortestPathFilter->SetFullNeighborsMode(true);
  //m_ShortestPathFilter->SetInput( m_CostFunction->SetImage(m_PreProcessedImage) );
  m_ShortestPathFilter->SetMakeOutputImage(false);

  //m_ShortestPathFilter->SetCalcAllDistances(true);
  m_ShortestPathFilter->SetStartIndex(startPoint);
  m_ShortestPathFilter->SetEndIndex(endPoint);

  m_ShortestPathFilter->Update();

  // construct contour from path image
  //get the shortest path as vector
  ShortestPathType shortestPath = m_ShortestPathFilter->GetVectorPath();

  //fill the output contour with control points from the path
  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->MakeOutput( 0 ).GetPointer() );
  this->SetNthOutput(0, output.GetPointer());

//  OutputType::Pointer output = dynamic_cast<OutputType*> ( this->GetOutput() );
  output->Expand(m_Timestep+1);

//  output->Clear();

  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());

  ShortestPathType::const_iterator pathIterator = shortestPath.begin();

  while(pathIterator != shortestPath.end())
  {
    mitk::Point3D currentPoint;
    currentPoint[0] = (*pathIterator)[0];
    currentPoint[1] = (*pathIterator)[1];
    currentPoint[2] = 0;

    input->GetGeometry()->IndexToWorld(currentPoint, currentPoint);
    output->AddVertex(currentPoint, false, m_Timestep);

    pathIterator++;
  }
}

bool mitk::ImageLiveWireContourModelFilter::CreateDynamicCostMap(mitk::ContourModel* path)
{
  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());
  if(input)
  {
    AccessFixedDimensionByItk_1(input,CreateDynamicCostMapByITK, 2, path);
    return true;
  }
  else
  {
    return false;
  }
}

template<typename TPixel, unsigned int VImageDimension>
void mitk::ImageLiveWireContourModelFilter::CreateDynamicCostMapByITK( itk::Image<TPixel, VImageDimension>* inputImage, mitk::ContourModel* path )
{
  /*++++++++++ create dynamic cost transfer map ++++++++++*/

  /* Compute  the costs of the gradient magnitude dynamically.
  * using a map of the histogram of gradient magnitude image.
  * Use the histogram gradient map to interpolate the costs
  * with gaussing function including next two bins right and left
  * to current position x. With the histogram gradient costs are interpolated
  * with a gaussing function summation of next two bins right and left
  * to current position x.
  */
  std::vector< itk::Index<VImageDimension> > shortestPath;

  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());
  if(path == NULL)
  {
    OutputType::Pointer output = this->GetOutput();
    mitk::ContourModel::VertexIterator it = output->IteratorBegin();
    while( it != output->IteratorEnd() )
    {
      itk::Index<VImageDimension> cur;
      mitk::Point3D c = (*it)->Coordinates;
      input->GetGeometry()->WorldToIndex(c, c);
      cur[0] = c[0];
      cur[1] = c[1];

      shortestPath.push_back( cur);
      it++;
    }
  }
  else
  {

    mitk::ContourModel::VertexIterator it = path->IteratorBegin();
    while( it != path->IteratorEnd() )
    {
      itk::Index<VImageDimension> cur;
      mitk::Point3D c = (*it)->Coordinates;
      input->GetGeometry()->WorldToIndex(c, c);
      cur[0] = c[0];
      cur[1] = c[1];

      shortestPath.push_back( cur);
      it++;
    }

  }

  /*+++ filter image gradient magnitude +++*/
  typedef  itk::GradientMagnitudeImageFilter< itk::Image<TPixel, VImageDimension>,  itk::Image<TPixel, VImageDimension> > GradientMagnitudeFilterType;
  typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New();
  gradientFilter->SetInput(inputImage);
  gradientFilter->Update();
  typename itk::Image<TPixel, VImageDimension>::Pointer gradientMagnImage = gradientFilter->GetOutput();

  //get the path

  //iterator of path
  typename std::vector< itk::Index<VImageDimension> >::iterator pathIterator = shortestPath.begin();

  std::map< int, int > histogram;

  //create histogram within path
  while(pathIterator != shortestPath.end())
  {
    //count pixel values
    //use scale factor to avoid mapping gradients between 0.0 and 1.0 to same bin
    histogram[ static_cast<int>( gradientMagnImage->GetPixel((*pathIterator)) * ImageLiveWireContourModelFilter::CostFunctionType::MAPSCALEFACTOR ) ] += 1;

    pathIterator++;
  }

  double max = 1.0;

  if( !histogram.empty() )
  {

    std::map< int, int >::iterator itMAX;

    //get max of histogramm
    int currentMaxValue = 0;
    std::map< int, int >::iterator it = histogram.begin();
    while( it != histogram.end())
    {
      if((*it).second > currentMaxValue)
      {
        itMAX = it;
        currentMaxValue = (*it).second;
      }
      it++;
    }

    std::map< int, int >::key_type keyOfMax = itMAX->first;

    /*+++++++++++++++++++++++++ compute the to max of gaussian summation ++++++++++++++++++++++++*/
    std::map< int, int >::iterator end = histogram.end();
    std::map< int, int >::iterator last = --(histogram.end());

    std::map< int, int >::iterator left2;
    std::map< int, int >::iterator left1;
    std::map< int, int >::iterator right1;
    std::map< int, int >::iterator right2;

    right1 = itMAX;

    if(right1 == end || right1 == last )
    {
      right2 = end;
    }
    else//( right1 <= last )
    {
      std::map< int, int >::iterator temp = right1;
      right2 = ++right1;//rght1 + 1
      right1 = temp;
    }

    if( right1 == histogram.begin() )
    {
      left1 = end;
      left2 = end;
    }
    else if( right1 == (++(histogram.begin())) )
    {
      std::map< int, int >::iterator temp = right1;
      left1  = --right1;//rght1 - 1
      right1 = temp;
      left2  = end;
    }
    else
    {
      std::map< int, int >::iterator temp = right1;
      left1 = --right1;//rght1 - 1
      left2 = --right1;//rght1 - 2
      right1 = temp;
    }

    double partRight1, partRight2, partLeft1, partLeft2;
    partRight1 = partRight2 = partLeft1 = partLeft2 = 0.0;

    /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    f(x) = v(bin) * e^ ( -1/2 * (|x-k(bin)| / sigma)^2 )

    gaussian approximation

    where
    v(bin) is the value in the map
    k(bin) is the key
    */
    if( left2 != end )
    {
      partLeft2 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, left2->first, left2->second);
    }

    if( left1 != end )
    {
      partLeft1 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, left1->first, left1->second);
    }

    if( right1 != end )
    {
      partRight1 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, right1->first, right1->second);
    }

    if( right2 != end )
    {
      partRight2 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, right2->first, right2->second);
    }
    /*----------------------------------------------------------------------------*/

    max = (partRight1 + partRight2 + partLeft1 + partLeft2);

  }

  this->m_CostFunction->SetDynamicCostMap(histogram);
  this->m_CostFunction->SetCostMapMaximum(max);

}
<|endoftext|>