From 0559ec4abd3e1ef46cc0c4e02a9353cf4d9eec7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Thu, 24 Sep 2020 16:39:31 -0400 Subject: [PATCH 01/15] Finish migration to ITKv4 and prepare for migration to ITKv5 --- Superbuild/ITKExternal.cmake | 6 ++++-- src/Application/Filters/Actions/ActionWatershedFilter.cc | 2 +- src/Application/Filters/ITKFilter.h | 4 ++++ src/Application/LayerIO/ITKLayerImporter.cc | 4 ++-- src/Core/LargeVolume/LargeVolumeConverter.cc | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Superbuild/ITKExternal.cmake b/Superbuild/ITKExternal.cmake index 2a8a2296c..01d772cbc 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" + "-DITKV3_COMPATIBILITY:BOOL=OFF" + "-DITK_LEGACY_REMOVE:BOOL=ON" + "-DITK_FUTURE_LEGACY_REMOVE:BOOL=ON" "-DModule_ITKRegistrationCommon:BOOL=ON" "-DModule_ITKSmoothing:BOOL=ON" "-DModule_ITKAnisotropicSmoothing:BOOL=ON" @@ -68,7 +70,7 @@ 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}" diff --git a/src/Application/Filters/Actions/ActionWatershedFilter.cc b/src/Application/Filters/Actions/ActionWatershedFilter.cc index 368d8b80a..e7bcd1693 100644 --- a/src/Application/Filters/Actions/ActionWatershedFilter.cc +++ b/src/Application/Filters/Actions/ActionWatershedFilter.cc @@ -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 long, 3 > WtrImageTypeFilter; //WtrImageTypeFilter itk::Image< unsigned long long, 3 > bool ActionWatershedFilter::validate( Core::ActionContextHandle& context ) { diff --git a/src/Application/Filters/ITKFilter.h b/src/Application/Filters/ITKFilter.h index aa5f689ee..54b471646 100644 --- a/src/Application/Filters/ITKFilter.h +++ b/src/Application/Filters/ITKFilter.h @@ -537,6 +537,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;\ };\ @@ -564,6 +566,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;\ };\ diff --git a/src/Application/LayerIO/ITKLayerImporter.cc b/src/Application/LayerIO/ITKLayerImporter.cc index 4ead9ae00..5e1cb0f3d 100644 --- a/src/Application/LayerIO/ITKLayerImporter.cc +++ b/src/Application/LayerIO/ITKLayerImporter.cc @@ -298,7 +298,7 @@ bool ITKLayerImporterPrivate::read_header() else if ( detect_analyze( extension ) ) { this->file_type_ = "Analyze"; - return this->scan_simple_volume< itk::AnalyzeImageIO >(); + return this->scan_simple_volume< itk::NiftiImageIO >(); } else if ( detect_nifti( extension ) ) { @@ -440,7 +440,7 @@ bool ITKLayerImporterPrivate::read_data() } else if ( detect_analyze( extension ) ) { - return this->import_simple_volume(); + return this->import_simple_volume(); } else if ( detect_nifti( extension ) ) { diff --git a/src/Core/LargeVolume/LargeVolumeConverter.cc b/src/Core/LargeVolume/LargeVolumeConverter.cc index a3fd6d3c8..71cf8b906 100644 --- a/src/Core/LargeVolume/LargeVolumeConverter.cc +++ b/src/Core/LargeVolume/LargeVolumeConverter.cc @@ -650,7 +650,7 @@ 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() ); From 3b6512c15c97736f7dff06469e4461ecbc4f4621 Mon Sep 17 00:00:00 2001 From: Ally Warner Date: Thu, 6 Aug 2020 20:30:18 -0400 Subject: [PATCH 02/15] Update ITK version to 5.1.0 --- Superbuild/ITKExternal.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Superbuild/ITKExternal.cmake b/Superbuild/ITKExternal.cmake index 01d772cbc..833606830 100644 --- a/Superbuild/ITKExternal.cmake +++ b/Superbuild/ITKExternal.cmake @@ -50,9 +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=OFF" - "-DITK_LEGACY_REMOVE:BOOL=ON" - "-DITK_FUTURE_LEGACY_REMOVE: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" @@ -88,7 +88,7 @@ IF(BUILD_MOSAIC_TOOLS) ) ENDIF() -SET(itk_GIT_TAG "origin/itk-4.13.1") +SET(itk_GIT_TAG "origin/itk5.1.0") # If CMake ever allows overriding the checkout command or adding flags, # git checkout -q will silence message about detached head (harmless). @@ -103,6 +103,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.1" CACHE PATH "") MESSAGE(STATUS "ITK_DIR=${ITK_DIR}") From 3cf1c2e4e0abd5b5f3b3b8eec61fb477b5e84b21 Mon Sep 17 00:00:00 2001 From: Ally Warner Date: Mon, 24 Aug 2020 17:16:42 -0600 Subject: [PATCH 03/15] 7 errors left --- src/Application/LayerIO/ITKLayerImporter.cc | 55 ++----------------- .../LayerIO/ITKSeriesLayerImporter.cc | 28 ++++------ .../LayerIO/ITKSeriesLayerImporter.h | 3 + src/Core/DataBlock/ITKImageData.h | 6 +- 4 files changed, 20 insertions(+), 72 deletions(-) diff --git a/src/Application/LayerIO/ITKLayerImporter.cc b/src/Application/LayerIO/ITKLayerImporter.cc index 5e1cb0f3d..4650150b6 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 @@ -86,10 +86,6 @@ class ITKLayerImporterPrivate // 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 @@ -164,48 +160,6 @@ 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() { @@ -237,9 +191,6 @@ bool ITKLayerImporterPrivate::scan_simple_volume() this->importer_->set_error( "ITK crashed while reading file." ); 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; @@ -255,7 +206,7 @@ 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. @@ -298,6 +249,8 @@ bool ITKLayerImporterPrivate::read_header() else if ( detect_analyze( extension ) ) { this->file_type_ = "Analyze"; + //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 ) ) diff --git a/src/Application/LayerIO/ITKSeriesLayerImporter.cc b/src/Application/LayerIO/ITKSeriesLayerImporter.cc index 876956b55..73fdf8055 100644 --- a/src/Application/LayerIO/ITKSeriesLayerImporter.cc +++ b/src/Application/LayerIO/ITKSeriesLayerImporter.cc @@ -77,10 +77,6 @@ class ITKSeriesLayerImporterPrivate // 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 @@ -117,39 +113,38 @@ class ITKSeriesLayerImporterPrivate bool read_data_; }; - -Core::DataType ITKSeriesLayerImporterPrivate::convert_data_type( std::string& type ) +Core::DataType Seg3D::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::FLOAT) { return Core::DataType::FLOAT_E; } - else if ( type == "double" ) + else if ( type == itk::CommonEnums::IOComponent::DOUBLE) { return Core::DataType::DOUBLE_E; } @@ -235,9 +230,6 @@ bool ITKSeriesLayerImporterPrivate::scan_simple_series() this->importer_->set_error( "ITK reader failed." ); 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; @@ -253,7 +245,7 @@ bool ITKSeriesLayerImporterPrivate::scan_simple_series() } // 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; diff --git a/src/Application/LayerIO/ITKSeriesLayerImporter.h b/src/Application/LayerIO/ITKSeriesLayerImporter.h index 311f72980..68aa04528 100644 --- a/src/Application/LayerIO/ITKSeriesLayerImporter.h +++ b/src/Application/LayerIO/ITKSeriesLayerImporter.h @@ -45,6 +45,9 @@ 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; 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(); } From c799f01fcfeb24fe51272cf4f0980eff88b0f63d Mon Sep 17 00:00:00 2001 From: Lee Newberg Date: Thu, 1 Oct 2020 08:59:20 -0400 Subject: [PATCH 04/15] ENH: Migration to ITK 5.1.0 Missing typename directives in declarations. Confusion between long and long long Use of itkMutexLock instead of std::mutex. Failure to include . Use of ComposeRGBImageFilter instead of ComposeImageFilter. Use of NULL instead of nullptr. Use of vcl_sqrt instead of std::sqrt, etc. itk::MultiThreader --> itk::MultiThreaderBase. Removal of inappropriate Seg3D:: explicit qualification. --- src/Application/Clipboard/ClipboardItem.cc | 6 +- .../DatabaseManager/DatabaseManager.cc | 88 +- .../DatabaseManager/DatabaseManager.h | 4 +- src/Application/Filters/Actions/ActionCrop.cc | 74 +- .../Filters/Actions/ActionInvert.cc | 64 +- .../ActionNeighborhoodConnectedFilter.cc | 86 +- .../Actions/ActionPointSetRegisterFilter.cc | 2 +- .../Actions/ActionPointSetTransformFilter.cc | 2 +- .../Filters/Actions/ActionTransform.cc | 56 +- .../Filters/Actions/ActionWatershedFilter.cc | 118 +- src/Application/Filters/ITKFilter.h | 194 +- src/Application/Filters/LayerFilter.h | 80 +- .../Filters/SingleThresholdFilter.cc | 6 + src/Application/Filters/ThresholdFilter.cc | 8 + .../Actions/ActionAddTransformsFilter.cc | 2 +- .../Actions/ActionAssembleFilter.cc | 10 +- .../Actions/ActionFFTFilter.cc | 4 +- .../Actions/ActionSliceToSliceBruteFilter.cc | 12 +- .../Actions/ActionSliceToSliceFilter.cc | 6 +- src/Application/Layer/DataLayer.cc | 77 +- src/Application/Layer/LargeVolumeLayer.cc | 45 +- src/Application/LayerIO/GDCMLayerImporter.cc | 6 + src/Application/LayerIO/ITKLayerImporter.cc | 130 +- .../LayerIO/ITKSeriesLayerImporter.cc | 78 +- .../LayerIO/ITKSeriesLayerImporter.h | 11 +- src/Application/LayerIO/MRCLayerImporter.cc | 10 +- .../LayerIO/Matlab73LayerImporter.cc | 16 +- .../LayerIO/MatlabLayerExporter.cc | 128 +- .../LayerIO/MatlabLayerImporter.cc | 216 +- src/Application/LayerIO/VFFLayerImporter.cc | 10 +- src/Application/Tools/SpeedlineTool.cc | 2 +- src/Core/Application/Application.cc | 2 +- src/Core/DataBlock/DataBlock.cc | 482 ++-- src/Core/DataBlock/DataType.cc | 5 +- src/Core/DataBlock/Histogram.cc | 275 ++- src/Core/DataBlock/Histogram.h | 36 +- src/Core/DataBlock/MaskDataBlockManager.cc | 222 +- src/Core/DataBlock/NrrdData.cc | 6 + src/Core/DataBlock/StdDataBlock.cc | 26 +- src/Core/Graphics/FramebufferObject.cc | 2 +- src/Core/Graphics/FramebufferObject.h | 2 +- src/Core/Graphics/GLSLShader.cc | 4 +- src/Core/ITKCommon/FFT/fft.cxx | 34 +- src/Core/ITKCommon/FFT/fft.hxx | 4 +- src/Core/ITKCommon/FFT/fft_common.hxx | 6 +- .../itkNormalizeImageFilterWithMask.txx | 2 +- src/Core/ITKCommon/IRImageLoader.cxx | 149 +- .../Optimizers/itkImageMosaicVarianceMetric.h | 2 +- .../itkImageMosaicVarianceMetric.txx | 2 +- ...tkRegularStepGradientDescentOptimizer2.cxx | 4 +- src/Core/ITKCommon/STOS/stos.hxx | 2 +- src/Core/ITKCommon/STOS/stos_common.hxx | 4 +- .../ThreadUtils/the_boost_thread.cxx | 8 +- .../ThreadUtils/the_boost_thread_storage.hxx | 2 +- .../ThreadUtils/the_mutex_interface.cxx | 4 +- .../ThreadUtils/the_thread_interface.cxx | 32 +- .../ThreadUtils/the_thread_interface.hxx | 2 +- .../ITKCommon/ThreadUtils/the_thread_pool.cxx | 20 +- .../ITKCommon/ThreadUtils/the_thread_pool.hxx | 4 +- .../ITKCommon/ThreadUtils/the_transaction.cxx | 22 +- .../ITKCommon/ThreadUtils/the_transaction.hxx | 4 +- .../Transform/IRRefineTranslateCanvas.cxx | 138 +- .../Transform/IRRefineTranslateCanvas.hxx | 2 +- .../ITKCommon/Transform/itkGridTransform.h | 2 +- .../ITKCommon/Transform/itkInverseTransform.h | 4 +- .../itkLegendrePolynomialTransform.h | 2 +- .../itkLegendrePolynomialTransform.txx | 2 +- .../ITKCommon/Transform/itkMeshTransform.h | 2 +- .../ITKCommon/Transform/itkRBFTransform.h | 2 +- .../Transform/itkRadialDistortionTransform.h | 2 +- src/Core/ITKCommon/common.cxx | 16 +- src/Core/ITKCommon/common.hxx | 1976 ++++++++--------- src/Core/ITKCommon/extrema.hxx | 6 +- src/Core/ITKCommon/grid_common.cxx | 8 +- src/Core/ITKCommon/grid_common.hxx | 20 +- src/Core/ITKCommon/match.hxx | 8 +- src/Core/ITKCommon/mosaic_layout_common.cxx | 8 +- src/Core/ITKCommon/mosaic_layout_common.hxx | 38 +- .../ITKCommon/mosaic_refinement_common.hxx | 4 +- src/Core/ITKCommon/pyramid.cxx | 6 +- src/Core/ITKCommon/the_dynamic_array.hxx | 12 +- src/Core/ITKCommon/the_text.cxx | 8 +- src/Core/ITKCommon/the_text.hxx | 2 +- src/Core/ITKCommon/the_utils.cxx | 18 +- src/Core/ITKCommon/the_utils.hxx | 10 +- src/Core/ITKCommon/tree.hxx | 76 +- src/Core/ITKCommon/visualize.cxx | 4 +- src/Core/ITKCommon/visualize.hxx | 4 +- .../ITKLiveWire/itkLiveWireImageFunction.hxx | 160 +- src/Core/LargeVolume/LargeVolumeConverter.cc | 162 +- src/Core/LargeVolume/LargeVolumeSchema.cc | 204 +- src/Core/Python/PythonInterpreter.cc | 2 +- src/Core/RenderResources/RenderResources.cc | 12 +- src/Core/Volume/DataVolume.cc | 86 +- src/Core/Volume/DataVolumeSlice.cc | 60 +- src/Core/Volume/LargeVolumeBrickSlice.cc | 32 +- src/Core/Volume/MaskVolumeSlice.cc | 4 +- src/Core/VolumeRenderer/TransferFunction.cc | 2 +- src/HeadlessMain/main.cc | 32 +- src/Interface/Application/LayerGroupWidget.cc | 4 +- src/Main/Seg3DBase.cc | 8 +- src/Main/Seg3DLib/Lib/Seg3D_lib.cc | 4 +- src/Main/main.cc | 2 +- 103 files changed, 3305 insertions(+), 2769 deletions(-) mode change 100755 => 100644 src/Core/ITKLiveWire/itkLiveWireImageFunction.hxx 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/DatabaseManager/DatabaseManager.cc b/src/Application/DatabaseManager/DatabaseManager.cc index 144b7a2ab..4438bfcdb 100644 --- a/src/Application/DatabaseManager/DatabaseManager.cc +++ b/src/Application/DatabaseManager/DatabaseManager.cc @@ -78,9 +78,9 @@ DatabaseManager::DatabaseManager( const DatabaseManager& src ) : // Copy the database content from the source sqlite3_backup* db_backup_obj = sqlite3_backup_init( this->private_->database_, "main", src.private_->database_, "main" ); - if ( db_backup_obj == NULL ) + if ( db_backup_obj == nullptr ) { - CORE_THROW_EXCEPTION( std::string( "Failed to copy database: " ) + + CORE_THROW_EXCEPTION( std::string( "Failed to copy database: " ) + sqlite3_errmsg( this->private_->database_ ) ); } @@ -94,7 +94,7 @@ DatabaseManager::DatabaseManager( const DatabaseManager& src ) : } DatabaseManager::~DatabaseManager() -{ +{ // We need to close the database to avoid memory leak. if ( this->private_->database_ ) { @@ -104,7 +104,7 @@ DatabaseManager::~DatabaseManager() static int InternalExecuteSqlStatement( sqlite3_stmt* statement, ResultSet& results ) { - assert( statement != NULL ); + assert( statement != nullptr ); int result; while ( ( result = sqlite3_step( statement ) ) == SQLITE_ROW ) @@ -118,7 +118,7 @@ static int InternalExecuteSqlStatement( sqlite3_stmt* statement, ResultSet& resu case SQLITE_TEXT: case SQLITE_BLOB: { - std::string string_result = std::string( reinterpret_cast< const char* >( + std::string string_result = std::string( reinterpret_cast< const char* >( sqlite3_column_text( statement, j ) ) ); temp_any = boost::any( string_result ); break; @@ -156,22 +156,22 @@ bool DatabaseManager::run_sql_statement( const std::string& sql_str, std::string return this->run_sql_statement( sql_str, dummy_results, error ); } -bool DatabaseManager::run_sql_statement( const std::string& sql_str, ResultSet& results, +bool DatabaseManager::run_sql_statement( const std::string& sql_str, ResultSet& results, std::string& error ) { results.clear(); DatabaseManagerPrivate::lock_type lock( this->private_->get_mutex() ); - if ( this->private_->database_ == NULL ) + if ( this->private_->database_ == nullptr ) { error = "Invalid database connection."; return false; } - sqlite3_stmt* statement = NULL; - if ( sqlite3_prepare_v2( this->private_->database_, sql_str.c_str(), - static_cast< int >( sql_str.size() ), &statement, NULL ) != SQLITE_OK ) + sqlite3_stmt* statement = nullptr; + if ( sqlite3_prepare_v2( this->private_->database_, sql_str.c_str(), + static_cast< int >( sql_str.size() ), &statement, nullptr ) != SQLITE_OK ) { error = "The SQL statement '" + sql_str + "' failed to compile with error: " + sqlite3_errmsg( this->private_->database_ ); @@ -183,7 +183,7 @@ bool DatabaseManager::run_sql_statement( const std::string& sql_str, ResultSet& error = "The SQL statement '" + sql_str + "' returned error: " + sqlite3_errmsg( this->private_->database_ ); return false; - } + } return true; } @@ -192,7 +192,7 @@ bool DatabaseManager::run_sql_script( const std::string& sql_str, std::string& e { DatabaseManagerPrivate::lock_type lock( this->private_->get_mutex() ); - if ( this->private_->database_ == NULL ) + if ( this->private_->database_ == nullptr ) { error = "Invalid database connection."; return false; @@ -200,13 +200,13 @@ bool DatabaseManager::run_sql_script( const std::string& sql_str, std::string& e ResultSet dummy_results; const char* head = sql_str.c_str(); - const char* tail = NULL; + const char* tail = nullptr; // The input string length including the null terminator - int num_bytes = static_cast< int >( sql_str.size() + 1 ); + int num_bytes = static_cast< int >( sql_str.size() + 1 ); while ( num_bytes > 1 ) { - sqlite3_stmt* statement = NULL; - if ( sqlite3_prepare_v2( this->private_->database_, head, + sqlite3_stmt* statement = nullptr; + if ( sqlite3_prepare_v2( this->private_->database_, head, num_bytes, &statement, &tail ) != SQLITE_OK ) { error = "The SQL statement '" + std::string( head ) + "' failed to compile with error: " @@ -214,14 +214,14 @@ bool DatabaseManager::run_sql_script( const std::string& sql_str, std::string& e return false; } - if ( statement == NULL ) break; + if ( statement == nullptr ) break; if( InternalExecuteSqlStatement( statement, dummy_results ) != SQLITE_DONE ) { error = "The SQL statement '" + std::string( head ) + "' returned error: " + sqlite3_errmsg( this->private_->database_ ); return false; - } + } num_bytes -= static_cast< int >( tail - head ); head = tail; @@ -230,7 +230,7 @@ bool DatabaseManager::run_sql_script( const std::string& sql_str, std::string& e return true; } -bool DatabaseManager::load_database( const boost::filesystem::path& database_file, +bool DatabaseManager::load_database( const boost::filesystem::path& database_file, std::string& error ) { DatabaseManagerPrivate::lock_type lock( this->private_->get_mutex() ); @@ -238,79 +238,79 @@ bool DatabaseManager::load_database( const boost::filesystem::path& database_fil int result; sqlite3* temp_open_database; sqlite3_backup* backup_database_object; - + result = sqlite3_open( database_file.string().c_str(), &temp_open_database ); - - if ( result != SQLITE_OK ) + + if ( result != SQLITE_OK ) { sqlite3_close( temp_open_database ); error = std::string( "Could not open database file '" ) + database_file.string() + "'."; return false; } - - backup_database_object = + + backup_database_object = sqlite3_backup_init( this->private_->database_, "main", temp_open_database, "main" ); - + if ( backup_database_object ) { sqlite3_backup_step( backup_database_object, -1 ); sqlite3_backup_finish( backup_database_object ); } - + sqlite3_close( temp_open_database ); result = sqlite3_errcode( this->private_->database_ ); - if ( result != SQLITE_OK ) + if ( result != SQLITE_OK ) { error = "Internal error in database."; return false; } - + // Enable foreign key this->run_sql_statement( "PRAGMA foreign_keys = ON;", error ); error = ""; - return true; + return true; } -bool DatabaseManager::save_database( const boost::filesystem::path& database_file, +bool DatabaseManager::save_database( const boost::filesystem::path& database_file, std::string& error ) { DatabaseManagerPrivate::lock_type lock( this->private_->get_mutex() ); int result; sqlite3* temp_open_database; sqlite3_backup* backup_database_object; - + result = sqlite3_open( database_file.string().c_str(), &temp_open_database ); - - if ( result != SQLITE_OK ) + + if ( result != SQLITE_OK ) { sqlite3_close( temp_open_database ); error = std::string( "Could not open database file '" ) + database_file.string() + "'."; return false; } - - backup_database_object = + + backup_database_object = sqlite3_backup_init( temp_open_database, "main", this->private_->database_, "main" ); - + if ( backup_database_object ) { sqlite3_backup_step( backup_database_object, -1 ); sqlite3_backup_finish( backup_database_object ); } - + result = sqlite3_errcode( temp_open_database ); - if ( result != SQLITE_OK ) + if ( result != SQLITE_OK ) { error = "Internal error in database."; return false; } - + sqlite3_close( temp_open_database ); error = ""; - return true; + return true; } long long DatabaseManager::get_last_insert_rowid() @@ -323,10 +323,10 @@ long long DatabaseManager::get_last_insert_rowid() return 0; } -bool DatabaseManager::get_column_metadata( const std::string& table_name, - const std::string& column_name, char const** data_type /*= NULL*/, - char const** coll_seq /*= NULL*/, int* not_null /*= NULL*/, - int* primary_key /*= NULL*/, int* auto_inc /*= NULL */ ) +bool DatabaseManager::get_column_metadata( const std::string& table_name, + const std::string& column_name, char const** data_type /*= nullptr*/, + char const** coll_seq /*= nullptr*/, int* not_null /*= nullptr*/, + int* primary_key /*= nullptr*/, int* auto_inc /*= nullptr */ ) { if ( this->private_->database_ == 0 ) { diff --git a/src/Application/DatabaseManager/DatabaseManager.h b/src/Application/DatabaseManager/DatabaseManager.h index 498977079..e6cceac35 100644 --- a/src/Application/DatabaseManager/DatabaseManager.h +++ b/src/Application/DatabaseManager/DatabaseManager.h @@ -97,8 +97,8 @@ class DatabaseManager : public boost::noncopyable /// Get metadata about a specific column of a specific database table. /// Returns true if the table and column exist, otherwise false. bool get_column_metadata( const std::string& table_name, const std::string& column_name, - char const** data_type = NULL, char const** coll_seq = NULL, - int* not_null = NULL, int* primary_key = NULL, int* auto_inc = NULL ); + char const** data_type = nullptr, char const** coll_seq = nullptr, + int* not_null = nullptr, int* primary_key = nullptr, int* auto_inc = nullptr ); private: boost::shared_ptr< DatabaseManagerPrivate > private_; 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 e7bcd1693..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 long, 3 > WtrImageTypeFilter; //WtrImageTypeFilter itk::Image< unsigned long long, 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.h b/src/Application/Filters/ITKFilter.h index 54b471646..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_; }; @@ -549,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() \ } @@ -585,7 +587,7 @@ public:\ #define SCI_END_ITK_RUN() \ } - + } // end namespace Seg3D #endif 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..330dd66b7 100644 --- a/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceBruteFilter.cc +++ b/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceBruteFilter.cc @@ -177,7 +177,7 @@ refine_one_pair(const image_t * i0, // 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); @@ -185,7 +185,7 @@ refine_one_pair(const image_t * i0, } 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); @@ -595,7 +595,7 @@ 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(); @@ -761,13 +761,13 @@ brute_force(const bool & brute_force_rotation, // 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 diff --git a/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceFilter.cc b/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceFilter.cc index cc089ed4c..367b19fe9 100644 --- a/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceFilter.cc +++ b/src/Application/ImageRegistrationTools/Actions/ActionSliceToSliceFilter.cc @@ -196,7 +196,7 @@ refine_one_pair(const image_t * i0, // 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); @@ -204,7 +204,7 @@ refine_one_pair(const image_t * i0, } 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); @@ -525,7 +525,7 @@ 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(); 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 4650150b6..4eadcd3a3 100644 --- a/src/Application/LayerIO/ITKLayerImporter.cc +++ b/src/Application/LayerIO/ITKLayerImporter.cc @@ -74,15 +74,15 @@ 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(); @@ -91,7 +91,7 @@ class ITKLayerImporterPrivate // 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 > @@ -102,7 +102,7 @@ class ITKLayerImporterPrivate template< class ItkImporterType > bool import_simple_volume(); - + public: // File type that we are importing std::string file_type_; @@ -115,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_; @@ -148,7 +148,7 @@ class ITKLayerImporterPrivate { return ( extension == ".img" || extension == ".hdr" ); } - + bool detect_nifti( const std::string& extension ) { return ( extension == ".nii" || extension == ".nii.gz" ); @@ -165,7 +165,7 @@ 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(); @@ -191,13 +191,13 @@ bool ITKLayerImporterPrivate::scan_simple_volume() this->importer_->set_error( "ITK crashed while reading file." ); return false; } - + // 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 ( ... ) { @@ -208,7 +208,7 @@ bool ITKLayerImporterPrivate::scan_simple_volume() // Store the information we just extracted from the file in this private class 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; @@ -241,30 +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"; //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 ) ) + } + 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 > @@ -309,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 ( ... ) { @@ -335,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_ ) { @@ -351,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; } } @@ -369,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; @@ -386,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 ) ) + } + 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; } ////////////////////////////////////////////////////////////////////////////////////// @@ -425,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_ ); @@ -463,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; } @@ -471,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; @@ -488,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 @@ -516,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 ) ) @@ -533,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() ) { @@ -543,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; } @@ -567,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; } @@ -588,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 ) { @@ -604,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 @@ -612,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( ... ) @@ -623,7 +627,7 @@ bool CopyITKFile( const boost::filesystem::path& src, } // Successfully copied data file and generated new header. - return true; + return true; } @@ -639,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 73fdf8055..ee48a240d 100644 --- a/src/Application/LayerIO/ITKSeriesLayerImporter.cc +++ b/src/Application/LayerIO/ITKSeriesLayerImporter.cc @@ -69,11 +69,11 @@ 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(); @@ -82,7 +82,7 @@ class ITKSeriesLayerImporterPrivate // 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 > @@ -91,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 @@ -105,15 +105,15 @@ 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 Seg3D::convert_data_type(itk::CommonEnums::IOComponent type ) +Core::DataType convert_data_type(itk::CommonEnums::IOComponent type ) { // Convert ITK types into our enum if ( type == itk::CommonEnums::IOComponent::UCHAR) @@ -140,6 +140,14 @@ Core::DataType Seg3D::convert_data_type(itk::CommonEnums::IOComponent type ) { return Core::DataType::INT_E; } + 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; @@ -159,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"; @@ -191,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 >(); @@ -230,20 +238,20 @@ bool ITKSeriesLayerImporterPrivate::scan_simple_series() this->importer_->set_error( "ITK reader failed." ); return false; } - + // 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_ = convert_data_type(IO->GetComponentType()); this->grid_transform_ = image_data->get_grid_transform(); @@ -264,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(); @@ -296,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 ); @@ -338,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; } } @@ -351,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 >(); @@ -377,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 >(); } @@ -392,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_ ); @@ -437,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 68aa04528..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,6 +43,9 @@ #include #include +// ITK +#include + namespace Seg3D { // CONVERT_DATA_TYPE: @@ -75,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..0b3935e40 100644 --- a/src/Application/LayerIO/Matlab73LayerImporter.cc +++ b/src/Application/LayerIO/Matlab73LayerImporter.cc @@ -146,6 +146,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 +476,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 +523,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_LONGLONG, 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_ULONGLONG, 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/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/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..97a11e9c8 100644 --- a/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.h +++ b/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.h @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include /** . diff --git a/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.txx b/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.txx index e59488dd7..e59e8e31a 100644 --- a/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.txx +++ b/src/Core/ITKCommon/Optimizers/itkImageMosaicVarianceMetric.txx @@ -375,7 +375,7 @@ GetValueAndDerivative(const params_t & parameters, // reset the accumulators: derivative = derivative_t(n_concat); - derivative.Fill(NumericTraits::Zero); + derivative.Fill(NumericTraits::Zero); measure = NumericTraits::Zero; m_NumberOfPixelsCounted = 0; 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/IRRefineTranslateCanvas.hxx b/src/Core/ITKCommon/Transform/IRRefineTranslateCanvas.hxx index 577ee9bd3..05b6f6d24 100644 --- a/src/Core/ITKCommon/Transform/IRRefineTranslateCanvas.hxx +++ b/src/Core/ITKCommon/Transform/IRRefineTranslateCanvas.hxx @@ -128,7 +128,7 @@ public: private: void addProcessedConnection(IRConnection* connection); - // returns NULL if there are no more entries to process + // returns nullptr if there are no more entries to process IRConnection* getConectionToProcess(); void setTransformAndNeighborsToGroupID(IRTransform* transform, 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..d14584314 100644 --- a/src/Core/ITKCommon/grid_common.hxx +++ b/src/Core/ITKCommon/grid_common.hxx @@ -142,8 +142,8 @@ estimate_displacement(double & best_metric, // current best metric 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) { @@ -287,7 +287,7 @@ match_one_pair(translate_transform_t::Pointer & best_transform, 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, @@ -398,7 +398,7 @@ match_one_pair(translate_transform_t::Pointer & best_transform, 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, @@ -911,7 +911,7 @@ extract(const typename TImage::PointType & origin, 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); @@ -1184,7 +1184,7 @@ refine_one_point_helper(// the large images and their masks: 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); @@ -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, @@ -1477,7 +1477,7 @@ refine_one_pair(typename TTransform::Pointer & t01, // 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); @@ -1485,7 +1485,7 @@ refine_one_pair(typename TTransform::Pointer & t01, } 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); 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..28ad7ac36 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); @@ -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(); } } @@ -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 old mode 100755 new mode 100644 index 880d4385a..d8b86924f --- 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 71cf8b906..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") ) { @@ -654,13 +666,15 @@ bool LargeVolumeConverterPrivate::scan_file( const boost::filesystem::path& file // 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/Interface/Application/LayerGroupWidget.cc b/src/Interface/Application/LayerGroupWidget.cc index b267403ca..e99e5a294 100644 --- a/src/Interface/Application/LayerGroupWidget.cc +++ b/src/Interface/Application/LayerGroupWidget.cc @@ -353,7 +353,7 @@ void LayerGroupWidget::dropEvent( QDropEvent* event ) event->setAccepted( true ); LayerGroupWidget* source_widget = dynamic_cast< LayerGroupWidget* >( event->source() ); - if( source_widget != NULL && source_widget != this ) + if( source_widget != nullptr && source_widget != this ) { source_widget->private_->set_drop_target( this ); event->setDropAction( Qt::MoveAction ); @@ -365,7 +365,7 @@ void LayerGroupWidget::dropEvent( QDropEvent* event ) void LayerGroupWidget::dragEnterEvent( QDragEnterEvent* event) { LayerGroupWidget* source_widget = dynamic_cast< LayerGroupWidget* >( event->source() ); - if( source_widget != NULL && source_widget != this ) + if( source_widget != nullptr && source_widget != this ) { this->private_->enable_drop_space( true ); } 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(); From a0747d87c7a17098a78e83e526846f08ecdfbfa3 Mon Sep 17 00:00:00 2001 From: Ally Warner Date: Wed, 4 Nov 2020 13:08:22 -0500 Subject: [PATCH 05/15] Trimming excess white-space This is a squashed commit with erroneous changes of NULL to nullptr and its revert to fix the introduced SQL errors and Tinyxml updates. --- src/Application/Project/Project.cc | 488 +++++++++--------- .../ProjectManager/ProjectManager.cc | 144 +++--- src/ThirdParty/tinyxml/tinyxml.h | 145 +++--- src/ThirdParty/tinyxml/tinyxmlparser.cpp | 153 +++--- 4 files changed, 464 insertions(+), 466 deletions(-) diff --git a/src/Application/Project/Project.cc b/src/Application/Project/Project.cc index 4727d4cae..0260cfb22 100644 --- a/src/Application/Project/Project.cc +++ b/src/Application/Project/Project.cc @@ -56,7 +56,7 @@ #include // NOTE: This include is needed for APPLE to deal with directories that are bundled as a single file. -#if defined( __APPLE__ ) +#if defined( __APPLE__ ) # include #endif @@ -84,8 +84,8 @@ class ProjectPrivate project_( 0 ), changed_( false ), last_saved_session_time_stamp_( boost::posix_time::second_clock::local_time() ), - need_anonymize_( false ) - { + need_anonymize_( false ) + { } public: @@ -99,21 +99,21 @@ class ProjectPrivate // CLEAN_UP_SESSION_DATABASE: // this function cleans up sessions in the session list that have been deleted by the user - bool clean_up_session_database(); - + bool clean_up_session_database(); + // CLEAN_UP_DATA_FILES: // Clean up files that are not used by any session. - void clean_up_data_files(); - + void clean_up_data_files(); + // SAVE_STATE: // Save the state of the current project into the xml file and save the database // in the database file - bool save_state( const boost::filesystem::path& project_directory ); - + bool save_state( const boost::filesystem::path& project_directory ); + // SET_LAST_SAVED_SESSION_TIME_STAMP // this function updates the time of when the last session was saved void set_last_saved_session_time_stamp(); - + // INITIALIZE_SESSION_DATABASE: // Create tables for the session database. bool initialize_session_database(); @@ -129,16 +129,16 @@ class ProjectPrivate // INITIALIZE_NOTE_DATABASE: // Create tables for the note database. bool initialize_note_database(); - + // INSERT_SESSION_INTO_DATABASE // Inset a session into the database - SessionID insert_session_into_database( const std::string& session_name, + SessionID insert_session_into_database( const std::string& session_name, const std::string& user_id, const std::string& timestamp = "" ); - + // DELETE_SESSION_FROM_DATABASE: // this deletes a session from the database bool delete_session_from_database( SessionID session_id ); - + // SET_SESSION_DATA: // Add the data generation numbers used by the session into the database. bool set_session_data( SessionID id, const std::set< long long >& generations ); @@ -154,13 +154,13 @@ class ProjectPrivate // GET_PROVENANCE_STEPS: // Get all the provenance steps that lead to the given provenance ID. - void get_provenance_steps( const std::vector< ProvenanceID >& prov_ids, + void get_provenance_steps( const std::vector< ProvenanceID >& prov_ids, std::set< ProvenanceStepID >& prov_steps ); - + // EXTRACT_SESSION_INFO: // Extract session information from the database query result. void extract_session_info( ResultSet& result_set, std::vector< SessionInfo >& sessions ); - + // GET_ALL_SESSIONS: // Get a list of all sessions. bool get_all_sessions( std::vector< SessionInfo >& sessions ); @@ -179,7 +179,7 @@ class ProjectPrivate // PARSE_SESSION_PROVENANCE_IDS: // Parse the session XML file and get the provenance IDs referenced by the session. - bool parse_session_provenance_ids( const boost::filesystem::path& file_path, + bool parse_session_provenance_ids( const boost::filesystem::path& file_path, std::vector< long long >& prov_ids ); // SET_SESSION_FILE: @@ -191,15 +191,15 @@ class ProjectPrivate // GET_SESSION_FILE: // Get the path of the session XML file. bool get_session_file( SessionID id, boost::filesystem::path& file_path, std::string& error ); - + // PROCESS_INPUTFILE_IMPROTERS // try to copy all the files into the project - bool process_inputfile_importers(); + bool process_inputfile_importers(); // INSERT_NOTE_INTO_DATABASE: // Add a note into the note database. If the timestamp is empty, the database will use the // current timestamp. - long long insert_note_into_database( const std::string& note, + long long insert_note_into_database( const std::string& note, const std::string& user_id, const std::string& timestamp = "" ); // GET_ALL_NOTES: @@ -246,12 +246,12 @@ class ProjectPrivate // The database that contains the session list DatabaseManager session_database_; - + // NOTE: This variable is preventing a circular dependency // Layer session saving will add this number to this list so it can be included // into the final session database. std::set session_generation_numbers_; - + // The database that contains the provenance information DatabaseManager provenance_database_; @@ -266,7 +266,7 @@ class ProjectPrivate // Cached action_id to action_name map std::map< long long, std::string > action_name_map_; - + // Whether data needs to be anonymized on the next save bool need_anonymize_; @@ -285,13 +285,13 @@ void ProjectPrivate::update_project_size() // Iteratively scan through the full directory long long size = this->compute_directory_size( project_path ); - + // Update the project with the new size this->project_->project_size_state_->set( size ); } -// NOTE: This function needs to return a value in long long, even in 32 bit mode, as +// NOTE: This function needs to return a value in long long, even in 32 bit mode, as // file sizes can exceed 2GB. The total of directory with session can be larger than // the total size long long ProjectPrivate::compute_directory_size( const boost::filesystem::path& directory ) @@ -302,7 +302,7 @@ long long ProjectPrivate::compute_directory_size( const boost::filesystem::path& // Reset the counter long long size = 0; - + // Walk through elements in the directory boost::filesystem::directory_iterator dir_end; for( boost::filesystem::directory_iterator dir_itr( directory ); dir_itr != dir_end; ++dir_itr ) @@ -310,7 +310,7 @@ long long ProjectPrivate::compute_directory_size( const boost::filesystem::path& // Filename of the next component in the directory std::string filename = dir_itr->path().filename().string(); boost::filesystem::path dir_file = directory / filename; - + // We only scan directories and regular files, to avoid circular dependencies from // symbolic links. if ( boost::filesystem::is_regular_file( dir_file ) ) @@ -336,21 +336,21 @@ bool ProjectPrivate::UpdateProjectDirectory( const boost::filesystem::path& proj { // If something went wrong, log the problem and continue // We should not completely fail. The user should have the opportunity to try again/ - std::string error = std::string( "Could not create directory '" ) + + std::string error = std::string( "Could not create directory '" ) + project_directory.filename().string() + "'."; CORE_LOG_ERROR( error ); - + // Return false to force the program to try again. - return false; + return false; } -#if defined( __APPLE__ ) +#if defined( __APPLE__ ) // Specialty code for bundles if ( PreferencesManager::Instance()->generate_osx_project_bundle_state_->get() ) - { + { // Get a list with possible extensions. std::vector project_path_extensions = Project::GetProjectPathExtensions(); - + // Check if it has the special extension, old version do not have the extension and we should // leave them the way they were, in order to prevent it from hiding files the user saved // in that directory. @@ -364,11 +364,11 @@ bool ProjectPrivate::UpdateProjectDirectory( const boost::filesystem::path& proj // This code sets the special flags on the mac FSRef file_ref; Boolean is_directory; - FSPathMakeRef( reinterpret_cast( + FSPathMakeRef( reinterpret_cast( project_directory.string().c_str() ), &file_ref, &is_directory ); FSCatalogInfo info; FSGetCatalogInfo( &file_ref, kFSCatInfoFinderInfo, &info, 0, 0, 0 ); - + FileInfo& finder_info = *reinterpret_cast( &info.finderInfo ); finder_info.finderFlags |= kHasBundle; FSSetCatalogInfo( &file_ref, kFSCatInfoFinderInfo, &info); @@ -386,45 +386,45 @@ bool ProjectPrivate::UpdateProjectDirectory( const boost::filesystem::path& proj // All session XMLs are stored here if ( !Core::CreateOrIgnoreDirectory( project_directory / SESSION_DIR_C ) ) { - std::string error = "Could not create sessions directory in project folder '" + + std::string error = "Could not create sessions directory in project folder '" + project_directory.filename().string() + "'."; CORE_LOG_ERROR( error ); - return false; + return false; } - + // Data directory logic // All the session data files are stored here if ( !Core::CreateOrIgnoreDirectory( project_directory / DATA_DIR_C ) ) - { - std::string error = "Could not create data directory in project folder '" + + { + std::string error = "Could not create data directory in project folder '" + project_directory.filename().string() + "'."; CORE_LOG_ERROR( error ); - return false; + return false; } - + // Database directory logic // All the database files (session, provenance, and notes) are stored here. if ( !Core::CreateOrIgnoreDirectory( project_directory / DATABASE_DIR_C ) ) { - std::string error = "Could not create database directory in project folder '" + + std::string error = "Could not create database directory in project folder '" + project_directory.filename().string() + "'."; CORE_LOG_ERROR( error ); - return false; + return false; } // Inputfiles directory logic // All input files are stored here if ( !Core::CreateOrIgnoreDirectory( project_directory / INPUTFILES_DIR_C ) ) - { - std::string error = "Could not create inputfiles directory in project folder '" + + { + std::string error = "Could not create inputfiles directory in project folder '" + project_directory.filename().string() + "'."; CORE_LOG_ERROR( error ); - return false; + return false; } // Everything worked, we should have a valid project directory return true; -} +} bool ProjectPrivate::clean_up_session_database() @@ -447,7 +447,7 @@ bool ProjectPrivate::clean_up_session_database() for( size_t i = 0; i < result_set.size(); ++i ) { SessionID session_id = boost::any_cast< long long >( ( result_set[ i ] )[ "session_id" ] ); - + // Check the existence of the session file boost::filesystem::path session_file; if ( !this->get_session_file( session_id, session_file, error ) ) @@ -466,7 +466,7 @@ bool ProjectPrivate::save_state( const boost::filesystem::path& project_director { CORE_LOG_ERROR( "Tried to save state, while no project directory is active." ); return false; - } + } // Save the project file using the name specified std::string project_file_name = this->project_->project_file_state_->get(); @@ -482,7 +482,7 @@ bool ProjectPrivate::save_state( const boost::filesystem::path& project_director CORE_LOG_ERROR( error ); return false; } - + if ( ! stateio.export_to_file( project_file ) ) { std::string error = std::string( "Failed to save the state of the project in file '" ) + @@ -490,14 +490,14 @@ bool ProjectPrivate::save_state( const boost::filesystem::path& project_director CORE_LOG_ERROR( error ); return false; } - + this->project_->project_files_generated_state_->set( true ); this->project_->project_files_accessible_state_->set( true ); std::string error; // Save the session database to disk - boost::filesystem::path session_database = project_directory / + boost::filesystem::path session_database = project_directory / DATABASE_DIR_C / SESSION_DATABASE_C; if ( !this->session_database_.save_database( session_database, error ) ) { @@ -522,7 +522,7 @@ bool ProjectPrivate::save_state( const boost::filesystem::path& project_director CORE_LOG_ERROR( error ); return false; } - + return true; } @@ -547,15 +547,15 @@ void ProjectPrivate::clean_up_data_files() generations[ i ] = boost::any_cast< long long >( result_set[ i ][ "data_generation" ] ); } - + boost::filesystem::path project_path( this->project_->project_path_state_->get() ); boost::filesystem::path data_path = project_path / "data"; - + boost::filesystem::directory_iterator dir_end; for ( boost::filesystem::directory_iterator dir_itr( data_path ); dir_itr != dir_end; ++dir_itr ) { boost::filesystem::path file_path = dir_itr->path(); - + // Skip directories if ( !boost::filesystem::is_regular_file( file_path ) ) continue; // Skip non-nrrd files @@ -714,7 +714,7 @@ bool ProjectPrivate::clear_provenance_database() // Delete records from table for user names sql_statements += "DELETE FROM user;"; - + // Delete records from table for action names sql_statements += "DELETE FROM action;"; @@ -723,7 +723,7 @@ bool ProjectPrivate::clear_provenance_database() // Delete records from table for storing inputs of each provenance step sql_statements += "DELETE FROM provenance_input;"; - + // Delete records from table for storing outputs of each provenance step sql_statements += "DELETE FROM provenance_output;"; @@ -732,7 +732,7 @@ bool ProjectPrivate::clear_provenance_database() // Delete records from table for storing outputs of each provenance step sql_statements += "DELETE FROM provenance_inputfiles_cache;"; - + std::string error; if ( !this->provenance_database_.run_sql_script( sql_statements, error ) ) { @@ -774,20 +774,20 @@ bool ProjectPrivate::initialize_note_database() return true; } -SessionID ProjectPrivate::insert_session_into_database( const std::string& session_name, +SessionID ProjectPrivate::insert_session_into_database( const std::string& session_name, const std::string& user_id, const std::string& timestamp ) { std::string sql_statement; if ( timestamp.empty() ) { sql_statement = "INSERT INTO session (session_name, user_id) VALUES ('" + - DatabaseManager::EscapeQuotes( session_name ) + "', '" + + DatabaseManager::EscapeQuotes( session_name ) + "', '" + DatabaseManager::EscapeQuotes( user_id ) + "');"; } else { sql_statement = "INSERT INTO session (session_name, user_id, timestamp) VALUES ('" + - DatabaseManager::EscapeQuotes( session_name ) + "', '" + + DatabaseManager::EscapeQuotes( session_name ) + "', '" + DatabaseManager::EscapeQuotes( user_id ) + "', '" + timestamp + "');"; } @@ -803,7 +803,7 @@ SessionID ProjectPrivate::insert_session_into_database( const std::string& sessi bool ProjectPrivate::delete_session_from_database( SessionID session_id ) { - std::string sql_str = "DELETE FROM session WHERE session_id = " + + std::string sql_str = "DELETE FROM session WHERE session_id = " + Core::ExportToString( session_id ) + ";"; std::string error; @@ -812,11 +812,11 @@ bool ProjectPrivate::delete_session_from_database( SessionID session_id ) CORE_LOG_ERROR( error ); return false; } - + return true; } -bool ProjectPrivate::query_provenance_trail( const std::vector< ProvenanceID >& prov_ids, +bool ProjectPrivate::query_provenance_trail( const std::vector< ProvenanceID >& prov_ids, ProvenanceTrail& provenance_trail ) { if ( prov_ids.size() == 0 ) return false; @@ -830,7 +830,7 @@ bool ProjectPrivate::query_provenance_trail( const std::vector< ProvenanceID >& // String stream for extracting timestamp value std::stringstream ss; - ss.imbue( std::locale( ss.getloc(), new boost::posix_time::time_input_facet( + ss.imbue( std::locale( ss.getloc(), new boost::posix_time::time_input_facet( "%Y-%m-%d %H:%M:%S" ) ) ); ss.exceptions( std::ios_base::failbit ); @@ -885,7 +885,7 @@ bool ProjectPrivate::query_provenance_trail( const std::vector< ProvenanceID >& { return false; } - + ProvenanceStep::timestamp_type timestamp; ss.str( timestamp_str ); try @@ -968,7 +968,7 @@ bool ProjectPrivate::query_provenance_trail( const std::vector< ProvenanceID >& void ProjectPrivate::extract_session_info( ResultSet& result_set, std::vector< SessionInfo >& sessions ) { std::stringstream ss; - ss.imbue( std::locale( ss.getloc(), new boost::posix_time::time_input_facet( + ss.imbue( std::locale( ss.getloc(), new boost::posix_time::time_input_facet( "%Y-%m-%d %H:%M:%S" ) ) ); ss.exceptions( std::ios_base::failbit ); @@ -1010,20 +1010,20 @@ bool ProjectPrivate::get_all_sessions( std::vector< SessionInfo >& sessions ) return true; } -long long ProjectPrivate::insert_note_into_database( const std::string& note, +long long ProjectPrivate::insert_note_into_database( const std::string& note, const std::string& user_id, const std::string& timestamp ) { std::string sql_statement; if ( timestamp.empty() ) { sql_statement = "INSERT INTO note (note, user_id) VALUES ('" + - DatabaseManager::EscapeQuotes( note ) + "', '" + + DatabaseManager::EscapeQuotes( note ) + "', '" + DatabaseManager::EscapeQuotes( user_id ) + "');"; } else { sql_statement = "INSERT INTO note (note, user_id, timestamp) VALUES ('" + - DatabaseManager::EscapeQuotes( note ) + "', '" + + DatabaseManager::EscapeQuotes( note ) + "', '" + DatabaseManager::EscapeQuotes( user_id ) + "', '" + timestamp + "');"; } @@ -1053,9 +1053,9 @@ void ProjectPrivate::convert_version1_project() // I/O stream for timestamp conversion std::stringstream ss; - ss.imbue( std::locale( std::locale::classic(), new boost::posix_time::time_facet( + ss.imbue( std::locale( std::locale::classic(), new boost::posix_time::time_facet( "%Y-%m-%d %H:%M:%S" ) ) ); - ss.imbue( std::locale( ss.getloc(), new boost::posix_time::time_input_facet( + ss.imbue( std::locale( ss.getloc(), new boost::posix_time::time_input_facet( "%d-%b-%Y-%H-%M-%S" ) ) ); ss.exceptions( std::ios_base::failbit ); @@ -1063,7 +1063,7 @@ void ProjectPrivate::convert_version1_project() // NOTE: This assumes that the time zone and DST setting when the session was saved // is the same as the current machine setting, which isn't always true. But this is the // best guess I can do since the old timestamp didn't ecode local time information. - boost::posix_time::time_duration time_diff = boost::posix_time::second_clock::local_time() - + boost::posix_time::time_duration time_diff = boost::posix_time::second_clock::local_time() - boost::posix_time::second_clock::universal_time(); int number_of_sessions = static_cast< int >( sessions.size() ); @@ -1076,13 +1076,13 @@ void ProjectPrivate::convert_version1_project() std::vector< std::string > session_info_strs = Core::SplitString( old_session_name, " - " ); - // Ensure it is a valid name + // Ensure it is a valid name if ( session_info_strs.size() < 3 ) continue; boost::filesystem::path old_path = project_path / SESSION_DIR_C / ( old_session_name + ".xml" ); // If the old one does not exist, just continue - we should not fail - - if( ! boost::filesystem::exists( old_path ) ) continue; + if( ! boost::filesystem::exists( old_path ) ) continue; // Convert the timestamp to universal time ss.str( session_info_strs[ 0 ] ); @@ -1106,7 +1106,7 @@ void ProjectPrivate::convert_version1_project() if ( !generations.empty() ) { - generation_count = Core::Max( generation_count, + generation_count = Core::Max( generation_count, *( std::max_element( generations.begin(), generations.end() ) ) ); } @@ -1123,7 +1123,7 @@ void ProjectPrivate::convert_version1_project() } // Finally we set the session list to an empty vector so we aren't tempted to do this again. - // This variable remains empty and unused from this point onward. + // This variable remains empty and unused from this point onward. this->project_->sessions_state_->clear(); // Set the generation count @@ -1132,7 +1132,7 @@ void ProjectPrivate::convert_version1_project() // Need to overwrite the generation_count_state, otherwise at the end of session load // it will be set back to zero if there was no generation_count_state in the old project this->project_->generation_count_state_->set( generation_count + 1); - + // ==== Convert notes ==== const std::vector< std::string >& notes = this->project_->project_notes_state_->get(); @@ -1144,7 +1144,7 @@ void ProjectPrivate::convert_version1_project() std::vector< std::string > note_info = Core::SplitString( note_components[ 0 ], " - " ); if ( note_info.size() < 2 ) continue; - + boost::posix_time::ptime note_time( boost::posix_time::not_a_date_time ); ss.str( note_info[ 0 ] ); try @@ -1181,7 +1181,7 @@ bool ProjectPrivate::rename_version1_session_files() } boost::filesystem::path sessions_path = this->project_->get_project_sessions_path(); - + for ( size_t i = 0; i < results.size(); ++i ) { std::string session_file_name; @@ -1189,21 +1189,21 @@ bool ProjectPrivate::rename_version1_session_files() { session_file_name = boost::any_cast< std::string >( results[ i ][ "session_file" ] ); } - catch ( ... ) + catch ( ... ) { - continue; + continue; } SessionID session_id = boost::any_cast< SessionID >( results[ i ][ "session_id" ] ); boost::filesystem::path old_session_file = sessions_path / session_file_name; - boost::filesystem::path new_session_file = sessions_path / + boost::filesystem::path new_session_file = sessions_path / ( Core::ExportToString( session_id ) + ".xml" ); try { boost::filesystem::rename( old_session_file, new_session_file ); } - catch ( ... ) + catch ( ... ) { continue; } @@ -1267,7 +1267,7 @@ bool ProjectPrivate::parse_session_data( const boost::filesystem::path& file_pat return true; } -bool ProjectPrivate::parse_session_provenance_ids( const boost::filesystem::path& file_path, +bool ProjectPrivate::parse_session_provenance_ids( const boost::filesystem::path& file_path, std::vector< long long >& prov_ids ) { Core::StateIO state_io; @@ -1320,7 +1320,7 @@ bool ProjectPrivate::parse_session_provenance_ids( const boost::filesystem::path void ProjectPrivate::set_session_file( SessionID id, const std::string& file_name ) { - std::string sql_str = "UPDATE session SET session_file = '" + + std::string sql_str = "UPDATE session SET session_file = '" + DatabaseManager::EscapeQuotes( file_name ) + "' WHERE session_id = " + Core::ExportToString( id ) + ";"; std::string err; @@ -1388,19 +1388,19 @@ bool ProjectPrivate::process_inputfile_importers() } // Get the directory in which we need to store the input files. - boost::filesystem::path inputfiles_dir = this->project_->get_project_inputfiles_path(); + boost::filesystem::path inputfiles_dir = this->project_->get_project_inputfiles_path(); if ( ! boost::filesystem::exists( inputfiles_dir ) ) { // Directory does not exist return false; - } - + } + // TODO: Keep the records that could not be written for ( size_t j = 0; j < this->input_file_importers_.size(); j++ ) { InputFilesImporterHandle importer = this->input_file_importers_[ j ]; InputFilesID inputfiles_id = importer->get_inputfiles_id(); - + boost::filesystem::path import_dir = inputfiles_dir / Core::ExportToString( inputfiles_id ); if ( boost::filesystem::exists( import_dir ) ) { @@ -1424,23 +1424,23 @@ bool ProjectPrivate::process_inputfile_importers() catch ( ... ) { CORE_LOG_ERROR( std::string( "Could not create directory '" ) + import_dir.string() + - "'." ); + "'." ); } } - + if ( boost::filesystem::exists( import_dir ) ) { if ( !importer->copy_files( import_dir ) ) { - CORE_LOG_ERROR( std::string( "Could not import original files into directory '" ) + + CORE_LOG_ERROR( std::string( "Could not import original files into directory '" ) + import_dir.string() + "'." ); } } } - + // Clear the list with importers this->input_file_importers_.clear(); - + return true; } @@ -1459,7 +1459,7 @@ bool ProjectPrivate::get_all_notes( ProjectNoteList& notes ) } std::stringstream ss; - ss.imbue( std::locale( ss.getloc(), new boost::posix_time::time_input_facet( + ss.imbue( std::locale( ss.getloc(), new boost::posix_time::time_input_facet( "%Y-%m-%d %H:%M:%S" ) ) ); ss.exceptions( std::ios_base::failbit ); @@ -1487,7 +1487,7 @@ bool ProjectPrivate::get_all_notes( ProjectNoteList& notes ) bool ProjectPrivate::get_session_file( SessionID session_id, boost::filesystem::path& file_path, std::string& error ) { // Query session information from database - std::string sql_str = "SELECT session_file FROM session WHERE session_id = " + + std::string sql_str = "SELECT session_file FROM session WHERE session_id = " + Core::ExportToString( session_id ) + ";"; ResultSet result_set; if ( !this->session_database_.run_sql_statement( sql_str, result_set, error ) || @@ -1502,7 +1502,7 @@ bool ProjectPrivate::get_session_file( SessionID session_id, boost::filesystem:: boost::filesystem::path project_path( this->project_->project_path_state_->get() ); // Get the session XML file - boost::filesystem::path session_file = project_path / SESSION_DIR_C / + boost::filesystem::path session_file = project_path / SESSION_DIR_C / ( Core::ExportToString( session_id ) + ".xml" ); if ( !boost::filesystem::exists( session_file ) ) { @@ -1524,13 +1524,13 @@ bool ProjectPrivate::get_session_file( SessionID session_id, boost::filesystem:: return true; } -void ProjectPrivate::get_provenance_steps( const std::vector< ProvenanceID >& prov_ids, +void ProjectPrivate::get_provenance_steps( const std::vector< ProvenanceID >& prov_ids, std::set< ProvenanceStepID >& prov_steps ) { typedef std::queue< ProvenanceID > prov_id_queue_type; void ( prov_id_queue_type::*push_queue_func )( const ProvenanceID& ) = &prov_id_queue_type::push; prov_id_queue_type provenance_queue; - std::for_each( prov_ids.begin(), prov_ids.end(), boost::bind( + std::for_each( prov_ids.begin(), prov_ids.end(), boost::bind( push_queue_func, &provenance_queue, _1 ) ); while ( !provenance_queue.empty() ) @@ -1589,13 +1589,13 @@ void ProjectPrivate::set_project_changed( Core::ActionHandle action, Core::Actio // NOTE: Changing the variable Core::Application::lock_type lock( Core::Application::GetMutex() ); this->changed_ = true; - } + } } } long long ProjectPrivate::get_user_id( const std::string& user_name ) { - std::string sql_str = "SELECT user_id FROM user WHERE user_name = '" + + std::string sql_str = "SELECT user_id FROM user WHERE user_name = '" + DatabaseManager::EscapeQuotes( user_name ) + "';"; std::string error; ResultSet results; @@ -1609,15 +1609,15 @@ long long ProjectPrivate::get_user_id( const std::string& user_name ) { return boost::any_cast< long long >( results[ 0 ][ "user_id" ] ); } - - sql_str = "INSERT INTO user (user_name) VALUES('" + + + sql_str = "INSERT INTO user (user_name) VALUES('" + DatabaseManager::EscapeQuotes( user_name ) + "');"; if ( !this->provenance_database_.run_sql_statement( sql_str, error ) ) { CORE_LOG_ERROR( error ); return -1; } - + return this->provenance_database_.get_last_insert_rowid(); } @@ -1655,7 +1655,7 @@ bool ProjectPrivate::get_user_name( long long user_id, std::string& user_name ) user_name = it->second; return true; } - + std::string sql_str = "SELECT user_name FROM user WHERE user_id = " + Core::ExportToString( user_id ) + ";"; ResultSet results; @@ -1665,13 +1665,13 @@ bool ProjectPrivate::get_user_name( long long user_id, std::string& user_name ) CORE_LOG_ERROR( error ); return false; } - + if ( results.size() == 0 ) { CORE_LOG_ERROR( "Invalid provenance database." ); return false; } - + try { user_name = boost::any_cast< std::string >( results[ 0 ][ "user_name" ] ); @@ -1818,7 +1818,7 @@ void Project::initialize() { // Initialize the colors with the default colors from the preference manager std::string stateid = std::string( "color_" ) + Core::ExportToString( j ); - this->add_state( stateid, this->color_states_[ j ], + this->add_state( stateid, this->color_states_[ j ], PreferencesManager::Instance()->get_default_colors()[ j ] ); } @@ -1834,7 +1834,7 @@ void Project::initialize() // Each time an action is executed, check whether it changes the project data, if so // mark this in the project, so the UI can query the user for a save action if the application // is closed while there is unsaved data. - this->add_connection( Core::ActionDispatcher::Instance()->post_action_signal_.connect( + this->add_connection( Core::ActionDispatcher::Instance()->post_action_signal_.connect( boost::bind( &ProjectPrivate::set_project_changed, this->private_, _1, _2 ) ) ); } @@ -1842,29 +1842,29 @@ bool Project::load_project( const boost::filesystem::path& project_file ) { // This function sets state variables directly, hence we need to be on the application thread ASSERT_IS_APPLICATION_THREAD(); - + // Ensure the filename is an actual file that exists boost::filesystem::path full_filename; - + try { - full_filename = boost::filesystem::absolute( project_file ); + full_filename = boost::filesystem::absolute( project_file ); // Ensure the given file actually exists if ( ! boost::filesystem::exists( full_filename ) ) { std::string error = std::string( "File '" ) + project_file.string() + "' does not exist."; - CORE_LOG_ERROR( error ); + CORE_LOG_ERROR( error ); return false; } - + // Ensure it is a regular file and not a directory or a symbolic link if ( ! boost::filesystem::is_regular_file( full_filename ) ) { std::string error = std::string( "File '" ) + project_file.string() + "' is not a regular file."; - CORE_LOG_ERROR( error ); + CORE_LOG_ERROR( error ); return false; } } @@ -1875,7 +1875,7 @@ bool Project::load_project( const boost::filesystem::path& project_file ) CORE_LOG_ERROR( error ); return false; } - + // Load the information from the file Core::StateIO stateio; if ( !stateio.import_from_file( project_file ) ) @@ -1883,19 +1883,19 @@ bool Project::load_project( const boost::filesystem::path& project_file ) // We could not load the file, hence send a message to the user std::string error = std::string( "Could not open project file '" ) + project_file.string() + "'."; CORE_LOG_ERROR( error ); - return false; + return false; } - - if ( !this->load_states( stateio ) ) + + if ( !this->load_states( stateio ) ) { // We could not load the file, hence send a message to the user std::string error = std::string( "Could not read project file '" ) + project_file.string() + "'."; CORE_LOG_ERROR( error ); - return false; + return false; } // First update the state variables that were not saved, such as // project name and project path - + bool is_bundle = false; #ifdef __APPLE__ @@ -1905,11 +1905,11 @@ bool Project::load_project( const boost::filesystem::path& project_file ) { FSRef file_ref; Boolean is_directory; - FSPathMakeRef( reinterpret_cast( + FSPathMakeRef( reinterpret_cast( full_filename.parent_path().string().c_str() ), &file_ref, &is_directory ); FSCatalogInfo info; FSGetCatalogInfo( &file_ref, kFSCatInfoFinderInfo, &info, 0, 0, 0 ); - + FileInfo& finder_info = *reinterpret_cast( &info.finderInfo ); if ( finder_info.finderFlags & kHasBundle ) is_bundle = true; } @@ -1917,15 +1917,15 @@ bool Project::load_project( const boost::filesystem::path& project_file ) { } -#endif - +#endif + if ( is_bundle ) { if ( full_filename.parent_path().stem().string() != full_filename.stem().string() ) { boost::filesystem::path new_project_file = full_filename.parent_path() / ( full_filename.parent_path().stem().string() + Project::GetDefaultProjectFileExtension() ); - + try { boost::filesystem::rename( full_filename, new_project_file ); @@ -1951,7 +1951,7 @@ bool Project::load_project( const boost::filesystem::path& project_file ) //{ // return false; //} - + this->project_path_state_->set( full_filename.parent_path().string() ); // Since we load this one from disk, it obviously exists on disk @@ -1985,9 +1985,9 @@ bool Project::load_project( const boost::filesystem::path& project_file ) this->private_->initialize_provenance_database(); } - boost::filesystem::path note_db_file = full_filename.parent_path() / + boost::filesystem::path note_db_file = full_filename.parent_path() / DATABASE_DIR_C / NOTE_DATABASE_C; - if ( !boost::filesystem::exists( note_db_file ) || + if ( !boost::filesystem::exists( note_db_file ) || !this->private_->note_database_.load_database( note_db_file, error ) ) { this->private_->initialize_note_database(); @@ -2000,12 +2000,12 @@ bool Project::load_project( const boost::filesystem::path& project_file ) return true; } -bool Project::save_project( const boost::filesystem::path& project_path, +bool Project::save_project( const boost::filesystem::path& project_path, const std::string& project_name, bool anonymize ) { // This function sets state variables directly, hence we need to be on the application thread. ASSERT_IS_APPLICATION_THREAD(); - + // Ensure that we have the full path boost::filesystem::path full_path; try @@ -2014,21 +2014,21 @@ bool Project::save_project( const boost::filesystem::path& project_path, } catch ( ... ) { - std::string error = std::string( "Could not resolve directory name '" ) + + std::string error = std::string( "Could not resolve directory name '" ) + project_path.string() + "'."; CORE_LOG_ERROR( error ); return false; } - + // Directory may not exist, but if it exists it needs to be directory - if ( boost::filesystem::exists( project_path ) && + if ( boost::filesystem::exists( project_path ) && !boost::filesystem::is_directory( project_path ) ) { std::string error = std::string( "'" ) + project_path.string() + "' is not a directory."; CORE_LOG_ERROR( error ); return false; } - + // Remove patient-specific data if project should be anonymized if( anonymize ) { @@ -2038,7 +2038,7 @@ bool Project::save_project( const boost::filesystem::path& project_path, { boost::filesystem::remove_all( inputfiles_dir ); } - catch ( ... ) + catch ( ... ) { CORE_LOG_ERROR( "Couldn't remove directory '" + inputfiles_dir.string() + "' for anonymization." ); return false; @@ -2053,17 +2053,17 @@ bool Project::save_project( const boost::filesystem::path& project_path, } // NOTE: This function has several modes: - // (1) If the project has not been saved yet, the project will be saved to the location + // (1) If the project has not been saved yet, the project will be saved to the location // indicated and a session will be saved, as a session is needed to load a project // (2) If the project exists and the name is the same, we only save a session // (3) If the project is in the same directory but the project name is changed, we save a new // session and rename the project file // (4) If the project is directed towards a new directory all files are copied and the project // is saved in the new location. Afterwards the project refers to that new project. - + if ( this->project_files_generated_state_->get() == false || this->project_files_accessible_state_->get() == false ) - { + { // Set the new project name. this->project_name_state_->set( project_name ); this->project_file_state_->set( project_name + Project::GetDefaultProjectFileExtension() ); @@ -2071,19 +2071,19 @@ bool Project::save_project( const boost::filesystem::path& project_path, // Set the new directory in which this project is saved. this->project_path_state_->set( project_path.string() ); - // Make sure that the program knows that the current project now lives on disk. + // Make sure that the program knows that the current project now lives on disk. this->project_files_generated_state_->set( true ); // Save the current session so there is something to load when the project is opened. return this->save_session( AUTO_SESSION_NAME_C ); } - else + else { boost::filesystem::path current_project_path( this->project_path_state_->get() ); current_project_path = boost::filesystem::absolute( current_project_path ); std::string current_project_name = this->project_name_state_->get(); std::string current_project_file = this->project_file_state_->get(); - + if ( current_project_path == project_path && current_project_name == project_name ) { // All the user wanted is to save a session, as it is the same name and directory @@ -2094,8 +2094,8 @@ bool Project::save_project( const boost::filesystem::path& project_path, { // OK, the user gave us a new name, but directory is the same // Update the project information - this->project_name_state_->set( project_name ); - + this->project_name_state_->set( project_name ); + // Save out a session with the current information bool succeeded = this->save_session( this->current_session_name_state_->get() ); @@ -2103,24 +2103,24 @@ bool Project::save_project( const boost::filesystem::path& project_path, { boost::filesystem::path current_xml_file = current_project_path / current_project_file; // Remove the old project file - try + try { boost::filesystem::remove( current_xml_file ); } catch( ... ) { - std::string error = std::string( "Could not delete file '" ) + + std::string error = std::string( "Could not delete file '" ) + current_xml_file.string() + "'."; CORE_LOG_ERROR( error ); } } - + return succeeded; } else { // OK copy the full project to the new directory - // Some users have requested that all files/folders be copied, even ones they put in the + // Some users have requested that all files/folders be copied, even ones they put in the // project folder. This is why we need to do a recursive copy instead of explicity // copying certain files and folders. if ( !Core::RecursiveCopyDirectory( current_project_path, project_path ) ) @@ -2138,31 +2138,31 @@ bool Project::save_project( const boost::filesystem::path& project_path, { boost::filesystem::remove_all( inputfiles_dir ); } - catch ( ... ) + catch ( ... ) { - CORE_LOG_ERROR( "Couldn't remove directory '" + + CORE_LOG_ERROR( "Couldn't remove directory '" + inputfiles_dir.string() + "' for anonymization." ); return false; } - + // Remove meta data from session files boost::filesystem::path session_dir = project_path / SESSION_DIR_C; - + // Iterate through directory - boost::filesystem::directory_iterator it = + boost::filesystem::directory_iterator it = boost::filesystem::directory_iterator( session_dir ); boost::filesystem::directory_iterator it_end; - + while ( it != it_end ) { boost::filesystem::path filename = (*it).path(); if ( filename.extension().string() == ".xml" ) - { + { Core::StateIO state_io; - if ( !state_io.import_from_file( filename ) ) + if ( !state_io.import_from_file( filename ) ) { // NOTE: Rather remove a file than let patient data continue to persist - + try { boost::filesystem::remove( filename ); @@ -2170,29 +2170,29 @@ bool Project::save_project( const boost::filesystem::path& project_path, } catch( ... ) { - CORE_LOG_ERROR( "Couldn't remove file '" + filename.string() + CORE_LOG_ERROR( "Couldn't remove file '" + filename.string() + "' for anonymization." ); - return false; + return false; } } - + // Find the layer manager element TiXmlElement* root_element = state_io.get_current_element(); TiXmlElement* lm_element = root_element->FirstChildElement( "layermanager" ); - if ( lm_element == 0 ) + if ( lm_element == 0 ) { // does not contain layer manager so continue continue; } - + // Finr the groups element TiXmlElement* groups_element = lm_element->FirstChildElement( "groups" ); - if ( groups_element == 0 ) + if ( groups_element == 0 ) { // does not contain layer groups so continue continue; } - + TiXmlElement* group_element = groups_element->FirstChildElement(); while ( group_element != 0 ) { @@ -2209,15 +2209,15 @@ bool Project::save_project( const boost::filesystem::path& project_path, { state_element->FirstChild()->SetValue( "" ); } - } + } } - + state_element = state_element->NextSiblingElement( "State" ); } group_element = group_element->NextSiblingElement(); } - + group_element = groups_element->FirstChildElement(); while ( group_element != 0 ) { @@ -2244,9 +2244,9 @@ bool Project::save_project( const boost::filesystem::path& project_path, { state_element->FirstChild()->SetValue( "" ); } - } + } } - + state_element = state_element->NextSiblingElement( "State" ); } @@ -2255,11 +2255,11 @@ bool Project::save_project( const boost::filesystem::path& project_path, group_element = group_element->NextSiblingElement(); } - + if ( !state_io.export_to_file( filename ) ) { // NOTE: Rather remove a file than let patient data continue to persist - + try { boost::filesystem::remove( filename ); @@ -2267,18 +2267,18 @@ bool Project::save_project( const boost::filesystem::path& project_path, } catch( ... ) { - CORE_LOG_ERROR( "Couldn't remove file '" + filename.string() + CORE_LOG_ERROR( "Couldn't remove file '" + filename.string() + "' for anonymization." ); - return false; + return false; } } } ++it; } - + // This will instruct the save session to strip the meta data out, when it is // saved at the end of this function. - + this->set_need_anonymize( true ); // Done anonymizing } @@ -2289,18 +2289,18 @@ bool Project::save_project( const boost::filesystem::path& project_path, { boost::filesystem::remove( old_project_file ); } - catch ( ... ) + catch ( ... ) { CORE_LOG_ERROR( "Couldn't remove file '" + old_project_file.string() + "'." ); } // Update the project this->project_name_state_->set( project_name ); - this->project_file_state_->set( project_name + + this->project_file_state_->set( project_name + Project::GetDefaultProjectFileExtension() ); this->project_path_state_->set( project_path.string() ); - - // This will save a session and update the project file and + + // This will save a session and update the project file and // provenance database return this->save_session( AUTO_SESSION_NAME_C ); } @@ -2353,7 +2353,7 @@ bool Project::save_state() } -bool Project::export_project( const boost::filesystem::path& export_path, +bool Project::export_project( const boost::filesystem::path& export_path, const std::string& project_name, long long session_id ) { // This function sets state variables directly, hence we need to be on the application thread. @@ -2366,7 +2366,7 @@ bool Project::export_project( const boost::filesystem::path& export_path, } std::string error; - if ( boost::filesystem::exists( export_path ) && + if ( boost::filesystem::exists( export_path ) && !boost::filesystem::is_directory( export_path ) ) { error = std::string( "Could not export project, because '" ) + @@ -2417,7 +2417,7 @@ bool Project::export_project( const boost::filesystem::path& export_path, } // Save out the session database - boost::filesystem::path export_session_db_path = + boost::filesystem::path export_session_db_path = export_path / DATABASE_DIR_C / SESSION_DATABASE_C; if ( !export_session_db.save_database( export_session_db_path, error ) ) { @@ -2443,7 +2443,7 @@ bool Project::export_project( const boost::filesystem::path& export_path, // Copy those data files BOOST_FOREACH( Core::DataBlock::generation_type generation, generations ) { - boost::filesystem::path src_file = project_path / DATA_DIR_C / + boost::filesystem::path src_file = project_path / DATA_DIR_C / ( Core::ExportToString( generation ) + ".nrrd" ); boost::filesystem::path dst_file = export_path / DATA_DIR_C / ( Core::ExportToString( generation ) + ".nrrd" ); @@ -2491,9 +2491,9 @@ bool Project::export_project( const boost::filesystem::path& export_path, CORE_LOG_ERROR( error ); return false; } - + // Save out the provenance database - boost::filesystem::path export_provenance_db_path = + boost::filesystem::path export_provenance_db_path = export_path / DATABASE_DIR_C / PROVENANCE_DATABASE_C; if ( !export_prov_db.save_database( export_provenance_db_path, error ) ) { @@ -2511,7 +2511,7 @@ bool Project::export_project( const boost::filesystem::path& export_path, BOOST_FOREACH( ResultSet::value_type result, result_set ) { long long inputfiles_cache_id = boost::any_cast< long long >( result[ "inputfiles_cache_id" ] ); - boost::filesystem::path src_dir = project_path / INPUTFILES_DIR_C / + boost::filesystem::path src_dir = project_path / INPUTFILES_DIR_C / Core::ExportToString( inputfiles_cache_id ); boost::filesystem::path dst_dir = export_path / INPUTFILES_DIR_C / Core::ExportToString( inputfiles_cache_id ); @@ -2532,7 +2532,7 @@ bool Project::export_project( const boost::filesystem::path& export_path, } // Write out the project file - boost::filesystem::path export_project_file = export_path / + boost::filesystem::path export_project_file = export_path / ( project_name + GetDefaultProjectFileExtension() ); Core::StateIO stateio; stateio.initialize(); @@ -2578,15 +2578,15 @@ bool Project::check_project_files() this->project_files_accessible_state_->set( false ); return false; } - - + + //// Check if s3d file still exists //if ( !boost::filesystem::exists( project_path / ( this->project_file_state_->get() ) ) ) //{ // //this->project_files_generated_state_->set( false ); // this->project_files_accessible_state_->set( false ); - // return false; + // return false; //} //// Check if session database file still exists @@ -2594,7 +2594,7 @@ bool Project::check_project_files() //{ // //this->project_files_generated_state_->set( false ); // this->project_files_accessible_state_->set( false ); - // return false; + // return false; //} //// Check if provenance database file still exists @@ -2602,7 +2602,7 @@ bool Project::check_project_files() //{ // //this->project_files_generated_state_->set( false ); // this->project_files_accessible_state_->set( false ); - // return false; + // return false; //} this->project_files_accessible_state_->set( true ); @@ -2623,10 +2623,10 @@ bool Project::load_session( SessionID session_id ) CORE_LOG_ERROR( error ); return false; } - + // Tell program that project does not yet need to be saved. this->reset_project_changed(); - + Core::StateIO state_io; if ( !state_io.import_from_file( session_file ) ) { @@ -2641,17 +2641,17 @@ bool Project::load_session( SessionID session_id ) CORE_LOG_ERROR( error ); return false; } - + this->project_files_generated_state_->set( true ); this->project_files_accessible_state_->set( true ); // We need to restore provenance and generation count from the project - Core::DataBlock::generation_type generation = this->generation_count_state_->get(); + Core::DataBlock::generation_type generation = this->generation_count_state_->get(); Core::DataBlockManager::Instance()->set_generation_count( generation ); ProvenanceID provenance_id = this->provenance_count_state_->get(); SetProvenanceCount( provenance_id ); - return true; + return true; } bool Project::load_last_session() @@ -2685,7 +2685,7 @@ bool Project::save_session( const std::string& name ) std::string session_name = name; // Update the session name if needed - if ( session_name.empty() ) + if ( session_name.empty() ) { session_name = this->current_session_name_state_->get(); } @@ -2700,7 +2700,7 @@ bool Project::save_session( const std::string& name ) if ( !ProjectPrivate::UpdateProjectDirectory( project_path ) ) { return false; - } + } // Copy all the input files into the project directory this->private_->process_inputfile_importers(); @@ -2721,7 +2721,7 @@ bool Project::save_session( const std::string& name ) { user_id = "unknown"; } - + // Convert the old session files if necessary if ( this->private_->conversion_needed_ ) { @@ -2738,14 +2738,14 @@ bool Project::save_session( const std::string& name ) } // Write the XML file in the session directory - boost::filesystem::path session_path = project_path / SESSION_DIR_C / + boost::filesystem::path session_path = project_path / SESSION_DIR_C / ( Core::ExportToString( session_id ) + ".xml" ); if ( !state_io.export_to_file( session_path ) ) { - std::string error = std::string( "Could not save session file '" ) + + std::string error = std::string( "Could not save session file '" ) + session_path.string() + "'."; CORE_LOG_ERROR( error ); - + // NOTE: We need to delete it when saving fails this->private_->delete_session_from_database( session_id ); return false; @@ -2763,13 +2763,13 @@ bool Project::save_session( const std::string& name ) // Update the size of the project this->private_->update_project_size(); - + // Add a timestamp of when the last session was saved for auto save functionality this->private_->set_last_saved_session_time_stamp(); // Tell program that project does not yet need to be saved. this->reset_project_changed(); - + // Signal the user interface the new session list SessionInfoListHandle session_list( new SessionInfoList ); this->private_->get_all_sessions( *session_list ); @@ -2792,15 +2792,15 @@ bool Project::delete_session( SessionID session_id ) { boost::filesystem::remove( session_file ); } - catch ( ... ) + catch ( ... ) { CORE_LOG_ERROR( "Couldn't delete file '" + session_file.string() + "'." ); } } - + // Delete the file from the database this->private_->delete_session_from_database( session_id ); - + // Remove redundant files from the project this->private_->clean_up_data_files(); @@ -2816,7 +2816,7 @@ bool Project::delete_session( SessionID session_id ) this->session_list_changed_signal_( session_list ); return true; -} +} bool Project::get_session_info( SessionID session_id, SessionInfo& session_info ) { @@ -2871,11 +2871,11 @@ bool Project::pre_save_states( Core::StateIO& state_io ) for ( size_t j = 0; j < this->color_states_.size(); j++ ) { // NOTE: color_states_ is only used locally for storing and retrieving colors - this->color_states_[ j ]->set( + this->color_states_[ j ]->set( PreferencesManager::Instance()->color_states_[ j ]->get() ); } } - + // We need to store the generation count // NOTE: Again this is an internally used variable, and it is only synchronized so generation // numbers are unique project wide. @@ -2896,7 +2896,7 @@ bool Project::post_load_states( const Core::StateIO& state_io ) { for ( size_t j = 0; j < this->color_states_.size(); j++ ) { - PreferencesManager::Instance()->color_states_[ j ]->set( + PreferencesManager::Instance()->color_states_[ j ]->set( this->color_states_[ j ]->get() ); } } @@ -2906,7 +2906,7 @@ bool Project::post_load_states( const Core::StateIO& state_io ) // We need to restore provenance and generation count for the project - Core::DataBlock::generation_type generation = this->generation_count_state_->get(); + Core::DataBlock::generation_type generation = this->generation_count_state_->get(); Core::DataBlockManager::Instance()->set_generation_count( generation ); ProvenanceID provenance_id = this->provenance_count_state_->get(); @@ -2942,21 +2942,21 @@ ProvenanceStepID Project::add_provenance_record( const ProvenanceStepHandle& ste if ( user_id == -1 || action_id == -1 ) return -1; // Make sure action_params is not empty. - // NOTE: A non-empty parameter string simplifies the query process + // NOTE: A non-empty parameter string simplifies the query process std::string action_params = step->get_action_params(); if ( action_params.empty() ) { action_params = " "; } - + ProvenanceIDList output_list = step->get_output_provenance_ids(); ProvenanceIDList input_list = step->get_input_provenance_ids(); ProvenanceIDList deleted_list = step->get_replaced_provenance_ids(); InputFilesID inputfiles_id = step->get_inputfiles_id(); std::string sql_str = "INSERT INTO provenance_step (action_id, action_params, user_id)" - " VALUES(" + Core::ExportToString( action_id ) + ", '" + - DatabaseManager::EscapeQuotes( action_params ) + + " VALUES(" + Core::ExportToString( action_id ) + ", '" + + DatabaseManager::EscapeQuotes( action_params ) + "', " + Core::ExportToString( user_id ) + ");"; std::string error; if ( !this->private_->provenance_database_.run_sql_statement( sql_str, error ) ) @@ -2989,7 +2989,7 @@ ProvenanceStepID Project::add_provenance_record( const ProvenanceStepHandle& ste return -1; } } - + for ( size_t i = 0; i < deleted_list.size(); ++i ) { sql_str = "INSERT INTO provenance_replaced (prov_step_id,prov_id) VALUES(" + Core::ExportToString( step_id ) + ", " + @@ -3001,12 +3001,12 @@ ProvenanceStepID Project::add_provenance_record( const ProvenanceStepHandle& ste return -1; } } - + if ( inputfiles_id > -1 ) { // If it is a valid ID add it to the table - sql_str = "INSERT INTO provenance_inputfiles_cache VALUES (" + + sql_str = "INSERT INTO provenance_inputfiles_cache VALUES (" + Core::ExportToString( step_id ) + ", " + Core::ExportToString( inputfiles_id ) + ");"; - + if ( !this->private_->provenance_database_.run_sql_statement( sql_str, error ) ) { CORE_LOG_ERROR( error ); @@ -3014,7 +3014,7 @@ ProvenanceStepID Project::add_provenance_record( const ProvenanceStepHandle& ste return -1; } } - + return step_id; } @@ -3036,13 +3036,13 @@ void Project::update_provenance_record( ProvenanceStepID record_id, const Proven std::string action_params = prov_step->get_action_params(); // Make sure action_params is not empty. - // NOTE: A non-empty parameter string simplifies the query process + // NOTE: A non-empty parameter string simplifies the query process if ( action_params.empty() ) { action_params = " "; } - std::string sql_str = "UPDATE provenance_step SET action_params = '" + + std::string sql_str = "UPDATE provenance_step SET action_params = '" + DatabaseManager::EscapeQuotes( action_params ) + "' WHERE prov_step_id = " + Core::ExportToString( record_id ) + ";"; std::string error; @@ -3097,7 +3097,7 @@ void Project::request_session_list() Core::Application::PostEvent( boost::bind( &Project::request_session_list, this ) ); return; } - + SessionInfoListHandle session_list( new SessionInfoList ); this->private_->get_all_sessions( *session_list ); this->session_list_changed_signal_( session_list ); @@ -3105,9 +3105,9 @@ void Project::request_session_list() std::string Project::GetDefaultProjectPathExtension() { - std::vector path_extensions = + std::vector path_extensions = Core::SplitString( CORE_APPLICATION_PROJECT_FOLDER_EXTENSION, ";"); - + if ( path_extensions.size() > 0 ) { return path_extensions[ 0 ]; @@ -3117,12 +3117,12 @@ std::string Project::GetDefaultProjectPathExtension() return ".seg3dproj"; } } - + std::string Project::GetDefaultProjectFileExtension() { - std::vector file_extensions = + std::vector file_extensions = Core::SplitString( CORE_APPLICATION_PROJECT_EXTENSION, ";"); - + if ( file_extensions.size() > 0 ) { return file_extensions[ 0 ]; @@ -3135,9 +3135,9 @@ std::string Project::GetDefaultProjectFileExtension() std::vector Project::GetProjectPathExtensions() { - std::vector path_extensions = + std::vector path_extensions = Core::SplitString( CORE_APPLICATION_PROJECT_FOLDER_EXTENSION, ";"); - + if ( path_extensions.size() > 0 ) { return path_extensions; @@ -3147,13 +3147,13 @@ std::vector Project::GetProjectPathExtensions() std::vector default_vector( 1, ".seg3dproj" ); return default_vector; } -} - -std::vector Project::GetProjectFileExtensions() +} + +std::vector Project::GetProjectFileExtensions() { - std::vector file_extensions = + std::vector file_extensions = Core::SplitString( CORE_APPLICATION_PROJECT_EXTENSION, ";"); - + if ( file_extensions.size() ) { return file_extensions; @@ -3176,7 +3176,7 @@ bool Project::execute_or_add_inputfiles_importer( const InputFilesImporterHandle this->private_->input_file_importers_.push_back( importer ); // If the project exists on disk copy all the files over - return this->private_->process_inputfile_importers(); + return this->private_->process_inputfile_importers(); } int Project::get_version() @@ -3200,7 +3200,7 @@ bool Project::add_note( const std::string& note ) { this->request_note_list(); } - + return succeeded; } @@ -3211,7 +3211,7 @@ void Project::request_note_list() Core::Application::PostEvent( boost::bind( &Project::request_note_list, this ) ); return; } - + ProjectNoteListHandle note_list( new ProjectNoteList ); this->private_->get_all_notes( *note_list ); this->note_list_changed_signal_( note_list ); diff --git a/src/Application/ProjectManager/ProjectManager.cc b/src/Application/ProjectManager/ProjectManager.cc index bfdd6087f..52f10e7ed 100644 --- a/src/Application/ProjectManager/ProjectManager.cc +++ b/src/Application/ProjectManager/ProjectManager.cc @@ -49,17 +49,17 @@ namespace Seg3D CORE_SINGLETON_IMPLEMENTATION( ProjectManager ); // File name of the project database -static const std::string PROJECT_DATABASE_C( +static const std::string PROJECT_DATABASE_C( std::string( CORE_APPLICATION_VERSION ) + "_recentprojects.sqlite" ); // File name of the ProjectManager state config file -static const std::string CONFIGURATION_FILE_C( +static const std::string CONFIGURATION_FILE_C( std::string( CORE_APPLICATION_VERSION ) + "_projectmanager.xml" ); // Version number of the project database static const int PROJECT_DATABASE_VERSION_C = 2; -class ProjectManagerPrivate : public DatabaseManager +class ProjectManagerPrivate : public DatabaseManager { public: // INITIALIZE_PROJECT_DATABASE: @@ -83,7 +83,7 @@ class ProjectManagerPrivate : public DatabaseManager // CLEANUP_PROJECTS_LIST: // this function cleans up projects from the recent projects list that don't exist. void cleanup_project_database(); - + // INSERT_OR_UPDATE_PROJECT_ENTRY: // Add a project to the database if it doesn't exist yet, otherwise update // its last_access_time to the current time. @@ -204,11 +204,11 @@ bool ProjectManagerPrivate::create_project_directory( const std::string& project // Location where the project needs to be generated boost::filesystem::path project_loc( project_location ); - try + try { project_loc = boost::filesystem::absolute( project_loc ); } - catch ( ... ) + catch ( ... ) { std::ostringstream error; error << "Directory '" << project_loc.string() << "' does not exist."; @@ -237,7 +237,7 @@ bool ProjectManagerPrivate::create_project_directory( const std::string& project } // try to create a project folder - try + try { boost::filesystem::create_directory( project_path ); } @@ -255,7 +255,7 @@ bool ProjectManagerPrivate::create_project_directory( const std::string& project void ProjectManagerPrivate::reset_current_project_folder() { - this->project_manager_->current_project_folder_state_->set( + this->project_manager_->current_project_folder_state_->set( PreferencesManager::Instance()->project_path_state_->get() ); } @@ -271,7 +271,7 @@ bool ProjectManagerPrivate::insert_or_update_project_entry( const boost::filesys CORE_LOG_ERROR( error ); return false; } - + if ( results.size() > 0 ) { // TODO: this code replaces an assert. @@ -303,7 +303,7 @@ bool ProjectManagerPrivate::insert_or_update_project_entry( const boost::filesys return false; } } - + // if we've successfully added recent projects to our database // then we let everyone know things have changed. this->project_manager_->recent_projects_changed_signal_(); @@ -321,7 +321,7 @@ void ProjectManagerPrivate::cleanup_project_database() CORE_LOG_ERROR( error ); return; } - + // Whether the database has been changed bool changed = false; @@ -361,7 +361,7 @@ void ProjectManagerPrivate::cleanup_project_database() } } } - + // If the database was changed, save it out if ( changed && !this->project_database_->save_database( this->project_db_file_, error ) ) { @@ -375,7 +375,7 @@ void ProjectManagerPrivate::cleanup_project_database() ProjectManager::ProjectManager() : StateHandler( "projectmanager", false ), private_( new ProjectManagerPrivate ) -{ +{ // Ensure we have a pointer back for the private functions this->private_->project_manager_ = this; @@ -403,9 +403,9 @@ ProjectManager::ProjectManager() : if ( stateio.import_from_file( configuration_dir / CONFIGURATION_FILE_C ) || stateio.import_from_file( configuration_dir / "projectmanager.xml" ) ) { - this->load_states( stateio ); + this->load_states( stateio ); } - + // Check whether directory exists and whether it can be used, if not update it to something // useful. The next function will go over a number of potential directories and finds the // one that it can use. @@ -413,15 +413,15 @@ ProjectManager::ProjectManager() : boost::filesystem::path current_file_folder = this->get_current_file_folder(); - // Update the current_project_folder to the most recent version + // Update the current_project_folder to the most recent version this->current_project_folder_state_->set( current_project_folder.string() ); this->current_file_folder_state_->set( current_file_folder.string() ); - + // Here we check to see if the recent projects database exists, otherwise we create it this->private_->load_or_create_project_database(); - + // Create a new project - this->private_->current_project_ = ProjectHandle( new Project( std::string( "Untitled Project" ) ) ); + this->private_->current_project_ = ProjectHandle( new Project( std::string( "Untitled Project" ) ) ); // Start the auto save thread AutoSave::Instance()->start(); @@ -440,13 +440,13 @@ ProjectManager::~ProjectManager() boost::filesystem::path ProjectManager::get_current_project_folder() { - Core::StateEngine::lock_type lock( Core::StateEngine::GetMutex() ); + Core::StateEngine::lock_type lock( Core::StateEngine::GetMutex() ); - std::string current_project_folder_string = this->current_project_folder_state_->get(); + std::string current_project_folder_string = this->current_project_folder_state_->get(); if ( current_project_folder_string.empty() ) { - current_project_folder_string = PreferencesManager::Instance()->project_path_state_->get(); + current_project_folder_string = PreferencesManager::Instance()->project_path_state_->get(); } boost::filesystem::path current_project_folder( current_project_folder_string ); @@ -472,24 +472,24 @@ boost::filesystem::path ProjectManager::get_current_project_folder() if (! boost::filesystem::exists( current_project_folder ) ) { Core::Application::Instance()->get_user_directory( current_project_folder ); - - current_project_folder = current_project_folder / + + current_project_folder = current_project_folder / ( Core::Application::GetApplicationName() + "-Projects" ); // Try current working path if (! boost::filesystem::exists( current_project_folder ) ) - { + { current_project_folder = current_project_folder.parent_path(); } - } + } } - + return current_project_folder; } boost::filesystem::path ProjectManager::get_current_file_folder() { - Core::StateEngine::lock_type lock( Core::StateEngine::GetMutex() ); + Core::StateEngine::lock_type lock( Core::StateEngine::GetMutex() ); boost::filesystem::path current_file_folder( this->current_file_folder_state_->get() ); try @@ -508,14 +508,14 @@ boost::filesystem::path ProjectManager::get_current_file_folder() if (! boost::filesystem::exists( current_file_folder ) ) { Core::Application::Instance()->get_user_directory( current_file_folder ); - + // Try current working path if (! boost::filesystem::exists( current_file_folder ) ) { current_file_folder = current_file_folder.parent_path(); } } - + return current_file_folder; } @@ -538,30 +538,30 @@ bool ProjectManager::new_project( const std::string& project_location, return false; } } - + // Reset the application. Core::Application::Reset(); // Ensure that the next project default name will be increased by 1. if ( project_name.substr( 0, 11 ) == "New Project" ) { - this->default_project_name_counter_state_->set( - this->default_project_name_counter_state_->get() + 1 ); + this->default_project_name_counter_state_->set( + this->default_project_name_counter_state_->get() + 1 ); } // Generate a new project this->private_->set_current_project( ProjectHandle( new Project( project_name ) ) ); - + // Open the default tools ToolManager::Instance()->open_default_tools(); - + if (! project_location.empty() ) { if (! this->get_current_project()->save_project( project_path, project_name, false ) ) { // Need to update this so the old project this->current_project_changed_signal_(); - // An error should have been logged by the save_project function. + // An error should have been logged by the save_project function. return false; } @@ -569,44 +569,44 @@ bool ProjectManager::new_project( const std::string& project_location, this->checkpoint_projectmanager(); // Make sure auto save is recomputed - AutoSave::Instance()->recompute_auto_save(); + AutoSave::Instance()->recompute_auto_save(); } - // NOTE: Even if the project location is empty (Quick Open), it is not necessary (or safe) + // NOTE: Even if the project location is empty (Quick Open), it is not necessary (or safe) // to turn off autosave. Autosave will not run if it sees an empty project location, even // if autosave is enabled. this->current_project_changed_signal_(); - + return true; } - + bool ProjectManager::open_project( const std::string& project_file ) -{ +{ // This function sets state variables directly, hence we need to be on the application thread. ASSERT_IS_APPLICATION_THREAD(); - + // Try to resolve the filename before we reset the application. boost::filesystem::path full_filename( project_file ); - - try + + try { full_filename = boost::filesystem::absolute( full_filename ); } - catch( ... ) + catch( ... ) { std::ostringstream error; error << "Converting '" << project_file << "' to absolute path failed."; CORE_LOG_ERROR( error.str() ); return false; } - + // Reset the application. Core::Application::Reset(); - // Create a new project, the old one will go out of scope as soon as + // Create a new project, the old one will go out of scope as soon as // the GUI releases the old project ProjectHandle new_proj; bool succeeded = true; @@ -627,7 +627,7 @@ bool ProjectManager::open_project( const std::string& project_file ) succeeded = new_proj->load_last_session(); if (! succeeded ) { - this->private_->set_current_project( ProjectHandle( + this->private_->set_current_project( ProjectHandle( new Project( std::string( "Untitled Project" ) ) ) ); } } @@ -640,26 +640,26 @@ bool ProjectManager::open_project( const std::string& project_file ) // Update recent file list, the current folder and save them to disk this->checkpoint_projectmanager(); } - + // TODO: Need to fix the widget, so it connects to the state variables correctly this->current_project_changed_signal_(); return succeeded; } - - -bool ProjectManager::save_project_as( const std::string& project_location, + + +bool ProjectManager::save_project_as( const std::string& project_location, const std::string& project_name, bool anonymize ) { // This function sets state variables directly, hence we need to be on the application thread ASSERT_IS_APPLICATION_THREAD(); - + if ( project_name.substr( 0, 12 ) == "New Project " ) { int number; if ( Core::ImportFromString( project_name.substr( 12 ), number ) ) { - int default_name_count = + int default_name_count = ProjectManager::Instance()->default_project_name_counter_state_->get(); if ( number >= default_name_count ) { @@ -667,7 +667,7 @@ bool ProjectManager::save_project_as( const std::string& project_location, } } } - + // Create a new directory for the project boost::filesystem::path project_path; if (! this->private_->create_project_directory( project_location, project_name, project_path ) ) @@ -677,7 +677,7 @@ bool ProjectManager::save_project_as( const std::string& project_location, if (! this->get_current_project()->save_project( project_path, project_name, anonymize ) ) { - // An error should have been logged by the save_project function. + // An error should have been logged by the save_project function. return false; } @@ -686,15 +686,15 @@ bool ProjectManager::save_project_as( const std::string& project_location, // Reset the auto save system AutoSave::Instance()->recompute_auto_save(); - + // Update recent file list, the current folder and save them to disk this->checkpoint_projectmanager(); return true; } - -bool ProjectManager::export_project( const std::string& export_path, + +bool ProjectManager::export_project( const std::string& export_path, const std::string& project_name, long long session_id ) { // This function sets state variables directly, hence we need to be on the application thread @@ -730,7 +730,7 @@ bool ProjectManager::save_project_session( const std::string& session_name ) AutoSave::Instance()->recompute_auto_save(); return true; } - + return false; } @@ -750,18 +750,18 @@ bool ProjectManager::load_project_session( long long session_id ) AutoSave::Instance()->recompute_auto_save(); return true; } - + // Reset the application. Core::Application::Reset(); return false; } - + bool ProjectManager::delete_project_session( long long session_id ) { // This function sets state variables directly, hence we need to be on the application thread ASSERT_IS_APPLICATION_THREAD(); - + return this->get_current_project()->delete_session( session_id ); } @@ -775,7 +775,7 @@ ProjectHandle ProjectManager::get_current_project() const void ProjectManager::checkpoint_projectmanager() { ProjectHandle current_project = this->get_current_project(); - + boost::filesystem::path project_path( current_project->project_path_state_->get() ); boost::filesystem::path project_file = project_path / current_project->project_file_state_->get(); this->private_->insert_or_update_project_entry( project_file ); @@ -785,17 +785,17 @@ void ProjectManager::checkpoint_projectmanager() // Get local configuration directory boost::filesystem::path configuration_dir; Core::Application::Instance()->get_config_directory( configuration_dir ); - + // Write out the XML file Core::StateIO stateio; stateio.initialize(); this->save_states( stateio ); - + if ( boost::filesystem::exists( configuration_dir ) ) { stateio.export_to_file( configuration_dir / CONFIGURATION_FILE_C ); } - + // Write out the database std::string error; if (! this->private_->project_database_->save_database( this->private_->project_db_file_, error ) ) @@ -818,17 +818,17 @@ bool ProjectManager::get_recent_projects( ProjectInfoList& recent_projects ) CORE_LOG_ERROR( error ); return false; } - + for ( size_t i = 0; i < results.size(); ++i ) { std::string name = boost::any_cast< std::string >( results[ i ][ "name" ] ); boost::filesystem::path path( boost::any_cast< std::string >( results[ i ][ "path" ] ) ); - time_t last_access_time = static_cast< time_t >( boost::any_cast< long long >( + time_t last_access_time = static_cast< time_t >( boost::any_cast< long long >( results[ i ][ "last_access_time" ] ) ); recent_projects.push_back( ProjectInfo( name, path, boost::posix_time::from_time_t( last_access_time ) ) ); } - + return true; } @@ -843,14 +843,14 @@ bool ProjectManager::CheckProjectFile( const boost::filesystem::path& path, std: { return false; } - + // Check whether the version is equal or lower to the program version if ( stateio.get_major_version() > Core::Application::GetMajorVersion() ) { error = "This project was saved with a newer version of Seg3D."; return false; } - + // Check the minor version if ( stateio.get_major_version() == Core::Application::GetMajorVersion() ) { diff --git a/src/ThirdParty/tinyxml/tinyxml.h b/src/ThirdParty/tinyxml/tinyxml.h index 01822911c..b1a6583a5 100755 --- a/src/ThirdParty/tinyxml/tinyxml.h +++ b/src/ThirdParty/tinyxml/tinyxml.h @@ -78,7 +78,7 @@ distribution. #define TIXML_SNPRINTF snprintf #define TIXML_SSCANF sscanf #endif -#endif +#endif class TiXmlDocument; class TiXmlElement; @@ -93,7 +93,7 @@ const int TIXML_MAJOR_VERSION = 2; const int TIXML_MINOR_VERSION = 6; const int TIXML_PATCH_VERSION = 1; -/* Internal structure for tracking location of items +/* Internal structure for tracking location of items in the XML file. */ struct TiXmlCursor @@ -116,7 +116,7 @@ struct TiXmlCursor If you return 'true' from a Visit method, recursive parsing will continue. If you return false, no children of this node or its sibilings will be Visited. - All flavors of Visit methods have a default implementation that returns 'true' (continue + All flavors of Visit methods have a default implementation that returns 'true' (continue visiting). You need to only override methods that are interesting to you. Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. @@ -151,8 +151,8 @@ class TiXmlVisitor }; // Only used by Attribute::Query functions -enum -{ +enum +{ TIXML_SUCCESS, TIXML_NO_ATTRIBUTE, TIXML_WRONG_TYPE @@ -204,10 +204,10 @@ class TiXmlBase /** All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL mode, std::string in STL mode.) Either or both cfile and str can be null. - - This is a formatted print, and will insert + + This is a formatted print, and will insert tabs and newlines. - + (For an unformatted stream, use the << operator.) */ virtual void Print( FILE* cfile, int depth ) const = 0; @@ -252,11 +252,11 @@ class TiXmlBase // in the UTF-8 sequence. static const int utf8ByteTable[256]; - virtual const char* Parse( const char* p, - TiXmlParsingData* data, + virtual const char* Parse( const char* p, + TiXmlParsingData* data, TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; - /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, + /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, or they will be transformed into entities! */ static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); @@ -287,9 +287,9 @@ class TiXmlBase static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); - inline static bool IsWhiteSpace( char c ) - { - return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); } inline static bool IsWhiteSpace( int c ) { @@ -374,7 +374,7 @@ class TiXmlBase /// Field containing a generic user pointer void* userData; - + // None of these methods are reliable for any language except English. // Good for approximation, not great for accuracy. static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); @@ -426,7 +426,7 @@ class TiXmlNode : public TiXmlBase friend class TiXmlElement; public: - #ifdef TIXML_USE_STL + #ifdef TIXML_USE_STL /** An input stream operator, for every class. Tolerant of newlines and formatting, but doesn't expect them. @@ -440,7 +440,7 @@ class TiXmlNode : public TiXmlBase The operator<< and operator>> are not completely symmetric. Writing a node to a stream is very well defined. You'll get a nice stream of output, without any extra whitespace or newlines. - + But reading is not as well defined. (As it always is.) If you create a TiXmlElement (for example) and read that from an input stream, the text needs to define an element or junk will result. This is @@ -448,7 +448,7 @@ class TiXmlNode : public TiXmlBase A TiXmlDocument will read nodes until it reads a root element, and all the children of that root element. - */ + */ friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); /// Appends the XML node or attribute to a std::string. @@ -530,7 +530,7 @@ class TiXmlNode : public TiXmlBase } const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. TiXmlNode* LastChild() { return lastChild; } - + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. TiXmlNode* LastChild( const char * _value ) { return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); @@ -709,11 +709,11 @@ class TiXmlNode : public TiXmlBase virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. /** Create an exact duplicate of this node and return it. The memory must be deleted - by the caller. + by the caller. */ virtual TiXmlNode* Clone() const = 0; - /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the XML tree will be conditionally visited and the host will be called back via the TiXmlVisitor interface. @@ -724,7 +724,7 @@ class TiXmlNode : public TiXmlBase The interface has been based on ideas from: - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern Which are both good references for "visiting". @@ -821,7 +821,7 @@ class TiXmlAttribute : public TiXmlBase /** QueryIntValue examines the value string. It is an alternative to the IntValue() method with richer error checking. - If the value is an integer, it is stored in 'value' and + If the value is an integer, it is stored in 'value' and the call returns TIXML_SUCCESS. If it is not an integer, it returns TIXML_WRONG_TYPE. @@ -840,21 +840,21 @@ class TiXmlAttribute : public TiXmlBase #ifdef TIXML_USE_STL /// STL std::string form. - void SetName( const std::string& _name ) { name = _name; } - /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. void SetValue( const std::string& _value ) { value = _value; } #endif /// Get the next sibling attribute in the DOM. Returns null at end. const TiXmlAttribute* Next() const; TiXmlAttribute* Next() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); } /// Get the previous sibling attribute in the DOM. Returns null at beginning. const TiXmlAttribute* Previous() const; TiXmlAttribute* Previous() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); } bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } @@ -890,7 +890,7 @@ class TiXmlAttribute : public TiXmlBase /* A class used to manage a group of attributes. It is only used internally, both by the ELEMENT and the DECLARATION. - + The set can be changed transparent to the Element and Declaration classes that use it, but NOT transparent to the Attribute which has to implement a next() and previous() method. Which makes @@ -977,11 +977,11 @@ class TiXmlElement : public TiXmlNode /** QueryIntAttribute examines the attribute - it is an alternative to the Attribute() method with richer error checking. - If the attribute is an integer, it is stored in 'value' and + If the attribute is an integer, it is stored in 'value' and the call returns TIXML_SUCCESS. If it is not an integer, it returns TIXML_WRONG_TYPE. If the attribute does not exist, then TIXML_NO_ATTRIBUTE is returned. - */ + */ int QueryIntAttribute( const char* name, int* _value ) const; /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). int QueryDoubleAttribute( const char* name, double* _value ) const; @@ -1009,7 +1009,7 @@ class TiXmlElement : public TiXmlNode /** Template form of the attribute query which will try to read the attribute into the specified type. Very easy, very powerful, but be careful to make sure to call this with the correct type. - + NOTE: This method doesn't work correctly for 'string' types that contain spaces. @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE @@ -1082,7 +1082,7 @@ class TiXmlElement : public TiXmlNode /** Convenience function for easy access to the text inside an element. Although easy and concise, GetText() is limited compared to getting the TiXmlText child and accessing it directly. - + If the first child of 'this' is a TiXmlText, the GetText() returns the character string of the Text node, else null is returned. @@ -1092,23 +1092,23 @@ class TiXmlElement : public TiXmlNode const char* str = fooElement->GetText(); @endverbatim - 'str' will be a pointer to "This is text". - + 'str' will be a pointer to "This is text". + Note that this function can be misleading. If the element foo was created from this XML: @verbatim - This is text + This is text @endverbatim then the value of str would be null. The first child node isn't a text node, it is another element. From this XML: @verbatim - This is text + This is text @endverbatim GetText() will return "This is ". - WARNING: GetText() accesses a child node - don't become confused with the - similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are safe type casts on the referenced node. */ const char* GetText() const; @@ -1126,7 +1126,7 @@ class TiXmlElement : public TiXmlNode virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - /** Walk the XML tree visiting this node and all of its children. + /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* visitor ) const; @@ -1179,7 +1179,7 @@ class TiXmlComment : public TiXmlNode virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - /** Walk the XML tree visiting this node and all of its children. + /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* visitor ) const; @@ -1197,16 +1197,16 @@ class TiXmlComment : public TiXmlNode }; -/** XML text. A text node can have 2 ways to output the next. "normal" output +/** XML text. A text node can have 2 ways to output the next. "normal" output and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with + you generally want to leave it alone, but you can change the output mode with SetCDATA() and query it with CDATA(). */ class TiXmlText : public TiXmlNode { friend class TiXmlElement; public: - /** Constructor for text element. By default, it is treated as + /** Constructor for text element. By default, it is treated as normal, encoded text. If you want it be output as a CDATA text element, set the parameter _cdata to 'true' */ @@ -1242,7 +1242,7 @@ class TiXmlText : public TiXmlNode virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - /** Walk the XML tree visiting this node and all of its children. + /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* content ) const; @@ -1318,7 +1318,7 @@ class TiXmlDeclaration : public TiXmlNode virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - /** Walk the XML tree visiting this node and all of its children. + /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* visitor ) const; @@ -1363,7 +1363,7 @@ class TiXmlUnknown : public TiXmlNode virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - /** Walk the XML tree visiting this node and all of its children. + /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* content ) const; @@ -1449,7 +1449,7 @@ class TiXmlDocument : public TiXmlNode - The ErrorId() will contain the integer identifier of the error (not generally useful) - The ErrorDesc() method will return the name of the error. (very useful) - The ErrorRow() and ErrorCol() will return the location of the error (if known) - */ + */ bool Error() const { return error; } /// Contains a textual (english) description of the error if one occurs. @@ -1460,7 +1460,7 @@ class TiXmlDocument : public TiXmlNode */ int ErrorId() const { return errorId; } - /** Returns the location (if known) of the error. The first column is column 1, + /** Returns the location (if known) of the error. The first column is column 1, and the first row is row 1. A value of 0 means the row and column wasn't applicable (memory errors, for example, have no row/column) or the parser lost the error. (An error in the error reporting, in that case.) @@ -1473,7 +1473,7 @@ class TiXmlDocument : public TiXmlNode /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) to report the correct values for row and column. It does not change the output or input in any way. - + By calling this method, with a tab size greater than 0, the row and column of each node and attribute is stored when the file is loaded. Very useful for tracking the DOM back in to @@ -1501,11 +1501,11 @@ class TiXmlDocument : public TiXmlNode /** If you have handled the error, it can be reset with this call. The error state is automatically cleared if you Parse a new XML block. */ - void ClearError() { error = false; - errorId = 0; - errorDesc = ""; - errorLocation.row = errorLocation.col = 0; - //errorLocation.last = 0; + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; } /** Write the document to standard out using formatted printing ("pretty print"). */ @@ -1515,7 +1515,7 @@ class TiXmlDocument : public TiXmlNode will allocate a character array (new char[]) and return it as a pointer. The calling code pust call delete[] on the return char* to avoid a memory leak. */ - //char* PrintToMemory() const; + //char* PrintToMemory() const; /// Print this Document to a FILE stream. virtual void Print( FILE* cfile, int depth = 0 ) const; @@ -1525,7 +1525,7 @@ class TiXmlDocument : public TiXmlNode virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - /** Walk the XML tree visiting this node and all of its children. + /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* content ) const; @@ -1563,7 +1563,7 @@ protected : @endverbatim - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very easy to write a *lot* of code that looks like: @verbatim @@ -1583,7 +1583,7 @@ protected : @endverbatim And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity - of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe and correct to use: @verbatim @@ -1604,7 +1604,7 @@ protected : What they should not be used for is iteration: @verbatim - int i=0; + int i=0; while ( true ) { TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); @@ -1615,8 +1615,8 @@ protected : } @endverbatim - It seems reasonable, but it is in fact two embedded while loops. The Child method is - a linear walk to find the element, so this code would iterate much more than it needs + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs to. Instead, prefer: @verbatim @@ -1646,20 +1646,20 @@ class TiXmlHandle /// Return a handle to the first child element with the given name. TiXmlHandle FirstChildElement( const char * value ) const; - /** Return a handle to the "index" child with the given name. + /** Return a handle to the "index" child with the given name. The first child is 0, the second 1, etc. */ TiXmlHandle Child( const char* value, int index ) const; - /** Return a handle to the "index" child. + /** Return a handle to the "index" child. The first child is 0, the second 1, etc. */ TiXmlHandle Child( int index ) const; - /** Return a handle to the "index" child element with the given name. + /** Return a handle to the "index" child element with the given name. The first child element is 0, the second 1, etc. Note that only TiXmlElements are indexed: other types are not counted. */ TiXmlHandle ChildElement( const char* value, int index ) const; - /** Return a handle to the "index" child element. + /** Return a handle to the "index" child element. The first child element is 0, the second 1, etc. Note that only TiXmlElements are indexed: other types are not counted. */ @@ -1675,7 +1675,7 @@ class TiXmlHandle /** Return the handle as a TiXmlNode. This may return null. */ - TiXmlNode* ToNode() const { return node; } + TiXmlNode* ToNode() const { return node; } /** Return the handle as a TiXmlElement. This may return null. */ TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } @@ -1686,11 +1686,11 @@ class TiXmlHandle */ TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } - /** @deprecated use ToNode. + /** @deprecated use ToNode. Return the handle as a TiXmlNode. This may return null. */ - TiXmlNode* Node() const { return ToNode(); } - /** @deprecated use ToElement. + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. Return the handle as a TiXmlElement. This may return null. */ TiXmlElement* Element() const { return ToElement(); } @@ -1750,7 +1750,7 @@ class TiXmlPrinter : public TiXmlVisitor void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } /// Query the indention string. const char* Indent() { return indent.c_str(); } - /** Set the line breaking string. By default set to newline (\n). + /** Set the line breaking string. By default set to newline (\n). Some operating systems prefer other characters, or can be set to the null/empty string for no indenation. */ @@ -1758,12 +1758,12 @@ class TiXmlPrinter : public TiXmlVisitor /// Query the current line breaking string. const char* LineBreak() { return lineBreak.c_str(); } - /** Switch over to "stream printing" which is the most dense formatting without + /** Switch over to "stream printing" which is the most dense formatting without linebreaks. Common when the XML is needed for network transmission. */ void SetStreamPrinting() { indent = ""; lineBreak = ""; - } + } /// Return the result. const char* CStr() { return buffer.c_str(); } /// Return the length of the result string. @@ -1796,4 +1796,3 @@ class TiXmlPrinter : public TiXmlVisitor #endif #endif - diff --git a/src/ThirdParty/tinyxml/tinyxmlparser.cpp b/src/ThirdParty/tinyxml/tinyxmlparser.cpp index 666a4f757..fd4127ed8 100755 --- a/src/ThirdParty/tinyxml/tinyxmlparser.cpp +++ b/src/ThirdParty/tinyxml/tinyxmlparser.cpp @@ -2,23 +2,23 @@ www.sourceforge.net/projects/tinyxml Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: -1. The origin of this software must not be misrepresented; you must +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source +3. This notice may not be removed or altered from any source distribution. */ @@ -39,8 +39,8 @@ distribution. // Note tha "PutString" hardcodes the same list. This // is less flexible than it appears. Changing the entries -// or order will break putstring. -TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = +// or order will break putstring. +TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = { { "&", 5, '&' }, { "<", 4, '<' }, @@ -54,16 +54,16 @@ TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = // Including the basic of this table, which determines the #bytes in the // sequence from the lead byte. 1 placed for invalid sequences -- // although the result will be junk, pass it through as much as possible. -// Beware of the non-characters in UTF-8: +// Beware of the non-characters in UTF-8: // ef bb bf (Microsoft "lead bytes") // ef bf be -// ef bf bf +// ef bf bf const unsigned char TIXML_UTF_LEAD_0 = 0xefU; const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; -const int TiXmlBase::utf8ByteTable[256] = +const int TiXmlBase::utf8ByteTable[256] = { // 0 1 2 3 4 5 6 7 8 9 a b c d e f 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 @@ -75,9 +75,9 @@ const int TiXmlBase::utf8ByteTable[256] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte @@ -91,7 +91,7 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng const unsigned long BYTE_MARK = 0x80; const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - if (input < 0x80) + if (input < 0x80) *length = 1; else if ( input < 0x800 ) *length = 2; @@ -105,22 +105,22 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng output += *length; // Scary scary fall throughs. - switch (*length) + switch (*length) { case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; case 1: - --output; + --output; *output = (char)(input | FIRST_BYTE_MARK[*length]); } } @@ -130,7 +130,7 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng { // This will only work for low-ascii, everything else is assumed to be a valid // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very + // to figure out alhabetical vs. not across encoding. So take a very // conservative approach. // if ( encoding == TIXML_ENCODING_UTF8 ) @@ -151,7 +151,7 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng { // This will only work for low-ascii, everything else is assumed to be a valid // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very + // to figure out alhabetical vs. not across encoding. So take a very // conservative approach. // if ( encoding == TIXML_ENCODING_UTF8 ) @@ -224,7 +224,7 @@ void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) case '\r': // bump down to the next line ++row; - col = 0; + col = 0; // Eat the character ++p; @@ -266,11 +266,11 @@ void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) // In these cases, don't advance the column. These are // 0-width spaces. if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) - p += 3; + p += 3; else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) - p += 3; + p += 3; else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) - p += 3; + p += 3; else { p +=3; ++col; } // A normal character. } @@ -322,10 +322,10 @@ const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) while ( *p ) { const unsigned char* pU = (const unsigned char*)p; - + // Skip the stupid Microsoft UTF-8 Byte order marks if ( *(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==TIXML_UTF_LEAD_1 + && *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) { p += 3; @@ -413,12 +413,12 @@ const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncodi // After that, they can be letters, underscores, numbers, // hyphens, or colons. (Colons are valid ony for namespaces, // but tinyxml can't tell namespaces from names.) - if ( p && *p + if ( p && *p && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) { const char* start = p; while( p && *p - && ( IsAlphaNum( (unsigned char ) *p, encoding ) + && ( IsAlphaNum( (unsigned char ) *p, encoding ) || *p == '_' || *p == '-' || *p == '.' @@ -469,7 +469,7 @@ const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXml ucs += mult * (*q - 'a' + 10); else if ( *q >= 'A' && *q <= 'F' ) ucs += mult * (*q - 'A' + 10 ); - else + else return 0; mult *= 16; --q; @@ -492,7 +492,7 @@ const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXml { if ( *q >= '0' && *q <= '9' ) ucs += mult * (*q - '0'); - else + else return 0; mult *= 10; --q; @@ -571,10 +571,10 @@ bool TiXmlBase::StringEqual( const char* p, return false; } -const char* TiXmlBase::ReadText( const char* p, - TIXML_STRING * text, - bool trimWhiteSpace, - const char* endTag, +const char* TiXmlBase::ReadText( const char* p, + TIXML_STRING * text, + bool trimWhiteSpace, + const char* endTag, bool caseInsensitive, TiXmlEncoding encoding ) { @@ -631,7 +631,7 @@ const char* TiXmlBase::ReadText( const char* p, } } } - if ( p && *p ) + if ( p && *p ) p += strlen( endTag ); return p; } @@ -647,7 +647,7 @@ void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) // This "pre-streaming" will never read the closing ">" so the // sub-tag can orient itself. - if ( !StreamTo( in, '<', tag ) ) + if ( !StreamTo( in, '<', tag ) ) { SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); return; @@ -669,7 +669,7 @@ void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) if ( in->good() ) { - // We now have something we presume to be a node of + // We now have something we presume to be a node of // some sort. Identify it, and call the node to // continue streaming. TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); @@ -778,7 +778,7 @@ const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiX encoding = TIXML_ENCODING_UTF8; else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice - else + else encoding = TIXML_ENCODING_LEGACY; } @@ -796,7 +796,7 @@ const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiX } void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ +{ // The first error in a chain is more accurate - don't set again! if ( error ) return; @@ -832,7 +832,7 @@ TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) return 0; } - // What is this thing? + // What is this thing? // - Elements start with a letter or underscore, but xml is reserved. // - Comments: