diff --git a/Superbuild/ITKExternal.cmake b/Superbuild/ITKExternal.cmake index 2a8a2296c..465b5532c 100644 --- a/Superbuild/ITKExternal.cmake +++ b/Superbuild/ITKExternal.cmake @@ -50,7 +50,9 @@ SET(itk_CACHE_ARGS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}" "-DCMAKE_INSTALL_PREFIX:PATH=" "-DITK_BUILD_DEFAULT_MODULES:BOOL=OFF" - "-DITKV3_COMPATIBILITY:BOOL=ON" + "-DITKV4_COMPATIBILITY:BOOL=ON" + "-DITK_LEGACY_REMOVE:BOOL=OFF" + "-DITK_FUTURE_LEGACY_REMOVE:BOOL=OFF" "-DModule_ITKRegistrationCommon:BOOL=ON" "-DModule_ITKSmoothing:BOOL=ON" "-DModule_ITKAnisotropicSmoothing:BOOL=ON" @@ -68,12 +70,13 @@ SET(itk_CACHE_ARGS "-DModule_ITKIOGIPL:BOOL=ON" "-DModule_IITKIOMeta:BOOL=ON" "-DModule_ITKIONRRD:BOOL=ON" - "-DModule_ITKDeprecated:BOOL=ON" + "-DModule_ITKDeprecated:BOOL=OFF" "-DCMAKE_CXX_FLAGS:STATIC=${CMAKE_CXX_FLAGS}" "-DCMAKE_CXX_FLAGS_DEBUG:STATIC=${CMAKE_CXX_FLAGS_DEBUG}" "-DCMAKE_C_FLAGS:STATIC=${CMAKE_C_FLAGS}" "-DCMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD:STATIC=${CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD}" "-DCMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY:STATIC=${CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY}" + "-DHDF5_BUILD_HL_LIB:BOOL=ON" ) IF(BUILD_MOSAIC_TOOLS) @@ -86,12 +89,12 @@ IF(BUILD_MOSAIC_TOOLS) ) ENDIF() -SET(itk_GIT_TAG "origin/itk-4.13.1") +SET(itk_GIT_TAG "enableH5HL") # If CMake ever allows overriding the checkout command or adding flags, # git checkout -q will silence message about detached head (harmless). ExternalProject_Add(ITK_external - GIT_REPOSITORY "https://github.com/CIBC-Internal/itk.git" + GIT_REPOSITORY "https://github.com/InsightSoftwareConsortium/ITK.git" GIT_TAG ${itk_GIT_TAG} UPDATE_COMMAND "" PATCH_COMMAND "" @@ -101,6 +104,6 @@ ExternalProject_Add(ITK_external # hardcoded, since we need this before ITK's configure step ExternalProject_Get_Property(ITK_external INSTALL_DIR) -SET(ITK_DIR "${INSTALL_DIR}/lib/cmake/ITK-4.13" CACHE PATH "") +SET(ITK_DIR "${INSTALL_DIR}/lib/cmake/ITK-5.2" CACHE PATH "") MESSAGE(STATUS "ITK_DIR=${ITK_DIR}") diff --git a/src/Application/Clipboard/ClipboardItem.cc b/src/Application/Clipboard/ClipboardItem.cc index aaedd7164..8406da3b4 100644 --- a/src/Application/Clipboard/ClipboardItem.cc +++ b/src/Application/Clipboard/ClipboardItem.cc @@ -68,7 +68,7 @@ ClipboardItem::~ClipboardItem() ClipboardItemHandle ClipboardItem::clone() const { - ClipboardItem* cpy = new ClipboardItem( this->private_->width_, + ClipboardItem* cpy = new ClipboardItem( this->private_->width_, this->private_->height_, this->private_->data_type_ ); cpy->private_->buffer_ = this->private_->buffer_; cpy->private_->provenance_id_ = this->private_->provenance_id_; @@ -126,6 +126,10 @@ void ClipboardItem::resize( size_t width, size_t height, Core::DataType data_typ case Core::DataType::UINT_E: buffer_size = sizeof( int ); break; + case Core::DataType::LONGLONG_E: + case Core::DataType::ULONGLONG_E: + buffer_size = sizeof( long long ); + break; case Core::DataType::FLOAT_E: buffer_size = sizeof( float ); break; diff --git a/src/Application/Filters/Actions/ActionCrop.cc b/src/Application/Filters/Actions/ActionCrop.cc index 1d7d84516..51913dbb6 100644 --- a/src/Application/Filters/Actions/ActionCrop.cc +++ b/src/Application/Filters/Actions/ActionCrop.cc @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -90,14 +90,14 @@ class CropAlgo : public LayerFilter public: template< class T > - void crop_typed_data( Core::DataBlockHandle src, Core::DataBlockHandle dst, + void crop_typed_data( Core::DataBlockHandle src, Core::DataBlockHandle dst, LayerHandle dst_layer ); void crop_data_layer( DataLayerHandle input, DataLayerHandle output ); void crop_mask_layer( MaskLayerHandle input, MaskLayerHandle output ); // RUN_FILTER: - // Implementation of run of the Runnable base class, this function is called + // Implementation of run of the Runnable base class, this function is called // when the thread is launched. virtual void run_filter(); @@ -109,11 +109,11 @@ class CropAlgo : public LayerFilter } // GET_LAYER_PREFIX: - // This function returns the name of the filter. The latter is prepended to the new layer name, - // when a new layer is generated. + // This function returns the name of the filter. The latter is prepended to the new layer name, + // when a new layer is generated. virtual std::string get_layer_prefix() const { - return "Crop"; + return "Crop"; } }; @@ -184,14 +184,14 @@ void CropAlgo::run_filter() void CropAlgo::crop_data_layer( DataLayerHandle input, DataLayerHandle output ) { Core::DataBlockHandle input_datablock = input->get_data_volume()->get_data_block(); - Core::DataBlockHandle output_datablock = Core::StdDataBlock::New( + Core::DataBlockHandle output_datablock = Core::StdDataBlock::New( output->get_grid_transform(), input_datablock->get_data_type() ); - if ( !output_datablock ) + if ( !output_datablock ) { this->report_error( "Could not allocate enough memory" ); return; } - + Core::DataBlock::shared_lock_type data_lock( input_datablock->get_mutex() ); switch ( input_datablock->get_data_type() ) { @@ -213,6 +213,12 @@ void CropAlgo::crop_data_layer( DataLayerHandle input, DataLayerHandle output ) case Core::DataType::UINT_E: this->crop_typed_data< unsigned int >( input_datablock, output_datablock, output ); break; + case Core::DataType::LONGLONG_E: + this->crop_typed_data< long long >( input_datablock, output_datablock, output ); + break; + case Core::DataType::ULONGLONG_E: + this->crop_typed_data< unsigned long long >( input_datablock, output_datablock, output ); + break; case Core::DataType::FLOAT_E: this->crop_typed_data< float >( input_datablock, output_datablock, output ); break; @@ -229,11 +235,11 @@ void CropAlgo::crop_data_layer( DataLayerHandle input, DataLayerHandle output ) { // Centering should be preserved for each layer Core::GridTransform output_grid_transform = output->get_grid_transform(); - output_grid_transform.set_originally_node_centered( + output_grid_transform.set_originally_node_centered( input->get_grid_transform().get_originally_node_centered() ); this->dispatch_insert_data_volume_into_layer( output, Core::DataVolumeHandle( - new Core::DataVolume( output_grid_transform, output_datablock ) ), + new Core::DataVolume( output_grid_transform, output_datablock ) ), true ); output->update_progress_signal_( 1.0 ); this->dispatch_unlock_layer( output ); @@ -253,12 +259,12 @@ void CropAlgo::crop_mask_layer( MaskLayerHandle input, MaskLayerHandle output ) Core::MaskDataBlockHandle input_mask = input->get_mask_volume()->get_mask_data_block(); Core::DataBlockHandle output_mask = Core::StdDataBlock::New( output->get_grid_transform(), Core::DataType::UCHAR_E ); - if ( !output_mask ) + if ( !output_mask ) { this->report_error( "Could not allocate enough memory" ); return; } - + Core::MaskDataBlock::shared_lock_type data_lock( input_mask->get_mutex() ); const unsigned char* src_data = input_mask->get_mask_data(); unsigned char* dst_data = reinterpret_cast< unsigned char* >( output_mask->get_data() ); @@ -338,7 +344,7 @@ bool ActionCrop::validate( Core::ActionContextHandle& context ) context->report_error( "No input layers specified" ); return false; } - + Core::GridTransform grid_trans; for ( size_t i = 0; i < this->private_->layer_ids_.size(); ++i ) { @@ -361,12 +367,12 @@ bool ActionCrop::validate( Core::ActionContextHandle& context ) context->report_error( "Input layers do not belong to the same group" ); return false; } - - // Check for layer availability - if ( !LayerManager::CheckLayerAvailability( this->private_->layer_ids_[ i ], + + // Check for layer availability + if ( !LayerManager::CheckLayerAvailability( this->private_->layer_ids_[ i ], this->private_->replace_, context, this->private_->sandbox_ ) ) return false; } - + const Core::Point& origin = this->private_->origin_; const Core::Vector& size = this->private_->size_; @@ -404,19 +410,19 @@ bool ActionCrop::validate( Core::ActionContextHandle& context ) return false; } - // Compute the cropped grid transform - Core::Point clamped_origin( this->private_->start_x_, + // Compute the cropped grid transform + Core::Point clamped_origin( this->private_->start_x_, this->private_->start_y_, this->private_->start_z_ ); clamped_origin = trans * clamped_origin; trans( 0, 3 ) = clamped_origin[ 0 ]; trans( 1, 3 ) = clamped_origin[ 1 ]; trans( 2, 3 ) = clamped_origin[ 2 ]; this->private_->output_grid_trans_.load_matrix( trans ); - this->private_->output_grid_trans_.set_nx( static_cast< size_t >( + this->private_->output_grid_trans_.set_nx( static_cast< size_t >( this->private_->end_x_ - this->private_->start_x_ + 1 ) ); - this->private_->output_grid_trans_.set_ny( static_cast< size_t >( + this->private_->output_grid_trans_.set_ny( static_cast< size_t >( this->private_->end_y_ - this->private_->start_y_ + 1 ) ); - this->private_->output_grid_trans_.set_nz( static_cast< size_t >( + this->private_->output_grid_trans_.set_nz( static_cast< size_t >( this->private_->end_z_ - this->private_->start_z_ + 1 ) ); this->private_->output_grid_trans_.set_originally_node_centered( grid_trans.get_originally_node_centered() ); @@ -425,7 +431,7 @@ bool ActionCrop::validate( Core::ActionContextHandle& context ) return true; } -bool ActionCrop::run( Core::ActionContextHandle& context, +bool ActionCrop::run( Core::ActionContextHandle& context, Core::ActionResultHandle& result ) { // Create algorithm @@ -462,7 +468,7 @@ bool ActionCrop::run( Core::ActionContextHandle& context, switch ( algo->src_layers_[ i ]->get_type() ) { case Core::VolumeType::DATA_E: - algo->create_and_lock_data_layer( this->private_->output_grid_trans_, + algo->create_and_lock_data_layer( this->private_->output_grid_trans_, algo->src_layers_[ i ], algo->dst_layers_[ i ] ); break; case Core::VolumeType::MASK_E: @@ -480,7 +486,7 @@ bool ActionCrop::run( Core::ActionContextHandle& context, } dst_layer_ids[ i ] = algo->dst_layers_[ i ]->get_layer_id(); } - + // Return the ids of the destination layer. result = Core::ActionResultHandle( new Core::ActionResult( dst_layer_ids ) ); // If the action is run from a script (provenance is a special case of script), @@ -500,9 +506,9 @@ bool ActionCrop::run( Core::ActionContextHandle& context, return true; } -void ActionCrop::Dispatch( Core::ActionContextHandle context, - const std::vector< std::string >& layer_ids, - const Core::Point& origin, +void ActionCrop::Dispatch( Core::ActionContextHandle context, + const std::vector< std::string >& layer_ids, + const Core::Point& origin, const Core::Vector& size, bool replace ) { ActionCrop* action = new ActionCrop; diff --git a/src/Application/Filters/Actions/ActionInvert.cc b/src/Application/Filters/Actions/ActionInvert.cc index a18aaf626..eb2302e67 100644 --- a/src/Application/Filters/Actions/ActionInvert.cc +++ b/src/Application/Filters/Actions/ActionInvert.cc @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -61,7 +61,7 @@ class InvertFilterAlgo : public LayerFilter { Core::DataBlockHandle dst_data_block = Core::StdDataBlock::New( dst->get_grid_transform(), src->get_data_type() ); - if ( !dst_data_block ) + if ( !dst_data_block ) { this->report_error( "Could not allocate enough memory." ); return; @@ -78,7 +78,7 @@ class InvertFilterAlgo : public LayerFilter T min_val = static_cast< T >( src->get_min() ); T max_val = static_cast< T >( src->get_max() ); T bias = max_val + min_val; - + size_t index = 0; for ( size_t z = 0; z < nz; ++z ) { @@ -103,7 +103,7 @@ class InvertFilterAlgo : public LayerFilter } this->dispatch_insert_data_volume_into_layer( dst, - Core::DataVolumeHandle( new Core::DataVolume( + Core::DataVolumeHandle( new Core::DataVolume( dst->get_grid_transform(), dst_data_block ) ), true ); } @@ -120,7 +120,7 @@ class InvertFilterAlgo : public LayerFilter this->report_error( "Could not allocate enough memory." ); return; } - + Core::MaskDataBlock::shared_lock_type lock( mask_datablock->get_mutex() ); unsigned char* dst_data = reinterpret_cast< unsigned char* >( output_datablock->get_data() ); size_t z_plane_size = mask_datablock->get_nx() * mask_datablock->get_ny(); @@ -147,15 +147,15 @@ class InvertFilterAlgo : public LayerFilter lock.unlock(); Core::MaskDataBlockHandle output_mask; - Core::MaskDataBlockManager::Convert( output_datablock, + Core::MaskDataBlockManager::Convert( output_datablock, output->get_grid_transform(), output_mask ); if ( !output_mask ) { this->report_error( "Could not allocate enough memory." ); return; } - - this->dispatch_insert_mask_volume_into_layer( output, Core::MaskVolumeHandle( + + this->dispatch_insert_mask_volume_into_layer( output, Core::MaskVolumeHandle( new Core::MaskVolume( output->get_grid_transform(), output_mask ) ) ); } @@ -183,6 +183,12 @@ class InvertFilterAlgo : public LayerFilter case Core::DataType::UINT_E: this->invert_data< unsigned int >( src_data_block, output ); break; + case Core::DataType::LONGLONG_E: + this->invert_data< long long >( src_data_block, output ); + break; + case Core::DataType::ULONGLONG_E: + this->invert_data< unsigned long long >( src_data_block, output ); + break; case Core::DataType::FLOAT_E: this->invert_data< float >( src_data_block, output ); break; @@ -193,7 +199,7 @@ class InvertFilterAlgo : public LayerFilter } // RUN_FILTER: - // Implementation of run of the Runnable base class, this function is called + // Implementation of run of the Runnable base class, this function is called // when the thread is launched. virtual void run_filter() { @@ -209,7 +215,7 @@ class InvertFilterAlgo : public LayerFilter break; } } - + // GET_FITLER_NAME: // The name of the filter, this information is used for generating new layer labels. virtual std::string get_filter_name() const @@ -218,11 +224,11 @@ class InvertFilterAlgo : public LayerFilter } // GET_LAYER_PREFIX: - // This function returns the name of the filter. The latter is prepended to the new layer name, - // when a new layer is generated. + // This function returns the name of the filter. The latter is prepended to the new layer name, + // when a new layer is generated. virtual std::string get_layer_prefix() const { - return "Invert"; + return "Invert"; } }; @@ -234,22 +240,22 @@ bool ActionInvert::validate( Core::ActionContextHandle& context ) // Check for layer existence and type information if ( ! LayerManager::CheckLayerExistence( this->layer_id_, context, this->sandbox_ ) ) return false; - // Check for layer availability - if ( ! LayerManager::CheckLayerAvailability( this->layer_id_, + // Check for layer availability + if ( ! LayerManager::CheckLayerAvailability( this->layer_id_, this->replace_, context, this->sandbox_ ) ) return false; // Validation successful return true; } -bool ActionInvert::run( Core::ActionContextHandle& context, +bool ActionInvert::run( Core::ActionContextHandle& context, Core::ActionResultHandle& result ) { // Create algorithm boost::shared_ptr< InvertFilterAlgo > algo( new InvertFilterAlgo ); algo->set_sandbox( this->sandbox_ ); - // Find the handle to the layer + // Find the handle to the layer if ( !( algo->find_layer( this->layer_id_, algo->src_layer_ ) ) ) { return false; @@ -260,13 +266,13 @@ bool ActionInvert::run( Core::ActionContextHandle& context, // Copy the handles as destination and source will be the same algo->dst_layer_ = algo->src_layer_; // Mark the layer for processing. - algo->lock_for_processing( algo->dst_layer_ ); + algo->lock_for_processing( algo->dst_layer_ ); } else { // Lock the src layer, so it cannot be used else where algo->lock_for_use( algo->src_layer_ ); - + // Create the destination layer, which will show progress switch ( algo->src_layer_->get_type() ) { @@ -284,7 +290,7 @@ bool ActionInvert::run( Core::ActionContextHandle& context, algo->connect_abort( algo->dst_layer_ ); // Return the id of the destination layer. - result = Core::ActionResultHandle( new Core::ActionResult( + result = Core::ActionResultHandle( new Core::ActionResult( algo->dst_layer_->get_layer_id() ) ); // If the action is run from a script (provenance is a special case of script), // return a notifier that the script engine can wait on. @@ -296,7 +302,7 @@ bool ActionInvert::run( Core::ActionContextHandle& context, // Build the undo-redo record algo->create_undo_redo_and_provenance_record( context, this->shared_from_this() ); - + // Start the filter. Core::Runnable::Start( algo ); @@ -304,9 +310,9 @@ bool ActionInvert::run( Core::ActionContextHandle& context, } -void ActionInvert::Dispatch( Core::ActionContextHandle context, +void ActionInvert::Dispatch( Core::ActionContextHandle context, std::string layer_id, bool replace ) -{ +{ // Create a new action ActionInvert* action = new ActionInvert; @@ -317,5 +323,5 @@ void ActionInvert::Dispatch( Core::ActionContextHandle context, // Dispatch action to underlying engine Core::ActionDispatcher::PostAction( Core::ActionHandle( action ), context ); } - + } // end namespace Seg3D diff --git a/src/Application/Filters/Actions/ActionNeighborhoodConnectedFilter.cc b/src/Application/Filters/Actions/ActionNeighborhoodConnectedFilter.cc index 785688370..47b3e7702 100644 --- a/src/Application/Filters/Actions/ActionNeighborhoodConnectedFilter.cc +++ b/src/Application/Filters/Actions/ActionNeighborhoodConnectedFilter.cc @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -54,11 +54,11 @@ bool ActionNeighborhoodConnectedFilter::validate( Core::ActionContextHandle& con if ( !LayerManager::CheckSandboxExistence( this->sandbox_, context ) ) return false; // Check for layer existence and type information - if ( ! LayerManager::CheckLayerExistenceAndType( this->target_layer_, + if ( ! LayerManager::CheckLayerExistenceAndType( this->target_layer_, Core::VolumeType::DATA_E, context, this->sandbox_ ) ) return false; - - // Check for layer availability - if ( ! LayerManager::CheckLayerAvailabilityForProcessing( this->target_layer_, + + // Check for layer availability + if ( ! LayerManager::CheckLayerAvailabilityForProcessing( this->target_layer_, context, this->sandbox_ ) ) return false; if ( this->seeds_.size() == 0 ) @@ -66,7 +66,7 @@ bool ActionNeighborhoodConnectedFilter::validate( Core::ActionContextHandle& con context->report_error( "There needs to be at least one seed point." ); return false; } - + // Validation successful return true; } @@ -84,7 +84,7 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter LayerHandle dst_layer_; std::vector< std::vector< int > > seeds_; - + public: template< class T > void typed_run( Core::DataBlock* src ) @@ -92,13 +92,13 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter const T* src_data = reinterpret_cast< T* >( src->get_data() ); // Allocate the data block for storing the results - Core::DataBlockHandle dst_mask = Core::StdDataBlock::New( + Core::DataBlockHandle dst_mask = Core::StdDataBlock::New( this->src_layer_->get_grid_transform(), Core::DataType::UCHAR_E ); if ( !dst_mask ) { this->report_error( "Could not allocate enough memory." ); - return; + return; } // Get the dimensions @@ -128,7 +128,7 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter max_val = Core::Max( max_val, value ); seeds.push( seed ); } - + std::vector< int > neighbor_index( 3 ); size_t visited_voxels = seeds.size(); size_t last_report_voxels = visited_voxels; @@ -147,7 +147,7 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter { neighbor_index[ i ] -= 1; size_t offset = src->to_index( static_cast< size_t >( neighbor_index[ 0 ] ), - static_cast< size_t >( neighbor_index[ 1 ] ), + static_cast< size_t >( neighbor_index[ 1 ] ), static_cast< size_t >( neighbor_index[ 2 ] ) ); if ( dst_data[ offset ] != 1 && src_data[ offset ] >= min_val && @@ -158,13 +158,13 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter } ++visited_voxels; } - + neighbor_index = seed_index; if ( neighbor_index[ i ] < dimensions[ i ] - 1 ) { neighbor_index[ i ] += 1; size_t offset = src->to_index( static_cast< size_t >( neighbor_index[ 0 ] ), - static_cast< size_t >( neighbor_index[ 1 ] ), + static_cast< size_t >( neighbor_index[ 1 ] ), static_cast< size_t >( neighbor_index[ 2 ] ) ); if ( dst_data[ offset ] != 1 && src_data[ offset ] >= min_val && @@ -180,7 +180,7 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter if ( visited_voxels - last_report_voxels > progress_threshold ) { if ( this->check_abort() ) return; - + this->dst_layer_->update_progress_signal_( visited_voxels * 0.8 / total_voxels ); last_report_voxels = visited_voxels; } @@ -190,22 +190,22 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter { return; } - + this->dst_layer_->update_progress_signal_( 0.8 ); Core::MaskDataBlockHandle mask_datablock; - if ( !( Core::MaskDataBlockManager::Convert( dst_mask, + if ( !( Core::MaskDataBlockManager::Convert( dst_mask, this->dst_layer_->get_grid_transform(), mask_datablock ) ) ) { this->report_error( "Could not allocate enough memory." ); - return; + return; } - + this->dst_layer_->update_progress_signal_( 1.0 ); - + this->dispatch_insert_mask_volume_into_layer( this->dst_layer_, Core::MaskVolumeHandle( new Core::MaskVolume( this->dst_layer_->get_grid_transform(), mask_datablock ) ) ); - + } // RUN_FILTER: @@ -215,7 +215,7 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter { // Add the seeds to the filter, and compute the threshold values - Core::DataBlockHandle datablock = dynamic_cast< DataLayer* >( + Core::DataBlockHandle datablock = dynamic_cast< DataLayer* >( this->src_layer_.get() )->get_data_volume()->get_data_block(); switch ( datablock->get_data_type() ) @@ -238,15 +238,21 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter case Core::DataType::UINT_E: this->typed_run< unsigned int >( datablock.get() ); break; + case Core::DataType::LONGLONG_E: + this->typed_run< long long >( datablock.get() ); + break; + case Core::DataType::ULONGLONG_E: + this->typed_run< unsigned long long >( datablock.get() ); + break; case Core::DataType::FLOAT_E: this->typed_run< float >( datablock.get() ); break; case Core::DataType::DOUBLE_E: this->typed_run< double >( datablock.get() ); break; - } + } } - + // GET_FITLER_NAME: // The name of the filter, this information is used for generating new layer labels. virtual std::string get_filter_name() const @@ -255,16 +261,16 @@ class NeighborhoodConnectedFilterAlgo : public LayerFilter } // GET_LAYER_PREFIX: - // This function returns the name of the filter. The latter is prepended to the new layer name, - // when a new layer is generated. + // This function returns the name of the filter. The latter is prepended to the new layer name, + // when a new layer is generated. virtual std::string get_layer_prefix() const { - return "NeighborhoodConnected"; + return "NeighborhoodConnected"; } }; -bool ActionNeighborhoodConnectedFilter::run( Core::ActionContextHandle& context, +bool ActionNeighborhoodConnectedFilter::run( Core::ActionContextHandle& context, Core::ActionResultHandle& result ) { // Create algorithm @@ -305,18 +311,18 @@ bool ActionNeighborhoodConnectedFilter::run( Core::ActionContextHandle& context, catch ( ... ) { algo->report_error( "Could not allocate enough memory." ); - return false; + return false; } - + if ( algo->seeds_.size() == 0 ) { context->report_error( "All seed points are out of the volume boundary" ); return false; } - + // Lock the src layer, so it cannot be used else where algo->lock_for_use( algo->src_layer_ ); - + // Create the destination layer, which will show progress algo->create_and_lock_mask_layer_from_layer( algo->src_layer_, algo->dst_layer_ ); algo->connect_abort( algo->dst_layer_ ); @@ -333,16 +339,16 @@ bool ActionNeighborhoodConnectedFilter::run( Core::ActionContextHandle& context, // Build the undo-redo record algo->create_undo_redo_and_provenance_record( context, this->shared_from_this() ); - + // Start the filter on a separate thread. Core::Runnable::Start( algo ); return true; } -void ActionNeighborhoodConnectedFilter::Dispatch( Core::ActionContextHandle context, +void ActionNeighborhoodConnectedFilter::Dispatch( Core::ActionContextHandle context, std::string target_layer, const std::vector< Core::Point >& seeds ) -{ +{ // Create a new action ActionNeighborhoodConnectedFilter* action = new ActionNeighborhoodConnectedFilter; @@ -353,5 +359,5 @@ void ActionNeighborhoodConnectedFilter::Dispatch( Core::ActionContextHandle cont // Dispatch action to underlying engine Core::ActionDispatcher::PostAction( Core::ActionHandle( action ), context ); } - + } // end namespace Seg3D diff --git a/src/Application/Filters/Actions/ActionPointSetRegisterFilter.cc b/src/Application/Filters/Actions/ActionPointSetRegisterFilter.cc index 30c4f20f3..06cd87f0e 100644 --- a/src/Application/Filters/Actions/ActionPointSetRegisterFilter.cc +++ b/src/Application/Filters/Actions/ActionPointSetRegisterFilter.cc @@ -414,7 +414,7 @@ class PointSetFilterAlgo : public ITKFilter resampler->Update(); - if ( resampler->GetOutput() != NULL ) + if ( resampler->GetOutput() != nullptr ) { this->insert_itk_image_into_layer( this->dst_layer_, resampler->GetOutput() ); diff --git a/src/Application/Filters/Actions/ActionPointSetTransformFilter.cc b/src/Application/Filters/Actions/ActionPointSetTransformFilter.cc index 39ea215f4..999ee61c3 100644 --- a/src/Application/Filters/Actions/ActionPointSetTransformFilter.cc +++ b/src/Application/Filters/Actions/ActionPointSetTransformFilter.cc @@ -156,7 +156,7 @@ class PointSetTransformAlgo : public ITKFilter resampler->Update(); - if (resampler->GetOutput() != NULL) + if (resampler->GetOutput() != nullptr) { this->insert_itk_image_into_layer(dst_layer, resampler->GetOutput()); } diff --git a/src/Application/Filters/Actions/ActionTransform.cc b/src/Application/Filters/Actions/ActionTransform.cc index 79c3e79f4..1df9f897e 100644 --- a/src/Application/Filters/Actions/ActionTransform.cc +++ b/src/Application/Filters/Actions/ActionTransform.cc @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -82,7 +82,7 @@ class TransformAlgo : public LayerFilter void transform_mask_layer( MaskLayerHandle input, MaskLayerHandle output ); // RUN_FILTER: - // Implementation of run of the Runnable base class, this function is called + // Implementation of run of the Runnable base class, this function is called // when the thread is launched. virtual void run_filter(); @@ -94,8 +94,8 @@ class TransformAlgo : public LayerFilter } // GET_LAYER_PREFIX: - // This function returns the name of the filter. The latter is prepended to the new layer name, - // when a new layer is generated. + // This function returns the name of the filter. The latter is prepended to the new layer name, + // when a new layer is generated. virtual std::string get_layer_prefix() const { return "Transform"; @@ -131,7 +131,7 @@ void TransformAlgo::run_filter() void TransformAlgo::transform_data_layer( DataLayerHandle input, DataLayerHandle output ) { Core::DataBlockHandle input_datablock = input->get_data_volume()->get_data_block(); - Core::DataBlockHandle output_datablock = Core::StdDataBlock::New( + Core::DataBlockHandle output_datablock = Core::StdDataBlock::New( output->get_grid_transform(), input_datablock->get_data_type() ); const void* src_data = input_datablock->get_data(); @@ -153,6 +153,10 @@ void TransformAlgo::transform_data_layer( DataLayerHandle input, DataLayerHandle case Core::DataType::UINT_E: data_size = sizeof( int ); break; + case Core::DataType::LONGLONG_E: + case Core::DataType::ULONGLONG_E: + data_size = sizeof( long long ); + break; case Core::DataType::FLOAT_E: data_size = sizeof( float ); break; @@ -171,11 +175,11 @@ void TransformAlgo::transform_data_layer( DataLayerHandle input, DataLayerHandle { // Centering should be preserved for each layer Core::GridTransform output_grid_transform = output->get_grid_transform(); - output_grid_transform.set_originally_node_centered( + output_grid_transform.set_originally_node_centered( input->get_grid_transform().get_originally_node_centered() ); this->dispatch_insert_data_volume_into_layer( output, Core::DataVolumeHandle( - new Core::DataVolume( output_grid_transform, output_datablock ) ), + new Core::DataVolume( output_grid_transform, output_datablock ) ), true ); output->update_progress_signal_( 1.0 ); this->dispatch_unlock_layer( output ); @@ -256,7 +260,7 @@ bool ActionTransform::validate( Core::ActionContextHandle& context ) context->report_error( "No input layers specified" ); return false; } - + Core::GridTransform src_grid_trans; for ( size_t i = 0; i < layer_ids.size(); ++i ) { @@ -278,12 +282,12 @@ bool ActionTransform::validate( Core::ActionContextHandle& context ) context->report_error( "Input layers do not belong to the same group" ); return false; } - - // Check for layer availability - if ( !LayerManager::CheckLayerAvailability( layer_ids[ i ], + + // Check for layer availability + if ( !LayerManager::CheckLayerAvailability( layer_ids[ i ], this->private_->replace_, context, this->private_->sandbox_ ) ) return false; } - + const Core::Vector& spacing = this->private_->spacing_; if ( spacing[ 0 ] <= 0 || spacing[ 1 ] <= 0 || spacing[ 2 ] <= 0 ) { @@ -295,15 +299,15 @@ bool ActionTransform::validate( Core::ActionContextHandle& context ) this->private_->output_grid_trans_.set_nx( src_grid_trans.get_nx() ); this->private_->output_grid_trans_.set_ny( src_grid_trans.get_ny() ); this->private_->output_grid_trans_.set_nz( src_grid_trans.get_nz() ); - this->private_->output_grid_trans_.load_basis( this->private_->origin_, - Core::Vector( spacing[ 0 ], 0, 0 ), Core::Vector( 0, spacing[ 1 ], 0 ), + this->private_->output_grid_trans_.load_basis( this->private_->origin_, + Core::Vector( spacing[ 0 ], 0, 0 ), Core::Vector( 0, spacing[ 1 ], 0 ), Core::Vector( 0, 0, spacing[ 2 ] ) ); - + // Validation successful return true; } -bool ActionTransform::run( Core::ActionContextHandle& context, +bool ActionTransform::run( Core::ActionContextHandle& context, Core::ActionResultHandle& result ) { // Create algorithm @@ -332,9 +336,9 @@ bool ActionTransform::run( Core::ActionContextHandle& context, } switch ( algo->src_layers_[ i ]->get_type() ) - { + { case Core::VolumeType::DATA_E: - algo->create_and_lock_data_layer( this->private_->output_grid_trans_, + algo->create_and_lock_data_layer( this->private_->output_grid_trans_, algo->src_layers_[ i ], algo->dst_layers_[ i ] ); break; case Core::VolumeType::MASK_E: @@ -348,7 +352,7 @@ bool ActionTransform::run( Core::ActionContextHandle& context, } dst_layer_ids[ i ] = algo->dst_layers_[ i ]->get_layer_id(); } - + // Return the ids of the destination layer. result = Core::ActionResultHandle( new Core::ActionResult( dst_layer_ids ) ); // If the action is run from a script (provenance is a special case of script), @@ -368,8 +372,8 @@ bool ActionTransform::run( Core::ActionContextHandle& context, return true; } -void ActionTransform::Dispatch( Core::ActionContextHandle context, - const std::vector< std::string >& layer_ids, +void ActionTransform::Dispatch( Core::ActionContextHandle context, + const std::vector< std::string >& layer_ids, const Core::Point& origin, const Core::Vector& spacing, bool replace ) { diff --git a/src/Application/Filters/Actions/ActionWatershedFilter.cc b/src/Application/Filters/Actions/ActionWatershedFilter.cc index 368d8b80a..68e46256d 100644 --- a/src/Application/Filters/Actions/ActionWatershedFilter.cc +++ b/src/Application/Filters/Actions/ActionWatershedFilter.cc @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -25,19 +25,19 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - - + + + /* * Version 0.1 * 22 / 06 / 2016 - * + * * Uses ITK's Watershedding filter to segment 2D and 3D data layers. Never uses 0 as * a label so as to numerically discriminate from nonsegmented regions. - * + * * TODO: * - Speed up relabeling. I included timing in the console output (can be switched - * with the _ConsoleOuput define). See timing for low threshold/level values. + * with the _ConsoleOuput define). See timing for low threshold/level values. * Can be an extremely long wait; especially for 3D watersheds. * - Break segmentations into useful objects (masks, rgb, etc) it is currently * saved as a WtrLabelType label (see below register action). @@ -45,7 +45,7 @@ * is then outputted as a single grayscale layer. Simply implementing RGB data * types in Seg3D would significantly improve the variety of information conveyed * visually. I have mock code showing how easy it would be to do when Seg3D handles - * RGB data types. Note that a label (grayscale value) of 0 is never used. Similarly, + * RGB data types. Note that a label (grayscale value) of 0 is never used. Similarly, * a RGB value of (0, 0, 0) is never used in the mock code. This allows for a hook to * identify unsegmented regions. * ~ Masks would potentially enable quick sub-segmentation of undersegmented regions. @@ -92,7 +92,7 @@ static timestamp_t get_timestamp () { struct timeval now; - gettimeofday (&now, NULL); + gettimeofday (&now, nullptr); return now.tv_usec + (timestamp_t)now.tv_sec * 1000000; } #endif @@ -109,7 +109,7 @@ namespace Seg3D typedef double WtrLabelType; //WtrLabelType typedef WtrLabelType WtrPixelTypeOut; //WtrPixelTypeOut WtrLabelType // Should be the same typedef itk::Image< WtrPixelTypeOut, 3 > WtrImageTypeOut; //WtrImageTypeOut itk::Image< WtrPixelTypeOut, 3 > -typedef itk::Image< unsigned long int, 3 > WtrImageTypeFilter; //WtrImageTypeFilter itk::Image< unsigned long int, 3 > +typedef itk::Image< unsigned long int, 3 > WtrImageTypeFilter; //WtrImageTypeFilter itk::Image< unsigned long int, 3 > bool ActionWatershedFilter::validate( Core::ActionContextHandle& context ) { @@ -117,10 +117,10 @@ bool ActionWatershedFilter::validate( Core::ActionContextHandle& context ) if ( !LayerManager::CheckSandboxExistence( this->sandbox_, context ) ) return false; // Check for layer existence and type information - if ( ! LayerManager::CheckLayerExistenceAndType( this->target_layer_, + if ( ! LayerManager::CheckLayerExistenceAndType( this->target_layer_, Core::VolumeType::DATA_E, context, this->sandbox_ ) ) return false; - // Check for layer availability + // Check for layer availability if ( ! LayerManager::CheckLayerAvailabilityForProcessing( this->target_layer_, context, this->sandbox_ ) ) return false; // make sure parameters are valid @@ -151,7 +151,7 @@ class WatershedFilterAlgo : public ITKFilter LayerHandle src_layer_; //std::vector dst_layer_; LayerHandle dst_layer_; - + double watershedThreshold_val_; double watershedLevel_val_; @@ -159,7 +159,7 @@ class WatershedFilterAlgo : public ITKFilter std::vector watershed_image_output_labels_; public: - + // RUN: // Implemtation of run of the Runnable base class, this function is called when the thread // is launched. @@ -169,36 +169,36 @@ class WatershedFilterAlgo : public ITKFilter SCI_BEGIN_TYPED_ITK_RUN( this->src_layer_->get_data_type() ) { CORE_LOG_DEBUG( this->get_filter_name() + ": Initializing watershedding filter..." ); - + // Define the type of filter that we use. typedef itk::WatershedImageFilter< TYPED_IMAGE_TYPE > filter_type; - + // Retrieve the image as an itk image from the underlying data structure // NOTE: This only does wrapping and does not regenerate the data. - typename Core::ITKImageDataT::Handle input_image; + typename Core::ITKImageDataT::Handle input_image; this->get_itk_image_from_layer( this->src_layer_, input_image ); - - // Create a new ITK filter instantiation. + + // Create a new ITK filter instantiation. typename filter_type::Pointer filter = filter_type::New(); - + // Relay abort and progress information to the layer that is executing the filter. this->forward_abort_to_filter( filter, this->dst_layer_ ); this->observe_itk_progress( filter, this->dst_layer_ ); - + filter->SetLevel( this->watershedLevel_val_ ); filter->SetThreshold( this->watershedThreshold_val_ ); filter->SetInput( input_image->get_image() ); - + // Ensure we will have some threads left for doing something else this->limit_number_of_itk_threads( filter ); - + // Run the actual ITK filter. // This needs to be in a try/catch statement as certain filters throw exceptions when they // are aborted. In that case we will relay a message to the status bar for information. CORE_LOG_DEBUG( this->get_filter_name() + ": Updating watershedding filter..." ); - try{ - filter->Update(); - } + try{ + filter->Update(); + } catch ( ... ){ if ( this->check_abort() ) { @@ -206,19 +206,19 @@ class WatershedFilterAlgo : public ITKFilter return; } this->report_error( "ITK filter failed to complete." ); - return; + return; } - + // As ITK filters generate an inconsistent abort behavior, we record our own abort flag // This one is set when the abort button is pressed and an abort is sent to ITK. if ( this->check_abort() ) return; - + CORE_LOG_DEBUG( this->get_filter_name() + ": Casting filter to output type..." ); - typedef itk::CastImageFilter< WtrImageTypeFilter, WtrImageTypeOut > CastImageFilter_FilterToOut; - CastImageFilter_FilterToOut::Pointer castImage_FilterToOut = CastImageFilter_FilterToOut::New(); + typedef itk::CastImageFilter< typename itk::WatershedImageFilter< TYPED_IMAGE_TYPE >::OutputImageType, WtrImageTypeOut > CastImageFilter_FilterToOut; + typename CastImageFilter_FilterToOut::Pointer castImage_FilterToOut = CastImageFilter_FilterToOut::New(); castImage_FilterToOut->SetInput( filter->GetOutput() ); castImage_FilterToOut->Update(); - + CORE_LOG_DEBUG( this->get_filter_name() + ": Reading in all labels (extreme patience required)..." ); #if defined (ENABLE_TIMING) timestamp_t t0 = get_timestamp(); @@ -239,13 +239,13 @@ class WatershedFilterAlgo : public ITKFilter #if defined (ENABLE_TIMING) timestamp_t t1 = get_timestamp(); double secs = (t1 - t0) / 1000000.0L; - + std::ostringstream oss_msg; oss_msg << "\t" << iterCount << " iterations for " << this->watershed_image_output_labels_.size() << " labels in " << secs << " seconds."; CORE_LOG_DEBUG( oss_msg.str() ); #endif CORE_LOG_DEBUG( this->get_filter_name() + ": Creating new labels..." ); - + std::vector< WtrLabelType > new_labels; // Could be an issue if the size of watershed_image_ouput_labels is larger than unsigned int can handle. Doubt it, but still... for( unsigned int n=1; n<=this->watershed_image_output_labels_.size(); n++ ){ @@ -256,20 +256,20 @@ class WatershedFilterAlgo : public ITKFilter * to see a (probably) better way to convert the watershed output to an RGB image. Specifically look * to the code following itk::Functor::ScalarToRGBPixelFunctor ColorMapFunctorType; * Needs random library. Random code from http://stackoverflow.com/a/19728404 - * + * * --[CODE]-- * #include - * + * * typedef itk::RGBPixel< WtrLabelType > RGBPixelType; * typedef itk::Image< RGBPixelType, 3 > RGBImageType; - * + * * std::vector< RGBPixelType > watershed_image_ouput_rgb_labels; // As a member of WatershedFilterAlgo class - * + * * typedef itk::CastImageFilter< WtrImageTypeOut, RGBImageType > CastImageFilter_OutToRGB; // Would be more efficient to make RGB the Out - * CastImageFilter_OutToRGB::Pointer castImage_OutToRGB = CastImageFilter_OutToRGB::New(); + * typename CastImageFilter_OutToRGB::Pointer castImage_OutToRGB = CastImageFilter_OutToRGB::New(); * castImage_OutToRGB->SetInput( castImage_FilterToOut->GetOutput() ); * castImage_OutToRGB->Update(); - * + * * std::random_device rd; // only used once to initialise (seed) engine * std::mt19937 rng(rd()); // random-number engine used (Mersenne-Twister in this case) * std::uniform_int_distribution uni(1,255); // guaranteed unbiased. 1 - 255 with 0 left for non segmented regions @@ -283,8 +283,8 @@ class WatershedFilterAlgo : public ITKFilter * tmpRGB[2] = uni(rng); * check=true; * for( int j=0; jwatershed_image_ouput_rgb_labels[j][0]) && - * (tmpRGB[1] == this->watershed_image_ouput_rgb_labels[j][1]) && + * if( (tmpRGB[0] == this->watershed_image_ouput_rgb_labels[j][0]) && + * (tmpRGB[1] == this->watershed_image_ouput_rgb_labels[j][1]) && * (tmpRGB[2] == this->watershed_image_ouput_rgb_labels[j][2]) ){ // if already used * check = false; * break; @@ -294,38 +294,38 @@ class WatershedFilterAlgo : public ITKFilter * this->watershed_image_ouput_rgb_labels.push_back( tmpRGB ); * } * --[END CODE]-- - * + * * Note that random_shuffle and mapping code would no longer be needed. * The wtrImg_iter.Set code needs to be modified use to a RGB ImageRegionIterator * on the castImage_OutToRGB image object in order to use the rgb labels. Also, * make sure to insert the rgb image into the layer - */ - + */ + CORE_LOG_DEBUG( this->get_filter_name() + ": Shuffling new labels..." ); random_shuffle( new_labels.begin(), new_labels.end() ); - + CORE_LOG_DEBUG( this->get_filter_name() + ": Mapping old labels to new..." ); std::map< WtrLabelType, WtrLabelType > label_map; for( unsigned int i=0; iwatershed_image_output_labels_.size(); i++ ){ label_map[ this->watershed_image_output_labels_[i] ] = new_labels[i]; } - + CORE_LOG_DEBUG( this->get_filter_name() + ": Setting new labels..." ); for( wtrImg_iter.GoToBegin(); !wtrImg_iter.IsAtEnd(); ++wtrImg_iter ) { wtrImg_iter.Set( label_map[ wtrImg_iter.Get() ] ); } - + CORE_LOG_DEBUG( this->get_filter_name() + ": Linking new labels..." ); this->watershed_image_output_labels_ = new_labels; - + CORE_LOG_DEBUG( this->get_filter_name() + ": Inserting output into layer..." ); this->insert_itk_image_into_layer( this->dst_layer_, castImage_FilterToOut->GetOutput() ); - + CORE_LOG_DEBUG( this->get_filter_name() + ": Finished.\n" ); } SCI_END_TYPED_ITK_RUN() - + // GET_FITLER_NAME: // The name of the filter, this information is used for generating new layer labels. virtual std::string get_filter_name() const @@ -343,7 +343,7 @@ class WatershedFilterAlgo : public ITKFilter }; -bool ActionWatershedFilter::run( Core::ActionContextHandle& context, +bool ActionWatershedFilter::run( Core::ActionContextHandle& context, Core::ActionResultHandle& result ) { // Create algorithm @@ -357,7 +357,7 @@ bool ActionWatershedFilter::run( Core::ActionContextHandle& context, // Find the handle to the layer if ( !( algo->find_layer( this->target_layer_, algo->src_layer_ ) ) ) { - return false; + return false; } // Lock the src layer, so it cannot be used else where @@ -388,7 +388,7 @@ bool ActionWatershedFilter::run( Core::ActionContextHandle& context, void ActionWatershedFilter::Dispatch( Core::ActionContextHandle context, std::string target_layer, double watershedThreshold_val, double watershedLevel_val ) -{ +{ // Create a new action ActionWatershedFilter* action = new ActionWatershedFilter; diff --git a/src/Application/Filters/ITKFilter.cc b/src/Application/Filters/ITKFilter.cc index 0d7f9292b..a90eb375e 100644 --- a/src/Application/Filters/ITKFilter.cc +++ b/src/Application/Filters/ITKFilter.cc @@ -243,7 +243,7 @@ void ITKFilter::limit_number_of_itk_threads_internal( itk::ProcessObject::Pointe unsigned int max_threads = boost::thread::hardware_concurrency(); if ( max_threads < 2 ) max_threads = 2; - filter->GetMultiThreader()->SetNumberOfThreads( max_threads - 1 ); + filter->GetMultiThreader()->SetMaximumNumberOfThreads( max_threads - 1 ); } } // end namespace Core diff --git a/src/Application/Filters/ITKFilter.h b/src/Application/Filters/ITKFilter.h index aa5f689ee..4529bf0fd 100644 --- a/src/Application/Filters/ITKFilter.h +++ b/src/Application/Filters/ITKFilter.h @@ -25,15 +25,15 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef APPLICATION_FILTERS_ITKFILTER_H + +#ifndef APPLICATION_FILTERS_ITKFILTER_H #define APPLICATION_FILTERS_ITKFILTER_H - + // Boost includes #include -#include -#include - +#include +#include + // Core includes #include #include @@ -41,12 +41,12 @@ #include #include #include - + // Application includes -#include -#include +#include +#include #include - + namespace Seg3D { @@ -63,21 +63,23 @@ class ITKFilter : public LayerFilter typedef itk::Image< unsigned int, 3> UINT_IMAGE_TYPE; typedef itk::Image< float, 3> FLOAT_IMAGE_TYPE; typedef itk::Image< unsigned char, 3> UCHAR_IMAGE_TYPE; + typedef itk::Image< unsigned long long, 3> ULONGLONG_IMAGE_TYPE; typedef Core::ITKImageDataT FLOAT_CONTAINER_TYPE; typedef Core::ITKImageDataT UINT_CONTAINER_TYPE; typedef Core::ITKImageDataT USHORT_CONTAINER_TYPE; typedef Core::ITKImageDataT UCHAR_CONTAINER_TYPE; + typedef Core::ITKImageDataT ULONGLONG_CONTAINER_TYPE; public: ITKFilter(); virtual ~ITKFilter(); - + protected: /// GET_ITK_IMAGE_FROM_LAYER: /// Retrieve an itk image from a data or mask layer template - bool get_itk_image_from_layer( const LayerHandle& layer, + bool get_itk_image_from_layer( const LayerHandle& layer, typename Core::ITKImageDataT::Handle& image, bool invert = false ) { // Clear the handle @@ -85,13 +87,13 @@ class ITKFilter : public LayerFilter Core::DataBlockHandle data_block; Core::Transform transform; - + // If the layer is a data layer if ( layer->get_type() == Core::VolumeType::DATA_E ) { DataLayerHandle data = boost::dynamic_pointer_cast( layer ); Core::DataVolumeHandle volume = data->get_data_volume(); - + // If the data is in the right format: do not convert the data, just copy the // data block pointer if ( volume->get_data_type() == Core::GetDataType( reinterpret_cast( 0 ) ) ) @@ -102,14 +104,14 @@ class ITKFilter : public LayerFilter { // TODO: In future we may want to add quantization here --JS // Data is not in requested format, hence we need to cast the data - if ( ! ( Core::DataBlock::ConvertDataType( volume->get_data_block(), + if ( ! ( Core::DataBlock::ConvertDataType( volume->get_data_block(), data_block, Core::GetDataType( reinterpret_cast( 0 ) ) ) ) ) { this->report_error( "Could not allocate enough memory." ); return false; } } - + transform = volume->get_transform(); } // If the layer is a mask layer @@ -120,12 +122,12 @@ class ITKFilter : public LayerFilter // We always need to convert the data, ITK does not support the compressed way of // dealing with bitplanes - if ( ! ( Core::MaskDataBlockManager::Convert( volume->get_mask_data_block(), + if ( ! ( Core::MaskDataBlockManager::Convert( volume->get_mask_data_block(), data_block, Core::GetDataType( reinterpret_cast( 0 ) ), invert ) ) ) { this->report_error( "Could not allocate enough memory." ); return false; - } + } transform = volume->get_transform(); } else @@ -135,15 +137,15 @@ class ITKFilter : public LayerFilter } // Create a new ITK Image wrapper - image = typename Core::ITKImageDataT::Handle( + image = typename Core::ITKImageDataT::Handle( new Core::ITKImageDataT( data_block, transform ) ); - + if ( !image ) { this->report_error( "Could not allocate enough memory." ); return false; } - + // Success return true; } @@ -152,7 +154,7 @@ class ITKFilter : public LayerFilter /// GET_ITK_IMAGE_FROM_MASK_LAYER: /// Retrieve an itk image from a data or mask layer template - bool get_itk_image_from_mask_layer( const LayerHandle& layer, + bool get_itk_image_from_mask_layer( const LayerHandle& layer, typename Core::ITKImageDataT::Handle& image, double label = 1.0 ) { // Clear the handle @@ -160,8 +162,8 @@ class ITKFilter : public LayerFilter Core::DataBlockHandle data_block; Core::Transform transform; - - + + // If the layer is a mask layer if ( layer->get_type() != Core::VolumeType::MASK_E ) { @@ -173,25 +175,25 @@ class ITKFilter : public LayerFilter // We always need to convert the data, ITK does not support the compressed way of // dealing with bitplanes - if ( ! ( Core::MaskDataBlockManager::ConvertLabel( volume->get_mask_data_block(), + if ( ! ( Core::MaskDataBlockManager::ConvertLabel( volume->get_mask_data_block(), data_block, Core::GetDataType( reinterpret_cast( 0 ) ), label ) ) ) { this->report_error( "Could not allocate enough memory." ); return false; } - + transform = volume->get_transform(); // Create a new ITK Image wrapper - image = typename Core::ITKImageDataT::Handle( + image = typename Core::ITKImageDataT::Handle( new Core::ITKImageDataT( data_block, transform ) ); - + if ( !image ) { this->report_error( "Could not allocate enough memory." ); return false; } - + // Success return true; } @@ -200,7 +202,7 @@ class ITKFilter : public LayerFilter /// INSERT_ITK_IMAGE_INTO_LAYER: /// Insert an itk image back into a layer template< class T > - bool insert_itk_image_into_layer( const LayerHandle& layer, + bool insert_itk_image_into_layer( const LayerHandle& layer, typename itk::Image* itk_image ) { typename itk::Image::Pointer pointer = itk_image; @@ -210,20 +212,20 @@ class ITKFilter : public LayerFilter /// INSERT_ITK_IMAGE_POINTER_INTO_LAYER: /// Insert an itk image back into a layer template< class T > - bool insert_itk_image_pointer_into_layer( const LayerHandle& layer, + bool insert_itk_image_pointer_into_layer( const LayerHandle& layer, typename itk::Image::Pointer itk_image ) { - + // If the layer is a data layer if ( layer->get_type() == Core::VolumeType::DATA_E ) { DataLayerHandle data_layer = boost::dynamic_pointer_cast( layer ); // Wrap an ITKImageData object around the itk object - Core::DataVolumeHandle data_volume( new Core::DataVolume( + Core::DataVolumeHandle data_volume( new Core::DataVolume( data_layer->get_grid_transform(), Core::ITKDataBlock::New( itk_image ) ) ); - - // NOTE: Do not need an update of the generation number as this volume + + // NOTE: Do not need an update of the generation number as this volume // was generated from scratch. But it will need a new histogram this->dispatch_insert_data_volume_into_layer( data_layer, data_volume, true ); return true; @@ -232,29 +234,29 @@ class ITKFilter : public LayerFilter else if ( layer->get_type() == Core::VolumeType::MASK_E ) { MaskLayerHandle mask_layer = boost::dynamic_pointer_cast( layer ); - + // Need to make an intermediate representation as a datablock of the data // before it can be uploaded into the mask. // NOTE: This only generates a wrapper, no new data is generated - Core::DataBlockHandle data_block = Core::ITKDataBlock::New( + Core::DataBlockHandle data_block = Core::ITKDataBlock::New( typename itk::Image::Pointer( itk_image ) ); - + // NOTE: The only reason we need the transform here, is that data blocks are // sorted by grid transform so we can use the nrrd library to save them, the // latter only allows storing one transform per data block, and since 8 masks // share one datablock, they are required for now to have the same transform. Core::MaskDataBlockHandle mask; - if (!( Core::MaskDataBlockManager::Convert( data_block, + if (!( Core::MaskDataBlockManager::Convert( data_block, mask_layer->get_grid_transform(), mask ) ) ) { this->report_error( "Could not allocate enough memory." ); return false; } - - Core::MaskVolumeHandle mask_volume( new Core::MaskVolume( + + Core::MaskVolumeHandle mask_volume( new Core::MaskVolume( mask_layer->get_grid_transform(), mask ) ); - + this->dispatch_insert_mask_volume_into_layer( mask_layer, mask_volume ); return true; } @@ -266,7 +268,7 @@ class ITKFilter : public LayerFilter /// INSERT_ITK_POSITIVE_LABELS_INTO_MASK_LAYER: /// Insert an itk image back into a layer template< class T > - bool insert_itk_positive_labels_into_mask_layer( const LayerHandle& layer, + bool insert_itk_positive_labels_into_mask_layer( const LayerHandle& layer, typename itk::Image* itk_image, bool invert = false ) { typename itk::Image::Pointer pointer = itk_image; @@ -276,34 +278,34 @@ class ITKFilter : public LayerFilter /// INSERT_ITK_POSITIVE_LABELS_POINTER_INTO_MASK_LAYER: /// Insert an itk image back into a layer template< class T > - bool insert_itk_positive_labels_pointer_into_mask_layer( const LayerHandle& layer, + bool insert_itk_positive_labels_pointer_into_mask_layer( const LayerHandle& layer, typename itk::Image::Pointer itk_image, bool invert = false ) { if ( layer->get_type() == Core::VolumeType::MASK_E ) { MaskLayerHandle mask_layer = boost::dynamic_pointer_cast( layer ); - + // Need to make an intermediate representation as a datablock of the data // before it can be uploaded into the mask. // NOTE: This only generates a wrapper, no new data is generated Core::DataBlockHandle data_block = Core::ITKDataBlock::New( itk_image ); - + // NOTE: The only reason we need the transform here, is that data blocks are // sorted by grid transform so we can use the nrrd library to save them, the // latter only allows storing one transform per data block, and since 8 masks // share one datablock, they are required for now to have the same transform. Core::MaskDataBlockHandle mask; - if (!( Core::MaskDataBlockManager::ConvertLargerThan( data_block, + if (!( Core::MaskDataBlockManager::ConvertLargerThan( data_block, mask_layer->get_grid_transform(), mask, invert ) ) ) { this->report_error( "Could not allocate enough memory." ); return false; } - - Core::MaskVolumeHandle mask_volume( new Core::MaskVolume( + + Core::MaskVolumeHandle mask_volume( new Core::MaskVolume( mask_layer->get_grid_transform(), mask ) ); - + this->dispatch_insert_mask_volume_into_layer( mask_layer, mask_volume ); return true; } @@ -314,7 +316,7 @@ class ITKFilter : public LayerFilter /// INSERT_ITK_LABEL_INTO_MASK_LAYER: /// Insert an itk image back into a layer template< class T > - bool insert_itk_label_into_mask_layer( const LayerHandle& layer, + bool insert_itk_label_into_mask_layer( const LayerHandle& layer, typename itk::Image* itk_image, T label ) { typename itk::Image::Pointer pointer = itk_image; @@ -324,34 +326,34 @@ class ITKFilter : public LayerFilter /// INSERT_ITK_LABEL_POINTER_INTO_MASK_LAYER: /// Insert an itk image back into a layer template< class T > - bool insert_itk_label_pointer_into_mask_layer( const LayerHandle& layer, + bool insert_itk_label_pointer_into_mask_layer( const LayerHandle& layer, typename itk::Image::Pointer itk_image, T label ) { if ( layer->get_type() == Core::VolumeType::MASK_E ) { MaskLayerHandle mask_layer = boost::dynamic_pointer_cast( layer ); - + // Need to make an intermediate representation as a datablock of the data // before it can be uploaded into the mask. // NOTE: This only generates a wrapper, no new data is generated Core::DataBlockHandle data_block = Core::ITKDataBlock::New( itk_image ); - + // NOTE: The only reason we need the transform here, is that data blocks are // sorted by grid transform so we can use the nrrd library to save them, the // latter only allows storing one transform per data block, and since 8 masks // share one datablock, they are required for now to have the same transform. Core::MaskDataBlockHandle mask; - if (!( Core::MaskDataBlockManager::ConvertLabel( data_block, + if (!( Core::MaskDataBlockManager::ConvertLabel( data_block, mask_layer->get_grid_transform(), mask, static_cast( label ) ) ) ) { this->report_error( "Could not allocate enough memory." ); return false; } - - Core::MaskVolumeHandle mask_volume( new Core::MaskVolume( + + Core::MaskVolumeHandle mask_volume( new Core::MaskVolume( mask_layer->get_grid_transform(), mask ) ); - + this->dispatch_insert_mask_volume_into_layer( mask_layer, mask_volume ); return true; } @@ -361,21 +363,21 @@ class ITKFilter : public LayerFilter /// CONVERT_AND_INSERT_ITK_IMAGE_INTO_LAYER: /// Insert an itk image back into a layer template< class T > - bool convert_and_insert_itk_image_into_layer( const LayerHandle& layer, + bool convert_and_insert_itk_image_into_layer( const LayerHandle& layer, typename itk::Image* itk_image, Core::DataType data_type ) { typename itk::Image::Pointer pointer = itk_image; - return convert_and_insert_itk_image_pointer_into_layer( layer, + return convert_and_insert_itk_image_pointer_into_layer( layer, pointer, data_type ); } /// CONVERT_AND_INSERT_ITK_IMAGE_POINTER_INTO_LAYER: /// Insert an itk image back into a layer template< class T > - bool convert_and_insert_itk_image_pointer_into_layer( const LayerHandle& layer, + bool convert_and_insert_itk_image_pointer_into_layer( const LayerHandle& layer, typename itk::Image::Pointer itk_image, Core::DataType data_type ) { - + // If the layer is a data layer if ( layer->get_type() == Core::VolumeType::DATA_E ) { @@ -386,24 +388,24 @@ class ITKFilter : public LayerFilter if ( ! data_block_src ) { this->report_error( "Could not allocate enough memory." ); - return false; + return false; } - + Core::DataBlockHandle data_block_dst = data_block_src; if ( data_block_src->get_data_type() != data_type ) { - if ( !( Core::DataBlock::ConvertDataType( data_block_src, + if ( !( Core::DataBlock::ConvertDataType( data_block_src, data_block_dst, data_type ) ) ) { this->report_error( "Could not allocate enough memory." ); - return false; + return false; } } - - Core::DataVolumeHandle data_volume( new Core::DataVolume( + + Core::DataVolumeHandle data_volume( new Core::DataVolume( data_layer->get_grid_transform(), data_block_dst ) ); - - // NOTE: Do not need an update of the generation number as this volume + + // NOTE: Do not need an update of the generation number as this volume // was generated from scratch. But it will need a new histogram this->dispatch_insert_data_volume_into_layer( data_layer, data_volume, true ); return true; @@ -412,39 +414,39 @@ class ITKFilter : public LayerFilter else if ( layer->get_type() == Core::VolumeType::MASK_E ) { MaskLayerHandle mask_layer = boost::dynamic_pointer_cast( layer ); - + // Need to make an intermediate representation as a datablock of the data // before it can be uploaded into the mask. // NOTE: This only generates a wrapper, no new data is generated - Core::DataBlockHandle data_block = Core::ITKDataBlock::New( + Core::DataBlockHandle data_block = Core::ITKDataBlock::New( typename itk::Image::Pointer( itk_image ) ); if ( ! data_block ) { this->report_error( "Could not allocate enough memory." ); - return false; + return false; } - + // NOTE: The only reason we need the transform here, is that data blocks are // sorted by grid transform so we can use the nrrd library to save them, the // latter only allows storing one transform per data block, and since 8 masks // share one datablock, they are required for now to have the same transform. Core::MaskDataBlockHandle mask; - if (!( Core::MaskDataBlockManager::Convert( data_block, + if (!( Core::MaskDataBlockManager::Convert( data_block, mask_layer->get_grid_transform(), mask ) ) ) { this->report_error( "Could not allocate enough memory." ); return false; } - - Core::MaskVolumeHandle mask_volume( new Core::MaskVolume( + + Core::MaskVolumeHandle mask_volume( new Core::MaskVolume( mask_layer->get_grid_transform(), mask ) ); - + this->dispatch_insert_mask_volume_into_layer( mask_layer, mask_volume ); return true; } - + return false; } @@ -453,14 +455,14 @@ class ITKFilter : public LayerFilter template< class T > void forward_abort_to_filter( T filter_pointer, LayerHandle layer ) { - this->forward_abort_to_filter_internal( itk::ProcessObject::Pointer( filter_pointer ), + this->forward_abort_to_filter_internal( itk::ProcessObject::Pointer( filter_pointer ), layer ); } /// OBSERVE_ITK_PROGRESS: /// Forward the progress an itk filter is making and check for the abort status of the layer template< class T > - void observe_itk_progress( T filter_pointer, const LayerHandle& layer, + void observe_itk_progress( T filter_pointer, const LayerHandle& layer, float progress_start = 0.0, float progress_amount = 1.0 ) { this->observe_itk_progress_internal( itk::ProcessObject::Pointer( filter_pointer ), layer, @@ -494,34 +496,34 @@ class ITKFilter : public LayerFilter { this->limit_number_of_itk_threads_internal( itk::ProcessObject::Pointer( filter_pointer ) ); } - -protected: + +protected: /// HANDLE_ABORT: /// A virtual function that can be overloaded - virtual void handle_abort(); + virtual void handle_abort(); /// HANDLE_STOP: /// A virtual function that can be overloaded - virtual void handle_stop(); - + virtual void handle_stop(); + private: // Internal function for setting up itk progress forwarding - void observe_itk_progress_internal( itk::ProcessObject::Pointer filter, + void observe_itk_progress_internal( itk::ProcessObject::Pointer filter, const LayerHandle& layer, float progress_start, float progress_amount ); /// Internal function for setting up itk iteration forwarding - ///void observe_itk_iterations_internal( itk::ProcessObject::Pointer filter, + ///void observe_itk_iterations_internal( itk::ProcessObject::Pointer filter, /// boost::function< void( itk::Object* ) > iteration_fcn ); - void observe_itk_iterations_internal( itk::Object::Pointer filter, + void observe_itk_iterations_internal( itk::Object::Pointer filter, boost::function< void( itk::Object* ) > iteration_fcn ); - + /// Internal function for setting up abort handling void forward_abort_to_filter_internal( itk::ProcessObject::Pointer filter, LayerHandle layer ); - - /// Internal function for limiting the number of threads - void limit_number_of_itk_threads_internal( itk::ProcessObject::Pointer filter ); - + + /// Internal function for limiting the number of threads + void limit_number_of_itk_threads_internal( itk::ProcessObject::Pointer filter ); + ITKFilterPrivateHandle private_; }; @@ -537,6 +539,8 @@ public:\ case Core::DataType::USHORT_E: this->typed_run_filter(); break;\ case Core::DataType::INT_E: this->typed_run_filter(); break;\ case Core::DataType::UINT_E: this->typed_run_filter(); break;\ + case Core::DataType::LONGLONG_E: this->typed_run_filter(); break;\ + case Core::DataType::ULONGLONG_E: this->typed_run_filter(); break;\ case Core::DataType::FLOAT_E: this->typed_run_filter(); break;\ case Core::DataType::DOUBLE_E: this->typed_run_filter(); break;\ };\ @@ -547,7 +551,7 @@ public:\ {\ typedef itk::Image< VALUE_TYPE, 3> TYPED_IMAGE_TYPE; \ typedef Core::ITKImageDataT TYPED_CONTAINER_TYPE; \ - + #define SCI_END_TYPED_ITK_RUN() \ } @@ -564,6 +568,8 @@ public:\ case Core::DataType::USHORT_E: this->typed_run_filter(); break;\ case Core::DataType::INT_E: this->typed_run_filter(); break;\ case Core::DataType::UINT_E: this->typed_run_filter(); break;\ + case Core::DataType::LONGLONG_E: this->typed_run_filter(); break;\ + case Core::DataType::ULONGLONG_E: this->typed_run_filter(); break;\ case Core::DataType::FLOAT_E: this->typed_run_filter(); break;\ case Core::DataType::DOUBLE_E: this->typed_run_filter(); break;\ };\ @@ -581,7 +587,7 @@ public:\ #define SCI_END_ITK_RUN() \ } - + } // end namespace Seg3D #endif diff --git a/src/Application/Filters/LayerFilter.cc b/src/Application/Filters/LayerFilter.cc index 185cf3c6d..b0b71e972 100644 --- a/src/Application/Filters/LayerFilter.cc +++ b/src/Application/Filters/LayerFilter.cc @@ -932,13 +932,13 @@ void LayerFilter::run() // If more filters are running wait until one of them finished computing LayerFilterLock::Instance()->lock(); - try - { + //try + //{ this->run_filter(); - } - catch( ... ) - { - } + //} + //catch( ... ) + //{ + //} // Release the lock so another filter can start LayerFilterLock::Instance()->unlock(); diff --git a/src/Application/Filters/LayerFilter.h b/src/Application/Filters/LayerFilter.h index 0ffc58ee7..4cbe302b7 100644 --- a/src/Application/Filters/LayerFilter.h +++ b/src/Application/Filters/LayerFilter.h @@ -25,20 +25,20 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#ifndef APPLICATION_FILTERS_LAYERFILTER_H -#define APPLICATION_FILTERS_LAYERFILTER_H - + +#ifndef APPLICATION_FILTERS_LAYERFILTER_H +#define APPLICATION_FILTERS_LAYERFILTER_H + // Boost includes -#include - +#include + // Core includes #include #include #include // Application includes -#include +#include #include #include @@ -62,13 +62,13 @@ class LayerFilter : public LayerAbstractFilter public: LayerFilter(); virtual ~LayerFilter(); - - // -- abort/stop handling -- -public: + + // -- abort/stop handling -- +public: /// RAISE_ABORT: /// Raise the abort flag virtual void raise_abort() override; - + /// CHECK_ABORT: /// Check the abort flag virtual bool check_abort() override; @@ -76,21 +76,21 @@ class LayerFilter : public LayerAbstractFilter /// RAISE_STOP: /// Raise the stop flag void raise_stop(); - + /// CHECK_STOP: /// Check the stop flag - bool check_stop(); + bool check_stop(); - /// ABORT_AND_WAIT: + /// ABORT_AND_WAIT: /// NOTE: When undoing asynchronous layer operations, one may need to wait until the filter /// can be aborted. If not the state of the program is unclear. Hence this function will ensure /// that the filter has finished processing and that all locks are cleared. /// NOTE: This function should be run on the application thread only virtual void abort_and_wait() override; - + /// CONNECT_ABORT: /// Monitor the abort flag of a layer - void connect_abort( const LayerHandle& layer ); + void connect_abort( const LayerHandle& layer ); /// CONNECT_STOP: /// Monitor the stop flag of a layer @@ -101,22 +101,22 @@ class LayerFilter : public LayerAbstractFilter /// GET_NOTIFIER: /// Return a notifier that can be used to wait for the filter to finish. Core::NotifierHandle get_notifier(); - -protected: + +protected: /// HANDLE_ABORT: /// A virtual function that can be overloaded - virtual void handle_abort(); + virtual void handle_abort(); /// HANDLE_STOP: /// A virtual function that can be overloaded - virtual void handle_stop(); - - // -- shortcuts into the LayerManager -- + virtual void handle_stop(); + + // -- shortcuts into the LayerManager -- public: /// FIND_LAYER: /// Find a layer in the layer manager with this id bool find_layer( const std::string& layer_id, LayerHandle& layer ); - + /// LOCK_FOR_USE: /// Lock a layer for usage, i.e. we need the data/mask volume but we will not change /// the data. @@ -140,7 +140,7 @@ class LayerFilter : public LayerAbstractFilter /// NOTE: The BaseFilter class records which layers are locked and will schedule an unlock /// for each layer that was not unlocked by the time this class is destroyed. bool lock_for_deletion( LayerHandle layer ); - + /// CREATE_AND_LOCK_DATA_LAYER_FROM_LAYER: /// Create a new data layer with the same dimensions as another layer, the layer is immediately /// locked as it does not contain any data and will be in the creating state. @@ -151,7 +151,7 @@ class LayerFilter : public LayerAbstractFilter /// Create a new data layer with the given grid transform, the layer is immediately /// locked as it does not contain any data and will be in the creating state. /// NOTE: This function can only be run from the application thread - bool create_and_lock_data_layer( const Core::GridTransform& grid_trans, + bool create_and_lock_data_layer( const Core::GridTransform& grid_trans, LayerHandle src_layer, LayerHandle& dst_layer ); /// CREATE_CROPPED_LARGE_VOLUME_LAYER: @@ -164,7 +164,7 @@ class LayerFilter : public LayerAbstractFilter /// Create a new mask layer with the same dimensions as another layer, the layer is immediately /// locked as it does not contain any data and will be in the creating state. /// NOTE: This function can only be run from the application thread. - bool create_and_lock_mask_layer_from_layer( LayerHandle src_layer, LayerHandle& dst_layer ); + bool create_and_lock_mask_layer_from_layer( LayerHandle src_layer, LayerHandle& dst_layer ); /// CREATE_AND_LOCK_MASK_LAYER_FROM_LAYER: /// Create a new mask layer with the same dimensions as another layer, the layer is immediately @@ -173,12 +173,12 @@ class LayerFilter : public LayerAbstractFilter /// NOTE: This function can only be run from the application thread. bool create_and_lock_mask_layer_from_layer( LayerHandle src_layer, LayerHandle& dst_layer, std::string dst_name ); - + /// CREATE_AND_LOCK_MASK_LAYER: /// Create a new mask layer with the given grid transform, the layer is immediately /// locked as it does not contain any data and will be in the creating state. /// NOTE: This function can only be run from the application thread - bool create_and_lock_mask_layer( const Core::GridTransform& grid_trans, + bool create_and_lock_mask_layer( const Core::GridTransform& grid_trans, LayerHandle src_layer, LayerHandle& dst_layer ); /// DISPATCH_UNLOCK_LAYER: @@ -188,21 +188,21 @@ class LayerFilter : public LayerAbstractFilter /// DISPATCH_DELETE_LAYER: /// Schedule a layer to be deleted bool dispatch_delete_layer( LayerHandle layer ); - + /// DISPATCH_INSERT_DATA_VOLUME_INTO_LAYER: /// Schedule a new data volume to be inserted into a layer - bool dispatch_insert_data_volume_into_layer( LayerHandle layer, + bool dispatch_insert_data_volume_into_layer( LayerHandle layer, Core::DataVolumeHandle data, bool update_histogram ); - + /// DISPATCH_INSERT_MASK_VOLUME_INTO_LAYER: /// Schedule a new mask volume to be inserted into a layer - bool dispatch_insert_mask_volume_into_layer( LayerHandle layer, + bool dispatch_insert_mask_volume_into_layer( LayerHandle layer, Core::MaskVolumeHandle mask ); /// CREATE_UNDO_REDO_AND_RPOVENANCE_RECORD: - /// Create a provenance record and add it to the provenance database, + /// Create a provenance record and add it to the provenance database, /// and an undo record and add it to the undo stack. - void create_undo_redo_and_provenance_record( Core::ActionContextHandle context, + void create_undo_redo_and_provenance_record( Core::ActionContextHandle context, Core::ActionHandle action, bool split_prov = false ); /// UPDATE_PROVENANCE_ACTION_STRING: @@ -224,10 +224,10 @@ class LayerFilter : public LayerAbstractFilter /// GET_FILTER_NAME: /// This functions returns the name of the filter that is used in the error report. virtual std::string get_filter_name() const = 0; - + /// GET_LAYER_PREFIX: - /// This function returns the name of the filter. The latter is prepended to the new layer name, - /// when a new layer is generated. + /// This function returns the name of the filter. The latter is prepended to the new layer name, + /// when a new layer is generated. virtual std::string get_layer_prefix() const = 0; protected: @@ -271,6 +271,8 @@ public:\ case Core::DataType::USHORT_E: this->typed_run_filter(); break;\ case Core::DataType::INT_E: this->typed_run_filter(); break;\ case Core::DataType::UINT_E: this->typed_run_filter(); break;\ + case Core::DataType::LONGLONG_E: this->typed_run_filter(); break;\ + case Core::DataType::ULONGLONG_E: this->typed_run_filter(); break;\ case Core::DataType::FLOAT_E: this->typed_run_filter(); break;\ case Core::DataType::DOUBLE_E: this->typed_run_filter(); break;\ };\ @@ -279,7 +281,7 @@ public:\ template< class VALUE_TYPE>\ void typed_run_filter()\ {\ - + #define SCI_END_TYPED_RUN() \ } @@ -291,6 +293,6 @@ public:\ #define SCI_END_RUN() \ } - + #endif diff --git a/src/Application/Filters/SingleThresholdFilter.cc b/src/Application/Filters/SingleThresholdFilter.cc index 458077950..b7605070a 100644 --- a/src/Application/Filters/SingleThresholdFilter.cc +++ b/src/Application/Filters/SingleThresholdFilter.cc @@ -76,6 +76,12 @@ void SingleThresholdFilter::run_filter() case DataType::UINT_E: this->threshold_data< unsigned int >( threshold_result, this->threshold_ ); break; + case DataType::LONGLONG_E: + this->threshold_data< long long >( threshold_result, this->threshold_ ); + break; + case DataType::ULONGLONG_E: + this->threshold_data< unsigned long long >( threshold_result, this->threshold_ ); + break; case DataType::FLOAT_E: this->threshold_data< float >( threshold_result, this->threshold_ ); break; diff --git a/src/Application/Filters/ThresholdFilter.cc b/src/Application/Filters/ThresholdFilter.cc index e9e644015..a7e99011f 100644 --- a/src/Application/Filters/ThresholdFilter.cc +++ b/src/Application/Filters/ThresholdFilter.cc @@ -83,6 +83,14 @@ void ThresholdFilter::run_filter() this->threshold_data< unsigned int >( threshold_result, this->lower_threshold_, this->upper_threshold_ ); break; + case DataType::LONGLONG_E: + this->threshold_data< long long >( threshold_result, + this->lower_threshold_, this->upper_threshold_ ); + break; + case DataType::ULONGLONG_E: + this->threshold_data< unsigned long long >( threshold_result, + this->lower_threshold_, this->upper_threshold_ ); + break; case DataType::FLOAT_E: this->threshold_data< float >( threshold_result, this->lower_threshold_, this->upper_threshold_ ); diff --git a/src/Application/ImageRegistrationTools/Actions/ActionAddTransformsFilter.cc b/src/Application/ImageRegistrationTools/Actions/ActionAddTransformsFilter.cc index 583c4e8a2..380837b5c 100644 --- a/src/Application/ImageRegistrationTools/Actions/ActionAddTransformsFilter.cc +++ b/src/Application/ImageRegistrationTools/Actions/ActionAddTransformsFilter.cc @@ -321,7 +321,7 @@ ActionAddTransformsFilter::run( Core::ActionContextHandle& context, Core::Action grid_transforms[i] = dynamic_cast(transform_stos.GetPointer()); - if ( grid_transforms[i].GetPointer() == NULL ) + if ( grid_transforms[i].GetPointer() == nullptr ) { std::cerr << stos[i].fn_load_ << " is not a grid transform. Currently " << "ir-add-transforms only supports grid transforms." << std::endl; diff --git a/src/Application/ImageRegistrationTools/Actions/ActionAssembleFilter.cc b/src/Application/ImageRegistrationTools/Actions/ActionAssembleFilter.cc index 9c50bade4..9f688beae 100644 --- a/src/Application/ImageRegistrationTools/Actions/ActionAssembleFilter.cc +++ b/src/Application/ImageRegistrationTools/Actions/ActionAssembleFilter.cc @@ -382,7 +382,7 @@ ActionAssembleFilter::run( Core::ActionContextHandle& context, Core::ActionResul image_t::SpacingType mosaic_sp = image.front()->GetSpacing(); if ( this->defer_image_loading_ ) { - image[0] = image_t::Pointer(NULL); + image[0] = image_t::Pointer(nullptr); } mosaic_sz[0] = static_cast((mosaic_max[0] - mosaic_min[0]) / mosaic_sp[0]); @@ -477,7 +477,7 @@ ActionAssembleFilter::run( Core::ActionContextHandle& context, Core::ActionResul { if ( verbose ) std::cout << "unloading " << (*iter) << std::endl; - image[i] = image_t::Pointer(NULL); + image[i] = image_t::Pointer(nullptr); } } } @@ -590,7 +590,7 @@ ActionAssembleFilter::run( Core::ActionContextHandle& context, Core::ActionResul if ( verbose ) std::cout << "unloading " << (*iter).string() << std::endl; - image[i] = image_t::Pointer(NULL); + image[i] = image_t::Pointer(nullptr); } } @@ -691,7 +691,7 @@ ActionAssembleFilter::run( Core::ActionContextHandle& context, Core::ActionResul return true; } - if (mosaic_mask.GetPointer() == NULL) + if (mosaic_mask.GetPointer() == nullptr) { // assemble the mosaic mask: std::cout << "assembling mosaic mask..." << std::endl; @@ -704,7 +704,7 @@ ActionAssembleFilter::run( Core::ActionContextHandle& context, Core::ActionResul mask[i] = std_mask(image[i], false); // free up the image memory, we no longer need it: - image[i] = image_t::Pointer(NULL); + image[i] = image_t::Pointer(nullptr); } } diff --git a/src/Application/ImageRegistrationTools/Actions/ActionFFTFilter.cc b/src/Application/ImageRegistrationTools/Actions/ActionFFTFilter.cc index 42a9b6f2c..23d558387 100644 --- a/src/Application/ImageRegistrationTools/Actions/ActionFFTFilter.cc +++ b/src/Application/ImageRegistrationTools/Actions/ActionFFTFilter.cc @@ -289,7 +289,7 @@ ActionFFTFilter::run( Core::ActionContextHandle& context, Core::ActionResultHand img = shrink(img, 2); tile_pyramid[i][j] = img; - if (mask_pyramid[i + 1][j].GetPointer() != NULL) + if (mask_pyramid[i + 1][j].GetPointer() != nullptr) { mask_t::ConstPointer msk(shrink(mask_pyramid[i + 1][j], 2)); mask_pyramid[i][j] = msk; @@ -368,7 +368,7 @@ ActionFFTFilter::run( Core::ActionContextHandle& context, Core::ActionResultHand std::cerr << "UNMATCHED: " << *iterator_at_index(in, i) << ", ignoring..." << std::endl; - image[i] = NULL; + image[i] = nullptr; num_unmatched++; } std::cerr << std::endl; diff --git a/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceBruteFilter.cc b/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceBruteFilter.cc index 21ce1cb29..c70bd62e2 100644 --- a/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceBruteFilter.cc +++ b/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceBruteFilter.cc @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -74,7 +74,7 @@ CORE_REGISTER_ACTION( Seg3D, SliceToSliceBruteFilter ) namespace Seg3D { - + //---------------------------------------------------------------- // DEBUG_EVERYTHING @@ -130,15 +130,15 @@ refine_one_pair(const image_t * i0, const double & min_step, const double & max_step, const itk::Array & optimizer_scales, - + const bfs::path & fn_prefix = "") { // setup the registration object: registration_t::Pointer registration = registration_t::New(); - + // setup the image interpolator: registration->SetInterpolator(interpolator_t::New()); - + // setup the optimizer: optimizer_t::Pointer optimizer = optimizer_t::New(); registration->SetOptimizer(optimizer); @@ -154,14 +154,14 @@ refine_one_pair(const image_t * i0, optimizer->SetPickUpPaceSteps(5); // FIXME: optimizer->SetBackTracking(true); - + try { optimizer->SetScales(optimizer_scales); } catch (itk::ExceptionObject &err) { CORE_LOG_ERROR(err.GetDescription()); throw; } - + // setup the image-to-image metric: typedef itk::NormalizedCorrelationImageToImageMetric // FIXME: typedef itk::MeanSquaresImageToImageMetric @@ -170,36 +170,36 @@ refine_one_pair(const image_t * i0, metric->SetInterpolator(interpolator_t::New()); metric->SetSubtractMean(true); registration->SetMetric(metric); - + registration->SetTransform(t01); registration->SetInitialTransformParameters(t01->GetParameters()); - + // setup the masks: typedef itk::ImageMaskSpatialObject<2> mask_so_t; mask_t::ConstPointer fi_mask = m0; - if (m0 != NULL) + if (m0 != nullptr) { mask_so_t::Pointer fi_mask_so = mask_so_t::New(); fi_mask_so->SetImage(fi_mask); metric->SetFixedImageMask(fi_mask_so); } - + mask_t::ConstPointer mi_mask = m1; - if (m1 != NULL) + if (m1 != nullptr) { mask_so_t::Pointer mi_mask_so = mask_so_t::New(); mi_mask_so->SetImage(mi_mask); metric->SetMovingImageMask(mi_mask_so); } - + // setup the fixed and moving image: image_t::ConstPointer fi = i0; image_t::ConstPointer mi = i1; - + registration->SetFixedImageRegion(fi->GetLargestPossibleRegion()); registration->SetFixedImage(fi); registration->SetMovingImage(mi); - + // evaluate the metric before the registration: double metric_before = eval_metric(t01, fi, mi, fi_mask, mi_mask); @@ -208,10 +208,10 @@ refine_one_pair(const image_t * i0, { CORE_THROW_EXCEPTION("Metric failed evaluation step."); } - + typename transform_t::ParametersType params_before = t01->GetParameters(); - + if (! fn_prefix.empty()) { try @@ -229,25 +229,25 @@ refine_one_pair(const image_t * i0, throw; } } - + // perform the registration: try { std::cout << "starting image registration:" << std::endl; - registration->StartRegistration(); + registration->Update(); } catch (itk::ExceptionObject & err) { std::cerr << "image registration threw an exception: " << std::endl << err << std::endl; CORE_LOG_ERROR(err.GetDescription()); - + // FIXME: #ifdef DEBUG_EVERYTHING try { // try to save the failed mosaic -- sometimes the resulting image // may not fit in memory, so an exception will be thrown: - + save_rgb(fn_prefix.string() + "exception.png", remap_min_max(fi), remap_min_max(mi), @@ -261,20 +261,20 @@ refine_one_pair(const image_t * i0, throw; } t01->SetParameters(optimizer->GetBestParams()); - + // evaluate the metric after the registration: double metric_after = eval_metric(t01, fi, mi, fi_mask, mi_mask); - + std::cout << "BEFORE: " << metric_before << std::endl << "AFTER: " << metric_after << std::endl; - + if (! fn_prefix.empty()) { try { // try to save the failed mosaic -- sometimes the resulting image // may not fit in memory, so an exception will be thrown: - + save_rgb(fn_prefix.string() + "v1.png", remap_min_max(fi), remap_min_max(mi), @@ -286,17 +286,17 @@ refine_one_pair(const image_t * i0, throw; } } - + if (metric_before <= metric_after || metric_after != metric_after) { std::cout << "NOTE: minimization failed, ignoring registration results..." << std::endl; t01->SetParameters(params_before); return metric_before; } - + return metric_after; } - + //---------------------------------------------------------------- // refine_one_pair // @@ -311,11 +311,11 @@ refine_one_pair(int octave_start, const double & min_step, const double & max_step, const itk::Array & optimizer_scales, - + const bfs::path & fn_prefix = "") { int octave_end = octave_start + 1 - num_octaves; - + double metric = std::numeric_limits::max(); for (int i = octave_start; i >= octave_end; i--) { @@ -325,12 +325,12 @@ refine_one_pair(int octave_start, { CORE_THROW_EXCEPTION("pair scales do not match"); } - + for (int j = last_scale; j >= 0; j--) { std::ostringstream pfx; pfx << fn_prefix << "o" << the_text_t::number(i) << "-s" << the_text_t::number(j) << "-"; - + metric = refine_one_pair(p0.octave_[i].L_[j], p1.octave_[i].L_[j], p0.octave_[i].mask_, @@ -343,7 +343,7 @@ refine_one_pair(int octave_start, bfs::path(pfx.str())); } } - + return metric; } @@ -359,7 +359,7 @@ refine_one_pair(const pyramid_t & p0, const double & min_step, const double & max_step, const itk::Array & optimizer_scales, - + const bfs::path & fn_prefix = "") { int num_octaves = std::min(p0.octaves(), p1.octaves()); @@ -387,18 +387,18 @@ refine_one_pair(const pyramid_t & p0, const unsigned int iterations, const double & min_step, const double & max_step, - + const bfs::path & fn_prefix = "") { // FIXME: this is probably unnecessary: typedef optimizer_t::ScalesType optimizer_scales_t; optimizer_scales_t scales(t01->GetNumberOfParameters()); scales.Fill(1.0); - + // encourage translation: // scales[transform_t::index_a(0, 0)] = 1e-1; // scales[transform_t::index_b(0, 0)] = 1e-1; - + return refine_one_pair(p0, p1, t01, iterations, min_step, max_step, scales, fn_prefix); } @@ -413,11 +413,11 @@ refine_one_pair(int octave_start, const bool & use_low_order_intermediate, const coarse_transform_t * t_coarse, order4_transform_t::Pointer & t_order4, - + const unsigned int iterations, const double & min_step, const double & max_step, - + const bfs::path & fn_prefix = "") { // encourage translation: @@ -426,17 +426,17 @@ refine_one_pair(int octave_start, scales2.Fill(1e-0); scales2[order2_transform_t::index_a(0, 0)] = 1e-1; scales2[order2_transform_t::index_b(0, 0)] = 1e-1; - + // encourage translation: itk::Array scales4( order4_transform_t::New()->GetNumberOfParameters() ); scales4.Fill(1e-0); scales4[order4_transform_t::index_a(0, 0)] = 1e-1; scales4[order4_transform_t::index_b(0, 0)] = 1e-1; - + base_transform_t::ConstPointer t_previous = t_coarse; double metric = std::numeric_limits::max(); - + int octave_end = octave_start + 1 - num_octaves; for (int i = octave_start; i >= octave_end; i--) { @@ -446,17 +446,17 @@ refine_one_pair(int octave_start, { CORE_THROW_EXCEPTION("pair scales do not match"); } - + for (int j = last_scale; j >= 0; j--) { std::ostringstream pfx2; pfx2 << fn_prefix << "o" << the_text_t::number(i) << "-s" << the_text_t::number(j) << "-order2-"; - + const image_t * a = p0.octave_[i].L_[j]; const image_t * b = p1.octave_[i].L_[j]; const mask_t * ma = p0.octave_[i].mask_; const mask_t * mb = p1.octave_[i].mask_; - + if (use_low_order_intermediate) { // bootstrap the low-order transform: @@ -464,7 +464,7 @@ refine_one_pair(int octave_start, t_order2 = setup_transform(b); solve_for_transform (b, mb, t_previous, t_order2, 16, 2, true); - + // refine the low-order transform: metric = refine_one_pair(a, b, @@ -478,16 +478,16 @@ refine_one_pair(int octave_start, bfs::path(pfx2.str())); t_previous = t_order2; } - + // bootstrap the high-order transform: t_order4 = setup_transform(b); solve_for_transform (b, mb, t_previous, t_order4, 16, 1, true); - + // refine the high-order transform: std::ostringstream pfx4; pfx4 << fn_prefix << "o" << the_text_t::number(i) << "-s" << the_text_t::number(j) << "-order4-"; - + metric = refine_one_pair(a, b, ma, @@ -501,7 +501,7 @@ refine_one_pair(int octave_start, t_previous = t_order4; } } - + return metric; } @@ -515,11 +515,11 @@ refine_one_pair(int octave_start, const pyramid_t & p1, const coarse_transform_t * t_coarse, order2_transform_t::Pointer & t_order2, - + const unsigned int iterations, const double & min_step, const double & max_step, - + const bfs::path & fn_prefix = "") { // encourage translation: @@ -528,14 +528,14 @@ refine_one_pair(int octave_start, scales2.Fill(1e-0); scales2[order2_transform_t::index_a(0, 0)] = 1e-1; scales2[order2_transform_t::index_b(0, 0)] = 1e-1; - + double metric = std::numeric_limits::max(); int octave_end = octave_start + 1 - num_octaves; - + t_order2 = setup_transform (p1.octave_[octave_end].L_[0]); - + solve_for_transform (p1.octave_[octave_end].L_[0], p1.octave_[octave_end].mask_, @@ -544,7 +544,7 @@ refine_one_pair(int octave_start, 16, 2, true); - + for (int i = octave_start; i >= octave_end; i--) { const unsigned int last_scale = p0.octave_[i].scales() - 1; @@ -553,19 +553,19 @@ refine_one_pair(int octave_start, { CORE_THROW_EXCEPTION("pair scales do not match"); } - + for (int j = last_scale; j >= 0; j--) { const image_t * a = p0.octave_[i].L_[j]; const image_t * b = p1.octave_[i].L_[j]; const mask_t * ma = p0.octave_[i].mask_; const mask_t * mb = p1.octave_[i].mask_; - + // bootstrap the low-order transform: // refine the low-order transform: std::ostringstream pfx2; pfx2 << fn_prefix << "o" << the_text_t::number(i) << "-s" << the_text_t::number(j) << "-order2-"; - + metric = refine_one_pair(a, b, ma, @@ -578,7 +578,7 @@ refine_one_pair(int octave_start, bfs::path(pfx2.str())); } } - + return metric; } @@ -595,14 +595,14 @@ fast_variance(const image_t * a, const base_transform_t * t_ab, double samples_per_64x64 = 128.0) { - if (t_ab == NULL) return std::numeric_limits::max(); - + if (t_ab == nullptr) return std::numeric_limits::max(); + image_t::SpacingType a_sp = a->GetSpacing(); image_t::SizeType a_sz = a->GetLargestPossibleRegion().GetSize(); pnt2d_t a_min = a->GetOrigin(); pnt2d_t a_max = a_min + vec2d((a_sz[0]) * a_sp[0], (a_sz[1]) * a_sp[1]); - + const double w0 = a_max[0] - a_min[0]; const double h0 = a_max[1] - a_min[1]; const double samples_per_pixel = samples_per_64x64 / (4096.0); @@ -610,55 +610,55 @@ fast_variance(const image_t * a, const double sy = samples_per_pixel * h0; const unsigned int nx = static_cast(sx + 0.5); const unsigned int ny = static_cast(sy + 0.5); - + // uniformly sample the variance in the overlapping region: interpolator_t::Pointer ia = interpolator_t::New(); ia->SetInputImage(a); - + interpolator_t::Pointer ib = interpolator_t::New(); ib->SetInputImage(b); - + double v = 0.0; double n = 0.0; - + pnt2d_t pa; pnt2d_t pb; for (unsigned int i = 1; i <= nx; i++) { double tx = static_cast(i) / static_cast(nx + 1); pa[0] = a_min[0] + tx * w0; - + for (unsigned int j = 1; j <= ny; j++) { double ty = static_cast(j) / static_cast(ny + 1); pa[1] = a_min[1] + ty * h0; if (!ia->IsInsideBuffer(pa)) continue; - + image_t::IndexType index_a; if (!ma->TransformPhysicalPointToIndex(pa, index_a)) continue; if (ma->GetPixel(index_a) == 0) continue; - + pb = t_ab->TransformPoint(pa); if (!ib->IsInsideBuffer(pb)) continue; - + image_t::IndexType index_b; if (!mb->TransformPhysicalPointToIndex(pb, index_b)) continue; if (mb->GetPixel(index_b) == 0) continue; - + double pixel_a = ia->Evaluate(pa); double pixel_b = ib->Evaluate(pb); double mean = (pixel_a + pixel_b) / 2.0; - + double da = pixel_a - mean; double db = pixel_b - mean; - + v += da * da + db * db; n += 1.0; } } - + if (n == 0.0) return std::numeric_limits::max(); - + // return the mean variance: return v / n; } @@ -672,12 +672,12 @@ image_center(const image_t * image) { typename image_t::SizeType sz = image->GetLargestPossibleRegion().GetSize(); typename image_t::SpacingType sp = image->GetSpacing(); - + pnt2d_t min = image->GetOrigin(); pnt2d_t max = min + vec2d(static_cast(sz[0]) * sp[0], static_cast(sz[1]) * sp[1]); pnt2d_t center = min + (max - min) * 0.5; - + return center; } @@ -704,22 +704,22 @@ brute_force(const bool & brute_force_rotation, { // octave 0 is fixed, octave 1 is rotated and matched to octave 0: double best_metric = std::numeric_limits::max(); - + double v_min_global = std::numeric_limits::max(); double v_max_global = -v_min_global; std::vector v_min(num_orientations, v_min_global); std::vector v_max(num_orientations, v_max_global); std::vector vimage(num_orientations); - + image_t::SizeType z0 = a->GetLargestPossibleRegion().GetSize(); image_t::SpacingType s1 = b->GetSpacing(); const pnt2d_t center = image_center(b); - + typedef itk::NearestNeighborInterpolateImageFunction interpolator_t; interpolator_t::Pointer b_interpolator = interpolator_t::New(); b_interpolator->SetInputImage(b); - + #ifdef DEBUG_EVERYTHING if (! fn_debug.empty()) { @@ -727,21 +727,21 @@ brute_force(const bool & brute_force_rotation, fn_debug.string() + "fixed.png"); } #endif - + // TODO: this needs to be a state instead // set_major_progress(0.05); - + bool done_rotation = false; for (int k = 0; k < num_orientations && !done_rotation; k++) { double angle = a0 + (a1 - a0) * static_cast(k) / static_cast(num_orientations - 1); - + if (!brute_force_rotation) { angle = best_angle; done_rotation = true; } - + #ifdef DEBUG_EVERYTHING std::ostringstream fn_dbg_pfx; if (! fn_debug.empty()) @@ -749,27 +749,27 @@ brute_force(const bool & brute_force_rotation, fn_dbg_pfx << fn_debug << "a" << the_text_t::number(static_cast(0.5 + angle * 360.0 / TWO_PI), 3, '0') << "-"; } #endif - + coarse_transform_t::Pointer rot = coarse_transform_t::New(); rot->SetCenterOfRotationComponent(center); rot->Rotate2D(angle); - + // re-estimate the dimensions of the rotated tile: image_t::PointType min; image_t::PointType max; calc_tile_mosaic_bbox(rot, b, min, max); - + // resample the moving image: image_t::Pointer b_warped = warp(b, rot.GetPointer()); - mask_t::Pointer mb_warped = NULL; - if ( mb != NULL ) + mask_t::Pointer mb_warped = nullptr; + if ( mb != nullptr ) mb_warped = warp(mb, rot.GetPointer()); static const pnt2d_t zero = pnt2d(0, 0); vec2d_t shift = b_warped->GetOrigin() - zero; b_warped->SetOrigin(zero); - if ( mb != NULL ) + if ( mb != nullptr ) mb_warped->SetOrigin(zero); - + //#if 0 // def DEBUG_EVERYTHING // if (fn_debug.size() != 0) // { @@ -777,81 +777,81 @@ brute_force(const bool & brute_force_rotation, // fn_dbg_pfx.str() + "warped.png"); // } //#endif - + image_t::SizeType period_sz = calc_padding(a, b_warped); - + image_t::PointType offset_min; min[0] = -std::numeric_limits::max(); min[1] = -std::numeric_limits::max(); image_t::PointType offset_max; max[0] = std::numeric_limits::max(); max[1] = std::numeric_limits::max(); - - + + translate_transform_t::Pointer translate; double v = match_one_pair(translate, - + a, ma, b_warped.GetPointer(), mb_warped.GetPointer(), - + period_sz, - + // overlap min/max: 0.6, 1.0, - + // offset min/max: offset_min, offset_max, - + // low pass filters: 0.9, // r 0.1, // s - + // max peaks in the PDF: 10, - + // don't consider the zero displacement: false); - + //#if 0 // def DEBUG_EVERYTHING // if (fn_debug.size() != 0) // { // if (v != std::numeric_limits::max()) // { // save_rgb(fn_dbg_pfx.str() + "000000.png", -// +// // remap_min_max(a), // remap_min_max(b_warped), -// +// // translate, -// +// // ma, // mb_warped, // false); // } // } //#endif - + if (v < best_metric) { best_metric = v; best_angle = angle; best_shift = translate->GetOffset() + shift; // best_overlap = overlap; - + #ifdef DEBUG_EVERYTHING if (! fn_debug.empty()) { save_rgb(fn_dbg_pfx.str() + "better.png", - + remap_min_max(a), remap_min_max(b_warped), - + translate, - + ma, mb_warped, true); @@ -861,7 +861,7 @@ brute_force(const bool & brute_force_rotation, // TODO: this needs to be a state instead // set_major_progress(0.94 * (k+1)/(num_orientations+1) + 0.05); } - + // TODO: this needs to be a state instead // set_major_progress(0.99); } @@ -883,18 +883,18 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac // this is so that the printouts look better: std::cout.precision(6); std::cout.setf(std::ios::scientific); - + track_progress(true); - + // setup thread storage for the main thread: set_the_thread_storage_provider(the_boost_thread_t::thread_storage); the_boost_thread_t MAIN_THREAD_DUMMY; MAIN_THREAD_DUMMY.set_stopped(false); - + // setup thread and mutex interface creators: the_mutex_interface_t::set_creator(the_boost_mutex_t::create); the_thread_interface_t::set_creator(the_boost_thread_t::create); - + bfs::path fn_load[2] = { this->input_fixed_, this->input_moving_ }; // fn_load[0] = this->input_fixed_; // fn_load[1] = this->input_moving_; @@ -907,14 +907,14 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac } bool flip[2] = { this->flip_fixed_, this->flip_moving_ }; - + bfs::path image_dirs[2]; if ( (this->image_dir_fixed_ != "") && (this->image_dir_moving_ != "") ) { image_dirs[0] = this->image_dir_fixed_; image_dirs[1] = this->image_dir_moving_; } - + bfs::path fn_save(this->output_stos_); if (! bfs::is_directory( fn_save.parent_path() ) ) { @@ -927,7 +927,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac return false; } } - + bool brute_force_rotation = true; if (this->best_angle_ != 0) { @@ -950,35 +950,35 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac // TODO: expose? bool verbose = false; - + if (fn_load[0].empty() || fn_load[1].empty()) { context->report_error("must specify 2 files with the -load option"); return false; } - + if (fn_save.empty()) { context->report_error("must specify a file to open with the -save option"); return false; } - + // dump the status: std::cout << "shrink factor: " << this->shrink_factor_ << std::endl << "search for rotation: " << brute_force_rotation << std::endl << "search for translation: " << brute_force_translation << std::endl << std::endl; - + bfs::path fn_debug; #ifdef DEBUG_EVERYTHING fn_debug = fn_save.string() + ".FIXME-"; #endif - + // load the images, assemble the pyramids, match them: image_t::Pointer mosaic[2]; mask_t::Pointer mosaic_mask[2]; pyramid_t pyramid[2]; - + if (fn_load[0].extension() == ".mosaic") { load_slice(fn_load[0], @@ -988,7 +988,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac image_dirs[0], mosaic[0], mosaic_mask[0]); - + setup_pyramid(pyramid[0], 0, // index fn_load[0], @@ -1010,7 +1010,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac mosaic[0] = std_tile(fn_load[0], this->shrink_factor_, this->pixel_spacing_); - + if (!fn_mask[0].empty()) { // load slice mask: @@ -1022,7 +1022,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac { mosaic_mask[0] = std_mask(mosaic[0], this->use_standard_mask_); } - + setup_pyramid(pyramid[0], 0, // index fn_load[0], @@ -1033,7 +1033,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac DEFAULT_KEY_GENERATE_SETTING, // generate descriptors? fn_debug); } - + if (fn_load[1].extension() == ".mosaic") { load_slice(fn_load[1], @@ -1043,7 +1043,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac image_dirs[1], mosaic[1], mosaic_mask[1]); - + setup_pyramid(pyramid[1], 1, // index fn_load[1], @@ -1065,7 +1065,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac mosaic[1] = std_tile(fn_load[1], this->shrink_factor_, this->pixel_spacing_); - + if (!fn_mask[1].empty()) { // load slice mask: @@ -1077,7 +1077,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac { mosaic_mask[1] = std_mask(mosaic[1], this->use_standard_mask_); } - + setup_pyramid(pyramid[1], 1, // index fn_load[1], @@ -1088,9 +1088,9 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac DEFAULT_KEY_GENERATE_SETTING, // generate descriptors? fn_debug); } - + const int num_levels = std::min(pyramid[0].octaves(), pyramid[1].octaves()); - + // FIXME: //#if 0 // for (unsigned int i = 0; i < 2; i++) @@ -1100,14 +1100,14 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac // the_text_t fn = // the_text_t::number(i, 2, '0') + "-" + // the_text_t::number(j, 2, '0') + ".png"; -// +// // save // (cast(pyramid[i].octave_[j].L_[0]), // fn); // } // } //#endif - + // brute force registration: brute_force(brute_force_rotation, brute_force_translation, @@ -1120,7 +1120,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac pyramid[1].octave_[num_levels - 1].L_[0], pyramid[0].octave_[num_levels - 1].mask_, pyramid[1].octave_[num_levels - 1].mask_, - + // start/finish rotation angles: 0.0, TWO_PI * (static_cast(num_orientations - 1) / @@ -1128,17 +1128,17 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac num_orientations, step_size, verbose); - + std::cout << "BEST SHIFT: " << best_shift << std::endl << "BEST ANGLE: " << this->best_angle_ * 360.0 / TWO_PI<< std::endl << "BEST OVERLAP: " << this->best_overlap_ << std::endl; - + coarse_transform_t::Pointer t_coarse = coarse_transform_t::New(); t_coarse->SetTranslation(best_shift); t_coarse->SetCenterOfRotationComponent (image_center(pyramid[1].octave_[num_levels - 1].L_[0])); t_coarse->Rotate2D(this->best_angle_); - + base_transform_t::ConstPointer t_final; if (!this->use_refinement_) { @@ -1155,7 +1155,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac std::min(3, static_cast(std::min(pyramid[0].octaves(), pyramid[1].octaves()))), 0); - + if (! this->use_cubic_) { order2_transform_t::Pointer t_order2; @@ -1169,7 +1169,7 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac DEFAULT_MIN_STEP, DEFAULT_MAX_STEP, // FIXME: 1e-6 fn_debug); - + t_final = t_order2.GetPointer(); } else @@ -1186,16 +1186,16 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac DEFAULT_MIN_STEP, DEFAULT_MAX_STEP, // FIXME: 1e-6 fn_debug); - + if (octave_end > 0) { itk::Array scales( t_order4->GetNumberOfParameters() ); scales.Fill(1e-0); - + // encourage translation: scales[order4_transform_t::index_a(0, 0)] = 1e-1; scales[order4_transform_t::index_b(0, 0)] = 1e-1; - + // Avoid ruining the previous transform results due to image // artifacts in the low resolution octaves of the pyramid. // Start with the next unprocessed octave and complete the process @@ -1211,11 +1211,11 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac scales, fn_debug.string() + "final-"); } - + t_final = t_order4.GetPointer(); } } - + save_stos(fn_save, fn_load[0], fn_load[1], @@ -1228,12 +1228,12 @@ ActionSliceToSliceBruteFilter::run( Core::ActionContextHandle& context, Core::Ac this->shrink_factor_, t_final, true); - + // TODO: this needs to be a state instead // set_major_progress(1.0); CORE_LOG_SUCCESS("ir-stos-brute done"); - + // done: return true; } @@ -1287,7 +1287,7 @@ ActionSliceToSliceBruteFilter::Dispatch(Core::ActionContextHandle context, { // Create a new action ActionSliceToSliceBruteFilter* action = new ActionSliceToSliceBruteFilter; - + // Setup the parameters action->target_layer_ = target_layer; action->shrink_factor_ = shrink_factor; @@ -1310,7 +1310,7 @@ ActionSliceToSliceBruteFilter::Dispatch(Core::ActionContextHandle context, action->mask_moving_ = mask_moving; action->image_dir_fixed_ = image_dir_fixed; action->image_dir_moving_ = image_dir_moving; - + // Dispatch action to underlying engine Core::ActionDispatcher::PostAction( Core::ActionHandle( action ), context ); } diff --git a/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceFilter.cc b/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceFilter.cc index cc089ed4c..563f60b3d 100644 --- a/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceFilter.cc +++ b/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceFilter.cc @@ -117,22 +117,22 @@ class optimizer_observer_t : public itk::Command typedef optimizer_observer_t Self; typedef itk::Command Superclass; typedef itk::SmartPointer Pointer; - + itkNewMacro(Self); - + void Execute(itk::Object *caller, const itk::EventObject & event) { Execute((const itk::Object *)(caller), event); } - + void Execute(const itk::Object * object, const itk::EventObject & event) override { if (typeid(event) != typeid(itk::IterationEvent)) return; - + const optimizer_t * optimizer = dynamic_cast(object); std::cout << static_cast(optimizer->GetCurrentIteration()) << '\t' << optimizer->GetValue() << '\t' << optimizer->GetCurrentPosition() << std::endl; } - + protected: optimizer_observer_t() {} }; @@ -151,15 +151,15 @@ refine_one_pair(const image_t * i0, const double & min_step, const double & max_step, const itk::Array & optimizer_scales, - + const bfs::path & fn_prefix = "") { // setup the registration object: registration_t::Pointer registration = registration_t::New(); - + // setup the image interpolator: registration->SetInterpolator(interpolator_t::New()); - + // setup the optimizer: optimizer_t::Pointer optimizer = optimizer_t::New(); registration->SetOptimizer(optimizer); @@ -173,14 +173,14 @@ refine_one_pair(const image_t * i0, optimizer->SetPickUpPaceSteps(5); // FIXME: optimizer->SetBackTracking(true); - + try { optimizer->SetScales(optimizer_scales); } catch (itk::ExceptionObject &err) { CORE_LOG_ERROR(err.GetDescription()); throw; } - + // setup the image-to-image metric: typedef itk::NormalizedCorrelationImageToImageMetric // FIXME: typedef itk::MeanSquaresImageToImageMetric @@ -189,51 +189,51 @@ refine_one_pair(const image_t * i0, metric->SetInterpolator(interpolator_t::New()); metric->SetSubtractMean(true); registration->SetMetric(metric); - + registration->SetTransform(t01); registration->SetInitialTransformParameters(t01->GetParameters()); - + // setup the masks: typedef itk::ImageMaskSpatialObject<2> mask_so_t; mask_t::ConstPointer fi_mask = m0; - if (m0 != NULL) + if (m0 != nullptr) { mask_so_t::Pointer fi_mask_so = mask_so_t::New(); fi_mask_so->SetImage(fi_mask); metric->SetFixedImageMask(fi_mask_so); } - + mask_t::ConstPointer mi_mask = m1; - if (m1 != NULL) + if (m1 != nullptr) { mask_so_t::Pointer mi_mask_so = mask_so_t::New(); mi_mask_so->SetImage(mi_mask); metric->SetMovingImageMask(mi_mask_so); } - + // setup the fixed and moving image: image_t::ConstPointer fi = i0; image_t::ConstPointer mi = i1; - + registration->SetFixedImageRegion(fi->GetLargestPossibleRegion()); registration->SetFixedImage(fi); registration->SetMovingImage(mi); - + // evaluate the metric before the registration: double metric_before = eval_metric(t01, fi, mi, fi_mask, mi_mask); assert(metric_before != std::numeric_limits::max()); - + typename transform_t::ParametersType params_before = t01->GetParameters(); - + if (! fn_prefix.empty()) { try { // try to save the failed mosaic -- sometimes the resulting image // may not fit in memory, so an exception will be thrown: - + save_rgb(fn_prefix.string() + "v0.tif", remap_min_max(fi), remap_min_max(mi), @@ -245,18 +245,18 @@ refine_one_pair(const image_t * i0, throw; } } - + // perform the registration: try { std::cout << "starting image registration:" << std::endl; - registration->StartRegistration(); + registration->Update(); } catch (itk::ExceptionObject & exception) { std::cerr << "image registration threw an exception: " << std::endl << exception << std::endl; - + // FIXME: //#if 1 #ifdef DEBUG_EVERYTHING @@ -264,7 +264,7 @@ refine_one_pair(const image_t * i0, { // try to save the failed mosaic -- sometimes the resulting image // may not fit in memory, so an exception will be thrown: - + save_rgb(fn_prefix.string() + "exception.tif", remap_min_max(fi), remap_min_max(mi), @@ -279,21 +279,21 @@ refine_one_pair(const image_t * i0, throw; } t01->SetParameters(optimizer->GetBestParams()); - + // evaluate the metric after the registration: double metric_after = eval_metric(t01, fi, mi, fi_mask, mi_mask); - + std::cout << "BEFORE: " << metric_before << std::endl << "AFTER: " << metric_after << std::endl; - + if (! fn_prefix.empty()) { try { // try to save the failed mosaic -- sometimes the resulting image // may not fit in memory, so an exception will be thrown: - + save_rgb(fn_prefix.string() + "v1.tif", remap_min_max(fi), remap_min_max(mi), @@ -305,7 +305,7 @@ refine_one_pair(const image_t * i0, throw; } } - + if (metric_before <= metric_after || metric_after != metric_after) { std::cout << "NOTE: minimization failed, ignoring registration results..." @@ -313,7 +313,7 @@ refine_one_pair(const image_t * i0, t01->SetParameters(params_before); return metric_before; } - + return metric_after; } @@ -331,22 +331,22 @@ refine_one_pair(int octave_start, const double & min_step, const double & max_step, const itk::Array & optimizer_scales, - + const bfs::path & fn_prefix = "") { int octave_end = octave_start + 1 - num_octaves; - + double metric = std::numeric_limits::max(); for (int i = octave_start; i >= octave_end; i--) { const unsigned int last_scale = p0.octave_[i].scales() - 1; assert(last_scale + 1 == p1.octave_[i].scales()); - + for (int j = last_scale; j >= 0; j--) { std::ostringstream pfx; pfx << fn_prefix << "o" << the_text_t::number(i) << "-s" << the_text_t::number(j) << "-"; - + metric = refine_one_pair(p0.octave_[i].L_[j], p1.octave_[i].L_[j], p0.octave_[i].mask_, @@ -359,7 +359,7 @@ refine_one_pair(int octave_start, bfs::path(pfx.str())); } } - + return metric; } @@ -375,7 +375,7 @@ refine_one_pair(const pyramid_t & p0, const double & min_step, const double & max_step, const itk::Array & optimizer_scales, - + const bfs::path & fn_prefix = "") { int num_octaves = std::min(p0.octaves(), p1.octaves()); @@ -403,18 +403,18 @@ refine_one_pair(const pyramid_t & p0, const unsigned int iterations, const double & min_step, const double & max_step, - + const bfs::path & fn_prefix = "") { // FIXME: this is probably unnecessary: typedef optimizer_t::ScalesType optimizer_scales_t; optimizer_scales_t scales(t01->GetNumberOfParameters()); scales.Fill(1.0); - + // encourage translation: // scales[transform_t::index_a(0, 0)] = 1e-1; // scales[transform_t::index_b(0, 0)] = 1e-1; - + return refine_one_pair (p0, p1, t01, iterations, min_step, max_step, scales, fn_prefix); } @@ -429,11 +429,11 @@ refine_one_pair(int octave_start, const pyramid_t & p1, const base_transform_t * t_coarse, order4_transform_t::Pointer & t_order4, - + const unsigned int iterations, const double & min_step, const double & max_step, - + const bfs::path & fn_prefix = "") { // encourage translation: @@ -441,39 +441,39 @@ refine_one_pair(int octave_start, scales2.Fill(1e-0); scales2[order2_transform_t::index_a(0, 0)] = 1e-1; scales2[order2_transform_t::index_b(0, 0)] = 1e-1; - + // encourage translation: itk::Array scales4( order4_transform_t::New()->GetNumberOfParameters() ); scales4.Fill(1e-0); scales4[order4_transform_t::index_a(0, 0)] = 1e-1; scales4[order4_transform_t::index_b(0, 0)] = 1e-1; - + base_transform_t::ConstPointer t_previous = t_coarse; double metric = std::numeric_limits::max(); - + int octave_end = octave_start + 1 - num_octaves; for (int i = octave_start; i >= octave_end; i--) { const unsigned int last_scale = p0.octave_[i].scales() - 1; assert(last_scale + 1 == p1.octave_[i].scales()); - + for (int j = last_scale; j >= 0; j--) { const image_t * a = p0.octave_[i].L_[j]; const image_t * b = p1.octave_[i].L_[j]; const mask_t * ma = p0.octave_[i].mask_; const mask_t * mb = p1.octave_[i].mask_; - + // bootstrap the low-order transform: order2_transform_t::Pointer t_order2 = setup_transform(b); solve_for_transform (b, mb, t_previous, t_order2, 16, 2, true); - + // refine the low-order transform: std::ostringstream pfx2; pfx2 << fn_prefix << "o" << the_text_t::number(i) << "-s" << the_text_t::number(j) << "-order2-"; - + metric = refine_one_pair(a, b, ma, @@ -485,16 +485,16 @@ refine_one_pair(int octave_start, scales2, bfs::path(pfx2.str())); t_previous = t_order2; - + // bootstrap the high-order transform: t_order4 = setup_transform(b); solve_for_transform (b, mb, t_previous, t_order4, 16, 1, true); - + // refine the high-order transform: std::ostringstream pfx4; pfx4 << fn_prefix << "o" << the_text_t::number(i) << "-s" << the_text_t::number(j) << "-order4-"; - + metric = refine_one_pair(a, b, ma, @@ -508,7 +508,7 @@ refine_one_pair(int octave_start, t_previous = t_order4; } } - + return metric; } @@ -525,14 +525,14 @@ fast_variance(const image_t * a, const base_transform_t * t_ab, double samples_per_64x64 = 128.0) { - if (t_ab == NULL) return std::numeric_limits::max(); - + if (t_ab == nullptr) return std::numeric_limits::max(); + image_t::SpacingType a_sp = a->GetSpacing(); image_t::SizeType a_sz = a->GetLargestPossibleRegion().GetSize(); pnt2d_t a_min = a->GetOrigin(); pnt2d_t a_max = a_min + vec2d((a_sz[0]) * a_sp[0], (a_sz[1]) * a_sp[1]); - + const double w0 = a_max[0] - a_min[0]; const double h0 = a_max[1] - a_min[1]; const double samples_per_pixel = samples_per_64x64 / (4096.0); @@ -540,55 +540,55 @@ fast_variance(const image_t * a, const double sy = samples_per_pixel * h0; const unsigned int nx = static_cast(sx + 0.5); const unsigned int ny = static_cast(sy + 0.5); - + // uniformly sample the variance in the overlapping region: interpolator_t::Pointer ia = interpolator_t::New(); ia->SetInputImage(a); - + interpolator_t::Pointer ib = interpolator_t::New(); ib->SetInputImage(b); - + double v = 0.0; double n = 0.0; - + pnt2d_t pa; pnt2d_t pb; for (unsigned int i = 1; i <= nx; i++) { double tx = static_cast(i) / static_cast(nx + 1); pa[0] = a_min[0] + tx * w0; - + for (unsigned int j = 1; j <= ny; j++) { double ty = static_cast(j) / static_cast(ny + 1); pa[1] = a_min[1] + ty * h0; if (!ia->IsInsideBuffer(pa)) continue; - + image_t::IndexType index_a; if (!ma->TransformPhysicalPointToIndex(pa, index_a)) continue; if (ma->GetPixel(index_a) == 0) continue; - + pb = t_ab->TransformPoint(pa); if (!ib->IsInsideBuffer(pb)) continue; - + image_t::IndexType index_b; if (!mb->TransformPhysicalPointToIndex(pb, index_b)) continue; if (mb->GetPixel(index_b) == 0) continue; - + double pixel_a = ia->Evaluate(pa); double pixel_b = ib->Evaluate(pb); double mean = (pixel_a + pixel_b) / 2.0; - + double da = pixel_a - mean; double db = pixel_b - mean; - + v += da * da + db * db; n += 1.0; } } - + if (n == 0.0) return std::numeric_limits::max(); - + // return the mean variance: return v / n; } @@ -602,12 +602,12 @@ image_center(const image_t * image) { typename image_t::SizeType sz = image->GetLargestPossibleRegion().GetSize(); typename image_t::SpacingType sp = image->GetSpacing(); - + pnt2d_t min = image->GetOrigin(); pnt2d_t max = min + vec2d(static_cast(sz[0]) * sp[0], static_cast(sz[1]) * sp[1]); pnt2d_t center = min + (max - min) * 0.5; - + return center; } @@ -619,16 +619,16 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR // this is so that the printouts look better: std::cout.precision(6); std::cout.setf(std::ios::scientific); - + // setup thread storage for the main thread: set_the_thread_storage_provider(the_boost_thread_t::thread_storage); the_boost_thread_t MAIN_THREAD_DUMMY; MAIN_THREAD_DUMMY.set_stopped(false); - + // setup thread and mutex interface creators: the_mutex_interface_t::set_creator(the_boost_mutex_t::create); the_thread_interface_t::set_creator(the_boost_thread_t::create); - + // parameters: bfs::path fn_load[2] = { this->input_fixed_, this->input_moving_ }; // bfs::path fn_load_directory[2]; @@ -642,44 +642,44 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR bool flip[2] = { this->flip_fixed_, this->flip_moving_ }; // bool flip[2] = { false, false }; - + bfs::path image_dirs[2]; if ( (this->image_dir_fixed_ != "") && (this->image_dir_moving_ != "") ) { image_dirs[0] = this->image_dir_fixed_; image_dirs[1] = this->image_dir_moving_; } - + bfs::path fn_save(this->output_stos_); - + if (fn_load[0].empty() || fn_load[1].empty()) { CORE_LOG_ERROR("must specify 2 files with the -load option"); return false; } - + if (fn_save.empty()) { CORE_LOG_ERROR("must specify a file to open with the -save option"); return false; } - + // dump the status: std::cout << "shrink factor: " << this->shrink_factor_ << std::endl // << "transform order: " << this->transform_order_ << std::endl << "descriptor: v" << this->descriptor_version_ << std::endl << std::endl; - + bfs::path fn_debug; #ifdef DEBUG_EVERYTHING fn_debug = fn_save.string() + ".FIXME-"; #endif - + // load the images, assemble the pyramids, match them: image_t::Pointer mosaic[2]; mask_t::Pointer mosaic_mask[2]; pyramid_t pyramid[2]; - + if (fn_load[0].extension() == ".mosaic") { load_slice(fn_load[0], @@ -689,7 +689,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR image_dirs[0], mosaic[0], mosaic_mask[0]); - + setup_pyramid(pyramid[0], 0, fn_load[0], @@ -704,11 +704,11 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR { // load the pyramid: load_pyramid(fn_load[0], pyramid[0], mosaic[0], mosaic_mask[0]); - + std::cout << " generating keys: "; pyramid[0].generate_keys(); std::cout << pyramid[0].count_keys() << std::endl; - + std::cout << " generating descriptors" << std::endl; pyramid[0].generate_descriptors(this->descriptor_version_); } @@ -718,7 +718,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR mosaic[0] = std_tile(fn_load[0], this->shrink_factor_, this->pixel_spacing_); - + if (! fn_mask[0].empty()) { // load slice mask: @@ -730,7 +730,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR { mosaic_mask[0] = std_mask(mosaic[0], this->use_standard_mask_); } - + setup_pyramid(pyramid[0], 0, fn_load[0], @@ -741,7 +741,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR true, // generate descriptors? fn_debug); } - + if (fn_load[1].extension() == ".mosaic") { load_slice(fn_load[1], @@ -751,7 +751,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR image_dirs[1], mosaic[1], mosaic_mask[1]); - + setup_pyramid(pyramid[1], 1, fn_load[1], @@ -766,11 +766,11 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR { // load the pyramid: load_pyramid(fn_load[1], pyramid[1], mosaic[1], mosaic_mask[1]); - + std::cout << " generating keys: "; pyramid[1].generate_keys(); std::cout << pyramid[1].count_keys() << std::endl; - + std::cout << " generating descriptors" << std::endl; pyramid[1].generate_descriptors(this->descriptor_version_); } @@ -780,7 +780,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR mosaic[1] = std_tile(fn_load[1], this->shrink_factor_, this->pixel_spacing_); - + if (! fn_mask[1].empty()) { // load slice mask: @@ -792,7 +792,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR { mosaic_mask[1] = std_mask(mosaic[1], this->use_standard_mask_); } - + setup_pyramid(pyramid[1], 1, fn_load[1], @@ -803,10 +803,10 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR true, // generate descriptors? fn_debug); } - + pyramid[0].debug(fn_debug.string() + "p0-"); pyramid[1].debug(fn_debug.string() + "p1-"); - + // solve for the transform mapping between the adjacent slices: order2_transform_t::Pointer t_coarse = match(order2_transform_t::Degree + 1, @@ -814,7 +814,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR pyramid[0], pyramid[1], fn_debug); - + // calculate the octave range for initial transform estimation // (low-order, or constrained high-order): int octave_start = std::min(pyramid[0].octaves(), @@ -824,7 +824,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR std::min(3, static_cast(std::min(pyramid[0].octaves(), pyramid[1].octaves()))), 0); - + // try to minimize the mismatch via energy minimization: order4_transform_t::Pointer t_order4; refine_one_pair(octave_start, @@ -837,16 +837,16 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR 1e-12, 1e-3, // FIXME: 1e-6 fn_debug); - + if (octave_end > 0) { itk::Array scales( t_order4->GetNumberOfParameters() ); scales.Fill(1e-0); - + // encourage translation: scales[order4_transform_t::index_a(0, 0)] = 1e-1; scales[order4_transform_t::index_b(0, 0)] = 1e-1; - + // Avoid ruining the previous transform results due to image // artifacts in the low resolution octaves of the pyramid. // Start with the next unprocessed octave and complete the process @@ -862,7 +862,7 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR scales, fn_debug.string() + "final-"); } - + // save the slice-to-slice transform: save_stos(fn_save, fn_load[0], @@ -876,9 +876,9 @@ ActionSliceToSliceFilter::run( Core::ActionContextHandle& context, Core::ActionR this->shrink_factor_, t_order4, true); - + CORE_LOG_SUCCESS("ir-stos done"); - + // done: return true; } @@ -927,7 +927,7 @@ ActionSliceToSliceFilter::Dispatch(Core::ActionContextHandle context, { // Create a new action ActionSliceToSliceFilter* action = new ActionSliceToSliceFilter; - + // Setup the parameters action->target_layer_ = target_layer; action->shrink_factor_ = shrink_factor; @@ -943,7 +943,7 @@ ActionSliceToSliceFilter::Dispatch(Core::ActionContextHandle context, action->mask_moving_ = mask_moving; action->image_dir_fixed_ = image_dir_fixed; action->image_dir_moving_ = image_dir_moving; - + // Dispatch action to underlying engine Core::ActionDispatcher::PostAction( Core::ActionHandle( action ), context ); } diff --git a/src/Application/Layer/DataLayer.cc b/src/Application/Layer/DataLayer.cc index aa8ed30fc..a6fc17d99 100644 --- a/src/Application/Layer/DataLayer.cc +++ b/src/Application/Layer/DataLayer.cc @@ -29,7 +29,7 @@ // STL includes #include -// Boost includes +// Boost includes #include // Core includes @@ -71,7 +71,7 @@ void DataLayer::initialize_states() { boost::mutex::scoped_lock lock(data_ColorCountMutex); - this->private_->layer_->add_state("color", this->private_->layer_->color_state_, + this->private_->layer_->add_state("color", this->private_->layer_->color_state_, static_cast(data_ColorCount % PreferencesManager::Instance()->color_states_.size())); data_ColorCount++; @@ -131,8 +131,8 @@ void DataLayerPrivate::update_data_info() this->layer_->max_value_state_->set( std::numeric_limits< double >::quiet_NaN() ); return; } - - this->layer_->centering_state_->set( + + this->layer_->centering_state_->set( this->layer_->get_grid_transform().get_originally_node_centered() ? "node" : "cell" ); switch ( this->layer_->get_data_type() ) @@ -155,6 +155,12 @@ void DataLayerPrivate::update_data_info() case Core::DataType::UINT_E: this->layer_->data_type_state_->set( "unsigned int" ); break; + case Core::DataType::LONGLONG_E: + this->layer_->data_type_state_->set( "long long" ); + break; + case Core::DataType::ULONGLONG_E: + this->layer_->data_type_state_->set( "unsigned long long" ); + break; case Core::DataType::FLOAT_E: this->layer_->data_type_state_->set( "float" ); break; @@ -162,7 +168,7 @@ void DataLayerPrivate::update_data_info() this->layer_->data_type_state_->set( "double" ); break; } - + this->layer_->min_value_state_->set( this->layer_->data_volume_->get_min() ); this->layer_->max_value_state_->set( this->layer_->data_volume_->get_max() ); } @@ -170,7 +176,7 @@ void DataLayerPrivate::update_data_info() void DataLayerPrivate::update_display_value_range() { if ( !this->layer_->has_valid_data() ) return; - + { Core::ScopedCounter signal_block( this->signal_block_count_ ); double min_val = this->layer_->get_data_volume()->get_min(); @@ -188,7 +194,7 @@ void DataLayerPrivate::handle_contrast_brightness_changed() { return; } - + Core::ScopedCounter signal_block( this->signal_block_count_ ); // Convert contrast to range ( 0, 1 ] and brightness to [ 0, 2 ] @@ -220,7 +226,7 @@ void DataLayerPrivate::handle_display_value_range_changed() { std::swap( display_min, display_max ); } - + double contrast = 1.0 - ( display_max - display_min ) / ( max_val - min_val ); double brightness = ( max_val * 2 - display_min - display_max ) / ( max_val - min_val ); this->layer_->contrast_state_->set( contrast * 100 ); @@ -239,7 +245,7 @@ DataLayer::DataLayer( const std::string& name, const Core::DataVolumeHandle& vol this->initialize_states(); this->private_->update_display_value_range(); } - + DataLayer::DataLayer( const std::string& state_id ) : Layer( "not initialized", state_id ), private_( new DataLayerPrivate ) @@ -259,13 +265,13 @@ DataLayer::~DataLayer() } } -Core::GridTransform DataLayer::get_grid_transform() const -{ +Core::GridTransform DataLayer::get_grid_transform() const +{ Layer::lock_type lock( Layer::GetMutex() ); if ( this->data_volume_ ) { - return this->data_volume_->get_grid_transform(); + return this->data_volume_->get_grid_transform(); } else { @@ -273,14 +279,14 @@ Core::GridTransform DataLayer::get_grid_transform() const } } -void DataLayer::set_grid_transform( const Core::GridTransform& grid_transform, +void DataLayer::set_grid_transform( const Core::GridTransform& grid_transform, bool preserve_centering ) { Layer::lock_type lock( Layer::GetMutex() ); if ( this->data_volume_ ) { - this->data_volume_->set_grid_transform( grid_transform, preserve_centering ); + this->data_volume_->set_grid_transform( grid_transform, preserve_centering ); } } @@ -292,7 +298,7 @@ Core::DataType DataLayer::get_data_type() const { return this->data_volume_->get_data_type(); } - + return Core::DataType::UNKNOWN_E; } @@ -333,12 +339,12 @@ Core::VolumeHandle DataLayer::get_volume() const } bool DataLayer::set_data_volume( Core::DataVolumeHandle data_volume ) -{ +{ ASSERT_IS_APPLICATION_THREAD(); // Only insert the volume if the layer is still valid if ( !this->is_valid() ) return false; - + { Layer::lock_type lock( Layer::GetMutex() ); @@ -347,8 +353,8 @@ bool DataLayer::set_data_volume( Core::DataVolumeHandle data_volume ) // Unregister the old volume this->data_volume_->unregister_data(); } - - this->data_volume_ = data_volume; + + this->data_volume_ = data_volume; if ( this->data_volume_ ) { @@ -362,7 +368,7 @@ bool DataLayer::set_data_volume( Core::DataVolumeHandle data_volume ) } return true; -} +} bool DataLayer::pre_save_states( Core::StateIO& state_io ) { @@ -373,31 +379,31 @@ bool DataLayer::pre_save_states( Core::StateIO& state_io ) // Add the number to the project so it can be recorded into the session database ProjectManager::Instance()->get_current_project()->add_generation_number( generation_number ); - + std::string data_file_name = this->generation_state_->export_to_string() + ".nrrd"; boost::filesystem::path full_data_file_name = ProjectManager::Instance()-> get_current_project()->get_project_data_path() / data_file_name; - + if ( boost::filesystem::exists( full_data_file_name ) ) { // File has already been saved return true; } - + bool compress = PreferencesManager::Instance()->compression_state_->get(); int level = PreferencesManager::Instance()->compression_level_state_->get(); - + std::string error; - if ( ! Core::DataVolume::SaveDataVolume( full_data_file_name.string(), this->data_volume_, + if ( ! Core::DataVolume::SaveDataVolume( full_data_file_name.string(), this->data_volume_, error, compress, level ) ) { CORE_LOG_ERROR( error ); - return false; + return false; } return true; } - + return true; } @@ -409,7 +415,7 @@ bool DataLayer::post_load_states( const Core::StateIO& state_io ) boost::filesystem::path volume_path = ProjectManager::Instance()->get_current_project()-> get_project_data_path() / generation; std::string error; - + if( Core::DataVolume::LoadDataVolume( volume_path, this->data_volume_, error ) ) { this->data_volume_->register_data( this->generation_state_->get() ); @@ -429,25 +435,25 @@ bool DataLayer::post_load_states( const Core::StateIO& state_io ) return false; } - + void DataLayer::clean_up() { // Abort any filter still using this layer this->abort_signal_(); - + // Clean up the data that is still associated with this layer { Layer::lock_type lock( Layer::GetMutex() ); - if ( this->data_volume_ ) + if ( this->data_volume_ ) { this->data_volume_->unregister_data(); - Core::DataVolume::CreateInvalidData( this->data_volume_->get_grid_transform(), + Core::DataVolume::CreateInvalidData( this->data_volume_->get_grid_transform(), this->data_volume_ ); } } - + // Remove all the connections - this->disconnect_all(); + this->disconnect_all(); } LayerHandle DataLayer::duplicate() const @@ -460,7 +466,7 @@ LayerHandle DataLayer::duplicate() const // NOTE: return an empty handle return layer; } - + return DataLayerHandle( new DataLayer( "Copy_" + this->get_layer_name(), data_volume ) ); } @@ -478,4 +484,3 @@ void DataLayer::SetColorCount(size_t count) } } // end namespace Seg3D - diff --git a/src/Application/Layer/LargeVolumeLayer.cc b/src/Application/Layer/LargeVolumeLayer.cc index 1a5c7be62..61b9b0ae9 100644 --- a/src/Application/Layer/LargeVolumeLayer.cc +++ b/src/Application/Layer/LargeVolumeLayer.cc @@ -29,7 +29,7 @@ // STL includes #include -// Boost includes +// Boost includes #include // Core includes @@ -71,8 +71,8 @@ void LargeVolumeLayerPrivate::update_data_info() this->layer_->max_value_state_->set( std::numeric_limits< double >::quiet_NaN() ); return; } - - this->layer_->centering_state_->set( + + this->layer_->centering_state_->set( this->layer_->get_grid_transform().get_originally_node_centered() ? "node" : "cell" ); switch ( this->layer_->get_data_type() ) @@ -95,6 +95,12 @@ void LargeVolumeLayerPrivate::update_data_info() case Core::DataType::UINT_E: this->layer_->data_type_state_->set( "unsigned int" ); break; + case Core::DataType::LONGLONG_E: + this->layer_->data_type_state_->set( "long long" ); + break; + case Core::DataType::ULONGLONG_E: + this->layer_->data_type_state_->set( "unsigned long long" ); + break; case Core::DataType::FLOAT_E: this->layer_->data_type_state_->set( "float" ); break; @@ -102,7 +108,7 @@ void LargeVolumeLayerPrivate::update_data_info() this->layer_->data_type_state_->set( "double" ); break; } - + this->layer_->min_value_state_->set( this->volume_->get_min() ); this->layer_->max_value_state_->set( this->volume_->get_max() ); } @@ -110,7 +116,7 @@ void LargeVolumeLayerPrivate::update_data_info() void LargeVolumeLayerPrivate::update_display_value_range() { if ( !this->layer_->has_valid_data() ) return; - + { Core::ScopedCounter signal_block( this->signal_block_count_ ); double min_val = this->volume_->get_min(); @@ -128,7 +134,7 @@ void LargeVolumeLayerPrivate::handle_contrast_brightness_changed() { return; } - + Core::ScopedCounter signal_block( this->signal_block_count_ ); // Convert contrast to range ( 0, 1 ] and brightness to [ 0, 2 ] @@ -160,7 +166,7 @@ void LargeVolumeLayerPrivate::handle_display_value_range_changed() { std::swap( display_min, display_max ); } - + double contrast = 1.0 - ( display_max - display_min ) / ( max_val - min_val ); double brightness = ( max_val * 2 - display_min - display_max ) / ( max_val - min_val ); this->layer_->contrast_state_->set( contrast * 100 ); @@ -180,7 +186,7 @@ LargeVolumeLayer::LargeVolumeLayer( const std::string& name, Core::LargeVolumeSc this->private_->update_display_value_range(); } -LargeVolumeLayer::LargeVolumeLayer( const std::string& name, Core::LargeVolumeSchemaHandle schema, +LargeVolumeLayer::LargeVolumeLayer( const std::string& name, Core::LargeVolumeSchemaHandle schema, const Core::GridTransform& crop_trans ) : Layer( name ), private_( new LargeVolumeLayerPrivate ) @@ -217,7 +223,7 @@ boost::mutex lv_ColorCountMutex; void LargeVolumeLayer::initialize_states() { // NOTE: This function allows setting of state variables outside of application thread - this->set_initializing( true ); + this->set_initializing( true ); this->add_state( "dir_name", this->dir_name_state_, "" ); @@ -235,7 +241,7 @@ void LargeVolumeLayer::initialize_states() this->add_state("colormap", this->colormap_state_, PreferencesManager::Instance()-> default_colormap_state_->export_to_string(), PreferencesManager::Instance()-> default_colormap_state_->export_list_to_string()); - + // == The brightness of the layer == this->add_state( "brightness", brightness_state_, 50.0, 0.0, 100.0, 0.1 ); @@ -272,8 +278,8 @@ void LargeVolumeLayer::initialize_states() this->set_initializing( false ); } -Core::GridTransform LargeVolumeLayer::get_grid_transform() const -{ +Core::GridTransform LargeVolumeLayer::get_grid_transform() const +{ Layer::lock_type lock( Layer::GetMutex() ); if ( this->private_->volume_ ) @@ -286,7 +292,7 @@ Core::GridTransform LargeVolumeLayer::get_grid_transform() const } } -void LargeVolumeLayer::set_grid_transform( const Core::GridTransform& grid_transform, +void LargeVolumeLayer::set_grid_transform( const Core::GridTransform& grid_transform, bool preserve_centering ) { Layer::lock_type lock( Layer::GetMutex() ); @@ -305,7 +311,7 @@ Core::DataType LargeVolumeLayer::get_data_type() const { return this->private_->volume_->get_data_type(); } - + return Core::DataType::UNKNOWN_E; } @@ -328,7 +334,7 @@ Core::VolumeHandle LargeVolumeLayer::get_volume() const } bool LargeVolumeLayer::pre_save_states( Core::StateIO& state_io ) -{ +{ return true; } @@ -337,7 +343,7 @@ bool LargeVolumeLayer::post_load_states( const Core::StateIO& state_io ) Core::LargeVolumeSchemaHandle schema( new Core::LargeVolumeSchema); schema->set_dir( this->dir_name_state_->get() ); std::string error; - + if (! schema->load( error) ) { CORE_LOG_ERROR( error ); @@ -358,14 +364,14 @@ bool LargeVolumeLayer::post_load_states( const Core::StateIO& state_io ) return true; } - + void LargeVolumeLayer::clean_up() { // Abort any filter still using this layer this->abort_signal_(); - + // Remove all the connections - this->disconnect_all(); + this->disconnect_all(); } LayerHandle LargeVolumeLayer::duplicate() const @@ -379,4 +385,3 @@ Core::LargeVolumeSchemaHandle LargeVolumeLayer::get_schema() const } } // end namespace Seg3D - diff --git a/src/Application/LayerIO/GDCMLayerImporter.cc b/src/Application/LayerIO/GDCMLayerImporter.cc index 8e1f1aae1..de3c084b7 100644 --- a/src/Application/LayerIO/GDCMLayerImporter.cc +++ b/src/Application/LayerIO/GDCMLayerImporter.cc @@ -221,6 +221,12 @@ bool GDCMLayerImporterPrivate::read_header() case gdcm::PixelFormat::UINT32: this->pixel_type_ = Core::DataType::UINT_E; break; + case gdcm::PixelFormat::INT64: + this->pixel_type_ = Core::DataType::LONGLONG_E; + break; + case gdcm::PixelFormat::UINT64: + this->pixel_type_ = Core::DataType::ULONGLONG_E; + break; case gdcm::PixelFormat::FLOAT32: this->pixel_type_ = Core::DataType::FLOAT_E; break; diff --git a/src/Application/LayerIO/ITKLayerImporter.cc b/src/Application/LayerIO/ITKLayerImporter.cc index 4ead9ae00..4eadcd3a3 100644 --- a/src/Application/LayerIO/ITKLayerImporter.cc +++ b/src/Application/LayerIO/ITKLayerImporter.cc @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -54,6 +53,7 @@ // Application includes #include +#include #ifdef _WIN32 #define snprintf _snprintf @@ -74,28 +74,24 @@ class ITKLayerImporterPrivate read_data_( false ) { } - + // Pointer back to the main class ITKLayerImporter* importer_; -public: +public: // READ_HEADER // Read the header of the file bool read_header(); - + // READ_DATA // Read the data from the file bool read_data(); - - // CONVERT_DATA_TYPE: - // Copy the data type we get from itk and convert to a Seg3D enum type - Core::DataType convert_data_type( std::string& type ); // SCAN_SIMPLE_VOLUME: // Scan the data file template< class ItkImporterType > bool scan_simple_volume(); - + // IMPORT_SIMPLE_TYPED_VOLUME: // Read the data in its final format template< class DataType, class ItkImporterType > @@ -106,7 +102,7 @@ class ITKLayerImporterPrivate template< class ItkImporterType > bool import_simple_volume(); - + public: // File type that we are importing std::string file_type_; @@ -119,10 +115,10 @@ class ITKLayerImporterPrivate // The data that was read from the file Core::DataBlockHandle data_block_; - + // Whether the header was read bool read_header_; - + // Whether the data was read bool read_data_; @@ -152,7 +148,7 @@ class ITKLayerImporterPrivate { return ( extension == ".img" || extension == ".hdr" ); } - + bool detect_nifti( const std::string& extension ) { return ( extension == ".nii" || extension == ".nii.gz" ); @@ -164,54 +160,12 @@ class ITKLayerImporterPrivate } }; -Core::DataType ITKLayerImporterPrivate::convert_data_type( std::string& type ) -{ - // Convert ITK types into our enum - if ( type == "unsigned_char" ) - { - return Core::DataType::UCHAR_E; - } - else if ( type == "char" ) - { - return Core::DataType::CHAR_E; - } - else if ( type == "unsigned_short" ) - { - return Core::DataType::USHORT_E; - } - else if ( type == "short" ) - { - return Core::DataType::SHORT_E; - } - else if ( type == "unsigned_int" ) - { - return Core::DataType::UINT_E; - } - else if ( type == "int" ) - { - return Core::DataType::INT_E; - } - else if ( type == "float" ) - { - return Core::DataType::FLOAT_E; - } - else if ( type == "double" ) - { - return Core::DataType::DOUBLE_E; - } - else - { - // NOTE: Defaults to float if not known - return Core::DataType::FLOAT_E; - } -} - template< class ItkImporterType > bool ITKLayerImporterPrivate::scan_simple_volume() { // If header was already read, just return if ( this->read_header_ ) return true; - + typedef itk::ImageFileReader< itk::Image< unsigned char, 3 > > ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); @@ -238,15 +192,12 @@ bool ITKLayerImporterPrivate::scan_simple_volume() return false; } - // Grab the information on the data type from the ITK image - std::string type_string = IO->GetComponentTypeAsString( IO->GetComponentType() ); - // Grab the image from the output so we can read its transform Core::ITKUCharImageDataHandle image_data; try { - image_data = Core::ITKUCharImageDataHandle( - new typename Core::ITKUCharImageData( reader->GetOutput() ) ); + image_data = Core::ITKUCharImageDataHandle( + new typename Core::ITKUCharImageData( reader->GetOutput() ) ); } catch ( ... ) { @@ -255,9 +206,9 @@ bool ITKLayerImporterPrivate::scan_simple_volume() } // Store the information we just extracted from the file in this private class - this->data_type_ = this->convert_data_type( type_string ); + this->data_type_ = convert_data_type(IO->GetComponentType()); this->grid_transform_ = image_data->get_grid_transform(); - + // Header was read, hence mark it so we will not read it again. this->read_header_ = true; return true; @@ -290,28 +241,30 @@ bool ITKLayerImporterPrivate::read_header() this->file_type_ = "VTK"; return this->scan_simple_volume< itk::VTKImageIO >(); } - else if ( detect_lsm( extension ) ) + else if ( detect_lsm( extension ) ) { this->file_type_ = "LSM"; return this->scan_simple_volume< itk::LSMImageIO >(); } - else if ( detect_analyze( extension ) ) + else if ( detect_analyze( extension ) ) { this->file_type_ = "Analyze"; - return this->scan_simple_volume< itk::AnalyzeImageIO >(); - } - else if ( detect_nifti( extension ) ) + //Check if scan_simple_volume needs more settings for analyze? + //See function SetLegacyAnalyze75Mode - https://itk.org/Doxygen/html/classitk_1_1NiftiImageIO.html + return this->scan_simple_volume< itk::NiftiImageIO >(); + } + else if ( detect_nifti( extension ) ) { this->file_type_ = "NIfTY"; return this->scan_simple_volume< itk::NiftiImageIO >(); - } + } else if ( detect_metaimage( extension ) ) { this->file_type_ = "MetaIO"; return this->scan_simple_volume< itk::MetaImageIO >(); - } + } this->importer_->set_error( "Unknown file format." ); - return false; + return false; } template< class DataType, class ItkImporterType > @@ -356,8 +309,8 @@ bool ITKLayerImporterPrivate::import_simple_typed_volume() typename Core::ITKImageDataT< DataType >::Handle image_data; try { - image_data = typename Core::ITKImageDataT< DataType >::Handle( - new typename Core::ITKImageDataT< DataType >( reader->GetOutput() ) ); + image_data = typename Core::ITKImageDataT< DataType >::Handle( + new typename Core::ITKImageDataT< DataType >( reader->GetOutput() ) ); } catch ( ... ) { @@ -382,7 +335,7 @@ bool ITKLayerImporterPrivate::import_simple_typed_volume() template< class ItkImporterType > bool ITKLayerImporterPrivate::import_simple_volume() -{ +{ // For each data type instantiate the right reader switch( this->data_type_ ) { @@ -398,12 +351,16 @@ bool ITKLayerImporterPrivate::import_simple_volume() return this->import_simple_typed_volume< unsigned int, ItkImporterType >(); case Core::DataType::INT_E: return this->import_simple_typed_volume< int, ItkImporterType >(); + case Core::DataType::ULONGLONG_E: + return this->import_simple_typed_volume< unsigned long long, ItkImporterType >(); + case Core::DataType::LONGLONG_E: + return this->import_simple_typed_volume< signed long long, ItkImporterType >(); case Core::DataType::FLOAT_E: return this->import_simple_typed_volume< float, ItkImporterType >(); case Core::DataType::DOUBLE_E: return this->import_simple_typed_volume< double, ItkImporterType >(); default: - return false; + return false; } } @@ -416,7 +373,7 @@ bool ITKLayerImporterPrivate::read_data() { if ( ! this->read_header() ) return false; } - + // Get the extension of the file boost::filesystem::path full_filename( this->importer_->get_filename() ); std::string extension, base; @@ -433,27 +390,27 @@ bool ITKLayerImporterPrivate::read_data() else if ( detect_vtk( extension ) ) { return this->import_simple_volume(); - } - else if ( detect_lsm( extension ) ) + } + else if ( detect_lsm( extension ) ) { return this->import_simple_volume(); - } - else if ( detect_analyze( extension ) ) + } + else if ( detect_analyze( extension ) ) { - return this->import_simple_volume(); - } - else if ( detect_nifti( extension ) ) + return this->import_simple_volume(); + } + else if ( detect_nifti( extension ) ) { return this->import_simple_volume(); - } + } else if ( detect_metaimage( extension ) ) { - return this->import_simple_volume(); + return this->import_simple_volume(); } // In case no file extension matched this->importer_->set_error( "Unknown file format." ); - return false; + return false; } ////////////////////////////////////////////////////////////////////////////////////// @@ -472,36 +429,36 @@ ITKLayerImporter::~ITKLayerImporter() bool ITKLayerImporter::get_file_info( LayerImporterFileInfoHandle& info ) { try - { + { // Try to read the header if ( ! this->private_->read_header() ) return false; - + // Generate an information structure with the information. info = LayerImporterFileInfoHandle( new LayerImporterFileInfo ); info->set_data_type( this->private_->data_type_ ); info->set_grid_transform( this->private_->grid_transform_ ); - info->set_file_type( this->private_->file_type_ ); + info->set_file_type( this->private_->file_type_ ); info->set_mask_compatible( true ); } catch ( ... ) { // In case something failed, recover from here and let the user - // deal with the error. + // deal with the error. this->set_error( "ITK Importer crashed while reading file." ); return false; } - + return true; } bool ITKLayerImporter::get_file_data( LayerImporterFileDataHandle& data ) { try - { + { // Read the data from the file if ( !this->private_->read_data() ) return false; - - // Create a data structure with handles to the actual data in this file + + // Create a data structure with handles to the actual data in this file data = LayerImporterFileDataHandle( new LayerImporterFileData ); data->set_data_block( this->private_->data_block_ ); data->set_grid_transform( this->private_->grid_transform_ ); @@ -510,7 +467,7 @@ bool ITKLayerImporter::get_file_data( LayerImporterFileDataHandle& data ) catch ( ... ) { // In case something failed, recover from here and let the user - // deal with the error. + // deal with the error. this->set_error( "ITK Importer crashed when reading file." ); return false; } @@ -518,7 +475,7 @@ bool ITKLayerImporter::get_file_data( LayerImporterFileDataHandle& data ) return true; } -bool CopyITKFile( const boost::filesystem::path& src, +bool CopyITKFile( const boost::filesystem::path& src, const boost::filesystem::path& dst ) { boost::filesystem::path full_filename = src; @@ -535,23 +492,23 @@ bool CopyITKFile( const boost::filesystem::path& src, CORE_LOG_ERROR( std::string( "Could not copy file '" ) + src.string() + "' to '" + dst.string() + "'." ); return false; - } + } return true; } std::vector< boost::filesystem::path > data_files; - // Copy and update header file for ITK's MetaIO format + // Copy and update header file for ITK's MetaIO format try { boost::filesystem::path input_header_name( src.string() ); boost::filesystem::path output_header_name( dst.string() ); - + std::ifstream old_file_header( input_header_name.filename().c_str(), std::ios::binary ); std::ofstream new_file_header( output_header_name.filename().c_str(), std::ios::binary ); - + bool need_to_write_file_list = false; - + while( !old_file_header.eof() ) { // Grab the next line @@ -563,7 +520,7 @@ bool CopyITKFile( const boost::filesystem::path& src, { size_t index; while ( index < line.size() && line[ index ] != '=' ) index++; - + std::string contents = line.substr( index + 1 ); std::vector components; if ( Core::ImportFromString( contents, components ) ) @@ -580,7 +537,7 @@ bool CopyITKFile( const boost::filesystem::path& src, { // MetaIO format new_file_header << "ElementDataFile = LIST" << std::endl; - + // Copy over every entry and fix the name of the file to be local while( !old_file_header.eof() ) { @@ -590,7 +547,7 @@ bool CopyITKFile( const boost::filesystem::path& src, data_files.push_back( filename ); need_to_write_file_list = true; } - + // Translation is complete there are no entries after LIST break; } @@ -614,12 +571,12 @@ bool CopyITKFile( const boost::filesystem::path& src, src.string() + "'." ); return false; } - + for (int index = start; index <= stop; index += step ) - { + { snprintf( &buffer[ 0 ], buffer.size() - 1, components[ 0 ].c_str(), index ); boost::filesystem::path filename( &buffer[ 0 ] ); - data_files.push_back( filename ); + data_files.push_back( filename ); } need_to_write_file_list = true; } @@ -635,8 +592,8 @@ bool CopyITKFile( const boost::filesystem::path& src, // Copy the entry to cached file new_file_header << line << std::endl; } - } - + } + // Data file list needs to be at the end of the file if ( need_to_write_file_list ) { @@ -651,7 +608,7 @@ bool CopyITKFile( const boost::filesystem::path& src, { CORE_LOG_ERROR( std::string( "Could not copy and update header file '" ) + src.string() + "'." ); - return false; + return false; } // Copy the raw data files to the local cache directory @@ -659,7 +616,7 @@ bool CopyITKFile( const boost::filesystem::path& src, { try { - boost::filesystem::copy_file( data_files[ j ], + boost::filesystem::copy_file( data_files[ j ], dst.parent_path() / data_files[ j ].filename() ); } catch( ... ) @@ -670,7 +627,7 @@ bool CopyITKFile( const boost::filesystem::path& src, } // Successfully copied data file and generated new header. - return true; + return true; } @@ -686,11 +643,11 @@ InputFilesImporterHandle ITKLayerImporter::get_inputfiles_importer() } catch ( ... ) { - this->set_error( std::string( "Could not resolve filename '" ) + + this->set_error( std::string( "Could not resolve filename '" ) + this->get_filename() + "'." ); } - + return importer; } - + } // end namespace seg3D diff --git a/src/Application/LayerIO/ITKSeriesLayerImporter.cc b/src/Application/LayerIO/ITKSeriesLayerImporter.cc index 876956b55..ee48a240d 100644 --- a/src/Application/LayerIO/ITKSeriesLayerImporter.cc +++ b/src/Application/LayerIO/ITKSeriesLayerImporter.cc @@ -69,24 +69,20 @@ class ITKSeriesLayerImporterPrivate // Pointer back to the main class ITKSeriesLayerImporter* importer_; -public: +public: // READ_HEADER // Read the header of the file bool read_header(); - + // READ_DATA // Read the data from the file bool read_data(); - - // CONVERT_DATA_TYPE: - // Copy the data type we get from itk and convert to a Seg3D enum type - Core::DataType convert_data_type( std::string& type ); // SCAN_SIMPLE_SERIES: // Scan the data file template< class ItkImporterType > bool scan_simple_series(); - + // IMPORT_SIMPLE_TYPED_SERIES: // Read the data in its final format template< class DataType, class ItkImporterType > @@ -95,7 +91,7 @@ class ITKSeriesLayerImporterPrivate // IMPORT_SIMPLE_SERIES: // Import the series in its final format by choosing the right format template< class ItkImporterType > - bool import_simple_series(); + bool import_simple_series(); public: // File type that we are importing @@ -109,47 +105,54 @@ class ITKSeriesLayerImporterPrivate // The data that was read from the file Core::DataBlockHandle data_block_; - + // Whether the header was read bool read_header_; - + // Whether the data was read bool read_data_; }; - -Core::DataType ITKSeriesLayerImporterPrivate::convert_data_type( std::string& type ) +Core::DataType convert_data_type(itk::CommonEnums::IOComponent type ) { // Convert ITK types into our enum - if ( type == "unsigned_char" ) + if ( type == itk::CommonEnums::IOComponent::UCHAR) { return Core::DataType::UCHAR_E; } - else if ( type == "char" ) + else if ( type == itk::CommonEnums::IOComponent::CHAR ) { return Core::DataType::CHAR_E; } - else if ( type == "unsigned_short" ) + else if ( type == itk::CommonEnums::IOComponent::USHORT ) { return Core::DataType::USHORT_E; } - else if ( type == "short" ) + else if ( type == itk::CommonEnums::IOComponent::SHORT ) { return Core::DataType::SHORT_E; } - else if ( type == "unsigned_int" ) + else if ( type == itk::CommonEnums::IOComponent::UINT) { return Core::DataType::UINT_E; } - else if ( type == "int" ) + else if ( type == itk::CommonEnums::IOComponent::INT) { return Core::DataType::INT_E; } - else if ( type == "float" ) + else if ( type == itk::CommonEnums::IOComponent::ULONGLONG ) + { + return Core::DataType::ULONGLONG_E; + } + else if ( type == itk::CommonEnums::IOComponent::LONGLONG ) + { + return Core::DataType::LONGLONG_E; + } + else if ( type == itk::CommonEnums::IOComponent::FLOAT) { return Core::DataType::FLOAT_E; } - else if ( type == "double" ) + else if ( type == itk::CommonEnums::IOComponent::DOUBLE) { return Core::DataType::DOUBLE_E; } @@ -164,13 +167,13 @@ bool ITKSeriesLayerImporterPrivate::read_header() { // If importing already succeeded, don't do it again if ( this->read_header_ ) return true; - + // Extract the extension from the file name and use this to define // which importer to use. boost::filesystem::path full_filename( this->importer_->get_filename() ); std::string extension, base; std::tie( extension, base ) = Core::GetFullExtension( full_filename ); - + if ( extension == ".png" ) { this->file_type_ = "png"; @@ -196,7 +199,7 @@ bool ITKSeriesLayerImporterPrivate::read_header() this->file_type_ = "VTK"; return this->scan_simple_series< itk::VTKImageIO >(); } - else + else { // Assume it is DICOM return this->scan_simple_series< itk::GDCMImageIO >(); @@ -236,24 +239,21 @@ bool ITKSeriesLayerImporterPrivate::scan_simple_series() return false; } - // Grab the information on the data type from the ITK image - std::string type_string = IO->GetComponentTypeAsString( IO->GetComponentType() ); - // Grab the image from the output so we can read its transform Core::ITKUCharImage2DDataHandle image_data; try { - image_data = Core::ITKUCharImage2DDataHandle( - new typename Core::ITKUCharImage2DData( reader->GetOutput() ) ); + image_data = Core::ITKUCharImage2DDataHandle( + new typename Core::ITKUCharImage2DData( reader->GetOutput() ) ); } catch ( ... ) { this->importer_->set_error( "Importer could not unwrap itk object." ); return false; - } - + } + // Store the information we just extracted from the file in this private class - this->data_type_ = this->convert_data_type( type_string ); + this->data_type_ = convert_data_type(IO->GetComponentType()); this->grid_transform_ = image_data->get_grid_transform(); this->read_header_ = true; @@ -272,7 +272,7 @@ bool ITKSeriesLayerImporterPrivate::import_simple_typed_series() // levels. However converting everything to float is inefficient. Hence we prefer actual // datatypes if we can obtain them. Hence this class is templated with the right type in // mind. - + typedef itk::Image< DataType, 3 > ImageType; typedef itk::ImageSeriesReader< ImageType > ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); @@ -304,15 +304,15 @@ bool ITKSeriesLayerImporterPrivate::import_simple_typed_series() typename Core::ITKImageDataT< DataType >::Handle image_data; try { - image_data = typename Core::ITKImageDataT< DataType >::Handle( - new typename Core::ITKImageDataT< DataType >( reader->GetOutput() ) ); + image_data = typename Core::ITKImageDataT< DataType >::Handle( + new typename Core::ITKImageDataT< DataType >( reader->GetOutput() ) ); } catch ( ... ) { this->importer_->set_error( "Importer could not unwrap itk object." ); return false; } - + // Get grid transform and data block from the wrapped itk object this->data_block_ = Core::ITKDataBlock::New( image_data ); @@ -346,12 +346,16 @@ bool ITKSeriesLayerImporterPrivate::import_simple_series() return this->import_simple_typed_series< unsigned int, ItkImporterType >(); case Core::DataType::INT_E: return this->import_simple_typed_series< int, ItkImporterType >(); + case Core::DataType::ULONGLONG_E: + return this->import_simple_typed_series< unsigned long long, ItkImporterType >(); + case Core::DataType::LONGLONG_E: + return this->import_simple_typed_series< signed long long, ItkImporterType >(); case Core::DataType::FLOAT_E: return this->import_simple_typed_series< float, ItkImporterType >(); case Core::DataType::DOUBLE_E: return this->import_simple_typed_series< double, ItkImporterType >(); default: - return false; + return false; } } @@ -359,12 +363,12 @@ bool ITKSeriesLayerImporterPrivate::read_data() { // If importing already succeeded, don't do it again if ( this->read_data_ ) return true; - + // Extract the extension from the file name and use this to define // which importer to use. boost::filesystem::path full_filename( this->importer_->get_filename() ); std::string extension = boost::to_lower_copy( boost::filesystem::extension( full_filename ) ); - + if( extension == ".png" ) { return this->import_simple_series< itk::PNGImageIO >(); @@ -385,7 +389,7 @@ bool ITKSeriesLayerImporterPrivate::read_data() { return this->import_simple_series< itk::VTKImageIO >(); } - else // assume it is dicom + else // assume it is dicom { return this->import_simple_series< itk::GDCMImageIO >(); } @@ -400,43 +404,43 @@ ITKSeriesLayerImporter::ITKSeriesLayerImporter() : this->private_->importer_ = this; } -ITKSeriesLayerImporter::~ITKSeriesLayerImporter() +ITKSeriesLayerImporter::~ITKSeriesLayerImporter() { } bool ITKSeriesLayerImporter::get_file_info( LayerImporterFileInfoHandle& info ) { try - { + { // Try to read the header if ( ! this->private_->read_header() ) return false; - + // Generate an information structure with the information. info = LayerImporterFileInfoHandle( new LayerImporterFileInfo ); info->set_data_type( this->private_->data_type_ ); info->set_grid_transform( this->private_->grid_transform_ ); - info->set_file_type( this->private_->file_type_ ); + info->set_file_type( this->private_->file_type_ ); info->set_mask_compatible( true ); } catch ( ... ) { // In case something failed, recover from here and let the user - // deal with the error. + // deal with the error. this->set_error( "ITK Series Importer crashed while reading file." ); return false; } - + return true; } bool ITKSeriesLayerImporter::get_file_data( LayerImporterFileDataHandle& data ) { try - { + { // Read the data from the file if ( ! this->private_->read_data() ) return false; - - // Create a data structure with handles to the actual data in this file + + // Create a data structure with handles to the actual data in this file data = LayerImporterFileDataHandle( new LayerImporterFileData ); data->set_data_block( this->private_->data_block_ ); data->set_grid_transform( this->private_->grid_transform_ ); @@ -445,7 +449,7 @@ bool ITKSeriesLayerImporter::get_file_data( LayerImporterFileDataHandle& data ) catch ( ... ) { // In case something failed, recover from here and let the user - // deal with the error. + // deal with the error. this->set_error( "ITK Series Importer crashed when reading file." ); return false; } diff --git a/src/Application/LayerIO/ITKSeriesLayerImporter.h b/src/Application/LayerIO/ITKSeriesLayerImporter.h index 311f72980..18f6f7b6b 100644 --- a/src/Application/LayerIO/ITKSeriesLayerImporter.h +++ b/src/Application/LayerIO/ITKSeriesLayerImporter.h @@ -31,9 +31,9 @@ #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once -#endif +#endif -// Boost includes +// Boost includes #include // Core includes @@ -43,8 +43,14 @@ #include #include +// ITK +#include + namespace Seg3D { + // CONVERT_DATA_TYPE: + // Copy the data type we get from itk and convert to a Seg3D enum type + Core::DataType convert_data_type(itk::CommonEnums::IOComponent type); // Forward declaration for internals of this class class ITKSeriesLayerImporterPrivate; @@ -72,8 +78,8 @@ class ITKSeriesLayerImporter : public LayerFileSeriesImporter /// Hence it is best to run this on a separate thread if needed ( from the GUI ). virtual bool get_file_info( LayerImporterFileInfoHandle& info ); - // -- Import data from file -- -public: + // -- Import data from file -- +public: /// GET_FILE_DATA /// Get the file data from the file/ file series /// NOTE: The information is generated again, so that hints can be processed diff --git a/src/Application/LayerIO/MRCLayerImporter.cc b/src/Application/LayerIO/MRCLayerImporter.cc index b431d59bc..7745fa56b 100644 --- a/src/Application/LayerIO/MRCLayerImporter.cc +++ b/src/Application/LayerIO/MRCLayerImporter.cc @@ -329,7 +329,7 @@ namespace Seg3D #ifdef _WIN32 HANDLE file_desc = CreateFileA( this->importer_->get_filename().c_str(), GENERIC_READ, - FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); if ( file_desc == INVALID_HANDLE_VALUE ) { this->importer_->set_error( "Could not open file." ); @@ -348,7 +348,7 @@ namespace Seg3D // We start by getting the length of the entire file #ifdef _WIN32 LARGE_INTEGER offset; offset.QuadPart = 0; - SetFilePointerEx( file_desc, offset, NULL, FILE_END); + SetFilePointerEx( file_desc, offset, nullptr, FILE_END); #else data_file.seekg( 0, std::ios::end ); #endif @@ -379,7 +379,7 @@ namespace Seg3D #ifdef _WIN32 offset.QuadPart = MRC_HEADER_LENGTH; - SetFilePointerEx( file_desc, offset, NULL, FILE_BEGIN ); + SetFilePointerEx( file_desc, offset, nullptr, FILE_BEGIN ); #else data_file.seekg( MRC_HEADER_LENGTH, std::ios::beg ); #endif @@ -395,11 +395,11 @@ namespace Seg3D while ( read_length > chunk ) { - ReadFile( file_desc, data_ptr, DWORD(chunk), &dwReadBytes, NULL ); + ReadFile( file_desc, data_ptr, DWORD(chunk), &dwReadBytes, nullptr ); read_length -= static_cast( dwReadBytes ); data_ptr += static_cast( dwReadBytes ); } - ReadFile( file_desc, data_ptr, DWORD( read_length ), &dwReadBytes, NULL ); + ReadFile( file_desc, data_ptr, DWORD( read_length ), &dwReadBytes, nullptr ); #else data_file.read( data, length ); diff --git a/src/Application/LayerIO/Matlab73LayerImporter.cc b/src/Application/LayerIO/Matlab73LayerImporter.cc index ad6b3ef38..4d3be748e 100644 --- a/src/Application/LayerIO/Matlab73LayerImporter.cc +++ b/src/Application/LayerIO/Matlab73LayerImporter.cc @@ -29,7 +29,6 @@ // HDF5 includes #include #include -#include // Core includes #include @@ -40,6 +39,247 @@ #include +// Implementations of a few HDF5HL library functions so we don't have it as a dependency +// Copied from https://github.com/HDFGroup/hdf5/blob/hdf5-1_10_4/hl/src/H5LT.c + + +/*------------------------------------------------------------------------- +* Function: H5LTget_dataset_ndims +* +* Purpose: Gets the dimensionality of a dataset. +* +* Return: Success: 0, Failure: -1 +* +* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu +* +* Date: September 4, 2001 +* +*------------------------------------------------------------------------- +*/ + +herr_t H5LTget_dataset_ndims( hid_t loc_id, + const char *dset_name, + int *rank ) +{ + hid_t did = -1; + hid_t sid = -1; + + /* check the arguments */ + if (dset_name == NULL) + return -1; + + /* Open the dataset. */ + if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0) + return -1; + + /* Get the dataspace handle */ + if((sid = H5Dget_space(did)) < 0) + goto out; + + /* Get rank */ + if((*rank = H5Sget_simple_extent_ndims(sid)) < 0) + goto out; + + /* Terminate access to the dataspace */ + if(H5Sclose(sid) < 0) + goto out; + + /* End access to the dataset */ + if(H5Dclose(did)) + return -1; + + return 0; + +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Sclose(sid); + } H5E_END_TRY; + return -1; +} + + +/*------------------------------------------------------------------------- +* Function: H5LTget_dataset_info +* +* Purpose: Gets information about a dataset. +* +* Return: Success: 0, Failure: -1 +* +* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu +* +* Date: September 4, 2001 +* Modified: February 28, 2006: checked for NULL parameters +* +*------------------------------------------------------------------------- +*/ + +herr_t H5LTget_dataset_info( hid_t loc_id, + const char *dset_name, + hsize_t *dims, + H5T_class_t *type_class, + size_t *type_size ) +{ + hid_t did = -1; + hid_t tid = -1; + hid_t sid = -1; + + /* check the arguments */ + if (dset_name == NULL) + return -1; + + /* open the dataset. */ + if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0) + return -1; + + /* get an identifier for the datatype. */ + tid = H5Dget_type(did); + + /* get the class. */ + if(type_class != NULL) + *type_class = H5Tget_class(tid); + + /* get the size. */ + if(type_size!=NULL) + *type_size = H5Tget_size(tid); + + if(dims != NULL) { + /* get the dataspace handle */ + if((sid = H5Dget_space(did)) < 0) + goto out; + + /* get dimensions */ + if(H5Sget_simple_extent_dims(sid, dims, NULL) < 0) + goto out; + + /* terminate access to the dataspace */ + if(H5Sclose(sid) < 0) + goto out; + } /* end if */ + + /* release the datatype. */ + if(H5Tclose(tid)) + return -1; + + /* end access to the dataset */ + if(H5Dclose(did)) + return -1; + + return 0; + +out: + H5E_BEGIN_TRY { + H5Tclose(tid); + H5Sclose(sid); + H5Dclose(did); + } H5E_END_TRY; + return -1; + +} + + +/*------------------------------------------------------------------------- +* Function: H5LT_get_attribute_disk +* +* Purpose: Reads an attribute named attr_name with the datatype stored on disk +* +* Return: Success: 0, Failure: -1 +* +* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu +* +* Date: September 19, 2002 +* +* Comments: +* +* Modifications: +* +*------------------------------------------------------------------------- +*/ + +herr_t H5LT_get_attribute_disk( hid_t loc_id, + const char *attr_name, + void *attr_out ) +{ + /* identifiers */ + hid_t attr_id; + hid_t attr_type; + + if(( attr_id = H5Aopen(loc_id, attr_name, H5P_DEFAULT)) < 0) + return -1; + + if((attr_type = H5Aget_type(attr_id)) < 0) + goto out; + + if(H5Aread(attr_id, attr_type, attr_out) < 0) + goto out; + + if(H5Tclose(attr_type) < 0) + goto out; + + if ( H5Aclose( attr_id ) < 0 ) + return -1;; + + return 0; + +out: + H5Tclose( attr_type ); + H5Aclose( attr_id ); + return -1; +} + + +/*------------------------------------------------------------------------- +* Function: H5LTget_attribute_string +* +* Purpose: Reads an attribute named attr_name +* +* Return: Success: 0, Failure: -1 +* +* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu +* +* Date: September 19, 2002 +* +* Comments: +* +* Modifications: +* +*------------------------------------------------------------------------- +*/ + + +herr_t H5LTget_attribute_string( hid_t loc_id, + const char *obj_name, + const char *attr_name, + char *data ) +{ + /* identifiers */ + hid_t obj_id; + + /* check the arguments */ + if (obj_name == NULL) + return -1; + if (attr_name == NULL) + return -1; + + /* Open the object */ + if ((obj_id = H5Oopen( loc_id, obj_name, H5P_DEFAULT)) < 0) + return -1; + + /* Get the attribute */ + if ( H5LT_get_attribute_disk( obj_id, attr_name, data ) < 0 ) + { + H5Oclose(obj_id); + return -1; + } + + /* Close the object */ + if(H5Oclose(obj_id) < 0) + return -1; + + return 0; + +} + #define MAX_DIMS 3 #define BUFFER_SIZE 256 @@ -146,6 +386,8 @@ Core::DataType Matlab73LayerImporterPrivate::convert_type( const std::string& ma else if (matlab_type == "uint16") return Core::DataType::USHORT_E; else if (matlab_type == "int32") return Core::DataType::INT_E; else if (matlab_type == "uint32") return Core::DataType::UINT_E; + else if (matlab_type == "int64") return Core::DataType::LONGLONG_E; + else if (matlab_type == "uint64") return Core::DataType::ULONGLONG_E; else if (matlab_type == "single") return Core::DataType::FLOAT_E; else if (matlab_type == "double") return Core::DataType::DOUBLE_E; else return Core::DataType::UNKNOWN_E; @@ -474,7 +716,7 @@ bool Matlab73LayerImporterPrivate::import_mat_array( H5::DataSet& dataset, std:: // get full space for dataset H5::DataSpace dataspace = dataset.getSpace(); int rank = dataspace.getSimpleExtentNdims(); - int ndims = dataspace.getSimpleExtentDims( dims, NULL); + int ndims = dataspace.getSimpleExtentDims( dims, nullptr); size_t length = this->data_block_->get_size() * Core::GetSizeDataType( this->data_type_ ); @@ -521,6 +763,18 @@ bool Matlab73LayerImporterPrivate::import_mat_array( H5::DataSet& dataset, std:: dataset.read(data, H5::PredType::NATIVE_UINT, memspace, dataspace); break; } + case Core::DataType::LONGLONG_E: + { + long long* data = reinterpret_cast( this->data_block_->get_data() ); + dataset.read(data, H5::PredType::NATIVE_LLONG, memspace, dataspace); + break; + } + case Core::DataType::ULONGLONG_E: + { + unsigned long long* data = reinterpret_cast( this->data_block_->get_data() ); + dataset.read(data, H5::PredType::NATIVE_ULLONG, memspace, dataspace); + break; + } case Core::DataType::FLOAT_E: { float* data = reinterpret_cast( this->data_block_->get_data() ); diff --git a/src/Application/LayerIO/MatlabLayerExporter.cc b/src/Application/LayerIO/MatlabLayerExporter.cc index da3f998df..20617b23c 100644 --- a/src/Application/LayerIO/MatlabLayerExporter.cc +++ b/src/Application/LayerIO/MatlabLayerExporter.cc @@ -64,7 +64,7 @@ void MatlabLayerExporter::createStringArray(const char* name, const char* value, void MatlabLayerExporter::configureDataLayerAxis(MatlabIO::matlabarray& axisma, DataLayer* layer) { - Core::GridTransform tf = layer->get_data_volume()->get_grid_transform(); + Core::GridTransform tf = layer->get_data_volume()->get_grid_transform(); configureAxis(axisma, tf); } @@ -79,30 +79,30 @@ void MatlabLayerExporter::configureAxis(MatlabIO::matlabarray& axisma, Core::Gri // Set the properies of the axis std::vector axisfieldnames; axisfieldnames += "size", "spacing", "min", "max", "center", "label", "unit"; - + std::vector dims( 2 ); dims[0] = 3; dims[1] = 1; - + axisma.createstructarray( dims, axisfieldnames ); Core::Vector size( tf.get_nx(), tf.get_ny(), tf.get_nz() ); - Core::Vector spacing( tf.project( Core::Vector( 1.0, 0.0, 0.0 ) ).length(), + Core::Vector spacing( tf.project( Core::Vector( 1.0, 0.0, 0.0 ) ).length(), tf.project( Core::Vector( 0.0, 1.0, 0.0 ) ).length(), - tf.project( Core::Vector( 0.0, 0.0, 1.0 ) ).length() ); - - - Core::Point min( tf.project( Core::Point( 0.0 ,0.0, 0.0 ) ) ); + tf.project( Core::Vector( 0.0, 0.0, 1.0 ) ).length() ); + + + Core::Point min( tf.project( Core::Point( 0.0 ,0.0, 0.0 ) ) ); Core::Point max( tf.project( Core::Point( static_cast( tf.get_nx() - 1 ), - static_cast( tf.get_ny() - 1 ) , static_cast( tf.get_nz() - 1 ) ) ) ); + static_cast( tf.get_ny() - 1 ) , static_cast( tf.get_nz() - 1 ) ) ) ); Core::Vector center( 0.0, 0.0, 0.0 ); - + if ( ! tf.get_originally_node_centered() ) { min -= ( spacing * 0.5 ); max += ( spacing * 0.5 ); center = Core::Vector( 1.0, 1.0, 1.0 ); } - + for (int p = 0; p < 3; p++ ) { createDoubleArray("size", static_cast(size[ p ]), p, axisma); @@ -114,19 +114,19 @@ void MatlabLayerExporter::configureAxis(MatlabIO::matlabarray& axisma, Core::Gri createStringArray("unit", "no unit", p, axisma); } } - + MatlabLayerExporter::MatlabLayerExporter( std::vector< LayerHandle >& layers ) : LayerExporter( layers ) { if( !layers[ 0 ] ) return; } -bool MatlabLayerExporter::export_layer( const std::string& mode, const std::string& file_path, +bool MatlabLayerExporter::export_layer( const std::string& mode, const std::string& file_path, const std::string& name ) { boost::filesystem::path path = boost::filesystem::path( file_path ) / ( name + ".mat" ); bool success = false; - + // Export data as single volume file if ( mode == LayerIO::DATA_MODE_C ) { @@ -142,22 +142,22 @@ bool MatlabLayerExporter::export_layer( const std::string& mode, const std::stri { success = this->export_mask_label( path.string() ); } - + if( success ) CORE_LOG_SUCCESS( "Matlab export has been successfully completed." ); return success; } bool MatlabLayerExporter::export_matfile( const std::string& file_path ) { - DataLayer* layer = dynamic_cast< DataLayer* >( + DataLayer* layer = dynamic_cast< DataLayer* >( this->layers_[ 0 ].get() ); MatlabIO::matlabarray mldata; std::vector dims( 3 ); - dims[ 0 ] = layer->get_data_volume()->get_nx(); - dims[ 1 ] = layer->get_data_volume()->get_ny(); - dims[ 2 ] = layer->get_data_volume()->get_nz(); - + dims[ 0 ] = layer->get_data_volume()->get_nx(); + dims[ 1 ] = layer->get_data_volume()->get_ny(); + dims[ 2 ] = layer->get_data_volume()->get_nz(); + MatlabIO::matlabarray::mitype dataformat; switch( layer->get_data_volume()->get_data_type() ) { @@ -167,47 +167,57 @@ bool MatlabLayerExporter::export_matfile( const std::string& file_path ) case Core::DataType::USHORT_E: dataformat = MatlabIO::matlabarray::miUINT16; break; case Core::DataType::INT_E: dataformat = MatlabIO::matlabarray::miINT32; break; case Core::DataType::UINT_E: dataformat = MatlabIO::matlabarray::miUINT32; break; + case Core::DataType::LONGLONG_E: dataformat = MatlabIO::matlabarray::miINT64; break; + case Core::DataType::ULONGLONG_E: dataformat = MatlabIO::matlabarray::miUINT64; break; case Core::DataType::FLOAT_E: dataformat = MatlabIO::matlabarray::miSINGLE; break; case Core::DataType::DOUBLE_E: dataformat = MatlabIO::matlabarray::miDOUBLE; break; default: return false; } - + mldata.createdensearray( dims, dataformat ); Core::DataBlockHandle data_block = layer->get_data_volume()->get_data_block(); switch( layer->get_data_volume()->get_data_type() ) { - case Core::DataType::CHAR_E: + case Core::DataType::CHAR_E: mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), data_block->get_size(), dataformat ); break; - case Core::DataType::UCHAR_E: + case Core::DataType::UCHAR_E: mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), data_block->get_size(), dataformat ); break; - case Core::DataType::SHORT_E: + case Core::DataType::SHORT_E: mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), data_block->get_size(), dataformat ); break; - case Core::DataType::USHORT_E: + case Core::DataType::USHORT_E: mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), data_block->get_size(), dataformat ); break; - case Core::DataType::INT_E: + case Core::DataType::INT_E: mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), data_block->get_size(), dataformat ); break; - case Core::DataType::UINT_E: + case Core::DataType::UINT_E: mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), data_block->get_size(), dataformat ); break; - case Core::DataType::FLOAT_E: + case Core::DataType::LONGLONG_E: + mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), + data_block->get_size(), dataformat ); + break; + case Core::DataType::ULONGLONG_E: + mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), + data_block->get_size(), dataformat ); + break; + case Core::DataType::FLOAT_E: mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), data_block->get_size(), dataformat ); break; - case Core::DataType::DOUBLE_E: + case Core::DataType::DOUBLE_E: mldata.setnumericarray( reinterpret_cast( data_block->get_data() ), data_block->get_size(), dataformat ); break; @@ -222,13 +232,13 @@ bool MatlabLayerExporter::export_matfile( const std::string& file_path ) MatlabIO::matlabarray axisma; configureDataLayerAxis(axisma, layer); - + mlarray.setfield( 0, "axis", axisma ); MatlabIO::matlabfile output( file_path, "w" ); output.putmatlabarray( mlarray, "scirunnrrd" ); output.close(); - + return true; } @@ -244,10 +254,10 @@ bool MatlabLayerExporter::export_single_masks( const std::string& path ) // Step 2: Get a pointer to the mask's MaskDataBlock Core::MaskDataBlockHandle mask_block = layer->get_mask_volume()-> get_mask_data_block(); - - Core::DataBlock::shared_lock_type lock( mask_block->get_mutex() ); - // Step 3: Using the size and type information from our mask's MaskDataBlock, we create a + Core::DataBlock::shared_lock_type lock( mask_block->get_mutex() ); + + // Step 3: Using the size and type information from our mask's MaskDataBlock, we create a // new empty DataBlock Core::DataBlockHandle new_data_block = Core::StdDataBlock::New( mask_block->get_nx(), mask_block->get_ny(), mask_block->get_nz(), Core::DataType::UCHAR_E ); @@ -260,26 +270,26 @@ bool MatlabLayerExporter::export_single_masks( const std::string& path ) new_data_block->set_data_at( j, 1 ); } else - { + { new_data_block->set_data_at( j, 0 ); } } lock.unlock(); - + MatlabIO::matlabarray mldata; std::vector dims( 3 ); - dims[ 0 ] = layer->get_mask_volume()->get_nx(); - dims[ 1 ] = layer->get_mask_volume()->get_ny(); - dims[ 2 ] = layer->get_mask_volume()->get_nz(); - - - MatlabIO::matlabarray::mitype dataformat = MatlabIO::matlabarray::miINT8; + dims[ 0 ] = layer->get_mask_volume()->get_nx(); + dims[ 1 ] = layer->get_mask_volume()->get_ny(); + dims[ 2 ] = layer->get_mask_volume()->get_nz(); + + + MatlabIO::matlabarray::mitype dataformat = MatlabIO::matlabarray::miINT8; mldata.createdensearray( dims, dataformat ); mldata.setnumericarray( reinterpret_cast( new_data_block->get_data() ), new_data_block->get_size(), dataformat ); - + MatlabIO::matlabarray mlarray; mlarray.createstructarray(); @@ -287,14 +297,14 @@ bool MatlabLayerExporter::export_single_masks( const std::string& path ) MatlabIO::matlabarray axisma; configureMaskLayerAxis(axisma, layer); - + mlarray.setfield( 0, "axis", axisma ); - boost::filesystem::path mask_path = boost::filesystem::path( path ) / + boost::filesystem::path mask_path = boost::filesystem::path( path ) / ( layer->get_layer_name() + ".mat" ); - + MatlabIO::matlabfile output( mask_path.string(), "w" ); - output.putmatlabarray( mlarray, "scirunnrrd" ); + output.putmatlabarray( mlarray, "scirunnrrd" ); output.close(); } return true; @@ -306,7 +316,7 @@ bool MatlabLayerExporter::export_mask_label( const std::string& file_path ) std::vector < std::string > first_mask_name_and_number; MaskLayer* layer = dynamic_cast< MaskLayer* >( this->layers_[ 1 ].get() ); - // Step 2: Get a handle to its MaskDataBlock and use that to build a new DataBlockHandle of the + // Step 2: Get a handle to its MaskDataBlock and use that to build a new DataBlockHandle of the // same size and type. Core::MaskDataBlockHandle mask_block = layer->get_mask_volume()->get_mask_data_block(); Core::DataBlockHandle new_data_block = Core::StdDataBlock::New( mask_block->get_nx(), @@ -318,35 +328,35 @@ bool MatlabLayerExporter::export_mask_label( const std::string& file_path ) { new_data_block->set_data_at( i, this->label_values_[ 0 ] ); } - + // Step 4: Loop through all the MaskLayers and insert their values into our new DataBlock std::vector< MaskLayer* > mask_layers; for( int i = 1; i < static_cast< int >( this->layers_.size() ); ++i ) { layer = dynamic_cast< MaskLayer* >( this->layers_[ i ].get() ); mask_block = layer->get_mask_volume()->get_mask_data_block(); - + Core::DataBlock::shared_lock_type lock( mask_block->get_mutex() ); - + for( size_t j = 0; j < mask_block->get_size(); ++j ) { if( mask_block->get_mask_at( j ) ) { new_data_block->set_data_at( j, this->label_values_[ i ] ); } - } - + } + lock.unlock(); } MatlabIO::matlabarray mldata; std::vector dims( 3 ); - dims[ 0 ] = layer->get_mask_volume()->get_nx(); - dims[ 1 ] = layer->get_mask_volume()->get_ny(); - dims[ 2 ] = layer->get_mask_volume()->get_nz(); - - - MatlabIO::matlabarray::mitype dataformat = MatlabIO::matlabarray::miINT8; + dims[ 0 ] = layer->get_mask_volume()->get_nx(); + dims[ 1 ] = layer->get_mask_volume()->get_ny(); + dims[ 2 ] = layer->get_mask_volume()->get_nz(); + + + MatlabIO::matlabarray::mitype dataformat = MatlabIO::matlabarray::miINT8; mldata.createdensearray( dims, dataformat ); mldata.setnumericarray( reinterpret_cast( new_data_block->get_data() ), new_data_block->get_size(), dataformat ); diff --git a/src/Application/LayerIO/MatlabLayerImporter.cc b/src/Application/LayerIO/MatlabLayerImporter.cc index 8ea59d66b..dee702dca 100644 --- a/src/Application/LayerIO/MatlabLayerImporter.cc +++ b/src/Application/LayerIO/MatlabLayerImporter.cc @@ -54,7 +54,7 @@ class MatlabLayerImporterPrivate // Pointer back to the main class MatlabLayerImporter* importer_; - + public: // Information extracted from the header Core::GridTransform grid_transform_; @@ -62,9 +62,9 @@ class MatlabLayerImporterPrivate // Data extracted from the file Core::DataBlockHandle data_block_; - + int matlab_array_index_; - + public: // SCAN_MAT_ARRAY: @@ -75,25 +75,25 @@ class MatlabLayerImporterPrivate // SCAN_MAT_FILE: // Scan whether there is a compatible object in the mat file bool scan_mat_file( const std::string& filename ); - + // IMPORT_MAT_ARRAY: // Import the matlab array into the program. bool import_mat_array( MatlabIO::matlabarray &mlarray, std::string& error ); - + // IMPORT_MAT_FILE: // Scan through the file and now import the data bool import_mat_file( const std::string& filename ); - + // CONVERT_TYPE: // Convert the matlabio types to Seg3D types Core::DataType convert_type( MatlabIO::matlabarray::mitype type ); - + // Whether the header has been read bool read_header_; - + // Whether the data has been read bool read_data_; - + }; Core::DataType MatlabLayerImporterPrivate::convert_type( MatlabIO::matlabarray::mitype type ) @@ -107,6 +107,8 @@ Core::DataType MatlabLayerImporterPrivate::convert_type( MatlabIO::matlabarray:: case MatlabIO::matlabarray::miUINT16: return Core::DataType::USHORT_E; case MatlabIO::matlabarray::miINT32: return Core::DataType::INT_E; case MatlabIO::matlabarray::miUINT32: return Core::DataType::UINT_E; + case MatlabIO::matlabarray::miINT64: return Core::DataType::LONGLONG_E; + case MatlabIO::matlabarray::miUINT64: return Core::DataType::ULONGLONG_E; case MatlabIO::matlabarray::miSINGLE: return Core::DataType::FLOAT_E; case MatlabIO::matlabarray::miDOUBLE: return Core::DataType::DOUBLE_E; default: return Core::DataType::UNKNOWN_E; @@ -117,7 +119,7 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, { // Clear error string error = ""; - + // Check if the matlab array is empty if ( mlarray.isempty() ) { @@ -125,43 +127,43 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, error = "Matlab Object does not contain any data."; return false ; } - + // Check if there are any elements in the matlab array - if ( mlarray.getnumelements() == 0 ) + if ( mlarray.getnumelements() == 0 ) { error = "Matlab Object is empty."; return false ; } - + // What type of matlab array are we dealing with MatlabIO::matlabarray::mlclass mclass; mclass = mlarray.getclass(); - - // parse matrices are dealt with in a separate + + // parse matrices are dealt with in a separate // pr as the the data needs to be divided over // three separate Nrrds - - // If the class is struct or class, check whether the required data fields are present + + // If the class is struct or class, check whether the required data fields are present if ( mclass == MatlabIO::matlabarray::mlSTRUCT || mclass == MatlabIO::matlabarray::mlOBJECT ) { int fieldnameindex; MatlabIO::matlabarray subarray; - - // Check for different versions of where the data may be stored + + // Check for different versions of where the data may be stored fieldnameindex = mlarray.getfieldnameindexCI( "data" ); if (fieldnameindex == -1) fieldnameindex = mlarray.getfieldnameindexCI( "potvals" ); if (fieldnameindex == -1) fieldnameindex = mlarray.getfieldnameindexCI( "field" ); if (fieldnameindex == -1) fieldnameindex = mlarray.getfieldnameindexCI( "scalarfield" ); - if (fieldnameindex == -1) + if (fieldnameindex == -1) { // Could not find main data array in structure error = "Matlab array does not have a data, potvals, or field in its main data structure."; return false; } - + // Check whether the data array is not empty - subarray = mlarray.getfield( 0, fieldnameindex ); - if ( subarray.isempty() ) + subarray = mlarray.getfield( 0, fieldnameindex ); + if ( subarray.isempty() ) { error = "Matlab array does not contain any data."; return false; @@ -169,8 +171,8 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, MatlabIO::matlabarray::mlclass mclass; mclass = subarray.getclass(); - - if ( mclass != MatlabIO::matlabarray::mlDENSE ) + + if ( mclass != MatlabIO::matlabarray::mlDENSE ) { error = "Matrix that should contain data is not a dense matrix."; return false; @@ -178,12 +180,12 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, std::vector dims = subarray.getdims(); bool old_version_4d_matrix = false; - - if ( dims.size() > 3 ) - { + + if ( dims.size() > 3 ) + { // The old version of Seg3D had one version that generated 4D matrices instead // of 3D matrices. Only one dimension is 1 in this case - + if ( dims.size() == 4 && dims[ 0 ] == 1 ) { dims[ 0 ] = dims[ 1 ]; @@ -191,21 +193,21 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, dims[ 2 ] = dims[ 3 ]; old_version_4d_matrix = true; - } - + } + if ( !old_version_4d_matrix ) { error = "Matrix dimension is larger than 3."; - return false; + return false; } } - + if ( subarray.getnumelements() == 0 ) - { + { error = "Matlab array does not contain any data."; return false; - } + } // Get dimensions of the data while ( dims.size() < 3 ) dims.push_back( 1 ); @@ -221,19 +223,19 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, // Add axes properties if they are specified int axisindex; axisindex = mlarray.getfieldnameindexCI( "axis" ); - + if ( axisindex != -1 ) { if ( mlarray.isfieldCI( "axis" ) ) { MatlabIO::matlabarray axisarray = mlarray.getfieldCI( 0, "axis" ); - - if ( ! axisarray.isstruct() ) + + if ( ! axisarray.isstruct() ) { error = "Axis field needs to be structured objects."; return false; } - + int dim_start = 0; int numaxis = axisarray.getm(); @@ -242,18 +244,18 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, numaxis = 4; dim_start = 1; } - + bool read_spacing = false; bool read_min = false; bool read_max = false; - + Core::Vector spacing; Core::Point min; Core::Point max; for ( int p = dim_start ; p < numaxis; p++ ) - { + { if ( axisarray.isfield( "spacing" ) ) { MatlabIO::matlabarray farray = axisarray.getfield( p, "spacing" ); @@ -280,18 +282,18 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, if ( farray.isdense() && farray.getnumelements() > 0 ) { farray.getnumericarray( &max[ p - dim_start ], 1 ); - read_max = true; + read_max = true; } - } + } } - + // Sets up cell centered data Core::Point Origin; if ( ! read_spacing ) { if ( read_min && read_max ) { - spacing = Core::Vector( + spacing = Core::Vector( ( max.x() - min.x() ) / Core::Max( 1.0f, nxf ), ( max.y() - min.y() ) / Core::Max( 1.0f, nyf ), ( max.z() - min.z() ) / Core::Max( 1.0f, nzf ) ); @@ -301,19 +303,19 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, spacing = Core::Vector( 1.0, 1.0, 1.0 ); } } - + if ( read_min ) { Origin = min + 0.5 * spacing; } else if ( read_max ) { - Origin = max - Core::Vector( spacing.x() * ( nxf - 0.5 ), + Origin = max - Core::Vector( spacing.x() * ( nxf - 0.5 ), spacing.y() * ( nyf - 0.5 ), spacing.z() * ( nzf - 0.5 ) ); } - - this->grid_transform_ = Core::GridTransform( nx, ny, nz, Origin, - spacing.x() * Core::Vector( 1.0, 0.0, 0.0 ), + + this->grid_transform_ = Core::GridTransform( nx, ny, nz, Origin, + spacing.x() * Core::Vector( 1.0, 0.0, 0.0 ), spacing.y() * Core::Vector( 0.0, 1.0, 0.0 ), spacing.z() * Core::Vector( 0.0, 0.0, 1.0 ) ); this->grid_transform_.set_originally_node_centered( false ); @@ -322,27 +324,27 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, this->data_type_ = this->convert_type( subarray.gettype() ); this->read_header_ = true; - - return true; + + return true; } - + if ( mclass != MatlabIO::matlabarray::mlDENSE ) { error = "Matrix that should contain data is not a dense matrix."; return false; } - if ( mlarray.isempty() ) + if ( mlarray.isempty() ) { error = "Matlab array does not contain any data."; return false; } - + if ( mlarray.getnumelements() == 0 ) - { + { error = "Matlab array does not contain any data."; return false; - } + } std::vector dims = mlarray.getdims(); while ( dims.size() < 3 ) dims.push_back( 1 ); @@ -352,7 +354,7 @@ bool MatlabLayerImporterPrivate::scan_mat_array( MatlabIO::matlabarray &mlarray, size_t nz = static_cast( dims[ 2 ] ); this->grid_transform_ = Core::GridTransform( nx, ny, nz ); - this->data_type_ = this->convert_type( mlarray.gettype() ); + this->data_type_ = this->convert_type( mlarray.gettype() ); this->read_header_ = true; return true; @@ -372,21 +374,21 @@ bool MatlabLayerImporterPrivate::scan_mat_file( const std::string& filename ) // String from returning error std::string error; - + // Scan through all objects in the file and pick the first one that we can import. try { // Open the matlab file in read mode matlab_file.open( filename, "r" ); - + // Get the number of objects stored in the file int numarrays = matlab_file.getnummatlabarrays(); - + // Extract the objects one by one for ( int j = 0; j < numarrays; j++ ) { // The info call scans through the entire file and reads all objects except the - // large datablocks, entries with more than 100 elements. + // large datablocks, entries with more than 100 elements. matlab_array = matlab_file.getmatlabarray( j ); if ( this->scan_mat_array( matlab_array, error ) ) { @@ -400,7 +402,7 @@ bool MatlabLayerImporterPrivate::scan_mat_file( const std::string& filename ) { error = "Importer crashed while reading header of matlab file."; } - + // If the cause is known report an error to the user if ( ! error.empty() ) { @@ -417,67 +419,77 @@ bool MatlabLayerImporterPrivate::import_mat_array( MatlabIO::matlabarray &mlarra { MatlabIO::matlabarray::mlclass mclass; mclass = mlarray.getclass(); - + switch( mclass ) { case MatlabIO::matlabarray::mlDENSE: - { + { this->data_type_ = convert_type( mlarray.gettype() ); - + std::vector dims = mlarray.getdims(); while ( dims.size() < 3 ) dims.push_back( 1 ); if ( dims.size() == 4 ) { dims[ 0 ] = dims[ 1 ]; dims[ 1 ] = dims[ 2 ]; - dims[ 2 ] = dims[ 3 ]; + dims[ 2 ] = dims[ 3 ]; } - + // node-centered (default) this->data_block_ = Core::StdDataBlock::New( static_cast( dims[ 0 ] ), static_cast( dims[ 1 ] ), static_cast( dims[ 2 ] ), this->data_type_ ); - + switch( this->data_type_ ) { case Core::DataType::CHAR_E: - mlarray.getnumericarray( + mlarray.getnumericarray( static_cast( this->data_block_->get_data() ), static_cast( this->data_block_->get_size() ) ); break; case Core::DataType::UCHAR_E: - mlarray.getnumericarray( + mlarray.getnumericarray( static_cast( this->data_block_->get_data() ), static_cast( this->data_block_->get_size() ) ); - break; + break; case Core::DataType::SHORT_E: - mlarray.getnumericarray( + mlarray.getnumericarray( static_cast( this->data_block_->get_data() ), static_cast( this->data_block_->get_size() ) ); break; case Core::DataType::USHORT_E: - mlarray.getnumericarray( + mlarray.getnumericarray( static_cast( this->data_block_->get_data() ), static_cast( this->data_block_->get_size() ) ); - break; + break; case Core::DataType::INT_E: - mlarray.getnumericarray( + mlarray.getnumericarray( static_cast( this->data_block_->get_data() ), static_cast( this->data_block_->get_size() ) ); break; case Core::DataType::UINT_E: - mlarray.getnumericarray( + mlarray.getnumericarray( static_cast( this->data_block_->get_data() ), static_cast( this->data_block_->get_size() ) ); - break; + break; + case Core::DataType::LONGLONG_E: + mlarray.getnumericarray( + static_cast( this->data_block_->get_data() ), + static_cast( this->data_block_->get_size() ) ); + break; + case Core::DataType::ULONGLONG_E: + mlarray.getnumericarray( + static_cast( this->data_block_->get_data() ), + static_cast( this->data_block_->get_size() ) ); + break; case Core::DataType::FLOAT_E: - mlarray.getnumericarray( + mlarray.getnumericarray( static_cast( this->data_block_->get_data() ), static_cast( this->data_block_->get_size() ) ); break; case Core::DataType::DOUBLE_E: - mlarray.getnumericarray( + mlarray.getnumericarray( static_cast( this->data_block_->get_data() ), static_cast( this->data_block_->get_size() ) ); break; @@ -485,7 +497,7 @@ bool MatlabLayerImporterPrivate::import_mat_array( MatlabIO::matlabarray &mlarra error = "Encountered unknown datatype in matlab file."; return false; } - + return true; } case MatlabIO::matlabarray::mlSTRUCT: @@ -495,30 +507,30 @@ bool MatlabLayerImporterPrivate::import_mat_array( MatlabIO::matlabarray &mlarra dataindex = mlarray.getfieldnameindexCI( "data" ); if ( dataindex == -1 ) dataindex = mlarray.getfieldnameindexCI( "potvals" ); if ( dataindex == -1 ) dataindex = mlarray.getfieldnameindexCI( "field" ); - if ( dataindex == -1 ) dataindex = mlarray.getfieldnameindexCI( "scalarfield" ); + if ( dataindex == -1 ) dataindex = mlarray.getfieldnameindexCI( "scalarfield" ); if ( dataindex == -1 ) { error = "Matlab array needs to have field called data, potvals, or field."; return false; } - + MatlabIO::matlabarray subarray; subarray = mlarray.getfield( 0, dataindex ); - + MatlabIO::matlabarray::mlclass subclass; subclass = subarray.getclass(); - + if ( subclass != MatlabIO::matlabarray::mlDENSE ) { error = "Only importing dense matrices is supported."; return false; } - - if ( !( this->import_mat_array( subarray, error ) ) ) + + if ( !( this->import_mat_array( subarray, error ) ) ) { return false; } - return true; + return true; } default: error = "Matlab array needs to be a dense matrix or a structure array."; @@ -528,7 +540,7 @@ bool MatlabLayerImporterPrivate::import_mat_array( MatlabIO::matlabarray &mlarra catch ( ... ) { } - + error = "Could not open file."; return false; } @@ -541,14 +553,14 @@ bool MatlabLayerImporterPrivate::import_mat_file( const std::string& filename ) MatlabIO::matlabfile matlab_file; MatlabIO::matlabarray matlab_array; - + // String from returning error std::string error; - + try { matlab_file.open( filename, "r" ); - + matlab_array = matlab_file.getmatlabarray( this->matlab_array_index_ ); if ( this->import_mat_array( matlab_array, error ) ) { @@ -585,36 +597,36 @@ MatlabLayerImporter::~MatlabLayerImporter() bool MatlabLayerImporter::get_file_info( LayerImporterFileInfoHandle& info ) { try - { + { // Try to read the header if ( ! this->private_->scan_mat_file( this->get_filename() ) ) return false; - + // Generate an information structure with the information. info = LayerImporterFileInfoHandle( new LayerImporterFileInfo ); info->set_data_type( this->private_->data_type_ ); info->set_grid_transform( this->private_->grid_transform_ ); - info->set_file_type( "matlab" ); + info->set_file_type( "matlab" ); info->set_mask_compatible( true ); } catch ( ... ) { // In case something failed, recover from here and let the user - // deal with the error. + // deal with the error. this->set_error( "Matlab Importer crashed while reading file." ); return false; } - + return true; } bool MatlabLayerImporter::get_file_data( LayerImporterFileDataHandle& data ) { try - { + { // Read the data from the file if ( !this->private_->import_mat_file( this->get_filename() ) ) return false; - - // Create a data structure with handles to the actual data in this file + + // Create a data structure with handles to the actual data in this file data = LayerImporterFileDataHandle( new LayerImporterFileData ); data->set_data_block( this->private_->data_block_ ); data->set_grid_transform( this->private_->grid_transform_ ); @@ -623,7 +635,7 @@ bool MatlabLayerImporter::get_file_data( LayerImporterFileDataHandle& data ) catch ( ... ) { // In case something failed, recover from here and let the user - // deal with the error. + // deal with the error. this->set_error( "Matlab Importer crashed while reading file." ); return false; } diff --git a/src/Application/LayerIO/VFFLayerImporter.cc b/src/Application/LayerIO/VFFLayerImporter.cc index ae43ab220..f0d5d919f 100644 --- a/src/Application/LayerIO/VFFLayerImporter.cc +++ b/src/Application/LayerIO/VFFLayerImporter.cc @@ -254,7 +254,7 @@ bool VFFLayerImporterPrivate::read_data() #ifdef _WIN32 HANDLE file_desc = CreateFileA( this->importer_->get_filename().c_str(), GENERIC_READ, - FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); if ( file_desc == INVALID_HANDLE_VALUE ) { this->importer_->set_error( "Could not open file." ); @@ -273,7 +273,7 @@ bool VFFLayerImporterPrivate::read_data() // We start by getting the length of the entire file #ifdef _WIN32 LARGE_INTEGER offset; offset.QuadPart = 0; - SetFilePointerEx( file_desc, offset, NULL, FILE_END); + SetFilePointerEx( file_desc, offset, nullptr, FILE_END); #else data_file.seekg( 0, std::ios::end ); #endif @@ -303,7 +303,7 @@ bool VFFLayerImporterPrivate::read_data() #ifdef _WIN32 offset.QuadPart = this->vff_end_of_header_; - SetFilePointerEx( file_desc, offset, NULL, FILE_BEGIN ); + SetFilePointerEx( file_desc, offset, nullptr, FILE_BEGIN ); #else data_file.seekg( this->vff_end_of_header_, std::ios::beg ); #endif @@ -319,11 +319,11 @@ bool VFFLayerImporterPrivate::read_data() while ( read_length > chunk ) { - ReadFile( file_desc, data_ptr, DWORD(chunk), &dwReadBytes, NULL ); + ReadFile( file_desc, data_ptr, DWORD(chunk), &dwReadBytes, nullptr ); read_length -= static_cast( dwReadBytes ); data_ptr += static_cast( dwReadBytes ); } - ReadFile( file_desc, data_ptr, DWORD( read_length ), &dwReadBytes, NULL ); + ReadFile( file_desc, data_ptr, DWORD( read_length ), &dwReadBytes, nullptr ); #else data_file.read( data, length ); diff --git a/src/Application/ProjectManager/ProjectManager.cc b/src/Application/ProjectManager/ProjectManager.cc index bfdd6087f..64cc1e60b 100644 --- a/src/Application/ProjectManager/ProjectManager.cc +++ b/src/Application/ProjectManager/ProjectManager.cc @@ -114,14 +114,14 @@ bool ProjectManagerPrivate::initialize_project_database() // Create table for storing the database version sql_statements << "CREATE TABLE database_version " - << "(version INTEGER NOT NULL PRIMARY KEY);"; + << "(version INTEGER NOT nullptr PRIMARY KEY);"; // Create table for storing projects sql_statements << "CREATE TABLE project " - << "(project_id INTEGER NOT NULL PRIMARY KEY, " - << "name TEXT NOT NULL, " - << "path TEXT NOT NULL UNIQUE, " - << "last_access_time INTEGER NOT NULL);"; + << "(project_id INTEGER NOT nullptr PRIMARY KEY, " + << "name TEXT NOT nullptr, " + << "path TEXT NOT nullptr UNIQUE, " + << "last_access_time INTEGER NOT nullptr);"; // Set the database version to 2 sql_statements << "INSERT INTO database_version VALUES (" diff --git a/src/Application/Tools/Actions/ActionSpeedline.cc b/src/Application/Tools/Actions/ActionSpeedline.cc index c6dbde777..7012d2ea6 100644 --- a/src/Application/Tools/Actions/ActionSpeedline.cc +++ b/src/Application/Tools/Actions/ActionSpeedline.cc @@ -127,6 +127,7 @@ class ActionSpeedlineAlgo : public ITKFilter extract_filter->SetExtractionRegion( desired_region ); extract_filter->SetInput( image ); + extract_filter->SetDirectionCollapseToIdentity(); extract_filter->Update(); typename TYPED_IMAGE_TYPE_2D::Pointer input_image_2D = extract_filter->GetOutput(); diff --git a/src/Application/Tools/SpeedlineTool.cc b/src/Application/Tools/SpeedlineTool.cc index 794903280..723288db2 100644 --- a/src/Application/Tools/SpeedlineTool.cc +++ b/src/Application/Tools/SpeedlineTool.cc @@ -481,7 +481,7 @@ void SpeedlineTool::deactivate() // < DataVolumeSlice >( ViewerManager::Instance()->get_viewer( i )->get_volume_slice( // this->gradient_state_->get() ) ); // -// if ( volume_slice != NULL ) +// if ( volume_slice != nullptr ) // { // this->private_->slice_no_[ i ] = volume_slice->get_slice_number(); // } diff --git a/src/Core/Application/Application.cc b/src/Core/Application/Application.cc index 4e5953236..510aa4642 100644 --- a/src/Core/Application/Application.cc +++ b/src/Core/Application/Application.cc @@ -547,7 +547,7 @@ long long Application::get_total_physical_memory() name[ 0 ] = CTL_HW; name[ 1 ] = HW_MEMSIZE; size_t length = sizeof( unsigned long long ); - sysctl( name, 2, &total_physical_memory, &length, NULL, 0); + sysctl( name, 2, &total_physical_memory, &length, nullptr, 0); return total_physical_memory; #else struct sysinfo info; diff --git a/src/Core/DataBlock/DataBlock.cc b/src/Core/DataBlock/DataBlock.cc index 8365db6d6..f5fa842d2 100644 --- a/src/Core/DataBlock/DataBlock.cc +++ b/src/Core/DataBlock/DataBlock.cc @@ -34,10 +34,10 @@ namespace Core { DataBlock::DataBlock() : - nx_( 0 ), - ny_( 0 ), - nz_( 0 ), - data_type_( DataType::UNKNOWN_E ), + nx_( 0 ), + ny_( 0 ), + nz_( 0 ), + data_type_( DataType::UNKNOWN_E ), data_( 0 ), generation_( -1 ) { @@ -68,17 +68,17 @@ double DataBlock::get_data_at( index_type index ) const { signed char* data = reinterpret_cast( this->data_ ); return static_cast( data[ index ] ); - } + } case DataType::UCHAR_E: { unsigned char* data = reinterpret_cast( this->data_ ); return static_cast( data[ index ] ); - } + } case DataType::SHORT_E: { short* data = reinterpret_cast( this->data_ ); return static_cast( data[ index ] ); - } + } case DataType::USHORT_E: { unsigned short* data = reinterpret_cast( this->data_ ); @@ -88,24 +88,34 @@ double DataBlock::get_data_at( index_type index ) const { int* data = reinterpret_cast( this->data_ ); return static_cast( data[ index ] ); - } + } case DataType::UINT_E: { unsigned int* data = reinterpret_cast( this->data_ ); return static_cast( data[ index ] ); - } + } + case DataType::LONGLONG_E: + { + long long* data = reinterpret_cast( this->data_ ); + return static_cast( data[ index ] ); + } + case DataType::ULONGLONG_E: + { + unsigned long long* data = reinterpret_cast( this->data_ ); + return static_cast( data[ index ] ); + } case DataType::FLOAT_E: { float* data = reinterpret_cast( this->data_ ); return static_cast( data[ index ] ); - } + } case DataType::DOUBLE_E: { double* data = reinterpret_cast( this->data_ ); return data[ index ]; - } + } } - + return 0.0; } @@ -119,43 +129,55 @@ void DataBlock::set_data_at( index_type index, double value ) signed char* data = reinterpret_cast( this->data_ ); data[ index ] = static_cast( value ); return; - } + } case DataType::UCHAR_E: { unsigned char* data = reinterpret_cast( this->data_ ); data[ index ] = static_cast( value ); return; - } + } case DataType::SHORT_E: { short* data = reinterpret_cast( this->data_ ); data[ index ] = static_cast( value ); return; - } + } case DataType::USHORT_E: { unsigned short* data = reinterpret_cast( this->data_ ); data[ index ] = static_cast( value ); return; - } + } case DataType::INT_E: { int* data = reinterpret_cast( this->data_ ); data[ index ] = static_cast( value ); return; - } + } case DataType::UINT_E: { unsigned int* data = reinterpret_cast( this->data_ ); data[ index ] = static_cast( value ); return; - } + } + case DataType::LONGLONG_E: + { + long long* data = reinterpret_cast( this->data_ ); + data[ index ] = static_cast( value ); + return; + } + case DataType::ULONGLONG_E: + { + unsigned long long* data = reinterpret_cast( this->data_ ); + data[ index ] = static_cast( value ); + return; + } case DataType::FLOAT_E: { float* data = reinterpret_cast( this->data_ ); data[ index ] = static_cast( value ); return; - } + } case DataType::DOUBLE_E: { double* data = reinterpret_cast( this->data_ ); @@ -263,6 +285,10 @@ bool DataBlock::update_histogram() return this->histogram_.compute( reinterpret_cast( get_data() ), get_size() ); case DataType::UINT_E: return this->histogram_.compute( reinterpret_cast( get_data() ), get_size() ); + case DataType::LONGLONG_E: + return this->histogram_.compute( reinterpret_cast( get_data() ), get_size() ); + case DataType::ULONGLONG_E: + return this->histogram_.compute( reinterpret_cast( get_data() ), get_size() ); case DataType::FLOAT_E: return this->histogram_.compute( reinterpret_cast( get_data() ), get_size() ); case DataType::DOUBLE_E: @@ -291,6 +317,9 @@ size_t DataBlock::get_elem_size() const case DataType::INT_E: case DataType::UINT_E: return sizeof( int ); + case DataType::LONGLONG_E: + case DataType::ULONGLONG_E: + return sizeof( long long ); case DataType::FLOAT_E: return sizeof( float ); case DataType::DOUBLE_E: @@ -311,7 +340,7 @@ void SwapEndian( void* data, size_t size, size_t elem_size ) case 2: { unsigned char tmp; - + size_t size8 = size & ~(0x7); size_t j = 0; for ( ; j < size8; j+=8 ) @@ -324,7 +353,7 @@ void SwapEndian( void* data, size_t size, size_t elem_size ) udata += 2; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 1 ]; udata[ 1 ] = tmp; udata += 2; - + tmp = udata[ 0 ]; udata[ 0 ] = udata[ 1 ]; udata[ 1 ] = tmp; udata += 2; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 1 ]; udata[ 1 ] = tmp; @@ -334,7 +363,7 @@ void SwapEndian( void* data, size_t size, size_t elem_size ) tmp = udata[ 0 ]; udata[ 0 ] = udata[ 1 ]; udata[ 1 ] = tmp; udata += 2; } - + for( ; j < size; j++ ) { tmp = udata[ 0 ]; udata[ 0 ] = udata[ 1 ]; udata[ 1 ] = tmp; @@ -352,29 +381,29 @@ void SwapEndian( void* data, size_t size, size_t elem_size ) { tmp = udata[ 0 ]; udata[ 0 ] = udata[ 3 ]; udata[ 3 ] = tmp; tmp = udata[ 1 ]; udata[ 1 ] = udata[ 2 ]; udata[ 2 ] = tmp; - udata += 4; + udata += 4; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 3 ]; udata[ 3 ] = tmp; tmp = udata[ 1 ]; udata[ 1 ] = udata[ 2 ]; udata[ 2 ] = tmp; - udata += 4; + udata += 4; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 3 ]; udata[ 3 ] = tmp; tmp = udata[ 1 ]; udata[ 1 ] = udata[ 2 ]; udata[ 2 ] = tmp; - udata += 4; + udata += 4; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 3 ]; udata[ 3 ] = tmp; tmp = udata[ 1 ]; udata[ 1 ] = udata[ 2 ]; udata[ 2 ] = tmp; - udata += 4; + udata += 4; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 3 ]; udata[ 3 ] = tmp; tmp = udata[ 1 ]; udata[ 1 ] = udata[ 2 ]; udata[ 2 ] = tmp; - udata += 4; + udata += 4; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 3 ]; udata[ 3 ] = tmp; tmp = udata[ 1 ]; udata[ 1 ] = udata[ 2 ]; udata[ 2 ] = tmp; - udata += 4; + udata += 4; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 3 ]; udata[ 3 ] = tmp; tmp = udata[ 1 ]; udata[ 1 ] = udata[ 2 ]; udata[ 2 ] = tmp; - udata += 4; + udata += 4; tmp = udata[ 0 ]; udata[ 0 ] = udata[ 3 ]; udata[ 3 ] = tmp; tmp = udata[ 1 ]; udata[ 1 ] = udata[ 2 ]; udata[ 2 ] = tmp; - udata += 4; + udata += 4; } for( ; j < size; j++ ) { @@ -383,8 +412,8 @@ void SwapEndian( void* data, size_t size, size_t elem_size ) udata += 4; } return; - - } + + } case 8: { size_t size8 = size & ~(0x7); @@ -433,7 +462,7 @@ void SwapEndian( void* data, size_t size, size_t elem_size ) tmp = udata[ 1 ]; udata[ 1 ] = udata[ 6 ]; udata[ 6 ] = tmp; tmp = udata[ 2 ]; udata[ 2 ] = udata[ 5 ]; udata[ 5 ] = tmp; tmp = udata[ 3 ]; udata[ 3 ] = udata[ 4 ]; udata[ 4 ] = tmp; - udata += 8; + udata += 8; } for( ; j < size; j++ ) { @@ -443,7 +472,7 @@ void SwapEndian( void* data, size_t size, size_t elem_size ) tmp = udata[ 3 ]; udata[ 3 ] = udata[ 4 ]; udata[ 4 ] = tmp; udata += 8; } - return; + return; } } } @@ -454,7 +483,7 @@ void DataBlock::swap_endian() switch( this->data_type_ ) { - case DataType::CHAR_E: + case DataType::CHAR_E: case DataType::UCHAR_E: break; case DataType::SHORT_E: @@ -466,6 +495,8 @@ void DataBlock::swap_endian() case DataType::FLOAT_E: SwapEndian( get_data(), get_size(), 4 ); break; + case DataType::LONGLONG_E: + case DataType::ULONGLONG_E: case DataType::DOUBLE_E: SwapEndian( get_data(), get_size(), 8 ); break; @@ -479,7 +510,7 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block size_t size = dst_data_block->get_size(); switch ( dst_data_block->get_data_type() ) { - case DataType::CHAR_E: + case DataType::CHAR_E: { signed char* dst = reinterpret_cast( dst_data_block->get_data() ); size_t size8 = size & ~(0x7); @@ -501,7 +532,7 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block } return true; } - case DataType::UCHAR_E: + case DataType::UCHAR_E: { unsigned char* dst = reinterpret_cast( dst_data_block->get_data() ); size_t size8 = size & ~(0x7); @@ -520,10 +551,10 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block for ( ; j < size; j++ ) { dst[ j ] = static_cast( src[ j ] ); - } + } return true; } - case DataType::SHORT_E: + case DataType::SHORT_E: { short* dst = reinterpret_cast( dst_data_block->get_data() ); size_t size8 = size & ~(0x7); @@ -542,10 +573,10 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block for ( ; j < size; j++ ) { dst[ j ] = static_cast( src[ j ] ); - } + } return true; } - case DataType::USHORT_E: + case DataType::USHORT_E: { unsigned short* dst = reinterpret_cast( dst_data_block->get_data() ); size_t size8 = size & ~(0x7); @@ -564,10 +595,10 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block for ( ; j < size; j++ ) { dst[ j ] = static_cast( src[ j ] ); - } + } return true; } - case DataType::INT_E: + case DataType::INT_E: { int* dst = reinterpret_cast( dst_data_block->get_data() ); size_t size8 = size & ~(0x7); @@ -586,10 +617,10 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block for ( ; j < size; j++ ) { dst[ j ] = static_cast( src[ j ] ); - } + } return true; } - case DataType::UINT_E: + case DataType::UINT_E: { unsigned int* dst = reinterpret_cast( dst_data_block->get_data() ); size_t size8 = size & ~(0x7); @@ -608,10 +639,54 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block for ( ; j < size; j++ ) { dst[ j ] = static_cast( src[ j ] ); - } + } + return true; + } + case DataType::LONGLONG_E: + { + long long* dst = reinterpret_cast( dst_data_block->get_data() ); + size_t size8 = size & ~(0x7); + size_t j = 0; + for ( ; j < size8; j+=8 ) + { + dst[ j ] = static_cast( src[ j ] ); + dst[ j + 1 ] = static_cast( src[ j + 1 ] ); + dst[ j + 2 ] = static_cast( src[ j + 2 ] ); + dst[ j + 3 ] = static_cast( src[ j + 3 ] ); + dst[ j + 4 ] = static_cast( src[ j + 4 ] ); + dst[ j + 5 ] = static_cast( src[ j + 5 ] ); + dst[ j + 6 ] = static_cast( src[ j + 6 ] ); + dst[ j + 7 ] = static_cast( src[ j + 7 ] ); + } + for ( ; j < size; j++ ) + { + dst[ j ] = static_cast( src[ j ] ); + } + return true; + } + case DataType::ULONGLONG_E: + { + unsigned long long* dst = reinterpret_cast( dst_data_block->get_data() ); + size_t size8 = size & ~(0x7); + size_t j = 0; + for ( ; j < size8; j+=8 ) + { + dst[ j ] = static_cast( src[ j ] ); + dst[ j + 1 ] = static_cast( src[ j + 1 ] ); + dst[ j + 2 ] = static_cast( src[ j + 2 ] ); + dst[ j + 3 ] = static_cast( src[ j + 3 ] ); + dst[ j + 4 ] = static_cast( src[ j + 4 ] ); + dst[ j + 5 ] = static_cast( src[ j + 5 ] ); + dst[ j + 6 ] = static_cast( src[ j + 6 ] ); + dst[ j + 7 ] = static_cast( src[ j + 7 ] ); + } + for ( ; j < size; j++ ) + { + dst[ j ] = static_cast( src[ j ] ); + } return true; } - case DataType::FLOAT_E: + case DataType::FLOAT_E: { float* dst = reinterpret_cast( dst_data_block->get_data() ); size_t size8 = size & ~(0x7); @@ -630,10 +705,10 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block for ( ; j < size; j++ ) { dst[ j ] = static_cast( src[ j ] ); - } + } return true; } - case DataType::DOUBLE_E: + case DataType::DOUBLE_E: { double* dst = reinterpret_cast( dst_data_block->get_data() ); size_t size8 = size & ~(0x7); @@ -652,7 +727,7 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block for ( ; j < size; j++ ) { dst[ j ] = static_cast( src[ j ] ); - } + } return true; } default: @@ -664,7 +739,7 @@ static bool ConvertDataTypeInternal( DATA* src, DataBlockHandle& dst_data_block } -bool DataBlock::ConvertDataType( const DataBlockHandle& src_data_block, +bool DataBlock::ConvertDataType( const DataBlockHandle& src_data_block, DataBlockHandle& dst_data_block, DataType new_data_type ) { dst_data_block.reset(); @@ -674,37 +749,43 @@ bool DataBlock::ConvertDataType( const DataBlockHandle& src_data_block, dst_data_block = StdDataBlock::New( src_data_block->get_nx(), src_data_block->get_ny(), src_data_block->get_nz(), new_data_type ); - + if ( !dst_data_block ) { return false; } - + switch( src_data_block->get_data_type() ) { case DataType::CHAR_E: - return ConvertDataTypeInternal( + return ConvertDataTypeInternal( reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::UCHAR_E: - return ConvertDataTypeInternal( + return ConvertDataTypeInternal( reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::SHORT_E: - return ConvertDataTypeInternal( + return ConvertDataTypeInternal( reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::USHORT_E: - return ConvertDataTypeInternal( + return ConvertDataTypeInternal( reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::INT_E: - return ConvertDataTypeInternal( + return ConvertDataTypeInternal( reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::UINT_E: - return ConvertDataTypeInternal( + return ConvertDataTypeInternal( reinterpret_cast( src_data_block->get_data() ), dst_data_block ); + case DataType::LONGLONG_E: + return ConvertDataTypeInternal( + reinterpret_cast( src_data_block->get_data() ), dst_data_block ); + case DataType::ULONGLONG_E: + return ConvertDataTypeInternal( + reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::FLOAT_E: - return ConvertDataTypeInternal( + return ConvertDataTypeInternal( reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::DOUBLE_E: - return ConvertDataTypeInternal( + return ConvertDataTypeInternal( reinterpret_cast( src_data_block->get_data() ), dst_data_block ); default: dst_data_block.reset(); @@ -713,7 +794,7 @@ bool DataBlock::ConvertDataType( const DataBlockHandle& src_data_block, } template -static bool PermuteDataInternal( const DataBlockHandle& src_data_block, +static bool PermuteDataInternal( const DataBlockHandle& src_data_block, DataBlockHandle& dst_data_block, std::vector& permutation ) { DATA* src = reinterpret_cast( src_data_block->get_data() ); @@ -723,47 +804,47 @@ static bool PermuteDataInternal( const DataBlockHandle& src_data_block, std::vector start(3); std::vector stride(3); - + index_type nx = static_cast( src_data_block->get_nx() ); index_type ny = static_cast( src_data_block->get_ny() ); index_type nz = static_cast( src_data_block->get_nz() ); index_type nxy = nx*ny; index_type nxyz = nx*ny*nz; - + for ( index_type j = 0; j < 3; j++) { if ( permutation[ j ] == 1 ) { start[ j ] = 0; - stride[ j ] = 1; + stride[ j ] = 1; } else if ( permutation[ j ] == -1 ) { start[ j ] = nx - 1; - stride[ j ] = -1; + stride[ j ] = -1; } else if ( permutation[ j ] == 2 ) { start[ j ] = 0; - stride[ j ] = nx; + stride[ j ] = nx; } else if ( permutation[ j ] == -2 ) { start[ j ] = nxy - nx; - stride[ j ] = -nx; + stride[ j ] = -nx; } else if ( permutation[ j ] == 3 ) { start[ j ] = 0; - stride[ j ] = nxy; + stride[ j ] = nxy; } else if ( permutation[ j ] == -3 ) { start[ j ] = nxyz - nxy; - stride[ j ] = -nxy; + stride[ j ] = -nxy; } } - + index_type dnx = static_cast( dst_data_block->get_nx() ); index_type dny = static_cast( dst_data_block->get_ny() ); index_type dnz = static_cast( dst_data_block->get_nz() ); @@ -788,11 +869,11 @@ static bool PermuteDataInternal( const DataBlockHandle& src_data_block, } sz += sz_stride; } - + return true; } -bool DataBlock::PermuteData( const DataBlockHandle& src_data_block, +bool DataBlock::PermuteData( const DataBlockHandle& src_data_block, DataBlockHandle& dst_data_block, std::vector permutation ) { dst_data_block.reset(); @@ -805,49 +886,55 @@ bool DataBlock::PermuteData( const DataBlockHandle& src_data_block, dst_data_block.reset(); return false; } - + size_t dn[3]; dn[ 0 ] = 1; dn[ 1 ] = 1; dn[ 2 ] = 1; - + for ( size_t j = 0; j < 3; j++) { if ( permutation[ j ] == 1 || permutation[ j ] == -1 ) dn[ j ] = src_data_block->get_nx(); if ( permutation[ j ] == 2 || permutation[ j ] == -2 ) dn[ j ] = src_data_block->get_ny(); - if ( permutation[ j ] == 3 || permutation[ j ] == -3 ) dn[ j ] = src_data_block->get_nz(); + if ( permutation[ j ] == 3 || permutation[ j ] == -3 ) dn[ j ] = src_data_block->get_nz(); } - + if ( dn[ 0 ] * dn[ 1 ] * dn[ 2 ] == 0 ) return false; - - dst_data_block = StdDataBlock::New( dn[ 0 ], dn[ 1 ], dn[ 2 ], - src_data_block->get_data_type() ); + + dst_data_block = StdDataBlock::New( dn[ 0 ], dn[ 1 ], dn[ 2 ], + src_data_block->get_data_type() ); switch( src_data_block->get_data_type() ) { case DataType::CHAR_E: - return PermuteDataInternal( src_data_block, dst_data_block, + return PermuteDataInternal( src_data_block, dst_data_block, permutation ); case DataType::UCHAR_E: - return PermuteDataInternal( src_data_block, dst_data_block, + return PermuteDataInternal( src_data_block, dst_data_block, permutation ); case DataType::SHORT_E: - return PermuteDataInternal( src_data_block, dst_data_block, + return PermuteDataInternal( src_data_block, dst_data_block, permutation ); case DataType::USHORT_E: - return PermuteDataInternal( src_data_block, dst_data_block, + return PermuteDataInternal( src_data_block, dst_data_block, permutation ); case DataType::INT_E: - return PermuteDataInternal( src_data_block, dst_data_block, + return PermuteDataInternal( src_data_block, dst_data_block, permutation ); case DataType::UINT_E: - return PermuteDataInternal( src_data_block, dst_data_block, + return PermuteDataInternal( src_data_block, dst_data_block, + permutation ); + case DataType::LONGLONG_E: + return PermuteDataInternal( src_data_block, dst_data_block, + permutation ); + case DataType::ULONGLONG_E: + return PermuteDataInternal( src_data_block, dst_data_block, permutation ); case DataType::FLOAT_E: - return PermuteDataInternal( src_data_block, dst_data_block, + return PermuteDataInternal( src_data_block, dst_data_block, permutation ); case DataType::DOUBLE_E: - return PermuteDataInternal( src_data_block, dst_data_block, + return PermuteDataInternal( src_data_block, dst_data_block, permutation ); default: return false; @@ -860,103 +947,135 @@ static bool QuantizeDataInternal( double min, double max, DATA* src, DataBlockHa { float fmin = static_cast( min ); float fmax = static_cast( max ); - + size_t size = dst_data_block->get_size(); switch ( dst_data_block->get_data_type() ) { - case DataType::CHAR_E: + case DataType::CHAR_E: { signed char* dst = reinterpret_cast( dst_data_block->get_data() ); float offset = 0.5f - static_cast( 0x80 ); float multiplier = 0.0f; if ( fmax > fmin ) multiplier = static_cast( 0x100 ) / (fmax - fmin); - + for ( size_t j = 0 ; j < size; j++ ) { - dst[ j ] = static_cast( multiplier * + dst[ j ] = static_cast( multiplier * (static_cast( src[ j ] ) - fmin) + offset ); } - + return true; } - case DataType::UCHAR_E: + case DataType::UCHAR_E: { unsigned char* dst = reinterpret_cast( dst_data_block->get_data() ); - + float offset = 0.5f; float multiplier = 0.0f; if ( fmax > fmin ) multiplier = static_cast( 0x100 ) / (fmax - fmin); - + for ( size_t j = 0 ; j < size; j++ ) { - dst[ j ] = static_cast( multiplier * + dst[ j ] = static_cast( multiplier * (static_cast( src[ j ] ) - fmin) + offset ); } return true; } - case DataType::SHORT_E: + case DataType::SHORT_E: { short* dst = reinterpret_cast( dst_data_block->get_data() ); float offset = 0.5f - static_cast( 0x8000 ); float multiplier = 0.0f; if ( fmax > fmin ) multiplier = static_cast( 0x10000 ) / (fmax - fmin); - + for ( size_t j = 0 ; j < size; j++ ) { - dst[ j ] = static_cast( multiplier * + dst[ j ] = static_cast( multiplier * (static_cast( src[ j ] ) - fmin) + offset ); } - + return true; } - case DataType::USHORT_E: + case DataType::USHORT_E: { unsigned short* dst = reinterpret_cast( dst_data_block->get_data() ); float offset = 0.5f; float multiplier = 0.0f; if ( fmax > fmin ) multiplier = static_cast( 0x10000 ) / (fmax - fmin); - + for ( size_t j = 0 ; j < size; j++ ) { - dst[ j ] = static_cast( multiplier * + dst[ j ] = static_cast( multiplier * (static_cast( src[ j ] ) - fmin) + offset); } - + return true; } - case DataType::INT_E: + case DataType::INT_E: { int* dst = reinterpret_cast( dst_data_block->get_data() ); double offset = 0.5 - static_cast( 0x80000000 ); double multiplier = 0.0; if ( max > min ) multiplier = static_cast( 0x100000000ull ) / (max - min); - + for ( size_t j = 0 ; j < size; j++ ) { - dst[ j ] = static_cast( multiplier * + dst[ j ] = static_cast( multiplier * (static_cast( src[ j ] ) - min) + offset); } - + return true; } - case DataType::UINT_E: + case DataType::UINT_E: { unsigned int* dst = reinterpret_cast( dst_data_block->get_data() ); double offset = 0.5; double multiplier = 0.0; if ( max > min ) multiplier = static_cast( 0x100000000ull ) / (max - min); - + for ( size_t j = 0 ; j < size; j++ ) { - dst[ j ] = static_cast( multiplier * + dst[ j ] = static_cast( multiplier * (static_cast( src[ j ] ) - min) + offset); } - + + return true; + } + case DataType::LONGLONG_E: + { + long long* dst = reinterpret_cast( dst_data_block->get_data() ); + + double offset = 0.5 - static_cast( 0x80000000 ) * static_cast( 0x100000000ull ); + double multiplier = 0.0; + if ( max > min ) multiplier = static_cast( 0x100000000ull ) * static_cast( 0x100000000ull ) / (max - min); + + for ( size_t j = 0 ; j < size; j++ ) + { + dst[ j ] = static_cast( multiplier * + (static_cast( src[ j ] ) - fmin) + offset ); + } + + return true; + } + case DataType::ULONGLONG_E: + { + unsigned long long* dst = reinterpret_cast( dst_data_block->get_data() ); + + double offset = 0.5; + double multiplier = 0.0; + if ( max > min ) multiplier = static_cast( 0x100000000ull ) * static_cast( 0x100000000ull ) / (max - min); + + for ( size_t j = 0 ; j < size; j++ ) + { + dst[ j ] = static_cast( multiplier * + (static_cast( src[ j ] ) - fmin) + offset); + } + return true; } default: @@ -967,39 +1086,40 @@ static bool QuantizeDataInternal( double min, double max, DATA* src, DataBlockHa } } -bool DataBlock::QuantizeData( const DataBlockHandle& src_data_block, +bool DataBlock::QuantizeData( const DataBlockHandle& src_data_block, DataBlockHandle& dst_data_block, DataType new_data_type ) { dst_data_block.reset(); if ( !src_data_block ) return false; - + shared_lock_type lock( src_data_block->get_mutex( ) ); if ( new_data_type != DataType::CHAR_E && new_data_type != DataType::UCHAR_E && new_data_type != DataType::SHORT_E && new_data_type != DataType::USHORT_E && - new_data_type != DataType::INT_E && new_data_type != DataType::UINT_E ) + new_data_type != DataType::INT_E && new_data_type != DataType::UINT_E && + new_data_type != DataType::LONGLONG_E && new_data_type != DataType::ULONGLONG_E ) { return false; - } + } dst_data_block = StdDataBlock::New( src_data_block->get_nx(), src_data_block->get_ny(), src_data_block->get_nz(), new_data_type ); - + if ( !dst_data_block ) { return false; } - + double min = src_data_block->get_min(); double max = src_data_block->get_max(); - + switch( src_data_block->get_data_type() ) { case DataType::CHAR_E: - return QuantizeDataInternal( min, max, + return QuantizeDataInternal( min, max, reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::UCHAR_E: - return QuantizeDataInternal( min, max, + return QuantizeDataInternal( min, max, reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::SHORT_E: return QuantizeDataInternal( min, max, @@ -1013,6 +1133,12 @@ bool DataBlock::QuantizeData( const DataBlockHandle& src_data_block, case DataType::UINT_E: return QuantizeDataInternal( min, max, reinterpret_cast( src_data_block->get_data() ), dst_data_block ); + case DataType::LONGLONG_E: + return QuantizeDataInternal( min, max, + reinterpret_cast( src_data_block->get_data() ), dst_data_block ); + case DataType::ULONGLONG_E: + return QuantizeDataInternal( min, max, + reinterpret_cast( src_data_block->get_data() ), dst_data_block ); case DataType::FLOAT_E: return QuantizeDataInternal( min, max, reinterpret_cast( src_data_block->get_data() ), dst_data_block ); @@ -1024,7 +1150,7 @@ bool DataBlock::QuantizeData( const DataBlockHandle& src_data_block, } } -bool DataBlock::Duplicate( const DataBlockHandle& src_data_block, +bool DataBlock::Duplicate( const DataBlockHandle& src_data_block, DataBlockHandle& dst_data_block ) { // Step (1) : Check whether there is a source data block @@ -1037,9 +1163,9 @@ bool DataBlock::Duplicate( const DataBlockHandle& src_data_block, // Step (3): Generate a new data block with the right type dst_data_block = StdDataBlock::New( src_data_block->get_nx(), src_data_block->get_ny(), src_data_block->get_nz(), src_data_block->get_data_type() ); - - // Step (4): Copy the data - size_t mem_size = src_data_block->get_size(); + + // Step (4): Copy the data + size_t mem_size = src_data_block->get_size(); switch( src_data_block->get_data_type() ) { case DataType::CHAR_E: @@ -1060,6 +1186,12 @@ bool DataBlock::Duplicate( const DataBlockHandle& src_data_block, case DataType::UINT_E: mem_size *= sizeof( unsigned int ); break; + case DataType::LONGLONG_E: + mem_size *= sizeof( long long ); + break; + case DataType::ULONGLONG_E: + mem_size *= sizeof( unsigned long long ); + break; case DataType::FLOAT_E: mem_size *= sizeof( float ); break; @@ -1070,7 +1202,7 @@ bool DataBlock::Duplicate( const DataBlockHandle& src_data_block, return false; } std::memcpy( dst_data_block->get_data(), src_data_block->get_data(), mem_size ); - + // Step (5) : Copy the histogram dst_data_block->set_histogram( src_data_block->get_histogram() ); @@ -1078,12 +1210,12 @@ bool DataBlock::Duplicate( const DataBlockHandle& src_data_block, } template -bool ExtractSliceInternal( DataBlock* volume_data_block, +bool ExtractSliceInternal( DataBlock* volume_data_block, DataSliceHandle& slice, SliceType type, DataBlock::index_type index ) { // Clear the handle so it does not refer to anything slice.reset(); - + // Create a datablock in which the slice is generated DataBlockHandle slice_data_block; @@ -1091,7 +1223,7 @@ bool ExtractSliceInternal( DataBlock* volume_data_block, size_t nx = volume_data_block->get_nx(); size_t ny = volume_data_block->get_ny(); size_t nz = volume_data_block->get_nz(); - + // The algorithm is optimized for the axis type switch( type ) { @@ -1100,15 +1232,15 @@ bool ExtractSliceInternal( DataBlock* volume_data_block, { // Check whether the slice is in range if ( index < 0 || index >= static_cast( nx ) ) return false; - + // Create a new datablock for this slice slice_data_block = StdDataBlock::New( 1, ny, nz, volume_data_block->get_data_type() ); if ( !slice_data_block ) return false; - + // Get the direct pointers to the data T* volume_ptr = reinterpret_cast( volume_data_block->get_data() ); T* slice_ptr = reinterpret_cast( slice_data_block->get_data() ); - + // Short cut so we do not need to recompute this one over and over again size_t nxy = nx * ny; // Size for loop unrolling @@ -1121,7 +1253,7 @@ bool ExtractSliceInternal( DataBlock* volume_data_block, for ( ; y < ny8; y += 8 ) { // Copy the data over - size_t a = y + z * ny; + size_t a = y + z * ny; size_t b = index + y * nx + z * nxy; slice_ptr[ a ] = volume_ptr[ b ]; a++; b+= nx; slice_ptr[ a ] = volume_ptr[ b ]; a++; b+= nx; @@ -1138,7 +1270,7 @@ bool ExtractSliceInternal( DataBlock* volume_data_block, slice_ptr[ y + z * ny ] = volume_ptr[ index + y * nx + z * nxy ]; } } - + slice = DataSliceHandle( new DataSlice( slice_data_block, type, index ) ); return true; } @@ -1147,15 +1279,15 @@ bool ExtractSliceInternal( DataBlock* volume_data_block, { // Check whether the slice is in range if ( index < 0 || index >= static_cast( ny ) ) return false; - + // Create a new datablock for this slice slice_data_block = StdDataBlock::New( nx, 1, nz, volume_data_block->get_data_type() ); if ( !slice_data_block ) return false; - + // Get the direct pointers to the data T* volume_ptr = reinterpret_cast( volume_data_block->get_data() ); T* slice_ptr = reinterpret_cast( slice_data_block->get_data() ); - + // Short cut so we do not need to recompute this one over and over again size_t nxy = nx * ny; // Size for loop unrolling @@ -1168,7 +1300,7 @@ bool ExtractSliceInternal( DataBlock* volume_data_block, for ( ; x < nx8; x += 8 ) { // Copy the data over - size_t a = x + z * nx; + size_t a = x + z * nx; size_t b = x + index * nx + z * nxy; slice_ptr[ a ] = volume_ptr[ b ]; a++; b++; slice_ptr[ a ] = volume_ptr[ b ]; a++; b++; @@ -1194,15 +1326,15 @@ bool ExtractSliceInternal( DataBlock* volume_data_block, { // Check range of data if ( index < 0 || index >= static_cast( nz ) ) return false; - + // Create a new data block slice_data_block = StdDataBlock::New( nx, ny, 1, volume_data_block->get_data_type() ); if ( !slice_data_block ) return false; - + // Get direct pointers to the data T* volume_ptr = reinterpret_cast( volume_data_block->get_data() ); T* slice_ptr = reinterpret_cast( slice_data_block->get_data() ); - + // Copy the data as one block copy. As data is properly aligned in data, it can be // done in one copy, unlike the previous two std::memcpy( slice_ptr, volume_ptr + index * ( nx * ny ), nx * ny * sizeof( T ) ); @@ -1224,7 +1356,7 @@ bool DataBlock::extract_slice( SliceType type, index_type index, DataSliceHandle // For each of the supported datatypes grab the slice using a templated function switch( this->get_data_type() ) - { + { case DataType::CHAR_E: return ExtractSliceInternal( this, slice, type, index ); case DataType::UCHAR_E: @@ -1237,6 +1369,10 @@ bool DataBlock::extract_slice( SliceType type, index_type index, DataSliceHandle return ExtractSliceInternal( this, slice, type, index ); case DataType::UINT_E: return ExtractSliceInternal( this, slice, type, index ); + case DataType::LONGLONG_E: + return ExtractSliceInternal( this, slice, type, index ); + case DataType::ULONGLONG_E: + return ExtractSliceInternal( this, slice, type, index ); case DataType::FLOAT_E: return ExtractSliceInternal( this, slice, type, index ); case DataType::DOUBLE_E: @@ -1254,17 +1390,17 @@ bool InsertSliceInternal( DataBlock* volume_data_block, const DataSliceHandle& s size_t nx = volume_data_block->get_nx(); size_t ny = volume_data_block->get_ny(); size_t nz = volume_data_block->get_nz(); - + // Get the slice DataBlock DataBlockHandle slice_data_block = slice->get_data_block(); - + // Need to have a write lock for the volume // NOTE: once the data is altered, the generation number needs to be increased DataBlock::lock_type lock( volume_data_block->get_mutex() ); // Need to have a read lock on the slice DataBlock::shared_lock_type slock( slice_data_block->get_mutex() ); - - DataBlock::index_type index = slice->get_index(); + + DataBlock::index_type index = slice->get_index(); // For each axis there is an optimized algorithm switch( slice->get_slice_type() ) { @@ -1273,11 +1409,11 @@ bool InsertSliceInternal( DataBlock* volume_data_block, const DataSliceHandle& s { // Check the range of the slice number if ( index < 0 || index >= static_cast( nx ) ) return false; - + // Get the pointers for source and destination T* volume_ptr = reinterpret_cast( volume_data_block->get_data() ); T* slice_ptr = reinterpret_cast( slice_data_block->get_data() ); - + size_t nxy = nx * ny; // For loop unroll size_t ny8 = RemoveRemainder8( ny ); @@ -1289,7 +1425,7 @@ bool InsertSliceInternal( DataBlock* volume_data_block, const DataSliceHandle& s for ( ; y < ny8; y += 8 ) { // Copy data back - size_t a = y + z * ny; + size_t a = y + z * ny; size_t b = index + y * nx + z * nxy; volume_ptr[ b ] = slice_ptr[ a ]; a++; b+= nx; volume_ptr[ b ] = slice_ptr[ a ]; a++; b+= nx; @@ -1306,7 +1442,7 @@ bool InsertSliceInternal( DataBlock* volume_data_block, const DataSliceHandle& s volume_ptr[ index + y * nx + z * nxy ] = slice_ptr[ y + z * ny ]; } } - + volume_data_block->increase_generation(); return true; @@ -1315,11 +1451,11 @@ bool InsertSliceInternal( DataBlock* volume_data_block, const DataSliceHandle& s { // Check the range of the slice number if ( index < 0 || index >= static_cast( ny ) ) return false; - + // Get the pointers for source and destination T* volume_ptr = reinterpret_cast( volume_data_block->get_data() ); T* slice_ptr = reinterpret_cast( slice_data_block->get_data() ); - + size_t nxy = nx * ny; // For loop unroll size_t nx8 = RemoveRemainder8( nx ); @@ -1331,7 +1467,7 @@ bool InsertSliceInternal( DataBlock* volume_data_block, const DataSliceHandle& s for ( ; x < nx8; x += 8 ) { // Copy data back - size_t a = x + z * nx; + size_t a = x + z * nx; size_t b = x + index * nx + z * nxy; volume_ptr[ b ] = slice_ptr[ a ]; a++; b++; volume_ptr[ b ] = slice_ptr[ a ]; a++; b++; @@ -1350,23 +1486,23 @@ bool InsertSliceInternal( DataBlock* volume_data_block, const DataSliceHandle& s } volume_data_block->increase_generation(); - + return true; } case SliceType::AXIAL_E: { // Check the range of the slice number if ( index < 0 || index >= static_cast( nz ) ) return false; - + // Get the pointers for source and destination T* volume_ptr = reinterpret_cast( volume_data_block->get_data() ); T* slice_ptr = reinterpret_cast( slice_data_block->get_data() ); - + // Copy data as one memory block back std::memcpy( volume_ptr + index * ( nx * ny ), slice_ptr, nx * ny * sizeof( T ) ); - + volume_data_block->increase_generation(); - + return true; } default: @@ -1384,7 +1520,7 @@ bool DataBlock::insert_slice( const DataSliceHandle slice ) // Jump to the right algorithm for each data type switch( this->get_data_type() ) - { + { case DataType::CHAR_E: return InsertSliceInternal( this, slice ); case DataType::UCHAR_E: @@ -1397,6 +1533,10 @@ bool DataBlock::insert_slice( const DataSliceHandle slice ) return InsertSliceInternal( this, slice ); case DataType::UINT_E: return InsertSliceInternal( this, slice ); + case DataType::LONGLONG_E: + return InsertSliceInternal( this, slice ); + case DataType::ULONGLONG_E: + return InsertSliceInternal( this, slice ); case DataType::FLOAT_E: return InsertSliceInternal( this, slice ); case DataType::DOUBLE_E: @@ -1435,7 +1575,7 @@ bool PadInternal( DataBlockHandle src, DataBlockHandle dst, int pad, double val) DataBlock::index_type pnz = dst->get_nz(); DataBlock::index_type p = static_cast(pad); - + if (p > 0) { size_t size = dst->get_size(); @@ -1477,7 +1617,7 @@ bool PadInternal( DataBlockHandle src, DataBlockHandle dst, int pad, double val) } } } - + return true; } @@ -1499,7 +1639,7 @@ bool DataBlock::Pad( DataBlockHandle src_data_block, dst_data_block = StdDataBlock::New( src_data_block->get_nx() + 2*pad, src_data_block->get_ny() + 2*pad, src_data_block->get_nz() + 2*pad, src_data_block->get_data_type() ); - + switch( src_data_block->get_data_type() ) { case DataType::CHAR_E: @@ -1514,6 +1654,10 @@ bool DataBlock::Pad( DataBlockHandle src_data_block, return PadInternal(src_data_block,dst_data_block,pad, val); case DataType::UINT_E: return PadInternal(src_data_block,dst_data_block,pad, val); + case DataType::LONGLONG_E: + return PadInternal(src_data_block,dst_data_block,pad, val); + case DataType::ULONGLONG_E: + return PadInternal(src_data_block,dst_data_block,pad, val); case DataType::FLOAT_E: return PadInternal(src_data_block,dst_data_block,pad, val); case DataType::DOUBLE_E: @@ -1561,12 +1705,12 @@ bool ClipInternal( DataBlockHandle src, DataBlockHandle dst, double val) for ( DataBlock::index_type x = 0; x < mnx; x++, sk++, dk++ ) { ddata[dk] = sdata[sk]; - } + } for ( DataBlock::index_type x = 0; x < dx_offset; x++, dk++ ) { ddata[dk] = typed_val; } - } + } for ( DataBlock::index_type m = 0; m < dy_offset; m++, dk++ ) { ddata[dk] = typed_val; @@ -1576,7 +1720,7 @@ bool ClipInternal( DataBlockHandle src, DataBlockHandle dst, double val) { ddata[dk] = typed_val; } - + return true; } @@ -1595,7 +1739,7 @@ bool DataBlock::Clip( DataBlockHandle src_data_block, // Step (3): Generate a new data block with the right type dst_data_block = StdDataBlock::New( width, height, depth, src_data_block->get_data_type() ); - + switch( src_data_block->get_data_type() ) { case DataType::CHAR_E: @@ -1610,6 +1754,10 @@ bool DataBlock::Clip( DataBlockHandle src_data_block, return ClipInternal(src_data_block,dst_data_block, val); case DataType::UINT_E: return ClipInternal(src_data_block,dst_data_block, val); + case DataType::LONGLONG_E: + return ClipInternal(src_data_block,dst_data_block, val); + case DataType::ULONGLONG_E: + return ClipInternal(src_data_block,dst_data_block, val); case DataType::FLOAT_E: return ClipInternal(src_data_block,dst_data_block, val); case DataType::DOUBLE_E: diff --git a/src/Core/DataBlock/DataType.cc b/src/Core/DataBlock/DataType.cc index b6adcb645..cf5e473ab 100644 --- a/src/Core/DataBlock/DataType.cc +++ b/src/Core/DataBlock/DataType.cc @@ -41,7 +41,7 @@ namespace Core bool ImportFromString( const std::string& data_type_string, DataType& data_type ) { - std::string lower_data_type = boost::to_lower_copy( data_type_string ); + std::string lower_data_type = boost::to_lower_copy( data_type_string ); boost::erase_all( lower_data_type , " " ); if ( lower_data_type == "char" || lower_data_type == "signedchar") @@ -189,7 +189,8 @@ bool IsInteger( const DataType& data_type ) { return ( data_type == DataType::CHAR_E || data_type == DataType::UCHAR_E || data_type == DataType::SHORT_E || data_type == DataType::USHORT_E || - data_type == DataType::INT_E || data_type == DataType::UINT_E ); + data_type == DataType::INT_E || data_type == DataType::UINT_E || + data_type == DataType::LONGLONG_E || data_type == DataType::ULONGLONG_E ); } bool IsReal( const DataType& data_type ) diff --git a/src/Core/DataBlock/Histogram.cc b/src/Core/DataBlock/Histogram.cc index 03912110d..d8b445464 100644 --- a/src/Core/DataBlock/Histogram.cc +++ b/src/Core/DataBlock/Histogram.cc @@ -42,7 +42,7 @@ namespace Core { -Histogram::Histogram() +Histogram::Histogram() { this->min_ = Core::Nan(); this->max_ = Core::Nan(); @@ -55,7 +55,7 @@ Histogram::Histogram( const signed char* data, size_t size ) { this->compute( data, size ); } - + Histogram::Histogram( const unsigned char* data, size_t size ) { this->compute( data, size ); @@ -81,6 +81,16 @@ Histogram::Histogram( const unsigned int* data, size_t size ) this->compute( data, size ); } +Histogram::Histogram( const long long* data, size_t size ) +{ + this->compute( data, size ); +} + +Histogram::Histogram( const unsigned long long* data, size_t size ) +{ + this->compute( data, size ); +} + Histogram::Histogram( const float* data, size_t size ) { this->compute( data, size ); @@ -107,7 +117,7 @@ bool Histogram::compute( const signed char* data, size_t size ) this->bin_size_ = Core::Nan(); this->histogram_.resize( 0 ); if ( size == 0 ) return false; - + try { std::vector histogram; @@ -117,10 +127,10 @@ bool Histogram::compute( const signed char* data, size_t size ) { histogram[ static_cast( data[ j ] ) + 0x80 ]++; } - + size_t hist_begin = 0; size_t hist_end = 0; - + for ( size_t j = 0 ; j < histogram.size() ; j++ ) { if ( histogram[ j ] > 0 ) hist_end = j; @@ -144,7 +154,7 @@ bool Histogram::compute( const signed char* data, size_t size ) this->histogram_[ j ] = histogram[ j + hist_begin ]; } - std::pair< std::vector::iterator, std::vector::iterator > min_max = + std::pair< std::vector::iterator, std::vector::iterator > min_max = boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); this->min_bin_ = (*min_max.first); this->max_bin_ = (*min_max.second); @@ -158,7 +168,7 @@ bool Histogram::compute( const signed char* data, size_t size ) this->histogram_.resize( 0 ); return false; } - + return true; } @@ -175,15 +185,15 @@ bool Histogram::compute( const unsigned char* data, size_t size ) { std::vector histogram; histogram.resize( 0x100, 0 ); - + for ( size_t j = 0 ; j < size ; j++ ) { histogram[ static_cast( data[ j ] ) ]++; } - + size_t hist_begin = 0; size_t hist_end = 0; - + for ( size_t j = 0 ; j < histogram.size() ; j++ ) { if ( histogram[ j ] > 0 ) hist_end = j; @@ -209,7 +219,7 @@ bool Histogram::compute( const unsigned char* data, size_t size ) this->histogram_[ j ] = histogram[ j + hist_begin ]; } - std::pair< std::vector::iterator, std::vector::iterator > min_max = + std::pair< std::vector::iterator, std::vector::iterator > min_max = boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); this->min_bin_ = (*min_max.first); this->max_bin_ = (*min_max.second); @@ -223,8 +233,8 @@ bool Histogram::compute( const unsigned char* data, size_t size ) this->histogram_.resize( 0 ); return false; } - - return true; + + return true; } bool Histogram::compute( const short* data, size_t size ) @@ -240,15 +250,15 @@ bool Histogram::compute( const short* data, size_t size ) { std::vector histogram; histogram.resize( 0x10000 , 0 ); - + for ( size_t j = 0 ; j < size ; j++ ) { histogram[ static_cast( data[ j ] ) + 0x8000 ]++; } - + size_t hist_begin = 0; size_t hist_end = 0; - + for ( size_t j = 0 ; j < histogram.size() ; j++ ) { if ( histogram[ j ] > 0 ) hist_end = j; @@ -265,7 +275,7 @@ bool Histogram::compute( const short* data, size_t size ) size_t hist_length = hist_end + 1 - hist_begin; if ( hist_length > 0x100 ) hist_length = 0x100; - + this->histogram_.resize( hist_length, 0 ); if ( hist_length == 1 ) @@ -278,7 +288,7 @@ bool Histogram::compute( const short* data, size_t size ) this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_length - 1 ); this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); } - + for ( size_t j = 0 ; j < histogram_.size() ; j++ ) { double min_value = this->bin_start_ + j * this->bin_size_; @@ -287,14 +297,14 @@ bool Histogram::compute( const short* data, size_t size ) for ( int k = Ceil( min_value ) ; k < Ceil( max_value ); k++ ) { int idx = static_cast( k ) + 0x8000; - if ( idx >= 0 && idx < static_cast( histogram.size() ) ) + if ( idx >= 0 && idx < static_cast( histogram.size() ) ) { this->histogram_[ j ] += histogram[ idx ]; } } } - std::pair< std::vector::iterator, std::vector::iterator > min_max = + std::pair< std::vector::iterator, std::vector::iterator > min_max = boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); this->min_bin_ = (*min_max.first); this->max_bin_ = (*min_max.second); @@ -308,8 +318,8 @@ bool Histogram::compute( const short* data, size_t size ) this->histogram_.resize( 0 ); return false; } - - return true; + + return true; } @@ -326,15 +336,15 @@ bool Histogram::compute( const unsigned short* data, size_t size ) { std::vector histogram; histogram.resize( 0x10000 , 0 ); - + for ( size_t j = 0 ; j < size ; j++ ) { histogram[ static_cast( data[ j ] ) ]++; } - + size_t hist_begin = 0; size_t hist_end = 0; - + for ( size_t j = 0 ; j < histogram.size() ; j++ ) { if ( histogram[ j ] > 0 ) hist_end = j; @@ -351,7 +361,7 @@ bool Histogram::compute( const unsigned short* data, size_t size ) size_t hist_length = hist_end + 1 - hist_begin; if ( hist_length > 0x100 ) hist_length = 0x100; - + this->histogram_.resize( hist_length, 0 ); if ( hist_length == 1 ) @@ -364,7 +374,7 @@ bool Histogram::compute( const unsigned short* data, size_t size ) this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_length - 1 ); this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); } - + for ( size_t j = 0 ; j < histogram_.size() ; j++ ) { double min_value = this->bin_start_ + j * this->bin_size_; @@ -373,14 +383,14 @@ bool Histogram::compute( const unsigned short* data, size_t size ) for ( int k = Ceil( min_value ) ; k < Ceil( max_value ); k ++ ) { int idx = static_cast( k ); - if ( idx >= 0 && idx < static_cast( histogram.size() ) ) + if ( idx >= 0 && idx < static_cast( histogram.size() ) ) { this->histogram_[ j ] += histogram[ idx ]; } } } - std::pair< std::vector::iterator, std::vector::iterator > min_max = + std::pair< std::vector::iterator, std::vector::iterator > min_max = boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); this->min_bin_ = (*min_max.first); this->max_bin_ = (*min_max.second); @@ -394,8 +404,8 @@ bool Histogram::compute( const unsigned short* data, size_t size ) this->histogram_.resize( 0 ); return false; } - - return true; + + return true; } @@ -418,7 +428,7 @@ bool Histogram::compute( const int* data, size_t size ) if ( data[ j ] < int_min ) int_min = data[ j ]; if ( data[ j ] > int_max ) int_max = data[ j ]; } - + this->min_ = static_cast( int_min ); this->max_ = static_cast( int_max ); @@ -440,18 +450,18 @@ bool Histogram::compute( const int* data, size_t size ) size_t hist_size = 0x100; this->histogram_.resize( hist_size, 0 ); this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_size - 1 ); - this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); } double inv_bin_size = 1.0 / this->bin_size_; for ( size_t j = 1 ; j < size ; j++ ) { - size_t idx = static_cast( ( static_cast( data[j] ) - + size_t idx = static_cast( ( static_cast( data[j] ) - this->min_ ) * inv_bin_size ); this->histogram_[ idx ]++; } - std::pair< std::vector::iterator, std::vector::iterator > min_max = + std::pair< std::vector::iterator, std::vector::iterator > min_max = boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); this->min_bin_ = (*min_max.first); this->max_bin_ = (*min_max.second); @@ -465,7 +475,7 @@ bool Histogram::compute( const int* data, size_t size ) this->histogram_.resize( 0 ); return false; } - + return true; } @@ -489,7 +499,77 @@ bool Histogram::compute( const unsigned int* data, size_t size ) if ( data[ j ] < int_min ) int_min = data[ j ]; if ( data[ j ] > int_max ) int_max = data[ j ]; } - + + this->min_ = static_cast( int_min ); + this->max_ = static_cast( int_max ); + + if ( this->min_ == this->max_ ) + { + this->bin_size_ = 1.0; + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + this->histogram_.resize( 1, 0 ); + } + else if ( ( this->max_ - this->min_ ) < 256.0 ) + { + size_t hist_size = static_cast( this->max_ - this->min_ ) + 1; + this->histogram_.resize( hist_size, 0 ); + this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_size - 1 ); + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + } + else + { + size_t hist_size = 0x100; + this->histogram_.resize( hist_size, 0 ); + this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_size - 1 ); + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + } + + double inv_bin_size = 1.0 / this->bin_size_; + for ( size_t j = 1 ; j < size ; j++ ) + { + size_t idx = static_cast( ( static_cast( data[j] ) - this->min_ ) * inv_bin_size ); + this->histogram_[ idx ]++; + } + + std::pair< std::vector::iterator, std::vector::iterator > min_max = + boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); + this->min_bin_ = (*min_max.first); + this->max_bin_ = (*min_max.second); + } + catch( ... ) + { + this->min_ = Core::Nan(); + this->max_ = Core::Nan(); + this->bin_start_ = Core::Nan(); + this->bin_size_ = Core::Nan(); + this->histogram_.resize( 0 ); + return false; + } + + return true; +} + + +bool Histogram::compute( const long long* data, size_t size ) +{ + this->min_ = Core::Nan(); + this->max_ = Core::Nan(); + this->bin_start_ = Core::Nan(); + this->bin_size_ = Core::Nan(); + this->histogram_.resize( 0 ); + if ( size == 0 ) return false; + + try + { + long long int_min = data[ 0 ]; + long long int_max = data[ 0 ]; + + for ( size_t j = 1 ; j < size ; j++ ) + { + if ( data[ j ] < int_min ) int_min = data[ j ]; + if ( data[ j ] > int_max ) int_max = data[ j ]; + } + this->min_ = static_cast( int_min ); this->max_ = static_cast( int_max ); @@ -511,7 +591,78 @@ bool Histogram::compute( const unsigned int* data, size_t size ) size_t hist_size = 0x100; this->histogram_.resize( hist_size, 0 ); this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_size - 1 ); - this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + } + + double inv_bin_size = 1.0 / this->bin_size_; + for ( size_t j = 1 ; j < size ; j++ ) + { + size_t idx = static_cast( ( static_cast( data[j] ) - + this->min_ ) * inv_bin_size ); + this->histogram_[ idx ]++; + } + + std::pair< std::vector::iterator, std::vector::iterator > min_max = + boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); + this->min_bin_ = (*min_max.first); + this->max_bin_ = (*min_max.second); + } + catch( ... ) + { + this->min_ = Core::Nan(); + this->max_ = Core::Nan(); + this->bin_start_ = Core::Nan(); + this->bin_size_ = Core::Nan(); + this->histogram_.resize( 0 ); + return false; + } + + return true; +} + + +bool Histogram::compute( const unsigned long long* data, size_t size ) +{ + this->min_ = Core::Nan(); + this->max_ = Core::Nan(); + this->bin_start_ = Core::Nan(); + this->bin_size_ = Core::Nan(); + this->histogram_.resize( 0 ); + if ( size == 0 ) return false; + + try + { + unsigned long long int_min = data[ 0 ]; + unsigned long long int_max = data[ 0 ]; + + for ( size_t j = 1 ; j < size ; j++ ) + { + if ( data[ j ] < int_min ) int_min = data[ j ]; + if ( data[ j ] > int_max ) int_max = data[ j ]; + } + + this->min_ = static_cast( int_min ); + this->max_ = static_cast( int_max ); + + if ( this->min_ == this->max_ ) + { + this->bin_size_ = 1.0; + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + this->histogram_.resize( 1, 0 ); + } + else if ( ( this->max_ - this->min_ ) < 256.0 ) + { + size_t hist_size = static_cast( this->max_ - this->min_ ) + 1; + this->histogram_.resize( hist_size, 0 ); + this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_size - 1 ); + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + } + else + { + size_t hist_size = 0x100; + this->histogram_.resize( hist_size, 0 ); + this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_size - 1 ); + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); } double inv_bin_size = 1.0 / this->bin_size_; @@ -521,7 +672,7 @@ bool Histogram::compute( const unsigned int* data, size_t size ) this->histogram_[ idx ]++; } - std::pair< std::vector::iterator, std::vector::iterator > min_max = + std::pair< std::vector::iterator, std::vector::iterator > min_max = boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); this->min_bin_ = (*min_max.first); this->max_bin_ = (*min_max.second); @@ -535,7 +686,7 @@ bool Histogram::compute( const unsigned int* data, size_t size ) this->histogram_.resize( 0 ); return false; } - + return true; } @@ -561,7 +712,7 @@ bool Histogram::compute( const float* data, size_t size ) if ( val < float_min ) float_min = val; if ( val > float_max ) float_max = val; } - + if ( float_min > float_max ) { // Most likely all the data is NaN @@ -570,9 +721,9 @@ bool Histogram::compute( const float* data, size_t size ) this->bin_start_ = Core::Nan(); this->bin_size_ = Core::Nan(); this->histogram_.resize( 0 ); - return false; + return false; } - + this->min_ = static_cast( float_min ); this->max_ = static_cast( float_max ); @@ -587,7 +738,7 @@ bool Histogram::compute( const float* data, size_t size ) size_t hist_size = 0x100; this->histogram_.resize( hist_size, 0 ); this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_size - 1 ); - this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); } float inv_bin_size = static_cast< float >( 1.0f / this->bin_size_ ); @@ -601,7 +752,7 @@ bool Histogram::compute( const float* data, size_t size ) } } - std::pair< std::vector::iterator, std::vector::iterator > min_max = + std::pair< std::vector::iterator, std::vector::iterator > min_max = boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); this->min_bin_ = (*min_max.first); this->max_bin_ = (*min_max.second); @@ -615,7 +766,7 @@ bool Histogram::compute( const float* data, size_t size ) this->histogram_.resize( 0 ); return false; } - + return true; } @@ -641,7 +792,7 @@ bool Histogram::compute( const double* data, size_t size ) if ( val < this->min_ ) this->min_ = val; if ( val > this->max_ ) this->max_ = val; } - + if ( this->min_ > this->max_ ) { // Most likely all the data is NaN @@ -650,9 +801,9 @@ bool Histogram::compute( const double* data, size_t size ) this->bin_start_ = Core::Nan(); this->bin_size_ = Core::Nan(); this->histogram_.resize( 0 ); - return false; + return false; } - + if ( this->min_ == this->max_ ) { this->bin_size_ = 1.0; @@ -664,7 +815,7 @@ bool Histogram::compute( const double* data, size_t size ) size_t hist_size = 0x100; this->histogram_.resize( hist_size, 0 ); this->bin_size_ = ( this->max_ - this->min_ ) / static_cast( hist_size - 1 ); - this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); + this->bin_start_ = this->min_ - ( this->bin_size_ * 0.5 ); } double inv_bin_size = 1.0 / bin_size_; @@ -677,10 +828,10 @@ bool Histogram::compute( const double* data, size_t size ) { size_t idx = static_cast( ( val - this->min_ ) * inv_bin_size ); this->histogram_[ idx ]++; - } + } } - - std::pair< std::vector::iterator, std::vector::iterator > min_max = + + std::pair< std::vector::iterator, std::vector::iterator > min_max = boost::minmax_element( this->histogram_.begin(), this->histogram_.end() ); this->min_bin_ = (*min_max.first); this->max_bin_ = (*min_max.second); @@ -694,18 +845,18 @@ bool Histogram::compute( const double* data, size_t size ) this->histogram_.resize( 0 ); return false; } - - return true; + + return true; } double Histogram::get_min() const -{ +{ return this->min_; } double Histogram::get_max() const -{ - return this->max_; +{ + return this->max_; } double Histogram::get_cum_value( double fraction ) const @@ -731,18 +882,18 @@ double Histogram::get_cum_value( double fraction ) const break; } } - + return this->bin_start_ + ( jj * this->bin_size_ ); } size_t Histogram::get_max_bin() const -{ +{ return this->max_bin_; } size_t Histogram::get_min_bin() const -{ - return this->min_bin_; +{ + return this->min_bin_; } double Histogram::get_bin_size() const diff --git a/src/Core/DataBlock/Histogram.h b/src/Core/DataBlock/Histogram.h index 440b8c0d5..cb869847d 100644 --- a/src/Core/DataBlock/Histogram.h +++ b/src/Core/DataBlock/Histogram.h @@ -25,8 +25,8 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - + + #ifndef CORE_DATABLOCK_HISTOGRAM_H #define CORE_DATABLOCK_HISTOGRAM_H @@ -51,11 +51,13 @@ class Histogram Histogram( const unsigned short* data, size_t size ); Histogram( const int* data, size_t size ); Histogram( const unsigned int* data, size_t size ); + Histogram( const long long* data, size_t size ); + Histogram( const unsigned long long* data, size_t size ); Histogram( const float* data, size_t size ); Histogram( const double* data, size_t size ); virtual ~Histogram(); - + // COMPUTE: /// Compute a histogram on an arbitrary size of data bool compute( const signed char* data, size_t size ); @@ -64,9 +66,11 @@ class Histogram bool compute( const unsigned short* data, size_t size ); bool compute( const int* data, size_t size ); bool compute( const unsigned int* data, size_t size ); + bool compute( const long long* data, size_t size ); + bool compute( const unsigned long long* data, size_t size ); bool compute( const float* data, size_t size ); bool compute( const double* data, size_t size ); - + // GET_MIN: /// Get the minimum value of the data double get_min() const; @@ -74,11 +78,11 @@ class Histogram // GET_MAX: /// Get the maximum value of the data double get_max() const; - + // GET_CUM_VALUE: /// Get the value that has a certain fraction of the data be smaller values double get_cum_value( double fraction ) const; - + // GET_MIN_BIN: /// Get the minimum size of a histogram bar size_t get_min_bin() const; @@ -86,11 +90,11 @@ class Histogram // GET_MAX_BIN: /// Get the maximum size of a histogram bar size_t get_max_bin() const; - + // GET_BIN_SIZE: /// Get the size of each bin in data values double get_bin_size() const; - + // GET_BIN_START: /// Get the value where a specific bin starts double get_bin_start( size_t idx = 0) const; @@ -98,32 +102,32 @@ class Histogram // GET_BIN_END: /// Get the value where a specific bin ends double get_bin_end( size_t idx = 0) const; - + // GET_SIZE: // Get the number of bin in the histogram size_t get_size() const; - + // GET_BINS: /// Get the actual histogram data const std::vector& get_bins() const; - + // IS_VALID: /// Check whther histogram is valid bool is_valid() const; - + private: friend std::string ExportToString( const Histogram& value ); friend bool ImportFromString( const std::string& str, Histogram& value ); - + double min_; double max_; - + size_t min_bin_; size_t max_bin_; double bin_start_; double bin_size_; - + std::vector histogram_; }; @@ -133,7 +137,7 @@ class Histogram std::string ExportToString( const Histogram& value ); // IMPORTFROMSTRING: -/// Import the histogram from a string and return true if the conversion succeeded +/// Import the histogram from a string and return true if the conversion succeeded bool ImportFromString( const std::string& str, Histogram& value ); diff --git a/src/Core/DataBlock/ITKImageData.h b/src/Core/DataBlock/ITKImageData.h index 8137b0f8b..9b6aedb17 100644 --- a/src/Core/DataBlock/ITKImageData.h +++ b/src/Core/DataBlock/ITKImageData.h @@ -232,7 +232,7 @@ ITKImageDataT::ITKImageDataT( typename image_type::Pointer itk_image ) : template ITKImageDataT::ITKImageDataT( DataBlockHandle data_block ) : - itk_image_( 0 ) + itk_image_( nullptr ) { Transform transform; initialize( data_block, transform ); @@ -240,7 +240,7 @@ ITKImageDataT::ITKImageDataT( DataBlockHandle data_block ) : template ITKImageDataT::ITKImageDataT( DataBlockHandle data_block, Transform transform ) : - itk_image_( 0 ) + itk_image_( nullptr ) { initialize( data_block, transform ); } @@ -248,7 +248,7 @@ ITKImageDataT::ITKImageDataT( DataBlockHandle data_block, Transform transform template ITKImageDataT::~ITKImageDataT() { - itk_image_ = 0; + itk_image_ = nullptr; this->data_block_.reset(); } diff --git a/src/Core/DataBlock/MaskDataBlockManager.cc b/src/Core/DataBlock/MaskDataBlockManager.cc index ca17c49af..40ccbdde0 100644 --- a/src/Core/DataBlock/MaskDataBlockManager.cc +++ b/src/Core/DataBlock/MaskDataBlockManager.cc @@ -113,7 +113,7 @@ bool MaskDataBlockManager::create( GridTransform grid_transform, MaskDataBlockHa data_block = mask_list[ j ].data_block_; mask_entry_index = j; - for ( size_t k = 0; k < 8; k++) + for ( size_t k = 0; k < 8; k++) { if ( !( mask_list[j].bits_used_.test( k ) ) ) { @@ -130,9 +130,9 @@ bool MaskDataBlockManager::create( GridTransform grid_transform, MaskDataBlockHa if ( !( data_block.get() ) ) { // Could not find empty position, so create a new data block - data_block = StdDataBlock::New( grid_transform.get_nx(), grid_transform.get_ny(), + data_block = StdDataBlock::New( grid_transform.get_nx(), grid_transform.get_ny(), grid_transform.get_nz(), DataType::UCHAR_E ); - if ( !data_block ) return false; + if ( !data_block ) return false; mask_bit = 0; mask_entry_index = mask_list.size(); mask_list.push_back( MaskDataBlockEntry( data_block, grid_transform ) ); @@ -140,13 +140,13 @@ bool MaskDataBlockManager::create( GridTransform grid_transform, MaskDataBlockHa // Generate the new mask mask = MaskDataBlockHandle( new MaskDataBlock( data_block, mask_bit ) ); - + // Clear the mask before using it - + size_t data_size = grid_transform.get_nx() * grid_transform.get_ny() * grid_transform.get_nz(); unsigned char* data = mask->get_mask_data(); unsigned char not_mask_value = ~( mask->get_mask_value() ); - + size_t data_size8 = RemoveRemainder8( data_size ); size_t i = 0; for ( ; i< data_size8; i+=8 ) @@ -172,7 +172,7 @@ bool MaskDataBlockManager::create( GridTransform grid_transform, MaskDataBlockHa return true; } -bool MaskDataBlockManager::create( DataBlock::generation_type generation, unsigned int bit, +bool MaskDataBlockManager::create( DataBlock::generation_type generation, unsigned int bit, GridTransform& grid_transform, MaskDataBlockHandle& mask ) { lock_type lock( this->get_mutex() ); @@ -230,7 +230,7 @@ bool MaskDataBlockManager::compact() return false; } -void MaskDataBlockManager::register_data_block( DataBlockHandle data_block, +void MaskDataBlockManager::register_data_block( DataBlockHandle data_block, const GridTransform& grid_transform ) { lock_type lock( get_mutex() ); @@ -259,7 +259,7 @@ template< class T > bool ConvertToMaskInternal( DataBlockHandle data, MaskDataBlockHandle& mask, bool invert ) { T* data_ptr = reinterpret_cast( data->get_data() ); - + unsigned char* mask_ptr = mask->get_mask_data(); unsigned char mask_value; unsigned char not_mask_value; @@ -274,7 +274,7 @@ bool ConvertToMaskInternal( DataBlockHandle data, MaskDataBlockHandle& mask, boo mask_value = mask->get_mask_value(); not_mask_value = ~( mask->get_mask_value() ); } - + size_t size = data->get_size(); size_t size8 = size & ~(0x7); for ( size_t j = 0; j < size8; j+= 8 ) @@ -290,13 +290,13 @@ bool ConvertToMaskInternal( DataBlockHandle data, MaskDataBlockHandle& mask, boo } for ( size_t j = size8; j < size; j++ ) { - if ( data_ptr[ j ] ) mask_ptr[ j ] |= mask_value; else mask_ptr[ j ] &= not_mask_value; + if ( data_ptr[ j ] ) mask_ptr[ j ] |= mask_value; else mask_ptr[ j ] &= not_mask_value; } - + return true; } -bool MaskDataBlockManager::Convert( DataBlockHandle data, +bool MaskDataBlockManager::Convert( DataBlockHandle data, GridTransform grid_transform, MaskDataBlockHandle& mask, bool invert ) { if ( !( MaskDataBlockManager::Instance()->create( grid_transform, mask ) ) ) @@ -307,10 +307,10 @@ bool MaskDataBlockManager::Convert( DataBlockHandle data, assert( mask->get_nx() == data->get_nx() ); assert( mask->get_ny() == data->get_ny() ); assert( mask->get_nz() == data->get_nz() ); - + DataBlock::shared_lock_type lock( data->get_mutex( ) ); DataBlock::lock_type mask_lock( mask->get_mutex( ) ); - + switch( data->get_data_type() ) { case DataType::CHAR_E: @@ -325,6 +325,10 @@ bool MaskDataBlockManager::Convert( DataBlockHandle data, return ConvertToMaskInternal( data, mask, invert ); case DataType::UINT_E: return ConvertToMaskInternal( data, mask, invert ); + case DataType::LONGLONG_E: + return ConvertToMaskInternal( data, mask, invert ); + case DataType::ULONGLONG_E: + return ConvertToMaskInternal( data, mask, invert ); case DataType::FLOAT_E: return ConvertToMaskInternal( data, mask, invert ); case DataType::DOUBLE_E: @@ -340,7 +344,7 @@ template< class T > bool ConvertToMaskLargerThanInternal( DataBlockHandle data, MaskDataBlockHandle& mask, bool invert ) { T* data_ptr = reinterpret_cast( data->get_data() ); - + unsigned char* mask_ptr = mask->get_mask_data(); unsigned char mask_value; unsigned char not_mask_value; @@ -355,41 +359,41 @@ bool ConvertToMaskLargerThanInternal( DataBlockHandle data, MaskDataBlockHandle& mask_value = mask->get_mask_value(); not_mask_value = ~( mask->get_mask_value() ); } - + size_t size = data->get_size(); size_t size8 = size & ~(0x7); - + T zero = T( 0 ); - + for ( size_t j = 0; j < size8; j+= 8 ) { - if ( data_ptr[ j ] > zero ) + if ( data_ptr[ j ] > zero ) mask_ptr[ j ] |= mask_value; else mask_ptr[ j ] &= not_mask_value; - if ( data_ptr[ j + 1 ] > zero ) + if ( data_ptr[ j + 1 ] > zero ) mask_ptr[ j + 1 ] |= mask_value; else mask_ptr[ j + 1 ] &= not_mask_value; - if ( data_ptr[ j + 2 ] > zero ) + if ( data_ptr[ j + 2 ] > zero ) mask_ptr[ j + 2 ] |= mask_value; else mask_ptr[ j + 2 ] &= not_mask_value; - if ( data_ptr[ j + 3 ] > zero ) + if ( data_ptr[ j + 3 ] > zero ) mask_ptr[ j + 3 ] |= mask_value; else mask_ptr[ j + 3 ] &= not_mask_value; - if ( data_ptr[ j + 4 ] > zero ) + if ( data_ptr[ j + 4 ] > zero ) mask_ptr[ j + 4 ] |= mask_value; else mask_ptr[ j + 4 ] &= not_mask_value; - if ( data_ptr[ j + 5 ] > zero ) + if ( data_ptr[ j + 5 ] > zero ) mask_ptr[ j + 5 ] |= mask_value; else mask_ptr[ j + 5 ] &= not_mask_value; - if ( data_ptr[ j + 6 ] > zero ) + if ( data_ptr[ j + 6 ] > zero ) mask_ptr[ j + 6 ] |= mask_value; else mask_ptr[ j + 6 ] &= not_mask_value; - if ( data_ptr[ j + 7 ] > zero ) + if ( data_ptr[ j + 7 ] > zero ) mask_ptr[ j + 7 ] |= mask_value; else mask_ptr[ j + 7 ] &= not_mask_value; } for ( size_t j = size8; j < size; j++ ) { if ( data_ptr[ j ] > zero ) - mask_ptr[ j ] |= mask_value; else mask_ptr[ j ] &= not_mask_value; + mask_ptr[ j ] |= mask_value; else mask_ptr[ j ] &= not_mask_value; } - + return true; } -bool MaskDataBlockManager::ConvertLargerThan( DataBlockHandle data, +bool MaskDataBlockManager::ConvertLargerThan( DataBlockHandle data, GridTransform grid_transform, MaskDataBlockHandle& mask, bool invert ) { if ( !( MaskDataBlockManager::Instance()->create( grid_transform, mask ) ) ) @@ -400,10 +404,10 @@ bool MaskDataBlockManager::ConvertLargerThan( DataBlockHandle data, assert( mask->get_nx() == data->get_nx() ); assert( mask->get_ny() == data->get_ny() ); assert( mask->get_nz() == data->get_nz() ); - + DataBlock::shared_lock_type lock( data->get_mutex( ) ); DataBlock::lock_type mask_lock( mask->get_mutex( ) ); - + switch( data->get_data_type() ) { case DataType::CHAR_E: @@ -418,6 +422,10 @@ bool MaskDataBlockManager::ConvertLargerThan( DataBlockHandle data, return ConvertToMaskLargerThanInternal( data, mask, invert ); case DataType::UINT_E: return ConvertToMaskInternal( data, mask, invert ); + case DataType::LONGLONG_E: + return ConvertToMaskLargerThanInternal( data, mask, invert ); + case DataType::ULONGLONG_E: + return ConvertToMaskInternal( data, mask, invert ); case DataType::FLOAT_E: return ConvertToMaskLargerThanInternal( data, mask, invert ); case DataType::DOUBLE_E: @@ -434,42 +442,42 @@ bool ConvertLabelToMaskInternal( DataBlockHandle data, MaskDataBlockHandle& mask { T typed_label = static_cast( label ); T* data_ptr = reinterpret_cast( data->get_data() ); - + unsigned char* mask_ptr = mask->get_mask_data(); unsigned char mask_value = mask->get_mask_value(); unsigned char not_mask_value = ~( mask->get_mask_value() ); - + size_t size = data->get_size(); size_t size8 = size & ~(0x7); for ( size_t j = 0; j < size8; j+= 8 ) { - if ( data_ptr[ j ] == typed_label ) mask_ptr[ j ] |= mask_value; + if ( data_ptr[ j ] == typed_label ) mask_ptr[ j ] |= mask_value; else mask_ptr[ j ] &= not_mask_value; if ( data_ptr[ j + 1 ] == typed_label ) mask_ptr[ j + 1 ] |= mask_value; else mask_ptr[ j + 1 ] &= not_mask_value; - if ( data_ptr[ j + 2 ] == typed_label ) mask_ptr[ j + 2 ] |= mask_value; + if ( data_ptr[ j + 2 ] == typed_label ) mask_ptr[ j + 2 ] |= mask_value; else mask_ptr[ j + 2 ] &= not_mask_value; - if ( data_ptr[ j + 3 ] == typed_label ) mask_ptr[ j + 3 ] |= mask_value; + if ( data_ptr[ j + 3 ] == typed_label ) mask_ptr[ j + 3 ] |= mask_value; else mask_ptr[ j + 3 ] &= not_mask_value; - if ( data_ptr[ j + 4 ] == typed_label ) mask_ptr[ j + 4 ] |= mask_value; + if ( data_ptr[ j + 4 ] == typed_label ) mask_ptr[ j + 4 ] |= mask_value; else mask_ptr[ j + 4 ] &= not_mask_value; - if ( data_ptr[ j + 5 ] == typed_label ) mask_ptr[ j + 5 ] |= mask_value; + if ( data_ptr[ j + 5 ] == typed_label ) mask_ptr[ j + 5 ] |= mask_value; else mask_ptr[ j + 5 ] &= not_mask_value; - if ( data_ptr[ j + 6 ] == typed_label ) mask_ptr[ j + 6 ] |= mask_value; + if ( data_ptr[ j + 6 ] == typed_label ) mask_ptr[ j + 6 ] |= mask_value; else mask_ptr[ j + 6 ] &= not_mask_value; - if ( data_ptr[ j + 7 ] == typed_label ) mask_ptr[ j + 7 ] |= mask_value; + if ( data_ptr[ j + 7 ] == typed_label ) mask_ptr[ j + 7 ] |= mask_value; else mask_ptr[ j + 7 ] &= not_mask_value; } for ( size_t j = size8; j < size; j++ ) { - if ( data_ptr[ j ] == typed_label ) mask_ptr[ j ] |= mask_value; - else mask_ptr[ j ] &= not_mask_value; + if ( data_ptr[ j ] == typed_label ) mask_ptr[ j ] |= mask_value; + else mask_ptr[ j ] &= not_mask_value; } - + return true; } -bool MaskDataBlockManager::ConvertLabel( DataBlockHandle data, +bool MaskDataBlockManager::ConvertLabel( DataBlockHandle data, GridTransform grid_transform, MaskDataBlockHandle& mask, double label ) { if ( !( MaskDataBlockManager::Instance()->create( grid_transform, mask ) ) ) @@ -480,10 +488,10 @@ bool MaskDataBlockManager::ConvertLabel( DataBlockHandle data, assert( mask->get_nx() == data->get_nx() ); assert( mask->get_ny() == data->get_ny() ); assert( mask->get_nz() == data->get_nz() ); - + DataBlock::shared_lock_type lock( data->get_mutex( ) ); DataBlock::lock_type mask_lock( mask->get_mutex( ) ); - + switch( data->get_data_type() ) { case DataType::CHAR_E: @@ -498,6 +506,10 @@ bool MaskDataBlockManager::ConvertLabel( DataBlockHandle data, return ConvertLabelToMaskInternal( data, mask, label ); case DataType::UINT_E: return ConvertLabelToMaskInternal( data, mask, label ); + case DataType::LONGLONG_E: + return ConvertLabelToMaskInternal( data, mask, label ); + case DataType::ULONGLONG_E: + return ConvertLabelToMaskInternal( data, mask, label ); case DataType::FLOAT_E: return ConvertLabelToMaskInternal( data, mask, label ); case DataType::DOUBLE_E: @@ -516,11 +528,11 @@ bool ConvertLabelToDataInternal( MaskDataBlockHandle mask, DataBlockHandle& data unsigned char* mask_ptr = mask->get_mask_data(); unsigned char mask_value = mask->get_mask_value(); - - data = StdDataBlock::New( mask->get_nx(), mask->get_ny(), mask->get_nz(), + + data = StdDataBlock::New( mask->get_nx(), mask->get_ny(), mask->get_nz(), GetDataType( reinterpret_cast< T* >( 0 ) ) ); T* data_ptr = reinterpret_cast< T* >( data->get_data() ); - + const T on = static_cast( label ); const T off = static_cast( 0 ); size_t size = data->get_size(); @@ -562,11 +574,15 @@ bool MaskDataBlockManager::ConvertLabel( MaskDataBlockHandle mask, DataBlockHand return ConvertLabelToDataInternal( mask, data, label ); case DataType::UINT_E: return ConvertLabelToDataInternal( mask, data, label ); + case DataType::LONGLONG_E: + return ConvertLabelToDataInternal( mask, data, label ); + case DataType::ULONGLONG_E: + return ConvertLabelToDataInternal( mask, data, label ); case DataType::FLOAT_E: return ConvertLabelToDataInternal( mask, data, label ); case DataType::DOUBLE_E: return ConvertLabelToDataInternal( mask, data, label ); - } + } return false; } @@ -577,11 +593,11 @@ bool ConvertToDataInternal( MaskDataBlockHandle mask, DataBlockHandle& data, boo unsigned char* mask_ptr = mask->get_mask_data(); unsigned char mask_value = mask->get_mask_value(); - - data = StdDataBlock::New( mask->get_nx(), mask->get_ny(), mask->get_nz(), + + data = StdDataBlock::New( mask->get_nx(), mask->get_ny(), mask->get_nz(), GetDataType( reinterpret_cast< T* >( 0 ) ) ); T* data_ptr = reinterpret_cast< T* >( data->get_data() ); - + const T on = static_cast( invert?0:1 ); const T off = static_cast( invert?1:0 ); size_t size = data->get_size(); @@ -623,15 +639,19 @@ bool MaskDataBlockManager::Convert( MaskDataBlockHandle mask, DataBlockHandle& d return ConvertToDataInternal( mask, data, invert ); case DataType::UINT_E: return ConvertToDataInternal( mask, data, invert ); + case DataType::LONGLONG_E: + return ConvertToDataInternal( mask, data, invert ); + case DataType::ULONGLONG_E: + return ConvertToDataInternal( mask, data, invert ); case DataType::FLOAT_E: return ConvertToDataInternal( mask, data, invert ); case DataType::DOUBLE_E: return ConvertToDataInternal( mask, data, invert ); - } + } return false; } -bool MaskDataBlockManager::Duplicate( MaskDataBlockHandle src_mask_data_block, +bool MaskDataBlockManager::Duplicate( MaskDataBlockHandle src_mask_data_block, const GridTransform& grid_transform, MaskDataBlockHandle& dst_mask_data_block ) { // Step (1): Create a new mask @@ -645,7 +665,7 @@ bool MaskDataBlockManager::Duplicate( MaskDataBlockHandle src_mask_data_block, // Step (2): Need to lock the source data MaskDataBlock::lock_type lock( dst_mask_data_block->get_mutex( ) ); MaskDataBlock::shared_lock_type slock; - + // NOTE: Need to check if we not already locked this one. If the underlying datablocks are // the same we do not need a read lock. In fact putting one would result in a deadlock if ( src_mask_data_block->get_data_block( ) != dst_mask_data_block->get_data_block( ) ) @@ -657,44 +677,44 @@ bool MaskDataBlockManager::Duplicate( MaskDataBlockHandle src_mask_data_block, // Step (3): Get the mask data pointer and which bit is used unsigned char* src_mask_ptr = src_mask_data_block->get_mask_data(); unsigned char src_mask_value = src_mask_data_block->get_mask_value(); - - + + // Step (4): Security check if ( src_mask_data_block->get_size() != dst_mask_data_block->get_size() ) { return false; } - + // Step (2): Get the mask data pointer and which bit is used unsigned char* dst_mask_ptr = dst_mask_data_block->get_mask_data(); - unsigned char dst_mask_value = dst_mask_data_block->get_mask_value(); - unsigned char dst_not_mask_value = ~( dst_mask_data_block->get_mask_value() ); - + unsigned char dst_mask_value = dst_mask_data_block->get_mask_value(); + unsigned char dst_not_mask_value = ~( dst_mask_data_block->get_mask_value() ); + size_t size = dst_mask_data_block->get_size(); size_t size8 = RemoveRemainder8( size ); for ( size_t j = 0; j < size8; j+= 8 ) { - if ( src_mask_ptr[ j ] & src_mask_value ) + if ( src_mask_ptr[ j ] & src_mask_value ) dst_mask_ptr[ j ] |= dst_mask_value; else dst_mask_ptr[ j ] &= dst_not_mask_value; - if ( src_mask_ptr[ j + 1 ] & src_mask_value ) + if ( src_mask_ptr[ j + 1 ] & src_mask_value ) dst_mask_ptr[ j + 1 ] |= dst_mask_value; else dst_mask_ptr[ j + 1 ] &= dst_not_mask_value; - if ( src_mask_ptr[ j + 2 ] & src_mask_value ) + if ( src_mask_ptr[ j + 2 ] & src_mask_value ) dst_mask_ptr[ j + 2 ] |= dst_mask_value; else dst_mask_ptr[ j + 2 ] &= dst_not_mask_value; - if ( src_mask_ptr[ j + 3 ] & src_mask_value ) + if ( src_mask_ptr[ j + 3 ] & src_mask_value ) dst_mask_ptr[ j + 3 ] |= dst_mask_value; else dst_mask_ptr[ j + 3 ] &= dst_not_mask_value; if ( src_mask_ptr[ j + 4 ] & src_mask_value ) - dst_mask_ptr[ j + 4 ] |= dst_mask_value; else dst_mask_ptr[ j + 4 ] &= dst_not_mask_value; + dst_mask_ptr[ j + 4 ] |= dst_mask_value; else dst_mask_ptr[ j + 4 ] &= dst_not_mask_value; if ( src_mask_ptr[ j + 5 ] & src_mask_value ) - dst_mask_ptr[ j + 5 ] |= dst_mask_value; else dst_mask_ptr[ j + 5 ] &= dst_not_mask_value; + dst_mask_ptr[ j + 5 ] |= dst_mask_value; else dst_mask_ptr[ j + 5 ] &= dst_not_mask_value; if ( src_mask_ptr[ j + 6 ] & src_mask_value ) - dst_mask_ptr[ j + 6 ] |= dst_mask_value; else dst_mask_ptr[ j + 6 ] &= dst_not_mask_value; + dst_mask_ptr[ j + 6 ] |= dst_mask_value; else dst_mask_ptr[ j + 6 ] &= dst_not_mask_value; if ( src_mask_ptr[ j + 7 ] & src_mask_value ) - dst_mask_ptr[ j + 7 ] |= dst_mask_value; else dst_mask_ptr[ j + 7 ] &= dst_not_mask_value; + dst_mask_ptr[ j + 7 ] |= dst_mask_value; else dst_mask_ptr[ j + 7 ] &= dst_not_mask_value; } for ( size_t j = size8; j < size; j++ ) { - if ( src_mask_ptr[ j ] & src_mask_value ) + if ( src_mask_ptr[ j ] & src_mask_value ) dst_mask_ptr[ j ] |= dst_mask_value; else dst_mask_ptr[ j ] &= dst_not_mask_value; } @@ -703,10 +723,10 @@ bool MaskDataBlockManager::Duplicate( MaskDataBlockHandle src_mask_data_block, template< class DATA > -static bool CreateMaskFromNonZeroDataInternal( const DataBlockHandle& data, +static bool CreateMaskFromNonZeroDataInternal( const DataBlockHandle& data, const MaskDataBlockHandle& mask ) { - DATA* src = reinterpret_cast( data->get_data() ); + DATA* src = reinterpret_cast( data->get_data() ); size_t size = mask->get_size(); unsigned char* mask_data = mask->get_mask_data(); @@ -722,8 +742,8 @@ static bool CreateMaskFromNonZeroDataInternal( const DataBlockHandle& data, return true; } -bool MaskDataBlockManager::CreateMaskFromNonZeroData( const DataBlockHandle& data, - const GridTransform& grid_transform, +bool MaskDataBlockManager::CreateMaskFromNonZeroData( const DataBlockHandle& data, + const GridTransform& grid_transform, MaskDataBlockHandle& mask ) { // Ensure there is no valid pointer left in the handle @@ -760,6 +780,10 @@ bool MaskDataBlockManager::CreateMaskFromNonZeroData( const DataBlockHandle& dat return CreateMaskFromNonZeroDataInternal( data, mask ); case DataType::UINT_E: return CreateMaskFromNonZeroDataInternal( data, mask ); + case DataType::LONGLONG_E: + return CreateMaskFromNonZeroDataInternal( data, mask ); + case DataType::ULONGLONG_E: + return CreateMaskFromNonZeroDataInternal( data, mask ); case DataType::FLOAT_E: return CreateMaskFromNonZeroDataInternal( data, mask ); case DataType::DOUBLE_E: @@ -770,13 +794,13 @@ bool MaskDataBlockManager::CreateMaskFromNonZeroData( const DataBlockHandle& dat } template< class DATA > -static bool CreateMaskFromBitPlaneDataInternal( const DataBlockHandle& data, - const GridTransform& grid_transform, +static bool CreateMaskFromBitPlaneDataInternal( const DataBlockHandle& data, + const GridTransform& grid_transform, std::vector& masks ) { masks.clear(); - DATA* src = reinterpret_cast( data->get_data() ); + DATA* src = reinterpret_cast( data->get_data() ); size_t size = data->get_size(); DATA used_bits(0); @@ -820,8 +844,8 @@ static bool CreateMaskFromBitPlaneDataInternal( const DataBlockHandle& data, return true; } -bool MaskDataBlockManager::CreateMaskFromBitPlaneData( const DataBlockHandle& data, - const GridTransform& grid_transform, +bool MaskDataBlockManager::CreateMaskFromBitPlaneData( const DataBlockHandle& data, + const GridTransform& grid_transform, std::vector& masks ) { // Ensure there is no valid pointer left in the handle @@ -847,19 +871,23 @@ bool MaskDataBlockManager::CreateMaskFromBitPlaneData( const DataBlockHandle& da return CreateMaskFromBitPlaneDataInternal( data, grid_transform, masks ); case DataType::UINT_E: return CreateMaskFromBitPlaneDataInternal( data, grid_transform, masks ); + case DataType::LONGLONG_E: + return CreateMaskFromBitPlaneDataInternal( data, grid_transform, masks ); + case DataType::ULONGLONG_E: + return CreateMaskFromBitPlaneDataInternal( data, grid_transform, masks ); default: return false; } } template< class DATA > -static bool CreateMaskFromLabelDataInternal( const DataBlockHandle& data, +static bool CreateMaskFromLabelDataInternal( const DataBlockHandle& data, const GridTransform& grid_transform, std::vector& masks ) { masks.clear(); - DATA* src = reinterpret_cast( data->get_data() ); + DATA* src = reinterpret_cast( data->get_data() ); size_t size = data->get_size(); DATA label( 0 ); DATA zero_label( 0 ); @@ -872,7 +900,7 @@ static bool CreateMaskFromLabelDataInternal( const DataBlockHandle& data, { if ( src[ next_label_index ] != zero_label ) break; next_label_index++; - } + } if ( next_label_index < size ) { @@ -894,7 +922,7 @@ static bool CreateMaskFromLabelDataInternal( const DataBlockHandle& data, for ( size_t j = next_label_index; j < size; j++ ) { - if ( src[ j ] == label ) + if ( src[ j ] == label ) { src[ j ] = zero_label; mask_data[ j ] |= mask_value; @@ -905,15 +933,15 @@ static bool CreateMaskFromLabelDataInternal( const DataBlockHandle& data, } } - masks.push_back( mask ); + masks.push_back( mask ); } } return true; } -bool MaskDataBlockManager::CreateMaskFromLabelData( const DataBlockHandle& data, - const GridTransform& grid_transform, +bool MaskDataBlockManager::CreateMaskFromLabelData( const DataBlockHandle& data, + const GridTransform& grid_transform, std::vector& masks ) { // Ensure there is no valid pointer left in the handle @@ -939,6 +967,10 @@ bool MaskDataBlockManager::CreateMaskFromLabelData( const DataBlockHandle& data, return CreateMaskFromLabelDataInternal( data, grid_transform, masks ); case DataType::UINT_E: return CreateMaskFromLabelDataInternal( data, grid_transform, masks ); + case DataType::LONGLONG_E: + return CreateMaskFromLabelDataInternal( data, grid_transform, masks ); + case DataType::ULONGLONG_E: + return CreateMaskFromLabelDataInternal( data, grid_transform, masks ); case DataType::FLOAT_E: return CreateMaskFromLabelDataInternal( data, grid_transform, masks ); case DataType::DOUBLE_E: @@ -955,9 +987,9 @@ bool InscribeInternal( MaskDataBlockHandle mask, DataBlockHandle data, double la unsigned char* mask_ptr = mask->get_mask_data(); unsigned char mask_value = mask->get_mask_value(); - + T* data_ptr = reinterpret_cast< T* >( data->get_data() ); - + const T label_value = static_cast( label ); size_t size = data->get_size(); size_t size8 = size & ~(0x7); @@ -978,7 +1010,7 @@ bool InscribeInternal( MaskDataBlockHandle mask, DataBlockHandle data, double la for ( size_t j = size8; j < size; j++ ) { if ( !( mask_ptr[ j ] & mask_value ) ) data_ptr[ j ] = label_value; - } + } } else { @@ -998,11 +1030,11 @@ bool InscribeInternal( MaskDataBlockHandle mask, DataBlockHandle data, double la if ( mask_ptr[ j ] & mask_value ) data_ptr[ j ] = label_value; } } - + return true; } -bool MaskDataBlockManager::Inscribe( MaskDataBlockHandle mask, DataBlockHandle data, double label, +bool MaskDataBlockManager::Inscribe( MaskDataBlockHandle mask, DataBlockHandle data, double label, bool invert ) { // Check if there is any data @@ -1032,6 +1064,10 @@ bool MaskDataBlockManager::Inscribe( MaskDataBlockHandle mask, DataBlockHandle d return InscribeInternal( mask, data, label, invert ); case DataType::UINT_E: return InscribeInternal( mask, data, label, invert ); + case DataType::LONGLONG_E: + return InscribeInternal( mask, data, label, invert ); + case DataType::ULONGLONG_E: + return InscribeInternal( mask, data, label, invert ); case DataType::FLOAT_E: return InscribeInternal( mask, data, label, invert ); case DataType::DOUBLE_E: diff --git a/src/Core/DataBlock/NrrdData.cc b/src/Core/DataBlock/NrrdData.cc index 32f2f8095..8e469620b 100644 --- a/src/Core/DataBlock/NrrdData.cc +++ b/src/Core/DataBlock/NrrdData.cc @@ -432,6 +432,12 @@ Histogram NrrdData::get_histogram( bool trust_meta_data ) case Core::DataType::UINT_E: result.compute( reinterpret_cast( this->get_data() ), this->get_size() ); break; + case Core::DataType::LONGLONG_E: + result.compute( reinterpret_cast( this->get_data() ), this->get_size() ); + break; + case Core::DataType::ULONGLONG_E: + result.compute( reinterpret_cast( this->get_data() ), this->get_size() ); + break; case Core::DataType::FLOAT_E: result.compute( reinterpret_cast( this->get_data() ), this->get_size() ); break; diff --git a/src/Core/DataBlock/StdDataBlock.cc b/src/Core/DataBlock/StdDataBlock.cc index 79985c7f6..f6c08e514 100644 --- a/src/Core/DataBlock/StdDataBlock.cc +++ b/src/Core/DataBlock/StdDataBlock.cc @@ -53,19 +53,25 @@ StdDataBlock::StdDataBlock( size_t nx, size_t ny, size_t nz, DataType dtype ) set_data( reinterpret_cast< void* > ( new char[ get_size() ] ) ); break; case DataType::UCHAR_E: - set_data( reinterpret_cast( new unsigned char[ get_size() ] ) ); + set_data( reinterpret_cast( new unsigned char[ get_size() ] ) ); break; case DataType::SHORT_E: set_data( reinterpret_cast< void* > ( new short[ get_size() ] ) ); break; case DataType::USHORT_E: - set_data(reinterpret_cast( new unsigned short[ get_size() ] ) ); + set_data(reinterpret_cast( new unsigned short[ get_size() ] ) ); break; case DataType::INT_E: set_data( reinterpret_cast< void* > ( new int[ get_size() ] ) ); break; case DataType::UINT_E: - set_data( reinterpret_cast( new unsigned int[ get_size() ] ) ); + set_data( reinterpret_cast( new unsigned int[ get_size() ] ) ); + break; + case DataType::LONGLONG_E: + set_data( reinterpret_cast< void* > ( new long long[ get_size() ] ) ); + break; + case DataType::ULONGLONG_E: + set_data(reinterpret_cast( new unsigned long long[ get_size() ] ) ); break; case DataType::FLOAT_E: set_data( reinterpret_cast< void* > ( new float[ get_size() ] ) ); @@ -88,19 +94,25 @@ StdDataBlock::~StdDataBlock() delete[] reinterpret_cast< char* > ( get_data() ); break; case DataType::UCHAR_E: - delete[] reinterpret_cast( get_data() ); + delete[] reinterpret_cast( get_data() ); break; case DataType::SHORT_E: delete[] reinterpret_cast< short* > ( get_data() ); break; case DataType::USHORT_E: - delete[] reinterpret_cast( get_data() ); + delete[] reinterpret_cast( get_data() ); break; case DataType::INT_E: delete[] reinterpret_cast< int* > ( get_data() ); break; case DataType::UINT_E: - delete[] reinterpret_cast( get_data() ); + delete[] reinterpret_cast( get_data() ); + break; + case DataType::LONGLONG_E: + delete[] reinterpret_cast< long long* > ( get_data() ); + break; + case DataType::ULONGLONG_E: + delete[] reinterpret_cast( get_data() ); break; case DataType::FLOAT_E: delete[] reinterpret_cast< float* > ( get_data() ); @@ -131,7 +143,7 @@ DataBlockHandle StdDataBlock::New( GridTransform transform, DataType type ) { try { - DataBlockHandle data_block( new StdDataBlock( transform.get_nx(), + DataBlockHandle data_block( new StdDataBlock( transform.get_nx(), transform.get_ny(), transform.get_nz(), type ) ); return data_block; } diff --git a/src/Core/Graphics/FramebufferObject.cc b/src/Core/Graphics/FramebufferObject.cc index e31adc90c..1805b5cf6 100644 --- a/src/Core/Graphics/FramebufferObject.cc +++ b/src/Core/Graphics/FramebufferObject.cc @@ -119,7 +119,7 @@ bool FramebufferObject::check_status( GLenum* status ) this->safe_bind(); GLenum result = glCheckFramebufferStatusEXT( TARGET_C ); this->safe_unbind(); - if ( status != NULL ) + if ( status != nullptr ) { *status = result; } diff --git a/src/Core/Graphics/FramebufferObject.h b/src/Core/Graphics/FramebufferObject.h index 91f1fc27a..fa4522148 100644 --- a/src/Core/Graphics/FramebufferObject.h +++ b/src/Core/Graphics/FramebufferObject.h @@ -61,7 +61,7 @@ class FramebufferObject : public boost::noncopyable void detach_texture( TextureHandle texture, unsigned int attachment = GL_COLOR_ATTACHMENT0_EXT ); void attach_renderbuffer( RenderbufferHandle renderbuffer, unsigned int attachment ); void detach_renderbuffer( RenderbufferHandle renderbuffer, unsigned int attachment ); - bool check_status( GLenum* status = NULL ); + bool check_status( GLenum* status = nullptr ); private: unsigned int id_; diff --git a/src/Core/Graphics/GLSLShader.cc b/src/Core/Graphics/GLSLShader.cc index 534104887..e9b273ff4 100644 --- a/src/Core/Graphics/GLSLShader.cc +++ b/src/Core/Graphics/GLSLShader.cc @@ -75,7 +75,7 @@ bool GLSLShader::set_source_file( const std::string& file_name ) source_file.close(); const char* str = source_str.c_str(); - glShaderSource( this->shader_id_, 1, &str, NULL ); + glShaderSource( this->shader_id_, 1, &str, nullptr ); return true; } @@ -93,7 +93,7 @@ void GLSLShader::set_source( const std::string& source ) source_str += source; const char* shader_str = source_str.c_str(); - glShaderSource( this->shader_id_, 1, &shader_str, NULL ); + glShaderSource( this->shader_id_, 1, &shader_str, nullptr ); } bool GLSLShader::compile() diff --git a/src/Core/ITKCommon/FFT/fft.cxx b/src/Core/ITKCommon/FFT/fft.cxx index a0d36ce31..0458c2157 100644 --- a/src/Core/ITKCommon/FFT/fft.cxx +++ b/src/Core/ITKCommon/FFT/fft.cxx @@ -96,13 +96,13 @@ namespace itk_fft { public: fft_cache_t(): - fwd_(NULL), - inv_(NULL), + fwd_(nullptr), + inv_(nullptr), w_(0), h_(0), h_complex_(0), h_padded_(0), - buffer_(NULL) + buffer_(nullptr) {} ~fft_cache_t() @@ -118,13 +118,13 @@ namespace itk_fft the_lock_t lock(fftw_mutex()); fftwf_destroy_plan(fwd_); - fwd_ = NULL; + fwd_ = nullptr; fftwf_destroy_plan(inv_); - inv_ = NULL; + inv_ = nullptr; fftwf_free(buffer_); - buffer_ = NULL; + buffer_ = nullptr; } w_ = 0; @@ -193,7 +193,7 @@ namespace itk_fft // fft_data_t::fft_data_t // fft_data_t::fft_data_t(const itk_image_t::Pointer & real): - data_(NULL), + data_(nullptr), nx_(0), ny_(0) { @@ -204,7 +204,7 @@ namespace itk_fft // fft_data_t::fft_data_t // fft_data_t::fft_data_t(const unsigned int w, const unsigned int h): - data_(NULL), + data_(nullptr), nx_(0), ny_(0) { @@ -216,7 +216,7 @@ namespace itk_fft // fft_data_t::fft_data_t(const itk_image_t::Pointer & real, const itk_image_t::Pointer & imag): - data_(NULL), + data_(nullptr), nx_(0), ny_(0) { @@ -227,7 +227,7 @@ namespace itk_fft // fft_data_t::fft_data_t // fft_data_t::fft_data_t(const fft_data_t & data): - data_(NULL), + data_(nullptr), nx_(0), ny_(0) { @@ -242,7 +242,7 @@ namespace itk_fft { // assert(this != &data); - if (data.data_ != NULL) + if (data.data_ != nullptr) { resize(data.nx_, data.ny_); data_ = (fft_complex_t *)(memcpy(data_, @@ -263,8 +263,8 @@ namespace itk_fft void fft_data_t::cleanup() { - if (data_ != NULL) fftwf_free((fft_complex_t *)(data_)); - data_ = NULL; + if (data_ != nullptr) fftwf_free((fft_complex_t *)(data_)); + data_ = nullptr; nx_ = 0; ny_ = 0; } @@ -279,10 +279,10 @@ namespace itk_fft const unsigned int old_sz = nx_ * ny_; if (old_sz == new_sz) return; - if (data_ != NULL) fftwf_free((fft_complex_t *)(data_)); + if (data_ != nullptr) fftwf_free((fft_complex_t *)(data_)); data_ = static_cast( fftwf_malloc(new_sz * sizeof(fft_complex_t)) ); -// assert(data_ != NULL); - if (data_ == NULL) +// assert(data_ != nullptr); + if (data_ == nullptr) { CORE_THROW_EXCEPTION("fftwf_malloc failed"); } @@ -341,7 +341,7 @@ namespace itk_fft } // iterate over the imaginary component image: - if (imag.GetPointer() == NULL) return; + if (imag.GetPointer() == nullptr) return; itex = itex_t(imag, real->GetLargestPossibleRegion()); for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { diff --git a/src/Core/ITKCommon/FFT/fft.hxx b/src/Core/ITKCommon/FFT/fft.hxx index 6c13d6f72..837b3991f 100644 --- a/src/Core/ITKCommon/FFT/fft.hxx +++ b/src/Core/ITKCommon/FFT/fft.hxx @@ -78,7 +78,7 @@ namespace itk_fft class fft_data_t { public: - fft_data_t(): data_(NULL), nx_(0), ny_(0) {} + fft_data_t(): data_(nullptr), nx_(0), ny_(0) {} fft_data_t(const unsigned int w, const unsigned int h); explicit fft_data_t(const itk_imageptr_t & real); fft_data_t(const itk_imageptr_t & real, @@ -95,7 +95,7 @@ namespace itk_fft void fill(const float real, const float imag = 0.0); void setup(const itk_imageptr_t & real, - const itk_imageptr_t & imag = itk_imageptr_t(NULL)); + const itk_imageptr_t & imag = itk_imageptr_t(nullptr)); // ITK helpers: itk_imageptr_t component(const bool imag = 0) const; diff --git a/src/Core/ITKCommon/FFT/fft_common.hxx b/src/Core/ITKCommon/FFT/fft_common.hxx index db2d91c0d..441571784 100644 --- a/src/Core/ITKCommon/FFT/fft_common.hxx +++ b/src/Core/ITKCommon/FFT/fft_common.hxx @@ -296,8 +296,8 @@ estimate_displacement(const TImage * a, image_t::PointType offset_max, const double overlap_min = 0.0, const double overlap_max = 1.0, - const mask_t * mask_a = NULL, - const mask_t * mask_b = NULL) + const mask_t * mask_a = nullptr, + const mask_t * mask_b = nullptr) { // FIXME: //#ifdef DEBUG_PDF @@ -431,7 +431,7 @@ match_one_pair(const bool images_were_resampled, // DEBUG_COUNTER1++; //#endif - ti = NULL; + ti = nullptr; unsigned int total_peaks = 0; if (use_std_mask) diff --git a/src/Core/ITKCommon/Filtering/itkNormalizeImageFilterWithMask.txx b/src/Core/ITKCommon/Filtering/itkNormalizeImageFilterWithMask.txx index 590c71c3c..539c9187c 100644 --- a/src/Core/ITKCommon/Filtering/itkNormalizeImageFilterWithMask.txx +++ b/src/Core/ITKCommon/Filtering/itkNormalizeImageFilterWithMask.txx @@ -93,7 +93,7 @@ NormalizeImageFilterWithMask // Set the parameters for Shift m_ShiftScaleFilter->SetShift(-m_StatisticsFilter->GetMean()); - m_ShiftScaleFilter->SetScale(NumericTraits::RealType>::One + m_ShiftScaleFilter->SetScale(NumericTraits::RealType>::One / m_StatisticsFilter->GetSigma()); m_ShiftScaleFilter->SetInput(this->GetInput()); diff --git a/src/Core/ITKCommon/IRImageLoader.cxx b/src/Core/ITKCommon/IRImageLoader.cxx index cbd0cdb7f..6a22f96ce 100644 --- a/src/Core/ITKCommon/IRImageLoader.cxx +++ b/src/Core/ITKCommon/IRImageLoader.cxx @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -32,6 +32,9 @@ // Copyright : (C) 2008 University of Utah // Description : +// C++ +#include + // ITK includes: #include @@ -49,33 +52,33 @@ namespace bfs=boost::filesystem; //---------------------------------------------------------------- // __sharedIRImageLoader -// -static IRImageLoader * __sharedIRImageLoader = NULL; +// +static IRImageLoader * __sharedIRImageLoader = nullptr; //---------------------------------------------------------------- // __IRImageLoaderSharedImageLoaderLock -// -static itk::SimpleMutexLock __IRImageLoaderSharedImageLoaderLock; +// +static std::mutex __IRImageLoaderSharedImageLoaderLock; //---------------------------------------------------------------- // IRImageLoader::sharedImageLoader -// +// IRImageLoader * IRImageLoader::sharedImageLoader() { - __IRImageLoaderSharedImageLoaderLock.Lock(); - if (__sharedIRImageLoader == NULL) + __IRImageLoaderSharedImageLoaderLock.lock(); + if (__sharedIRImageLoader == nullptr) { __sharedIRImageLoader = new IRImageLoader(); } - - __IRImageLoaderSharedImageLoaderLock.Unlock(); + + __IRImageLoaderSharedImageLoaderLock.unlock(); return __sharedIRImageLoader; } //---------------------------------------------------------------- // IRImageLoader::IRImageLoader -// +// IRImageLoader::IRImageLoader() : SHRINK_FACTOR(1), PIXEL_SPACING(1.0), @@ -85,25 +88,25 @@ IRImageLoader::IRImageLoader() : //---------------------------------------------------------------- // IRImageLoader::~IRImageLoader -// +// IRImageLoader::~IRImageLoader() {} //---------------------------------------------------------------- // __IRImageLoaderImageAcessLock -// -static itk::SimpleMutexLock __IRImageLoaderImageAcessLock; -static itk::SimpleMutexLock __IRImageLoaderMaskAcessLock; +// +static std::mutex __IRImageLoaderImageAcessLock; +static std::mutex __IRImageLoaderMaskAcessLock; //---------------------------------------------------------------- // IRImageLoader::setTransformList -// +// void IRImageLoader::setTransformList(const IRTransformVector & transforms, const TheTextVector & imageIDs) { - __IRImageLoaderImageAcessLock.Lock(); - + __IRImageLoaderImageAcessLock.lock(); + IRTransformVector::const_iterator transformIter = transforms.begin(); TheTextVector::const_iterator imageIDIter = imageIDs.begin(); for (; transformIter != transforms.end(); transformIter++, imageIDIter++) @@ -111,13 +114,13 @@ IRImageLoader::setTransformList(const IRTransformVector & transforms, _transformations[*imageIDIter] = *transformIter; } _images = imageMap(); - - __IRImageLoaderImageAcessLock.Unlock(); + + __IRImageLoaderImageAcessLock.unlock(); } //---------------------------------------------------------------- // IRImageLoader::setShrinkFactor -// +// void IRImageLoader::setShrinkFactor(unsigned int shrinkFactor) { @@ -126,7 +129,7 @@ IRImageLoader::setShrinkFactor(unsigned int shrinkFactor) //---------------------------------------------------------------- // IRImageLoader::shrinkFactor -// +// unsigned int IRImageLoader::shrinkFactor() { @@ -135,7 +138,7 @@ IRImageLoader::shrinkFactor() //---------------------------------------------------------------- // IRImageLoader::setPixelSpacing -// +// void IRImageLoader::setPixelSpacing(double pixelSpacing) { @@ -144,7 +147,7 @@ IRImageLoader::setPixelSpacing(double pixelSpacing) //---------------------------------------------------------------- // IRImageLoader::pixelSpacing -// +// double IRImageLoader::pixelSpacing() { @@ -153,7 +156,7 @@ IRImageLoader::pixelSpacing() //---------------------------------------------------------------- // IRImageLoader::getImageSize -// +// vec2d_t IRImageLoader::getImageSize(const std::string& imageID, base_transform_t::Pointer transform) @@ -164,7 +167,7 @@ IRImageLoader::getImageSize(const std::string& imageID, dynamic_cast *> (transform.GetPointer()); const double SCALE = 2.0; - + if (legendrePointer.IsNotNull()) { imageSize[0] = legendrePointer->GetFixedParameters()[2] * SCALE; @@ -174,7 +177,7 @@ IRImageLoader::getImageSize(const std::string& imageID, { // since this version does not rescale the image it is much faster image_t::Pointer image = getFullResImage(imageID); - + // first find the size of the tile pnt2d_t bbox_min; pnt2d_t bbox_max; @@ -182,15 +185,15 @@ IRImageLoader::getImageSize(const std::string& imageID, imageSize = bbox_max - bbox_min; imageSize *= _pixelSpacing; } - + return imageSize; } //---------------------------------------------------------------- // IRImageLoader::getFullResImage -// +// // this does not cache the image -// +// image_t::Pointer IRImageLoader::getFullResImage(const std::string& imageID) { @@ -208,77 +211,77 @@ IRImageLoader::getFullResImage(const std::string& imageID) //---------------------------------------------------------------- // IRImageLoader::getImage -// +// image_t::Pointer IRImageLoader::getImage(const std::string& imageID) { imageCheckLoad(imageID); - - __IRImageLoaderImageAcessLock.Lock(); + + __IRImageLoaderImageAcessLock.lock(); image_t::Pointer image = _images[imageID]; - __IRImageLoaderImageAcessLock.Unlock(); - + __IRImageLoaderImageAcessLock.unlock(); + return image; } //---------------------------------------------------------------- // IRImageLoader::getMask -// +// mask_t::Pointer IRImageLoader::getMask(const std::string& maskID) { maskCheckLoad(maskID); - - __IRImageLoaderImageAcessLock.Lock(); + + __IRImageLoaderImageAcessLock.lock(); mask_t::Pointer mask = _masks[maskID]; - __IRImageLoaderImageAcessLock.Unlock(); - + __IRImageLoaderImageAcessLock.unlock(); + return mask; } //---------------------------------------------------------------- // IRImageLoader::imageCheckLoad -// +// void IRImageLoader::imageCheckLoad(const std::string& imageID) { - __IRImageLoaderImageAcessLock.Lock(); - + __IRImageLoaderImageAcessLock.lock(); + if (_images.find(imageID) != _images.end()) { while (_images[imageID].IsNull()) { // if another thread is already loading this same image, // spin until it is loaded - __IRImageLoaderImageAcessLock.Unlock(); + __IRImageLoaderImageAcessLock.unlock(); sleep_msec(1000); - __IRImageLoaderImageAcessLock.Lock(); + __IRImageLoaderImageAcessLock.lock(); } - - __IRImageLoaderImageAcessLock.Unlock(); + + __IRImageLoaderImageAcessLock.unlock(); return; } - - _images[imageID] = NULL; - __IRImageLoaderImageAcessLock.Unlock(); - + + _images[imageID] = nullptr; + __IRImageLoaderImageAcessLock.unlock(); + image_t::Pointer image = std_tile(imageID.c_str(), _shrinkFactor, _pixelSpacing); - - __IRImageLoaderImageAcessLock.Lock(); + + __IRImageLoaderImageAcessLock.lock(); _images[imageID] = image; - __IRImageLoaderImageAcessLock.Unlock(); + __IRImageLoaderImageAcessLock.unlock(); } //---------------------------------------------------------------- // IRImageLoader::maskCheckLoad -// +// void IRImageLoader::maskCheckLoad(const std::string& maskID) { - __IRImageLoaderMaskAcessLock.Lock(); - + __IRImageLoaderMaskAcessLock.lock(); + if (_masks.find(maskID) != _masks.end()) { if ( !maskID.empty() ) @@ -287,24 +290,24 @@ IRImageLoader::maskCheckLoad(const std::string& maskID) { // if another thread is already loading this same image, // spin until it is loaded - __IRImageLoaderMaskAcessLock.Unlock(); + __IRImageLoaderMaskAcessLock.unlock(); sleep_msec(1000); - __IRImageLoaderMaskAcessLock.Lock(); + __IRImageLoaderMaskAcessLock.lock(); } } - - __IRImageLoaderMaskAcessLock.Unlock(); + + __IRImageLoaderMaskAcessLock.unlock(); return; } - - _masks[maskID] = NULL; - __IRImageLoaderMaskAcessLock.Unlock(); - + + _masks[maskID] = nullptr; + __IRImageLoaderMaskAcessLock.unlock(); + mask_t::Pointer mask; if ( !maskID.empty() ) mask = std_tile(maskID.c_str(), _shrinkFactor, _pixelSpacing); - - __IRImageLoaderMaskAcessLock.Lock(); + + __IRImageLoaderMaskAcessLock.lock(); _masks[maskID] = mask; - __IRImageLoaderMaskAcessLock.Unlock(); + __IRImageLoaderMaskAcessLock.unlock(); } diff --git a/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.h b/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.h index 92bd963bf..11b3a0206 100644 --- a/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.h +++ b/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.h @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include /** . @@ -59,14 +59,14 @@ namespace itk { - + /** \class ImageMosaicVarianceMetric * \brief Computes mean pixel variance within the overlapping regions * of a mosaic. * */ -template -class ITK_EXPORT ImageMosaicVarianceMetric : public SingleValuedCostFunction +template +class ITK_EXPORT ImageMosaicVarianceMetric : public SingleValuedCostFunction { public: /** Standard class typedefs. */ @@ -74,65 +74,65 @@ class ITK_EXPORT ImageMosaicVarianceMetric : public SingleValuedCostFunction typedef SingleValuedCostFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; - + /** Method for creation through the object factory. */ itkNewMacro(Self); - + /** Run-time type information (and related methods). */ itkTypeMacro(ImageMosaicVarianceMetric, SingleValuedCostFunction); - + /** Type of the moving Image. */ typedef TInterpolator interpolator_t; typedef TImage image_t; typedef typename TImage::PixelType pixel_t; - + /** Constant for the image dimension */ itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension); - + typedef itk::Image mask_t; - + /** Type of the transform base class */ - typedef Transform transform_t; - + typedef typename transform_t::InputPointType point_t; typedef typename transform_t::ParametersType params_t; typedef typename transform_t::JacobianType jacobian_t; - + /** Gaussian filter to compute the gradient of the mosaic images */ // typedef typename NumericTraits::RealType typedef float scalar_t; - + typedef CovariantVector gradient_pixel_t; - + typedef Image gradient_image_t; - + typedef GradientRecursiveGaussianImageFilter gradient_filter_t; - + /** Type of the measure. */ typedef Superclass::MeasureType measure_t; - + /** Type of the derivative. */ typedef Superclass::DerivativeType derivative_t; - + /** Get the number of pixels considered in the computation. */ itkGetConstReferenceMacro( NumberOfPixelsCounted, unsigned long ); - + /** Set/Get the region over which the metric will be computed */ itkSetMacro( MosaicRegion, typename image_t::RegionType ); itkGetConstReferenceMacro( MosaicRegion, typename image_t::RegionType ); - + /** Initialize transform parameter offsets. - + Setup the mapping from individual transform parameter indices to the corresponding indices in the concatenated parameter vector. - + The radial distortion transforms typically share the same parameters across all images in the mosaic, therefore it is slow and unnecessary to duplicate the same parameters parameters in the concatenated @@ -140,42 +140,42 @@ class ITK_EXPORT ImageMosaicVarianceMetric : public SingleValuedCostFunction This also allows a significant speedup of the optimization. On the other hand, translation parameters are typically unique for each image. - + params_shared is a vector of boolean flags indicating which of the transform parameters are shared (true) or unique (false). - + NOTE: this function will fail if the transform_ has not been initialized. */ void setup_param_map(const std::vector & params_shared, const std::vector & params_active); - + /** Concatenate parameters of each transform into one big vector. - + NOTE: this function will fail if SetupTransformParameterOffsets has not been called yet. */ params_t GetTransformParameters() const; - + /** virtual: Set the parameters defining the transforms: - + NOTE: this function will fail if SetupTransformParameterOffsets has not been called yet. */ void SetTransformParameters(const params_t & parameters) const; - + /** virtual: Return the number of parameters required by the transforms. - + NOTE: this function will fail if SetupTransformParameterOffsets has not been called yet. */ unsigned int GetNumberOfParameters() const; - + /** Initialize the Metric by making sure that all the components are present and plugged together correctly. */ virtual void Initialize() throw (ExceptionObject); - + /** virtual: Get the value for single valued optimizers. */ measure_t GetValue(const params_t & parameters) const { @@ -184,7 +184,7 @@ class ITK_EXPORT ImageMosaicVarianceMetric : public SingleValuedCostFunction GetValueAndDerivative(parameters, measure, derivative); return measure; } - + /** virtual: Get the derivatives of the match measure. */ void GetDerivative(const params_t & parameters, derivative_t & derivative) const @@ -192,18 +192,18 @@ class ITK_EXPORT ImageMosaicVarianceMetric : public SingleValuedCostFunction measure_t measure; GetValueAndDerivative(parameters, measure, derivative); } - + /** virtual: Get value and derivatives for multiple valued optimizers. */ void GetValueAndDerivative(const params_t & parameters, measure_t & value, derivative_t & derivative) const; - + //---------------------------------------------------------------- // image_data_t - // + // // This datastructure is used to speed up access to relevant // information when evaluating GetValueAndDerivative: - // + // class image_data_t { public: @@ -213,77 +213,77 @@ class ITK_EXPORT ImageMosaicVarianceMetric : public SingleValuedCostFunction dPdx_(measure_t(0)), dPdy_(measure_t(0)) {} - + // image id: unsigned int id_; - + // image value: measure_t P_; - + // partial derivative with respect to x: measure_t dPdx_; - + // partial derivative with respect to y: measure_t dPdy_; - + // a pointer to the Jacobian of the transform: - const jacobian_t * J_; + jacobian_t J_; }; - + // calculate the bounding box for a given set of image bounding boxes: void CalcMosaicBBox(point_t & mosaic_min, point_t & mosaic_max, std::vector & image_min, std::vector & image_max) const; - + // calculate the mosaic variance image as well as maximum and mean variance: typename image_t::Pointer variance(measure_t & max_var, measure_t & avg_var) const; - + typename image_t::Pointer variance(const typename TImage::SpacingType & sp, const pnt2d_t & mosaic_min, const pnt2d_t & mosaic_max, measure_t & max_var, measure_t & avg_var) const; - + typename image_t::Pointer variance(const typename TImage::SpacingType & sp, const pnt2d_t & mosaic_min, const typename TImage::SizeType & sz, measure_t & max_var, measure_t & avg_var) const; - + typename image_t::Pointer variance() const { measure_t max_var; measure_t avg_var; return variance(max_var, avg_var); } - + // mosaic images: std::vector image_; std::vector mask_; - + // image transforms (cascaded): mutable std::vector transform_; - + // image interpolators: std::vector interpolator_; - + // image gradients: std::vector gradient_; - + // adresses of the individual transform parameter indices within the // concatenated parameter vector: std::vector > address_; - + // number of shared/unique parameters per transform: unsigned int n_shared_; unsigned int n_unique_; - + // this mask defines which of the individual transform parameters are // active and will be included into the metric parameter vector: std::vector param_active_; - + protected: ImageMosaicVarianceMetric(): n_shared_(0), @@ -291,24 +291,24 @@ class ITK_EXPORT ImageMosaicVarianceMetric : public SingleValuedCostFunction param_active_(0), m_NumberOfPixelsCounted(0) {} - + virtual ~ImageMosaicVarianceMetric() {} - + // standard ITK debugging helper: void PrintSelf(std::ostream & os, Indent indent) const; - + // number of pixels in the overlapping regions of the mosaic: mutable unsigned long m_NumberOfPixelsCounted; - + private: // unimplemented on purpose: ImageMosaicVarianceMetric(const Self &); void operator = (const Self &); - + typename image_t::RegionType m_MosaicRegion; }; - + } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION diff --git a/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.txx b/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.txx index e59488dd7..af4401ac0 100644 --- a/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.txx +++ b/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.txx @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -57,8 +57,8 @@ namespace itk //---------------------------------------------------------------- // setup_param_map -// -template +// +template void ImageMosaicVarianceMetric:: setup_param_map(const std::vector & param_shared, @@ -66,15 +66,15 @@ setup_param_map(const std::vector & param_shared, { const unsigned int num_transforms = transform_.size(); assert(num_transforms > 0); - + const unsigned int n_params = param_shared.size(); assert(n_params > 0 && n_params == param_active.size() && n_params == transform_[0]->GetNumberOfParameters()); - + // save the active parameters mask: param_active_ = param_active; - + // count the number of shared/unique params: n_shared_ = 0; n_unique_ = 0; @@ -83,12 +83,12 @@ setup_param_map(const std::vector & param_shared, n_shared_ += param_active[i] && param_shared[i]; n_unique_ += param_active[i] && !param_shared[i]; } - + // build a mapping into the concatenated parameters vector, // shared parameters will be stored at the head of the vector // (to help with debugging) followed by the unique parameters: resize(address_, num_transforms, n_params); - + unsigned int u_off = n_shared_; for (unsigned int i = 0; i < num_transforms; i++) { @@ -96,7 +96,7 @@ setup_param_map(const std::vector & param_shared, for (unsigned int j = 0; j < n_params; j++) { if (!param_active[j]) continue; - + if (param_shared[j]) { address_[i][j] = s_off; @@ -107,7 +107,7 @@ setup_param_map(const std::vector & param_shared, address_[i][j] = u_off; u_off++; } - + // FIXME: // cout << "address[" << i << "][" << j << "] = " << address_[i][j] // << endl; @@ -117,18 +117,18 @@ setup_param_map(const std::vector & param_shared, //---------------------------------------------------------------- // GetTransformParameters -// -template +// +template typename ImageMosaicVarianceMetric::params_t ImageMosaicVarianceMetric:: GetTransformParameters() const { const unsigned int num_transforms = transform_.size(); assert(num_transforms > 0); - + const unsigned int n_params = param_active_.size(); assert(n_params > 0); - + params_t parameters(GetNumberOfParameters()); for (unsigned int i = 0; i < num_transforms; i++) { @@ -139,24 +139,24 @@ GetTransformParameters() const parameters[address_[i][k]] = params[k]; } } - + return parameters; } //---------------------------------------------------------------- // SetTransformParameters -// -template +// +template void ImageMosaicVarianceMetric:: SetTransformParameters(const params_t & parameters) const { const unsigned int num_transforms = transform_.size(); assert(num_transforms > 0); - + const unsigned int n_params = param_active_.size(); assert(n_params > 0); - + // extract individual transform parameter values: for (unsigned int i = 0; i < num_transforms; i++) { @@ -172,11 +172,11 @@ SetTransformParameters(const params_t & parameters) const //---------------------------------------------------------------- // GetNumberOfParameters -// -template +// +template unsigned int ImageMosaicVarianceMetric:: -GetNumberOfParameters() const +GetNumberOfParameters() const { const unsigned int num_transforms = transform_.size(); return n_shared_ + n_unique_ * num_transforms; @@ -184,8 +184,8 @@ GetNumberOfParameters() const //---------------------------------------------------------------- // Initialize -// -template +// +template void ImageMosaicVarianceMetric:: Initialize() throw (ExceptionObject) @@ -197,21 +197,21 @@ Initialize() throw (ExceptionObject) << "sizeof(gradient_pixel_t) = " << sizeof(gradient_pixel_t) << endl << endl; #endif - + const unsigned int num_transforms = address_.size(); - + if (num_transforms == 0) { itkExceptionMacro(<< "call setup_param_map first"); } - + for (unsigned int i = 0; i < num_transforms; i++) { if (!transform_[i]) { itkExceptionMacro(<< "One of the transforms is missing"); } - + if (!image_[i]) { itkExceptionMacro(<< "One of the images is missing"); @@ -222,7 +222,7 @@ Initialize() throw (ExceptionObject) image_[i]->GetSource()->Update(); } } - + // setup the interpolators, calculate the gradient images: interpolator_.resize(num_transforms); gradient_.resize(num_transforms); @@ -230,22 +230,22 @@ Initialize() throw (ExceptionObject) { interpolator_[i] = interpolator_t::New(); interpolator_[i]->SetInputImage(image_[i]); - + // calculate the image gradient: typename gradient_filter_t::Pointer gradient_filter = gradient_filter_t::New(); gradient_filter->SetInput(image_[i]); - + const typename image_t::SpacingType & spacing = image_[i]->GetSpacing(); double maximum_spacing = 0.0; for (unsigned int j = 0; j < ImageDimension; j++) { maximum_spacing = std::max(maximum_spacing, spacing[j]); } - + gradient_filter->SetSigma(maximum_spacing); gradient_filter->SetNormalizeAcrossScale(true); - + try { gradient_filter->Update(); @@ -257,10 +257,10 @@ Initialize() throw (ExceptionObject) << exception << std::endl; throw exception; } - + gradient_[i] = gradient_filter->GetOutput(); } - + // If there are any observers on the metric, call them to give the // user code a chance to set parameters on the metric: this->InvokeEvent(InitializeEvent()); @@ -268,10 +268,10 @@ Initialize() throw (ExceptionObject) //---------------------------------------------------------------- // GetValueAndDerivative -// +// // FIXME: the following code assumes a 2D mosaic: -// -template +// +template void ImageMosaicVarianceMetric:: GetValueAndDerivative(const params_t & parameters, @@ -280,31 +280,31 @@ GetValueAndDerivative(const params_t & parameters, { WRAP(itk_terminator_t terminator("ImageMosaicVarianceMetric::GetValueAndDerivative")); - + typedef typename image_t::IndexType index_t; typedef typename image_t::SpacingType spacing_t; typedef typename image_t::RegionType::SizeType imagesz_t; typedef typename image_t::RegionType region_t; - + itkDebugMacro("GetValueAndDerivative( " << parameters << " ) "); - + // shortcuts: const unsigned int num_images = interpolator_.size(); if (num_images == 0) { itkExceptionMacro(<< "You forgot to call Initialize()"); } - + // number of parameters per transform: const unsigned int n_params = param_active_.size(); if (n_params == 0) { itkExceptionMacro(<< "You forgot to call setup_param_map()"); } - + // the derivative vector size: const unsigned int n_concat = GetNumberOfParameters(); - + // compare the previous parameters to the next set of parameters: #if 0 { @@ -321,7 +321,7 @@ GetValueAndDerivative(const params_t & parameters, cout << endl; } #endif - + #if 0 { cout << "new parameters:\n" << parameters << endl; @@ -331,10 +331,10 @@ GetValueAndDerivative(const params_t & parameters, } } #endif - + // update the transforms: SetTransformParameters(parameters); - + // calculate image bounding boxes in the mosaic space, as well as the // mosaic bounding box: pnt2d_t mosaic_min = pnt2d(std::numeric_limits::max(), @@ -343,18 +343,18 @@ GetValueAndDerivative(const params_t & parameters, std::vector min(num_images); std::vector max(num_images); CalcMosaicBBox(mosaic_min, mosaic_max, min, max); - + // mosaic will have the same spacing as the first image in the mosaic: spacing_t spacing = image_[0]->GetSpacing(); imagesz_t mosaic_sz; { double nx = (mosaic_max[0] - mosaic_min[0]) / spacing[0]; double ny = (mosaic_max[1] - mosaic_min[1]) / spacing[1]; - + mosaic_sz[0] = (unsigned int)(nx + 0.5); mosaic_sz[1] = (unsigned int)(ny + 0.5); } - + // update the region of interest if necessary: region_t ROI = m_MosaicRegion; if (ROI.GetNumberOfPixels() == 0) @@ -366,30 +366,30 @@ GetValueAndDerivative(const params_t & parameters, ROI.SetIndex(index); ROI.SetSize(mosaic_sz); } - + // setup the mosaic image, but don't allocate any buffers for it: typename image_t::Pointer mosaic = image_t::New(); mosaic->SetRegions(mosaic_sz); mosaic->SetSpacing(spacing); mosaic->SetOrigin(pnt2d(mosaic_min[0], mosaic_min[1])); - + // reset the accumulators: derivative = derivative_t(n_concat); - derivative.Fill(NumericTraits::Zero); + derivative.Fill(NumericTraits::Zero); measure = NumericTraits::Zero; m_NumberOfPixelsCounted = 0; - + // pre-allocate and initialize image data for each image: std::vector image_data(num_images); for (unsigned int i = 0; i < num_images; i++) { image_data[i].id_ = i; } - + // preallocate derivatives of the mean and variance: std::vector dMu(n_concat); std::vector dV(n_concat); - + // iterate over the mosaic, evaluate the metric in the overlapping regions: typedef itk::ImageRegionConstIteratorWithIndex itex_t; // bool FIXME_FIRST_RUN = true; @@ -398,55 +398,55 @@ GetValueAndDerivative(const params_t & parameters, { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + pnt2d_t point; mosaic->TransformIndexToPhysicalPoint(itex.GetIndex(), point); - + // find pixels in overlapping regions of the mosaic: std::list overlap; for (unsigned int k = 0; k < num_images; k++) { if (point[0] < min[k][0] || point[0] > max[k][0] || point[1] < min[k][1] || point[1] > max[k][1]) continue; - + typename transform_t::Pointer & t = transform_[k]; pnt2d_t pt_k = t->TransformPoint(point); index_t index; // make sure the pixel maps into the image: image_[k]->TransformPhysicalPointToIndex(pt_k, index); if (!interpolator_[k]->IsInsideBuffer(pt_k)) continue; - + // make sure the pixel maps into the mask: if (mask_[k].GetPointer() && mask_[k]->GetPixel(index) == 0) continue; - + // shortcut: image_data_t & data = image_data[k]; - + // get the image value: // data.P_ = image_[k]->GetPixel(index); // faster data.P_ = interpolator_[k]->Evaluate(pt_k); // slower - + // get the image gradient: const gradient_pixel_t & gradient = gradient_[k]->GetPixel(index); data.dPdx_ = gradient[0]; data.dPdy_ = gradient[1]; - + // get the transform Jacobian: - data.J_ = &(t->GetJacobian(point)); - + t->ComputeJacobianWithRespectToPosition(point, data.J_); + // add to the list: overlap.push_back(&data); } - + // skip over the regions that do not overlap: if (overlap.size() < 2) continue; - + // found a pixel in an overlapping region, increment the counter: m_NumberOfPixelsCounted++; - + // shortcut: measure_t normalization_factor = measure_t(1) / measure_t(overlap.size()); - + // calculate the mean and derivative of the mean: measure_t Mu = measure_t(0); dMu.assign(n_concat, measure_t(0)); @@ -455,10 +455,10 @@ GetValueAndDerivative(const params_t & parameters, { const image_data_t & data = *(*i); const unsigned int * addr = &(address_[data.id_][0]); - const jacobian_t & J = *(data.J_); - + const jacobian_t & J = data.J_; + Mu += data.P_; - + for (unsigned int j = 0; j < n_params; j++) { dMu[addr[j]] += @@ -474,7 +474,7 @@ GetValueAndDerivative(const params_t & parameters, dMu[i] *= normalization_factor; } #endif - + // calculate the variance: measure_t V = measure_t(0); dV.assign(n_concat, measure_t(0)); @@ -483,11 +483,11 @@ GetValueAndDerivative(const params_t & parameters, { const image_data_t & data = *(*i); const unsigned int * addr = &(address_[data.id_][0]); - const jacobian_t & J = *(data.J_); - + const jacobian_t & J = data.J_; + measure_t d = data.P_ - Mu; V += d * d; - + for (unsigned int j = 0; j < n_params; j++) { dV[addr[j]] += @@ -504,7 +504,7 @@ GetValueAndDerivative(const params_t & parameters, dV[i] *= normalization_factor; } #endif - + #if 0 if (FIXME_FIRST_RUN && overlap.size() > 2) { @@ -514,8 +514,8 @@ GetValueAndDerivative(const params_t & parameters, { const image_data_t & data = *(*i); const unsigned int * addr = &(address_[data.id_][0]); - const jacobian_t & J = *(data.J_); - + const jacobian_t & J = data.J_; + for (unsigned int k = 0; k < 2; k++) { cout << "J[" << k << "] ="; @@ -531,29 +531,29 @@ GetValueAndDerivative(const params_t & parameters, #endif // update the measure: measure += V; - + // update the derivative: for (unsigned int i = 0; i < n_concat; i++) { derivative[i] += dV[i]; } } - + if (m_NumberOfPixelsCounted == 0) { itkExceptionMacro(<< "mosaic contains no overlapping images"); return; } - + measure_t normalization_factor = measure_t(1) / measure_t(m_NumberOfPixelsCounted); measure *= normalization_factor; - + for (unsigned int i = 0; i < n_concat; i++) { derivative[i] *= normalization_factor; } - + #if 0 cout << "stdV: " << measure << endl; cout << "0 dV: "; @@ -570,8 +570,8 @@ GetValueAndDerivative(const params_t & parameters, //---------------------------------------------------------------- // CalcMosaicBBox -// -template +// +template void ImageMosaicVarianceMetric:: CalcMosaicBBox(point_t & mosaic_min, @@ -585,22 +585,22 @@ CalcMosaicBBox(point_t & mosaic_min, calc_image_bboxes(image_, image_min, image_max); - + // mosaic space bounding boxes: calc_mosaic_bboxes(transform_, image_min, image_max, min, max); - + // mosiac bounding box: calc_mosaic_bbox(min, max, mosaic_min, mosaic_max); } //---------------------------------------------------------------- // variance -// -template +// +template typename TImage::Pointer ImageMosaicVarianceMetric:: variance(measure_t & max_var, @@ -608,21 +608,21 @@ variance(measure_t & max_var, { max_var = measure_t(0); avg_var = measure_t(0); - + // shortcut: const unsigned int num_images = interpolator_.size(); if (num_images == 0) { itkExceptionMacro(<< "You forgot to call Initialize()"); } - + pnt2d_t mosaic_min = pnt2d(std::numeric_limits::max(), std::numeric_limits::max()); pnt2d_t mosaic_max = pnt2d(-mosaic_min[0], -mosaic_min[1]); std::vector min(num_images); std::vector max(num_images); CalcMosaicBBox(mosaic_min, mosaic_max, min, max); - + return variance(image_[0]->GetSpacing(), mosaic_min, mosaic_max, @@ -632,8 +632,8 @@ variance(measure_t & max_var, //---------------------------------------------------------------- // variance -// -template +// +template typename TImage::Pointer ImageMosaicVarianceMetric:: variance(const typename TImage::SpacingType & mosaic_sp, @@ -656,8 +656,8 @@ variance(const typename TImage::SpacingType & mosaic_sp, //---------------------------------------------------------------- // variance -// -template +// +template typename TImage::Pointer ImageMosaicVarianceMetric:: variance(const typename TImage::SpacingType & mosaic_sp, @@ -668,20 +668,20 @@ variance(const typename TImage::SpacingType & mosaic_sp, { WRAP(itk_terminator_t terminator("ImageMosaicVarianceMetric::GetValueAndDerivative")); - + typedef typename image_t::IndexType index_t; //typedef typename image_t::RegionType::SizeType imagesz_t; - + max_var = measure_t(0); avg_var = measure_t(0); - + // shortcut: const unsigned int num_images = interpolator_.size(); if (num_images == 0) { itkExceptionMacro(<< "You forgot to call Initialize()"); } - + // calculate image bounding boxes in the mosaic space, as well as the // mosaic bounding box: pnt2d_t global_min = pnt2d(std::numeric_limits::max(), @@ -690,7 +690,7 @@ variance(const typename TImage::SpacingType & mosaic_sp, std::vector min(num_images); std::vector max(num_images); CalcMosaicBBox(global_min, global_max, min, max); - + // setup the mosaic image: typename image_t::Pointer mosaic = image_t::New(); mosaic->SetOrigin(mosaic_min); @@ -698,51 +698,51 @@ variance(const typename TImage::SpacingType & mosaic_sp, mosaic->SetSpacing(mosaic_sp); mosaic->Allocate(); mosaic->FillBuffer(NumericTraits::Zero); - + // iterate over the mosaic, evaluate the metric in the overlapping regions: typedef itk::ImageRegionIteratorWithIndex itex_t; unsigned int pixel_count = 0; - + itex_t itex(mosaic, mosaic->GetLargestPossibleRegion()); for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + pnt2d_t point; mosaic->TransformIndexToPhysicalPoint(itex.GetIndex(), point); - + // find pixels in overlapping regions of the mosaic: std::list overlap; for (unsigned int k = 0; k < num_images; k++) { if (point[0] < min[k][0] || point[0] > max[k][0] || point[1] < min[k][1] || point[1] > max[k][1]) continue; - + const typename transform_t::Pointer & t = transform_[k]; pnt2d_t pt_k = t->TransformPoint(point); index_t index; image_[k]->TransformPhysicalPointToIndex(pt_k, index); - + // make sure the pixel maps into the image: if (!interpolator_[k]->IsInsideBuffer(pt_k)) continue; - + // make sure the pixel maps into the mask: if (mask_[k].GetPointer() && mask_[k]->GetPixel(index) == 0) continue; - + // get the image value, add it to the list: overlap.push_back(interpolator_[k]->Evaluate(pt_k)); } - + // skip over the regions that do not overlap: if (overlap.size() < 2) continue; - + // found a pixel in an overlapping region, increment the counter: pixel_count++; - + // shortcut: measure_t normalization_factor = measure_t(1) / measure_t(overlap.size()); - + // calculate the mean and derivative of the mean: measure_t Mu = measure_t(0); for (std::list::const_iterator i = overlap.begin(); @@ -751,7 +751,7 @@ variance(const typename TImage::SpacingType & mosaic_sp, Mu += *i; } Mu *= normalization_factor; - + // calculate the variance: measure_t V = measure_t(0); for (std::list::const_iterator i = overlap.begin(); @@ -762,27 +762,27 @@ variance(const typename TImage::SpacingType & mosaic_sp, } V *= normalization_factor; itex.Set(pixel_t(V)); - + max_var = std::max(max_var, V); avg_var += V; } - + measure_t normalization_factor = measure_t(1) / measure_t(pixel_count); avg_var *= normalization_factor; - + return mosaic; } //---------------------------------------------------------------- // PrintSelf -// -template +// +template void ImageMosaicVarianceMetric:: PrintSelf(std::ostream & os, Indent indent) const { // FIXME: write me: - + Superclass::PrintSelf( os, indent ); os << indent << "MosaicRegion: " << m_MosaicRegion << std::endl << indent << "Number of Pixels Counted: " << m_NumberOfPixelsCounted diff --git a/src/Core/ITKCommon/Optimizers/itkRegularStepGradientDescentOptimizer2.cxx b/src/Core/ITKCommon/Optimizers/itkRegularStepGradientDescentOptimizer2.cxx index 6ae46f0be..31eae30e7 100644 --- a/src/Core/ITKCommon/Optimizers/itkRegularStepGradientDescentOptimizer2.cxx +++ b/src/Core/ITKCommon/Optimizers/itkRegularStepGradientDescentOptimizer2.cxx @@ -73,7 +73,7 @@ RegularStepGradientDescentOptimizer2::RegularStepGradientDescentOptimizer2(): m_PickUpPaceSteps(1000000) { itkDebugMacro("Constructor"); - m_CostFunction = NULL; + m_CostFunction = nullptr; } //---------------------------------------------------------------- @@ -273,7 +273,7 @@ RegularStepGradientDescentOptimizer2::AdvanceOneStep() magnitudeSquared += weighted * weighted; } - const double gradientMagnitude = vcl_sqrt(magnitudeSquared); + const double gradientMagnitude = std::sqrt(magnitudeSquared); if (gradientMagnitude < m_GradientMagnitudeTolerance) { m_StopCondition = GradientMagnitudeTolerance; diff --git a/src/Core/ITKCommon/STOS/stos.hxx b/src/Core/ITKCommon/STOS/stos.hxx index 12cdbdc46..891627c36 100644 --- a/src/Core/ITKCommon/STOS/stos.hxx +++ b/src/Core/ITKCommon/STOS/stos.hxx @@ -254,7 +254,7 @@ public: itk::TransformBase::Pointer tmp = load_transform(si); t01_ = dynamic_cast(tmp.GetPointer()); - bool ok = t01_.GetPointer() != NULL; + bool ok = t01_.GetPointer() != nullptr; fn_mask_[0].clear(); fn_mask_[1].clear(); diff --git a/src/Core/ITKCommon/STOS/stos_common.hxx b/src/Core/ITKCommon/STOS/stos_common.hxx index 8d3d7730f..ad3246e12 100644 --- a/src/Core/ITKCommon/STOS/stos_common.hxx +++ b/src/Core/ITKCommon/STOS/stos_common.hxx @@ -445,7 +445,7 @@ public: load_data(data, mask, shrink_factor, clahe_slope, clahe_window); // we don't care about the image data here, get rid of it: - data = NULL; + data = nullptr; // gather childrens masks and clip this nodes mask against it children: for (typename std::list::const_iterator @@ -465,7 +465,7 @@ public: // clip this nodes mask against the childs mask: base_transform_t::ConstPointer t = link.stos_.t01_.GetPointer(); - if ( mask != mask_t::Pointer(NULL) && imask != mask_t::Pointer(NULL) ) + if ( mask != mask_t::Pointer(nullptr) && imask != mask_t::Pointer(nullptr) ) clip_mask_a_by_b(mask, imask, t); } } diff --git a/src/Core/ITKCommon/ThreadUtils/the_boost_thread.cxx b/src/Core/ITKCommon/ThreadUtils/the_boost_thread.cxx index 312c130ea..ea8175e98 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_boost_thread.cxx +++ b/src/Core/ITKCommon/ThreadUtils/the_boost_thread.cxx @@ -60,9 +60,9 @@ static the_boost_thread_storage_t THREAD_STORAGE; // the_boost_thread_t::the_boost_thread_t(): the_thread_interface_t(the_boost_mutex_t::create()), - boost_thread_(NULL) + boost_thread_(nullptr) { - if (THREAD_STORAGE.get() == NULL) + if (THREAD_STORAGE.get() == nullptr) { THREAD_STORAGE.reset(new the_thread_observer_t(*this)); } @@ -162,7 +162,7 @@ the_boost_thread_t::wait() boost_thread_->join(); delete boost_thread_; - boost_thread_ = NULL; + boost_thread_ = nullptr; } //---------------------------------------------------------------- @@ -202,5 +202,5 @@ the_boost_thread_t::run() work(); // clean up the thread storage: - THREAD_STORAGE.reset(NULL); + THREAD_STORAGE.reset(nullptr); } diff --git a/src/Core/ITKCommon/ThreadUtils/the_boost_thread_storage.hxx b/src/Core/ITKCommon/ThreadUtils/the_boost_thread_storage.hxx index ef85b133f..bf942b064 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_boost_thread_storage.hxx +++ b/src/Core/ITKCommon/ThreadUtils/the_boost_thread_storage.hxx @@ -53,7 +53,7 @@ public: // virtual: check whether the thread storage has been initialized: bool is_ready() const { - return (boost::thread_specific_ptr::get() != NULL); + return (boost::thread_specific_ptr::get() != nullptr); } // virtual: check whether the thread has been stopped: diff --git a/src/Core/ITKCommon/ThreadUtils/the_mutex_interface.cxx b/src/Core/ITKCommon/ThreadUtils/the_mutex_interface.cxx index 78b63b473..803c8e654 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_mutex_interface.cxx +++ b/src/Core/ITKCommon/ThreadUtils/the_mutex_interface.cxx @@ -43,7 +43,7 @@ // the_mutex_interface_t::creator_ // the_mutex_interface_t::creator_t -the_mutex_interface_t::creator_ = NULL; +the_mutex_interface_t::creator_ = nullptr; //---------------------------------------------------------------- // the_mutex_interface_t::~the_mutex_interface_t @@ -66,6 +66,6 @@ the_mutex_interface_t::set_creator(the_mutex_interface_t::creator_t creator) the_mutex_interface_t * the_mutex_interface_t::create() { - if (creator_ == NULL) return NULL; + if (creator_ == nullptr) return nullptr; return creator_(); } diff --git a/src/Core/ITKCommon/ThreadUtils/the_thread_interface.cxx b/src/Core/ITKCommon/ThreadUtils/the_thread_interface.cxx index c9230228d..780fdac5e 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_thread_interface.cxx +++ b/src/Core/ITKCommon/ThreadUtils/the_thread_interface.cxx @@ -59,8 +59,8 @@ using std::endl; // static the_mutex_interface_t * MUTEX() { - static the_mutex_interface_t * mutex_ = NULL; - if (mutex_ == NULL) + static the_mutex_interface_t * mutex_ = nullptr; + if (mutex_ == nullptr) { mutex_ = the_mutex_interface_t::create(); } @@ -73,7 +73,7 @@ static the_mutex_interface_t * MUTEX() // the_thread_interface_t::creator_ // the_thread_interface_t::creator_t -the_thread_interface_t::creator_ = NULL; +the_thread_interface_t::creator_ = nullptr; //---------------------------------------------------------------- // the_thread_interface_t::the_thread_interface_t @@ -83,9 +83,9 @@ the_thread_interface_t::the_thread_interface_t(the_mutex_interface_t * mutex): stopped_(true), sleep_when_idle_(false), sleep_microsec_(10000), - active_transaction_(NULL), - thread_pool_(NULL), - thread_pool_cb_data_(NULL) + active_transaction_(nullptr), + thread_pool_(nullptr), + thread_pool_cb_data_(nullptr) { the_lock_t locker(MUTEX()); static unsigned int counter = 0; @@ -115,7 +115,7 @@ the_thread_interface_t::set_creator(the_thread_interface_t::creator_t creator) the_thread_interface_t * the_thread_interface_t::create() { - if (creator_ == NULL) return NULL; + if (creator_ == nullptr) return nullptr; return creator_(); } @@ -176,7 +176,7 @@ the_thread_interface_t::push_back(std::list & schedule) bool the_thread_interface_t::has_work() const { - return (active_transaction_ != NULL) || !transactions_.empty(); + return (active_transaction_ != nullptr) || !transactions_.empty(); } //---------------------------------------------------------------- @@ -359,19 +359,19 @@ the_thread_interface_t::work() { the_lock_t lock_this(mutex_, false); the_lock_t lock_pool(thread_pool_ ? - thread_pool_->mutex_ : NULL, + thread_pool_->mutex_ : nullptr, false); bool all_transactions_completed = true; while (!stopped_) { // get the next transaction: - the_transaction_t * t = NULL; + the_transaction_t * t = nullptr; { lock_pool.arm(); lock_this.arm(); - if (thread_pool_ != NULL) + if (thread_pool_ != nullptr) { // call back the thread pool: #ifdef DEBUG_THREAD @@ -418,12 +418,12 @@ the_thread_interface_t::work() t->notify(this, the_transaction_t::STARTED_E); t->execute(this); all_transactions_completed = (all_transactions_completed && true); - active_transaction_ = NULL; + active_transaction_ = nullptr; t->notify(this, the_transaction_t::DONE_E); } catch (std::exception & e) { - active_transaction_ = NULL; + active_transaction_ = nullptr; #ifdef DEBUG_THREAD cerr << "FIXME: caught exception: " << e.what() << endl; #endif @@ -433,7 +433,7 @@ the_thread_interface_t::work() } catch (...) { - active_transaction_ = NULL; + active_transaction_ = nullptr; #ifdef DEBUG_THREAD cerr << "FIXME: caught unknonwn exception" << endl; #endif @@ -468,7 +468,7 @@ the_thread_interface_t::work() cerr << "thread " << this << " is finished" << endl; #endif - if (thread_pool_ != NULL) + if (thread_pool_ != nullptr) { lock_pool.arm(); lock_this.arm(); @@ -504,7 +504,7 @@ the_thread_interface_t::handle(the_transaction_t * transaction, void the_thread_interface_t::blab(const char * message) const { - if (thread_pool_ == NULL) + if (thread_pool_ == nullptr) { cerr << message << endl; } diff --git a/src/Core/ITKCommon/ThreadUtils/the_thread_interface.hxx b/src/Core/ITKCommon/ThreadUtils/the_thread_interface.hxx index 31a53abfc..c17d82965 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_thread_interface.hxx +++ b/src/Core/ITKCommon/ThreadUtils/the_thread_interface.hxx @@ -74,7 +74,7 @@ public: // the thread will own the mutex passed down to it, // it will delete the mutex when the thread is deleted: - the_thread_interface_t(the_mutex_interface_t * mutex = NULL); + the_thread_interface_t(the_mutex_interface_t * mutex = nullptr); //---------------------------------------------------------------- // creator_t diff --git a/src/Core/ITKCommon/ThreadUtils/the_thread_pool.cxx b/src/Core/ITKCommon/ThreadUtils/the_thread_pool.cxx index 290ad60ef..912685834 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_thread_pool.cxx +++ b/src/Core/ITKCommon/ThreadUtils/the_thread_pool.cxx @@ -63,7 +63,7 @@ the_transaction_wrapper_t(const unsigned int & num_parts, cb_data_(transaction->notify_cb_data_), num_parts_(num_parts) { - assert(mutex_ != NULL); + assert(mutex_ != nullptr); for (unsigned int i = 0; i <= the_transaction_t::DONE_E; i++) { @@ -78,7 +78,7 @@ the_transaction_wrapper_t(const unsigned int & num_parts, the_transaction_wrapper_t::~the_transaction_wrapper_t() { mutex_->delete_this(); - mutex_ = NULL; + mutex_ = nullptr; } //---------------------------------------------------------------- @@ -116,7 +116,7 @@ the_transaction_wrapper_t::notify(the_transaction_t * t, { case the_transaction_t::PENDING_E: case the_transaction_t::STARTED_E: - if (notified_[s] == 1 && num_terminal_notifications == 0 && cb_ != NULL) + if (notified_[s] == 1 && num_terminal_notifications == 0 && cb_ != nullptr) { cb_(cb_data_, t, s); } @@ -142,7 +142,7 @@ the_transaction_wrapper_t::notify(the_transaction_t * t, t->set_state(state); } - if (cb_ != NULL) + if (cb_ != nullptr) { cb_(cb_data_, t, t->state()); } @@ -171,7 +171,7 @@ the_thread_pool_t::the_thread_pool_t(unsigned int num_threads): pool_size_(num_threads) { mutex_ = the_mutex_interface_t::create(); - assert(mutex_ != NULL); + assert(mutex_ != nullptr); pool_ = new the_thread_pool_data_t[num_threads]; for (unsigned int i = 0; i < num_threads; i++) @@ -179,7 +179,7 @@ the_thread_pool_t::the_thread_pool_t(unsigned int num_threads): pool_[i].id_ = i; pool_[i].parent_ = this; pool_[i].thread_ = the_thread_interface_t::create(); - assert(pool_[i].thread_ != NULL); + assert(pool_[i].thread_ != nullptr); pool_[i].thread_->set_thread_pool_cb(this, &pool_[i]); // mark the thread as idle, initially: @@ -194,10 +194,10 @@ the_thread_pool_t::~the_thread_pool_t() { // TODO: sketchy! mutex_->delete_this(); - mutex_ = NULL; + mutex_ = nullptr; delete [] pool_; - pool_ = NULL; + pool_ = nullptr; pool_size_ = 0; } @@ -314,13 +314,13 @@ wrap(the_transaction_t * transaction, the_thread_pool_t * pool, bool multithreaded) { - if (transaction->notify_cb() == NULL) + if (transaction->notify_cb() == nullptr) { // override the callback: transaction->set_notify_cb(::notify_cb, pool); } - if (transaction->status_cb() == NULL) + if (transaction->status_cb() == nullptr) { // override the callback: transaction->set_status_cb(::status_cb, pool); diff --git a/src/Core/ITKCommon/ThreadUtils/the_thread_pool.hxx b/src/Core/ITKCommon/ThreadUtils/the_thread_pool.hxx index 444bbeae6..adb7d7ec0 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_thread_pool.hxx +++ b/src/Core/ITKCommon/ThreadUtils/the_thread_pool.hxx @@ -85,8 +85,8 @@ private: struct the_thread_pool_data_t { the_thread_pool_data_t(): - parent_(NULL), - thread_(NULL), + parent_(nullptr), + thread_(nullptr), id_(~0u) {} diff --git a/src/Core/ITKCommon/ThreadUtils/the_transaction.cxx b/src/Core/ITKCommon/ThreadUtils/the_transaction.cxx index 3a03c19e1..cc45dc935 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_transaction.cxx +++ b/src/Core/ITKCommon/ThreadUtils/the_transaction.cxx @@ -49,10 +49,10 @@ the_transaction_t::the_transaction_t(): mutex_(the_mutex_interface_t::create()), request_(NOTHING_E), state_(PENDING_E), - notify_cb_(NULL), - notify_cb_data_(NULL), - status_cb_(NULL), - status_cb_data_(NULL) + notify_cb_(nullptr), + notify_cb_data_(nullptr), + status_cb_(nullptr), + status_cb_data_(nullptr) {} //---------------------------------------------------------------- @@ -60,10 +60,10 @@ the_transaction_t::the_transaction_t(): // the_transaction_t::~the_transaction_t() { - if (mutex_ != NULL) + if (mutex_ != nullptr) { mutex_->delete_this(); - mutex_ = NULL; + mutex_ = nullptr; } } @@ -78,7 +78,7 @@ the_transaction_t::notify(the_transaction_handler_t * handler, set_state(s); blab(handler, message); - if (notify_cb_ == NULL) + if (notify_cb_ == nullptr) { handler->handle(this, s); } @@ -95,9 +95,9 @@ void the_transaction_t::blab(the_transaction_handler_t * handler, const char * message) { - if (message == NULL) return; + if (message == nullptr) return; - if (status_cb_ == NULL) + if (status_cb_ == nullptr) { handler->blab(message); } @@ -113,7 +113,7 @@ the_transaction_t::blab(the_transaction_handler_t * handler, bool the_transaction_t::callback_request() { - if (status_cb_ == NULL) + if (status_cb_ == nullptr) { return false; } @@ -125,7 +125,7 @@ the_transaction_t::callback_request() } // execute the status callback: - status_cb_(status_cb_data_, this, NULL); + status_cb_(status_cb_data_, this, nullptr); while (true) { diff --git a/src/Core/ITKCommon/ThreadUtils/the_transaction.hxx b/src/Core/ITKCommon/ThreadUtils/the_transaction.hxx index 88ed9bbee..269dc2ddf 100644 --- a/src/Core/ITKCommon/ThreadUtils/the_transaction.hxx +++ b/src/Core/ITKCommon/ThreadUtils/the_transaction.hxx @@ -96,7 +96,7 @@ public: //---------------------------------------------------------------- // status_cb_t // - // NOTE: if status is NULL, it means the transaction is requesting + // NOTE: if status is nullptr, it means the transaction is requesting // a callback from the main thread. This could be used by the // transaction for some GUI user interaction (such as finding replacement // tiles for a mosaic, etc...) @@ -115,7 +115,7 @@ public: // notify the transaction about a change in it's state: virtual void notify(the_transaction_handler_t * handler, state_t s, - const char * message = NULL); + const char * message = nullptr); // helper: virtual void blab(the_transaction_handler_t * handler, diff --git a/src/Core/ITKCommon/Transform/IRRefineTranslateCanvas.cxx b/src/Core/ITKCommon/Transform/IRRefineTranslateCanvas.cxx index bb7fb1cc5..c4fe0c5f6 100644 --- a/src/Core/ITKCommon/Transform/IRRefineTranslateCanvas.cxx +++ b/src/Core/ITKCommon/Transform/IRRefineTranslateCanvas.cxx @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -46,7 +46,7 @@ //---------------------------------------------------------------- // IRRefineTranslateCanvas::IRRefineTranslateCanvas -// +// IRRefineTranslateCanvas::IRRefineTranslateCanvas() { this->maxOffset[0] = std::numeric_limits::max(); @@ -58,13 +58,13 @@ IRRefineTranslateCanvas::IRRefineTranslateCanvas() //---------------------------------------------------------------- // IRRefineTranslateCanvas::~IRRefineTranslateCanvas -// +// IRRefineTranslateCanvas::~IRRefineTranslateCanvas() {} //---------------------------------------------------------------- // IRRefineTranslateCanvas::setBaseTransforms -// +// void IRRefineTranslateCanvas:: setBaseTransforms(const TrasformBasePointerVector & transforms, @@ -73,7 +73,7 @@ setBaseTransforms(const TrasformBasePointerVector & transforms, { TrasformBasePointerVector::const_iterator transformIter = transforms.begin(); - + TheTextVector::const_iterator imageIDIter = imageIDs.begin(); TheTextVector::const_iterator maskIDIter = maskIDs.begin(); for (; transformIter != transforms.end(); transformIter++, imageIDIter++, maskIDIter++) @@ -84,7 +84,7 @@ setBaseTransforms(const TrasformBasePointerVector & transforms, } //---------------------------------------------------------------- // IRRefineTranslateCanvas::setMaxOffset -// +// void IRRefineTranslateCanvas::setMaxOffset(const double maxOffset[], bool isPercent) { @@ -95,7 +95,7 @@ IRRefineTranslateCanvas::setMaxOffset(const double maxOffset[], bool isPercent) //---------------------------------------------------------------- // IRRefineTranslateCanvas::setBlackMaskPercent -// +// void IRRefineTranslateCanvas::setBlackMaskPercent(const double blackMaskPercent[]) { @@ -105,7 +105,7 @@ IRRefineTranslateCanvas::setBlackMaskPercent(const double blackMaskPercent[]) //---------------------------------------------------------------- // IRRefineTranslateCanvas::doClahe -// +// void IRRefineTranslateCanvas::doClahe( bool _doClahe ) { @@ -115,7 +115,7 @@ IRRefineTranslateCanvas::doClahe( bool _doClahe ) //---------------------------------------------------------------- // IRRefineTranslateCanvas::fillTransformAndImageIDVectors -// +// void IRRefineTranslateCanvas:: fillTransformAndImageIDVectors(TrasformBasePointerVector& transforms, @@ -136,10 +136,10 @@ fillTransformAndImageIDVectors(TrasformBasePointerVector& transforms, //---------------------------------------------------------------- // IRRefineTranslateCanvas::fillTransformAndImageIDVectors -// +// // silly other version that uses a list because fo some reason // paul likes using lists for the image IDs........ -// +// void IRRefineTranslateCanvas:: fillTransformAndImageIDVectors(TrasformBasePointerVector& transforms, @@ -163,12 +163,12 @@ fillTransformAndImageIDVectors(TrasformBasePointerVector& transforms, //---------------------------------------------------------------- // IRRefineTranslateCanvas::buildConnections -// +// void IRRefineTranslateCanvas::buildConnections( bool verbose ) { _preProcessedConnectionVector.clear(); - + IRTransformationVector::const_iterator transformIter1, transformIter2; for (transformIter1 = _transformationVector.begin(); transformIter1 != _transformationVector.end(); transformIter1++) @@ -180,10 +180,10 @@ IRRefineTranslateCanvas::buildConnections( bool verbose ) { continue; } - + if ((*transformIter1)->overlapsTransform(*transformIter2)) { - + _preProcessedConnectionVector.push_back(new IRConnection(*transformIter1, *transformIter2, verbose)); @@ -191,13 +191,13 @@ IRRefineTranslateCanvas::buildConnections( bool verbose ) } } } - + return; } //---------------------------------------------------------------- // IRRefineTranslateCanvas::fillGroupIDs -// +// void IRRefineTranslateCanvas::fillGroupIDs() { @@ -218,7 +218,7 @@ IRRefineTranslateCanvas::fillGroupIDs() // // removes transforms that are in a group that make up // less than cutoffPercentage of the mosaic -// +// void IRRefineTranslateCanvas::pruneSmallGroups(float cutoffPercentage) { @@ -228,7 +228,7 @@ IRRefineTranslateCanvas::pruneSmallGroups(float cutoffPercentage) { largestGroupID = std::max(largestGroupID, (*iter)->groupID()); } - + std::vector groupCounts; groupCounts.resize(largestGroupID + 1); for (std::vector::iterator iter = groupCounts.begin(); @@ -236,15 +236,15 @@ IRRefineTranslateCanvas::pruneSmallGroups(float cutoffPercentage) { *iter = 0.0f; } - + for (IRTransformationVector::iterator iter = _transformationVector.begin(); iter != _transformationVector.end(); ++iter) { groupCounts[(*iter)->groupID()] += 1.0f; } - + float transformCount = _transformationVector.size(); - + for (size_t i = 0; i < groupCounts.size(); i++) { if (groupCounts[i] / transformCount < cutoffPercentage) @@ -256,46 +256,46 @@ IRRefineTranslateCanvas::pruneSmallGroups(float cutoffPercentage) //---------------------------------------------------------------- // IRTransaction -// +// class IRTransaction : public the_transaction_t { public: IRTransaction(IRRefineTranslateCanvas * canvas): canvas_(canvas) {} - + // virtual: void execute(the_thread_interface_t * thread) { the_terminator_t terminator("IRTransaction"); canvas_->findOffsetsThreadEntry(); } - + IRRefineTranslateCanvas * canvas_; }; //---------------------------------------------------------------- // IRRefineTranslateCanvas::findIdealTransformationOffsets -// +// void IRRefineTranslateCanvas::findIdealTransformationOffsets(unsigned int numThreads) { the_thread_pool_t thread_pool(numThreads); thread_pool.set_idle_sleep_duration(50); // 50 usec - + for(unsigned int i = 0; i < numThreads; i++) { IRTransaction * t = new IRTransaction(this); thread_pool.push_back(t); } - + thread_pool.start(); thread_pool.wait(); } //---------------------------------------------------------------- // IRRefineTranslateCanvas::releaseTensionOnSystem -// +// void IRRefineTranslateCanvas::releaseTensionOnSystem() { @@ -308,7 +308,7 @@ IRRefineTranslateCanvas::releaseTensionOnSystem() //---------------------------------------------------------------- // IRRefineTranslateCanvas::systemEnergy -// +// float IRRefineTranslateCanvas::systemEnergy() { @@ -318,7 +318,7 @@ IRRefineTranslateCanvas::systemEnergy() { vec2d_t tension = (*iter)->tensionOnTransformation((*iter)->firstTransformation()); - + energy += tension*tension; } return energy; @@ -326,7 +326,7 @@ IRRefineTranslateCanvas::systemEnergy() //---------------------------------------------------------------- // IRRefineTranslateCanvas::maximumTension -// +// float IRRefineTranslateCanvas::maximumTension() { @@ -336,7 +336,7 @@ IRRefineTranslateCanvas::maximumTension() { vec2d_t tension = (*iter)->tensionOnTransformation((*iter)->firstTransformation()); - + maxTension = std::max(sqrtf(tension*tension), maxTension); } return maxTension; @@ -344,7 +344,7 @@ IRRefineTranslateCanvas::maximumTension() //---------------------------------------------------------------- // IRRefineTranslateCanvas::maximumPullOnTransformation -// +// float IRRefineTranslateCanvas::maximumPullOnTransformation() { @@ -360,12 +360,12 @@ IRRefineTranslateCanvas::maximumPullOnTransformation() //---------------------------------------------------------------- // __IRRefineTranslateCanvasConnectionLock -// -static itk::SimpleMutexLock __IRRefineTranslateCanvasConnectionLock; +// +static std::mutex __IRRefineTranslateCanvasConnectionLock; //---------------------------------------------------------------- // IRRefineTranslateCanvas::findOffsetsThreadEntry -// +// void IRRefineTranslateCanvas::findOffsetsThreadEntry() { @@ -373,7 +373,7 @@ IRRefineTranslateCanvas::findOffsetsThreadEntry() { IRConnection * connection = getConectionToProcess(); if (!connection) break; - + if (connection->findIdealOffset(maxOffset, maxOffsetIsPercent, blackMaskPercent, _doClahe) == 0) { connection->firstTransformation()->addConnection(connection); @@ -385,28 +385,28 @@ IRRefineTranslateCanvas::findOffsetsThreadEntry() //---------------------------------------------------------------- // IRRefineTranslateCanvas::addProcessedConnection -// +// void IRRefineTranslateCanvas::addProcessedConnection(IRConnection* connection) { - __IRRefineTranslateCanvasConnectionLock.Lock(); + __IRRefineTranslateCanvasConnectionLock.lock(); _connectionVector.push_back(connection); - __IRRefineTranslateCanvasConnectionLock.Unlock(); + __IRRefineTranslateCanvasConnectionLock.unlock(); return; } //---------------------------------------------------------------- // IRRefineTranslateCanvas::getConectionToProcess // -// returns NULL if there are no more entries to process -// +// returns nullptr if there are no more entries to process +// IRConnection* IRRefineTranslateCanvas::getConectionToProcess() { double vectorSize = 1; - - __IRRefineTranslateCanvasConnectionLock.Lock(); - IRConnection* connection = NULL; + + __IRRefineTranslateCanvasConnectionLock.lock(); + IRConnection* connection = nullptr; if (_preProcessedConnectionVector.size() > 0) { // by picking out random connection we have less of a chance @@ -416,21 +416,21 @@ IRRefineTranslateCanvas::getConectionToProcess() int element; element = rand() % _preProcessedConnectionVector.size(); connection = _preProcessedConnectionVector[element]; - + _preProcessedConnectionVector[element] = _preProcessedConnectionVector.back(); - + _preProcessedConnectionVector.pop_back(); - + vectorSize = _preProcessedConnectionVector.size(); - + // for now give them in order since the tiles these // are now preloaded and are BIG // connection = _preProcessedConnectionVector.back(); // _preProcessedConnectionVector.pop_back(); } - __IRRefineTranslateCanvasConnectionLock.Unlock(); - + __IRRefineTranslateCanvasConnectionLock.unlock(); + double task_percent = (initialSize - vectorSize) / initialSize; set_minor_progress(task_percent, 0.9); return connection; @@ -438,22 +438,22 @@ IRRefineTranslateCanvas::getConectionToProcess() //---------------------------------------------------------------- // IRRefineTranslateCanvas::setTransformAndNeighborsToGroupID -// +// void IRRefineTranslateCanvas:: setTransformAndNeighborsToGroupID(IRTransform* transform, long groupID) { std::stack transformStack; - + transformStack.push(transform); - + while (!transformStack.empty()) { IRTransform* currentTransform = transformStack.top(); transformStack.pop(); - + currentTransform->setGroupID(groupID); - + IRConnectionVector connections = currentTransform->connections(); for (IRConnectionVector::iterator iter = connections.begin(); iter != connections.end(); ++iter) @@ -463,23 +463,23 @@ setTransformAndNeighborsToGroupID(IRTransform* transform, long groupID) { neighbor = (*iter)->secondTransformation(); } - + if (neighbor->groupID() != groupID) { if (neighbor->groupID() != -1) { printf("Error! why was this groupID aready set!"); } - + transformStack.push(neighbor); } } - } + } } //---------------------------------------------------------------- // IRRefineTranslateCanvas::removeTransformsWithGroupID -// +// void IRRefineTranslateCanvas::removeTransformsWithGroupID(long groupID) { @@ -500,10 +500,10 @@ IRRefineTranslateCanvas::removeTransformsWithGroupID(long groupID) { neighbor = (*connIter)->secondTransformation(); } - + neighbor->removeConnection(*connIter); (*transIter)->removeConnection(*connIter); - + for (size_t i = 0; i < _connectionVector.size(); i++) { if (_connectionVector[i] == *connIter) @@ -513,7 +513,7 @@ IRRefineTranslateCanvas::removeTransformsWithGroupID(long groupID) break; } } - + delete *connIter; } delete *transIter; diff --git a/src/Core/ITKCommon/Transform/itkCascadedTransform.h b/src/Core/ITKCommon/Transform/itkCascadedTransform.h index 98e611e0e..5323f6e1d 100644 --- a/src/Core/ITKCommon/Transform/itkCascadedTransform.h +++ b/src/Core/ITKCommon/Transform/itkCascadedTransform.h @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -51,7 +51,7 @@ //---------------------------------------------------------------- // itk::CascadedTransform -// +// namespace itk { @@ -71,53 +71,53 @@ public ITK_EXPORT Transform * concrete inverse transform type or inheritance would be lost.*/ typedef typename Superclass::InverseTransformBaseType InverseTransformBaseType; typedef typename InverseTransformBaseType::Pointer InverseTransformBasePointer; - + typedef SmartPointer TransformPointer; typedef SmartPointer ConstTransformPointer; - + // RTTI: itkTypeMacro(CascadedTransform, Transform); - + // macro for instantiation through the object factory: itkNewMacro(Self); - + /** Standard scalar type for this class. */ typedef typename Superclass::ScalarType ScalarType; - + /** Dimension of the domain space. */ itkStaticConstMacro(InputSpaceDimension, unsigned int, Dimension); itkStaticConstMacro(OutputSpaceDimension, unsigned int, Dimension); - + // shortcuts: typedef typename Superclass::FixedParametersType FixedParametersType; typedef typename Superclass::FixedParametersValueType FixedParametersValueType; typedef typename Superclass::ParametersType ParametersType; typedef typename Superclass::JacobianType JacobianType; - + typedef typename Superclass::InputPointType PointType; typedef PointType InputPointType; typedef PointType OutputPointType; - + typedef typename Superclass::InputVectorType VectorType; typedef VectorType InputVectorType; typedef VectorType OutputVectorType; - + typedef typename Superclass::InputVnlVectorType VnlVectorType; typedef VnlVectorType InputVnlVectorType; typedef VnlVectorType OutputVnlVectorType; - + typedef typename Superclass::InputCovariantVectorType CovariantVectorType; typedef CovariantVectorType InputCovariantVectorType; typedef CovariantVectorType OutputCovariantVectorType; - + /** The number of parameters defininig this transform. */ typedef typename Superclass::NumberOfParametersType NumberOfParametersType; - + // virtual: virtual PointType TransformPoint(const PointType & x) const override { PointType y = x; - + // apply the transforms: for (unsigned int i = active_start_; i <= active_finish_; i++) { @@ -126,56 +126,56 @@ public ITK_EXPORT Transform { return tx; } - + y = tx; } - + return y; } - + // virtual: virtual VectorType TransformVector(const VectorType & x) const override { VectorType y(x); - + // apply the transforms: for (unsigned int i = active_start_; i <= active_finish_; i++) { y = transform_[i]->TransformVector(y); } - + return y; } - + // virtual: virtual VnlVectorType TransformVector(const VnlVectorType & x) const override { VnlVectorType y(x); - + // apply the transforms: for (unsigned int i = active_start_; i <= active_finish_; i++) { y = transform_[i]->TransformVector(y); } - + return y; } - + // virtual: virtual CovariantVectorType TransformCovariantVector(const CovariantVectorType & x) const override { CovariantVectorType y(x); - + // apply the transforms: for (unsigned int i = active_start_; i < active_finish_; i++) { y = transform_[i]->TransformCovariantVector(y); } - + return y; } - + // Inverse transformations: // If y = Transform(x), then x = BackTransform(y); // if no mapping from y to x exists, then an exception is thrown @@ -184,10 +184,10 @@ public ITK_EXPORT Transform if (! inverse) return false; const unsigned int cascade_length = transform_.size(); - + // Pointer inv = Self::New(); inverse->transform_.resize(cascade_length); - + for (unsigned int i = 0; i < cascade_length; i++) { unsigned int idx = (cascade_length - 1) - i; @@ -206,11 +206,11 @@ public ITK_EXPORT Transform CORE_LOG_DEBUG(oss.str()); } } - + inverse->active_start_ = active_start_; inverse->active_finish_ = active_finish_; inverse->active_params_ = (cascade_length - 1) - active_params_; - + // InverseTransformPointer tmp = inverse.GetPointer(); // return tmp; return true; @@ -225,7 +225,7 @@ public ITK_EXPORT Transform // virtual: virtual void SetParameters(const ParametersType & params) override { transform_[active_params_]->SetParameters(params); } - + virtual void SetFixedParameters(const FixedParametersType &) override { itkExceptionMacro(<< "SetFixedParameters is not implemented for CascadedTransform"); @@ -234,14 +234,18 @@ public ITK_EXPORT Transform // virtual: virtual const ParametersType & GetParameters() const override { return transform_[active_params_]->GetParameters(); } - + // virtual: virtual NumberOfParametersType GetNumberOfParameters() const override { return transform_[active_params_]->GetNumberOfParameters(); } - + // virtual: - virtual const JacobianType & GetJacobian(const PointType & pt) const override - { return transform_[active_params_]->GetJacobian(pt); } + virtual void + ComputeJacobianWithRespectToPosition(const PointType & pt, + JacobianType & jacobian) const override + { + transform_[active_params_]->ComputeJacobianWithRespectToPosition(pt, jacobian); + } virtual void ComputeJacobianWithRespectToParameters(const InputPointType &, JacobianType &) const override { @@ -253,48 +257,48 @@ public ITK_EXPORT Transform { const unsigned int old_sz = transform_.size(); std::vector new_array(old_sz + 1); - + for (unsigned int i = 0; i < old_sz; i++) { new_array[i] = transform_[i]; } - + new_array[old_sz] = transform; transform_ = new_array; active_params_ = transform_.size() - 1; active_finish_ = transform_.size() - 1; } - + // setup a cascaded transform: template void setup(const container_t & transforms, const unsigned int & cascade_length) { transform_.resize(cascade_length); - + for (unsigned int i = 0; i < cascade_length; i++) { transform_[i] = transforms[i]; } - + active_start_ = 0; active_finish_ = cascade_length - 1; active_params_ = active_finish_; } - + // accessor to the individual transforms on the stack: template transform_t * GetTransform(const unsigned int & index) const { return dynamic_cast(transform_[index].GetPointer()); } - + // accessor: inline const std::vector & GetTransforms() const { return transform_; } - + // accessors: inline unsigned int GetParamsIndex() const { return active_params_; } - + inline void SetParamsIndex(const unsigned int & index) { // assert(index < transform_.size()); @@ -309,10 +313,10 @@ public ITK_EXPORT Transform itkExceptionMacro(<< "active parameter index out of bounds"); } } - + inline unsigned int GetActiveIndex() const { return active_finish_; } - + inline void SetActiveIndex(const unsigned int & index) { // assert(index < transform_.size()); @@ -323,7 +327,7 @@ public ITK_EXPORT Transform active_finish_ = index; active_params_ = index; } - + protected: CascadedTransform(): Superclass(/*Dimension,*/0), @@ -332,47 +336,47 @@ public ITK_EXPORT Transform active_start_(0), active_finish_(~0) {} - + // virtual: virtual void PrintSelf(std::ostream & os, Indent indent) const override { Superclass::PrintSelf(os, indent); - + const unsigned int sz = transform_.size(); for (unsigned int i = 0; i < sz; i++) { os << indent << "transform_[" << i << "] = " << transform_[i] << std::endl; } - + os << indent << "active_params_ = " << active_params_ << std::endl << indent << "active_start_ = " << active_start_ << std::endl << indent << "active_finish_ = " << active_finish_ << std::endl; } - + private: // disable default copy constructor and assignment operator: CascadedTransform(const Self & other); const Self & operator = (const Self & t); - + // Cascaded transforms - input is first transformed by the first // transform, followed by the other transforms sequentially. // Only the top-most (last) transform in the array is accessible // for modification, all preciding transforms are fixed. std::vector transform_; - + // This index controls which transform on the stack can be manipulated // via GetParameters/SetParameters function. By default this is // the top transform on the stack, but it may be adjusted to suit // anyones needs: unsigned int active_params_; - + // Transforms which are outside of the [start, finish] range are // completely ignored. This feature is useful whenever it is necessary // to temporarily remove some of the transforms from the cascade: unsigned int active_start_; unsigned int active_finish_; - + }; // class CascadedTransform } // namespace itk diff --git a/src/Core/ITKCommon/Transform/itkGridTransform.h b/src/Core/ITKCommon/Transform/itkGridTransform.h index e460efc2c..e0cf7ca56 100644 --- a/src/Core/ITKCommon/Transform/itkGridTransform.h +++ b/src/Core/ITKCommon/Transform/itkGridTransform.h @@ -35,7 +35,7 @@ // ITK includes: #include -#include +#include #include #include #include diff --git a/src/Core/ITKCommon/Transform/itkInverseTransform.h b/src/Core/ITKCommon/Transform/itkInverseTransform.h index 0ee3d28eb..0b93ce6bf 100644 --- a/src/Core/ITKCommon/Transform/itkInverseTransform.h +++ b/src/Core/ITKCommon/Transform/itkInverseTransform.h @@ -113,8 +113,8 @@ ForwardTransform::InputSpaceDimension > virtual OutputPointType TransformPoint(const InputPointType & y) const override { // TODO: replace with exception -// assert(forward_ != NULL); - if (forward_ == NULL) +// assert(forward_ != nullptr); + if (forward_ == nullptr) { itkExceptionMacro(<< "Forward transform is null"); } diff --git a/src/Core/ITKCommon/Transform/itkLegendrePolynomialTransform.h b/src/Core/ITKCommon/Transform/itkLegendrePolynomialTransform.h index 55f68616d..d9282e9fd 100644 --- a/src/Core/ITKCommon/Transform/itkLegendrePolynomialTransform.h +++ b/src/Core/ITKCommon/Transform/itkLegendrePolynomialTransform.h @@ -42,7 +42,7 @@ // ITK includes: #include -#include +#include #include #include diff --git a/src/Core/ITKCommon/Transform/itkLegendrePolynomialTransform.txx b/src/Core/ITKCommon/Transform/itkLegendrePolynomialTransform.txx index 84c22a106..e98faeee2 100644 --- a/src/Core/ITKCommon/Transform/itkLegendrePolynomialTransform.txx +++ b/src/Core/ITKCommon/Transform/itkLegendrePolynomialTransform.txx @@ -44,7 +44,7 @@ #include // ITK includes: -#include +#include namespace itk diff --git a/src/Core/ITKCommon/Transform/itkMeshTransform.h b/src/Core/ITKCommon/Transform/itkMeshTransform.h index cf17b9e5a..a53c5cf60 100644 --- a/src/Core/ITKCommon/Transform/itkMeshTransform.h +++ b/src/Core/ITKCommon/Transform/itkMeshTransform.h @@ -46,7 +46,7 @@ // ITK includes: #include -#include +#include #include #include #include diff --git a/src/Core/ITKCommon/Transform/itkRBFTransform.h b/src/Core/ITKCommon/Transform/itkRBFTransform.h index 63cc69201..df6eb28d3 100644 --- a/src/Core/ITKCommon/Transform/itkRBFTransform.h +++ b/src/Core/ITKCommon/Transform/itkRBFTransform.h @@ -41,7 +41,7 @@ // ITK includes: #include -#include +#include #include // local includes: diff --git a/src/Core/ITKCommon/Transform/itkRadialDistortionTransform.h b/src/Core/ITKCommon/Transform/itkRadialDistortionTransform.h index c918b95a3..0b9534731 100644 --- a/src/Core/ITKCommon/Transform/itkRadialDistortionTransform.h +++ b/src/Core/ITKCommon/Transform/itkRadialDistortionTransform.h @@ -40,7 +40,7 @@ // ITK includes: #include -#include +#include #include // local includes: diff --git a/src/Core/ITKCommon/common.cxx b/src/Core/ITKCommon/common.cxx index 5e1c82a6a..1d8577726 100644 --- a/src/Core/ITKCommon/common.cxx +++ b/src/Core/ITKCommon/common.cxx @@ -191,7 +191,7 @@ load_transform(std::istream & si, const std::string & transform_type) itk::TransformBase::Pointer t = dynamic_cast(tmp.GetPointer()); - if (t.GetPointer() == NULL) + if (t.GetPointer() == nullptr) { std::ostringstream oss; oss << "could not instantiate " << transform_type << ", giving up ..."; @@ -660,7 +660,7 @@ calc_tile_mosaic_bbox(const base_transform_t * mosaic_to_tile, } base_transform_t::Pointer tile_to_mosaic = mosaic_to_tile->GetInverseTransform(); - if (tile_to_mosaic.GetPointer() == NULL) + if (tile_to_mosaic.GetPointer() == nullptr) { return false; } @@ -800,14 +800,14 @@ find_inverse(const pnt2d_t & tile_min, // tile space const unsigned int pick_up_pace_steps) { // #define DEBUG_FIND_INVERSE - if (tile_to_mosaic == NULL) + if (tile_to_mosaic == nullptr) { return false; } const itk::GridTransform *gridTransform = dynamic_cast(tile_to_mosaic); - if (gridTransform != NULL) + if (gridTransform != nullptr) { // special case for the grid transform -- the inverse is either exact // or it doesn't exist (maps to extreme coordinates): @@ -961,12 +961,12 @@ find_inverse(const base_transform_t * mosaic_to_tile, const unsigned int pick_up_pace_steps) { // #define DEBUG_FIND_INVERSE - if (tile_to_mosaic == NULL) + if (tile_to_mosaic == nullptr) { return false; } - if (dynamic_cast(tile_to_mosaic) != NULL || dynamic_cast(tile_to_mosaic) != NULL) + if (dynamic_cast(tile_to_mosaic) != nullptr || dynamic_cast(tile_to_mosaic) != nullptr) { // special case for the grid transform -- the inverse is either exact // or it doesn't exist (maps to extreme coordinates): @@ -1079,7 +1079,7 @@ generate_landmarks_v1(const pnt2d_t & tile_min, // #define DEBUG_LANDMARKS base_transform_t::Pointer tile_to_mosaic = mosaic_to_tile->GetInverseTransform(); - if (tile_to_mosaic.GetPointer() == NULL) + if (tile_to_mosaic.GetPointer() == nullptr) { return false; } @@ -1289,7 +1289,7 @@ generate_landmarks_v2(const pnt2d_t & tile_min, // #define DEBUG_LANDMARKS base_transform_t::Pointer tile_to_mosaic = mosaic_to_tile->GetInverseTransform(); - if (tile_to_mosaic.GetPointer() == NULL) + if (tile_to_mosaic.GetPointer() == nullptr) { return false; } diff --git a/src/Core/ITKCommon/common.hxx b/src/Core/ITKCommon/common.hxx index e2804757f..fec2d2a38 100644 --- a/src/Core/ITKCommon/common.hxx +++ b/src/Core/ITKCommon/common.hxx @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -101,7 +101,7 @@ #include #include #include -#include +#include #include #include @@ -110,35 +110,35 @@ namespace bfs=boost::filesystem; //---------------------------------------------------------------- // image_size_value_t -// +// typedef itk::Size<2>::SizeValueType image_size_value_t; //---------------------------------------------------------------- // array2d -// +// #define array2d( T ) std::vector > //---------------------------------------------------------------- // mask_t -// +// // 2D image with unsigned char pixel type. -// +// typedef itk::Image mask_t; //---------------------------------------------------------------- // mask_so_t -// +// // Spatial object for mask_t, used to specify a mask to ITK image // filters. -// +// typedef itk::ImageMaskSpatialObject<2> mask_so_t; //---------------------------------------------------------------- // mask_so -// +// // Convenience function for setting up a mask spatial object for // a give mask image. -// +// inline mask_so_t::Pointer mask_so(const mask_t * mask) { @@ -149,28 +149,28 @@ mask_so(const mask_t * mask) //---------------------------------------------------------------- // BREAK -// +// // This is for debugging. Insert a call to BREAK somewhere in // your code, recompile. Then load into a debugger and put a break // point in BREAK. This is to be used in those cases when you know // exactly when you want to hit the breakpoint. -// +// extern int BREAK(unsigned int i); //---------------------------------------------------------------- // native_pixel_t -// +// // Native refers to the usual 8 bit pixels here. These are native // (standard) in the real world, but may look odd in the medical // imaging world where float or short int are more common. -// +// typedef unsigned char native_pixel_t; //---------------------------------------------------------------- // native_image_t // // 8-bit grayscale image. -// +// typedef itk::Image native_image_t; //---------------------------------------------------------------- @@ -178,16 +178,16 @@ typedef itk::Image native_image_t; // // All-encompasing pixel type -- float. // Works everywhere, takes up 4 times as much memory as 8-bit pixels. -// +// typedef float pixel_t; //---------------------------------------------------------------- // std_tile -// +// // Load a mosaic tile image, reset the origin to zero, set pixel // spacing as specified. Downscale the image according to the // shrink factor. -// +// template typename T::Pointer std_tile(const bfs::path& fn_image, @@ -197,44 +197,44 @@ std_tile(const bfs::path& fn_image, //---------------------------------------------------------------- // image_t -// +// // float grayscale image. -// +// typedef itk::Image image_t; //---------------------------------------------------------------- // base_transform_t -// +// // Shorthand for abstract 2D tranforms. -// +// typedef itk::Transform base_transform_t; //---------------------------------------------------------------- // identity_transform_t -// +// // Shorthand for 2D identity ITK transform. -// +// typedef itk::IdentityTransform identity_transform_t; //---------------------------------------------------------------- // translate_transform_t -// +// // Shorthand for 2D rigid translation ITK transform. -// +// typedef itk::TranslationTransform translate_transform_t; //---------------------------------------------------------------- // pnt2d_t -// +// // Shorthand for 2D points. -// +// typedef itk::Point pnt2d_t; //---------------------------------------------------------------- // vec2d_t -// +// // Shorthand for 2D vectors. -// +// typedef itk::Vector vec2d_t; //---------------------------------------------------------------- @@ -242,14 +242,14 @@ typedef itk::Vector vec2d_t; // // Shorthand for 3D points. This is typically used to represent RGB // or HSV colors. -// +// typedef itk::Vector xyz_t; //---------------------------------------------------------------- // xyz // // Constructor function for xyz_t. -// +// inline static xyz_t xyz(const double & r, const double & g, const double & b) { @@ -262,22 +262,22 @@ xyz(const double & r, const double & g, const double & b) //---------------------------------------------------------------- // hsv_to_rgb -// +// // Convenience function for converting between HSV/RGB color // spaces. This is used for colormapping. -// +// inline static xyz_t hsv_to_rgb(const xyz_t & HSV) { double H = HSV[0]; double S = HSV[1]; double V = HSV[2]; - + xyz_t RGB; double & R = RGB[0]; double & G = RGB[1]; double & B = RGB[2]; - + if (S == 0.0) { // monochromatic: @@ -286,15 +286,15 @@ hsv_to_rgb(const xyz_t & HSV) B = V; return RGB; } - + H *= 6.0; double i = floor(H); double f = H - i; - + double p = V * (1.0 - S); double q = V * (1.0 - S * f); double t = V * (1.0 - S * (1 - f)); - + if (i == 0.0) { R = V; @@ -326,60 +326,60 @@ hsv_to_rgb(const xyz_t & HSV) B = V; } else - { + { // i == 5.0 R = V; G = p; B = q; } - + return RGB; } //---------------------------------------------------------------- // rgb_to_hsv -// +// // Convenience function for converting between RGB/HSV color // spaces. This is used for colormapping. -// +// inline static xyz_t rgb_to_hsv(const xyz_t & RGB) { double R = RGB[0]; double G = RGB[1]; double B = RGB[2]; - + xyz_t HSV; double & H = HSV[0]; double & S = HSV[1]; double & V = HSV[2]; - + double min = std::min(R, std::min(G, B)); double max = std::max(R, std::max(G, B)); V = max; - + double delta = max - min; if (max == 0) - { + { S = 0; H = -1; } else { S = delta / max; - + if (delta == 0) { delta = 1; } - + if (R == max) { // between yellow & magenta H = (G - B) / delta; } else if (G == max) - { + { // between cyan & yellow H = (B - R) / delta + 2; } @@ -388,23 +388,23 @@ rgb_to_hsv(const xyz_t & RGB) // between magenta & cyan H = (R - G) / delta + 4; } - + H /= 6.0; - + if (H < 0.0) - { + { H = H + 1.0; } } - + return HSV; } //---------------------------------------------------------------- // pnt2d -// +// // Constructor function for pnt2d_t. -// +// inline static const pnt2d_t pnt2d(const double & x, const double & y) { @@ -416,9 +416,9 @@ pnt2d(const double & x, const double & y) //---------------------------------------------------------------- // vec2d -// +// // Constructor function for vec2d_t. -// +// inline static const vec2d_t vec2d(const double & x, const double & y) { @@ -430,9 +430,9 @@ vec2d(const double & x, const double & y) //---------------------------------------------------------------- // add -// +// // Arithmetics helper function. -// +// inline static const pnt2d_t add(const pnt2d_t & pt, const vec2d_t & vc) { @@ -444,9 +444,9 @@ add(const pnt2d_t & pt, const vec2d_t & vc) //---------------------------------------------------------------- // add -// +// // Arithmetics helper function. -// +// inline static const vec2d_t add(const vec2d_t & a, const vec2d_t & b) { @@ -472,9 +472,9 @@ sub(const pnt2d_t & a, const pnt2d_t & b) //---------------------------------------------------------------- // mul -// +// // Arithmetics helper function. -// +// inline static const vec2d_t mul(const double & s, const vec2d_t & vc) { @@ -486,9 +486,9 @@ mul(const double & s, const vec2d_t & vc) //---------------------------------------------------------------- // neg -// +// // Arithmetics helper function. -// +// inline static const vec2d_t neg(const vec2d_t & v) { @@ -497,18 +497,18 @@ neg(const vec2d_t & v) //---------------------------------------------------------------- // is_empty_bbox -// +// // Test whether a bounding box is empty (min > max) -// +// extern bool is_empty_bbox(const pnt2d_t & min, const pnt2d_t & max); //---------------------------------------------------------------- // is_singular_bbox -// +// // Test whether a bounding box is singular (min == max) -// +// extern bool is_singular_bbox(const pnt2d_t & min, const pnt2d_t & max); @@ -521,15 +521,15 @@ is_singular_bbox(const pnt2d_t & min, // extern bool calc_tile_mosaic_bbox(const base_transform_t * mosaic_to_tile, - + // image space bounding boxes of the tile: const pnt2d_t & tile_min, const pnt2d_t & tile_max, - + // mosaic space bounding boxes of the tile: pnt2d_t & mosaic_min, pnt2d_t & mosaic_max, - + // sample points along the image edges: const unsigned int np = 15); @@ -544,22 +544,22 @@ template bool calc_tile_mosaic_bbox(const base_transform_t * mosaic_to_tile, const T * tile, - + // mosaic space bounding boxes of the tile: pnt2d_t & mosaic_min, pnt2d_t & mosaic_max, - + // sample points along the image edges: const unsigned int np = 15) { typename T::SizeType sz = tile->GetLargestPossibleRegion().GetSize(); typename T::SpacingType sp = tile->GetSpacing(); - + pnt2d_t tile_min = tile->GetOrigin(); pnt2d_t tile_max; tile_max[0] = tile_min[0] + sp[0] * static_cast(sz[0]); tile_max[1] = tile_min[1] + sp[1] * static_cast(sz[1]); - + return calc_tile_mosaic_bbox(mosaic_to_tile, tile_min, tile_max, @@ -589,9 +589,9 @@ calc_image_bbox(const T * image, pnt2d_t & bbox_min, pnt2d_t & bbox_max) //---------------------------------------------------------------- // clamp_bbox -// +// // Restrict a bounding box to be within given limits. -// +// extern void clamp_bbox(const pnt2d_t & confines_min, const pnt2d_t & confines_max, @@ -600,9 +600,9 @@ clamp_bbox(const pnt2d_t & confines_min, //---------------------------------------------------------------- // update_bbox -// +// // Expand the bounding box to include a given point. -// +// inline static void update_bbox(pnt2d_t & min, pnt2d_t & max, const pnt2d_t & pt) { @@ -615,26 +615,26 @@ update_bbox(pnt2d_t & min, pnt2d_t & max, const pnt2d_t & pt) //---------------------------------------------------------------- // suspend_itk_multithreading_t -// +// class suspend_itk_multithreading_t { public: suspend_itk_multithreading_t(): - itk_threads_(itk::MultiThreader::GetGlobalDefaultNumberOfThreads()), - max_threads_(itk::MultiThreader::GetGlobalMaximumNumberOfThreads()) + itk_threads_(itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads()), + max_threads_(itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads()) { // turn off ITK multithreading: - itk::MultiThreader::SetGlobalDefaultNumberOfThreads(1); - itk::MultiThreader::SetGlobalMaximumNumberOfThreads(1); + itk::MultiThreaderBase::SetGlobalDefaultNumberOfThreads(1); + itk::MultiThreaderBase::SetGlobalMaximumNumberOfThreads(1); } - + ~suspend_itk_multithreading_t() { // restore ITK multithreading: - itk::MultiThreader::SetGlobalMaximumNumberOfThreads(max_threads_); - itk::MultiThreader::SetGlobalDefaultNumberOfThreads(itk_threads_); + itk::MultiThreaderBase::SetGlobalMaximumNumberOfThreads(max_threads_); + itk::MultiThreaderBase::SetGlobalDefaultNumberOfThreads(itk_threads_); } - + private: int itk_threads_; int max_threads_; @@ -643,9 +643,9 @@ private: //---------------------------------------------------------------- // cast -// +// // Return a copy of image T0 cast to T1. -// +// template typename T1::Pointer cast(const T0 * a) @@ -653,7 +653,7 @@ cast(const T0 * a) typedef typename itk::CastImageFilter cast_t; typename cast_t::Pointer filter = cast_t::New(); filter->SetInput(a); - + // put a terminator on the filter: WRAP(terminator_t terminator(filter)); filter->Update(); @@ -662,10 +662,10 @@ cast(const T0 * a) //---------------------------------------------------------------- // make_image -// +// // make an image of the requested size, filled with some // value (by default zero): -// +// template typename image_t::Pointer make_image(const typename image_t::RegionType::SizeType & sz, @@ -684,7 +684,7 @@ make_image(const typename image_t::RegionType::SizeType & sz, // // make an image of the requested size, filled with some // value (by default zero): -// +// template typename image_t::Pointer make_image(const unsigned int width, @@ -696,22 +696,22 @@ make_image(const unsigned int width, typename image_t::SizeType sz; sz[0] = width; sz[1] = height; - + typename image_t::Pointer image = make_image(sz, fill_value); typename image_t::SpacingType sp; sp[0] = spacing; sp[1] = spacing; image->SetSpacing(sp); - + return image; } //---------------------------------------------------------------- // make_image -// +// // make an image of the requested size, filled with some // value (by default zero): -// +// template typename image_t::Pointer make_image(const unsigned int width, @@ -729,10 +729,10 @@ make_image(const unsigned int width, //---------------------------------------------------------------- // make_image -// +// // make an image of the requested size, filled with some // value (by default zero): -// +// template typename image_t::Pointer make_image(const typename image_t::SpacingType & sp, @@ -750,10 +750,10 @@ make_image(const typename image_t::SpacingType & sp, //---------------------------------------------------------------- // make_image -// +// // make an image of the requested size, filled with some // value (by default zero): -// +// template typename image_t::Pointer make_image(const typename image_t::PointType & origin, @@ -775,17 +775,17 @@ make_image(const typename image_t::PointType & origin, // add // // image arithmetic -- add two images together: -// +// template typename image_t::Pointer add(const image_t * a, const image_t * b) { typedef typename itk::AddImageFilter sum_t; - + typename sum_t::Pointer sum = sum_t::New(); sum->SetInput1(a); sum->SetInput2(b); - + WRAP(terminator_t terminator(sum)); sum->Update(); return sum->GetOutput(); @@ -795,17 +795,17 @@ add(const image_t * a, const image_t * b) // subtract // // image arithmetic -- subtract two images: c = a - b -// +// template typename image_t::Pointer subtract(const image_t * a, const image_t * b) { typedef typename itk::SubtractImageFilter dif_t; - + typename dif_t::Pointer dif = dif_t::New(); dif->SetInput1(a); dif->SetInput2(b); - + WRAP(terminator_t terminator(dif)); dif->Update(); return dif->GetOutput(); @@ -813,20 +813,20 @@ subtract(const image_t * a, const image_t * b) //---------------------------------------------------------------- // multiply -// +// // image arithmetic -- return an image resulting from // pixel-wise division a/b: -// +// template typename image_t::Pointer multiply(const image_t * a, const image_t * b) { typedef typename itk::MultiplyImageFilter mul_t; - + typename mul_t::Pointer mul = mul_t::New(); mul->SetInput1(a); mul->SetInput2(b); - + WRAP(terminator_t terminator(mul)); mul->Update(); return mul->GetOutput(); @@ -834,20 +834,20 @@ multiply(const image_t * a, const image_t * b) //---------------------------------------------------------------- // divide -// +// // image arithmetic -- return an image resulting from // pixel-wise division a/b: -// +// template typename image_t::Pointer divide(const image_t * a, const mask_t * b) { typedef typename itk::DivideImageFilter div_t; - + typename div_t::Pointer div = div_t::New(); div->SetInput1(a); div->SetInput2(b); - + WRAP(terminator_t terminator(div)); div->Update(); return div->GetOutput(); @@ -855,12 +855,12 @@ divide(const image_t * a, const mask_t * b) //---------------------------------------------------------------- // pixel_in_mask -// +// // Check whether a given pixel falls inside a mask. -// +// // NOTE: the mask is assumed to be at higher resolution // than the image. -// +// template inline static bool pixel_in_mask(const mask_t * mask, @@ -871,86 +871,86 @@ pixel_in_mask(const mask_t * mask, mask_t::IndexType mask_index(index); mask_index[0] *= spacing_scale; mask_index[1] *= spacing_scale; - + if (mask_index[0] >= 0 && mask_index[1] >= 0 && image_size_value_t(mask_index[0]) < mask_size[0] && image_size_value_t(mask_index[1]) < mask_size[1]) { // check the mask: - return (mask == NULL) ? true : (mask->GetPixel(mask_index) != 0); + return (mask == nullptr) ? true : (mask->GetPixel(mask_index) != 0); } - + // pixel falls outside the mask image: return false; } //---------------------------------------------------------------- // pixel_in_mask -// +// // Check whether a given physical point falls inside a mask. -// +// template inline static bool pixel_in_mask(const T * mask, const typename T::PointType & physical_point) { - if (mask == NULL) return true; - + if (mask == nullptr) return true; + typename T::IndexType mask_pixel_index; if (mask->TransformPhysicalPointToIndex(physical_point, mask_pixel_index)) { // let the mask decide: return mask->GetPixel(mask_pixel_index) != 0; } - + // point falls outside the mask image: return false; } //---------------------------------------------------------------- // pixel_in_mask -// +// // Check whether a given pixel falls inside a mask. -// +// template inline static bool pixel_in_mask(const T * image, const itk::Image * mask, const typename T::IndexType & image_pixel_index) { - if (mask == NULL) + if (mask == nullptr) { return true; } - + typename T::PointType physical_point; image->TransformIndexToPhysicalPoint(image_pixel_index, physical_point); - + typedef itk::Image mask_t; return pixel_in_mask(mask, physical_point); } //---------------------------------------------------------------- // image_min_max -// +// // Find min/max pixel values, return mean pixel value (average): -// +// template double image_min_max(const T * a, typename T::PixelType & min, typename T::PixelType & max, - const itk::Image * mask = NULL) + const itk::Image * mask = nullptr) { WRAP(itk_terminator_t terminator("image_min_max")); - + typedef typename T::PixelType pixel_t; typedef typename itk::ImageRegionConstIteratorWithIndex iter_t; - + min = std::numeric_limits::max(); max = -min; - + double mean = 0.0; double counter = 0.0; iter_t iter(a, a->GetLargestPossibleRegion()); @@ -958,20 +958,20 @@ image_min_max(const T * a, { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + if (!pixel_in_mask(a, mask, iter.GetIndex())) { continue; } - + pixel_t v = iter.Get(); min = std::min(min, v); max = std::max(max, v); - + mean += static_cast(v); counter += 1.0; } - + mean /= counter; return mean; } @@ -980,7 +980,7 @@ image_min_max(const T * a, // remap_min_max_inplace // // Rescale image intensities in-place -// +// template bool remap_min_max_inplace(image_t * a, @@ -990,26 +990,26 @@ remap_min_max_inplace(image_t * a, double new_max) { WRAP(itk_terminator_t terminator("remap_min_max_inplace")); - + typedef typename image_t::PixelType pixel_t; typedef typename itk::ImageRegionIterator iter_t; - + // rescale the intensities: double rng = max - min; if (rng == 0.0) return false; - + double new_rng = new_max - new_min; - + iter_t iter(a, a->GetLargestPossibleRegion()); for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + double t = (iter.Get() - min) / rng; iter.Set(pixel_t(new_min + t * new_rng)); } - + return true; } @@ -1017,7 +1017,7 @@ remap_min_max_inplace(image_t * a, // remap_min_max_inplace // // Rescale image intensities in-place -// +// template bool remap_min_max_inplace(image_t * a, @@ -1025,24 +1025,24 @@ remap_min_max_inplace(image_t * a, typename image_t::PixelType new_max = 255) { WRAP(itk_terminator_t terminator("remap_min_max_inplace")); - + typedef typename image_t::PixelType pixel_t; typedef typename itk::ImageRegionIterator iter_t; - + double min = std::numeric_limits::max(); double max = -min; - + iter_t iter(a, a->GetLargestPossibleRegion()); for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + double v = iter.Get(); min = std::min(min, v); max = std::max(max, v); } - + return remap_min_max_inplace(a, min, max, new_min, new_max); } @@ -1050,7 +1050,7 @@ remap_min_max_inplace(image_t * a, // remap_min_max // // Return a copy of the image with rescaled pixel intensities -// +// template typename T::Pointer remap_min_max(const T * a, @@ -1058,30 +1058,30 @@ remap_min_max(const T * a, typename T::PixelType new_max = 255) { WRAP(itk_terminator_t terminator("remap_min_max")); - + typedef typename T::RegionType rn_t; typedef typename T::SizeType sz_t; rn_t rn = a->GetLargestPossibleRegion(); sz_t sz = rn.GetSize(); - + typename T::Pointer b = T::New(); b->SetRegions(sz); b->SetSpacing(a->GetSpacing()); b->Allocate(); - + double min = std::numeric_limits::max(); double max = -min; - + typename T::IndexType ix_end; ix_end[0] = sz[0]; ix_end[1] = sz[1]; - + typename T::IndexType ix; for (ix[1] = 0; ix[1] < ix_end[1]; ++ix[1]) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + for (ix[0] = 0; ix[0] < ix_end[0]; ++ix[0]) { double v = a->GetPixel(ix); @@ -1089,7 +1089,7 @@ remap_min_max(const T * a, max = std::max(max, v); } } - + // rescale the intensities: double rng = max - min; if (rng == 0.0) @@ -1097,14 +1097,14 @@ remap_min_max(const T * a, b->FillBuffer(itk::NumericTraits::Zero); return b; } - + double new_rng = new_max - new_min; - + for (ix[1] = 0; ix[1] < ix_end[1]; ++ix[1]) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + for (ix[0] = 0; ix[0] < ix_end[0]; ++ix[0]) { double v = a->GetPixel(ix); @@ -1112,7 +1112,7 @@ remap_min_max(const T * a, b->SetPixel(ix, typename T::PixelType(new_min + t * new_rng)); } } - + return b; } @@ -1120,43 +1120,43 @@ remap_min_max(const T * a, // invert // // Invert pixel intensities in-place. -// +// template void invert(typename T::Pointer & a) { WRAP(itk_terminator_t terminator("invert")); - + typedef typename T::PixelType pixel_t; typedef typename itk::ImageRegionIterator iter_t; - + pixel_t min = std::numeric_limits::max(); pixel_t max = -min; - + iter_t iter(a, a->GetLargestPossibleRegion()); for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + pixel_t v = iter.Get(); min = std::min(min, v); max = std::max(max, v); } - + pixel_t rng = max - min; if (rng == pixel_t(0)) return; - + // rescale the value: pixel_t new_min = max; pixel_t new_max = min; pixel_t new_rng = new_max - new_min; - + for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + pixel_t t = (iter.Get() - min) / rng; iter.Set(new_min + t * new_rng); } @@ -1167,7 +1167,7 @@ invert(typename T::Pointer & a) // // Return a copy of the image with pixels above and below // a given threshold remapped to new values. -// +// template typename T::Pointer threshold(const T * a, @@ -1177,35 +1177,35 @@ threshold(const T * a, typename T::PixelType new_max) { WRAP(itk_terminator_t terminator("threshold")); - + typename T::RegionType::SizeType sz = a->GetLargestPossibleRegion().GetSize(); typename T::Pointer b = T::New(); b->SetRegions(sz); b->SetSpacing(a->GetSpacing()); b->Allocate(); - + typedef typename itk::ImageRegionConstIteratorWithIndex itex_t; itex_t itex(a, sz); for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + typename T::PixelType v = itex.Get(); if (v < min) v = new_min; else if (v > max) v = new_max; - + b->SetPixel(itex.GetIndex(), v); } - + return b; } //---------------------------------------------------------------- // clip_min_max -// +// // Clip the pixel intensities to the specified min/max limits. -// +// template typename T::Pointer clip_min_max(const T * a, @@ -1215,9 +1215,9 @@ clip_min_max(const T * a, //---------------------------------------------------------------- // calc_padding -// +// // Given two 2D images, return the pixel bounding box encompasing both. -// +// template typename T::SizeType calc_padding(const T * a, const T * b) @@ -1225,22 +1225,22 @@ calc_padding(const T * a, const T * b) typedef typename T::SizeType sz_t; sz_t sa = a->GetLargestPossibleRegion().GetSize(); const sz_t sb = b->GetLargestPossibleRegion().GetSize(); - + const unsigned int d = T::GetImageDimension(); for (unsigned int i = 0; i < d; i++) { sa[i] = std::max(sa[i], sb[i]); } - + return sa; } //---------------------------------------------------------------- // pad -// +// // Pad an image to a given size (in pixels), return the padded image. // The image is padded with zeros. -// +// template typename T::Pointer pad(const T * a, @@ -1250,14 +1250,14 @@ pad(const T * a, typedef typename T::SizeType sz_t; rn_t r = a->GetLargestPossibleRegion(); sz_t z = r.GetSize(); - + WRAP(itk_terminator_t terminator("pad")); - + typename T::Pointer b = T::New(); b->SetRegions(size); b->SetSpacing(a->GetSpacing()); b->Allocate(); - + typename T::PixelType zero = itk::NumericTraits::Zero; typename T::IndexType ix; for (ix[1] = 0; (image_size_value_t)(ix[1]) < z[1]; ++ix[1]) @@ -1266,13 +1266,13 @@ pad(const T * a, { b->SetPixel(ix, a->GetPixel(ix)); } - + for (ix[0] = z[0]; (image_size_value_t)(ix[0]) < size[0]; ++ix[0]) { b->SetPixel(ix, zero); } } - + for (ix[1] = z[1]; (image_size_value_t)(ix[1]) < size[1]; ++ix[1]) { for (ix[0] = 0; (image_size_value_t)(ix[0]) < size[0]; ++ix[0]) @@ -1280,15 +1280,15 @@ pad(const T * a, b->SetPixel(ix, zero); } } - + return b; } //---------------------------------------------------------------- // crop -// +// // Return a copy of the cropped image region -// +// template typename T::Pointer crop(const T * image, @@ -1297,7 +1297,7 @@ crop(const T * image, { WRAP(itk_terminator_t terminator("crop")); typedef typename T::RegionType::SizeType sz_t; - + sz_t img_sz = image->GetLargestPossibleRegion().GetSize(); sz_t reg_sz; const unsigned int d = T::GetImageDimension(); @@ -1306,30 +1306,30 @@ crop(const T * image, reg_sz[i] = std::min(static_cast(max[i] - min[i] + 1), static_cast(img_sz[i] - min[i])); } - + typename T::RegionType region; region.SetIndex(min); region.SetSize(reg_sz); - + typename T::Pointer out = make_image(reg_sz); - + typedef itk::ImageRegionIteratorWithIndex itex_t; itex_t itex(out, out->GetLargestPossibleRegion()); for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + typename T::IndexType ix1 = itex.GetIndex(); typename T::IndexType ix0; for (unsigned int i = 0; i < d; i++) { ix0[i] = ix1[i] + min[i]; } - + out->SetPixel(ix1, image->GetPixel(ix0)); } - + // FIXME: do I really want this? { typename T::PointType origin; @@ -1337,15 +1337,15 @@ crop(const T * image, out->SetOrigin(origin); } out->SetSpacing(image->GetSpacing()); - + return out; } //---------------------------------------------------------------- // smooth -// +// // Return a copy of the image smothed with a Gaussian kernel. -// +// template typename T::Pointer smooth(const T * in, @@ -1354,14 +1354,14 @@ smooth(const T * in, { typedef typename itk::DiscreteGaussianImageFilter smoother_t; typename smoother_t::Pointer smoother = smoother_t::New(); - + // FIXME: itk::SimpleFilterWatcher w(smoother.GetPointer(), "smoother"); - + smoother->SetInput(in); smoother->SetUseImageSpacing(false); smoother->SetVariance(sigma * sigma); smoother->SetMaximumError(maximum_error); - + WRAP(terminator_t terminator(smoother)); smoother->Update(); return smoother->GetOutput(); @@ -1369,9 +1369,9 @@ smooth(const T * in, //---------------------------------------------------------------- // shrink -// +// // Return a scaled down copy of the image. -// +// template typename T::Pointer shrink(const T * in, @@ -1382,22 +1382,22 @@ shrink(const T * in, // Create caster, smoother and shrinker filters typedef itk::Image flt_img_t; typename flt_img_t::Pointer image = cast(in); - + if (antialias) { double variance = static_cast(shrink_factor) / 2.0; double sigma = sqrt(variance); image = ::smooth(image, sigma, maximum_error); } - + typedef itk::ShrinkImageFilter shrinker_t; typename shrinker_t::Pointer shrinker = shrinker_t::New(); - + // FIXME: itk::SimpleFilterWatcher w(shrinker.GetPointer(), "shrinker"); - + shrinker->SetInput(image); shrinker->SetShrinkFactors(shrink_factor); - + WRAP(terminator_t terminator(shrinker)); shrinker->Update(); image = shrinker->GetOutput(); @@ -1406,32 +1406,32 @@ shrink(const T * in, //---------------------------------------------------------------- // load -// +// // Convenience functions for loading an ITK image. -// +// template typename T::Pointer load(const bfs::path& filename, bool blab = false) { typedef typename itk::ImageFileReader reader_t; typename reader_t::Pointer reader = reader_t::New(); - + // FIXME: itk::SimpleFilterWatcher w(reader.GetPointer(), "reader"); - + reader->SetFileName(filename.string().c_str()); //if (blab) std::cout << "loading " << filename.string() << std::endl; - + // WRAP(terminator_t terminator(reader)); - + reader->Update(); return reader->GetOutput(); } //---------------------------------------------------------------- // save -// +// // Convenience functions for saving an ITK image. -// +// template void save(const T * image, const bfs::path & filename, bool blab = false) @@ -1439,7 +1439,7 @@ save(const T * image, const bfs::path & filename, bool blab = false) typedef typename itk::ImageFileWriter writer_t; typename writer_t::Pointer writer = writer_t::New(); writer->SetInput(image); - + //if (blab) std::cout << "saving " << filename << std::endl; writer->SetFileName(filename.string().c_str()); writer->Update(); @@ -1447,91 +1447,91 @@ save(const T * image, const bfs::path & filename, bool blab = false) //---------------------------------------------------------------- // save_image_tile -// +// // Convenience functions for saving out a section of an ITK image. -// +// template void -save_image_tile(T * image, - const bfs::path & filename, - const unsigned int x, - const unsigned int y, - const unsigned int source_width, - const unsigned int source_height, - const unsigned int tile_width, +save_image_tile(T * image, + const bfs::path & filename, + const unsigned int x, + const unsigned int y, + const unsigned int source_width, + const unsigned int source_height, + const unsigned int tile_width, const unsigned int tile_height, bool blab = false) { typename itk::PasteImageFilter::Pointer pasteImageFilter = itk::PasteImageFilter::New(); - + pasteImageFilter->SetSourceImage( image ); - + typename T::RegionType mosaicRegion = image->GetBufferedRegion(); typename T::SizeType mosaicSize = mosaicRegion.GetSize(); - + // Setup the region we're interested in pasting to a new image. typename T::IndexType sourceIndex; sourceIndex[0] = x; sourceIndex[1] = y; - + typename T::SizeType sourceSize; sourceSize[0] = source_width; sourceSize[1] = source_height; - + typename T::RegionType sourceRegion; sourceRegion.SetIndex( sourceIndex ); sourceRegion.SetSize( sourceSize ); pasteImageFilter->SetSourceRegion( sourceRegion ); - + // Create a new image to paste the section onto. typename T::Pointer destImage = T::New(); pasteImageFilter->SetDestinationImage( destImage ); - + typename T::IndexType destIndex; destIndex[0] = 0; destIndex[1] = 0; - + typename T::SizeType destSize; destSize[0] = tile_width; destSize[1] = tile_height; - + typename T::RegionType sectionRegion; sectionRegion.SetIndex( destIndex ); sectionRegion.SetSize( destSize ); destImage->SetRegions( sectionRegion ); destImage->Allocate(); destImage->FillBuffer(0); - + pasteImageFilter->SetDestinationIndex( destIndex ); - + typename T::Pointer partialImage = pasteImageFilter->GetOutput(); - + typedef typename itk::ImageFileWriter writer_t; typename writer_t::Pointer writer = writer_t::New(); writer->SetInput(partialImage); - + //if (blab) //{ // std::cout << "saving " << filename << std::endl; //} - + writer->SetFileName(filename.string().c_str()); writer->Update(); } //---------------------------------------------------------------- // save_as_tiles -// +// // Convenience functions for saving out series of tiles as ITK images. Also // writes out an xml file explaining the position of these files. -// +// template bool -save_as_tiles(T * image, - const bfs::path & prefix, - const bfs::path & extension, - unsigned int w, +save_as_tiles(T * image, + const bfs::path & prefix, + const bfs::path & extension, + unsigned int w, unsigned int h, const double downsample, bool save_image = true, @@ -1544,28 +1544,28 @@ save_as_tiles(T * image, bfs::path xmlFileName(prefix); xmlFileName.replace_extension("xml"); std::ofstream xmlOut(xmlFileName.string().c_str()); - - if (! xmlOut.is_open()) + + if (! xmlOut.is_open()) { std::cout << "Error opening xml file for writing: " << xmlFileName << std::endl; return false; } - + typename T::RegionType mosaicRegion = image->GetBufferedRegion(); typename T::SizeType mosaicSize = mosaicRegion.GetSize(); if (w == std::numeric_limits::max()) { w = mosaicSize[0]; } - + if (h == std::numeric_limits::max()) { h = mosaicSize[1]; } - + unsigned int numTilesWide = (mosaicSize[0] + (w - 1)) / w; unsigned int numTilesTall = (mosaicSize[1] + (h - 1)) / h; - + // extract just the name portion // size_t num_forward = fileName.contains('/'); // size_t num_backward = fileName.contains('\\'); @@ -1573,7 +1573,7 @@ save_as_tiles(T * image, // the_text_t name_part = fileName.reverse().cut(slash, 0, 0).reverse() + "_"; // bfs::path name_part = fileName.stem() + "_"; std::string name_part(prefix.stem().string() + "_"); - + xmlOut << "" << std::endl; xmlOut << "" << std::endl; - + for (unsigned int x = 0, xid = 0; x < mosaicSize[0]; x += w, xid++) { for (unsigned int y = 0, yid = 0; y < mosaicSize[1]; y += h, yid++) @@ -1595,7 +1595,7 @@ save_as_tiles(T * image, fn_partialSave += "_Y"; fn_partialSave += the_text_t::number(yid, 3, '0'); fn_partialSave += extension; - + unsigned int sectionWidth = std::min(w, mosaicSize[0] - x); unsigned int sectionHeight = std::min(h, mosaicSize[1] - y); if ( save_image ) @@ -1611,22 +1611,22 @@ save_as_tiles(T * image, } } } - + xmlOut.close(); return true; } //---------------------------------------------------------------- // save_tile_xml -// +// // Exports the same xml file as save_as_tiles. But without actually // saving the tiles out. -// +// template bool -save_tile_xml(const bfs::path & prefix, - const bfs::path & extension, - unsigned int w, +save_tile_xml(const bfs::path & prefix, + const bfs::path & extension, + unsigned int w, unsigned int h, unsigned int full_width, unsigned int full_height, @@ -1641,33 +1641,33 @@ save_tile_xml(const bfs::path & prefix, bfs::path xmlFileName(prefix); xmlFileName.replace_extension("xml"); std::ofstream xmlOut(xmlFileName.c_str()); - - if (!xmlOut.is_open()) + + if (!xmlOut.is_open()) { std::cout << "Error opening xml file for writing: " << xmlFileName << std::endl; return false; } - + if (w == std::numeric_limits::max()) { w = full_width; } - + if (h == std::numeric_limits::max()) { h = full_height; } - + unsigned int numTilesWide = (full_width + (w - 1)) / w; unsigned int numTilesTall = (full_height + (h - 1)) / h; - + // extract just the name portion // size_t num_forward = fileName.contains('/'); // size_t num_backward = fileName.contains('\\'); // char slash = ( num_forward > num_backward ) ? '/' : '\\'; // the_text_t name_part = fileName.reverse().cut(slash, 0, 0).reverse() + "_"; std::string name_part(prefix.stem().string() + "_"); - + xmlOut << "" << std::endl; xmlOut << "" << std::endl; - + for (unsigned int x = 0, xid = 0; x < full_width; x += w, xid++) { for (unsigned int y = 0, yid = 0; y < full_height; y += h, yid++) @@ -1691,17 +1691,17 @@ save_tile_xml(const bfs::path & prefix, fn_partialSave += extension; } } - + xmlOut.close(); return true; } //---------------------------------------------------------------- // calc_area -// +// // Calculate the area covered by a given number of pixels // at the specified pixels spacing. -// +// inline double calc_area(const itk::Vector & spacing, const unsigned long int pixels) @@ -1713,36 +1713,36 @@ calc_area(const itk::Vector & spacing, //---------------------------------------------------------------- // calc_area -// +// // Calculate image area under the mask. -// +// template double calc_area(const T * image, const mask_t * mask) { WRAP(itk_terminator_t terminator("calc_area")); unsigned long int pixels = 0; - + typedef itk::ImageRegionConstIteratorWithIndex itex_t; itex_t itex(image, image->GetLargestPossibleRegion()); - + for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + if (pixel_in_mask(image, mask, itex.GetIndex())) { pixels++; } } - + return calc_area(image->GetSpacing(), pixels); } //---------------------------------------------------------------- // get_area -// +// template double get_area(const T * image) @@ -1755,25 +1755,25 @@ get_area(const T * image) //---------------------------------------------------------------- // eval_metric -// +// // A wrapper function for evaluating an image registration metric for // two images (one fixed, one moving) in the overlap region defined // by the fixed image to moving image transform and image masks. -// +// template double eval_metric(const base_transform_t * fi_to_mi, const typename metric_t::FixedImageType * fi, const typename metric_t::MovingImageType * mi, - const mask_t * fi_mask = NULL, - const mask_t * mi_mask = NULL) + const mask_t * fi_mask = nullptr, + const mask_t * mi_mask = nullptr) { typename metric_t::Pointer metric = metric_t::New(); metric->SetFixedImage(fi); metric->SetMovingImage(mi); metric->SetTransform(const_cast(fi_to_mi)); metric->SetInterpolator(interpolator_t::New()); - + // Instead of iterating over the whole fixed image, find the // bounding box of the overlapping region of the fixed and // moving images, clip it to the fixed image bounding box, and iterate @@ -1781,7 +1781,7 @@ eval_metric(const base_transform_t * fi_to_mi, // where the fixed image is large and the moving image is small: typedef typename metric_t::FixedImageType fi_image_t; typename fi_image_t::RegionType fi_roi = fi->GetLargestPossibleRegion(); - + // find the bounding box of the moving image in the space of the fixed image: pnt2d_t mi_min; pnt2d_t mi_max; @@ -1795,10 +1795,10 @@ eval_metric(const base_transform_t * fi_to_mi, pnt2d_t fi_min; pnt2d_t fi_max; calc_image_bbox(fi, fi_min, fi_max); - + // clip the bounding box to the bounding box of the fixed image: clamp_bbox(fi_min, fi_max, mi_min, mi_max); - + // reset the region of interest: typename fi_image_t::IndexType roi_index[2]; if (fi->TransformPhysicalPointToIndex(mi_min, roi_index[0]) && @@ -1811,21 +1811,21 @@ eval_metric(const base_transform_t * fi_to_mi, fi_roi.SetSize(roi_size); } } - + metric->SetFixedImageRegion(fi_roi); - - if (fi_mask != NULL) + + if (fi_mask != nullptr) { metric->SetFixedImageMask(mask_so(fi_mask)); } - - if (mi_mask != NULL) + + if (mi_mask != nullptr) { metric->SetMovingImageMask(mask_so(mi_mask)); } - + metric->Initialize(); - + double measure; try { @@ -1838,27 +1838,27 @@ eval_metric(const base_transform_t * fi_to_mi, CORE_LOG_WARNING(oss.str()); measure = std::numeric_limits::max(); } - + return measure; } //---------------------------------------------------------------- // my_metric -// +// // Calculate a normalized cross correlation metric between two // masked images, calculate the area of overlap. -// +// template double my_metric(double & area, - + const TImage * fi, const TImage * mi, - + const base_transform_t * fi_to_mi, const mask_t * fi_mask, const mask_t * mi_mask, - + const TInterpolator * mi_interpolator) { WRAP(itk_terminator_t terminator("my_metric")); @@ -1866,14 +1866,14 @@ my_metric(double & area, typedef typename TImage::IndexType index_t; typedef typename TImage::PointType point_t; typedef typename TImage::PixelType pixel_t; - + // Instead of iterating over the whole fixed image, find the // bounding box of the overlapping region of the fixed and // moving images, clip it to the fixed image bounding box, and iterate // over that -- this will produce a dramatic speedup in situations // where the fixed image is large and the moving image is small: typename TImage::RegionType fi_roi = fi->GetLargestPossibleRegion(); - + // find the bounding box of the moving image in the space of the fixed image: pnt2d_t mi_min; pnt2d_t mi_max; @@ -1887,14 +1887,14 @@ my_metric(double & area, pnt2d_t fi_min; pnt2d_t fi_max; calc_image_bbox(fi, fi_min, fi_max); - + // clip the bounding box to the bounding box of the fixed image: clamp_bbox(fi_min, fi_max, mi_min, mi_max); if (is_singular_bbox(mi_min, mi_max)) { return std::numeric_limits::max(); } - + // reset the region of interest: index_t roi_index[2]; if (fi->TransformPhysicalPointToIndex(mi_min, roi_index[0]) && @@ -1907,7 +1907,7 @@ my_metric(double & area, fi_roi.SetSize(roi_size); } } - + // performance shortcuts: mask_t::SizeType fi_mask_size = fi->GetLargestPossibleRegion().GetSize(); unsigned int fi_spacing_scale = 1; @@ -1917,7 +1917,7 @@ my_metric(double & area, fi_spacing_scale = sz[0] / fi_mask_size[0]; fi_mask_size = sz; } - + // counters: double ab = 0.0; double aa = 0.0; @@ -1925,7 +1925,7 @@ my_metric(double & area, double sa = 0.0; double sb = 0.0; unsigned long int pixels = 0; - + // iterate over the image: itex_t itex(fi, fi_roi); index_t fi_ix; @@ -1933,7 +1933,7 @@ my_metric(double & area, { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + fi_ix = itex.GetIndex(); if (fi_mask && !pixel_in_mask(fi_mask, fi_mask_size, @@ -1942,76 +1942,76 @@ my_metric(double & area, { continue; } - + // point coordinates in the fixed image: point_t xy; fi->TransformIndexToPhysicalPoint(fi_ix, xy); - + // corresponding coordinates in the moving image: const point_t uv = fi_to_mi->TransformPoint(xy); - + // check whether the point is within the moving image: if (!pixel_in_mask(mi_mask, uv) || !mi_interpolator->IsInsideBuffer(uv)) { continue; } - + pixel_t m = pixel_t(mi_interpolator->Evaluate(uv)); pixel_t f = itex.Get(); - + double A = f; double B = m; - + ab += A * B; aa += A * A; bb += B * B; sa += A; sb += B; - + pixels++; } - + area = calc_area(fi->GetSpacing(), pixels); if (area == 0) { return std::numeric_limits::max(); } - + aa = aa - ((sa * sa) / static_cast(pixels)); bb = bb - ((sb * sb) / static_cast(pixels)); ab = ab - ((sa * sb) / static_cast(pixels)); - + double result = -ab / sqrt(aa * bb); return result; } //---------------------------------------------------------------- // my_metric -// +// // Calculate the normalized cross correlation metric between two // masked images and the ratio of area of overlap to the area of the // smaller image. The metric is restricted by the min/max overlap // ratio thresholds. -// +// template double my_metric(double & overlap, const TImage * fi, const TImage * mi, const base_transform_t * fi_to_mi, - const mask_t * fi_mask = NULL, - const mask_t * mi_mask = NULL, + const mask_t * fi_mask = nullptr, + const mask_t * mi_mask = nullptr, const double min_overlap = 0.05, const double max_overlap = 1.0) { overlap = 0; - + typedef itk::NearestNeighborInterpolateImageFunction interpolator_t; typename interpolator_t::Pointer mi_interpolator = interpolator_t::New(); mi_interpolator->SetInputImage(mi); - + double overlap_area = 0; double m = my_metric(overlap_area, fi, @@ -2032,34 +2032,34 @@ my_metric(double & overlap, double area_a = get_area(fi); double area_b = get_area(mi); //#endif - + double smaller_area = std::min(area_a, area_b); overlap = overlap_area / smaller_area; - + if (overlap < min_overlap || overlap > max_overlap) { return std::numeric_limits::max(); } } - + return m; } //---------------------------------------------------------------- // my_metric -// +// // Calculate the normalized cross correlation metric between two // masked images and the ratio of area of overlap to the area of the // smaller image. The metric is restricted by the min/max overlap // ratio thresholds. -// +// template double my_metric(const TImage * fi, const TImage * mi, const base_transform_t * fi_to_mi, - const mask_t * fi_mask = NULL, - const mask_t * mi_mask = NULL, + const mask_t * fi_mask = nullptr, + const mask_t * mi_mask = nullptr, const double min_overlap = 0.0, const double max_overlap = 1.0) { @@ -2076,10 +2076,10 @@ my_metric(const TImage * fi, //---------------------------------------------------------------- // calc_image_bbox -// +// // Calculate the bounding box for a given image, // expressed in image space. -// +// //template //void //calc_image_bbox(const T * image, pnt2d_t & bbox_min, pnt2d_t & bbox_max) @@ -2093,14 +2093,14 @@ my_metric(const TImage * fi, //---------------------------------------------------------------- // calc_image_bboxes -// +// // Calculate the bounding boxes for a set of given images, // expressed in image space. -// +// template void calc_image_bboxes(const std::vector & image, - + // image space bounding boxes (for feathering): std::vector & image_min, std::vector & image_max) @@ -2108,11 +2108,11 @@ calc_image_bboxes(const std::vector & image, typedef typename image_pointer_t::ObjectType::Pointer::ObjectType T; //typedef typename T::RegionType::SizeType imagesz_t; //typedef typename T::SpacingType spacing_t; - + const unsigned int num_images = image.size(); image_min.resize(num_images); image_max.resize(num_images); - + // calculate the bounding boxes: for (unsigned int i = 0; i < num_images; i++) { @@ -2121,10 +2121,10 @@ calc_image_bboxes(const std::vector & image, image_min[i][1] = image_min[i][0]; image_max[i][0] = -image_min[i][0]; image_max[i][1] = -image_min[i][0]; - + // it happens: - if (image[i].GetPointer() == NULL) continue; - + if (image[i].GetPointer() == nullptr) continue; + // bounding box in the image space: calc_image_bbox(image[i], image_min[i], image_max[i]); } @@ -2132,30 +2132,30 @@ calc_image_bboxes(const std::vector & image, //---------------------------------------------------------------- // calc_image_bboxes_load_images -// +// // Calculate the bounding boxes for a set of images, // expressed in image space. These must be loaded, and are loaded // one by one to save memory on large images. -// +// template void calc_image_bboxes_load_images(const std::list & in, - + // image space bounding boxes (for feathering): std::vector & image_min, std::vector & image_max, - + const unsigned int shrink_factor, const double pixel_spacing) { typedef typename image_pointer_t::ObjectType::Pointer::ObjectType T; //typedef typename T::RegionType::SizeType imagesz_t; //typedef typename T::SpacingType spacing_t; - + const unsigned int num_images = in.size(); image_min.resize(num_images); image_max.resize(num_images); - + // calculate the bounding boxes: unsigned int i = 0; for (std::list::const_iterator iter = in.begin(); @@ -2166,72 +2166,72 @@ calc_image_bboxes_load_images(const std::list & in, image_min[i][1] = image_min[i][0]; image_max[i][0] = -image_min[i][0]; image_max[i][1] = -image_min[i][0]; - + // Read in just the OutputInformation for speed. typedef typename itk::ImageFileReader reader_t; typename reader_t::Pointer reader = reader_t::New(); - + reader->SetFileName((*iter).string().c_str()); //std::cout << "loading region from " << (*iter) << std::endl; - + WRAP(terminator_t terminator(reader)); - + // Load up the OutputInformation, faster than the whole image reader->UpdateOutputInformation(); typename T::Pointer image = reader->GetOutput(); - + // bounding box in the image space: calc_image_bbox(image, image_min[i], image_max[i]); - + // Unload the image. - image = image_t::Pointer(NULL); + image = image_t::Pointer(nullptr); } } //---------------------------------------------------------------- // calc_tile_mosaic_bbox -// +// // Calculate the warped image bounding box in the mosaic space. -// +// //extern bool //calc_tile_mosaic_bbox(const base_transform_t * mosaic_to_tile, -// +// // // image space bounding boxes of the tile: // const pnt2d_t & tile_min, // const pnt2d_t & tile_max, -// +// // // mosaic space bounding boxes of the tile: // pnt2d_t & mosaic_min, // pnt2d_t & mosaic_max, -// +// // // sample points along the image edges: // const unsigned int np = 15); //---------------------------------------------------------------- // calc_tile_mosaic_bbox -// +// // Calculate the warped image bounding box in the mosaic space. -// +// //template //bool //calc_tile_mosaic_bbox(const base_transform_t * mosaic_to_tile, // const T * tile, -// +// // // mosaic space bounding boxes of the tile: // pnt2d_t & mosaic_min, // pnt2d_t & mosaic_max, -// +// // // sample points along the image edges: // const unsigned int np = 15) //{ // typename T::SizeType sz = tile->GetLargestPossibleRegion().GetSize(); // typename T::SpacingType sp = tile->GetSpacing(); -// +// // pnt2d_t tile_min = tile->GetOrigin(); // pnt2d_t tile_max; // tile_max[0] = tile_min[0] + sp[0] * static_cast(sz[0]); // tile_max[1] = tile_min[1] + sp[1] * static_cast(sz[1]); -// +// // return calc_tile_mosaic_bbox(mosaic_to_tile, // tile_min, // tile_max, @@ -2242,31 +2242,31 @@ calc_image_bboxes_load_images(const std::list & in, //---------------------------------------------------------------- // calc_mosaic_bboxes -// +// // Calculate the warped image bounding boxes in the mosaic space. -// +// template bool calc_mosaic_bboxes(const std::vector & xform, - + // image space bounding boxes of mosaic tiles:: const std::vector & image_min, const std::vector & image_max, - + // mosaic space bounding boxes of individual tiles: std::vector & mosaic_min, std::vector & mosaic_max, - + // sample points along the image edges: const unsigned int np = 15) { const unsigned int num_images = xform.size(); mosaic_min.resize(num_images); mosaic_max.resize(num_images); - + point_t image_point; point_t mosaic_point; - + // calculate the bounding boxes bool ok = true; for (unsigned int i = 0; i < num_images; i++) @@ -2278,23 +2278,23 @@ calc_mosaic_bboxes(const std::vector & xform, mosaic_max[i], np); } - + return ok; } //---------------------------------------------------------------- // calc_mosaic_bbox -// +// // Calculate the mosaic bounding box (a union of mosaic space // bounding boxes of the warped tiles). -// +// template void calc_mosaic_bbox(// mosaic space bounding boxes of individual mosaic tiles: const std::vector & mosaic_min, const std::vector & mosaic_max, - + // mosiac bounding box: point_t & min, point_t & max) @@ -2304,14 +2304,14 @@ calc_mosaic_bbox(// mosaic space bounding boxes of individual mosaic tiles: min[1] = min[0]; max[0] = -min[0]; max[1] = -min[0]; - + // calculate the bounding box: const unsigned int num_images = mosaic_min.size(); for (unsigned int i = 0; i < num_images; i++) { // it happens: if (mosaic_min[i][0] == std::numeric_limits::max()) continue; - + // update the mosaic bounding box: update_bbox(min, max, mosaic_min[i]); update_bbox(min, max, mosaic_max[i]); @@ -2320,34 +2320,34 @@ calc_mosaic_bbox(// mosaic space bounding boxes of individual mosaic tiles: //---------------------------------------------------------------- // calc_mosaic_bbox -// +// // Calculate the mosaic bounding box (a union of mosaic space // bounding boxes of the warped tiles). -// +// template void calc_mosaic_bbox(const std::vector & transform, const std::vector & image, - + // mosaic bounding box: typename image_pointer_t::ObjectType::PointType & min, typename image_pointer_t::ObjectType::PointType & max, - + // points along the image edges: const unsigned int np = 15) { typedef typename image_pointer_t::ObjectType::Pointer::ObjectType image_t; typedef typename image_t::PointType point_t; - + // image space bounding boxes: std::vector image_min; std::vector image_max; calc_image_bboxes(image, image_min, image_max); - + // mosaic space bounding boxes: std::vector mosaic_min; std::vector mosaic_max; - + // FIXME: calc_mosaic_bboxes(transform, image_min, @@ -2355,22 +2355,22 @@ calc_mosaic_bbox(const std::vector & transform, mosaic_min, mosaic_max, np); - + // mosiac bounding box: calc_mosaic_bbox(mosaic_min, mosaic_max, min, max); } //---------------------------------------------------------------- // calc_mosaic_bbox_load_images -// +// // Calculate the mosaic bounding box (a union of mosaic space // bounding boxes of the warped tiles). -// +// template void calc_mosaic_bbox_load_images(const std::vector & transform, const std::list & fn_image, - + // mosaic bounding box: typename image_pointer_t::ObjectType::PointType & min, typename image_pointer_t::ObjectType::PointType & max, @@ -2378,23 +2378,23 @@ calc_mosaic_bbox_load_images(const std::vector & transform, std::vector & mosaic_max, const unsigned int shrink_factor, const double pixel_spacing, - + // points along the image edges: const unsigned int np = 15) { typedef typename image_pointer_t::ObjectType::Pointer::ObjectType image_t; typedef typename image_t::PointType point_t; - + // image space bounding boxes: std::vector image_min; std::vector image_max; - - calc_image_bboxes_load_images(fn_image, - image_min, + + calc_image_bboxes_load_images(fn_image, + image_min, image_max, shrink_factor, pixel_spacing); - + // mosaic space bounding boxes: // FIXME: calc_mosaic_bboxes(transform, @@ -2403,7 +2403,7 @@ calc_mosaic_bbox_load_images(const std::vector & transform, mosaic_min, mosaic_max, np); - + // mosiac bounding box: calc_mosaic_bbox(mosaic_min, mosaic_max, min, max); } @@ -2411,27 +2411,27 @@ calc_mosaic_bbox_load_images(const std::vector & transform, //---------------------------------------------------------------- // bbox_overlap -// +// // Test whether two bounding boxes overlap. -// +// inline bool -bbox_overlap(const pnt2d_t & min_box1, - const pnt2d_t & max_box1, +bbox_overlap(const pnt2d_t & min_box1, + const pnt2d_t & max_box1, const pnt2d_t & min_box2, const pnt2d_t & max_box2) { return - max_box1[0] > min_box2[0] && + max_box1[0] > min_box2[0] && min_box1[0] < max_box2[0] && - max_box1[1] > min_box2[1] && + max_box1[1] > min_box2[1] && min_box1[1] < max_box2[1]; } //---------------------------------------------------------------- // inside_bbox -// +// // Test whether a given point is inside the bounding box. -// +// inline bool inside_bbox(const pnt2d_t & min, const pnt2d_t & max, const pnt2d_t & pt) { @@ -2444,9 +2444,9 @@ inside_bbox(const pnt2d_t & min, const pnt2d_t & max, const pnt2d_t & pt) //---------------------------------------------------------------- // calc_pixel_weight -// +// // Calculate a pixel feathering weight used to blend mosaic tiles. -// +// inline static double calc_pixel_weight(const pnt2d_t & bbox_min, const pnt2d_t & bbox_max, @@ -2466,7 +2466,7 @@ calc_pixel_weight(const pnt2d_t & bbox_min, // feathering_t // // Supported pixel feathering modes -// +// typedef enum { FEATHER_NONE_E, FEATHER_BLEND_E, @@ -2475,13 +2475,13 @@ typedef enum { //---------------------------------------------------------------- // make_mosaic_st -// +// // Assemble a portion of the mosaic positioned at mosaic_min. // Each tile may be individually tinted with a grayscale color. // Individual tiles may be omitted. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. -// +// Tile masks are optional and may be nullptr. +// template typename image_pointer_t::ObjectType::Pointer make_mosaic_st @@ -2495,19 +2495,19 @@ make_mosaic_st const std::vector & tint, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E, double background = 255.0, - + bool dont_allocate = false) { WRAP(itk_terminator_t terminator("make_mosaic_st")); - + typedef typename image_pointer_t::ObjectType::Pointer::ObjectType image_t; //typedef typename image_t::IndexType index_t; typedef typename image_t::PointType point_t; @@ -2515,54 +2515,54 @@ make_mosaic_st //typedef typename image_t::SpacingType spacing_t; //typedef typename image_t::RegionType::SizeType imagesz_t; typedef typename itk::ImageRegionIteratorWithIndex itex_t; - + // setup the image interpolators: typedef typename itk::LinearInterpolateImageFunction img_interpolator_t; std::vector img(num_images); - + for (unsigned int i = 0; i < num_images; i++) { img[i] = img_interpolator_t::New(); img[i]->SetInputImage(image[i]); } - + // setup the image mask interpolators: typedef itk::NearestNeighborInterpolateImageFunction msk_interpolator_t; std::vector msk(num_images); - msk.assign(num_images, msk_interpolator_t::Pointer(NULL)); - + msk.assign(num_images, msk_interpolator_t::Pointer(nullptr)); + for (unsigned int i = 0; i < image_mask.size() && i < num_images; i++) { - if (image_mask[i].GetPointer() == NULL) continue; - + if (image_mask[i].GetPointer() == nullptr) continue; + msk[i] = msk_interpolator_t::New(); msk[i]->SetInputImage(image_mask[i]); } - + // image space bounding boxes (for feathering): std::vector bbox_min(num_images); std::vector bbox_max(num_images); calc_image_bboxes(image, bbox_min, bbox_max); - + // mosaic space bounding boxes: std::vector min(num_images); std::vector max(num_images); - + calc_mosaic_bboxes(transform, bbox_min, bbox_max, min, max); - + // setup the mosaic image: typename image_t::Pointer mosaic = image_t::New(); mosaic->SetOrigin(mosaic_min); mosaic->SetRegions(mosaic_sz); mosaic->SetSpacing(mosaic_sp); - - mosaic_mask = NULL; + + mosaic_mask = nullptr; if (assemble_mosaic_mask) { mosaic_mask = mask_t::New(); @@ -2570,66 +2570,66 @@ make_mosaic_st mosaic_mask->SetRegions(mosaic_sz); mosaic_mask->SetSpacing(mosaic_sp); } - + if (dont_allocate) { // this is useful for estimating the mosaic size: return mosaic; } - + // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + mosaic->Allocate(); - + if (assemble_mosaic_mask) { mosaic_mask->Allocate(); } - + // this is needed in order to prevent holes in the mask mosaic: bool integer_pixel = std::numeric_limits::is_integer; double pixel_max = static_cast(std::numeric_limits::max()); double pixel_min = integer_pixel ? static_cast(std::numeric_limits::min()) : -pixel_max; - + itex_t itex(mosaic, mosaic->GetLargestPossibleRegion()); for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + point_t point; mosaic->TransformIndexToPhysicalPoint(itex.GetIndex(), point); - + double pixel = 0.0; double weight = 0.0; unsigned int num_pixels = 0; for (unsigned int k = 0; k < num_images; k++) { // don't try to add missing or omitted images to the mosaic: - if (omit[k] || (image[k].GetPointer() == NULL)) continue; - + if (omit[k] || (image[k].GetPointer() == nullptr)) continue; + // avoid undesirable distortion artifacts: if (!inside_bbox(min[k], max[k], point)) continue; - + const transform_pointer_t & t = transform[k]; point_t pt_k = t->TransformPoint(point); - + // make sure the pixel maps into the image: if (!img[k]->IsInsideBuffer(pt_k)) continue; - + // make sure the pixel maps into the image mask: double alpha = 1.0; - if ((msk[k].GetPointer() != NULL) && + if ((msk[k].GetPointer() != nullptr) && (alpha = msk[k]->Evaluate(pt_k)) < 1.0) continue; - + // feather out the edges by giving them a tiny weight: num_pixels++; double wp = tint[k]; double p = img[k]->Evaluate(pt_k) * wp; double wa = ((alpha == 1.0) ? 1e-0 : 1e-6) * wp; - + if (feathering == FEATHER_NONE_E) { pixel += p * wa; @@ -2639,7 +2639,7 @@ make_mosaic_st { double pixel_weight = calc_pixel_weight(bbox_min[k], bbox_max[k], pt_k); - + if (feathering == FEATHER_BLEND_E) { pixel += pixel_weight * p * wa; @@ -2655,7 +2655,7 @@ make_mosaic_st } } } - + // calculate the final pixel value: if (weight > 0.0) { @@ -2663,11 +2663,11 @@ make_mosaic_st if (integer_pixel) { pixel = floor(pixel + 0.5); - + // make sure we don't exceed the intensity range: pixel = std::max(pixel_min, std::min(pixel_max, pixel)); } - + pixel_t tmp = pixel_t(pixel); itex.Set(tmp); } @@ -2675,23 +2675,23 @@ make_mosaic_st { itex.Set(num_pixels > 0 ? 0 : pixel_t(background)); } - + if (mosaic_mask.GetPointer()) { mask_t::PixelType mask_pixel = (weight > 0.0) ? 1 : 0; mosaic_mask->SetPixel(itex.GetIndex(), mask_pixel); } } - + return mosaic; } //---------------------------------------------------------------- // assemble_mosaic_t -// +// // Parallelized mosaic assembly mechanism -// +// template class assemble_mosaic_t : public the_transaction_t { @@ -2704,51 +2704,51 @@ public: typedef typename image_t::RegionType::IndexType ix_t; typedef typename itk::LinearInterpolateImageFunction itile_t; typedef itk::NearestNeighborInterpolateImageFunction imask_t; - + assemble_mosaic_t(// thread index and number of threads, used to avoid // concurrent access to the same point in the mosaic: unsigned int thread_offset, unsigned int thread_stride, - + // mosaic being assembled: typename tile_t::Pointer & mosaic, mask_t * mosaic_mask, - + // number of tiles to use for this mosaic (may be fewer // then the number of tiles available): unsigned int num_tiles, - + // omitted tile flags: const std::vector & omit, - + // tile tint: const std::vector & tint, - + // tile trasforms: const std::vector & transform, - + // tiles and tile masks const std::vector & tile, const std::vector & mask, - + // tile and tile mask interpolators: const std::vector & itile, const std::vector & imask, - + // image space tile bounding boxes (for feathering): const std::vector & bbox_min, const std::vector & bbox_max, - + // mosaic space tile bounding boxes: const std::vector & min, const std::vector & max, - + // overlap region feathering method: feathering_t feathering, - + // default mosaic pixel value: double background): - + thread_offset_(thread_offset), thread_stride_(thread_stride), mosaic_(mosaic), @@ -2768,23 +2768,23 @@ public: feathering_(feathering), background_(background) {} - + void execute(the_thread_interface_t * thread) { WRAP(itk_terminator_t terminator("assemble_mosaic_t::execute")); - + // this is needed in order to prevent holes in the mask mosaic: const bool integer_pixel = std::numeric_limits::is_integer; const double pixel_max = static_cast(std::numeric_limits::max()); const double pixel_min = integer_pixel ? static_cast(std::numeric_limits::min()) : -pixel_max; - + rn_t region = mosaic_->GetLargestPossibleRegion(); ix_t origin = region.GetIndex(); sz_t extent = region.GetSize(); ix_t::IndexValueType x_end = origin[0] + extent[0]; ix_t::IndexValueType y_end = origin[1] + extent[1]; - + ix_t ix = origin; for (ix[1] = origin[1]; ix[1] < y_end; ++ix[1]) { @@ -2794,51 +2794,51 @@ public: { // check whether termination was requested: WRAP(terminator.terminate_on_request()); - + pnt_t point; mosaic_->TransformIndexToPhysicalPoint(ix, point); - + double pixel = 0.0; double weight = 0.0; unsigned int num_pixels = 0; - + for (unsigned int k = 0; k < num_tiles_; k++) { // don't try to add missing or omitted images to the mosaic: - if (omit_[k] || (tile_[k].GetPointer() == NULL)) + if (omit_[k] || (tile_[k].GetPointer() == nullptr)) { continue; } - + // avoid undesirable distortion artifacts: if (!inside_bbox(min_[k], max_[k], point)) { continue; } - + const transform_pointer_t & t = transform_[k]; pnt_t pt_k = t->TransformPoint(point); - + // make sure the pixel maps into the image: if (!itile_[k]->IsInsideBuffer(pt_k)) { continue; } - + // make sure the pixel maps into the image mask: double alpha = 1.0; - if ((imask_[k].GetPointer() != NULL) && + if ((imask_[k].GetPointer() != nullptr) && (alpha = imask_[k]->Evaluate(pt_k)) < 1.0) { continue; } - + // feather out the edges by giving them a tiny weight: num_pixels++; double wp = tint_[k]; double p = itile_[k]->Evaluate(pt_k) * wp; double wa = ((alpha == 1.0) ? 1e-0 : 1e-6) * wp; - + if (feathering_ == FEATHER_NONE_E) { pixel += p * wa; @@ -2849,7 +2849,7 @@ public: double pixel_weight = calc_pixel_weight(bbox_min_[k], bbox_max_[k], pt_k); - + if (feathering_ == FEATHER_BLEND_E) { pixel += pixel_weight * p * wa; @@ -2865,7 +2865,7 @@ public: } } } - + // calculate the final pixel value: if (weight > 0.0) { @@ -2873,11 +2873,11 @@ public: if (integer_pixel) { pixel = floor(pixel + 0.5); - + // make sure we don't exceed the intensity range: pixel = std::max(pixel_min, std::min(pixel_max, pixel)); } - + pxl_t output = pxl_t(pixel); mosaic_->SetPixel(ix, output); } @@ -2886,7 +2886,7 @@ public: pxl_t output = num_pixels > 0 ? 0 : pxl_t(background_); mosaic_->SetPixel(ix, output); } - + if (mosaic_mask_) { mask_t::PixelType mask_pixel = (weight > 0.0) ? 1 : 0; @@ -2895,61 +2895,61 @@ public: } } } - + // data members facilitating concurrent mosaic assembly: unsigned int thread_offset_; unsigned int thread_stride_; - + // output mosaic: typename tile_t::Pointer & mosaic_; mask_t * mosaic_mask_; - + // number of tiles used for this mosaic (may be fewer than // what's available from the tile vector): unsigned int num_tiles_; - + // omitted tile flags: const std::vector & omit_; - + // tile tint: const std::vector & tint_; - + // tile trasforms: const std::vector & transform_; - + // tiles and tile masks const std::vector & tile_; const std::vector & mask_; - - + + // tile and tile mask interpolators: const std::vector & itile_; const std::vector & imask_; - + // image space tile bounding boxes (for feathering): const std::vector & bbox_min_; const std::vector & bbox_max_; - + // mosaic space tile bounding boxes: const std::vector & min_; const std::vector & max_; - + // overlap region feathering method: feathering_t feathering_; - + // default mosaic pixel value: double background_; }; //---------------------------------------------------------------- // make_mosaic_mt -// +// // Assemble a portion of the mosaic positioned at mosaic_min. // Each tile may be individually tinted with a grayscale color. // Individual tiles may be omitted. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. -// +// Tile masks are optional and may be nullptr. +// template typename image_pointer_t::ObjectType::Pointer make_mosaic_mt @@ -2964,15 +2964,15 @@ make_mosaic_mt const std::vector & tint, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E, double background = 255.0, - + bool dont_allocate = false) { if (num_threads == 1) @@ -2995,42 +2995,42 @@ make_mosaic_mt background, dont_allocate); } - + WRAP(itk_terminator_t terminator("make_mosaic_mt")); - + typedef typename image_pointer_t::ObjectType::Pointer::ObjectType img_t; typedef typename img_t::PointType pnt_t; - + // setup the image interpolators: typedef typename itk::LinearInterpolateImageFunction img_interpolator_t; std::vector img(num_images); - + for (unsigned int i = 0; i < num_images; i++) { img[i] = img_interpolator_t::New(); img[i]->SetInputImage(image[i]); } - + // setup the image mask interpolators: typedef itk::NearestNeighborInterpolateImageFunction msk_interpolator_t; std::vector msk(num_images); - msk.assign(num_images, msk_interpolator_t::Pointer(NULL)); - + msk.assign(num_images, msk_interpolator_t::Pointer(nullptr)); + for (unsigned int i = 0; i < image_mask.size() && i < num_images; i++) { - if (image_mask[i].GetPointer() == NULL) continue; - + if (image_mask[i].GetPointer() == nullptr) continue; + msk[i] = msk_interpolator_t::New(); msk[i]->SetInputImage(image_mask[i]); } - + // image space bounding boxes (for feathering): std::vector bbox_min(num_images); std::vector bbox_max(num_images); calc_image_bboxes(image, bbox_min, bbox_max); - + // mosaic space bounding boxes: std::vector min(num_images); std::vector max(num_images); @@ -3039,14 +3039,14 @@ make_mosaic_mt bbox_max, min, max); - + // setup the mosaic image: typename img_t::Pointer mosaic = img_t::New(); mosaic->SetOrigin(mosaic_min); mosaic->SetRegions(mosaic_sz); mosaic->SetSpacing(mosaic_sp); - - mosaic_mask = NULL; + + mosaic_mask = nullptr; if (assemble_mosaic_mask) { mosaic_mask = mask_t::New(); @@ -3054,21 +3054,21 @@ make_mosaic_mt mosaic_mask->SetRegions(mosaic_sz); mosaic_mask->SetSpacing(mosaic_sp); } - + if (dont_allocate) { // this is useful for estimating the mosaic size: return mosaic; } - + // allocate the mosaic: mosaic->Allocate(); - + if (assemble_mosaic_mask) { mosaic_mask->Allocate(); } - + // setup transactions for multi-threaded mosaic assembly: std::list schedule; for (unsigned int i = 0; i < num_threads; i++) @@ -3093,36 +3093,36 @@ make_mosaic_mt max, feathering, background); - + schedule.push_back(t); } - + // setup the thread pool: the_thread_pool_t thread_pool(num_threads); thread_pool.set_idle_sleep_duration(50); // 50 usec thread_pool.push_back(schedule); thread_pool.pre_distribute_work(); - + // execute mosaic assembly transactions: suspend_itk_multithreading_t suspend_itk_mt; thread_pool.start(); thread_pool.wait(); - + // done: return mosaic; } //---------------------------------------------------------------- // make_mosaic -// +// // Assemble a portion of the mosaic positioned at mosaic_min. // Each tile may be individually tinted with a grayscale color. // Individual tiles may be omitted. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. +// Tile masks are optional and may be nullptr. // // Use all possible processors/cores available for multi-threading: -// +// template typename image_pointer_t::ObjectType::Pointer make_mosaic @@ -3134,24 +3134,24 @@ make_mosaic const std::vector & tint, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E, double background = 255.0, - + bool dont_allocate = false) { // use as many threads as supported by hardware: unsigned int num_threads = boost::thread::hardware_concurrency(); - + // NOTE: for backwards compatibility we do not assemble the mosaic mask: const bool assemble_mosaic_mask = false; mask_t::Pointer mosaic_mask; - + return make_mosaic_mt (num_threads, @@ -3174,10 +3174,10 @@ make_mosaic //---------------------------------------------------------------- // make_mosaic -// +// // Assemble a portion of the mosaic positioned at mosaic_min. // Tiles are not tinted. -// +// template typename image_pointer_t::ObjectType::Pointer make_mosaic @@ -3188,15 +3188,15 @@ make_mosaic const std::vector & omit, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E, double background = 255.0, - + bool dont_allocate = false) { const std::vector tint(num_images, 1.0); @@ -3217,10 +3217,10 @@ make_mosaic //---------------------------------------------------------------- // make_mosaic -// +// // Assemble a portion of the mosaic bounded by // mosaic_min and mosaic_max. -// +// template typename image_pointer_t::ObjectType::Pointer make_mosaic @@ -3231,16 +3231,16 @@ make_mosaic const std::vector & omit, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E, - + double background = 255.0, - + bool dont_allocate = false) { typename image_pointer_t::ObjectType::SizeType mosaic_sz; @@ -3248,7 +3248,7 @@ make_mosaic mosaic_sp[0]); mosaic_sz[1] = static_cast((mosaic_max[1] - mosaic_min[1]) / mosaic_sp[1]); - + return make_mosaic (mosaic_sp, mosaic_min, @@ -3265,10 +3265,10 @@ make_mosaic //---------------------------------------------------------------- // make_mosaic -// +// // Assemble a portion of the mosaic bounded by // mosaic_min and mosaic_max. -// +// template typename image_pointer_t::ObjectType::Pointer make_mosaic @@ -3277,16 +3277,16 @@ make_mosaic const std::vector & omit, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E, - + double background = 255.0, - + bool dont_allocate = false) { // mosaic bounding box: @@ -3297,7 +3297,7 @@ make_mosaic image, mosaic_min, mosaic_max); - + return make_mosaic (mosaic_sp, mosaic_min, @@ -3314,10 +3314,10 @@ make_mosaic //---------------------------------------------------------------- // make_mosaic -// +// // Assemble the entire mosaic from a set of tiles and transforms. // Individual tiles may be omitted. -// +// template typename image_pointer_t::ObjectType::Pointer make_mosaic(const std::vector & image, @@ -3333,14 +3333,14 @@ make_mosaic(const std::vector & image, { num_images = image.size(); } - + std::vector omit_vec(num_images); omit_vec.assign(num_images, false); if (omit != std::numeric_limits::max()) { omit_vec[omit] = true; } - + return make_mosaic (image[0]->GetSpacing(), @@ -3355,33 +3355,33 @@ make_mosaic(const std::vector & image, //---------------------------------------------------------------- // update_mosaic -// +// // Expand the mosaic by adding another tile to it. This may be // used to assemble the mosaic incrementally. -// +// template typename T::Pointer update_mosaic(const T * mosaic, const T * tile, const base_transform_t * tile_transform, - const mask_t * mask_mosaic = NULL, - const mask_t * mask_tile = NULL) + const mask_t * mask_mosaic = nullptr, + const mask_t * mask_tile = nullptr) { std::vector image(2); image[0] = mosaic; image[1] = tile; - + std::vector transform(2); transform[0] = identity_transform_t::New(); transform[1] = tile_transform; - + std::vector image_mask(2); image_mask[0] = mask_mosaic; image_mask[1] = mask_tile; - + std::vector omit(2); omit.assign(2, false); - + return make_mosaic (mosaic->GetSpacing(), @@ -3398,7 +3398,7 @@ update_mosaic(const T * mosaic, // // Assemble a mask for the entire mosaic. // Individual tiles may be omitted. -// +// template mask_t::Pointer make_mask_st(const mask_t::SpacingType & mosaic_sp, @@ -3408,33 +3408,33 @@ make_mask_st(const mask_t::SpacingType & mosaic_sp, const std::vector & image_mask) { WRAP(itk_terminator_t terminator("make_mask_st")); - + //typedef mask_t::IndexType index_t; typedef mask_t::PointType point_t; typedef mask_t::PixelType pixel_t; //typedef mask_t::SpacingType spacing_t; typedef mask_t::RegionType::SizeType imagesz_t; typedef itk::ImageRegionIteratorWithIndex itex_t; - + // setup the image mask interpolators: typedef itk::NearestNeighborInterpolateImageFunction msk_interpolator_t; std::vector msk(num_images); - msk.assign(num_images, msk_interpolator_t::Pointer(NULL)); - + msk.assign(num_images, msk_interpolator_t::Pointer(nullptr)); + for (unsigned int i = 0; i < image_mask.size() && i < num_images; i++) { - if (image_mask[i].GetPointer() == NULL) continue; - + if (image_mask[i].GetPointer() == nullptr) continue; + msk[i] = msk_interpolator_t::New(); msk[i]->SetInputImage(image_mask[i]); } - + // image space bounding boxes (for feathering): std::vector bbox_min(num_images); std::vector bbox_max(num_images); calc_image_bboxes(image_mask, bbox_min, bbox_max); - + // mosaic space bounding boxes: std::vector min(num_images); std::vector max(num_images); @@ -3443,16 +3443,16 @@ make_mask_st(const mask_t::SpacingType & mosaic_sp, bbox_max, min, max); - + // mosiac bounding box: point_t mosaic_min; point_t mosaic_max; calc_mosaic_bbox(min, max, mosaic_min, mosaic_max); - + // setup the mosaic image: mask_t::Pointer mosaic = mask_t::New(); imagesz_t mosaic_sz; - + mosaic_sz[0] = static_cast((mosaic_max[0] - mosaic_min[0]) / mosaic_sp[0]); mosaic_sz[1] = static_cast((mosaic_max[1] - mosaic_min[1]) / @@ -3460,44 +3460,44 @@ make_mask_st(const mask_t::SpacingType & mosaic_sp, mosaic->SetOrigin(pnt2d(mosaic_min[0], mosaic_min[1])); mosaic->SetRegions(mosaic_sz); mosaic->SetSpacing(mosaic_sp); - + // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + mosaic->Allocate(); mosaic->FillBuffer(itk::NumericTraits::Zero); - + itex_t itex(mosaic, mosaic->GetLargestPossibleRegion()); for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + point_t point; mosaic->TransformIndexToPhysicalPoint(itex.GetIndex(), point); - + for (unsigned int k = 0; k < num_images; k++) { // don't try to add missing or omitted images to the mosaic: - if (omit[k] || (image_mask[k].GetPointer() == NULL)) continue; - + if (omit[k] || (image_mask[k].GetPointer() == nullptr)) continue; + // avoid undesirable radial distortion artifacts for R >> Rmax: if (!inside_bbox(min[k], max[k], point)) continue; - + const transform_pointer_t & t = transform[k]; point_t pt_k = t->TransformPoint(point); - + // make sure the pixel maps into the image: if (!msk[k]->IsInsideBuffer(pt_k)) continue; - + // make sure the pixel maps into the image mask: if (msk[k]->Evaluate(pt_k) == 0) continue; - + itex.Set(1); break; } } - + return mosaic; } @@ -3505,9 +3505,9 @@ make_mask_st(const mask_t::SpacingType & mosaic_sp, //---------------------------------------------------------------- // assemble_mask_t -// +// // Parallelized mosaic mask assembly mechanism -// +// template class assemble_mask_t : public the_transaction_t { @@ -3518,35 +3518,35 @@ public: typedef mask_t::RegionType::SizeType sz_t; typedef mask_t::RegionType::IndexType ix_t; typedef itk::NearestNeighborInterpolateImageFunction imask_t; - + assemble_mask_t(// thread index and number of threads, used to avoid // concurrent access to the same point in the mosaic: unsigned int thread_offset, unsigned int thread_stride, - + // mosaic being assembled: mask_t::Pointer & mosaic, - + // number of tiles to use for this mosaic (may be fewer // then the number of tiles available): unsigned int num_tiles, - + // omitted tile flags: const std::vector & omit, - + // tile trasforms: const std::vector & transform, - + // tiles and tile masks const std::vector & mask, - + // tile and tile mask interpolators: const std::vector & imask, - + // mosaic space tile bounding boxes: const std::vector & min, const std::vector & max): - + thread_offset_(thread_offset), thread_stride_(thread_stride), mosaic_(mosaic), @@ -3558,17 +3558,17 @@ public: min_(min), max_(max) {} - + void execute(the_thread_interface_t * thread) { WRAP(itk_terminator_t terminator("assemble_mask_t::execute")); - + rn_t region = mosaic_->GetLargestPossibleRegion(); ix_t origin = region.GetIndex(); sz_t extent = region.GetSize(); ix_t::IndexValueType x_end = origin[0] + extent[0]; ix_t::IndexValueType y_end = origin[1] + extent[1]; - + ix_t ix = origin; for (ix[1] = origin[1]; ix[1] < y_end; ++ix[1]) { @@ -3578,72 +3578,72 @@ public: { // check whether termination was requested: WRAP(terminator.terminate_on_request()); - + pnt_t point; mosaic_->TransformIndexToPhysicalPoint(ix, point); - + mask_t::PixelType mask_pixel = 0; for (unsigned int k = 0; k < num_tiles_; k++) { // don't try to add missing or omitted images to the mosaic: - if (omit_[k] || (mask_[k].GetPointer() == NULL)) + if (omit_[k] || (mask_[k].GetPointer() == nullptr)) { continue; } - + // avoid undesirable distortion artifacts: if (!inside_bbox(min_[k], max_[k], point)) { continue; } - + const transform_pointer_t & t = transform_[k]; pnt_t pt_k = t->TransformPoint(point); - + // make sure the pixel maps into the image: if (!imask_[k]->IsInsideBuffer(pt_k)) { continue; } - + // make sure the pixel maps into the image mask: if (imask_[k]->Evaluate(pt_k) == 0) { continue; } - + mask_pixel = 1; break; } - + mosaic_->SetPixel(ix, mask_pixel); } } } - + // data members facilitating concurrent mosaic assembly: unsigned int thread_offset_; unsigned int thread_stride_; - + // output mosaic: mask_t::Pointer & mosaic_; - + // number of tiles used for this mosaic (may be fewer than // what's available from the tile vector): unsigned int num_tiles_; - + // omitted tile flags: const std::vector & omit_; - + // tile trasforms: const std::vector & transform_; - + // tile masks const std::vector & mask_; - + // tile mask interpolators: const std::vector & imask_; - + // mosaic space tile bounding boxes: const std::vector & min_; const std::vector & max_; @@ -3655,7 +3655,7 @@ public: // // Assemble a mask for the entire mosaic. // Individual tiles may be omitted. -// +// template mask_t::Pointer make_mask_mt(unsigned int num_threads, @@ -3674,29 +3674,29 @@ make_mask_mt(unsigned int num_threads, transform, image_mask); } - + // FIXME: make it multi-threaded: WRAP(itk_terminator_t terminator("make_mask_mt")); - + // setup the image mask interpolators: typedef itk::NearestNeighborInterpolateImageFunction imask_t; std::vector imask(num_images); - imask.assign(num_images, imask_t::Pointer(NULL)); - + imask.assign(num_images, imask_t::Pointer(nullptr)); + for (unsigned int i = 0; i < image_mask.size() && i < num_images; i++) { - if (image_mask[i].GetPointer() == NULL) continue; - + if (image_mask[i].GetPointer() == nullptr) continue; + imask[i] = imask_t::New(); imask[i]->SetInputImage(image_mask[i]); } - + // image space bounding boxes: typedef mask_t::PointType pnt_t; std::vector bbox_min(num_images); std::vector bbox_max(num_images); calc_image_bboxes(image_mask, bbox_min, bbox_max); - + // mosaic space bounding boxes: std::vector min(num_images); std::vector max(num_images); @@ -3705,12 +3705,12 @@ make_mask_mt(unsigned int num_threads, bbox_max, min, max); - + // mosiac bounding box: pnt_t mosaic_min; pnt_t mosaic_max; calc_mosaic_bbox(min, max, mosaic_min, mosaic_max); - + // setup the mosaic image: mask_t::Pointer mosaic = mask_t::New(); mask_t::RegionType::SizeType mosaic_sz; @@ -3722,7 +3722,7 @@ make_mask_mt(unsigned int num_threads, mosaic->SetRegions(mosaic_sz); mosaic->SetSpacing(mosaic_sp); mosaic->Allocate(); - + // setup transactions for multi-threaded mosaic assembly: std::list schedule; for (unsigned int i = 0; i < num_threads; i++) @@ -3738,28 +3738,28 @@ make_mask_mt(unsigned int num_threads, imask, min, max); - + schedule.push_back(t); } - + // setup the thread pool: the_thread_pool_t thread_pool(num_threads); thread_pool.set_idle_sleep_duration(50); // 50 usec thread_pool.push_back(schedule); thread_pool.pre_distribute_work(); - + // execute mosaic assembly transactions: suspend_itk_multithreading_t suspend_itk_mt; thread_pool.start(); thread_pool.wait(); - + // done: return mosaic; } //---------------------------------------------------------------- // make_mask -// +// template mask_t::Pointer make_mask(const mask_t::SpacingType & mosaic_sp, @@ -3770,7 +3770,7 @@ make_mask(const mask_t::SpacingType & mosaic_sp, { // use as many threads as supported by hardware: unsigned int num_threads = boost::thread::hardware_concurrency(); - + return make_mask_mt(num_threads, mosaic_sp, num_images, @@ -3781,9 +3781,9 @@ make_mask(const mask_t::SpacingType & mosaic_sp, //---------------------------------------------------------------- // make_mask -// +// // Assemble a mask for the entire mosaic. -// +// template mask_t::Pointer make_mask(const std::vector & transform, @@ -3799,9 +3799,9 @@ make_mask(const std::vector & transform, //---------------------------------------------------------------- // make_mosaic -// +// // Assemble the entire mosaic. -// +// template typename image_pointer_t::ObjectType::Pointer make_mosaic(const feathering_t feathering, @@ -3818,10 +3818,10 @@ make_mosaic(const feathering_t feathering, std::vector(num_images, false), // omit transform, image, - + // optional image masks: image_mask, - + // feathering to reduce image blurring is optional: feathering, 0.0, @@ -3833,7 +3833,7 @@ make_mosaic(const feathering_t feathering, // // Return a copy of a given image warped according to // a given transform. -// +// template typename T::Pointer warp(const T * a, @@ -3841,10 +3841,10 @@ warp(const T * a, { std::vector image(1); image[0] = a; - + std::vector transform(1); transform[0] = t; - + return make_mosaic (image, @@ -3857,7 +3857,7 @@ warp(const T * a, // // scale = 0.5 ---> reduce image in half along each dimension // scale = 2.0 ---> double the image size along each dimension -// +// template typename T::Pointer resize(const T * in, double scale) @@ -3877,14 +3877,14 @@ resize(const T * in, double scale) // Calculate a scale factor for a given image, such that // the largest dimension of the image is equal to max_edge_size. // Return a scaled copy of the image. -// +// template typename T::Pointer resize(const T * in, unsigned int max_edge_size, double & scale) { typename T::RegionType::SizeType sz = in->GetLargestPossibleRegion().GetSize(); - + double xScale = static_cast(max_edge_size) / static_cast(sz[0]); double yScale = static_cast(max_edge_size) / static_cast(sz[1]); scale = xScale < yScale ? xScale : yScale; @@ -3893,11 +3893,11 @@ resize(const T * in, unsigned int max_edge_size, double & scale) //---------------------------------------------------------------- // resize -// +// // Scale a given image such that the largest dimension -// of the image is equal to max_edge_size. +// of the image is equal to max_edge_size. // Return a scaled copy of the image. -// +// template typename T::Pointer resize(const T * in, unsigned int max_edge_size) @@ -3912,7 +3912,7 @@ resize(const T * in, unsigned int max_edge_size) // // Assemble the mosaic and save the mosaic image // Individual mosaic tiles may be omitted. -// +// template void save_mosaic(const std::vector & image, @@ -3922,7 +3922,7 @@ save_mosaic(const std::vector & image, unsigned int num_images = std::numeric_limits::max()) { typedef typename image_pointer_t::ObjectType::Pointer::ObjectType image_t; - + typename image_t::Pointer mosaic = make_mosaic(image, transform, @@ -3934,10 +3934,10 @@ save_mosaic(const std::vector & image, //---------------------------------------------------------------- // align_fi_mi -// +// // Warp images fi and mi. Both warped images will have the same // dimensions as a mosaic assembled from fi and mi. -// +// template void align_fi_mi(const T * fi, @@ -3949,18 +3949,18 @@ align_fi_mi(const T * fi, std::vector image(2); image[0] = fi; image[1] = mi; - + std::vector transform(2); transform[0] = identity_transform_t::New(); transform[1] = mi_transform; - + fi_aligned = make_mosaic (image, transform, FEATHER_NONE_E, 1); - + mi_aligned = make_mosaic (image, @@ -3975,7 +3975,7 @@ align_fi_mi(const T * fi, // Save an RGB image of images fi and mi registered via // a given transform. The mi image will be saved in the red channel, // and fi will be saved in the green and blue channels. -// +// template void save_composite(const bfs::path & filename, @@ -3987,41 +3987,41 @@ save_composite(const bfs::path & filename, typename T::Pointer fi_aligned; typename T::Pointer mi_aligned; align_fi_mi(fi, mi, xform, fi_aligned, mi_aligned); - + typedef itk::CastImageFilter cast_to_native_t; typename cast_to_native_t::Pointer fi_native = cast_to_native_t::New(); typename cast_to_native_t::Pointer mi_native = cast_to_native_t::New(); fi_native->SetInput(fi_aligned); mi_native->SetInput(mi_aligned); - + typedef itk::RGBPixel composite_pixel_t; typedef itk::Image composite_image_t; - typedef itk::ComposeRGBImageFilter + typedef itk::ComposeImageFilter compose_filter_t; - + compose_filter_t::Pointer composer = compose_filter_t::New(); composer->SetInput1(mi_native->GetOutput()); composer->SetInput2(fi_native->GetOutput()); composer->SetInput3(fi_native->GetOutput()); - + typedef itk::ImageFileWriter composite_writer_t; composite_writer_t::Pointer writer = composite_writer_t::New(); writer->SetFileName(filename.string().c_str()); writer->SetInput(composer->GetOutput()); - + //if (blab) std::cout << "saving " << filename << std::endl; writer->Update(); } //---------------------------------------------------------------- // make_mosaic_rgb -// +// // Assemble a portion of the mosaic positioned at mosaic_min. // Each tile may be individually tinted with an RGB color. // Individual tiles may be omitted. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. -// +// Tile masks are optional and may be nullptr. +// template void make_mosaic_rgb @@ -4034,17 +4034,17 @@ make_mosaic_rgb const std::vector & omit, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E) { WRAP(itk_terminator_t terminator("make_mosaic_rgb")); unsigned int num_images = image.size(); - + for (unsigned int i = 0; i < 3; i++) { std::vector tint(num_images); @@ -4052,7 +4052,7 @@ make_mosaic_rgb { tint[j] = color[j][i] / 255.0; } - + mosaic[i] = make_mosaic (mosaic_sp, @@ -4071,15 +4071,15 @@ make_mosaic_rgb //---------------------------------------------------------------- // make_mosaic_rgb -// +// // Assemble a portion of the mosaic bounded by // mosaic_min and mosaic_max. -// +// // Each tile may be individually tinted with an RGB color. // Individual tiles may be omitted. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. -// +// Tile masks are optional and may be nullptr. +// template void make_mosaic_rgb @@ -4092,11 +4092,11 @@ make_mosaic_rgb const std::vector & omit, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E) { @@ -4105,7 +4105,7 @@ make_mosaic_rgb mosaic_sp[0]); mosaic_sz[1] = static_cast((mosaic_max[1] - mosaic_min[1]) / mosaic_sp[1]); - + make_mosaic_rgb (mosaic, mosaic_sp, @@ -4122,13 +4122,13 @@ make_mosaic_rgb //---------------------------------------------------------------- // make_mosaic_rgb -// +// // Assemble the entire mosaic. // Each tile may be individually tinted with an RGB color. // Individual tiles may be omitted. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. -// +// Tile masks are optional and may be nullptr. +// template void make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, @@ -4137,18 +4137,18 @@ make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, const std::vector & omit, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E) { // mosaic pixel spacing will be the same as for the first mosaic tile: typename image_pointer_t::ObjectType::SpacingType mosaic_sp = image[0]->GetSpacing(); - + // mosaic bounding box: typename image_pointer_t::ObjectType::PointType mosaic_min; typename image_pointer_t::ObjectType::PointType mosaic_max; @@ -4157,7 +4157,7 @@ make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, image, mosaic_min, mosaic_max); - + make_mosaic_rgb (mosaic, mosaic_sp, @@ -4176,37 +4176,37 @@ make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, // make_colors // // Generate a scrambled rainbow colormap. -// +// extern void make_colors(const unsigned int & num_color, std::vector & color); //---------------------------------------------------------------- // make_mosaic_rgb -// +// // Assemble the entire mosaic. // Each tile will be tinted with an RGB color // from a scrambled rainbox colormap. // Individual tiles may be omitted. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. -// +// Tile masks are optional and may be nullptr. +// template void make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, const std::vector & omit, const std::vector & transform, const std::vector & image, - + // optional image masks: const std::vector & image_mask = std::vector(0), - + // feathering to reduce image blurring is optional: const feathering_t feathering = FEATHER_NONE_E, - + // background color: double background = 255.0, - + // should the first tile be white? bool first_tile_white = false) { @@ -4214,11 +4214,11 @@ make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, //static const xyz_t NORTH = xyz(0, 1, 0); //static const xyz_t WEST = xyz(0, 0, 1); //static const xyz_t SOUTH = xyz(0, 0, 0); - + unsigned int num_images = image.size(); xyz_t background_color = xyz(background, background, background); std::vector color; - + if (first_tile_white) { std::vector tmp; @@ -4234,7 +4234,7 @@ make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, { make_colors(num_images, color); } - + make_mosaic_rgb (mosaic, background_color, @@ -4248,13 +4248,13 @@ make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, //---------------------------------------------------------------- // make_mosaic_rgb -// +// // Assemble the entire mosaic. // Each tile will be tinted with an RGB color // from a scrambled rainbox colormap. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. -// +// Tile masks are optional and may be nullptr. +// template void make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, @@ -4281,7 +4281,7 @@ make_mosaic_rgb(typename image_pointer_t::ObjectType::Pointer * mosaic, // to_rgb // // Make an RGB image from a given grayscale image -// +// template void to_rgb(const T * image, native_image_t::Pointer * rgb) @@ -4296,43 +4296,43 @@ to_rgb(const T * image, native_image_t::Pointer * rgb) // save_rgb // // Save and RGB image specified by the individual color channel images. -// +// template void save_rgb(const image_ptr_t * image, const bfs::path & filename, bool blab = false) { typedef typename image_ptr_t::ObjectType::Pointer::ObjectType image_t; - + typedef itk::RGBPixel composite_pixel_t; typedef itk::Image composite_image_t; - typedef itk::ComposeRGBImageFilter + typedef itk::ComposeImageFilter compose_filter_t; - + typename compose_filter_t::Pointer composer = compose_filter_t::New(); composer->SetInput1(image[0]); composer->SetInput2(image[1]); composer->SetInput3(image[2]); - + typedef itk::ImageFileWriter composite_writer_t; typename composite_writer_t::Pointer writer = composite_writer_t::New(); writer->SetFileName(filename.string().c_str()); writer->SetInput(composer->GetOutput()); - + //if (blab) std::cout << "saving " << filename << std::endl; writer->Update(); } //---------------------------------------------------------------- // save_mosaic_rgb -// +// // Assemble the entire mosaic. // Each tile will be tinted with an RGB color // from a scrambled rainbox colormap. // Background color (outside the mask) may be specified. -// Tile masks are optional and may be NULL. +// Tile masks are optional and may be nullptr. // // Save the resulting mosaic -// +// template void save_mosaic_rgb(const bfs::path & filename, @@ -4360,10 +4360,10 @@ save_mosaic_rgb(const bfs::path & filename, //---------------------------------------------------------------- // save_rgb -// +// // Save an RGB image of images fi and mi registered via // a given transform. -// +// template void save_rgb(const bfs::path & fn_save, @@ -4377,16 +4377,16 @@ save_rgb(const bfs::path & fn_save, std::vector image(2); std::vector mask(2); std::vector transform(2); - + image[0] = fi; image[1] = mi; - + mask[0] = fi_mask; mask[1] = mi_mask; - + transform[0] = identity_transform_t::New(); transform[1] = xform; - + typename T::Pointer mosaic[3]; make_mosaic_rgb(mosaic, std::vector(2, false), @@ -4396,35 +4396,35 @@ save_rgb(const bfs::path & fn_save, FEATHER_NONE_E, 255.0, false); - + save_rgb(mosaic, fn_save, blab); } //---------------------------------------------------------------- // inverse -// +// // Return an inverse of a given translation transform. -// +// inline static translate_transform_t::Pointer inverse(const translate_transform_t * transform) { - translate_transform_t::Pointer inv = NULL; - if (transform != NULL) + translate_transform_t::Pointer inv = nullptr; + if (transform != nullptr) { inv = translate_transform_t::New(); inv->SetOffset(neg(transform->GetOffset())); } - + return inv; } //---------------------------------------------------------------- // remap -// +// // Re-arrange a data vector according to a given mapping -// +// template void remap(const std::list & mapping, @@ -4433,7 +4433,7 @@ remap(const std::list & mapping, { unsigned int size = mapping.size(); out.resize(size); - + typename std::list::const_iterator iter = mapping.begin(); for (unsigned int i = 0; i < size; i++, ++iter) { @@ -4443,9 +4443,9 @@ remap(const std::list & mapping, //---------------------------------------------------------------- // remap -// +// // Re-arrange a data list according to a given mapping -// +// template void remap(const std::list & mapping, @@ -4453,7 +4453,7 @@ remap(const std::list & mapping, std::list & out) { unsigned int size = in.size(); - + // setup rapid access to the list elements: std::vector rapid(size); { @@ -4463,7 +4463,7 @@ remap(const std::list & mapping, rapid[i] = &(*iter); } } - + // swap the list elements: out.clear(); typename std::list::const_iterator iter = mapping.begin(); @@ -4475,9 +4475,9 @@ remap(const std::list & mapping, //---------------------------------------------------------------- // remap -// +// // Return a re-arranged data container according to a given mapping. -// +// template container_t remap(const std::list & mapping, @@ -4491,9 +4491,9 @@ remap(const std::list & mapping, //---------------------------------------------------------------- // mark -// +// // Draw a cross mark in the given image. -// +// template void mark(typename T::Pointer & image, @@ -4505,15 +4505,15 @@ mark(typename T::Pointer & image, //typedef typename T::SpacingType spacing_t; typedef typename T::RegionType::SizeType image_size_t; typedef typename T::IndexType index_t; - + image_size_t sz = image->GetLargestPossibleRegion().GetSize(); index_t xy; - + for (int j = -arm_length; j <= arm_length; j++) { int x = index[0] + j; int y = index[1] + j; - + if (symbol == '+') { // draw a cross: @@ -4524,7 +4524,7 @@ mark(typename T::Pointer & image, { image->SetPixel(xy, mark_value); } - + xy[0] = index[0]; xy[1] = y; if (xy[0] >= 0 && image_size_value_t(xy[0]) < sz[0] && @@ -4543,7 +4543,7 @@ mark(typename T::Pointer & image, { image->SetPixel(xy, mark_value); } - + xy[1] = index[1] - j; if (xy[0] >= 0 && image_size_value_t(xy[0]) < sz[0] && xy[1] >= 0 && image_size_value_t(xy[1]) < sz[1]) @@ -4556,9 +4556,9 @@ mark(typename T::Pointer & image, //---------------------------------------------------------------- // mark -// +// // Draw a cross mark in the given image. -// +// template void mark(typename T::Pointer & image, @@ -4568,22 +4568,22 @@ mark(typename T::Pointer & image, const char symbol = '+') { typedef typename T::IndexType index_t; - + index_t index; if (!image->TransformPhysicalPointToIndex(mark_coords, index)) { // the mark lays outside of the image: return; } - + mark(image, index, mark_value, arm_length, symbol); } //---------------------------------------------------------------- // fill -// +// // Fill a portion of the image with a constant value. -// +// template void fill(typename T::Pointer & a, @@ -4595,57 +4595,57 @@ fill(typename T::Pointer & a, itk::NumericTraits::Zero) { WRAP(itk_terminator_t terminator("fill")); - + // shortcuts: typedef typename T::IndexType ix_t; typedef typename T::RegionType rn_t; typedef typename T::SizeType sz_t; - + sz_t sz = a->GetLargestPossibleRegion().GetSize(); - + ix_t origin; origin[0] = x; origin[1] = y; - + sz_t extent; extent[0] = w; extent[1] = h; - + rn_t region; region.SetIndex(origin); region.SetSize(extent); - + typedef typename itk::ImageRegionIterator iter_t; iter_t iter(a, region); for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + ix_t ix = iter.GetIndex(); if (image_size_value_t(ix[0]) >= sz[0] || image_size_value_t(ix[1]) >= sz[1]) { continue; } - + iter.Set(fill_value); } } //---------------------------------------------------------------- // save_transform -// +// // Save an ITK transform to a stream. -// +// extern void save_transform(std::ostream & so, const itk::TransformBase * t); //---------------------------------------------------------------- // load_transform -// +// // Load an ITK transform of specified type from a stream. -// +// extern itk::TransformBase::Pointer load_transform(std::istream & si, const bfs::path & transform_type); @@ -4654,16 +4654,16 @@ load_transform(std::istream & si, const bfs::path & transform_type); // // Load transform type from the stream, then load the transform // of that type. -// +// extern itk::TransformBase::Pointer load_transform(std::istream & si); //---------------------------------------------------------------- // save_mosaic -// +// // Save image filenames and associated ITK transforms to a stream. -// +// extern void save_mosaic(std::ostream & so, const unsigned int & num_images, @@ -4676,7 +4676,7 @@ save_mosaic(std::ostream & so, // load_mosaic // // Load image filenames and associated ITK transforms from a stream. -// +// extern void load_mosaic(std::istream & si, double & pixel_spacing, @@ -4687,9 +4687,9 @@ load_mosaic(std::istream & si, //---------------------------------------------------------------- // save_mosaic -// +// // Save tile image names and associated ITK transforms to a stream. -// +// template void save_mosaic(std::ostream & so, @@ -4701,10 +4701,10 @@ save_mosaic(std::ostream & so, unsigned int num_images = transforms.size(); std::vector image(num_images); std::vector tbase(num_images); - + std::vector & ttmp = const_cast &>(transforms); - + std::list::const_iterator iter = images.begin(); for (unsigned int i = 0; i < images.size(); i++, ++iter) { @@ -4712,7 +4712,7 @@ save_mosaic(std::ostream & so, image[i] = *iter; tbase[i] = ttmp[i].GetPointer(); } - + save_mosaic(so, image.size(), pixel_spacing, @@ -4723,9 +4723,9 @@ save_mosaic(std::ostream & so, //---------------------------------------------------------------- // load_mosaic -// +// // Load tile image names and associated ITK transforms from a stream. -// +// template void load_mosaic(std::istream & si, @@ -4737,7 +4737,7 @@ load_mosaic(std::istream & si, { std::vector image; std::vector tbase; - + load_mosaic(si, pixel_spacing, use_std_mask, image, tbase); transforms.resize(tbase.size()); for (unsigned int i = 0; i < tbase.size(); i++) @@ -4745,10 +4745,10 @@ load_mosaic(std::istream & si, images.push_back(image[i]); transforms[i] = dynamic_cast(tbase[i].GetPointer()); } - + if ( image_path.empty() ) return; - + // Replace global paths for backwards compatibility. for (std::list::iterator iter = images.begin(); iter != images.end(); ++iter) @@ -4759,7 +4759,7 @@ load_mosaic(std::istream & si, //---------------------------------------------------------------- // histogram_equalization -// +// // Histogram Equalization. // Transformed image will be mapped into the new min/max pixel // range. If the new range is not specified, pixels will be @@ -4773,52 +4773,52 @@ histogram_equalization(const T * in, std::numeric_limits::max(), typename T::PixelType new_max = -std::numeric_limits::max(), - const mask_t * mask = NULL) + const mask_t * mask = nullptr) { // local typedefs: //typedef typename T::RegionType rn_t; typedef typename T::IndexType ix_t; typedef typename T::SizeType sz_t; typedef typename T::PixelType pixel_t; - + // range of the image intensities: pixel_t p_min; pixel_t p_max; image_min_max(in, p_min, p_max, mask); pixel_t p_rng = p_max - p_min; - + typename T::Pointer image = cast(in); - + if (p_rng == pixel_t(0)) { // nothing to do: return image; } - + if (new_min == std::numeric_limits::max()) new_min = p_min; if (new_max == -std::numeric_limits::max()) new_max = p_max; pixel_t new_rng = new_max - new_min; - + sz_t sz = in->GetLargestPossibleRegion().GetSize(); - + // initialize the histogram: std::vector pdf(bins); std::vector clipped_pdf(bins); std::vector cdf(bins); - + for (unsigned int i = 0; i < bins; i++) { pdf[i] = 0; clipped_pdf[i] = 0.0; cdf[i] = 0.0; } - + typedef typename itk::ImageRegionConstIteratorWithIndex iter_t; iter_t iter(in, in->GetLargestPossibleRegion()); for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { ix_t ix = iter.GetIndex(); - + if (pixel_in_mask(in, mask, ix)) { pixel_t p = iter.Get(); @@ -4828,20 +4828,20 @@ histogram_equalization(const T * in, pdf[bin]++; } } - + // build a cumulative distribution function (CDF): cdf[0] = static_cast(pdf[0]); for (unsigned int i = 1; i < bins; i++) { cdf[i] = cdf[i - 1] + static_cast(pdf[i]); } - + // update the image: iter = iter_t(in, in->GetLargestPossibleRegion()); for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { ix_t ix = iter.GetIndex(); - + // generate the output pixel: pixel_t p_out = new_min; if (pixel_in_mask(in, mask, ix)) @@ -4853,19 +4853,19 @@ histogram_equalization(const T * in, p_out = pixel_t(static_cast(new_min) + static_cast(new_rng) * static_cast(cdf[bin]) / static_cast(cdf[bins - 1])); } - + image->SetPixel(ix, p_out); } - + return image; } //---------------------------------------------------------------- // clip_histogram -// +// // This is used by CLAHE to limit the contrast ratio slope. -// +// extern void clip_histogram(const double & clipping_height, const unsigned int & pdf_size, @@ -4874,7 +4874,7 @@ clip_histogram(const double & clipping_height, //---------------------------------------------------------------- // CLAHE -// +// // Perform Contrast-Limited Adaptive Histogram Equalization // Transformed image will be mapped into the new min/max pixel // range. If the new range is not specified, pixels will be @@ -4891,14 +4891,14 @@ CLAHE(const T * in, std::numeric_limits::max(), typename T::PixelType new_max = -std::numeric_limits::max(), - const mask_t * mask = NULL) + const mask_t * mask = nullptr) { // local typedefs: //typedef typename T::RegionType rn_t; typedef typename T::IndexType ix_t; typedef typename T::SizeType sz_t; typedef typename T::PixelType pixel_t; - + // sanity check: // assert(nx > 1 && ny > 1); if ( nx <= 1 && ny <= 1 ) @@ -4922,43 +4922,43 @@ CLAHE(const T * in, pixel_t p_max; image_min_max(in, p_min, p_max, mask); pixel_t p_rng = p_max - p_min; - + typename T::Pointer image = cast(in); - + if (p_rng == pixel_t(0)) { // nothing to do: return image; } - + if (new_min == std::numeric_limits::max()) new_min = p_min; if (new_max == -std::numeric_limits::max()) new_max = p_max; pixel_t new_rng = new_max - new_min; - + sz_t sz = in->GetLargestPossibleRegion().GetSize(); const int image_w = sz[0]; const int image_h = sz[1]; - + // make sure the histogram window doesn't exceed the image: nx = std::min(nx, image_w); ny = std::min(ny, image_h); - + // calculate the histogram window center: const int cx = nx / 2; const int cy = ny / 2; - + // initialize the histogram: std::vector pdf(bins); std::vector clipped_pdf(bins); std::vector cdf(bins); - + for (unsigned int i = 0; i < bins; i++) { pdf[i] = 0; clipped_pdf[i] = 0.0; cdf[i] = 0.0; } - + for (int x = 0; x < nx; x++) { for (int y = 0; y < ny; y++) @@ -4966,7 +4966,7 @@ CLAHE(const T * in, ix_t ix; ix[0] = x; ix[1] = y; - + if (pixel_in_mask(in, mask, ix)) { pixel_t p = in->GetPixel(ix); @@ -4977,7 +4977,7 @@ CLAHE(const T * in, } } } - + // clip the histogram: if (max_slope != 0.0) { @@ -4992,14 +4992,14 @@ CLAHE(const T * in, clipped_pdf[i] = static_cast(pdf[i]); } } - + // build a cumulative distribution function (CDF): cdf[0] = static_cast(clipped_pdf[0]); for (unsigned int i = 1; i < bins; i++) { cdf[i] = cdf[i - 1] + static_cast(clipped_pdf[i]); } - + // start at the origin: int hist_x = cx; int hist_y = cy; @@ -5010,7 +5010,7 @@ CLAHE(const T * in, int y0 = (x % 2 == 0) ? 0 : image_h - 1; int y1 = (x % 2 == 0) ? image_h - 1 : 0; int dy = (x % 2 == 0) ? 1 : -1; - + for (int y = y0; y != (y1 + dy); y += dy) { //#else @@ -5021,7 +5021,7 @@ CLAHE(const T * in, // int x0 = (y % 2 == 0) ? 0 : image_w - 1; // int x1 = (y % 2 == 0) ? image_w - 1 : 0; // int dx = (y % 2 == 0) ? 1 : -1; -// +// // for (int x = x0; x != (x1 + dx); x += dx) // { // */ @@ -5030,13 +5030,13 @@ CLAHE(const T * in, int spill_y0 = std::max(0, cy - y); int spill_x1 = std::max(0, x - (image_w - nx + cx)); int spill_y1 = std::max(0, y - (image_h - ny + cy)); - + int new_hx = x + spill_x0 - spill_x1; int new_hy = y + spill_y0 - spill_y1; - + int shift_x = new_hx - hist_x; int shift_y = new_hy - hist_y; - + if (shift_x != 0) { // update the histogram (add-remove columns): @@ -5045,15 +5045,15 @@ CLAHE(const T * in, { CORE_THROW_EXCEPTION("bad histogram shift"); } - + for (int ty = 0; ty < ny; ty++) { ix_t ix; ix[1] = hist_y + ty - cy; - + // add: ix[0] = (shift_x > 0) ? new_hx - cx + nx - 1 : new_hx - cx; - + if (pixel_in_mask(in, mask, ix)) { pixel_t a = in->GetPixel(ix); @@ -5061,7 +5061,7 @@ CLAHE(const T * in, (static_cast(a - p_min) / static_cast(p_rng)) * static_cast(bins - 1)); pdf[bin]++; } - + // remove: ix[0] = (shift_x > 0) ? hist_x - cx : hist_x - cx + nx - 1; if (pixel_in_mask(in, mask, ix)) @@ -5072,10 +5072,10 @@ CLAHE(const T * in, pdf[bin]--; } } - + hist_x = new_hx; } - + if (shift_y != 0) { // update the histogram (add-remove rows): @@ -5084,12 +5084,12 @@ CLAHE(const T * in, { CORE_THROW_EXCEPTION("bad histogram shift"); } - + for (int tx = 0; tx < nx; tx++) { ix_t ix; ix[0] = hist_x + tx - cx; - + // add: ix[1] = (shift_y > 0) ? new_hy - cy + ny - 1 : new_hy - cy; if (pixel_in_mask(in, mask, ix)) @@ -5099,7 +5099,7 @@ CLAHE(const T * in, (static_cast(a - p_min) / static_cast(p_rng)) * static_cast(bins - 1)); pdf[bin]++; } - + // remove: ix[1] = (shift_y > 0) ? hist_y - cy : hist_y - cy + ny - 1; if (pixel_in_mask(in, mask, ix)) @@ -5110,10 +5110,10 @@ CLAHE(const T * in, pdf[bin]--; } } - + hist_y = new_hy; } - + if (shift_x != 0 || shift_y != 0) { // clip the histogram: @@ -5130,7 +5130,7 @@ CLAHE(const T * in, clipped_pdf[i] = static_cast(pdf[i]); } } - + // build a cumulative distribution function (CDF): cdf[0] = static_cast(clipped_pdf[0]); for (unsigned int i = 1; i < bins; i++) @@ -5138,12 +5138,12 @@ CLAHE(const T * in, cdf[i] = cdf[i - 1] + static_cast(clipped_pdf[i]); } } - + // generate the output pixel: ix_t ix; ix[0] = x; ix[1] = y; - + pixel_t p_out = new_min; if (pixel_in_mask(in, mask, ix)) { @@ -5153,20 +5153,20 @@ CLAHE(const T * in, p_out = pixel_t(static_cast(new_min) + static_cast(new_rng) * static_cast(cdf[bin]) / static_cast(cdf[bins - 1])); } - + image->SetPixel(ix, p_out); } } - + return image; } //---------------------------------------------------------------- // median -// +// // Return a copy of a given image de-noised with a median filter. -// +// template typename T::Pointer median(const T * a, const unsigned int & median_radius) @@ -5178,10 +5178,10 @@ median(const T * a, const unsigned int & median_radius) radius[1] = median_radius; filter->SetInput(a); filter->SetRadius(radius); - + // FIXME: // itk::SimpleFilterWatcher w(filter.GetPointer(), "median"); - + WRAP(terminator_t terminator(filter)); filter->Update(); return filter->GetOutput(); @@ -5190,10 +5190,10 @@ median(const T * a, const unsigned int & median_radius) //---------------------------------------------------------------- // normalize -// +// // Return a copy of the image normalized (pixels shifted and -// rescaled) using the -// +// rescaled) using the +// template typename T::Pointer normalize(const T * a, const mask_t * ma) @@ -5202,7 +5202,7 @@ normalize(const T * a, const mask_t * ma) typename filter_t::Pointer filter = filter_t::New(); filter->SetInput(a); filter->SetImageMask(mask_so(ma)); - + WRAP(terminator_t terminator(filter)); filter->Update(); return filter->GetOutput(); @@ -5212,7 +5212,7 @@ normalize(const T * a, const mask_t * ma) // calc_pixel_weight // // Calculate a pixel feathering weight used to blend mosaic tiles. -// +// inline double pixel_weight(const image_t::IndexType & min, const image_t::IndexType & max, @@ -5231,13 +5231,13 @@ pixel_weight(const image_t::IndexType & min, //---------------------------------------------------------------- // normalize -// +// // Tiled image normalization -- mean shift and rescale // pixel intensities to match a normal distribution. // Tiles overlap and the overlap regions are blended together. // Clip the pixels to the [-3, 3] range // and remap into the new [min, max] range. -// +// template typename T::Pointer normalize(const T * image, @@ -5247,10 +5247,10 @@ normalize(const T * image, std::numeric_limits::max(), typename T::PixelType new_max = -std::numeric_limits::max(), - const mask_t * mask = NULL) + const mask_t * mask = nullptr) { WRAP(itk_terminator_t terminator("normalize")); - + if (new_min == std::numeric_limits::max() || new_max == -std::numeric_limits::max()) { @@ -5258,38 +5258,38 @@ normalize(const T * image, typename T::PixelType p_min; typename T::PixelType p_max; image_min_max(image, p_min, p_max, mask); - + if (new_min == std::numeric_limits::max()) { new_min = p_min; } - + if (new_max == -std::numeric_limits::max()) { new_max = p_max; } } - + // split the image into a set of overlapping tiles: typename T::SizeType sz = image->GetLargestPossibleRegion().GetSize(); - + double half_tw = static_cast(sz[0]) / static_cast(cols + 1); double half_th = static_cast(sz[1]) / static_cast(rows + 1); - + typename T::Pointer out = cast(image); - + array2d(typename T::Pointer) tile; resize(tile, cols, rows); - + array2d(mask_t::Pointer) tile_mask; resize(tile_mask, cols, rows); - + array2d(typename T::IndexType) tile_min; resize(tile_min, cols, rows); - + array2d(typename T::IndexType) tile_max; resize(tile_max, cols, rows); - + for (unsigned int i = 0; i < cols; i++) { double x0 = static_cast(i) * half_tw; @@ -5297,7 +5297,7 @@ normalize(const T * image, double x1 = static_cast(ix0) + (x0 - static_cast(ix0)) + 2.0 * half_tw; unsigned int ix1 = std::min(static_cast(sz[0] - 1), static_cast(ceil(x1))); - + for (unsigned int j = 0; j < rows; j++) { double y0 = static_cast(j) * half_th; @@ -5305,25 +5305,25 @@ normalize(const T * image, double y1 = static_cast(iy0) + (y0 - static_cast(iy0)) + 2.0 * half_th; unsigned int iy1 = std::min(static_cast(sz[1] - 1), static_cast(ceil(y1))); - + tile_min[i][j][0] = ix0; tile_min[i][j][1] = iy0; tile_max[i][j][0] = ix1; tile_max[i][j][1] = iy1; - + tile[i][j] = crop(image, tile_min[i][j], tile_max[i][j]); tile_mask[i][j] = crop(mask, tile_min[i][j], tile_max[i][j]); - + typename T::Pointer v1 = normalize(tile[i][j], tile_mask[i][j]); - + typename T::Pointer v2 = threshold(v1, -3, 3, -3, 3); - + tile[i][j] = v2; } } - + // blend the tiles together: typedef itk::ImageRegionIteratorWithIndex itex_t; itex_t itex(out, out->GetLargestPossibleRegion()); @@ -5331,9 +5331,9 @@ normalize(const T * image, { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + typename T::IndexType ix = itex.GetIndex(); - + double wsum = 0.0; double mass = 0.0; for (unsigned int i = 0; i < cols; i++) @@ -5348,18 +5348,18 @@ normalize(const T * image, typename T::IndexType index; index[0] = ix[0] - tile_min[i][j][0]; index[1] = ix[1] - tile_min[i][j][1]; - + double weight = pixel_weight(tile_min[i][j], tile_max[i][j], ix); wsum += weight * tile[i][j]->GetPixel(index); mass += weight; } } } - + if (mass != 0.0) wsum /= mass; out->SetPixel(ix, wsum); - } - + } + remap_min_max_inplace(out, new_min, new_max); return out; } @@ -5367,10 +5367,10 @@ normalize(const T * image, //---------------------------------------------------------------- // forward_transform -// +// // Cascaded forward transform. This function assumes // that it is given a vector of forward transforms. -// +// template typename T::PointType forward_transform(const transform_vec_t & t, @@ -5387,11 +5387,11 @@ forward_transform(const transform_vec_t & t, //---------------------------------------------------------------- // inverse_transform -// +// // Cascaded inverse transform. This function assumes // that it is given a vector of inverse transforms t_inverse, // it will not call GetInverseTransform on any of them. -// +// template typename T::PointType inverse_transform(const transform_vec_t & t_inverse, @@ -5409,12 +5409,12 @@ inverse_transform(const transform_vec_t & t_inverse, //---------------------------------------------------------------- // flip -// +// // Flip an image around vertical and/or horizontal axis. -// +// // flip_x -- flip around the vertical axis // flip_y -- flip around the horizontal axis. -// +// template typename T::Pointer flip(const T * in, @@ -5422,99 +5422,99 @@ flip(const T * in, const bool flip_y = false) { WRAP(itk_terminator_t terminator("flip")); - + // local typedefs: typedef typename T::RegionType rn_t; typedef typename T::IndexType ix_t; typedef typename T::SizeType sz_t; - + typename T::Pointer out = cast(in); - + if (flip_x || flip_y) { rn_t rn = in->GetLargestPossibleRegion(); sz_t sz = rn.GetSize(); - + typedef itk::ImageRegionIteratorWithIndex itex_t; itex_t itex(out, rn); - + for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { // make sure there hasn't been an interrupt: WRAP(terminator.terminate_on_request()); - + ix_t ix = itex.GetIndex(); if (flip_x) ix[0] = sz[0] - ix[0] - 1; if (flip_y) ix[1] = sz[1] - ix[1] - 1; - + itex.Set(in->GetPixel(ix)); } } - + return out; } //---------------------------------------------------------------- // overlap_ratio -// +// // Calculate the ratio of the overlap region area to the area // of the smaller image. -// +// template double overlap_ratio(const T * fi, const T * mi, const base_transform_t * fi_to_mi) { - if (fi_to_mi == NULL) return 0.0; - + if (fi_to_mi == nullptr) return 0.0; + typename T::PointType fi_min = fi->GetOrigin(); typename T::PointType mi_min = mi->GetOrigin(); - + typename T::SpacingType fi_sp = fi->GetSpacing(); typename T::SpacingType mi_sp = mi->GetSpacing(); - + typename T::SizeType fi_sz = fi->GetLargestPossibleRegion().GetSize(); typename T::SizeType mi_sz = mi->GetLargestPossibleRegion().GetSize(); - + typename T::PointType fi_max = fi_min + vec2d((fi_sz[0]) * fi_sp[0], (fi_sz[1]) * fi_sp[1]); - + typename T::PointType mi_max = mi_min + vec2d((mi_sz[0]) * mi_sp[0], (mi_sz[1]) * mi_sp[1]); - + const double w0 = fi_max[0] - fi_min[0]; const double h0 = fi_max[1] - fi_min[1]; - + const double w1 = mi_max[0] - mi_min[0]; const double h1 = mi_max[1] - mi_min[1]; - + const double smaller_area = std::min(w0, w1) * std::min(h0, h1); - + typename T::PointType ul = fi_to_mi->TransformPoint(fi_min); ul[0] = std::max(0.0, std::min(w1, ul[0] - mi_min[0])); ul[1] = std::max(0.0, std::min(h1, ul[1] - mi_min[1])); - + typename T::PointType lr = fi_to_mi->TransformPoint(fi_max); lr[0] = std::max(0.0, std::min(w1, lr[0] - mi_min[0])); lr[1] = std::max(0.0, std::min(h1, lr[1] - mi_min[1])); - + const double dx = lr[0] - ul[0]; const double dy = lr[1] - ul[1]; const double area_ratio = (dx * dy) / smaller_area; - + return area_ratio; } //---------------------------------------------------------------- // find_inverse -// -// Given a forward transform and image space coordinates, +// +// Given a forward transform and image space coordinates, // find mosaic space coordinates. -// +// extern bool find_inverse(const pnt2d_t & tile_min, // tile space const pnt2d_t & tile_max, // tile space @@ -5528,10 +5528,10 @@ find_inverse(const pnt2d_t & tile_min, // tile space //---------------------------------------------------------------- // find_inverse -// +// // Given a forward transform, an approximate inverse transform, // and image space coordinates, find mosaic space coordinates. -// +// extern bool find_inverse(const pnt2d_t & tile_min, // tile space const pnt2d_t & tile_max, // tile space @@ -5546,10 +5546,10 @@ find_inverse(const pnt2d_t & tile_min, // tile space //---------------------------------------------------------------- // find_inverse -// +// // Given a forward transform, an approximate inverse transform, // and image space coordinates, find mosaic space coordinates. -// +// extern bool find_inverse(const base_transform_t * mosaic_to_tile, // forward transform const base_transform_t * tile_to_mosaic, // inverse transform @@ -5562,15 +5562,15 @@ find_inverse(const base_transform_t * mosaic_to_tile, // forward transform //---------------------------------------------------------------- // generate_landmarks -// +// // Given a forward transform, generate a set of image space // coordinates and find their matching mosaic space coordinates. -// +// // version 1 -- uniform jittered sampling over the tile // version 2 -- non-uniform sampling skewed towards the center // of the tile radially. This may be useful when // the transform is ill-behaved at the tile edges. -// +// extern bool generate_landmarks(const pnt2d_t & tile_min, const pnt2d_t & tile_max, @@ -5584,7 +5584,7 @@ generate_landmarks(const pnt2d_t & tile_min, //---------------------------------------------------------------- // generate_landmarks -// +// // Given a forward transform, generate a set of image space // coordinates and find their matching mosaic space coordinates. // @@ -5592,7 +5592,7 @@ generate_landmarks(const pnt2d_t & tile_min, // version 2 -- non-uniform sampling skewed towards the center // of the tile radially. This may be useful when // the transform is ill-behaved at the tile edges. -// +// extern bool generate_landmarks(const image_t * tile, const mask_t * mask, @@ -5605,15 +5605,15 @@ generate_landmarks(const image_t * tile, //---------------------------------------------------------------- // approx_transform -// +// // Given a forward Legendre polynomial transform, solve for // transform parameters of the inverse Legendre polynomial transform. -// +// // version 1 -- uniform jittered sampling over the tile // version 2 -- non-uniform sampling skewed towards the center // of the tile radially. This may be useful when // the transform is ill-behaved at the tile edges. -// +// template typename legendre_transform_t::Pointer approx_transform(const pnt2d_t & tile_min, @@ -5625,21 +5625,21 @@ approx_transform(const pnt2d_t & tile_min, const bool refine = false) { base_transform_t::Pointer inverse = forward->GetInverseTransform(); -// assert(inverse.GetPointer() != NULL); - if (inverse.GetPointer() == NULL) +// assert(inverse.GetPointer() != nullptr); + if (inverse.GetPointer() == nullptr) { CORE_THROW_EXCEPTION("Null inverse transform"); } - + // calculate the shift: pnt2d_t center = pnt2d(tile_min[0] + (tile_max[0] - tile_min[0]) / 2.0, tile_min[1] + (tile_max[1] - tile_min[1]) / 2.0); vec2d_t shift = center - inverse->TransformPoint(center); - + typename legendre_transform_t::Pointer approx = setup_transform(tile_min, tile_max); approx->setup_translation(shift[0], shift[1]); - + std::vector xy; std::vector uv; generate_landmarks(tile_min, @@ -5651,32 +5651,32 @@ approx_transform(const pnt2d_t & tile_min, uv, version, refine); - + unsigned int order = legendre_transform_t::Degree + 1; unsigned int loworder = std::min(2u, order); - + //#if 1 approx->solve_for_parameters(0, loworder, uv, xy); approx->solve_for_parameters(loworder, order - loworder, uv, xy); //#else // approx->solve_for_parameters(0, order, uv, xy); //#endif - + return approx; } //---------------------------------------------------------------- // solve_for_transform -// +// // Given a forward transform and a gross translation vector for // the inverse mapping, solve for transform parameters of the // inverse Legendre polynomial transform. -// +// // version 1 -- uniform jittered sampling over the tile // version 2 -- non-uniform sampling skewed towards the center // of the tile radially. This may be useful when // the transform is ill-behaved at the tile edges. -// +// template void solve_for_transform(const pnt2d_t & tile_min, @@ -5690,13 +5690,13 @@ solve_for_transform(const pnt2d_t & tile_min, const bool refine = false) { mosaic_to_tile_1->setup_translation(shift[0], shift[1]); - + //#if 0 // // FIXME: // cerr << "SHIFT: " << shift << endl // << "ROUGH: " << mosaic_to_tile_1->GetParameters() << endl; //#endif - + std::vector xy; std::vector uv; generate_landmarks(tile_min, @@ -5708,17 +5708,17 @@ solve_for_transform(const pnt2d_t & tile_min, uv, version, refine); - + unsigned int order = legendre_transform_t::Degree + 1; unsigned int loworder = std::min(2u, order); - + //#if 1 mosaic_to_tile_1->solve_for_parameters(0, loworder, uv, xy); mosaic_to_tile_1->solve_for_parameters(loworder, order - loworder, uv, xy); //#else // mosaic_to_tile_1->solve_for_parameters(0, order, uv, xy); //#endif - + //#if 0 // // FIXME: // cerr << "FINAL: " << mosaic_to_tile_1->GetParameters() << endl; @@ -5727,16 +5727,16 @@ solve_for_transform(const pnt2d_t & tile_min, //---------------------------------------------------------------- // solve_for_transform -// +// // Given a forward transform and a gross translation vector for // the inverse mapping, solve for transform parameters of the // inverse Legendre polynomial transform. -// +// // version 1 -- uniform jittered sampling over the tile // version 2 -- non-uniform sampling skewed towards the center // of the tile radially. This may be useful when // the transform is ill-behaved at the tile edges. -// +// template void solve_for_transform(const T * tile, @@ -5753,7 +5753,7 @@ solve_for_transform(const T * tile, const pnt2d_t min = tile->GetOrigin(); const pnt2d_t max = min + vec2d(sp[0] * static_cast(sz[0]), sp[1] * static_cast(sz[1])); - + solve_for_transform(min, max, mask, @@ -5767,15 +5767,15 @@ solve_for_transform(const T * tile, //---------------------------------------------------------------- // solve_for_transform -// +// // Given a forward transform, solve for transform parameters of // the inverse Legendre polynomial transform. -// +// // version 1 -- uniform jittered sampling over the tile // version 2 -- non-uniform sampling skewed towards the center // of the tile radially. This may be useful when // the transform is ill-behaved at the tile edges. -// +// template void solve_for_transform(const pnt2d_t & tile_min, @@ -5788,17 +5788,17 @@ solve_for_transform(const pnt2d_t & tile_min, const bool refine = false) { base_transform_t::Pointer tile_to_mosaic = mosaic_to_tile_0->GetInverseTransform(); -// assert(tile_to_mosaic.GetPointer() != NULL); - if (tile_to_mosaic.GetPointer() == NULL) +// assert(tile_to_mosaic.GetPointer() != nullptr); + if (tile_to_mosaic.GetPointer() == nullptr) { CORE_THROW_EXCEPTION("Null inverse transform"); } - + // calculate the shift: pnt2d_t center = pnt2d(tile_min[0] + (tile_max[0] - tile_min[0]) / 2.0, tile_min[1] + (tile_max[1] - tile_min[1]) / 2.0); vec2d_t shift = center - tile_to_mosaic->TransformPoint(center); - + solve_for_transform(tile_min, tile_max, tile_mask, @@ -5815,12 +5815,12 @@ solve_for_transform(const pnt2d_t & tile_min, // // Given a forward transform, solve for transform parameters of // the inverse Legendre polynomial transform. -// +// // version 1 -- uniform jittered sampling over the tile // version 2 -- non-uniform sampling skewed towards the center // of the tile radially. This may be useful when // the transform is ill-behaved at the tile edges. -// +// template void solve_for_transform(const T * tile, @@ -5832,19 +5832,19 @@ solve_for_transform(const T * tile, const bool refine = false) { base_transform_t::Pointer tile_to_mosaic = mosaic_to_tile_0->GetInverseTransform(); -// assert(tile_to_mosaic.GetPointer() != NULL); - if (tile_to_mosaic.GetPointer() == NULL) +// assert(tile_to_mosaic.GetPointer() != nullptr); + if (tile_to_mosaic.GetPointer() == nullptr) { CORE_THROW_EXCEPTION("Null inverse transform"); } - + typename T::SizeType sz = tile->GetLargestPossibleRegion().GetSize(); typename T::SpacingType sp = tile->GetSpacing(); pnt2d_t tile_min = tile->GetOrigin(); pnt2d_t tile_max; tile_max[0] = tile_min[0] + sp[0] * static_cast(sz[0]); tile_max[1] = tile_min[1] + sp[1] * static_cast(sz[1]); - + return solve_for_transform(tile_min, tile_max, mask, @@ -5858,10 +5858,10 @@ solve_for_transform(const T * tile, //---------------------------------------------------------------- // std_mask -// +// // Given image dimensions, generate a mask image. // use_std_mask -- the standard mask for the Robert Marc Lab data. -// +// extern mask_t::Pointer std_mask(const itk::Point & origin, const itk::Vector & spacing, @@ -5870,10 +5870,10 @@ std_mask(const itk::Point & origin, //---------------------------------------------------------------- // std_mask -// +// // Given an image, generate a matching mask image. // use_std_mask -- the standard mask for the Robert Marc Lab data. -// +// template mask_t::Pointer std_mask(const T * tile, bool use_std_mask = true) @@ -5891,7 +5891,7 @@ std_mask(const T * tile, bool use_std_mask = true) // spacing as specified. Downscale the image according to the // shrink factor. If clahe_slope is greater than 1 then process // the image with the CLAHE algorithm. -// +// template typename T::Pointer std_tile(const bfs::path& fn_image, @@ -5902,30 +5902,30 @@ std_tile(const bfs::path& fn_image, const bool & blab) { typename T::Pointer image = load(fn_image, blab); - + // reset the tile image origin and spacing: typename T::PointType origin = image->GetOrigin(); origin[0] = 0; origin[1] = 0; image->SetOrigin(origin); - + typename T::SpacingType spacing = image->GetSpacing(); spacing[0] = 1; spacing[1] = 1; image->SetSpacing(spacing); - + // don't blur the images unnecessarily: if (shrink_factor > 1) { image = shrink(image, shrink_factor); } - + typename T::SpacingType sp = image->GetSpacing(); - + sp[0] *= pixel_spacing; sp[1] *= pixel_spacing; image->SetSpacing(sp); - + if (clahe_slope > 1.0) { image = CLAHE(image, @@ -5936,17 +5936,17 @@ std_tile(const bfs::path& fn_image, 0, // new min 1); // new max } - + return image; } //---------------------------------------------------------------- // std_tile -// +// // Load a mosaic tile image, reset the origin to zero, set pixel // spacing as specified. Downscale the image according to the // shrink factor. -// +// template typename T::Pointer std_tile(const bfs::path& fn_image, @@ -5967,7 +5967,7 @@ std_tile(const bfs::path& fn_image, // // Save a volume slice transform. This is used by ir-stom-approx // to generate the .stom files. -// +// template void save_volume_slice(std::ostream & so, @@ -5985,7 +5985,7 @@ save_volume_slice(std::ostream & so, std::ios::fmtflags old_flags = so.setf(std::ios::scientific); int old_precision = so.precision(); so.precision(12); - + so << "index: " << index << std::endl << "overall_min: " << overall_min[0] << ' ' << overall_min[1] << std::endl << "overall_max: " << overall_max[0] << ' ' << overall_max[1] << std::endl @@ -5997,17 +5997,17 @@ save_volume_slice(std::ostream & so, << image << std::endl; save_transform(so, transform); so << std::endl; - + so.setf(old_flags); so.precision(old_precision); } //---------------------------------------------------------------- // load_volume_slice -// +// // Load a volume slice transform. This is used by ir-slice // to assemble a volume slice image from a given .stom file. -// +// template void load_volume_slice(std::istream & si, @@ -6027,7 +6027,7 @@ load_volume_slice(std::istream & si, std::string token; si >> token; if (si.eof() && token.size() == 0) break; - + if (token == "index:") { si >> index; @@ -6071,11 +6071,11 @@ load_volume_slice(std::istream & si, CORE_LOG_WARNING(oss.str()); } } - + itk::TransformBase::Pointer t_base = load_transform(si); transform = dynamic_cast(t_base.GetPointer()); -// assert(transform.GetPointer() != NULL); - if (transform.GetPointer() == NULL) +// assert(transform.GetPointer() != nullptr); + if (transform.GetPointer() == nullptr) { CORE_THROW_EXCEPTION("Null transform"); } @@ -6092,10 +6092,10 @@ load_volume_slice(std::istream & si, //---------------------------------------------------------------- // calc_size -// +// // Given a bounding box expressed in the image space and // pixel spacing, calculate corresponding image size. -// +// extern image_t::SizeType calc_size(const pnt2d_t & min, const pnt2d_t & max, @@ -6103,9 +6103,9 @@ calc_size(const pnt2d_t & min, //---------------------------------------------------------------- // track_progress -// +// // Sets the current progress for determining the overall percentage -// +// inline static void track_progress(bool track) { @@ -6117,9 +6117,9 @@ track_progress(bool track) //---------------------------------------------------------------- // set_major_progress -// +// // Sets the current progress for determining the overall percentage -// +// inline static void set_major_progress(double major_percent) { @@ -6130,10 +6130,10 @@ set_major_progress(double major_percent) //---------------------------------------------------------------- // set_minor_progress -// +// // Sets the current progress for determining the percentage of this // particular task. -// +// inline static void set_minor_progress(double minor_percent, double major_percent) { diff --git a/src/Core/ITKCommon/extrema.hxx b/src/Core/ITKCommon/extrema.hxx index 723a19ff1..286a17c72 100644 --- a/src/Core/ITKCommon/extrema.hxx +++ b/src/Core/ITKCommon/extrema.hxx @@ -82,7 +82,7 @@ public: class descriptor_t { public: - descriptor_t(extrema_t * extrema = NULL): + descriptor_t(extrema_t * extrema = nullptr): extrema_(extrema) {} @@ -121,7 +121,7 @@ class ext_wrapper_t { public: ext_wrapper_t(): - key_(NULL) + key_(nullptr) {} // vector-like accessor to the extrema target space coordinates: @@ -139,7 +139,7 @@ class key_wrapper_t { public: key_wrapper_t(): - key_(NULL) + key_(nullptr) {} // vector-like accessor to the key descriptor: diff --git a/src/Core/ITKCommon/grid_common.cxx b/src/Core/ITKCommon/grid_common.cxx index 892900574..b5fc8b9a3 100644 --- a/src/Core/ITKCommon/grid_common.cxx +++ b/src/Core/ITKCommon/grid_common.cxx @@ -72,7 +72,7 @@ setup_grid_transform(the_grid_transform_t & transform, // the mosaic to tile transform is typically more stable: approx_transform_t::Pointer mosaic_to_tile_approx; - if (gt == NULL) + if (gt == nullptr) { mosaic_to_tile_approx = approx_transform(tile_min, @@ -103,7 +103,7 @@ setup_grid_transform(the_grid_transform_t & transform, pnt2d_t & xy = xy_arr[index]; pnt2d_t & xy_approx = xy_apx[index]; - if (gt == NULL) + if (gt == nullptr) { // general transform: if (!find_inverse(tile_min, @@ -223,7 +223,7 @@ setup_mesh_transform(the_mesh_transform_t & transform, // the mosaic to tile transform is typically more stable: approx_transform_t::Pointer mosaic_to_tile_approx; - if (gt == NULL) + if (gt == nullptr) { mosaic_to_tile_approx = approx_transform(tile_min, @@ -257,7 +257,7 @@ setup_mesh_transform(the_mesh_transform_t & transform, pnt2d_t & xy_approx = xy_apx[index]; uv_list[index] = pq; - if (gt == NULL) + if (gt == nullptr) { // general transform: if (!find_inverse(tile_min, diff --git a/src/Core/ITKCommon/grid_common.hxx b/src/Core/ITKCommon/grid_common.hxx index b8827981b..f5d0bfa92 100644 --- a/src/Core/ITKCommon/grid_common.hxx +++ b/src/Core/ITKCommon/grid_common.hxx @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -67,12 +67,12 @@ namespace bfs=boost::filesystem; //---------------------------------------------------------------- // DEBUG_REFINE_ONE_POINT -// +// // #define DEBUG_REFINE_ONE_POINT //---------------------------------------------------------------- // DEBUG_ESTIMATE_DISPLACEMENT -// +// // #define DEBUG_ESTIMATE_DISPLACEMENT #if defined(DEBUG_REFINE_ONE_POINT) || defined(DEBUG_ESTIMATE_DISPLACEMENT) @@ -82,7 +82,7 @@ static int COUNTER = 0; //---------------------------------------------------------------- // optimizer_t -// +// typedef itk::RegularStepGradientDescentOptimizer2 optimizer_t; @@ -105,7 +105,7 @@ setup_grid_transform(the_grid_transform_t & transform, //---------------------------------------------------------------- // setup_mesh_transform -// +// extern bool setup_mesh_transform(the_mesh_transform_t & transform, unsigned int rows, @@ -126,48 +126,48 @@ template void estimate_displacement(double & best_metric, // current best metric translate_transform_t::Pointer & best_transform, - + // origin offset of the small neighborhood of image A // within the large image A: const vec2d_t & offset, - + const TImage * a, // large image A const TImage * b, // small image B - + // this could be the size of B (ususally when matching // small neighborhoods in A and B), or the // maximum dimesions of A and B (plain image matching): const typename TImage::SizeType & period_sz, - + const local_max_t & lm, const double overlap_min = 0.05, const double overlap_max = 1.0, - const mask_t * mask_a = NULL, - const mask_t * mask_b = NULL, - + const mask_t * mask_a = nullptr, + const mask_t * mask_b = nullptr, + const unsigned int num_perms = 4) { vec2d_t best_offset = best_transform->GetOffset(); - + const unsigned int & w = period_sz[0]; const unsigned int & h = period_sz[1]; - + typedef typename TImage::SpacingType spacing_t; spacing_t spacing = b->GetSpacing(); double sx = spacing[0]; double sy = spacing[1]; - + // evaluate 4 permutation of the maxima: const double x = lm.x_; const double y = lm.y_; - + const vec2d_t t[] = { vec2d(sx * x, sy * y), vec2d(sx * (x - w), sy * y), vec2d(sx * x, sy * (y - h)), vec2d(sx * (x - w), sy * (y - h)) }; - + #ifdef DEBUG_ESTIMATE_DISPLACEMENT static const bfs::path fn_save("/tmp/estimate_displacement-"); static int COUNTER2 = 0; @@ -175,7 +175,7 @@ estimate_displacement(double & best_metric, // current best metric the_text_t::number(COUNTER, 3, '0') + "-" + the_text_t::number(COUNTER2, 3, '0') + "-"; COUNTER2++; - + // FIXME: { translate_transform_t::Pointer ti = translate_transform_t::New(); @@ -188,22 +188,22 @@ estimate_displacement(double & best_metric, // current best metric mask_b); } #endif - + std::ostringstream oss; for (unsigned int i = 0; i < num_perms; i++) { translate_transform_t::Pointer ti = translate_transform_t::New(); ti->SetOffset(t[i] - offset); - + double area_ratio = overlap_ratio(a, b, ti); oss << i << ": " << std::setw(3) << static_cast(area_ratio * 100.0) << "% of overlap, "; - + if (area_ratio < overlap_min || area_ratio > overlap_max) { oss << "skipping..." << std::endl; continue; } - + //#if 0 // typedef itk::LinearInterpolateImageFunction interpolator_t; // // typedef itk::MeanSquaresImageToImageMetric metric_t; @@ -224,14 +224,14 @@ estimate_displacement(double & best_metric, // current best metric overlap_min, overlap_max); //#endif - + oss << metric; if (metric < best_metric) { best_offset = t[i]; best_metric = metric; oss << " - better..." << std::endl; - + #ifdef DEBUG_ESTIMATE_DISPLACEMENT // FIXME: save_rgb(fn_save + suffix + @@ -256,7 +256,7 @@ estimate_displacement(double & best_metric, // current best metric //---------------------------------------------------------------- // match_one_pair -// +// // match two images, find the best matching transform and // return the corresponding match metric value // @@ -265,52 +265,52 @@ double match_one_pair(translate_transform_t::Pointer & best_transform, const TImage * fi, const mask_t * fi_mask, - + const TImage * mi, const mask_t * mi_mask, - + // this could be the size of B (ususally when matching // small neighborhoods in A and B), or the // maximum dimesions of A and B (plain image matching): const typename TImage::SizeType & period_sz, - + const double & overlap_min, const double & overlap_max, - + image_t::PointType offset_min, image_t::PointType offset_max, - + const double & lp_filter_r, const double & lp_filter_s, - + const unsigned int max_peaks, const bool & consider_zero_displacement) { static const vec2d_t offset = vec2d(0, 0); - best_transform = NULL; - + best_transform = nullptr; + std::list max_list; unsigned int total_peaks = find_correlation(max_list, fi, mi, lp_filter_r, lp_filter_s); - + unsigned int num_peaks = reject_negligible_maxima(max_list, 2.0); std::ostringstream oss; oss << num_peaks << '/' << total_peaks << " eligible peaks, "; - + if (num_peaks > max_peaks) { oss << "skipping..." << std::endl; CORE_LOG_MESSAGE(oss.str()); return std::numeric_limits::max(); } - + double best_metric = std::numeric_limits::max(); best_transform = translate_transform_t::New(); best_transform->SetIdentity(); - + if (consider_zero_displacement) { // make sure to consider the no-displacement case: @@ -327,17 +327,17 @@ match_one_pair(translate_transform_t::Pointer & best_transform, mi_mask, 1); // don't try permutations } - + // choose the best peak: for (std::list::iterator j = max_list.begin(); j != max_list.end(); ++j) { oss << "evaluating permutations..." << std::endl; const local_max_t & lm = *j; - + double prev_metric = best_metric; vec2d_t prev_offset = best_transform->GetOffset(); - + estimate_displacement(best_metric, best_transform, offset, @@ -349,7 +349,7 @@ match_one_pair(translate_transform_t::Pointer & best_transform, overlap_max, fi_mask, mi_mask); - + // re-evaluate the overlap in the context of the small neighborhoods: double overlap = overlap_ratio(fi, mi, best_transform); if (overlap < overlap_min || overlap > overlap_max) @@ -359,14 +359,14 @@ match_one_pair(translate_transform_t::Pointer & best_transform, } } CORE_LOG_MESSAGE(oss.str()); - + return best_metric; } //---------------------------------------------------------------- // match_one_pair -// +// // match two images, find the best matching transform and // return the corresponding match metric value // @@ -375,55 +375,55 @@ double match_one_pair(translate_transform_t::Pointer & best_transform, const TImage * fi_large, const mask_t * fi_large_mask, - + const TImage * fi, const mask_t * /* fi_mask */, - + const TImage * mi, const mask_t * mi_mask, - + // origin offset of the small fixed image neighborhood // within the full image: const vec2d_t & offset, - + const double & overlap_min, const double & overlap_max, - + //image_t::PointType offset_min, //image_t::PointType offset_max, - + const double & lp_filter_r, const double & lp_filter_s, - + const unsigned int max_peaks, const bool & consider_zero_displacement) { - best_transform = NULL; - + best_transform = nullptr; + std::list max_list; unsigned int total_peaks = find_correlation(max_list, fi, mi, lp_filter_r, lp_filter_s); - + unsigned int num_peaks = reject_negligible_maxima(max_list, 2.0); std::ostringstream oss; oss << num_peaks << '/' << total_peaks << " eligible peaks, "; - + if (num_peaks > max_peaks) { oss << "skipping..." << std::endl; CORE_LOG_MESSAGE(oss.str()); return std::numeric_limits::max(); } - + double best_metric = std::numeric_limits::max(); best_transform = translate_transform_t::New(); best_transform->SetIdentity(); - + typename TImage::SizeType period_sz = mi->GetLargestPossibleRegion().GetSize(); - + if (consider_zero_displacement) { // make sure to consider the no-displacement case: @@ -440,17 +440,17 @@ match_one_pair(translate_transform_t::Pointer & best_transform, mi_mask, 1); // don't try permutations } - + // choose the best peak: for (std::list::iterator j = max_list.begin(); j != max_list.end(); ++j) { oss << "evaluating permutations..." << std::endl; const local_max_t & lm = *j; - + double prev_metric = best_metric; vec2d_t prev_offset = best_transform->GetOffset(); - + estimate_displacement(best_metric, best_transform, offset, @@ -462,7 +462,7 @@ match_one_pair(translate_transform_t::Pointer & best_transform, overlap_max, fi_large_mask, mi_mask); - + // re-evaluate the overlap in the context of the small neighborhoods: double overlap = overlap_ratio(fi, mi, best_transform); if (overlap < overlap_min || overlap > overlap_max) @@ -472,7 +472,7 @@ match_one_pair(translate_transform_t::Pointer & best_transform, } } CORE_LOG_MESSAGE(oss.str()); - + return best_metric; } @@ -484,11 +484,11 @@ template bool refine_one_point_fft(vec2d_t & shift, const pnt2d_t & origin, - + // the large images and their masks: const TImage * tile_0, const mask_t * mask_0, - + // the extracted small neighborhoods and their masks: const TImage * img_0, const mask_t * msk_0, @@ -499,50 +499,50 @@ refine_one_point_fft(vec2d_t & shift, translate_transform_t::Pointer translate; double metric = match_one_pair(translate, // best translation transform - + // fixed image in full: tile_0, mask_0, - + // fixed image small neighborhood: img_0, msk_0, - + // moving image small neighborhood: img_1, msk_1, - + // origin offset of the small fixed image // neighborhood in the large image: vec2d(origin[0], origin[1]), - + 0.25,// overlap min 1.0, // overlap max 0.5, // low pass filter r 0.1, // low pass filter s 10, // number of peaks true); // consider the no-displacement case - + #ifdef DEBUG_REFINE_ONE_POINT static const bfs::path fn_save("/tmp/refine_one_point_fft-"); bfs::path suffix = the_text_t::number(COUNTER, 3, '0'); - + save_composite(fn_save + suffix + "-a.png", img_0, img_1, identity_transform_t::New(), true); #endif // DEBUG_REFINE_ONE_POINT - + #if defined(DEBUG_REFINE_ONE_POINT) || defined(DEBUG_ESTIMATE_DISPLACEMENT) COUNTER++; #endif - + if (metric == std::numeric_limits::max()) { return false; } - + #ifdef DEBUG_REFINE_ONE_POINT save_composite(fn_save + suffix + "-b.png", img_0, @@ -550,7 +550,7 @@ refine_one_point_fft(vec2d_t & shift, translate.GetPointer(), true); #endif // DEBUG_REFINE_ONE_POINT - + shift = -translate->GetOffset(); return true; } @@ -558,29 +558,29 @@ refine_one_point_fft(vec2d_t & shift, //---------------------------------------------------------------- // refine_one_point_helper -// +// template bool refine_one_point_helper(const pnt2d_t & center, const pnt2d_t & origin, const double & min_overlap, - + // the large images and their masks: const TImage * tile_0, const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - + // transform that maps from the space of // tile 0 to the space of tile 1: const base_transform_t * t_01, - + // the extracted small neighborhoods and their masks: TImage * img_0, mask_t * msk_0, TImage * img_1, mask_t * msk_1, - + // neighborhood size and pixel spacing: const typename TImage::SizeType & sz, const typename TImage::SpacingType & sp) @@ -591,25 +591,25 @@ refine_one_point_helper(const pnt2d_t & center, interpolator_t::New(), interpolator_t::New() }; - + interpolator[0]->SetInputImage(tile_0); interpolator[1]->SetInputImage(tile_1); - + if (!interpolator[0]->IsInsideBuffer(center)) { // don't bother extracting neigborhoods if the neighborhood center // doesn't fall inside both images: return false; } - + // temporaries: pnt2d_t mosaic_pt; pnt2d_t tile_pt; typename TImage::IndexType index; - + // keep count of pixel in the neighborhood: unsigned int area[] = { 0, 0 }; - + // extract a neighborhood of the given point from both tiles: for (unsigned int y = 0; y < sz[1]; y++) { @@ -619,7 +619,7 @@ refine_one_point_helper(const pnt2d_t & center, { mosaic_pt[0] = origin[0] + double(x) * sp[0]; index[0] = x; - + // fixed image: tile_pt = mosaic_pt; if (interpolator[0]->IsInsideBuffer(tile_pt) && @@ -635,7 +635,7 @@ refine_one_point_helper(const pnt2d_t & center, img_0->SetPixel(index, 0); msk_0->SetPixel(index, 0); } - + // moving image: tile_pt = t_01->TransformPoint(mosaic_pt); if (interpolator[1]->IsInsideBuffer(tile_pt) && @@ -653,19 +653,19 @@ refine_one_point_helper(const pnt2d_t & center, } } } - + // skip points which don't have enough neighborhood information: double max_area = double(sz[0] * sz[1]); double a[] = { double(area[0]) / max_area, double(area[1]) / max_area }; - + if (a[0] < min_overlap || a[1] < min_overlap) { return false; } - + return true; } @@ -678,23 +678,23 @@ refine_one_point_fft(vec2d_t & shift, const pnt2d_t & center, const pnt2d_t & origin, const double & min_overlap, - + // the large images and their masks: const TImage * tile_0, const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - + // transform that maps from the space of // tile 0 to the space of tile 1: const base_transform_t * t_01, - + // the extracted small neighborhoods and their masks: TImage * img_0, mask_t * msk_0, TImage * img_1, mask_t * msk_1, - + // neighborhood size and pixel spacing: const typename TImage::SizeType & sz, const typename TImage::SpacingType & sp) @@ -716,7 +716,7 @@ refine_one_point_fft(vec2d_t & shift, { return false; } - + return refine_one_point_fft(shift, origin, tile_0, @@ -735,16 +735,16 @@ bool refine_one_point_fft(vec2d_t & shift, const pnt2d_t & center, const double & min_overlap, - + const TImage * tile_0, const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - + // transform that maps from the space of // tile 0 to the space of tile 1: const base_transform_t * t_01, - + // neighborhood size: const unsigned int & neighborhood) { @@ -752,26 +752,26 @@ refine_one_point_fft(vec2d_t & shift, typename TImage::SizeType sz; sz[0] = neighborhood; sz[1] = neighborhood; - + pnt2d_t origin(center); origin[0] -= 0.5 * double(sz[0]) * sp[0]; origin[1] -= 0.5 * double(sz[1]) * sp[1]; - + typename TImage::Pointer img[] = { make_image(sz), make_image(sz) }; - + mask_t::Pointer msk[] = { make_image(sz), make_image(sz) }; - + img[0]->SetSpacing(sp); img[1]->SetSpacing(sp); msk[0]->SetSpacing(sp); msk[1]->SetSpacing(sp); - + return refine_one_point_fft(shift, center, origin, @@ -795,7 +795,7 @@ refine_one_point_fft(vec2d_t & shift, template bool refine_one_point_fft(vec2d_t & shift, - + // the extracted small neighborhoods and their masks: const TImage * img_0, const mask_t * msk_0, @@ -804,49 +804,49 @@ refine_one_point_fft(vec2d_t & shift, { typename TImage::SizeType period_sz = img_1->GetLargestPossibleRegion().GetSize(); - + // feed the two neighborhoods into the FFT translation estimator: translate_transform_t::Pointer translate; double metric = match_one_pair(translate, // best translation transform - + // fixed image small neighborhood: img_0, msk_0, - + // moving image small neighborhood: img_1, msk_1, - + period_sz, - + 0.25,// overlap min 1.0, // overlap max 0.5, // low pass filter r 0.1, // low pass filter s 10, // number of peaks true); // consider the no-displacement case - + #ifdef DEBUG_REFINE_ONE_POINT static const bfs::path fn_save("/tmp/refine_one_point_fft-"); bfs::path suffix = the_text_t::number(COUNTER, 3, '0'); - + save_composite(fn_save + suffix + "-a.png", img_0, img_1, identity_transform_t::New(), true); #endif // DEBUG_REFINE_ONE_POINT - + #if defined(DEBUG_REFINE_ONE_POINT) || defined(DEBUG_ESTIMATE_DISPLACEMENT) COUNTER++; #endif - + if (metric == std::numeric_limits::max()) { return false; } - + #ifdef DEBUG_REFINE_ONE_POINT save_composite(fn_save + suffix + "-b.png", img_0, @@ -854,7 +854,7 @@ refine_one_point_fft(vec2d_t & shift, translate.GetPointer(), true); #endif // DEBUG_REFINE_ONE_POINT - + shift = -translate->GetOffset(); return true; } @@ -862,61 +862,61 @@ refine_one_point_fft(vec2d_t & shift, //---------------------------------------------------------------- // extract -// +// // Return the number of pixels in the region in the mask: -// +// template unsigned int extract(const typename TImage::PointType & origin, - + const TImage * tile, const TMask * mask, - + TImage * tile_region, TMask * mask_region, - + const typename TImage::PixelType & bg = itk::NumericTraits::Zero) { tile_region->SetOrigin(origin); mask_region->SetOrigin(origin); - + // setup the image interpolator: typedef itk::LinearInterpolateImageFunction interpolator_t; typename interpolator_t::Pointer interpolator = interpolator_t::New(); interpolator->SetInputImage(tile); - + // temporary: typename TImage::PointType tile_pt; typename TImage::PixelType tile_val; typename TMask::IndexType mask_ix; typename TMask::PixelType mask_val; - + static const typename TMask::PixelType mask_min = itk::NumericTraits::Zero; - + static const typename TMask::PixelType mask_max = itk::NumericTraits::One; - + unsigned int num_pixels = 0; - + typedef itk::ImageRegionIteratorWithIndex itex_t; itex_t itex(tile_region, tile_region->GetLargestPossibleRegion()); for (itex.GoToBegin(); !itex.IsAtEnd(); ++itex) { tile_val = bg; mask_val = mask_min; - + tile_region->TransformIndexToPhysicalPoint(itex.GetIndex(), tile_pt); if (interpolator->IsInsideBuffer(tile_pt)) { mask_val = mask_max; - if (mask != NULL) + if (mask != nullptr) { mask->TransformPhysicalPointToIndex(tile_pt, mask_ix); mask_val = mask->GetPixel(mask_ix); } - + if (mask_val != mask_min) { tile_val = @@ -924,18 +924,18 @@ extract(const typename TImage::PointType & origin, num_pixels++; } } - + itex.Set(tile_val); mask_region->SetPixel(itex.GetIndex(), mask_val); } - + return num_pixels; } //---------------------------------------------------------------- // refine_one_point_helper -// +// template bool refine_one_point_helper(// the large images and their masks: @@ -943,15 +943,15 @@ refine_one_point_helper(// the large images and their masks: const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - - + + // mosaic space neighborhood center: const pnt2d_t & center, pnt2d_t & origin, - + // minimum acceptable neighborhood overlap ratio: const double & min_overlap, - + // the extracted small neighborhoods and their masks: TImage * img_0, mask_t * msk_0, @@ -962,16 +962,16 @@ refine_one_point_helper(// the large images and their masks: img_0->GetLargestPossibleRegion().GetSize(); const typename TImage::SpacingType & sp = img_0->GetSpacing(); - + origin[0] = center[0] - (double(sz[0]) * sp[0]) / 2; origin[1] = center[1] - (double(sz[1]) * sp[1]) / 2; - + pnt2d_t corner[] = { origin + vec2d(sz[0] * sp[0], 0), origin + vec2d(sz[0] * sp[0], sz[1] * sp[1]), origin + vec2d(0, sz[1] * sp[1]) }; - + // make sure both tiles overlap the region: typename TImage::IndexType tmp_ix; if (!(tile_0->TransformPhysicalPointToIndex(origin, tmp_ix) || @@ -985,53 +985,53 @@ refine_one_point_helper(// the large images and their masks: { return false; } - + // keep count of pixel in the neighborhood: unsigned int area[] = { 0, 0 }; - + area[0] = extract(origin, tile_0, mask_0, img_0, msk_0); - + area[1] = extract(origin, tile_1, mask_1, img_1, msk_1); - + // skip points which don't have enough neighborhood information: double max_area = double(sz[0] * sz[1]); double a[] = { double(area[0]) / max_area, double(area[1]) / max_area }; - + if (a[0] < min_overlap || a[1] < min_overlap) { return false; } - + return true; } //---------------------------------------------------------------- // tiles_intersect -// +// template bool tiles_intersect(// the large images and their masks: const TImage * tile_0, const TImage * tile_1, - + // transforms from mosaic space to tile space: const base_transform_t * forward_0, const base_transform_t * forward_1, - + // mosaic space neighborhood center: const pnt2d_t & origin, - + // neighborhood size and pixel spacing: const typename TImage::SizeType & sz, const typename TImage::SpacingType & sp) @@ -1042,29 +1042,29 @@ tiles_intersect(// the large images and their masks: origin + vec2d(sz[0] * sp[0], sz[1] * sp[1]), origin + vec2d(0, sz[1] * sp[1]) }; - + // temporary: typename TImage::IndexType tmp_ix; pnt2d_t tmp_pt; - + // make sure both tiles overlap the region: bool in[] = { false, false }; - + for (unsigned int i = 0; i < 4 && (!in[0] || !in[1]) ; i++) { tmp_pt = forward_0->TransformPoint(corner[i]); in[0] = in[0] || tile_0->TransformPhysicalPointToIndex(tmp_pt, tmp_ix); - + tmp_pt = forward_1->TransformPoint(corner[i]); in[1] = in[1] || tile_1->TransformPhysicalPointToIndex(tmp_pt, tmp_ix); } - + return in[0] && in[1]; } //---------------------------------------------------------------- // refine_one_point_helper -// +// template bool refine_one_point_helper(// the large images and their masks: @@ -1072,21 +1072,21 @@ refine_one_point_helper(// the large images and their masks: const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - + // transforms from mosaic space to tile space: const base_transform_t * forward_0, const base_transform_t * forward_1, - + // mosaic space neighborhood center: const pnt2d_t & center, - + // minimum acceptable neighborhood overlap ratio: const double & min_overlap, - + // neighborhood size and pixel spacing: const typename TImage::SizeType & sz, const typename TImage::SpacingType & sp, - + // the extracted small neighborhoods and their masks: TImage * img_0_large, mask_t * msk_0_large, @@ -1098,7 +1098,7 @@ refine_one_point_helper(// the large images and their masks: pnt2d_t origin = center; origin[0] -= (double(sz[0]) * sp[0]) / 2; origin[1] -= (double(sz[1]) * sp[1]) / 2; - + if (!tiles_intersect(tile_0, tile_1, forward_0, @@ -1109,25 +1109,25 @@ refine_one_point_helper(// the large images and their masks: { return false; } - + // setup the image interpolators: typedef itk::LinearInterpolateImageFunction interpolator_t; typename interpolator_t::Pointer interpolator[] = { interpolator_t::New(), interpolator_t::New() }; - + interpolator[0]->SetInputImage(tile_0); interpolator[1]->SetInputImage(tile_1); - + // temporaries: pnt2d_t mosaic_pt; pnt2d_t tile_pt; typename TImage::IndexType index; - + // keep count of pixel in the neighborhood: unsigned int area[] = { 0, 0 }; - + // extract a neighborhood of the given point from both tiles: for (unsigned int y = 0; y < sz[1]; y++) { @@ -1137,7 +1137,7 @@ refine_one_point_helper(// the large images and their masks: { mosaic_pt[0] = origin[0] + double(x) * sp[0]; index[0] = x; - + // fixed image: tile_pt = forward_0->TransformPoint(mosaic_pt); if (interpolator[0]->IsInsideBuffer(tile_pt) && @@ -1153,7 +1153,7 @@ refine_one_point_helper(// the large images and their masks: img_0->SetPixel(index, 0); msk_0->SetPixel(index, 0); } - + // moving image: tile_pt = forward_1->TransformPoint(mosaic_pt); if (interpolator[1]->IsInsideBuffer(tile_pt) && @@ -1171,26 +1171,26 @@ refine_one_point_helper(// the large images and their masks: } } } - + // skip points which don't have enough neighborhood information: double max_area = double(sz[0] * sz[1]); double a[] = { double(area[0]) / max_area, double(area[1]) / max_area }; - + if (a[0] < min_overlap || a[1] < min_overlap) { return false; } - - if (img_0_large != NULL) + + if (img_0_large != nullptr) { // extract the larger neighborhood from the fixed tile: pnt2d_t origin_large(center); origin_large[0] -= sz[0] * sp[0]; origin_large[1] -= sz[1] * sp[1]; - + for (unsigned int y = 0; y < sz[1] * 2; y++) { mosaic_pt[1] = origin_large[1] + double(y) * sp[1]; @@ -1199,7 +1199,7 @@ refine_one_point_helper(// the large images and their masks: { mosaic_pt[0] = origin_large[0] + double(x) * sp[0]; index[0] = x; - + // fixed image: tile_pt = forward_0->TransformPoint(mosaic_pt); if (interpolator[0]->IsInsideBuffer(tile_pt) && @@ -1217,7 +1217,7 @@ refine_one_point_helper(// the large images and their masks: } } } - + return true; } @@ -1228,21 +1228,21 @@ refine_one_point_helper(// the large images and their masks: template bool refine_one_point_fft(vec2d_t & shift, - + // fixed tile, in mosaic space: const TImage * tile_0, const mask_t * mask_0, - + // moving tile, in mosaic space: const TImage * tile_1, const mask_t * mask_1, - + // mosaic space neighborhood center: const pnt2d_t & center, - + // minimum acceptable neighborhood overlap ratio: const double & min_overlap, - + // the extracted small neighborhoods and their masks: TImage * img_0, mask_t * msk_0, @@ -1264,7 +1264,7 @@ refine_one_point_fft(vec2d_t & shift, { return false; } - + return refine_one_point_fft(shift, pnt2d(0, 0), // origin, tile_0, @@ -1282,31 +1282,31 @@ refine_one_point_fft(vec2d_t & shift, template bool refine_one_point_fft(vec2d_t & shift, - + // the large images and their masks: const TImage * tile_0, const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - + // transforms from mosaic space to tile space: const base_transform_t * forward_0, const base_transform_t * forward_1, - + // mosaic space neighborhood center: const pnt2d_t & center, - + // minimum acceptable neighborhood overlap ratio: const double & min_overlap, - + // neighborhood size and pixel spacing: const typename TImage::SizeType & sz, const typename TImage::SpacingType & sp, - + // the extracted larger neighborhood: TImage * img_0_large, mask_t * msk_0_large, - + // the extracted small neighborhoods and their masks: TImage * img_0, mask_t * msk_0, @@ -1332,7 +1332,7 @@ refine_one_point_fft(vec2d_t & shift, { return false; } - + pnt2d_t origin; origin[0] = sz[0] * sp[0] / 2; origin[1] = sz[1] * sp[1] / 2; @@ -1353,27 +1353,27 @@ refine_one_point_fft(vec2d_t & shift, template bool refine_one_point_fft(vec2d_t & shift, - + // the large images and their masks: const TImage * tile_0, const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - + // transforms from mosaic space to tile space: const base_transform_t * forward_0, const base_transform_t * forward_1, - + // mosaic space neighborhood center: const pnt2d_t & center, - + // minimum acceptable neighborhood overlap ratio: const double & min_overlap, - + // neighborhood size and pixel spacing: const typename TImage::SizeType & sz, const typename TImage::SpacingType & sp, - + // the extracted small neighborhoods and their masks: TImage * img_0, mask_t * msk_0, @@ -1383,7 +1383,7 @@ refine_one_point_fft(vec2d_t & shift, pnt2d_t origin(center); origin[0] -= sz[0] * sp[0] / 2; origin[1] -= sz[1] * sp[1] / 2; - + if (!refine_one_point_helper(tile_0, mask_0, tile_1, @@ -1394,8 +1394,8 @@ refine_one_point_fft(vec2d_t & shift, min_overlap, sz, sp, - NULL, - NULL, + nullptr, + nullptr, img_0, msk_0, img_1, @@ -1403,7 +1403,7 @@ refine_one_point_fft(vec2d_t & shift, { return false; } - + return refine_one_point_fft(shift, img_0, msk_0, @@ -1414,17 +1414,17 @@ refine_one_point_fft(vec2d_t & shift, //---------------------------------------------------------------- // refine_one_pair -// +// template double refine_one_pair(typename TTransform::Pointer & t01, - + const TImage * i0, const mask_t * m0, - + const TImage * i1, const mask_t * m1, - + const unsigned int levels, const unsigned int iterations, const double & min_step, @@ -1433,14 +1433,14 @@ refine_one_pair(typename TTransform::Pointer & t01, // typedef itk::MultiResolutionImageRegistrationMethod typedef itk::ImageRegistrationMethod registration_t; - + // setup the registration object: typename registration_t::Pointer registration = registration_t::New(); - + // setup the image interpolator: typedef itk::LinearInterpolateImageFunction interpolator_t; registration->SetInterpolator(interpolator_t::New()); - + // setup the optimizer: optimizer_t::Pointer optimizer = optimizer_t::New(); registration->SetOptimizer(optimizer); @@ -1455,67 +1455,67 @@ refine_one_pair(typename TTransform::Pointer & t01, optimizer->SetRelaxationFactor(5e-1); optimizer->SetPickUpPaceSteps(5); optimizer->SetBackTracking(true); - + // FIXME: this is probably unnecessary: typedef optimizer_t::ScalesType optimizer_scales_t; optimizer_scales_t parameter_scales(t01->GetNumberOfParameters()); parameter_scales.Fill(1.0); - + try { optimizer->SetScales(parameter_scales); } catch (itk::ExceptionObject &) {} - + // setup the image-to-image metric: typedef itk::NormalizedCorrelationImageToImageMetric metric_t; - + typename metric_t::Pointer metric = metric_t::New(); registration->SetMetric(metric); - + registration->SetTransform(t01); registration->SetInitialTransformParameters(t01->GetParameters()); - + // setup the masks: typedef itk::ImageMaskSpatialObject<2> mask_so_t; mask_t::ConstPointer fi_mask = m0; - if (m0 != NULL) + if (m0 != nullptr) { mask_so_t::Pointer fi_mask_so = mask_so_t::New(); fi_mask_so->SetImage(fi_mask); metric->SetFixedImageMask(fi_mask_so); } - + mask_t::ConstPointer mi_mask = m1; - if (m1 != NULL) + if (m1 != nullptr) { mask_so_t::Pointer mi_mask_so = mask_so_t::New(); mi_mask_so->SetImage(mi_mask); metric->SetMovingImageMask(mi_mask_so); } - + // setup the fixed and moving image: typename TImage::ConstPointer fi = i0; typename TImage::ConstPointer mi = i1; - + registration->SetFixedImageRegion(fi->GetLargestPossibleRegion()); registration->SetFixedImage(fi); registration->SetMovingImage(mi); - + // setup the multi-resolution image pyramids: // registration->SetNumberOfLevels(levels); - + // evaluate the metric before the registration: double metric_before = eval_metric(t01, fi, mi, fi_mask, mi_mask); assert(metric_before != std::numeric_limits::max()); - + typename TTransform::ParametersType params_before = t01->GetParameters(); std::ostringstream oss; - + // perform the registration: try { oss << std::endl; - registration->StartRegistration(); + registration->Update(); } catch (itk::ExceptionObject & exception) { @@ -1523,16 +1523,16 @@ refine_one_pair(typename TTransform::Pointer & t01, << std::endl << exception.what() << std::endl; } t01->SetParameters(optimizer->GetBestParams()); - + // evaluate the metric after the registration: double metric_after = eval_metric(t01, fi, mi, fi_mask, mi_mask); - + typename TTransform::ParametersType params_after = t01->GetParameters(); - + oss << "BEFORE: " << metric_before << std::endl << "AFTER: " << metric_after << std::endl; - + if (metric_before <= metric_after || metric_after != metric_after) { oss << "NOTE: minimization failed, ignoring registration results..." << std::endl; @@ -1540,7 +1540,7 @@ refine_one_pair(typename TTransform::Pointer & t01, CORE_LOG_MESSAGE(oss.str()); return metric_before; } - + CORE_LOG_MESSAGE(oss.str()); return metric_after; } @@ -1553,11 +1553,11 @@ template bool refine_one_point_nofft(vec2d_t & shift, const pnt2d_t & origin, - + // the large images and their masks: const TImage * tile_0, const mask_t * mask_0, - + // the extracted small neighborhood with masks: const TImage * img_1, const mask_t * msk_1) @@ -1566,7 +1566,7 @@ refine_one_point_nofft(vec2d_t & shift, translate_transform_t::Pointer translate = translate_transform_t::New(); vec2d_t offset = vec2d(origin[0], origin[1]); translate->SetOffset(-offset); - + double metric = refine_one_pair (translate, @@ -1578,13 +1578,13 @@ refine_one_point_nofft(vec2d_t & shift, 100, // number of iterations 1e-8, // min step 1e+4); // max step - + std::ostringstream oss; - + shift = -(translate->GetOffset() + offset); oss << "shift: " << shift << std::endl; CORE_LOG_MESSAGE(oss.str()); - + #ifdef DEBUG_REFINE_ONE_POINT static const bfs::path fn_save("/tmp/refine_one_point_nofft-"); bfs::path suffix = the_text_t::number(COUNTER, 3, '0'); @@ -1598,16 +1598,16 @@ refine_one_point_nofft(vec2d_t & shift, true); } #endif // DEBUG_REFINE_ONE_POINT - + #if defined(DEBUG_REFINE_ONE_POINT) || defined(DEBUG_ESTIMATE_DISPLACEMENT) COUNTER++; #endif - + if (metric == std::numeric_limits::max()) { return false; } - + #ifdef DEBUG_REFINE_ONE_POINT save_composite(fn_save + suffix + "-b.png", tile_0, @@ -1615,7 +1615,7 @@ refine_one_point_nofft(vec2d_t & shift, translate.GetPointer(), true); #endif // DEBUG_REFINE_ONE_POINT - + return true; } @@ -1629,23 +1629,23 @@ refine_one_point_nofft(vec2d_t & shift, const pnt2d_t & center, const pnt2d_t & origin, const double & min_overlap, - + // the large images and their masks: const TImage * tile_0, const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - + // transform that maps from the space of // tile 0 to the space of tile 1: const base_transform_t * t_01, - + // the extracted small neighborhoods and their masks: TImage * img_0, mask_t * msk_0, TImage * img_1, mask_t * msk_1, - + // neighborhood size and pixel spacing: const typename TImage::SizeType & sz, const typename TImage::SpacingType & sp) @@ -1667,11 +1667,11 @@ refine_one_point_nofft(vec2d_t & shift, { return false; } - + // feed the two neighborhoods into the optimizer translation estimator: translate_transform_t::Pointer translate = translate_transform_t::New(); translate->SetIdentity(); - + double metric = refine_one_pair (translate, @@ -1683,7 +1683,7 @@ refine_one_point_nofft(vec2d_t & shift, 100, // number of iterations 1e-8, // min step 1e+4); // max step - + #ifdef DEBUG_REFINE_ONE_POINT static const bfs::path fn_save("/tmp/refine_one_point_nofft-"); bfs::path suffix = the_text_t::number(COUNTER, 3, '0'); @@ -1693,16 +1693,16 @@ refine_one_point_nofft(vec2d_t & shift, identity_transform_t::New(), true); #endif // DEBUG_REFINE_ONE_POINT - + #if defined(DEBUG_REFINE_ONE_POINT) || defined(DEBUG_ESTIMATE_DISPLACEMENT) COUNTER++; #endif - + if (metric == std::numeric_limits::max()) { return false; } - + #ifdef DEBUG_REFINE_ONE_POINT save_composite(fn_save + suffix + "-b.png", img_0.GetPointer(), @@ -1710,7 +1710,7 @@ refine_one_point_nofft(vec2d_t & shift, translate.GetPointer(), true); #endif // DEBUG_REFINE_ONE_POINT - + shift = -translate->GetOffset(); return true; } @@ -1727,11 +1727,11 @@ refine_one_point_nofft(vec2d_t & shift, const mask_t * mask_0, const TImage * tile_1, const mask_t * mask_1, - + // transform that maps from the space of // tile 0 to the space of tile 1: const base_transform_t * t_01, - + // neighborhood size: const unsigned int & neighborhood) { @@ -1739,26 +1739,26 @@ refine_one_point_nofft(vec2d_t & shift, typename TImage::SizeType sz; sz[0] = neighborhood; sz[1] = neighborhood; - + pnt2d_t origin(center); origin[0] -= 0.5 * double(sz[0]) * sp[0]; origin[1] -= 0.5 * double(sz[1]) * sp[1]; - + typename TImage::Pointer img[] = { make_image(sz), make_image(sz) }; - + mask_t::Pointer msk[] = { make_image(sz), make_image(sz) }; - + img[0]->SetSpacing(sp); img[1]->SetSpacing(sp); msk[0]->SetSpacing(sp); msk[1]->SetSpacing(sp); - + return refine_one_point_nofft(shift, center, origin, diff --git a/src/Core/ITKCommon/match.hxx b/src/Core/ITKCommon/match.hxx index d173fcf67..8450fe42b 100644 --- a/src/Core/ITKCommon/match.hxx +++ b/src/Core/ITKCommon/match.hxx @@ -50,8 +50,8 @@ class match_t { public: match_t(): - a_(NULL), - b_(NULL), + a_(nullptr), + b_(nullptr), error_(std::numeric_limits::max()), r_(1.0) {} @@ -65,14 +65,14 @@ public: error_(error), r_(r) { - assert(a != NULL && b != NULL); + assert(a != nullptr && b != nullptr); } // this will be used to sort the matches from best to worst: inline bool operator < (const match_t & match) const { // FIXME: - assert(a_ != NULL && b_ != NULL); + assert(a_ != nullptr && b_ != nullptr); return error_ < match.error_; } diff --git a/src/Core/ITKCommon/mosaic_layout_common.cxx b/src/Core/ITKCommon/mosaic_layout_common.cxx index f7692e8a3..d0bfbe65d 100644 --- a/src/Core/ITKCommon/mosaic_layout_common.cxx +++ b/src/Core/ITKCommon/mosaic_layout_common.cxx @@ -57,7 +57,7 @@ reset(const unsigned int num_images, { for (unsigned int j = 0; j < num_images; j++) { - path[cascade][i][j] = NULL; + path[cascade][i][j] = nullptr; cost[cascade][i][j] = std::numeric_limits::max(); } } @@ -85,7 +85,7 @@ assemble_cascades(const unsigned int num_images, // attempt to establish a mapping between images i and j // via an intermediate mapping: - translate_transform_t::Pointer best_ij = NULL; + translate_transform_t::Pointer best_ij = nullptr; double best_metric = std::numeric_limits::max(); for (unsigned int sa = 0; sa < intermediate; sa++) @@ -143,8 +143,8 @@ establish_mappings(const unsigned int num_images, for (unsigned int j = i + 1; j < num_images; j++) { - mapping[i][j] = NULL; - mapping[j][i] = NULL; + mapping[i][j] = nullptr; + mapping[j][i] = nullptr; mapping_cost[i][j] = std::numeric_limits::max(); mapping_cost[j][i] = std::numeric_limits::max(); diff --git a/src/Core/ITKCommon/mosaic_layout_common.hxx b/src/Core/ITKCommon/mosaic_layout_common.hxx index ad4f430fb..c8a50fa64 100644 --- a/src/Core/ITKCommon/mosaic_layout_common.hxx +++ b/src/Core/ITKCommon/mosaic_layout_common.hxx @@ -87,7 +87,7 @@ template affine_transform_t::Pointer setup_transform(const TImage * image, const base_transform_t * t0, - const base_transform_t * t1 = NULL, + const base_transform_t * t1 = nullptr, const unsigned int samples = 16) { // shortcuts: @@ -140,9 +140,9 @@ setup_transform(const TImage * image, fwd_cascade[1] = t1; inv_cascade[0] = t0->GetInverseTransform(); - inv_cascade[1] = (t1 == NULL) ? NULL : t1->GetInverseTransform(); + inv_cascade[1] = (t1 == nullptr) ? nullptr : t1->GetInverseTransform(); - const unsigned int cascade_len = (t1 == NULL) ? 1 : 2; + const unsigned int cascade_len = (t1 == nullptr) ? 1 : 2; // calculate the shift: pnt2d_t center = pnt2d(tile_min[0] + (tile_max[0] - tile_min[0]) / 2.0, @@ -308,7 +308,7 @@ refine_one_pair(const TImage * i0, // setup the masks: typedef itk::ImageMaskSpatialObject<2> mask_so_t; typename TMask::ConstPointer fi_mask = m0; - if (m0 != NULL) + if (m0 != nullptr) { mask_so_t::Pointer fi_mask_so = mask_so_t::New(); fi_mask_so->SetImage(fi_mask); @@ -316,7 +316,7 @@ refine_one_pair(const TImage * i0, } typename TMask::ConstPointer mi_mask = m1; - if (m1 != NULL) + if (m1 != nullptr) { mask_so_t::Pointer mi_mask_so = mask_so_t::New(); mi_mask_so->SetImage(mi_mask); @@ -342,7 +342,7 @@ refine_one_pair(const TImage * i0, // perform the registration: try { - registration->StartRegistration(); + registration->Update(); } catch (itk::ExceptionObject & exception) { @@ -481,7 +481,7 @@ refine_pairs(const std::vector & image, if (overlap < overlap_min || overlap > overlap_max) { - path[i][j] = NULL; + path[i][j] = nullptr; cost[i][j] = std::numeric_limits::max(); } else @@ -510,7 +510,7 @@ refine_pairs(const std::vector & image, oss << i << "\t| "; for (unsigned int j = 0; j < num_images; j++) { - if (path[i][j].GetPointer() != NULL) + if (path[i][j].GetPointer() != nullptr) { oss << ' ' << cost[i][j]; } @@ -594,7 +594,7 @@ refine_pairs(const array2d(typename TImage::Pointer) & tile_pyramid, if (overlap < overlap_min || overlap > overlap_max) { - path[i][j] = NULL; + path[i][j] = nullptr; cost[i][j] = std::numeric_limits::max(); } else @@ -623,7 +623,7 @@ refine_pairs(const array2d(typename TImage::Pointer) & tile_pyramid, oss << i << "\t| "; for (unsigned int j = 0; j < num_images; j++) { - if (path[i][j].GetPointer() != NULL) + if (path[i][j].GetPointer() != nullptr) { oss << ' ' << cost[i][j]; } @@ -820,7 +820,7 @@ brute_force_pairs(const std::vector & image, if (overlap < overlap_min || overlap > overlap_max) { - path[i][j] = NULL; + path[i][j] = nullptr; cost[i][j] = std::numeric_limits::max(); } else @@ -849,7 +849,7 @@ brute_force_pairs(const std::vector & image, oss << i << "\t| "; for (unsigned int j = 0; j < num_images; j++) { - if (path[i][j].GetPointer() != NULL) + if (path[i][j].GetPointer() != nullptr) { oss << ' ' << cost[i][j]; } @@ -935,7 +935,7 @@ brute_force_pairs(const array2d(typename TImage::Pointer) & tile_pyramid, if (overlap < overlap_min || overlap > overlap_max) { - path[i][j] = NULL; + path[i][j] = nullptr; cost[i][j] = std::numeric_limits::max(); } else @@ -964,7 +964,7 @@ brute_force_pairs(const array2d(typename TImage::Pointer) & tile_pyramid, oss << i << "\t| "; for (unsigned int j = 0; j < num_images; j++) { - if (path[i][j].GetPointer() != NULL) + if (path[i][j].GetPointer() != nullptr) { oss << ' ' << cost[i][j]; } @@ -1010,7 +1010,7 @@ dump_neighbors(const std::vector & image, for (unsigned int j = 0; j < num_images; j++) { if (i == j) continue; - if (path[i][j].GetPointer() == NULL) continue; + if (path[i][j].GetPointer() == nullptr) continue; oss << "found a mapping: " << std::setw(2) << j << " -> " << std::setw(2) << i << std::endl; @@ -1065,7 +1065,7 @@ calc_area_and_dist(const std::vector & image, for (unsigned int i = 0; i < num_images; i++) { - if (image[i].GetPointer() == NULL) continue; + if (image[i].GetPointer() == nullptr) continue; // calculate the tile center: pnt2d_t ci; @@ -1090,7 +1090,7 @@ calc_area_and_dist(const std::vector & image, for (unsigned int j = i + 1; j < num_images; j++) { - if (mapping[i][j].GetPointer() == NULL) continue; + if (mapping[i][j].GetPointer() == nullptr) continue; overlap[i][j] = overlap_ratio(image[i], image[j], mapping[i][j]); overlap[j][i] = overlap[i][j]; @@ -1214,7 +1214,7 @@ match_pairs(std::vector & image, matched[i] = false; for (unsigned int j = 0; j < num_images; j++) { - path[i][j] = NULL; + path[i][j] = nullptr; cost[i][j] = std::numeric_limits::max(); } } @@ -1466,10 +1466,10 @@ else i + row < 0 || i + row >= edgeLen || j + column < 0 || j + column >= edgeLen) continue; - + //forget the diagonal neighbors if (i && j) continue; - + //get the neighbor int neighbor = seed + edgeLen * i + j; if (strategy == TOP_LEFT_SNAKE) @@ -1480,10 +1480,10 @@ else col = edgeLen - col - 1; neighbor = col + rw * edgeLen; } - + if (neighbor > num_images || neighbor < 0) continue; - + std::cout << "matching image " << seed << " to " << neighbor << ". " << std::endl; //oss << "matching image " << @@ -1788,7 +1788,7 @@ layout_mosaic(// multi-resolution image tiles and tile masks, for (unsigned int i = 0; i < num_tiles; i++) { if (i == best_target) continue; - if (tile_pyramid[high_res_level][i].GetPointer() == NULL) continue; + if (tile_pyramid[high_res_level][i].GetPointer() == nullptr) continue; tiles.push_back(i); } @@ -1825,7 +1825,7 @@ layout_mosaic(// multi-resolution image tiles and tile masks, jter != tiles.end(); ++jter) { const unsigned int j = *jter; - if (path[0][i][j].GetPointer() == NULL) continue; + if (path[0][i][j].GetPointer() == nullptr) continue; local_mapping_t m(i, j, cost[0][i][j]); candidates.push_back(m); diff --git a/src/Core/ITKCommon/mosaic_refinement_common.hxx b/src/Core/ITKCommon/mosaic_refinement_common.hxx index b9a02bb30..ce2ae7cf4 100644 --- a/src/Core/ITKCommon/mosaic_refinement_common.hxx +++ b/src/Core/ITKCommon/mosaic_refinement_common.hxx @@ -1170,7 +1170,7 @@ refine_mosaic(std::vector & transform, oss << std::setw(4) << i << ". warping image tile" << std::endl; warped_tile[i] = warp(tile[i], transform[i].GetPointer()); - if (mask[i].GetPointer() != NULL) + if (mask[i].GetPointer() != nullptr) { oss << " warping image tile mask" << std::endl; warped_mask[i] = warp(mask[i], transform[i].GetPointer()); @@ -1282,7 +1282,7 @@ public: warp(tile_[tile_index_], transform_[tile_index_].GetPointer()); - if (mask_[tile_index_].GetPointer() != NULL) + if (mask_[tile_index_].GetPointer() != nullptr) { oss << setw(4) << tile_index_ << ". warping image tile mask" << std::endl; warped_mask_[tile_index_] = diff --git a/src/Core/ITKCommon/pyramid.cxx b/src/Core/ITKCommon/pyramid.cxx index 080c0e7a0..23a6dc892 100644 --- a/src/Core/ITKCommon/pyramid.cxx +++ b/src/Core/ITKCommon/pyramid.cxx @@ -1626,7 +1626,7 @@ octave_t::setup(const unsigned int & octave, mask_ = mask; mask_eroded_ = mask; - if (mask != NULL) + if (mask != nullptr) { mask_eroded_ = erode(mask_, static_cast(r0_)); } @@ -2153,7 +2153,7 @@ pyramid_t::setup(const image_t * initial_image, // downsample the image: L0 = resize(octave_[i].L_[s], 0.5); - if (mask != NULL) + if (mask != nullptr) { M0 = cast(resize (cast(M0), 0.5)); @@ -2165,7 +2165,7 @@ pyramid_t::setup(const image_t * initial_image, spacing[1] *= 2.0; L0->SetSpacing(spacing); - if (mask != NULL) + if (mask != nullptr) { M0->SetSpacing(spacing); } diff --git a/src/Core/ITKCommon/the_dynamic_array.hxx b/src/Core/ITKCommon/the_dynamic_array.hxx index 95ab7fb80..874e75515 100644 --- a/src/Core/ITKCommon/the_dynamic_array.hxx +++ b/src/Core/ITKCommon/the_dynamic_array.hxx @@ -84,14 +84,14 @@ class the_dynamic_array_t { public: the_dynamic_array_t(): - array_(NULL), + array_(nullptr), page_size_(16), size_(0), init_value_() {} the_dynamic_array_t(const size_t & init_size): - array_(NULL), + array_(nullptr), page_size_(init_size), size_(0), init_value_() @@ -100,7 +100,7 @@ public: the_dynamic_array_t(const size_t & init_size, const size_t & page_size, const T & init_value): - array_(NULL), + array_(nullptr), page_size_(page_size), size_(0), init_value_(init_value) @@ -110,7 +110,7 @@ public: // copy constructor: the_dynamic_array_t(const the_dynamic_array_t & a): - array_(NULL), + array_(nullptr), page_size_(0), size_(0), init_value_(a.init_value_) @@ -134,7 +134,7 @@ public: } delete array_; - array_ = NULL; + array_ = nullptr; size_ = 0; } @@ -211,7 +211,7 @@ public: // number of pages currently allocated: inline size_t num_pages() const - { return (array_ == NULL) ? 0 : array_->size(); } + { return (array_ == nullptr) ? 0 : array_->size(); } inline const T * page(const size_t & page_index) const { return &((*(*array_)[page_index])[0]); } diff --git a/src/Core/ITKCommon/the_text.cxx b/src/Core/ITKCommon/the_text.cxx index 1839f6cb8..623e6784e 100644 --- a/src/Core/ITKCommon/the_text.cxx +++ b/src/Core/ITKCommon/the_text.cxx @@ -50,7 +50,7 @@ // the_text_t::the_text_t // the_text_t::the_text_t(const char * text): - text_(NULL), + text_(nullptr), size_(0) { assign(text); @@ -60,7 +60,7 @@ the_text_t::the_text_t(const char * text): // the_text_t::the_text_t // the_text_t::the_text_t(const char * text, const size_t & size): - text_(NULL), + text_(nullptr), size_(0) { assign(text, size); @@ -70,7 +70,7 @@ the_text_t::the_text_t(const char * text, const size_t & size): // the_text_t::the_text_t // the_text_t::the_text_t(const the_text_t & text): - text_(NULL), + text_(nullptr), size_(0) { assign(text.text_, text.size_); @@ -80,7 +80,7 @@ the_text_t::the_text_t(const the_text_t & text): // the_text_t::the_text_t // the_text_t::the_text_t(const std::list & text): - text_(NULL), + text_(nullptr), size_(text.size()) { text_ = new char [size_ + 1]; diff --git a/src/Core/ITKCommon/the_text.hxx b/src/Core/ITKCommon/the_text.hxx index 37eb8d0d5..7fbbfe20a 100644 --- a/src/Core/ITKCommon/the_text.hxx +++ b/src/Core/ITKCommon/the_text.hxx @@ -82,7 +82,7 @@ public: inline void clear() { delete [] text_; - text_ = NULL; + text_ = nullptr; size_ = 0; } diff --git a/src/Core/ITKCommon/the_utils.cxx b/src/Core/ITKCommon/the_utils.cxx index 2ae4ce2c0..248a081d0 100644 --- a/src/Core/ITKCommon/the_utils.cxx +++ b/src/Core/ITKCommon/the_utils.cxx @@ -118,7 +118,7 @@ utf8_to_utf16(const char * utf8, wchar_t *& utf16) 0, // flags (precomposed, composite,... ) utf8, // source multi-byte character string -1, // number of bytes in the source string - NULL, // wide-character destination + nullptr, // wide-character destination 0); // destination buffer size utf16 = new wchar_t[wcs_size + 1]; @@ -184,13 +184,13 @@ open_utf8(std::fstream & fstream_to_open, FILE * fopen_utf8(const char * filename_utf8, const char * mode) { - FILE * file = NULL; + FILE * file = nullptr; #ifdef _WIN32 - wchar_t * filename_utf16 = NULL; + wchar_t * filename_utf16 = nullptr; utf8_to_utf16(filename_utf8, filename_utf16); - wchar_t * mode_utf16 = NULL; + wchar_t * mode_utf16 = nullptr; utf8_to_utf16(mode, mode_utf16); _wfopen_s(&file, filename_utf16, mode_utf16); @@ -210,10 +210,10 @@ int rename_utf8(const char * old_utf8, const char * new_utf8) { #ifdef _WIN32 - wchar_t * old_utf16 = NULL; + wchar_t * old_utf16 = nullptr; utf8_to_utf16(old_utf8, old_utf16); - wchar_t * new_utf16 = NULL; + wchar_t * new_utf16 = nullptr; utf8_to_utf16(new_utf8, new_utf16); int ret = _wrename(old_utf16, new_utf16); @@ -235,7 +235,7 @@ int remove_utf8(const char * filename_utf8) { #ifdef _WIN32 - wchar_t * filename_utf16 = NULL; + wchar_t * filename_utf16 = nullptr; utf8_to_utf16(filename_utf8, filename_utf16); int ret = _wremove(filename_utf16); @@ -255,7 +255,7 @@ int rmdir_utf8(const char * dir_utf8) { #ifdef _WIN32 - wchar_t * dir_utf16 = NULL; + wchar_t * dir_utf16 = nullptr; utf8_to_utf16(dir_utf8, dir_utf16); int ret = _wrmdir(dir_utf16); @@ -275,7 +275,7 @@ int mkdir_utf8(const char * path_utf8) { #ifdef _WIN32 - wchar_t * path_utf16 = NULL; + wchar_t * path_utf16 = nullptr; utf8_to_utf16(path_utf8, path_utf16); int ret = _wmkdir(path_utf16); diff --git a/src/Core/ITKCommon/the_utils.hxx b/src/Core/ITKCommon/the_utils.hxx index d0ffd8336..6b29ec50a 100644 --- a/src/Core/ITKCommon/the_utils.hxx +++ b/src/Core/ITKCommon/the_utils.hxx @@ -756,7 +756,7 @@ public: inline void arm() { - if (!armed_ && lock_ != NULL) + if (!armed_ && lock_ != nullptr) { lock_->lock(); armed_ = true; @@ -765,7 +765,7 @@ public: inline void disarm() { - if (armed_ && lock_ != NULL) + if (armed_ && lock_ != nullptr) { lock_->unlock(); armed_ = false; @@ -791,7 +791,7 @@ public: the_unlock_t(T * lock): lock_(lock) { - if (lock_ != NULL) + if (lock_ != nullptr) { assert(lock_->try_lock() == false); } @@ -800,7 +800,7 @@ public: the_unlock_t(T & lock): lock_(&lock) { - if (lock_ != NULL) + if (lock_ != nullptr) { assert(lock_->try_lock() == false); } @@ -808,7 +808,7 @@ public: ~the_unlock_t() { - if (lock_ != NULL) + if (lock_ != nullptr) { lock_->unlock(); } diff --git a/src/Core/ITKCommon/tree.hxx b/src/Core/ITKCommon/tree.hxx index 1768ea279..2d95fff2a 100644 --- a/src/Core/ITKCommon/tree.hxx +++ b/src/Core/ITKCommon/tree.hxx @@ -74,11 +74,11 @@ public: m_(data_t(0)), min_(data_t(0)), max_(data_t(0)), - points_(NULL), + points_(nullptr), num_pts_(0), - parent_(NULL), - a_(NULL), - b_(NULL) + parent_(nullptr), + a_(nullptr), + b_(nullptr) {} // copy constructor: @@ -87,21 +87,21 @@ public: m_(data_t(0)), min_(data_t(0)), max_(data_t(0)), - points_(NULL), + points_(nullptr), num_pts_(0), - parent_(NULL), - a_(NULL), - b_(NULL) + parent_(nullptr), + a_(nullptr), + b_(nullptr) { *this = node; } // destructor: ~node_t() { delete a_; - a_ = NULL; + a_ = nullptr; delete b_; - b_ = NULL; + b_ = nullptr; } //---------------------------------------------------------------- @@ -117,11 +117,11 @@ public: m_(data_t(0)), min_(data_t(0)), max_(data_t(0)), - points_(NULL), + points_(nullptr), num_pts_(0), parent_(parent), - a_(NULL), - b_(NULL) + a_(nullptr), + b_(nullptr) { // first, find the mean point value for each dimension: data_t mean[kd] = { data_t(0) }; @@ -239,18 +239,18 @@ public: parent_ = node.parent_; delete a_; - a_ = NULL; + a_ = nullptr; delete b_; - b_ = NULL; + b_ = nullptr; - if (node.a_ != NULL) + if (node.a_ != nullptr) { a_ = new node_t(*node.a_); a_->parent_ = this; } - if (node.b_ != NULL) + if (node.b_ != nullptr) { b_ = new node_t(*node.b_); b_->parent_ = this; @@ -292,8 +292,8 @@ public: const data_t da = std::min(std::max(min_ - p, 0.0), std::max(p - m_, 0.0)); const data_t db = std::min(std::max(m_ - p, 0.0), std::max(p - max_, 0.0)); - if (da > best_distance && db > best_distance) return NULL; - if (points_ != NULL) return this; + if (da > best_distance && db > best_distance) return nullptr; + if (points_ != nullptr) return this; if (da < db) { @@ -314,7 +314,7 @@ public: data_t euclidian_distance(const point_t & query) const { - assert(points_ != NULL); + assert(points_ != nullptr); const point_t & point = points_[0]; data_t distance = 0.0; @@ -330,7 +330,7 @@ public: // FIXME: this is for debugging: void dump(std::ostream & so) const { - if (points_ != NULL) + if (points_ != nullptr) { for (unsigned int i = 0; i < num_pts_; i++) { @@ -347,8 +347,8 @@ public: } else { - if (a_ != NULL) a_->dump(so); - if (b_ != NULL) b_->dump(so); + if (a_ != nullptr) a_->dump(so); + if (b_ != nullptr) b_->dump(so); } } @@ -402,12 +402,12 @@ public: // default constructor: tree_t(): - root_(NULL) + root_(nullptr) {} // copy constructor: tree_t(const tree_t & tree): - root_(NULL) + root_(nullptr) { *this = tree; } @@ -416,7 +416,7 @@ public: ~tree_t() { delete root_; - root_ = NULL; + root_ = nullptr; } // assignment operator: @@ -424,8 +424,8 @@ public: operator = (const tree_t & tree) { delete root_; - root_ = NULL; - if (tree.root_ != NULL) + root_ = nullptr; + if (tree.root_ != nullptr) { root_ = new node_t(*(tree.root_)); } @@ -437,11 +437,11 @@ public: void setup(point_t * points, const unsigned int num_pts) { delete root_; - root_ = NULL; + root_ = nullptr; if (num_pts != 0) { - root_ = new node_t(NULL, points, num_pts); + root_ = new node_t(nullptr, points, num_pts); } } @@ -474,10 +474,10 @@ public: const unsigned int max_traversals = 200, const unsigned int max_nn = 3) const { - if (root_ == NULL) return 0; + if (root_ == nullptr) return 0; // the results: - const node_t * best_match = NULL; + const node_t * best_match = nullptr; best_distance = std::numeric_limits::max(); // bootstrap the search by starting at the root: @@ -494,7 +494,7 @@ public: // find a matching point in the tree: const node_t * match = start_here->leaf(unexplored, query, best_distance); - if (match == NULL) continue; + if (match == nullptr) continue; // find the distance to the matching point: data_t distance = match->euclidian_distance(query); @@ -552,7 +552,7 @@ public: std::list nn_sorted; if (nn(query, best_distance, nn_sorted, max_traversals, 1) == 0) { - return NULL; + return nullptr; } return nn_sorted.front().node_; @@ -565,7 +565,7 @@ public: std::list & nn_sorted, const unsigned int max_traversals = 200) const { - if (root_ == NULL) return 0; + if (root_ == nullptr) return 0; // bootstrap the search by starting at the root: std::list unexplored; @@ -581,7 +581,7 @@ public: // find a matching point in the tree: const node_t * match = start_here->leaf(unexplored, query, radius); - if (match == NULL) continue; + if (match == nullptr) continue; // find the distance to the matching point: data_t distance = match->euclidian_distance(query); @@ -601,8 +601,8 @@ public: // dump the leaf nodes into the stream: void dump(std::ostream & so) const { - if (root_ != NULL) root_->dump(so); - else so << "NULL"; + if (root_ != nullptr) root_->dump(so); + else so << "nullptr"; } node_t * root_; diff --git a/src/Core/ITKCommon/visualize.cxx b/src/Core/ITKCommon/visualize.cxx index 008b7904e..a76fb5b61 100644 --- a/src/Core/ITKCommon/visualize.cxx +++ b/src/Core/ITKCommon/visualize.cxx @@ -417,7 +417,7 @@ draw_keys(native_image_t::Pointer * image, i != keys.end(); ++i) { const descriptor_t & d = *i; - if (d.extrema_ == NULL) continue; + if (d.extrema_ == nullptr) continue; const double & v = d.extrema_->mass_; key_min = std::min(key_min, v); @@ -433,7 +433,7 @@ draw_keys(native_image_t::Pointer * image, for (unsigned int i = 0; i < num_keys; i++, ++iter) { const descriptor_t & key = *iter; - if (key.extrema_ == NULL) continue; + if (key.extrema_ == nullptr) continue; //#if 0 // const double t = (key.extrema_->mass_ - key_min) / key_rng; diff --git a/src/Core/ITKCommon/visualize.hxx b/src/Core/ITKCommon/visualize.hxx index 8a9f6431e..5b687cd58 100644 --- a/src/Core/ITKCommon/visualize.hxx +++ b/src/Core/ITKCommon/visualize.hxx @@ -112,8 +112,8 @@ visualize_best_fit(const bfs::path & fn_prefix, const base_transform_t * t_ab, const std::vector & ab, const std::list & inliers, - const mask_t * a_mask = NULL, - const mask_t * b_mask = NULL); + const mask_t * a_mask = nullptr, + const mask_t * b_mask = nullptr); //---------------------------------------------------------------- // visualize_matches_v2 diff --git a/src/Core/ITKLiveWire/itkLiveWireImageFunction.hxx b/src/Core/ITKLiveWire/itkLiveWireImageFunction.hxx index 880d4385a..d8b86924f 100755 --- a/src/Core/ITKLiveWire/itkLiveWireImageFunction.hxx +++ b/src/Core/ITKLiveWire/itkLiveWireImageFunction.hxx @@ -9,8 +9,8 @@ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + 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. =========================================================================*/ @@ -38,7 +38,7 @@ LiveWireImageFunction { this->m_GradientMagnitudeWeight = 0.43; this->m_ZeroCrossingWeight = 0.43; - this->m_GradientDirectionWeight = 0.14; + this->m_GradientDirectionWeight = 0.14; this->m_UseFaceConnectedness = true; this->m_UseImageSpacing = true; @@ -49,7 +49,7 @@ LiveWireImageFunction this->m_AnchorSeed.Fill( 0 ); } - + // Destructor template LiveWireImageFunction @@ -69,7 +69,7 @@ LiveWireImageFunction /** * Generate images for generating the weights from the input image - */ + */ typedef CastImageFilter CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput( this->GetInputImage() ); @@ -82,40 +82,40 @@ LiveWireImageFunction this->m_GradientImage = gradient->GetOutput(); this->m_GradientMagnitudeImage = RealImageType::New(); - this->m_GradientMagnitudeImage->SetOrigin( + this->m_GradientMagnitudeImage->SetOrigin( this->GetInputImage()->GetOrigin() ); - this->m_GradientMagnitudeImage->SetSpacing( + this->m_GradientMagnitudeImage->SetSpacing( this->GetInputImage()->GetSpacing() ); - this->m_GradientMagnitudeImage->SetRegions( + this->m_GradientMagnitudeImage->SetRegions( this->GetInputImage()->GetLargestPossibleRegion() ); this->m_GradientMagnitudeImage->Allocate(); - ImageRegionIterator ItG( this->m_GradientImage, + ImageRegionIterator ItG( this->m_GradientImage, this->m_GradientImage->GetLargestPossibleRegion() ); - ImageRegionIterator ItM( this->m_GradientMagnitudeImage, + ImageRegionIterator ItM( this->m_GradientMagnitudeImage, this->m_GradientMagnitudeImage->GetLargestPossibleRegion() ); for ( ItG.GoToBegin(), ItM.GoToBegin(); !ItG.IsAtEnd(); ++ItG, ++ItM ) { ItM.Set( ( ItG.Get() ).GetNorm() ); - } + } typedef RescaleIntensityImageFilter RescalerType; typename RescalerType::Pointer rescaler = RescalerType::New(); rescaler->SetInput( this->m_GradientMagnitudeImage ); rescaler->SetOutputMinimum( NumericTraits::Zero ); rescaler->SetOutputMaximum( NumericTraits::One ); - rescaler->Update(); + rescaler->Update(); this->m_RescaledGradientMagnitudeImage = rescaler->GetOutput(); if ( !this->m_ZeroCrossingImage ) { - typedef ZeroCrossingBasedEdgeDetectionImageFilter + typedef ZeroCrossingBasedEdgeDetectionImageFilter ZeroCrossingFilterType; - typename ZeroCrossingFilterType::Pointer + typename ZeroCrossingFilterType::Pointer zeroCrossing = ZeroCrossingFilterType::New(); zeroCrossing->SetInput( caster->GetOutput() ); - zeroCrossing->SetForegroundValue( NumericTraits::One ); - zeroCrossing->SetBackgroundValue( NumericTraits::Zero ); + zeroCrossing->SetForegroundValue( NumericTraits::One ); + zeroCrossing->SetBackgroundValue( NumericTraits::Zero ); zeroCrossing->Update(); this->m_ZeroCrossingImage = zeroCrossing->GetOutput(); } @@ -152,7 +152,7 @@ LiveWireImageFunction costImage->Allocate(); costImage->FillBuffer( NumericTraits::max() ); costImage->SetPixel( this->m_AnchorSeed, 0.0 ); - + this->m_PathDirectionImage = OffsetImageType::New(); this->m_PathDirectionImage->SetOrigin( this->GetInputImage()->GetOrigin() ); this->m_PathDirectionImage->SetSpacing( this->GetInputImage()->GetSpacing() ); @@ -161,12 +161,12 @@ LiveWireImageFunction typename ConstNeighborhoodIterator::RadiusType radius; radius.Fill( 1 ); - ConstNeighborhoodIterator It( radius, expanded, + ConstNeighborhoodIterator It( radius, expanded, expanded->GetLargestPossibleRegion() ); unsigned int numberOfNeighbors = 1; for ( unsigned int d = 0; d < ImageDimension; d++ ) { - numberOfNeighbors *= ( 2*radius[d] + 1 ); + numberOfNeighbors *= ( 2*radius[d] + 1 ); } Neighborhood scaleFactors; scaleFactors.SetRadius( radius ); @@ -175,41 +175,41 @@ LiveWireImageFunction scaleFactors[n] = 0; if ( n == static_cast( 0.5 * numberOfNeighbors ) ) { - continue; - } - typename Neighborhood::OffsetType offset + continue; + } + typename Neighborhood::OffsetType offset = scaleFactors.GetOffset( n ); - + bool isFaceConnected = true; - unsigned int sumOffset = 0; + unsigned int sumOffset = 0; for ( unsigned int d = 0; d < ImageDimension; d++ ) { sumOffset += vnl_math_abs( offset[d] ); if ( this->m_UseImageSpacing ) { - scaleFactors[n] += ( static_cast( offset[d] * offset[d] ) - * this->GetInputImage()->GetSpacing()[d] - * this->GetInputImage()->GetSpacing()[d] ); + scaleFactors[n] += ( static_cast( offset[d] * offset[d] ) + * this->GetInputImage()->GetSpacing()[d] + * this->GetInputImage()->GetSpacing()[d] ); } else { - scaleFactors[n] += static_cast( offset[d] * offset[d] ); + scaleFactors[n] += static_cast( offset[d] * offset[d] ); } if ( sumOffset > 1 && this->m_UseFaceConnectedness ) { isFaceConnected = false; break; } - } + } if ( !isFaceConnected ) { scaleFactors[n] = 0; } if ( scaleFactors[n] > 0 ) { - scaleFactors[n] = vcl_sqrt( scaleFactors[n] ); - } - } + scaleFactors[n] = std::sqrt( scaleFactors[n] ); + } + } /** * Generate the PathDirectionImage with Dijkstra's algorithm @@ -217,13 +217,13 @@ LiveWireImageFunction PriorityQueueElementType anchorElement( this->m_AnchorSeed, 0.0 ); - if ( this->m_MaskImage && - this->m_MaskImage->GetPixel( this->m_AnchorSeed ) + if ( this->m_MaskImage && + this->m_MaskImage->GetPixel( this->m_AnchorSeed ) != this->m_InsidePixelValue ) { - itkWarningMacro( "The anchor seed is outside the user-defined mask region." ); + itkWarningMacro( "The anchor seed is outside the user-defined mask region." ); return; - } + } typename PriorityQueueType::Pointer Q = PriorityQueueType::New(); Q->Initialize(); @@ -231,18 +231,18 @@ LiveWireImageFunction while ( !Q->Empty() ) { - PriorityQueueElementType centerElement = Q->Peek(); + PriorityQueueElementType centerElement = Q->Peek(); Q->Pop(); expanded->SetPixel( centerElement.m_Element, true ); - It.SetLocation( centerElement.m_Element ); + It.SetLocation( centerElement.m_Element ); PointType centerPoint; - this->GetInputImage()->TransformIndexToPhysicalPoint( + this->GetInputImage()->TransformIndexToPhysicalPoint( centerElement.m_Element, centerPoint ); - typename GradientImageType::PixelType centerGradient + typename GradientImageType::PixelType centerGradient = this->m_GradientImage->GetPixel( centerElement.m_Element ); - RealType centerNorm + RealType centerNorm = this->m_GradientMagnitudeImage->GetPixel( centerElement.m_Element ); for ( unsigned int n = 0; n < numberOfNeighbors; n++ ) @@ -250,27 +250,27 @@ LiveWireImageFunction if ( scaleFactors[n] == 0 ) { continue; - } + } bool inBounds; bool isExpanded = It.GetPixel( n, inBounds ); if ( isExpanded || !inBounds ) { continue; - } + } IndexType neighborIndex = It.GetIndex( n ); - - if ( this->m_MaskImage && this->m_MaskImage->GetPixel( + + if ( this->m_MaskImage && this->m_MaskImage->GetPixel( neighborIndex ) != this->m_InsidePixelValue ) { continue; - } + } - typename GradientImageType::PixelType neighborGradient + typename GradientImageType::PixelType neighborGradient = this->m_GradientImage->GetPixel( neighborIndex ); - RealType neighborNorm + RealType neighborNorm = this->m_GradientMagnitudeImage->GetPixel( neighborIndex ); - + RealType fz = 0.0; RealType fg = 0.0; RealType fd = 0.0; @@ -278,34 +278,34 @@ LiveWireImageFunction if ( this->m_ZeroCrossingWeight > 0 && this->m_ZeroCrossingImage ) { fz = 1.0 - this->m_ZeroCrossingImage->GetPixel( neighborIndex ); - } + } if ( this->m_GradientMagnitudeWeight > 0.0 ) { - fg = 1.0 - + fg = 1.0 - this->m_RescaledGradientMagnitudeImage->GetPixel( neighborIndex ); } - if ( this->m_GradientDirectionWeight > 0.0 + if ( this->m_GradientDirectionWeight > 0.0 && neighborNorm > 0 && centerNorm > 0 ) { PointType neighborPoint; - this->GetInputImage()->TransformIndexToPhysicalPoint( + this->GetInputImage()->TransformIndexToPhysicalPoint( neighborIndex, neighborPoint ); - typename PointType::VectorType vector + typename PointType::VectorType vector = neighborPoint - centerPoint; - RealType vectorNorm = vector.GetNorm(); + RealType vectorNorm = vector.GetNorm(); - RealType centerMin = vnl_math_min( centerGradient * vector, - centerGradient * -vector ); - RealType neighborMin = vnl_math_min( neighborGradient * vector, - neighborGradient * -vector ); + RealType centerMin = vnl_math_min( centerGradient * vector, + centerGradient * -vector ); + RealType neighborMin = vnl_math_min( neighborGradient * vector, + neighborGradient * -vector ); - fd = 1.0 - ( vcl_acos( centerMin / ( centerNorm * vectorNorm ) ) + - vcl_acos( neighborMin / ( neighborNorm * vectorNorm ) ) ) + fd = 1.0 - ( std::acos( centerMin / ( centerNorm * vectorNorm ) ) + + std::acos( neighborMin / ( neighborNorm * vectorNorm ) ) ) / vnl_math::pi; } - - RealType neighborCost + + RealType neighborCost = centerElement.m_Priority + scaleFactors[n] * ( fg * this->m_GradientMagnitudeWeight + fz * this->m_ZeroCrossingWeight @@ -324,29 +324,29 @@ LiveWireImageFunction { Q->Pop(); element = Q->Peek(); - } - } + } + } } } template -typename LiveWireImageFunction::OutputType::Pointer +typename LiveWireImageFunction::OutputType::Pointer LiveWireImageFunction ::EvaluateAtIndex( const IndexType &index ) const -{ +{ if ( !this->IsInsideBuffer( index ) ) { itkWarningMacro( "Requested index is not inside buffer." ); return nullptr; } - if ( this->m_MaskImage && - this->m_MaskImage->GetPixel( index ) + if ( this->m_MaskImage && + this->m_MaskImage->GetPixel( index ) != this->m_InsidePixelValue ) { - itkWarningMacro( "The index is outside the user-defined mask region." ); + itkWarningMacro( "The index is outside the user-defined mask region." ); return nullptr; - } + } typename OutputType::Pointer output = OutputType::New(); output->Initialize(); @@ -356,7 +356,7 @@ LiveWireImageFunction { output->AddVertex( VertexType( currentIndex ) ); currentIndex += this->m_PathDirectionImage->GetPixel( currentIndex ); - } + } output->AddVertex( VertexType( currentIndex ) ); return output; @@ -372,26 +372,26 @@ LiveWireImageFunction { Superclass::PrintSelf( os, indent ); - os << indent << "AnchorSeed: " + os << indent << "AnchorSeed: " << this->m_AnchorSeed << std::endl; - os << indent << "GradientMagnitudeWeight: " + os << indent << "GradientMagnitudeWeight: " << this->m_GradientMagnitudeWeight << std::endl; - os << indent << "GradientDirectionWeight: " + os << indent << "GradientDirectionWeight: " << this->m_GradientDirectionWeight << std::endl; - os << indent << "ZeroCrossingWeight: " + os << indent << "ZeroCrossingWeight: " << this->m_ZeroCrossingWeight << std::endl; - os << indent << "UseImageSpacing: " + os << indent << "UseImageSpacing: " << this->m_UseImageSpacing << std::endl; - os << indent << "UseFaceConnectedness: " + os << indent << "UseFaceConnectedness: " << this->m_UseFaceConnectedness << std::endl; os << indent << "MaskImage" << this->m_MaskImage << std::endl; os << indent << "InsidePixelValue" << this->m_InsidePixelValue << std::endl; - + } - + } // end namespace itk #endif diff --git a/src/Core/LargeVolume/LargeVolumeConverter.cc b/src/Core/LargeVolume/LargeVolumeConverter.cc index a3fd6d3c8..9f2c709dc 100644 --- a/src/Core/LargeVolume/LargeVolumeConverter.cc +++ b/src/Core/LargeVolume/LargeVolumeConverter.cc @@ -137,7 +137,7 @@ bool LargeVolumeBrickLevel::insert_slice_internals( DataBlockHandle slice ) IndexVector::index_type sy_begin2 = Max( by * eff_brick_size.y() - overlap , static_cast( 0 ) ); IndexVector::index_type sy_end2 = Min( ( by + 1 ) * eff_brick_size.y() + overlap, sny ); IndexVector::index_type sy_end = Min( ( by + 1 ) * eff_brick_size.y() + overlap, sny + overlap ) ; - + IndexVector::index_type sx_begin = bx * eff_brick_size.x() - overlap; IndexVector::index_type sx_begin2 = Max(bx * eff_brick_size.x() - overlap, static_cast( 0 ) ); IndexVector::index_type sx_end2 = Min( ( bx + 1 ) * eff_brick_size.x() + overlap, snx ); @@ -145,8 +145,8 @@ bool LargeVolumeBrickLevel::insert_slice_internals( DataBlockHandle slice ) // Copy brick; - for ( IndexVector::index_type p = sy_begin * nx ; p < sy_begin2 * nx ; p++, data++ ) - { + for ( IndexVector::index_type p = sy_begin * nx ; p < sy_begin2 * nx ; p++, data++ ) + { *data = T(0); } @@ -154,7 +154,7 @@ bool LargeVolumeBrickLevel::insert_slice_internals( DataBlockHandle slice ) { // Add overlap for ( IndexVector::index_type p = sx_begin; p < sx_begin2 ; p++, data++ ) - { + { *data = T(0); } @@ -165,19 +165,19 @@ bool LargeVolumeBrickLevel::insert_slice_internals( DataBlockHandle slice ) // Add overlap for ( IndexVector::index_type p = sx_end2; p < sx_end ; p++, data++ ) - { + { *data = T(0); } } - for ( IndexVector::index_type p = sy_end2 * nx ; p < sy_end * nx ; p++, data++ ) - { + for ( IndexVector::index_type p = sy_end2 * nx ; p < sy_end * nx ; p++, data++ ) + { *data = T(0); } - } + } } - } + } else { for ( IndexVector::index_type by = 0; by < this->layout_.y(); by++ ) @@ -222,10 +222,14 @@ bool LargeVolumeBrickLevel::insert_slice( DataBlockHandle slice ) return this->insert_slice_internals( slice ); case DataType::UINT_E: return this->insert_slice_internals( slice ); + case DataType::LONGLONG_E: + return this->insert_slice_internals( slice ); + case DataType::ULONGLONG_E: + return this->insert_slice_internals( slice ); case DataType::FLOAT_E: return this->insert_slice_internals( slice ); case DataType::DOUBLE_E: - return this->insert_slice_internals( slice ); + return this->insert_slice_internals( slice ); } return false; @@ -244,7 +248,7 @@ bool LargeVolumeBrickLevel::sync_buffers( bool done, std::string& error ) { IndexVector::index_type buffer_start = this->buffer_count_ - this->buffer_index_; IndexVector::index_type buffer_size = this->buffer_count_ - buffer_start; - + IndexVector brick_size = this->schema_->get_brick_size(); IndexVector eff_brick_size = this->schema_->get_effective_brick_size(); IndexVector::index_type overlap = this->schema_->get_overlap(); @@ -262,7 +266,7 @@ bool LargeVolumeBrickLevel::sync_buffers( bool done, std::string& error ) IndexVector::index_type end = Min( z_end , buffer_size ); IndexVector::index_type offset = buffer_start + start - b_start; - + if ( end >= 0 && start < buffer_size && start < end) { @@ -270,7 +274,7 @@ bool LargeVolumeBrickLevel::sync_buffers( bool done, std::string& error ) for (size_t k = 0; k < this->buffers_.size(); k++ ) { - + IndexVector::index_type brick = k + z * (this->layout_.x() * this->layout_.y() ); BrickInfo bi( brick, this->level_ ); @@ -331,21 +335,21 @@ class LargeVolumeConverterPrivate { DataBlockHandle load_file( const boost::filesystem::path& filename, std::string& error ); /// LOAD_FILE_INTERNALS - /// Intrernals for dealing with data type + /// Intrernals for dealing with data type template DataBlockHandle load_file_internals( const boost::filesystem::path& filename, std::string& error ); /// SCAN_FILE /// Scan file to determine type and size bool scan_file( const boost::filesystem::path& filename, std::string& error ); - + // -- downsample -- public: /// DOWNSAMPLE /// Down sample a slice based on the level ratios bool downsample( DataBlockHandle input, DataBlockHandle output, const IndexVector& input_ratio, const IndexVector& output_ratio ); - + /// DOWNSAMPLE_INTERNALS /// Templated version that does internal computation template @@ -356,7 +360,7 @@ class LargeVolumeConverterPrivate { /// Down sample a slice based on the level ratios and adds it to the existing slice bool downsample_add( DataBlockHandle input, DataBlockHandle output, const IndexVector& input_ratio, const IndexVector& output_ratio ); - + /// DOWNSAMPLE_ADD_INTERNALS /// Templated version that does internal computation template @@ -379,7 +383,7 @@ class LargeVolumeConverterPrivate { // -- slice processor -- public: bool process_slice( size_t level, std::string& error ); - + // slices at different resolution levels std::vector slices_; @@ -429,11 +433,15 @@ bool LargeVolumeConverterPrivate::compute_min_max( DataBlockHandle slice, double case DataType::INT_E: return compute_min_max_internals( slice, min, max); case DataType::UINT_E: - return compute_min_max_internals( slice, min, max); + return compute_min_max_internals( slice, min, max); + case DataType::LONGLONG_E: + return compute_min_max_internals( slice, min, max); + case DataType::ULONGLONG_E: + return compute_min_max_internals( slice, min, max); case DataType::FLOAT_E: return compute_min_max_internals( slice, min, max); case DataType::DOUBLE_E: - return compute_min_max_internals( slice, min, max); + return compute_min_max_internals( slice, min, max); } return false; @@ -445,7 +453,7 @@ bool LargeVolumeConverterPrivate::process_slice( size_t level, std::string& erro bool first_slice = ( this->index_[ level ] == 0); DataBlockHandle slice = slices_[ level ]; - + // Brick the data if ( first_slice ) { @@ -484,13 +492,13 @@ bool LargeVolumeConverterPrivate::process_slice( size_t level, std::string& erro { this->brick_level_[ level ]->sync_buffers( false, error ); } - + // Down sample data for next level if ( level < this->schema_->get_num_levels() - 1 ) { IndexVector input_ratio = this->schema_->get_level_downsample_ratio( level ); IndexVector output_ratio = this->schema_->get_level_downsample_ratio( level + 1); - + if ( output_ratio.z() / input_ratio.z() == 2 ) { if ( index_[ level ] % 2 ) @@ -518,7 +526,7 @@ bool LargeVolumeConverterPrivate::process_slice( size_t level, std::string& erro if (! this->process_slice( level + 1, error ) ) { return false; - } + } } } } @@ -529,13 +537,13 @@ bool LargeVolumeConverterPrivate::process_slice( size_t level, std::string& erro error = "Failed to downsample slice."; return false; } - + if (! this->process_slice( level + 1, error ) ) { return false; } } - + } index_[ level ]++; @@ -571,14 +579,14 @@ DataBlockHandle LargeVolumeConverterPrivate::load_file_internals( const boost::f try { - image_data = typename ITKImageContainer::Handle( - new ITKImageContainer( reader->GetOutput() ) ); + image_data = typename ITKImageContainer::Handle( + new ITKImageContainer( reader->GetOutput() ) ); } catch ( ... ) { error = "Importer could not read itk object."; return DataBlockHandle(); - } + } return ITKDataBlock::New( image_data ); } @@ -596,15 +604,19 @@ DataBlockHandle LargeVolumeConverterPrivate::load_file( const boost::filesystem: case DataType::USHORT_E: return this->load_file_internals( filename, error ); case DataType::SHORT_E: - return this->load_file_internals( filename, error ); + return this->load_file_internals( filename, error ); case DataType::UINT_E: return this->load_file_internals( filename, error ); case DataType::INT_E: - return this->load_file_internals( filename, error ); + return this->load_file_internals( filename, error ); + case DataType::ULONGLONG_E: + return this->load_file_internals( filename, error ); + case DataType::LONGLONG_E: + return this->load_file_internals( filename, error ); case DataType::FLOAT_E: return this->load_file_internals( filename, error ); case DataType::DOUBLE_E: - return this->load_file_internals( filename, error ); + return this->load_file_internals( filename, error ); } error = "Could not determine data type."; @@ -622,14 +634,14 @@ bool LargeVolumeConverterPrivate::scan_file( const boost::filesystem::path& file if ( Core::FileUtil::CheckExtension( filename, ".png") ) { reader->SetImageIO( itk::PNGImageIO::New() ); - } + } else if ( Core::FileUtil::CheckExtension( filename, ".tif|.tiff") ) { - reader->SetImageIO( itk::TIFFImageIO::New() ); + reader->SetImageIO( itk::TIFFImageIO::New() ); } else if ( Core::FileUtil::CheckExtension( filename, ".jpg|.jpeg") ) { - reader->SetImageIO( itk::JPEGImageIO::New() ); + reader->SetImageIO( itk::JPEGImageIO::New() ); } else if ( Core::FileUtil::CheckExtension( filename, ".dcm|.dicom") ) { @@ -650,17 +662,19 @@ bool LargeVolumeConverterPrivate::scan_file( const boost::filesystem::path& file return false; } - itk::ImageIOBase* IO = reader->GetImageIO(); + const itk::ImageIOBase* IO = reader->GetImageIO(); // Grab the information on the data type from the ITK image std::string type_string = IO->GetComponentTypeAsString( IO->GetComponentType() ); - + if( type_string == "unsigned_char" ) this->data_type_ = Core::DataType::UCHAR_E; if( type_string == "char" ) this->data_type_ = Core::DataType::CHAR_E; if( type_string == "unsigned_short" ) this->data_type_ = Core::DataType::USHORT_E; if( type_string == "short" ) this->data_type_ = Core::DataType::SHORT_E; if( type_string == "unsigned_int" ) this->data_type_ = Core::DataType::UINT_E; if( type_string == "int" ) this->data_type_ = Core::DataType::INT_E; + if( type_string == "unsigned_long_long" ) this->data_type_ = Core::DataType::ULONGLONG_E; + if( type_string == "long_long" ) this->data_type_ = Core::DataType::LONGLONG_E; if( type_string == "float" ) this->data_type_ = Core::DataType::FLOAT_E; if( type_string == "double" ) this->data_type_ = Core::DataType::DOUBLE_E; @@ -669,20 +683,20 @@ bool LargeVolumeConverterPrivate::scan_file( const boost::filesystem::path& file error = "Could not determine data type."; return false; } - + // Grab the image from the output so we can read its transform Core::ITKUCharImage2DDataHandle image_data; try { - image_data = Core::ITKUCharImage2DDataHandle( - new Core::ITKUCharImage2DData( reader->GetOutput() ) ); + image_data = Core::ITKUCharImage2DDataHandle( + new Core::ITKUCharImage2DData( reader->GetOutput() ) ); } catch ( ... ) { error = "Importer could not read itk object."; return false; - } - + } + this->data_size_.x( image_data->get_nx() ); this->data_size_.y( image_data->get_ny() ); @@ -711,7 +725,7 @@ bool LargeVolumeConverterPrivate::downsample_internals( DataBlockHandle input, D { *dst = static_cast( ( static_cast( src[0] ) + static_cast( src[1] ) + static_cast( src[nx] ) + static_cast( src[nx+1] ) ) / 4 ); } - + if (nx % 2) { *dst = static_cast( ( static_cast( src[0] ) + static_cast( src[nx] ) ) / 2 ); @@ -719,14 +733,14 @@ bool LargeVolumeConverterPrivate::downsample_internals( DataBlockHandle input, D src++; } } - + if ( ny % 2 ) { for ( DataBlock::index_type x = 0; x < (nx-1); x += 2, src += 2, dst++ ) { *dst = static_cast( ( static_cast( src[0] ) + static_cast( src[1] ) ) / 2 ); } - + if (nx % 2) { *dst = *src; @@ -743,7 +757,7 @@ bool LargeVolumeConverterPrivate::downsample_internals( DataBlockHandle input, D { *dst = static_cast( ( static_cast( src[0] ) + static_cast( src[1] ) ) / 2 ); } - + if (nx % 2) { *dst = *src; @@ -761,7 +775,7 @@ bool LargeVolumeConverterPrivate::downsample_internals( DataBlockHandle input, D *dst = static_cast( ( static_cast( src[0] ) + static_cast( src[nx] ) ) / 2 ); } } - + if ( ny % 2 ) { for ( DataBlock::index_type x = 0; x < nx; x ++, src ++, dst++ ) @@ -778,7 +792,7 @@ bool LargeVolumeConverterPrivate::downsample_internals( DataBlockHandle input, D *dst = *src; } } - + return true; } @@ -789,7 +803,7 @@ bool LargeVolumeConverterPrivate::downsample( DataBlockHandle input, DataBlockHa { return false; } - + switch( input->get_data_type() ) { case DataType::UCHAR_E: @@ -804,12 +818,16 @@ bool LargeVolumeConverterPrivate::downsample( DataBlockHandle input, DataBlockHa return this->downsample_internals( input, output, input_ratio, output_ratio ); case DataType::INT_E: return this->downsample_internals( input, output, input_ratio, output_ratio ); + case DataType::ULONGLONG_E: + return this->downsample_internals( input, output, input_ratio, output_ratio ); + case DataType::LONGLONG_E: + return this->downsample_internals( input, output, input_ratio, output_ratio ); case DataType::FLOAT_E: return this->downsample_internals( input, output, input_ratio, output_ratio ); case DataType::DOUBLE_E: return this->downsample_internals( input, output, input_ratio, output_ratio ); } - + return false; } @@ -834,7 +852,7 @@ bool LargeVolumeConverterPrivate::downsample_add_internals( DataBlockHandle inpu { *dst = static_cast( ( static_cast( dst[0] * 4 ) + static_cast( src[0] ) + static_cast( src[1] ) + static_cast( src[nx] ) + static_cast( src[nx+1] ) ) / 8 ); } - + if (nx % 2) { *dst = static_cast( ( static_cast( dst[0] * 2 ) + static_cast( src[0] ) + static_cast( src[nx] ) ) / 4 ); @@ -842,14 +860,14 @@ bool LargeVolumeConverterPrivate::downsample_add_internals( DataBlockHandle inpu src++; } } - + if ( ny % 2 ) { for ( DataBlock::index_type x = 0; x < (nx-1); x += 2, src += 2, dst++ ) { *dst = static_cast( ( static_cast( dst[0] * 2 ) + static_cast( src[0] ) + static_cast( src[1] ) ) / 4 ); } - + if (nx % 2) { *dst = static_cast( ( static_cast( *dst ) + static_cast( *src ) ) / 2 ); @@ -866,7 +884,7 @@ bool LargeVolumeConverterPrivate::downsample_add_internals( DataBlockHandle inpu { *dst = static_cast( ( static_cast( dst[0] * 2 ) + static_cast( src[0] ) + static_cast( src[1] ) ) / 4 ); } - + if (nx % 2) { *dst = static_cast( ( static_cast( *dst ) + static_cast( *src ) ) / 2 ); @@ -884,7 +902,7 @@ bool LargeVolumeConverterPrivate::downsample_add_internals( DataBlockHandle inpu *dst = static_cast( ( static_cast( dst[0] * 2 ) + static_cast( src[0] ) + static_cast( src[nx] ) ) / 4 ); } } - + if ( ny % 2 ) { for ( DataBlock::index_type x = 0; x < nx; x ++, src++, dst++ ) @@ -901,7 +919,7 @@ bool LargeVolumeConverterPrivate::downsample_add_internals( DataBlockHandle inpu *dst = static_cast( ( static_cast( *dst ) + static_cast( *src ) ) / 2 ); } } - + return true; } @@ -913,7 +931,7 @@ bool LargeVolumeConverterPrivate::downsample_add( DataBlockHandle input, DataBlo { return false; } - + switch( input->get_data_type() ) { case DataType::UCHAR_E: @@ -928,12 +946,16 @@ bool LargeVolumeConverterPrivate::downsample_add( DataBlockHandle input, DataBlo return downsample_add_internals( input, output, input_ratio, output_ratio ); case DataType::INT_E: return downsample_add_internals( input, output, input_ratio, output_ratio ); + case DataType::ULONGLONG_E: + return downsample_add_internals( input, output, input_ratio, output_ratio ); + case DataType::LONGLONG_E: + return downsample_add_internals( input, output, input_ratio, output_ratio ); case DataType::FLOAT_E: return downsample_add_internals( input, output, input_ratio, output_ratio ); case DataType::DOUBLE_E: return downsample_add_internals( input, output, input_ratio, output_ratio ); } - + return false; } @@ -1020,7 +1042,7 @@ bool LargeVolumeConverter::run_phase2( std::string& error ) // Calculate size for down sample slices size_t slice_buffer_size = 0; size_t element_size = Core::GetSizeDataType( this->private_->schema_->get_data_type() ); - + // Calculate size for each slice for ( size_t j = 0; j < num_levels; j++) { @@ -1041,7 +1063,7 @@ bool LargeVolumeConverter::run_phase2( std::string& error ) // Initialize parameters for each level this->private_->slices_.resize( num_levels ); this->private_->index_.resize( num_levels, 0 ); - + this->private_->brick_level_.resize( num_levels ); // Allocate resample buffers @@ -1068,7 +1090,7 @@ bool LargeVolumeConverter::run_phase2( std::string& error ) if ( buffer_size == 0 ) { error = "Please allocate more memory to conversion process."; - return false; + return false; } for ( size_t j = 0; j < num_levels; j++ ) @@ -1088,11 +1110,11 @@ bool LargeVolumeConverter::run_phase2( std::string& error ) // indicate which slice is being processed std::cout << "Processing file: " << this->private_->files_[ slice_idx ].string() << std::endl; - + // load slice this->private_->slices_[ 0 ] = this->private_->load_file( this->private_->files_[ slice_idx ], error ); - - if (! this->private_->slices_[ 0 ] ) + + if (! this->private_->slices_[ 0 ] ) { return false; } @@ -1101,9 +1123,9 @@ bool LargeVolumeConverter::run_phase2( std::string& error ) { std::cout << "WARNING: Dimensions of the slices are not equal, clipping/padding image to fit dimensions of first image." <private_->slices_[ 0 ], this->private_->slices_[ 0 ], total_size.x(), total_size.y(), 1, 0.0 ); - } - - + } + + if (! this->private_->compute_min_max( this->private_->slices_[ 0 ], min, max ) ) { error = "Could not compute min and max."; @@ -1142,12 +1164,12 @@ void LargeVolumeConverterPrivate::run_phase3_parallel( int thread_num, int num_t { if ( thread_num == 0 ) { - std::cout << "processing level: " << ExportToString( j ) << std::endl; + std::cout << "processing level: " << ExportToString( j ) << std::endl; } IndexVector layout = this->schema_->get_level_layout( j ); IndexVector::index_type num_bricks = layout[0] * layout[1] * layout[2]; - + if ( thread_num == 0 ) { std::cout << "processing brick: 000000/000000"; @@ -1160,7 +1182,7 @@ void LargeVolumeConverterPrivate::run_phase3_parallel( int thread_num, int num_t std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b" << std::setfill('0') << std::setw(6) << (k+1) << "/" << std::setfill('0') << std::setw(6) << num_bricks; std::cout.flush(); } - + BrickInfo bi( k ,j ); if (! this->schema_->reprocess_brick( bi, error) ) { @@ -1175,7 +1197,7 @@ void LargeVolumeConverterPrivate::run_phase3_parallel( int thread_num, int num_t { std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b" << std::setfill('0') << std::setw(6) << num_bricks << "/" << std::setfill('0') << std::setw(6) << num_bricks; std::cout << std::endl; - + } } diff --git a/src/Core/LargeVolume/LargeVolumeSchema.cc b/src/Core/LargeVolume/LargeVolumeSchema.cc index 7865b5b8c..aa9069314 100644 --- a/src/Core/LargeVolume/LargeVolumeSchema.cc +++ b/src/Core/LargeVolume/LargeVolumeSchema.cc @@ -89,7 +89,7 @@ class LargeVolumeSchemaPrivate { { const IndexVector& effective_brick_size = this->effective_brick_size_; - return IndexVector( Ceil( size.xd() / effective_brick_size.x() ), + return IndexVector( Ceil( size.xd() / effective_brick_size.x() ), Ceil( size.yd() / effective_brick_size.y() ), Ceil( size.zd() / effective_brick_size.z() ) ); } @@ -126,7 +126,7 @@ class LargeVolumeSchemaPrivate { return Ceil( size.xd() / effective_brick_size.x() ) * Ceil( size.yd() / effective_brick_size.y() ) * Ceil( size.zd() / effective_brick_size.z() ); } - + IndexVector compute_remainder_brick( const BrickInfo& bi, const IndexVector& index ) { @@ -134,7 +134,7 @@ class LargeVolumeSchemaPrivate { const IndexVector& size = this->level_size_[ bi.level_ ]; const size_t overlap = this->overlap_; IndexVector remainder_brick_size = this->brick_size_; - + if ( index.x() == layout.x() - 1 ) remainder_brick_size.x( size.x() - ( this->effective_brick_size_.x() * index.x()) + 2 * overlap ); if ( index.y() == layout.y() - 1 ) remainder_brick_size.y( size.y() - ( this->effective_brick_size_.y() * index.y()) + 2 * overlap ); if ( index.z() == layout.z() - 1 ) remainder_brick_size.z( size.z() - ( this->effective_brick_size_.z() * index.z()) + 2 * overlap ); @@ -150,7 +150,7 @@ class LargeVolumeSchemaPrivate { } - void compute_cached_level_info() + void compute_cached_level_info() { this->level_spacing_.clear(); this->level_size_.clear(); @@ -180,7 +180,7 @@ class LargeVolumeSchemaPrivate { const IndexVector& clip_start, const IndexVector& clip_end ); - void load_and_substitue_missing_bricks( std::vector& want_to_render, SliceType slice, + void load_and_substitue_missing_bricks( std::vector& want_to_render, SliceType slice, double depth, const std::string& load_key, std::vector& current_render ); // -- contents in the text header -- @@ -210,7 +210,7 @@ class LargeVolumeSchemaPrivate { double min_; double max_; - + bfs::path dir_; LargeVolumeSchema* schema_; }; @@ -247,7 +247,7 @@ bool LargeVolumeSchemaPrivate::insert_brick_internals( DataBlockHandle volume, D const IndexVector::index_type vxstride = vnx - ( bxend - bxstart ); const IndexVector::index_type vystride = ( vny - ( byend - bystart ) ) * vnx; - + // same code from here to return T* src = reinterpret_cast( brick->get_data() ); T* dst = reinterpret_cast( volume->get_data() ); @@ -262,8 +262,8 @@ bool LargeVolumeSchemaPrivate::insert_brick_internals( DataBlockHandle volume, D for ( IndexVector::index_type x = bxstart; x < bxend; x++ , src++, dst++ ) { *dst = *src; - } - } + } + } } return true; @@ -284,7 +284,7 @@ bool LargeVolumeSchemaPrivate::insert_brick_internals( DataBlockHandle volume, D const IndexVector::index_type bxstart = overlap; const IndexVector::index_type bystart = overlap; const IndexVector::index_type bzstart = overlap; - + const IndexVector::index_type bxend = bnx - overlap; const IndexVector::index_type byend = bny - overlap; const IndexVector::index_type bzend = bnz - overlap; @@ -299,7 +299,7 @@ bool LargeVolumeSchemaPrivate::insert_brick_internals( DataBlockHandle volume, D const IndexVector::index_type vxstride = vnx - ( bnx - 2 * overlap ); const IndexVector::index_type vystride = ( vny - ( bny - 2 * overlap ) ) * vnx; - + // same code from here to return T* src = reinterpret_cast( brick->get_data() ); T* dst = reinterpret_cast( volume->get_data() ); @@ -314,8 +314,8 @@ bool LargeVolumeSchemaPrivate::insert_brick_internals( DataBlockHandle volume, D for ( IndexVector::index_type x = bxstart; x < bxend; x++ , src++, dst++ ) { *dst = *src; - } - } + } + } } return true; @@ -345,14 +345,14 @@ bool LargeVolumeSchema::load( std::string& error) std::ifstream file_text( filename.string().c_str() ); std::string line; std::map values; - + // read text file while( !file_text.eof() ) { // Grab the next line std::getline( file_text, line ); - + std::vector key_value = SplitString( line, ":" ); if ( key_value.size() == 2 ) { @@ -369,7 +369,7 @@ bool LargeVolumeSchema::load( std::string& error) error = "Volume file does not contain a field called 'size'."; return false; } - + if (! ImportFromString( values[ "size" ], this->private_->size_ ) ) { error = "Could not read size field."; @@ -381,7 +381,7 @@ bool LargeVolumeSchema::load( std::string& error) error = "Volume file does not contain a field called 'origin'."; return false; } - + if ( !ImportFromString( values[ "origin" ], this->private_->origin_ ) ) { error = "Could not read origin field."; @@ -393,7 +393,7 @@ bool LargeVolumeSchema::load( std::string& error) error = "Volume file does not contain a field called 'spacing'."; return false; } - + if ( !ImportFromString( values["spacing" ], this->private_->spacing_ ) ) { error = "Could not read spacing field."; @@ -406,7 +406,7 @@ bool LargeVolumeSchema::load( std::string& error) error = "Volume file does not contain a field called 'bricksize'."; return false; } - + if (! ImportFromString( values[ "bricksize" ], this->private_->brick_size_ ) ) { IndexVector::index_type single_brick_size; @@ -425,7 +425,7 @@ bool LargeVolumeSchema::load( std::string& error) error = "Volume file does not contain a field called 'overlap'."; return false; } - + if (! ImportFromString( values[ "overlap" ], this->private_->overlap_ ) ) { error = "Could not read overlap field."; @@ -441,7 +441,7 @@ bool LargeVolumeSchema::load( std::string& error) error = "Volume file does not contain a field called 'datatype'."; return false; } - + if (! ImportFromString( values[ "datatype" ], this->private_->data_type_ ) ) { error = "Could not read datatype field."; @@ -453,7 +453,7 @@ bool LargeVolumeSchema::load( std::string& error) error = "Volume file does not contain a field called 'endian'."; return false; } - + if ( values[ "endian" ] == "little" ) { this->private_->little_endian_ = true; @@ -489,11 +489,11 @@ bool LargeVolumeSchema::load( std::string& error) } size_t level = 0; - + while ( values.find( "level" + ExportToString(level)) != values.end() ) { std::string level_string = values[ "level" + ExportToString(level) ]; - + IndexVector ratios; if (! ImportFromString( level_string, ratios )) { @@ -502,10 +502,10 @@ bool LargeVolumeSchema::load( std::string& error) } this->private_->levels_.push_back( ratios ); - + level++; } - + this->private_->compute_cached_level_info(); } catch (...) @@ -527,10 +527,10 @@ bool LargeVolumeSchema::save( std::string& error ) const } bfs::path filename = this->private_->dir_ / VOLUME_FILE_NAME_; - + try { std::ofstream text_file( filename.string().c_str() ); - + text_file << "size: " << ExportToString( this->private_->size_ ) << std::endl; text_file << "origin: " << ExportToString( this->private_->origin_ ) << std::endl; text_file << "spacing: " << ExportToString( this->private_->spacing_ ) << std::endl; @@ -541,9 +541,9 @@ bool LargeVolumeSchema::save( std::string& error ) const text_file << "endian: " << ( this->private_->little_endian_ ? "little" : "big" ) << std::endl; text_file << "min: " << ExportToString( this->private_->min_ ) << std::endl; text_file << "max: " << ExportToString( this->private_->max_ ) << std::endl; - + for (size_t j = 0 ; j < this->private_->levels_.size(); j++ ) - { + { text_file << "level" << j << ": " << ExportToString( this->private_->levels_[j] ) << std::endl; } } @@ -685,7 +685,7 @@ void LargeVolumeSchema::set_dir( const bfs::path& dir ) this->private_->dir_ = dir; } -void LargeVolumeSchema::set_parameters( const IndexVector& size, const Vector& spacing, const Point& origin, +void LargeVolumeSchema::set_parameters( const IndexVector& size, const Vector& spacing, const Point& origin, const IndexVector& brick_size, size_t overlap, DataType data_type ) { this->private_->size_ = size; @@ -720,8 +720,8 @@ void LargeVolumeSchema::compute_levels() { IndexVector size = this->private_->compute_level_size( cur_level ); IndexVector layout = this->private_->compute_brick_layout( size ); - while ( - (this->private_->downsample_x_ && layout.x() > 1) || + while ( + (this->private_->downsample_x_ && layout.x() > 1) || (this->private_->downsample_y_ && layout.y() > 1) || (this->private_->downsample_z_ && layout.z() > 1) ) { @@ -735,7 +735,7 @@ void LargeVolumeSchema::compute_levels() if ( spacing.x() < min_spacing ) ratio.x( 2 * ratio.x() ); if ( spacing.y() < min_spacing ) ratio.y( 2 * ratio.y() ); if ( spacing.z() < min_spacing ) ratio.z( 2 * ratio.z() ); - + this->private_->levels_.push_back( ratio ); cur_level++; size = this->private_->compute_level_size( cur_level ); @@ -777,7 +777,7 @@ bool LargeVolumeSchema::read_brick( DataBlockHandle& brick, const BrickInfo& bi, { IndexVector size = this->get_brick_size( bi ); brick = StdDataBlock::New( size[0], size[1], size[2], this->get_data_type() ); - + if ( !brick ) { error = "Could not allocate brick."; @@ -789,7 +789,7 @@ bool LargeVolumeSchema::read_brick( DataBlockHandle& brick, const BrickInfo& bi, if ( !bfs::exists(brick_file ) ) { error = "Could not open brick."; - return false; + return false; } size_t file_size = bfs::file_size( brick_file ); @@ -817,7 +817,7 @@ bool LargeVolumeSchema::read_brick( DataBlockHandle& brick, const BrickInfo& bi, { error = "Brick '" + brick_file.string() + "' contains invalid data."; brick->clear(); - return false; + return false; } } catch ( ... ) @@ -840,9 +840,9 @@ bool LargeVolumeSchema::read_brick( DataBlockHandle& brick, const BrickInfo& bi, error = "Error reading file '" + brick_file.string() + "'."; brick->clear(); return false; - } + } } - else + else { error = "Brick file is too large to be a brick."; brick->clear(); @@ -861,8 +861,8 @@ bool LargeVolumeSchema::append_brick_buffer( DataBlockHandle data_block, size_t size_t offset, const BrickInfo& bi, std::string& error ) const { IndexVector size = this->get_brick_size( bi ); - - size_t slice_size = data_block->get_nx() * data_block->get_ny(); + + size_t slice_size = data_block->get_nx() * data_block->get_ny(); if ( size[0] != data_block->get_nx() || size[1] != data_block->get_ny() ) { @@ -884,7 +884,7 @@ bool LargeVolumeSchema::append_brick_buffer( DataBlockHandle data_block, size_t try { std::ofstream output( brick_file.string().c_str(), std::ios_base::app | std::ios_base::binary | std::ios_base::out ); - + output.seekp( offset * size[0] * size[1] * GetSizeDataType( this->get_data_type()), std::ios_base::beg ); output.write( reinterpret_cast( data_block->get_data() ) + buffer_offset, buffer_size ); } @@ -892,7 +892,7 @@ bool LargeVolumeSchema::append_brick_buffer( DataBlockHandle data_block, size_t { error = "Could not write to file '" + brick_file.string() + "'."; return false; - } + } return true; } @@ -900,7 +900,7 @@ bool LargeVolumeSchema::append_brick_buffer( DataBlockHandle data_block, size_t bool LargeVolumeSchema::write_brick( DataBlockHandle data_block, const BrickInfo& bi, std::string& error ) const { IndexVector size = this->get_brick_size( bi ); - + if ( size[0] != data_block->get_nx() || size[1] != data_block->get_ny() || size[2] != data_block->get_nz() ) { @@ -918,7 +918,7 @@ bool LargeVolumeSchema::write_brick( DataBlockHandle data_block, const BrickInfo size_t brick_size = size[0] * size[1] * size[2] * GetSizeDataType( this->get_data_type() ); - if ( this->private_->compression_) + if ( this->private_->compression_) { std::vector buffer( brick_size + 12 ); zlib_uLongf brick_size_ul = brick_size + 12; @@ -930,7 +930,7 @@ bool LargeVolumeSchema::write_brick( DataBlockHandle data_block, const BrickInfo error = "Could not compress file."; return false; } - + if ( brick_size_ul < brick_size ) { // Compression succeeded @@ -945,8 +945,8 @@ bool LargeVolumeSchema::write_brick( DataBlockHandle data_block, const BrickInfo return false; } - } - else + } + else { try { @@ -957,7 +957,7 @@ bool LargeVolumeSchema::write_brick( DataBlockHandle data_block, const BrickInfo { error = "Could not write to file '" + brick_file.string() + "'."; return false; - } + } } } else @@ -971,7 +971,7 @@ bool LargeVolumeSchema::write_brick( DataBlockHandle data_block, const BrickInfo { error = "Could not write to file '" + brick_file.string() + "'."; return false; - } + } } return true; @@ -1003,7 +1003,7 @@ bool LargeVolumeSchema::get_children( const BrickInfo& bi, SliceType slice, doub children.clear(); BrickInfo::index_type level = bi.level_; - if (level == 0 ) return false; + if (level == 0 ) return false; IndexVector ratio = this->get_level_downsample_ratio( level ); IndexVector ratio_next = this->get_level_downsample_ratio( level - 1 ); @@ -1019,7 +1019,7 @@ bool LargeVolumeSchema::get_children( const BrickInfo& bi, SliceType slice, doub Vector spacing = this->get_level_spacing( level ); IndexVector eb = this->private_->effective_brick_size_; - + switch ( slice ) { case SliceType::SAGITTAL_E: @@ -1031,19 +1031,19 @@ bool LargeVolumeSchema::get_children( const BrickInfo& bi, SliceType slice, doub if ( spacing.x() * eb.xd() * ( index.xd() + 0.5 ) > depth - origin.x() ) { x_index = 2 * x_index; - } - else + } + else { - x_index = 2 * x_index + 1; + x_index = 2 * x_index + 1; } - } + } x_index = Min( x_index, layout_next.x() - 1 ); - for (IndexVector::index_type y = rat.y() * index.y(); + for (IndexVector::index_type y = rat.y() * index.y(); y < Min( layout_next.y(), rat.y() * ( index.y() + 1 ) ); y++ ) { - for (IndexVector::index_type z = rat.z() * index.z(); + for (IndexVector::index_type z = rat.z() * index.z(); z < Min( layout_next.z(), rat.z() * ( index.z() + 1 ) ); z++ ) { children.push_back( BrickInfo( layout_next.x() * layout_next.y() * z + @@ -1063,19 +1063,19 @@ bool LargeVolumeSchema::get_children( const BrickInfo& bi, SliceType slice, doub if (spacing.y() * eb.yd() * ( index.yd() + 0.5 ) > depth - origin.y()) { y_index = 2 * y_index; - } - else + } + else { - y_index = 2 * y_index + 1; + y_index = 2 * y_index + 1; } - } + } y_index = Min( y_index, layout_next.y() - 1 ); - for (IndexVector::index_type x = rat.x() * index.x(); + for (IndexVector::index_type x = rat.x() * index.x(); x < Min( layout_next.x(), rat.x() * ( index.x() + 1 ) ); x++ ) { - for (IndexVector::index_type z = rat.z() * index.z(); + for (IndexVector::index_type z = rat.z() * index.z(); z < Min( layout_next.z(), rat.z() * ( index.z() + 1 ) ); z++ ) { children.push_back( BrickInfo( layout_next.x() * layout_next.y() * z + @@ -1094,19 +1094,19 @@ bool LargeVolumeSchema::get_children( const BrickInfo& bi, SliceType slice, doub if (spacing.z() * eb.zd() * ( index.zd() + 0.5 ) > depth - origin.z()) { z_index = 2 * z_index; - } - else + } + else { - z_index = 2 * z_index + 1; + z_index = 2 * z_index + 1; } - } + } z_index = Min( z_index, layout_next.z() - 1 ); - for (IndexVector::index_type x = rat.x() * index.x(); + for (IndexVector::index_type x = rat.x() * index.x(); x < Min( layout_next.x(), rat.x() * ( index.x() + 1 ) ); x++ ) { - for (IndexVector::index_type y = rat.y() * index.y(); + for (IndexVector::index_type y = rat.y() * index.y(); y < Min( layout_next.y(), rat.y() * ( index.y() + 1 ) ); y++ ) { children.push_back( BrickInfo( layout_next.x() * layout_next.y() * z_index + @@ -1114,14 +1114,14 @@ bool LargeVolumeSchema::get_children( const BrickInfo& bi, SliceType slice, doub } } return true; - } + } } return false; } -std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world_viewport, +std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world_viewport, int width, int height, SliceType slice, const BBox& effective_bbox, double depth, const std::string& load_key ) { @@ -1138,7 +1138,7 @@ std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world } bool found_right_level = false; - + size_t overlap = this->get_overlap(); BBox viewable_box( Point(-1.0, -1.0, -1.0), Point( 1.0, 1.0, 1.0 )); @@ -1185,13 +1185,13 @@ std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world Point proj_q3 = world_viewport.project( q3 ); Point proj_q4 = world_viewport.project( q4 ); - if ( Abs( proj_p1.x() - proj_q1.x() ) * width > 2.0 || + if ( Abs( proj_p1.x() - proj_q1.x() ) * width > 2.0 || Abs( proj_p1.y() - proj_q1.y() ) * height > 2.0 || - Abs( proj_p2.x() - proj_q2.x() ) * width > 2.0 || + Abs( proj_p2.x() - proj_q2.x() ) * width > 2.0 || Abs( proj_p2.y() - proj_q2.y() ) * height > 2.0 || - Abs( proj_p3.x() - proj_q3.x() ) * width > 2.0 || - Abs( proj_p3.y() - proj_q3.y() ) * height > 2.0 || - Abs( proj_p4.x() - proj_q4.x() ) * width > 2.0 || + Abs( proj_p3.x() - proj_q3.x() ) * width > 2.0 || + Abs( proj_p3.y() - proj_q3.y() ) * height > 2.0 || + Abs( proj_p4.x() - proj_q4.x() ) * width > 2.0 || Abs( proj_p4.y() - proj_q4.y() ) * height > 2.0 ) { std::vector children; @@ -1202,7 +1202,7 @@ std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world } else { - result.push_back( bi ); + result.push_back( bi ); } } else @@ -1242,13 +1242,13 @@ std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world Point proj_q3 = world_viewport.project( q3 ); Point proj_q4 = world_viewport.project( q4 ); - if ( Abs( proj_p1.x() - proj_q1.x() ) * width > 2.0 || + if ( Abs( proj_p1.x() - proj_q1.x() ) * width > 2.0 || Abs( proj_p1.y() - proj_q1.y() ) * height > 2.0 || - Abs( proj_p2.x() - proj_q2.x() ) * width > 2.0 || + Abs( proj_p2.x() - proj_q2.x() ) * width > 2.0 || Abs( proj_p2.y() - proj_q2.y() ) * height > 2.0 || - Abs( proj_p3.x() - proj_q3.x() ) * width > 2.0 || - Abs( proj_p3.y() - proj_q3.y() ) * height > 2.0 || - Abs( proj_p4.x() - proj_q4.x() ) * width > 2.0 || + Abs( proj_p3.x() - proj_q3.x() ) * width > 2.0 || + Abs( proj_p3.y() - proj_q3.y() ) * height > 2.0 || + Abs( proj_p4.x() - proj_q4.x() ) * width > 2.0 || Abs( proj_p4.y() - proj_q4.y() ) * height > 2.0 ) { std::vector children; @@ -1259,7 +1259,7 @@ std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world } else { - result.push_back( bi ); + result.push_back( bi ); } } else @@ -1299,13 +1299,13 @@ std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world Point proj_q3 = world_viewport.project( q3 ); Point proj_q4 = world_viewport.project( q4 ); - if ( Abs( proj_p1.x() - proj_q1.x() ) * width > 2.0 || + if ( Abs( proj_p1.x() - proj_q1.x() ) * width > 2.0 || Abs( proj_p1.y() - proj_q1.y() ) * height > 2.0 || - Abs( proj_p2.x() - proj_q2.x() ) * width > 2.0 || + Abs( proj_p2.x() - proj_q2.x() ) * width > 2.0 || Abs( proj_p2.y() - proj_q2.y() ) * height > 2.0 || - Abs( proj_p3.x() - proj_q3.x() ) * width > 2.0 || - Abs( proj_p3.y() - proj_q3.y() ) * height > 2.0 || - Abs( proj_p4.x() - proj_q4.x() ) * width > 2.0 || + Abs( proj_p3.x() - proj_q3.x() ) * width > 2.0 || + Abs( proj_p3.y() - proj_q3.y() ) * height > 2.0 || + Abs( proj_p4.x() - proj_q4.x() ) * width > 2.0 || Abs( proj_p4.y() - proj_q4.y() ) * height > 2.0 ) { std::vector children; @@ -1316,7 +1316,7 @@ std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world } else { - result.push_back( bi ); + result.push_back( bi ); } } else @@ -1334,7 +1334,7 @@ std::vector LargeVolumeSchema::get_bricks_for_volume( Transform world return current_render; } -void LargeVolumeSchemaPrivate::load_and_substitue_missing_bricks( std::vector& want_to_render, +void LargeVolumeSchemaPrivate::load_and_substitue_missing_bricks( std::vector& want_to_render, SliceType slice, double depth, const std::string& load_key, std::vector& current_render ) { LargeVolumeCache* cache = LargeVolumeCache::Instance(); @@ -1440,7 +1440,7 @@ std::vector LargeVolumeSchema::get_bricks_for_region( const BBox& reg level++; } break; - } + } case SliceType::AXIAL_E: { depth = region.min().z(); @@ -1451,7 +1451,7 @@ std::vector LargeVolumeSchema::get_bricks_for_region( const BBox& reg level++; } break; - } + } } @@ -1485,7 +1485,7 @@ std::vector LargeVolumeSchema::get_bricks_for_region( const BBox& reg { want_to_render.push_back(BrickInfo( x + nx * y + nxy * z, level )); } - } + } } std::vector current_render; @@ -1557,18 +1557,18 @@ bool LargeVolumeSchema::get_level_start_and_end( const GridTransform& region, in Point origin = this->get_origin() - ( 0.5 * data_spacing ) + ( 0.5 * spacing ); - start = IndexVector( + start = IndexVector( Max( 0, Floor( ( rbox.min().x() - tbox.min().x() ) / spacing.x() ) ), Max( 0, Floor( ( rbox.min().y() - tbox.min().y() ) / spacing.y() ) ), Max( 0, Floor( ( rbox.min().z() - tbox.min().z() ) / spacing.z() ) ) ); - end = IndexVector( + end = IndexVector( Min( static_cast( trans.get_nx() ), Floor( ( rbox.max().x() - tbox.min().x() ) / spacing.x() ) ), Min( static_cast( trans.get_ny() ), Floor( ( rbox.max().y() - tbox.min().y() ) / spacing.y() ) ), Min( static_cast( trans.get_nz() ), Floor( ( rbox.max().z() - tbox.min().z() ) / spacing.z() ) ) ); gt = GridTransform( end.x() - start.x(), end.y() - start.y(), end.z() - start.z(), - origin + Vector( start.xd() * spacing.x(), start.yd() * spacing.y(), start.zd() * spacing.z()), + origin + Vector( start.xd() * spacing.x(), start.yd() * spacing.y(), start.zd() * spacing.z()), spacing.x() * Vector( 1.0, 0.0, 0.0 ), spacing.y() * Vector( 0.0, 1.0, 0.0 ), spacing.z() * Vector( 0.0, 0.0, 1.0 ) ); return true; @@ -1590,6 +1590,10 @@ bool LargeVolumeSchema::insert_brick( DataBlockHandle volume, DataBlockHandle br return this->private_->insert_brick_internals( volume, brick, offset, clip_start, clip_end ); case DataType::INT_E: return this->private_->insert_brick_internals( volume, brick, offset, clip_start, clip_end ); + case DataType::ULONGLONG_E: + return this->private_->insert_brick_internals( volume, brick, offset, clip_start, clip_end ); + case DataType::LONGLONG_E: + return this->private_->insert_brick_internals( volume, brick, offset, clip_start, clip_end ); case DataType::FLOAT_E: return this->private_->insert_brick_internals( volume, brick, offset, clip_start, clip_end ); case DataType::DOUBLE_E: @@ -1615,6 +1619,10 @@ bool LargeVolumeSchema::insert_brick( DataBlockHandle volume, DataBlockHandle br return this->private_->insert_brick_internals( volume, brick, offset ); case DataType::INT_E: return this->private_->insert_brick_internals( volume, brick, offset ); + case DataType::ULONGLONG_E: + return this->private_->insert_brick_internals( volume, brick, offset ); + case DataType::LONGLONG_E: + return this->private_->insert_brick_internals( volume, brick, offset ); case DataType::FLOAT_E: return this->private_->insert_brick_internals( volume, brick, offset ); case DataType::DOUBLE_E: diff --git a/src/Core/Python/PythonInterpreter.cc b/src/Core/Python/PythonInterpreter.cc index 14b2e9e65..7883f858e 100644 --- a/src/Core/Python/PythonInterpreter.cc +++ b/src/Core/Python/PythonInterpreter.cc @@ -613,7 +613,7 @@ void PythonInterpreter::run_file( const std::string& file_name ) } FILE* fp = _Py_fopen(file_name.c_str(), "r+"); - if ( fp != NULL ) + if ( fp != nullptr ) { PyRun_SimpleFileEx( fp, file_name.c_str(), 1 ); } diff --git a/src/Core/RenderResources/RenderResources.cc b/src/Core/RenderResources/RenderResources.cc index a4c0c577b..83fce5e1a 100644 --- a/src/Core/RenderResources/RenderResources.cc +++ b/src/Core/RenderResources/RenderResources.cc @@ -149,7 +149,7 @@ void RenderResourcesPrivate::query_video_memory_size() DWORD type = REG_DWORD; DWORD max_object_number = 0; DWORD buffer_size = sizeof( DWORD ); - if ( RegQueryValueEx( video_devicemap_key, MAX_OBJECT_NUMBER_C, NULL, &type, + if ( RegQueryValueEx( video_devicemap_key, MAX_OBJECT_NUMBER_C, nullptr, &type, reinterpret_cast< LPBYTE >( &max_object_number ), &buffer_size ) == ERROR_SUCCESS ) { @@ -157,15 +157,15 @@ void RenderResourcesPrivate::query_video_memory_size() { DWORD type = REG_SZ; std::string video_device_name = "\\Device\\Video" + ExportToString( i ); - if ( RegQueryValueEx( video_devicemap_key, video_device_name.c_str(), NULL, - &type, NULL, &buffer_size ) != ERROR_SUCCESS ) + if ( RegQueryValueEx( video_devicemap_key, video_device_name.c_str(), nullptr, + &type, nullptr, &buffer_size ) != ERROR_SUCCESS ) { continue; } std::vector< BYTE > buffer( buffer_size ); - if ( RegQueryValueEx( video_devicemap_key, video_device_name.c_str(), NULL, - NULL, &buffer[ 0 ], &buffer_size ) != ERROR_SUCCESS ) + if ( RegQueryValueEx( video_devicemap_key, video_device_name.c_str(), nullptr, + nullptr, &buffer[ 0 ], &buffer_size ) != ERROR_SUCCESS ) { continue; } @@ -187,7 +187,7 @@ void RenderResourcesPrivate::query_video_memory_size() buffer_size = sizeof( DWORD ); type = REG_BINARY; - if ( RegQueryValueEx( video_device_key, HARDWAREINFO_MEMSIZE, NULL, &type, + if ( RegQueryValueEx( video_device_key, HARDWAREINFO_MEMSIZE, nullptr, &type, reinterpret_cast< LPBYTE >( &vram_size ), &buffer_size ) == ERROR_SUCCESS ) { this->vram_size_ = vram_size; diff --git a/src/Core/Volume/DataVolume.cc b/src/Core/Volume/DataVolume.cc index 327dc7d9b..990f25f44 100644 --- a/src/Core/Volume/DataVolume.cc +++ b/src/Core/Volume/DataVolume.cc @@ -50,11 +50,11 @@ class DataVolumePrivate : public Lockable bool generate_bricks(); template< class DST_TYPE > - void copy_data( DST_TYPE* buffer, size_t width, size_t height, size_t depth, size_t x_start, + void copy_data( DST_TYPE* buffer, size_t width, size_t height, size_t depth, size_t x_start, size_t x_end, size_t y_start, size_t y_end, size_t z_start, size_t z_end ); template< class DST_TYPE, class SRC_TYPE > - void copy_typed_data( DST_TYPE* buffer, size_t width, size_t height, size_t depth, + void copy_typed_data( DST_TYPE* buffer, size_t width, size_t height, size_t depth, size_t x_start, size_t x_end, size_t y_start, size_t y_end, size_t z_start, size_t z_end ); // Handle to where the volume data is really stored @@ -73,8 +73,8 @@ const unsigned int DataVolumePrivate::BRICK_SIZE_C = 256; const unsigned int DataVolumePrivate::OVERLAP_SIZE_C = 2; template< class DST_TYPE, class SRC_TYPE > -void DataVolumePrivate::copy_typed_data( DST_TYPE* buffer, size_t width, size_t height, - size_t depth, size_t x_start, size_t x_end, size_t y_start, size_t y_end, +void DataVolumePrivate::copy_typed_data( DST_TYPE* buffer, size_t width, size_t height, + size_t depth, size_t x_start, size_t x_end, size_t y_start, size_t y_end, size_t z_start, size_t z_end ) { const double numeric_min = static_cast( std::numeric_limits< DST_TYPE >::min() ); @@ -120,10 +120,10 @@ void DataVolumePrivate::copy_typed_data( DST_TYPE* buffer, size_t width, size_t // Pad the texture in Z-direction with boundary values for ( size_t z = z_end - z_start + 2; z <= depth; ++z ) { - memcpy( buffer + dst_index, buffer + dst_index - texture_stride_z, + memcpy( buffer + dst_index, buffer + dst_index - texture_stride_z, sizeof( DST_TYPE ) * texture_stride_z ); dst_index += texture_stride_z; - } + } } template< class DST_TYPE > @@ -156,12 +156,20 @@ void DataVolumePrivate::copy_data( DST_TYPE* buffer, size_t width, size_t height this->copy_typed_data< DST_TYPE, unsigned int >( buffer, width, height, depth, x_start, x_end, y_start, y_end, z_start, z_end ); break; + case DataType::LONGLONG_E: + this->copy_typed_data< DST_TYPE, long long >( buffer, width, height, depth, + x_start, x_end, y_start, y_end, z_start, z_end ); + break; + case DataType::ULONGLONG_E: + this->copy_typed_data< DST_TYPE, unsigned long long >( buffer, width, height, depth, + x_start, x_end, y_start, y_end, z_start, z_end ); + break; case DataType::FLOAT_E: this->copy_typed_data< DST_TYPE, float >( buffer, width, height, depth, x_start, x_end, y_start, y_end, z_start, z_end ); break; case DataType::DOUBLE_E: - this->copy_typed_data< DST_TYPE, double >( buffer, width, height, depth, + this->copy_typed_data< DST_TYPE, double >( buffer, width, height, depth, x_start, x_end, y_start, y_end, z_start, z_end ); break; } @@ -246,7 +254,7 @@ bool DataVolumePrivate::generate_bricks() static_cast< double >( data_y_start ) - 0.5, static_cast< double >( data_z_start ) - 0.5 ); tex_bbox_min = grid_trans * tex_bbox_min; Core::Point tex_bbox_max( static_cast< double >( data_x_start + texture_width - 1.0 ) + 0.5, - static_cast< double >( data_y_start + texture_height - 1.0 ) + 0.5, + static_cast< double >( data_y_start + texture_height - 1.0 ) + 0.5, static_cast< double >( data_z_start + texture_depth - 1.0 ) + 0.5 ); tex_bbox_max = grid_trans * tex_bbox_max; @@ -256,9 +264,9 @@ bool DataVolumePrivate::generate_bricks() BBox texture_bbox( tex_bbox_min, tex_bbox_max ); // Texel size in texture space Vector texel_size( 1.0 / texture_width, 1.0 / texture_height, 1.0 / texture_depth ); - - pixel_buffer->set_buffer_data( sizeof( DataVolumeBrick::data_type ) * - texture_width * texture_height * texture_depth, NULL, GL_STREAM_DRAW ); + + pixel_buffer->set_buffer_data( sizeof( DataVolumeBrick::data_type ) * + texture_width * texture_height * texture_depth, nullptr, GL_STREAM_DRAW ); DataVolumeBrick::data_type* buffer = reinterpret_cast< DataVolumeBrick::data_type* >( pixel_buffer->map_buffer( GL_WRITE_ONLY ) ); if ( buffer == 0 ) @@ -267,7 +275,7 @@ bool DataVolumePrivate::generate_bricks() pixel_buffer->unbind(); return false; } - this->copy_data( buffer, texture_width, texture_height, texture_depth, data_x_start, + this->copy_data( buffer, texture_width, texture_height, texture_depth, data_x_start, data_x_end, data_y_start, data_y_end, data_z_start, data_z_end ); pixel_buffer->unmap_buffer(); Texture3DHandle tex( new Texture3D ); @@ -277,12 +285,12 @@ bool DataVolumePrivate::generate_bricks() tex->set_wrap_s( GL_CLAMP_TO_EDGE ); tex->set_wrap_t( GL_CLAMP_TO_EDGE ); tex->set_wrap_r( GL_CLAMP_TO_EDGE ); - tex->set_image( static_cast< int >( texture_width ), static_cast< int >( texture_height ), + tex->set_image( static_cast< int >( texture_width ), static_cast< int >( texture_height ), static_cast< int >( texture_depth ), DataVolumeBrick::TEXTURE_FORMAT_C, 0, GL_ALPHA, DataVolumeBrick::TEXTURE_DATA_TYPE_C ); tex->unbind(); - DataVolumeBrickHandle brick( new DataVolumeBrick( brick_bbox, + DataVolumeBrickHandle brick( new DataVolumeBrick( brick_bbox, texture_bbox, texel_size, tex ) ); this->bricks_.push_back( brick ); } @@ -302,9 +310,9 @@ bool DataVolumePrivate::generate_bricks() // Class DataVolumePrivate ////////////////////////////////////////////////////////////////////////// -DataVolume::DataVolume( const GridTransform& grid_transform, +DataVolume::DataVolume( const GridTransform& grid_transform, const DataBlockHandle& data_block ) : - Volume( grid_transform ), + Volume( grid_transform ), private_( new DataVolumePrivate ) { this->private_->data_block_ = data_block; @@ -389,7 +397,7 @@ NrrdDataHandle DataVolume::convert_to_nrrd() } DataBlock::generation_type DataVolume::get_generation() const -{ +{ if ( this->private_->data_block_ ) { return this->private_->data_block_->get_generation(); @@ -431,21 +439,21 @@ void DataVolume::unregister_data() { if ( this->private_->data_block_ && this->private_->data_block_->get_generation() != -1 ) { - Core::DataBlockManager::Instance()->unregister_datablock( + Core::DataBlockManager::Instance()->unregister_datablock( this->private_->data_block_->get_generation() ); } } -bool DataVolume::LoadDataVolume( const boost::filesystem::path& filename, +bool DataVolume::LoadDataVolume( const boost::filesystem::path& filename, DataVolumeHandle& volume, std::string& error ) { volume.reset(); - + NrrdDataHandle nrrd; if ( ! ( NrrdData::LoadNrrd( filename.string(), nrrd, error ) ) ) return false; - + Core::DataBlockHandle datablock( Core::NrrdDataBlock::New( nrrd ) ); - + // Load the datablock and trust any histogram recorded inside of it. datablock->set_histogram( nrrd->get_histogram( true ) ); @@ -453,31 +461,31 @@ bool DataVolume::LoadDataVolume( const boost::filesystem::path& filename, return true; } -bool DataVolume::SaveDataVolume( const boost::filesystem::path& filepath, - DataVolumeHandle& volume, std::string& error, +bool DataVolume::SaveDataVolume( const boost::filesystem::path& filepath, + DataVolumeHandle& volume, std::string& error, bool compress, int level ) { - NrrdDataHandle nrrd = NrrdDataHandle( new NrrdData( + NrrdDataHandle nrrd = NrrdDataHandle( new NrrdData( volume->private_->data_block_, volume->get_grid_transform() ) ); nrrd->set_histogram( volume->private_->data_block_->get_histogram() ); - + DataBlock::shared_lock_type slock( volume->private_->data_block_->get_mutex() ); - if ( ! ( NrrdData::SaveNrrd( filepath.string(), nrrd, error, compress, level ) ) ) + if ( ! ( NrrdData::SaveNrrd( filepath.string(), nrrd, error, compress, level ) ) ) { CORE_LOG_ERROR( error ); return false; } - + return true; } -bool DataVolume::CreateEmptyData( GridTransform grid_transform, +bool DataVolume::CreateEmptyData( GridTransform grid_transform, DataType data_type, DataVolumeHandle& data ) { DataBlockHandle data_block = StdDataBlock::New( grid_transform, data_type ) ; data_block->clear(); - + data = DataVolumeHandle( new DataVolume( grid_transform, data_block ) ); return true; } @@ -490,7 +498,7 @@ bool DataVolume::CreateInvalidData( GridTransform grid_transform, DataVolumeHand return true; } -bool DataVolume::ConvertToCanonicalVolume( const DataVolumeHandle& src_volume, +bool DataVolume::ConvertToCanonicalVolume( const DataVolumeHandle& src_volume, DataVolumeHandle& dst_volume ) { const GridTransform& src_transform = src_volume->get_grid_transform(); @@ -510,25 +518,25 @@ bool DataVolume::ConvertToCanonicalVolume( const DataVolumeHandle& src_volume, } dst_volume.reset( new DataVolume( dst_transform, dst_data_block ) ); - + return true; } -bool DataVolume::DuplicateVolume( const DataVolumeHandle& src_data_volume, +bool DataVolume::DuplicateVolume( const DataVolumeHandle& src_data_volume, DataVolumeHandle& dst_data_volume ) { if ( !src_data_volume ) return false; - + DataBlockHandle dst_data_block; - + if ( !( DataBlock::Duplicate( src_data_volume->get_data_block(), dst_data_block ) ) ) { return false; } - - dst_data_volume = DataVolumeHandle( new DataVolume( + + dst_data_volume = DataVolumeHandle( new DataVolume( src_data_volume->get_grid_transform(), dst_data_block ) ); - + if ( !dst_data_volume ) return false; return true; } @@ -564,7 +572,7 @@ void DataVolume::get_bricks( std::vector< DataVolumeBrickHandle >& bricks ) { return; } - + { DataVolumePrivate::lock_type lock( this->private_->get_mutex() ); if ( !this->private_->bricks_generated_ ) diff --git a/src/Core/Volume/DataVolumeSlice.cc b/src/Core/Volume/DataVolumeSlice.cc index 93abc9bcc..dfb8220df 100644 --- a/src/Core/Volume/DataVolumeSlice.cc +++ b/src/Core/Volume/DataVolumeSlice.cc @@ -39,14 +39,14 @@ const unsigned int DataVolumeSlice::TEXTURE_DATA_TYPE_C = GL_UNSIGNED_SHORT; const unsigned int DataVolumeSlice::TEXTURE_FORMAT_C = GL_LUMINANCE16; -DataVolumeSlice::DataVolumeSlice( const DataVolumeHandle& data_volume, +DataVolumeSlice::DataVolumeSlice( const DataVolumeHandle& data_volume, VolumeSliceType type, size_t slice_num ) : VolumeSlice( data_volume, type, slice_num ) { this->data_block_ = data_volume->get_data_block().get(); if ( this->data_block_ ) { - this->add_connection( this->data_block_->data_changed_signal_.connect( + this->add_connection( this->data_block_->data_changed_signal_.connect( boost::bind( &VolumeSlice::handle_volume_updated, this ) ) ); } } @@ -82,7 +82,7 @@ void CopyTypedData( DataVolumeSlice* slice, TYPE1* buffer, DataBlock* data_block const size_t nx = slice->nx(); const size_t ny = slice->ny(); - + TYPE2* data = static_cast( data_block->get_data() ); size_t row_start = current_index; for ( size_t j = 0; j < ny; j++ ) @@ -91,9 +91,9 @@ void CopyTypedData( DataVolumeSlice* slice, TYPE1* buffer, DataBlock* data_block for ( size_t i = 0; i < nx; i++ ) { // NOTE: removed unnecessary addition for unsigned texture types - // buffer[ j * nx + i ] = static_cast( ( data[ current_index ] - typed_value_min ) + // buffer[ j * nx + i ] = static_cast( ( data[ current_index ] - typed_value_min ) // * inv_value_range + numeric_min ); - buffer[ j * nx + i ] = static_cast( + buffer[ j * nx + i ] = static_cast( ( data[ current_index ] - typed_value_min ) * inv_value_range ); current_index += x_stride; @@ -125,22 +125,22 @@ void DataVolumeSlice::upload_texture() // Make sure there is no pixel unpack buffer bound PixelUnpackBuffer::RestoreDefault(); - tex->set_image( static_cast< int >( nx ), + tex->set_image( static_cast< int >( nx ), static_cast< int >( ny ), TEXTURE_FORMAT_C ); this->set_size_changed( false ); } - + // Step 1. copy the data in the slice to a pixel unpack buffer PixelBufferObjectHandle pixel_buffer( new PixelUnpackBuffer ); pixel_buffer->bind(); pixel_buffer->set_buffer_data( sizeof( texture_data_type ) * nx * ny, - NULL, GL_STREAM_DRAW ); + nullptr, GL_STREAM_DRAW ); texture_data_type* buffer = reinterpret_cast< texture_data_type* >( pixel_buffer->map_buffer( GL_WRITE_ONLY ) ); // Lock the volume DataBlock::shared_lock_type volume_lock( this->data_block_->get_mutex() ); - + switch ( this->data_block_->get_data_type() ) { case DataType::CHAR_E: @@ -161,6 +161,12 @@ void DataVolumeSlice::upload_texture() case DataType::UINT_E: CopyTypedData< texture_data_type, unsigned int >( this, buffer, this->data_block_ ); break; + case DataType::LONGLONG_E: + CopyTypedData< texture_data_type, long long >( this, buffer, this->data_block_ ); + break; + case DataType::ULONGLONG_E: + CopyTypedData< texture_data_type, unsigned long long >( this, buffer, this->data_block_ ); + break; case DataType::FLOAT_E: CopyTypedData< texture_data_type, float >( this, buffer, this->data_block_ ); break; @@ -170,12 +176,12 @@ void DataVolumeSlice::upload_texture() } volume_lock.unlock(); - + // Step 2. copy from the pixel buffer to texture pixel_buffer->unmap_buffer(); glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - tex->set_sub_image( 0, 0, static_cast( nx ), - static_cast( ny ), NULL, GL_LUMINANCE, TEXTURE_DATA_TYPE_C ); + tex->set_sub_image( 0, 0, static_cast( nx ), + static_cast( ny ), nullptr, GL_LUMINANCE, TEXTURE_DATA_TYPE_C ); tex->unbind(); // Step 3. release the pixel unpack buffer @@ -206,7 +212,7 @@ void DataVolumeSlice::set_volume( const VolumeHandle& volume ) this->data_block_ = data_volume->get_data_block().get(); if ( this->data_block_ ) { - this->add_connection( this->data_block_->data_changed_signal_.connect( + this->add_connection( this->data_block_->data_changed_signal_.connect( boost::bind( &VolumeSlice::handle_volume_updated, this ) ) ); } } @@ -244,7 +250,7 @@ void ThresholdTypedData( const DataVolumeSlice* slice, DataBlock* data_block, current_index = row_start; for ( size_t i = 0; i < nx; i++ ) { - in_range = ( data[ current_index ] >= min_val && + in_range = ( data[ current_index ] >= min_val && data[ current_index ] <= max_val ); buffer[ j * nx + i ] = negative_constraint ? !in_range : in_range; current_index += x_stride; @@ -253,7 +259,7 @@ void ThresholdTypedData( const DataVolumeSlice* slice, DataBlock* data_block, } } -void DataVolumeSlice::create_threshold_mask( std::vector< unsigned char >& mask, +void DataVolumeSlice::create_threshold_mask( std::vector< unsigned char >& mask, double min_val, double max_val, bool negative_constraint ) const { lock_type lock( this->get_mutex() ); @@ -263,35 +269,43 @@ void DataVolumeSlice::create_threshold_mask( std::vector< unsigned char >& mask, switch ( this->data_block_->get_data_type() ) { case DataType::CHAR_E: - ThresholdTypedData< signed char >( this, this->data_block_, &mask[ 0 ], + ThresholdTypedData< signed char >( this, this->data_block_, &mask[ 0 ], min_val, max_val, negative_constraint ); break; case DataType::UCHAR_E: - ThresholdTypedData< unsigned char >( this, this->data_block_, &mask[ 0 ], + ThresholdTypedData< unsigned char >( this, this->data_block_, &mask[ 0 ], min_val, max_val, negative_constraint ); break; case DataType::SHORT_E: - ThresholdTypedData< short >( this, this->data_block_, &mask[ 0 ], + ThresholdTypedData< short >( this, this->data_block_, &mask[ 0 ], min_val, max_val, negative_constraint ); break; case DataType::USHORT_E: - ThresholdTypedData< unsigned short >( this, this->data_block_, &mask[ 0 ], + ThresholdTypedData< unsigned short >( this, this->data_block_, &mask[ 0 ], min_val, max_val, negative_constraint ); break; case DataType::INT_E: - ThresholdTypedData< int >( this, this->data_block_, &mask[ 0 ], + ThresholdTypedData< int >( this, this->data_block_, &mask[ 0 ], min_val, max_val, negative_constraint ); break; case DataType::UINT_E: - ThresholdTypedData< unsigned int >( this, this->data_block_, &mask[ 0 ], + ThresholdTypedData< unsigned int >( this, this->data_block_, &mask[ 0 ], + min_val, max_val, negative_constraint ); + break; + case DataType::LONGLONG_E: + ThresholdTypedData< long long >( this, this->data_block_, &mask[ 0 ], + min_val, max_val, negative_constraint ); + break; + case DataType::ULONGLONG_E: + ThresholdTypedData< unsigned long long >( this, this->data_block_, &mask[ 0 ], min_val, max_val, negative_constraint ); break; case DataType::FLOAT_E: - ThresholdTypedData< float >( this, this->data_block_, &mask[ 0 ], + ThresholdTypedData< float >( this, this->data_block_, &mask[ 0 ], min_val, max_val, negative_constraint ); break; case DataType::DOUBLE_E: - ThresholdTypedData< double >( this, this->data_block_, &mask[ 0 ], + ThresholdTypedData< double >( this, this->data_block_, &mask[ 0 ], min_val, max_val, negative_constraint ); break; } diff --git a/src/Core/Volume/LargeVolumeBrickSlice.cc b/src/Core/Volume/LargeVolumeBrickSlice.cc index fa24cdf5a..8cb7bf8ff 100644 --- a/src/Core/Volume/LargeVolumeBrickSlice.cc +++ b/src/Core/Volume/LargeVolumeBrickSlice.cc @@ -67,13 +67,13 @@ class LargeVolumeBrickSlicePrivate Vector spacing = schema->get_level_spacing( bi.level_ ); BBox total = BBox( total_trans.get_origin() - total_trans.project( Vector( 0.5, 0.5, 0.5 ) ) , total_trans.project( Point ( - static_cast(total_trans.get_nx()), - static_cast(total_trans.get_ny()), + static_cast(total_trans.get_nx()), + static_cast(total_trans.get_ny()), static_cast(total_trans.get_nz()) ) ) - total_trans.project( Vector( 0.5, 0.5, 0.5 ) ) ); this->outer_ = BBox( brick_trans.get_origin() - brick_trans.project( Vector( 0.5, 0.5, 0.5 ) ) , brick_trans.project( Point ( - static_cast(brick_trans.get_nx()), - static_cast(brick_trans.get_ny()), + static_cast(brick_trans.get_nx()), + static_cast(brick_trans.get_ny()), static_cast(brick_trans.get_nz()) ) ) - brick_trans.project( Vector( 0.5, 0.5, 0.5 ) ) ); Point inner_min = outer_.min() + spacing * overlap; @@ -99,7 +99,7 @@ class LargeVolumeBrickSlicePrivate PixelBufferObjectHandle pixel_buffer(new PixelUnpackBuffer); pixel_buffer->bind(); pixel_buffer->set_buffer_data(sizeof(unsigned short) * width * height, - NULL, GL_STREAM_DRAW); + nullptr, GL_STREAM_DRAW); unsigned short* buffer = reinterpret_cast< unsigned short* >( pixel_buffer->map_buffer( GL_WRITE_ONLY ) ); int row_start = slice_data_start; @@ -109,7 +109,7 @@ class LargeVolumeBrickSlicePrivate current_index = row_start; for (int i = 0; i < width; i++) { - buffer[ j * width + i ] = static_cast( + buffer[ j * width + i ] = static_cast( ( data[ current_index ] - typed_value_min ) * inv_value_range ); current_index += h_stride; @@ -121,7 +121,7 @@ class LargeVolumeBrickSlicePrivate pixel_buffer->unmap_buffer(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); this->texture_->set_sub_image(0, 0, width, - height, NULL, GL_LUMINANCE, GL_UNSIGNED_SHORT); + height, nullptr, GL_LUMINANCE, GL_UNSIGNED_SHORT); this->texture_->unbind(); // Step 3. release the pixel unpack buffer @@ -195,11 +195,11 @@ class LargeVolumeBrickSlicePrivate switch (data_block->get_data_type()) { case DataType::UCHAR_E: - copy_slice_data(reinterpret_cast(data), slice_data_start, + copy_slice_data(reinterpret_cast(data), slice_data_start, width, height, h_stride, v_stride, min_val, max_val ); break; case DataType::CHAR_E: - copy_slice_data(reinterpret_cast(data), slice_data_start, + copy_slice_data(reinterpret_cast(data), slice_data_start, width, height, h_stride, v_stride, min_val, max_val ); break; case DataType::USHORT_E: @@ -217,7 +217,15 @@ class LargeVolumeBrickSlicePrivate case DataType::INT_E: copy_slice_data(reinterpret_cast(data), slice_data_start, width, height, h_stride, v_stride, min_val, max_val ); - break; + break; + case DataType::ULONGLONG_E: + copy_slice_data(reinterpret_cast(data), slice_data_start, + width, height, h_stride, v_stride, min_val, max_val ); + break; + case DataType::LONGLONG_E: + copy_slice_data(reinterpret_cast(data), slice_data_start, + width, height, h_stride, v_stride, min_val, max_val ); + break; case DataType::FLOAT_E: copy_slice_data(reinterpret_cast(data), slice_data_start, width, height, h_stride, v_stride, min_val, max_val ); @@ -225,7 +233,7 @@ class LargeVolumeBrickSlicePrivate case DataType::DOUBLE_E: copy_slice_data(reinterpret_cast(data), slice_data_start, width, height, h_stride, v_stride, min_val, max_val ); - break; + break; default: break; } @@ -236,7 +244,7 @@ class LargeVolumeBrickSlicePrivate } }; -LargeVolumeBrickSlice::LargeVolumeBrickSlice( LargeVolumeHandle volume, +LargeVolumeBrickSlice::LargeVolumeBrickSlice( LargeVolumeHandle volume, LargeVolumeSchemaHandle schema, const BrickInfo& bi ) : private_(new LargeVolumeBrickSlicePrivate(volume, schema, bi)) { diff --git a/src/Core/Volume/MaskVolumeSlice.cc b/src/Core/Volume/MaskVolumeSlice.cc index 604b5bf05..427dd5d93 100644 --- a/src/Core/Volume/MaskVolumeSlice.cc +++ b/src/Core/Volume/MaskVolumeSlice.cc @@ -144,7 +144,7 @@ void MaskVolumeSlice::upload_texture() PixelBufferObjectHandle pixel_buffer( new PixelUnpackBuffer ); pixel_buffer->bind(); pixel_buffer->set_buffer_data( sizeof(unsigned char) * nx * ny, - NULL, GL_STREAM_DRAW ); + nullptr, GL_STREAM_DRAW ); unsigned char* buffer = reinterpret_cast( pixel_buffer->map_buffer( GL_WRITE_ONLY ) ); @@ -158,7 +158,7 @@ void MaskVolumeSlice::upload_texture() pixel_buffer->unmap_buffer(); glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); tex->set_sub_image( 0, 0, static_cast( nx ), - static_cast( ny ), NULL, GL_ALPHA, GL_UNSIGNED_BYTE ); + static_cast( ny ), nullptr, GL_ALPHA, GL_UNSIGNED_BYTE ); tex->unbind(); // Step 3. release the pixel unpack buffer diff --git a/src/Core/VolumeRenderer/TransferFunction.cc b/src/Core/VolumeRenderer/TransferFunction.cc index ac084743d..49c21e10d 100644 --- a/src/Core/VolumeRenderer/TransferFunction.cc +++ b/src/Core/VolumeRenderer/TransferFunction.cc @@ -78,7 +78,7 @@ void TransferFunctionPrivate::build_lookup_texture() PixelBufferObjectHandle pbo( new PixelUnpackBuffer ); pbo->bind(); pbo->set_buffer_data( LUT_SIZE_C * 4 * sizeof( unsigned char ) * 2, - NULL, GL_STREAM_DRAW ); + nullptr, GL_STREAM_DRAW ); unsigned char* buffer = reinterpret_cast< unsigned char* >( pbo->map_buffer( GL_WRITE_ONLY ) ); diff --git a/src/HeadlessMain/main.cc b/src/HeadlessMain/main.cc index fd1e5c308..70306defe 100644 --- a/src/HeadlessMain/main.cc +++ b/src/HeadlessMain/main.cc @@ -1,22 +1,22 @@ /* For more information, please see: http://software.sci.utah.edu - + The MIT License - + Copyright (c) 2016 Scientific Computing and Imaging Institute, University of Utah. - - + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -86,7 +86,7 @@ int main( int argc, char **argv ) { // -- Parse the command line parameters -- Core::Application::Instance()->parse_command_line_parameters( argc, argv ); - + // -- Check whether the user requested a version / revision number if ( Core::Application::Instance()->is_command_line_parameter( "revision") ) { @@ -99,12 +99,12 @@ int main( int argc, char **argv ) if ( Core::Application::Instance()->is_command_line_parameter( "version") ) { // NOTE: This information is gathered by cmake from the main cmake file. - std::cout << Core::Application::Instance()->GetApplicationName() << " version: " << + std::cout << Core::Application::Instance()->GetApplicationName() << " version: " << Core::Application::Instance()->GetVersion() << std::endl; return 0; } - // -- Send message to revolving log file -- + // -- Send message to revolving log file -- // Logs messages in response to Log::Instance()->post_log_signal_ Core::RolloverLogFile event_log( Core::LogMessageType::ALL_E ); @@ -116,7 +116,7 @@ int main( int argc, char **argv ) // -- Log application information -- Core::Application::Instance()->log_start(); - // -- Add plugins into the architecture + // -- Add plugins into the architecture Core::RegisterClasses(); // -- Start the application event handler -- @@ -124,10 +124,10 @@ int main( int argc, char **argv ) // Initialize the startup tools list ToolFactory::Instance()->initialize_states(); - + // Trigger the application start signal Core::Application::Instance()->application_start_signal_(); - + // -- Warn user about being an alpha/beta version -- std::string file_to_view = ""; Core::Application::Instance()->check_command_line_parameter( "file_to_open_on_start", file_to_view ); @@ -135,7 +135,7 @@ int main( int argc, char **argv ) if ( sizeof( void * ) == 4 ) { std::string warning = std::string( "

" ) + - Core::Application::GetApplicationName() + " " + Core::Application::GetVersion() + " 32BIT" + Core::Application::GetApplicationName() + " " + Core::Application::GetVersion() + " 32BIT" "

Please note: " + Core::Application::GetApplicationName() + " is meant to run in 64-bit mode. " "In 32-bit mode the size of volumes that can be processed are limited, as " @@ -152,7 +152,7 @@ int main( int argc, char **argv ) Core::PythonInterpreter::module_list_type python_modules; std::string module_name = Core::StringToLower( BOOST_PP_STRINGIZE( APPLICATION_NAME ) ); - python_modules.push_back( Core::PythonInterpreter::module_entry_type( module_name, + python_modules.push_back( Core::PythonInterpreter::module_entry_type( module_name, BOOST_PP_CAT( PyInit_, APPLICATION_NAME ) ) ); Core::PythonInterpreter::Instance()->initialize( &program_name[ 0 ], python_modules ); Core::PythonInterpreter::Instance()->run_string( "import " + module_name + "\n" ); @@ -168,7 +168,7 @@ int main( int argc, char **argv ) { // -- Add a socket for receiving actions -- CORE_LOG_MESSAGE( std::string("Starting a socket on port: ") + Core::ExportToString( port_number ) ); - Seg3D::ActionSocket::Instance()->start( port_number ); + ActionSocket::Instance()->start( port_number ); InterfaceManager::Instance()->set_initializing( true ); InterfaceManager::Instance()->splash_screen_visibility_state_->set( false ); InterfaceManager::Instance()->set_initializing( false ); @@ -186,7 +186,7 @@ int main( int argc, char **argv ) // -- Setup Application Interface Window -- // std::string file_to_view = ""; // Core::Application::Instance()->check_command_line_parameter( "file_to_open_on_start", file_to_view ); - + signal(SIGABRT, &sighandler); signal(SIGTERM, &sighandler); diff --git a/src/Main/Seg3DBase.cc b/src/Main/Seg3DBase.cc index 819703eee..438b243a4 100644 --- a/src/Main/Seg3DBase.cc +++ b/src/Main/Seg3DBase.cc @@ -100,21 +100,21 @@ void RedirectIOToConsole() hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); fp = _fdopen(hConHandle, "w"); *stdout = *fp; - setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); // redirect unbuffered STDIN to the console lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE); hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); fp = _fdopen(hConHandle, "r"); *stdin = *fp; - setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdin, nullptr, _IONBF, 0); // redirect unbuffered STDERR to the console lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); fp = _fdopen(hConHandle, "w"); *stderr = *fp; - setvbuf(stderr, NULL, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); } #endif @@ -279,7 +279,7 @@ void Seg3DBase::initialize_sockets() #ifdef BUILD_WITH_PYTHON // -- Add a socket for receiving actions -- CORE_LOG_MESSAGE( std::string("Starting a socket on port: ") + Core::ExportToString( this->port_number ) ); - Seg3D::ActionSocket::Instance()->start( this->port_number ); + ActionSocket::Instance()->start( this->port_number ); InterfaceManager::Instance()->set_initializing( true ); InterfaceManager::Instance()->splash_screen_visibility_state_->set( false ); InterfaceManager::Instance()->set_initializing( false ); diff --git a/src/Main/Seg3DLib/Lib/Seg3D_lib.cc b/src/Main/Seg3DLib/Lib/Seg3D_lib.cc index f70c4ce9a..fb6a9452a 100644 --- a/src/Main/Seg3DLib/Lib/Seg3D_lib.cc +++ b/src/Main/Seg3DLib/Lib/Seg3D_lib.cc @@ -39,7 +39,7 @@ void Seg3DLibrary::exportSegFile(const QString& export_path) const std::string path = export_path.toStdString(); const std::string extension = ".nrrd"; std::vector< LayerHandle > layers; - Seg3D::LayerManager::Instance()->get_layers(layers); + LayerManager::Instance()->get_layers(layers); for(int i = 0; i < layers.size(); i++) { @@ -93,4 +93,4 @@ std::unique_ptr Seg3DLibrary::Context::makeContext(QAppli QWidget* Seg3DLibrary::makeSeg3DWidget() { return new ApplicationInterface(); -} \ No newline at end of file +} diff --git a/src/Main/main.cc b/src/Main/main.cc index 1fc534387..ba08e149c 100644 --- a/src/Main/main.cc +++ b/src/Main/main.cc @@ -54,7 +54,7 @@ int main( int argc, char **argv ) putenv("LANG=C"); Core::Application::Instance()->parse_command_line_parameters( argc, argv ); - Seg3DBase* app = NULL; + Seg3DBase* app = nullptr; bool headless = Core::Application::Instance()->is_command_line_parameter( "headless" ); if ( headless ) app = new Seg3DHeadless(); diff --git a/src/ThirdParty/tinyxml/tinyxml.h b/src/ThirdParty/tinyxml/tinyxml.h index 01822911c..2e2eaaaee 100755 --- a/src/ThirdParty/tinyxml/tinyxml.h +++ b/src/ThirdParty/tinyxml/tinyxml.h @@ -276,7 +276,7 @@ class TiXmlBase TIXML_ERROR_PARSING_COMMENT, TIXML_ERROR_PARSING_DECLARATION, TIXML_ERROR_DOCUMENT_EMPTY, - TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_EMBEDDED_nullptr, TIXML_ERROR_PARSING_CDATA, TIXML_ERROR_DOCUMENT_TOP_ONLY, @@ -576,7 +576,7 @@ class TiXmlNode : public TiXmlBase #endif /** Add a new node related to this. Adds a child past the LastChild. - Returns a pointer to the new object or NULL if an error occured. + Returns a pointer to the new object or nullptr if an error occured. */ TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); @@ -593,17 +593,17 @@ class TiXmlNode : public TiXmlBase TiXmlNode* LinkEndChild( TiXmlNode* addThis ); /** Add a new node related to this. Adds a child before the specified child. - Returns a pointer to the new object or NULL if an error occured. + Returns a pointer to the new object or nullptr if an error occured. */ TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); /** Add a new node related to this. Adds a child after the specified child. - Returns a pointer to the new object or NULL if an error occured. + Returns a pointer to the new object or nullptr if an error occured. */ TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); /** Replace a child of this node. - Returns a pointer to the new object or NULL if an error occured. + Returns a pointer to the new object or nullptr if an error occured. */ TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); diff --git a/src/ThirdParty/tinyxml/tinyxmlparser.cpp b/src/ThirdParty/tinyxml/tinyxmlparser.cpp index 666a4f757..922c3eb06 100755 --- a/src/ThirdParty/tinyxml/tinyxmlparser.cpp +++ b/src/ThirdParty/tinyxml/tinyxmlparser.cpp @@ -661,7 +661,7 @@ void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) int c = in->get(); if ( c <= 0 ) { - SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + SetError( TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN ); break; } (*tag) += (char) c; @@ -911,7 +911,7 @@ void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag) { TiXmlDocument* document = GetDocument(); if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + document->SetError( TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } (*tag) += (char) c ; @@ -973,7 +973,7 @@ void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag) { TiXmlDocument* document = GetDocument(); if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + document->SetError( TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } @@ -1013,7 +1013,7 @@ void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag) { TiXmlDocument* document = GetDocument(); if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + document->SetError( TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } assert( c == '>' ); @@ -1257,7 +1257,7 @@ void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag ) { TiXmlDocument* document = GetDocument(); if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + document->SetError( TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } (*tag) += (char) c; @@ -1315,7 +1315,7 @@ void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag ) { TiXmlDocument* document = GetDocument(); if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + document->SetError( TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } @@ -1474,7 +1474,7 @@ void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) { TiXmlDocument* document = GetDocument(); if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + document->SetError( TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } @@ -1552,7 +1552,7 @@ void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) { TiXmlDocument* document = GetDocument(); if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + document->SetError( TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } (*tag) += (char) c;