]> Creatis software - clitk.git/commitdiff
Merge commit '488f24aa984ae24adc9458bf5fbf3b2351415742'
authorVivien Delmon <vivien.delmon@creatis.insa-lyon.fr>
Tue, 30 Aug 2011 13:24:27 +0000 (15:24 +0200)
committerVivien Delmon <vivien.delmon@creatis.insa-lyon.fr>
Tue, 30 Aug 2011 13:24:27 +0000 (15:24 +0200)
Conflicts:
registration/clitkBSplineDeformableRegistrationGenericFilter.txx

326 files changed:
.cvsignore [deleted file]
.gitignore [deleted file]
CMakeLists.txt
CTestConfig.cmake
Licence_CeCILL-B_V1-en.txt
build/.cvsignore [deleted file]
cmake/FindGengetopt.cmake [new file with mode: 0644]
cmake/common.cmake
cmake/gengetopt/CMakeLists.txt [new file with mode: 0644]
cmake/gengetopt/Makefile.am [new file with mode: 0644]
cmake/gengetopt/acceptedvalues.cpp [new file with mode: 0644]
cmake/gengetopt/acceptedvalues.h [new file with mode: 0644]
cmake/gengetopt/argsdef.c [new file with mode: 0644]
cmake/gengetopt/argsdef.h [new file with mode: 0644]
cmake/gengetopt/cmdline.c [new file with mode: 0644]
cmake/gengetopt/cmdline.ggo [new file with mode: 0644]
cmake/gengetopt/cmdline.h [new file with mode: 0644]
cmake/gengetopt/errorcodes.h [new file with mode: 0644]
cmake/gengetopt/fileutils.cpp [new file with mode: 0644]
cmake/gengetopt/fileutils.h [new file with mode: 0644]
cmake/gengetopt/gengetopt.cc [new file with mode: 0644]
cmake/gengetopt/gengetopt.h [new file with mode: 0644]
cmake/gengetopt/getopt.c [new file with mode: 0644]
cmake/gengetopt/getopt1.c [new file with mode: 0644]
cmake/gengetopt/ggo_options.h [new file with mode: 0644]
cmake/gengetopt/ggos.cpp [new file with mode: 0644]
cmake/gengetopt/ggos.h [new file with mode: 0644]
cmake/gengetopt/global_opts.h [new file with mode: 0644]
cmake/gengetopt/globals.cpp [new file with mode: 0644]
cmake/gengetopt/globals.h [new file with mode: 0644]
cmake/gengetopt/gm.cc [new file with mode: 0644]
cmake/gengetopt/gm.h [new file with mode: 0644]
cmake/gengetopt/gm_utils.cpp [new file with mode: 0644]
cmake/gengetopt/gm_utils.h [new file with mode: 0644]
cmake/gengetopt/gnugetopt.h [new file with mode: 0644]
cmake/gengetopt/groups.h [new file with mode: 0644]
cmake/gengetopt/include_cygwin/getopt.h [new file with mode: 0644]
cmake/gengetopt/my_map.h [new file with mode: 0644]
cmake/gengetopt/my_sstream.h [new file with mode: 0644]
cmake/gengetopt/my_string.h [new file with mode: 0644]
cmake/gengetopt/parser.cc [new file with mode: 0644]
cmake/gengetopt/parser.h [new file with mode: 0644]
cmake/gengetopt/parser.yy [new file with mode: 0644]
cmake/gengetopt/scanner.cc [new file with mode: 0644]
cmake/gengetopt/skels/Makefile.am [new file with mode: 0644]
cmake/gengetopt/skels/c_source.cc [new file with mode: 0644]
cmake/gengetopt/skels/c_source.h [new file with mode: 0644]
cmake/gengetopt/skels/check_modes.cc [new file with mode: 0644]
cmake/gengetopt/skels/check_modes.h [new file with mode: 0644]
cmake/gengetopt/skels/clear_arg.cc [new file with mode: 0644]
cmake/gengetopt/skels/clear_arg.h [new file with mode: 0644]
cmake/gengetopt/skels/clear_given.cc [new file with mode: 0644]
cmake/gengetopt/skels/clear_given.h [new file with mode: 0644]
cmake/gengetopt/skels/copyright.cc [new file with mode: 0644]
cmake/gengetopt/skels/copyright.h [new file with mode: 0644]
cmake/gengetopt/skels/custom_getopt_gen.cc [new file with mode: 0644]
cmake/gengetopt/skels/custom_getopt_gen.h [new file with mode: 0644]
cmake/gengetopt/skels/dependant_option.cc [new file with mode: 0644]
cmake/gengetopt/skels/dependant_option.h [new file with mode: 0644]
cmake/gengetopt/skels/enum_decl.cc [new file with mode: 0644]
cmake/gengetopt/skels/enum_decl.h [new file with mode: 0644]
cmake/gengetopt/skels/exit_failure.cc [new file with mode: 0644]
cmake/gengetopt/skels/exit_failure.h [new file with mode: 0644]
cmake/gengetopt/skels/file_save.cc [new file with mode: 0644]
cmake/gengetopt/skels/file_save.h [new file with mode: 0644]
cmake/gengetopt/skels/file_save_multiple.cc [new file with mode: 0644]
cmake/gengetopt/skels/file_save_multiple.h [new file with mode: 0644]
cmake/gengetopt/skels/free_list.cc [new file with mode: 0644]
cmake/gengetopt/skels/free_list.h [new file with mode: 0644]
cmake/gengetopt/skels/free_multiple.cc [new file with mode: 0644]
cmake/gengetopt/skels/free_multiple.h [new file with mode: 0644]
cmake/gengetopt/skels/free_string.cc [new file with mode: 0644]
cmake/gengetopt/skels/free_string.h [new file with mode: 0644]
cmake/gengetopt/skels/generic_option.cc [new file with mode: 0644]
cmake/gengetopt/skels/generic_option.h [new file with mode: 0644]
cmake/gengetopt/skels/given_field.cc [new file with mode: 0644]
cmake/gengetopt/skels/given_field.h [new file with mode: 0644]
cmake/gengetopt/skels/group_counter.cc [new file with mode: 0644]
cmake/gengetopt/skels/group_counter.h [new file with mode: 0644]
cmake/gengetopt/skels/group_option.cc [new file with mode: 0644]
cmake/gengetopt/skels/group_option.h [new file with mode: 0644]
cmake/gengetopt/skels/handle_help.cc [new file with mode: 0644]
cmake/gengetopt/skels/handle_help.h [new file with mode: 0644]
cmake/gengetopt/skels/handle_version.cc [new file with mode: 0644]
cmake/gengetopt/skels/handle_version.h [new file with mode: 0644]
cmake/gengetopt/skels/header.cc [new file with mode: 0644]
cmake/gengetopt/skels/header.h [new file with mode: 0644]
cmake/gengetopt/skels/init_args_info.cc [new file with mode: 0644]
cmake/gengetopt/skels/init_args_info.h [new file with mode: 0644]
cmake/gengetopt/skels/multiple_fill_array.cc [new file with mode: 0644]
cmake/gengetopt/skels/multiple_fill_array.h [new file with mode: 0644]
cmake/gengetopt/skels/multiple_opt_list.cc [new file with mode: 0644]
cmake/gengetopt/skels/multiple_opt_list.h [new file with mode: 0644]
cmake/gengetopt/skels/option_arg.cc [new file with mode: 0644]
cmake/gengetopt/skels/option_arg.h [new file with mode: 0644]
cmake/gengetopt/skels/print_help_string.cc [new file with mode: 0644]
cmake/gengetopt/skels/print_help_string.h [new file with mode: 0644]
cmake/gengetopt/skels/required_option.cc [new file with mode: 0644]
cmake/gengetopt/skels/required_option.h [new file with mode: 0644]
cmake/gengetopt/skels/reset_group.cc [new file with mode: 0644]
cmake/gengetopt/skels/reset_group.h [new file with mode: 0644]
cmake/gengetopt/skels/update_given.cc [new file with mode: 0644]
cmake/gengetopt/skels/update_given.h [new file with mode: 0644]
cmake/gengetopt/yyerror.cc [new file with mode: 0644]
cmake/gengetopt/yyerror.h [new file with mode: 0644]
cmake/gengetopt/yywrap.c [new file with mode: 0644]
common/CMakeLists.txt
common/clitkCommon.cxx
common/clitkConfiguration.h.in
common/clitkDD.h
common/clitkDicomRT_Contour.cxx
common/clitkDicomRT_ROI.cxx
common/clitkDicomRT_ROI.h
common/clitkDicomRT_ROI_ConvertToImageFilter.cxx
common/clitkDicomRT_StructureSet.cxx
common/clitkImageCommon.h
common/clitkImageCommon.txx
common/clitkImageToImageGenericFilterBase.cxx
common/clitkImageToImageGenericFilterBase.h
common/clitkXdrImageIOReader.cxx
common/vvFromITK.h
common/vvImage.txx
common/vvImageReader.cxx
common/vvImageReader.h
common/vvImageReader.txx
itk/RelativePositionPropImageFilter.h
itk/clitkAddRelativePositionConstraintToLabelImageFilter.txx
itk/clitkAutoCropFilter.txx
itk/clitkBackProjectImageFilter.h
itk/clitkBackProjectImageFilter.txx
itk/clitkComposeVFFilter.txx
itk/clitkConditionalBinaryDilateImageFilter.txx
itk/clitkConditionalGrayscaleDilateImageFilter.h [new file with mode: 0644]
itk/clitkConditionalGrayscaleDilateImageFilter.txx [new file with mode: 0644]
itk/clitkCropLikeImageFilter.txx
itk/clitkDecomposeThroughErosionImageFilter.h
itk/clitkExtractSliceFilter.txx
itk/clitkForwardWarpImageFilter.txx
itk/clitkReconstructThroughDilationImageFilter.h
itk/clitkReconstructThroughDilationImageFilter.txx
itk/clitkReconstructWithConditionalGrayscaleDilateImageFilter.h [new file with mode: 0644]
itk/clitkReconstructWithConditionalGrayscaleDilateImageFilter.txx [new file with mode: 0644]
itk/clitkResampleImageWithOptionsFilter.txx
itk/clitkSegmentationUtils.h
itk/clitkSegmentationUtils.txx
itk/clitkSliceBySliceRelativePositionFilter.txx
itk/itkRayCastInterpolateImageFunctionWithOrigin.txx
license-header.txt
notes.org~ [deleted file]
registration/CMakeLists.txt
registration/clitkBLUTDIRGenericFilter.cxx
registration/clitkBLUTDIRGenericFilter.h
registration/clitkBSplineDeformableRegistrationGenericFilter.txx
registration/clitkBSplineDeformableTransform.h
registration/clitkBSplineDeformableTransform.txx
registration/clitkBSplineDeformableTransformInitializer.txx
registration/clitkConvertBSplineDeformableTransformToVFGenericFilter.cxx
registration/clitkConvertBSplineDeformableTransformToVFGenericFilter.h
registration/clitkCorrelationRatioImageToImageMetric.txx
registration/clitkDeformationFieldTransform.h
registration/clitkDeformationFieldTransform.txx
registration/clitkDemonsDeformableRegistrationGenericFilter.txx
registration/clitkGenericMetric.txx
registration/clitkMatrixTransformToVFGenericFilter.h
registration/clitkMatrixTransformToVFGenericFilter.txx
registration/clitkMultiResolutionPDEDeformableRegistration.txx
registration/clitkMultipleBSplineDeformableTransform.h
registration/clitkMultipleBSplineDeformableTransform.txx
registration/clitkMultipleBSplineDeformableTransformInitializer.txx
registration/clitkNormalizedCorrelationImageToImageMetric.txx
registration/clitkNormalizedCorrelationImageToImageMetricFor3DBLUTFFD.txx
registration/clitkPointListTransform.h
registration/clitkPointListTransform.txx
registration/clitkShapedBLUTSpatioTemporalDIRGenericFilter.txx
registration/clitkShapedBLUTSpatioTemporalDeformableTransform.h
registration/clitkShapedBLUTSpatioTemporalDeformableTransform.txx
registration/clitkShapedBLUTSpatioTemporalDeformableTransformInitializer.txx
registration/itkMattesMutualInformationImageToImageMetricFor3DBLUTFFD.h
registration/itkMattesMutualInformationImageToImageMetricFor3DBLUTFFD.txx
registration/itkMeanSquaresImageToImageMetricFor3DBLUTFFD.txx
scripts/create_mhd_3D.sh [new file with mode: 0755]
scripts/create_mhd_4D-2.0.sh [new file with mode: 0755]
scripts/create_mhd_4D.sh [moved from vv/scripts/create_mhd_4D.sh with 74% similarity]
scripts/create_mhd_4D_pattern.sh [new file with mode: 0755]
scripts/create_midP-2.0.sh [new file with mode: 0755]
scripts/create_midP.sh [new file with mode: 0755]
scripts/create_midP_masks-2.0.sh [new file with mode: 0755]
scripts/create_midP_masks.sh [new file with mode: 0755]
scripts/create_sequence.sh [moved from vv/scripts/create_sequence.sh with 91% similarity]
scripts/dcm_sort_by_field.sh [moved from vv/scripts/dcm_sort_by_field.sh with 100% similarity]
scripts/dicom_info.sh [moved from vv/scripts/dicom_info.sh with 100% similarity]
scripts/midp_common.sh [new file with mode: 0755]
scripts/midp_template.conf [new file with mode: 0644]
scripts/pts_to_landmarks.sh [new file with mode: 0755]
scripts/registration.sh [new file with mode: 0755]
segmentation/.gitignore [deleted file]
segmentation/CMakeLists.txt
segmentation/clitkAnatomicalFeatureDatabase.cxx
segmentation/clitkAnatomicalFeatureDatabase.h
segmentation/clitkBool.cxx [new file with mode: 0644]
segmentation/clitkBool.ggo [new file with mode: 0644]
segmentation/clitkBooleanOperatorLabelImageGenericFilter.h [new file with mode: 0644]
segmentation/clitkBooleanOperatorLabelImageGenericFilter.txx [new file with mode: 0644]
segmentation/clitkDecomposeAndReconstructImageFilter.h [deleted file]
segmentation/clitkDecomposeAndReconstructImageFilter.txx [deleted file]
segmentation/clitkDecomposeThroughErosionImageFilter.h [deleted file]
segmentation/clitkDecomposeThroughErosionImageFilter.txx [deleted file]
segmentation/clitkExtractImageFilter.h [deleted file]
segmentation/clitkExtractImageFilter.txx [deleted file]
segmentation/clitkExtractLung.ggo
segmentation/clitkExtractLungFilter.h
segmentation/clitkExtractLungFilter.txx
segmentation/clitkExtractLungGenericFilter.txx
segmentation/clitkExtractLymphStation_2RL.txx
segmentation/clitkExtractLymphStation_7.txx
segmentation/clitkExtractLymphStation_8.txx
segmentation/clitkExtractLymphStation_Supports.txx [new file with mode: 0644]
segmentation/clitkExtractLymphStations.ggo
segmentation/clitkExtractLymphStationsFilter.h
segmentation/clitkExtractLymphStationsFilter.txx
segmentation/clitkExtractLymphStationsGenericFilter.txx
segmentation/clitkExtractMediastinalVessels.cxx [new file with mode: 0644]
segmentation/clitkExtractMediastinalVessels.ggo [new file with mode: 0644]
segmentation/clitkExtractMediastinalVesselsFilter.h [new file with mode: 0644]
segmentation/clitkExtractMediastinalVesselsFilter.txx [new file with mode: 0644]
segmentation/clitkExtractMediastinalVesselsGenericFilter.h [new file with mode: 0644]
segmentation/clitkExtractMediastinalVesselsGenericFilter.txx [new file with mode: 0644]
segmentation/clitkExtractMediastinum.ggo
segmentation/clitkExtractMediastinumFilter.h
segmentation/clitkExtractMediastinumFilter.txx
segmentation/clitkExtractMediastinumGenericFilter.txx
segmentation/clitkExtractPatient.ggo
segmentation/clitkExtractPatientFilter.h
segmentation/clitkExtractPatientFilter.txx
segmentation/clitkExtractPatientGenericFilter.txx
segmentation/clitkMorphoMathFilter.txx
segmentation/clitkMotionMaskGenericFilter.txx
segmentation/clitkReconstructThroughDilationImageFilter.h [deleted file]
segmentation/clitkReconstructThroughDilationImageFilter.txx [deleted file]
tests/CMakeLists.txt
tests/tools/CMakeLists.txt
tests/tools/clitkImageInfoTest.cxx [deleted file]
tests/tools/clitkWriteDicomSeriesTest.cxx [deleted file]
tests/tools/toolTestRunner.cxx [new file with mode: 0644]
tools/.cvsignore [deleted file]
tools/CMakeLists.txt
tools/clitkAffineTransform.ggo
tools/clitkAffineTransformGenericFilter.txx
tools/clitkBSplineCoefficientsToValuesGenericFilter.h
tools/clitkBSplineCoefficientsToValuesGenericFilter.txx
tools/clitkBinaryImageToMesh.cxx [new file with mode: 0644]
tools/clitkBinaryImageToMesh.ggo [new file with mode: 0644]
tools/clitkConeBeamProjectImage.ggo
tools/clitkConeBeamProjectImageFilter.h
tools/clitkConeBeamProjectImageFilter.txx
tools/clitkConeBeamProjectImageGenericFilter.cxx
tools/clitkCropImage.cxx
tools/clitkCropImage.ggo
tools/clitkCropImageGenericFilter.cxx
tools/clitkDicomRTStruct2BinaryImage.cxx
tools/clitkDicomRTStruct2BinaryImage.ggo
tools/clitkImageArithm.ggo
tools/clitkImageArithmGenericFilter.txx
tools/clitkImageConvert.cxx
tools/clitkImageConvert.ggo
tools/clitkImageExtractLine.cxx
tools/clitkInvertVFGenericFilter.h
tools/clitkInvertVFGenericFilter.txx
tools/clitkJacobianImage.cxx [new file with mode: 0644]
tools/clitkJacobianImage.ggo [new file with mode: 0644]
tools/clitkJacobianImageGenericFilter.cxx [moved from vv/vvMainWindow.txx with 90% similarity]
tools/clitkJacobianImageGenericFilter.h [new file with mode: 0644]
tools/clitkJacobianImageGenericFilter.txx [new file with mode: 0644]
tools/clitkMakeSphereImage.cxx [new file with mode: 0644]
tools/clitkMedianTemporalDimensionGenericFilter.txx
tools/clitkMeshViewer.cxx [new file with mode: 0644]
tools/clitkMeshViewer.ggo [new file with mode: 0644]
tools/clitkPadImage.cxx [new file with mode: 0644]
tools/clitkPadImage.ggo [new file with mode: 0644]
tools/clitkSplitImageGenericFilter.cxx
tools/clitkTransformLandmarks.cxx
tools/clitkTransformLandmarks.ggo
tools/clitkWarpImageGenericFilter.txx
vv/.gitignore [deleted file]
vv/CMakeLists.txt
vv/License.txt
vv/icons/identity.png [new file with mode: 0644]
vv/icons/weNeedYou.png [new file with mode: 0644]
vv/qt_ui/vvHelpDialog.ui
vv/qt_ui/vvMainWindow.ui
vv/qt_ui/vvOverlayPanel.ui
vv/qt_ui/vvRegisterForm.ui [new file with mode: 0644]
vv/scripts/transfer_patients.sh [deleted file]
vv/vv.cxx
vv/vvConfiguration.h.in [new file with mode: 0644]
vv/vvIcons.qrc
vv/vvImageContour.cxx
vv/vvImageContour.h
vv/vvImageWarp.cxx
vv/vvInfoPanel.cxx
vv/vvInfoPanel.h
vv/vvMainWindow.cxx
vv/vvMainWindow.h
vv/vvMesh.cxx
vv/vvMeshReader.cxx
vv/vvMidPosition.cxx
vv/vvOverlayPanel.cxx
vv/vvOverlayPanel.h
vv/vvRegisterForm.cxx [new file with mode: 0644]
vv/vvRegisterForm.h [new file with mode: 0644]
vv/vvSlicer.cxx
vv/vvSlicer.h
vv/vvSlicerManager.cxx
vv/vvSlicerManager.h
vv/vvSlicerManagerCommand.cxx
vv/vvToolBinarize.cxx
vv/vvToolBinarize.h
vv/vvToolCreatorBase.cxx
vv/vvToolCropImage.cxx
vv/vvToolCropImage.h
vv/vvToolManager.cxx
vv/vvToolManager.h
vv/vvToolStructureSetManager.cxx
vv/vvUtils.cxx
vv/vvUtils.h
vv/write.php [new file with mode: 0644]

diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644 (file)
index db9f634..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-*.kdev4
-.git
-CVS
-mctools
-*.swp
-Makefile
-tags
-doc
-*.directory
-build/*
-*/.vimrc
diff --git a/.gitignore b/.gitignore
deleted file mode 100644 (file)
index c4986b3..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-CVS
-tests_jef
-mctools
-*.swp
-Makefile
-tags
-doc
-CVS
-CMakeFiles
-CMakeCache.txt
-*_ggo.*
-*.directory
-build/*
-*/.vimrc
-_*
-#*#
-notes.org
-build-release
-build-debug
-segmentation/clitkTestFilter*
index 3bb462c26acc90387183a7e32ac844e5bc32f87d..48f125772db517ac6d22b08b3a8ba6169fcf6f14 100644 (file)
@@ -1,7 +1,7 @@
 #=========================================================
 # CLITK = Command Line ITK
-cmake_minimum_required(VERSION 2.4)
-cmake_policy(VERSION 2.4)
+cmake_minimum_required(VERSION 2.8)
+cmake_policy(VERSION 2.8)
 if(COMMAND cmake_policy)
     cmake_policy(SET CMP0003 NEW)
 endif(COMMAND cmake_policy)
@@ -12,6 +12,15 @@ PROJECT(clitk)
 INCLUDE(cmake/common.cmake)
 #=========================================================
 
+#=========================================================
+#Support for the CTest dashboard testing system
+OPTION(BUILD_TESTING "Build the testing tree" OFF)
+IF (BUILD_TESTING)
+  OPTION(CLITK_BUILD_TESTING "Test ITK" ON)
+  INCLUDE(CTest)
+ENDIF(BUILD_TESTING)
+#=========================================================
+
 #=========================================================
 # Find ITK (required)
 FIND_PACKAGE(ITK)
@@ -33,18 +42,16 @@ ENDIF(VTK_FOUND)
 #=========================================================
 
 #=========================================================
-# Find gengetopt
-FIND_PATH(CLITK_GENGETOPT gengetopt)
-IF (CLITK_GENGETOPT STREQUAL "CLITK_GENGETOPT-NOTFOUND")
-  MESSAGE("gengetopt not found, please install it (see http://www.gnu.org/software/gengetopt/gengetopt.html)")
-ENDIF (CLITK_GENGETOPT STREQUAL "CLITK_GENGETOPT-NOTFOUND")
+# Find gengetopt, will create a target exe if not found
+SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
+FIND_PACKAGE(Gengetopt)
 #=========================================================
 
 #=========================================================
 # Find libstatgrab is installed, add clitkMemoryUsage.cxx in the library
 FIND_LIBRARY(LIBSTATGRAB NAMES statgrab PATHS)
 IF (${LIBSTATGRAB} MATCHES "LIBSTATGRAB-NOTFOUND")
-  MESSAGE("Install libstatgrab (http://www.i-scream.org/libstatgrab/) for memory usage information")
+#  MESSAGE("Install libstatgrab (http://www.i-scream.org/libstatgrab/) for memory usage information")
   SET(CLITK_MEMORY_INFO OFF)
 ELSE (${LIBSTATGRAB} MATCHES "LIBSTATGRAB-NOTFOUND")
   SET(CLITK_MEMORY_INFO ON)
@@ -80,9 +87,9 @@ INCLUDE_DIRECTORIES(itk filters segmentation registration tools ${PROJECT_BINARY
 
 # Select what is compiled
 ADD_SUBDIRECTORY(common)
-add_subdirectory(tools)
-add_subdirectory(segmentation)
-add_subdirectory(registration)
+ADD_SUBDIRECTORY(tools)
+ADD_SUBDIRECTORY(segmentation)
+ADD_SUBDIRECTORY(registration)
 
 
 # Compilation options
@@ -98,14 +105,24 @@ ENDIF(CLITK_BUILD_VV)
 
 
 #=========================================================
-#Support for the CTest dashboard testing system
-INCLUDE(CTest)
-#=========================================================
-IF (BUILD_TESTING)
+# Build test when vv has been compiled
+IF(BUILD_TESTING)
   ADD_SUBDIRECTORY(tests)
 ENDIF(BUILD_TESTING)
-#=========================================================
-
 
 #=========================================================
+# Install scripts when running make install
+SET(SCRIPTS 
+  scripts/midp_common.sh
+  scripts/registration.sh
+  scripts/create_midP.sh
+  scripts/create_midP-2.0.sh        
+  scripts/create_mhd_4D.sh          
+  scripts/create_mhd_4D_pattern.sh  
+  scripts/create_midP_masks.sh  
+  scripts/create_midP_masks-2.0.sh  
+  scripts/pts_to_landmarks.sh
+)
+
+INSTALL (FILES ${SCRIPTS} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
 
index 81c2402c7bf69dd79e15511501fee62f03eddbab..15bbadd615cfa17269b85c13408d813e1e3237dc 100644 (file)
@@ -1,7 +1,12 @@
-set(CTEST_PROJECT_NAME "vv_itk4")
-set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
+MACRO(SET_IF_NOT_SET var val)
+  IF(NOT DEFINED "${var}")
+    SET("${var}" "${val}")
+  ENDIF(NOT DEFINED "${var}")
+ENDMACRO(SET_IF_NOT_SET)
 
-set(CTEST_DROP_METHOD "http")
-set(CTEST_DROP_SITE "www.cdash.org")
-set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Insight")
-set(CTEST_DROP_SITE_CDASH TRUE)
+# Those are set for running a classical make Experimental
+SET_IF_NOT_SET(CTEST_DROP_METHOD "http")
+SET_IF_NOT_SET(CTEST_DROP_SITE "my.cdash.org")
+SET_IF_NOT_SET(CTEST_DROP_LOCATION "/submit.php?project=VV")
+SET_IF_NOT_SET(CTEST_DROP_SITE_CDASH TRUE)
+SET_IF_NOT_SET(CTEST_PROJECT_NAME "vv_itk4")
index fc5e8141bc9fa3797d4d0f74b16d64a3200cc7db..3ad4deaa3c84895c0ac4e6e7c74902b31d7b6e94 100644 (file)
@@ -1,20 +1,3 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to:
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
 
 CeCILL-B FREE SOFTWARE LICENSE AGREEMENT
 
diff --git a/build/.cvsignore b/build/.cvsignore
deleted file mode 100644 (file)
index 72e8ffc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-*
diff --git a/cmake/FindGengetopt.cmake b/cmake/FindGengetopt.cmake
new file mode 100644 (file)
index 0000000..aecb1fc
--- /dev/null
@@ -0,0 +1,34 @@
+
+# Attempt to find gengetopt. If not found, compile it.
+FIND_PROGRAM(GENGETOPT gengetopt)
+IF (GENGETOPT STREQUAL "GENGETOPT-NOTFOUND")
+  ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/cmake/gengetopt)
+ELSE(GENGETOPT STREQUAL "GENGETOPT-NOTFOUND")
+  ADD_EXECUTABLE(gengetopt IMPORTED)
+  SET_PROPERTY(TARGET gengetopt PROPERTY IMPORTED_LOCATION ${GENGETOPT})
+ENDIF(GENGETOPT STREQUAL "GENGETOPT-NOTFOUND")
+
+MACRO (WRAP_GGO GGO_SRCS)
+  FOREACH(GGO_FILE ${ARGN})
+    GET_FILENAME_COMPONENT(GGO_BASEFILENAME ${GGO_FILE} NAME_WE)
+    GET_FILENAME_COMPONENT(GGO_FILE_ABS ${GGO_FILE} ABSOLUTE)
+    SET(GGO_H ${GGO_BASEFILENAME}_ggo.h)
+    SET(GGO_C ${GGO_BASEFILENAME}_ggo.c)
+    SET(GGO_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${GGO_H} ${CMAKE_CURRENT_BINARY_DIR}/${GGO_C})
+    ADD_CUSTOM_COMMAND(OUTPUT ${GGO_OUTPUT}
+                       COMMAND gengetopt
+                       ARGS < ${GGO_FILE_ABS}
+                              --output-dir=${CMAKE_CURRENT_BINARY_DIR}
+                              --arg-struct-name=args_info_${GGO_BASEFILENAME}
+                              --func-name=cmdline_parser_${GGO_BASEFILENAME}
+                              --file-name=${GGO_BASEFILENAME}_ggo
+                              --unamed-opts
+                              --conf-parser
+                              --include-getopt
+                       DEPENDS ${GGO_FILE_ABS}
+                      )
+    SET(${GGO_SRCS} ${${GGO_SRCS}} ${GGO_OUTPUT})
+    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+  ENDFOREACH(GGO_FILE)
+  SET_SOURCE_FILES_PROPERTIES(${${GGO_SRCS}} PROPERTIES GENERATED TRUE)
+ENDMACRO (WRAP_GGO)
index eeb8755cf51f6455438dcd820478624f742ab58d..3239e966efa3e5dd121bfdfc4baa97fcbb1b4d55 100644 (file)
@@ -3,35 +3,8 @@ MACRO (DD in)
     MESSAGE(${in}=${${in}})
 ENDMACRO(DD)
 #=========================================================
-# Process ggo (gengetopt) files (http://www.gnu.org/software/gengetopt/)
-MACRO (WRAP_GGO GGO_SRCS)
-    FOREACH(GGO_FILE ${ARGN})
-        GET_FILENAME_COMPONENT(GGO_BASEFILENAME ${GGO_FILE} NAME_WE)
-        GET_FILENAME_COMPONENT(GGO_FILE_ABS ${GGO_FILE} ABSOLUTE)
-        SET(GGO_H ${GGO_BASEFILENAME}_ggo.h)
-        SET(GGO_C ${GGO_BASEFILENAME}_ggo.c)
-        SET(GGO_OUTPUT ${GGO_H} ${GGO_C})
-        ADD_CUSTOM_COMMAND(OUTPUT ${GGO_OUTPUT}
-                           COMMAND ${CLITK_GENGETOPT}/gengetopt
-                           ARGS < ${GGO_FILE_ABS}
-                                  --output-dir=${CMAKE_CURRENT_BINARY_DIR}
-                                  --arg-struct-name=args_info_${GGO_BASEFILENAME}
-                                  --func-name=cmdline_parser_${GGO_BASEFILENAME}
-                                  --file-name=${GGO_BASEFILENAME}_ggo
-                                  --unamed-opts
-                                  --conf-parser
-                                  --include-getopt
-                           DEPENDS ${GGO_FILE}
-                          )  
-       SET(${GGO_SRCS} ${${GGO_SRCS}} ${CMAKE_CURRENT_BINARY_DIR}/${GGO_BASEFILENAME}_ggo.c)
-       INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})  #For _ggo.h includes
-    ENDFOREACH(GGO_FILE)
-    SET_SOURCE_FILES_PROPERTIES(${${GGO_SRCS}} PROPERTIES GENERATED TRUE)
-ENDMACRO (WRAP_GGO)
 
-# Reproduce old mechanism with new macro for ggo files (for the time being)
-FILE(GLOB ALL_GGO_FILES *.ggo)
-#WRAP_GGO(ALL_GGO_SRCS ${ALL_GGO_FILES})
+
 #=========================================================
 #Set a reasonable build mode default if the user hasn't set any
 if (NOT CMAKE_BUILD_TYPE)
diff --git a/cmake/gengetopt/CMakeLists.txt b/cmake/gengetopt/CMakeLists.txt
new file mode 100644 (file)
index 0000000..84443f0
--- /dev/null
@@ -0,0 +1,63 @@
+# Gengetopt: http://www.gnu.org/software/gengetopt/
+
+ADD_DEFINITIONS(-DPACKAGE=\"gengetopt\")
+ADD_DEFINITIONS(-DVERSION=\"2.22.4\")
+ADD_DEFINITIONS(-DHAVE_SSTREAM)
+ADD_DEFINITIONS(-DHAVE_NAMESPACES)
+
+IF(WIN32)
+  ADD_DEFINITIONS(-DHAVE_STRING_H)
+  ADD_DEFINITIONS(-DYY_NO_UNISTD_H)
+  ADD_DEFINITIONS(-Disatty=!)
+  INCLUDE_DIRECTORIES(include_cygwin)
+ENDIF(WIN32)
+
+ADD_EXECUTABLE(gengetopt 
+  ./cmdline.c
+  ./ggos.cpp
+  ./scanner.cc
+  ./skels/required_option.cc
+  ./skels/handle_version.cc
+  ./skels/generic_option.cc
+  ./skels/clear_arg.cc
+  ./skels/update_given.cc
+  ./skels/dependant_option.cc
+  ./skels/custom_getopt_gen.cc
+  ./skels/handle_help.cc
+  ./skels/given_field.cc
+  ./skels/init_args_info.cc
+  ./skels/multiple_opt_list.cc
+  ./skels/free_list.cc
+  ./skels/exit_failure.cc
+  ./skels/clear_given.cc
+  ./skels/free_multiple.cc
+  ./skels/enum_decl.cc
+  ./skels/reset_group.cc
+  ./skels/c_source.cc
+  ./skels/group_option.cc
+  ./skels/file_save.cc
+  ./skels/check_modes.cc
+  ./skels/copyright.cc
+  ./skels/option_arg.cc
+  ./skels/group_counter.cc
+  ./skels/free_string.cc
+  ./skels/header.cc
+  ./skels/print_help_string.cc
+  ./skels/multiple_fill_array.cc
+  ./skels/file_save_multiple.cc
+  ./fileutils.cpp
+  ./getopt.c
+  ./gm.cc
+  ./globals.cpp
+  ./yywrap.c
+  ./getopt1.c
+  ./argsdef.c
+  ./gm_utils.cpp
+  ./acceptedvalues.cpp
+  ./gengetopt.cc
+  ./yyerror.cc
+  ./parser.cc)
+
+INCLUDE_DIRECTORIES(.)
+INCLUDE_DIRECTORIES(skels)
+#INCLUDE_DIRECTORIES(includes)
diff --git a/cmake/gengetopt/Makefile.am b/cmake/gengetopt/Makefile.am
new file mode 100644 (file)
index 0000000..091008f
--- /dev/null
@@ -0,0 +1,115 @@
+# Copyright (C) 1999-2009  Free Software Foundation, Inc.
+#  
+# This file is part of GNU gengetopt 
+#
+# GNU gengetopt is free software; you can redistribute it and/or modify 
+# it under the terms of the GNU General Public License as published by 
+# the Free Software Foundation; either version 3, or (at your option) 
+# any later version. 
+#
+# GNU gengetopt is distributed in the hope that it will be useful, but 
+# WITHOUT ANY WARRANTY; without even the implied warranty of 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. 
+#
+# You should have received a copy of the GNU General Public License along 
+# with gengetopt; see the file COPYING. If not, write to the Free Software 
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+
+SUBDIRS = includes skels tests
+
+#INCLUDES = -I@top_srcdir@/src/skels
+
+SUFFIXES = .text .c .ggo
+
+.text.o:
+       $(TXTC) $<
+
+bin_PROGRAMS = gengetopt
+
+noinst_LTLIBRARIES = libgengetopt.la
+
+libgengetopt_la_SOURCES = parser.cc scanner.cc \
+globals.cpp \
+argsdef.c cmdline.ggo gm.cc \
+yyerror.cc gm_utils.cpp fileutils.cpp acceptedvalues.cpp ggos.cpp
+
+gengetopt_SOURCES = gengetopt.cc
+
+scanner.cc: $(srcdir)/scanner.ll
+       $(LEX) $(LFLAGS) -o $(srcdir)/scanner.cc $(srcdir)/scanner.ll
+
+parser.cc: $(srcdir)/parser.yy
+       $(YACC) -o $(srcdir)/parser.cc $(srcdir)/parser.yy --defines=$(srcdir)/parser.h
+
+#gengetopt_LDADD = @LIBOBJS@ @LEXLIB@ skels/libgen.a
+
+# these are for gnulib
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_builddir)/gl
+
+libgengetopt_la_LIBADD = $(top_builddir)/gl/libgnu.la \
+       @LTLIBOBJS@ \
+       skels/libgen.la
+
+LDADD = $(top_builddir)/src/libgengetopt.la
+
+EXTRA_DIST = parser.h argsdef.h gengetopt.h ggos.h gm.h gnugetopt.h \
+cmdline.c cmdline.h my_sstream.h my_string.h my_map.h \
+global_opts.h \
+ggo_options.h \
+groups.h \
+parser.yy scanner.ll \
+globals.h \
+$(pkgdata_DATA)
+
+# version of gengetopt linked to the ElectricFence library
+# don't use it anymore: use valgrind
+#EXTRA_PROGRAMS = gengetopt-efence
+#gengetopt_efence_SOURCES = $(gengetopt_SOURCES)
+#gengetopt_efence_LDADD = -lefence $(gengetopt_LDADD)
+
+PROGNAME = $(top_builddir)/src/gengetopt$(EXEEXT)
+
+# to have flex generate a case insensitive scanner
+AM_LFLAGS = -i
+
+# it may happen, usually if the sources have been downloaded from CVS
+# repository, that cmdline.ggo is more recent than cmdline.c, but
+# cmdline.c cannot be re-generated, even because gengetopt has
+# to be built first. For instance if you only change spaces in cmdline.ggo
+# cmdline.c will not be different, and thus it is not updated in the CVS
+# repository; then when you make a checkout on another place, make
+# would try to build cmdline.c, but to do this it would need gengetopt
+# which is not built yet; so we simply touch cmdline.c (and this is safe)
+
+.ggo.c:
+       if test -f $(PROGNAME); then \
+       $(PROGNAME) --input=$< --output-dir=$(srcdir) ; \
+       else touch $(srcdir)/$@ ; fi
+
+cmdline.h: cmdline.c
+
+BUILT_SOURCES = cmdline.h cmdline.c parser.cc scanner.cc
+
+# automatically generate gengetopt_strdup() from the replacement function
+# strdup().
+# gengetopt_strdup.text: strdup.c
+#      echo "/* gengetopt_strdup(): automatically generated from strdup.c. */" > $@
+#      cat strdup.c | sed -e 's/^strdup (/gengetopt_&/' \
+#               -e 's/^char \* *$$/&/' \
+#               -e '/^#include.*$$/D' -e '/^$$/D' >> $@
+
+# we distribute these files because who uses gengetopt might need them
+# these are installed in $(prefix)/share/gengetopt
+pkgdata_DATA = gnugetopt.h getopt.c getopt1.c
+
+# yywrap.c is added only if it is not found on lex (flex) lib, and will be
+# added automatically by automake
+
+# automake (maybe due to a bug) doesn't added these files well,
+# so we explicitely declare them
+MAINTAINERCLEANFILES = scanner.cc parser.h parser.cc 
+
+noinst_HEADERS = acceptedvalues.h errorcodes.h fileutils.h \
+       gm_utils.h yyerror.h
+
diff --git a/cmake/gengetopt/acceptedvalues.cpp b/cmake/gengetopt/acceptedvalues.cpp
new file mode 100644 (file)
index 0000000..ea66c0a
--- /dev/null
@@ -0,0 +1,44 @@
+//
+// C++ Implementation: acceptedvalues
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "acceptedvalues.h"
+#include "my_sstream.h"
+
+using namespace std;
+
+void
+AcceptedValues::insert(const string &s)
+{
+  push_back(s);
+  values.insert(s);
+}
+
+bool
+AcceptedValues::contains(const string &s) const
+{
+  return (values.count(s) > 0);
+}
+
+const string
+AcceptedValues::toString(bool escape) const
+{
+  ostringstream buf;
+
+  for (const_iterator it = begin(); it != end(); ) {
+    buf << (escape ? "\\\"" : "\"") << *it
+        << (escape ? "\\\"" : "\"");
+    if (++it != end())
+      buf << ", ";
+  }
+
+  return buf.str();
+}
diff --git a/cmake/gengetopt/acceptedvalues.h b/cmake/gengetopt/acceptedvalues.h
new file mode 100644 (file)
index 0000000..d6a3d08
--- /dev/null
@@ -0,0 +1,40 @@
+//
+// C++ Interface: acceptedvalues
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef ACCEPTEDVALUES_H
+#define ACCEPTEDVALUES_H
+
+#include <list>
+#include <set>
+#include <string>
+
+/**
+the values that can be passed to an option
+
+@author Lorenzo Bettini
+*/
+class AcceptedValues : protected std::list<std::string>
+{
+  private:
+    typedef std::set<std::string> value_set;
+    value_set values;
+  
+  public:
+    using std::list<std::string>::const_iterator;
+    using std::list<std::string>::begin;
+    using std::list<std::string>::end;
+
+    void insert(const std::string &s);
+    const std::string toString(bool escape = true) const;
+    bool contains(const std::string &s) const;
+};
+
+#endif
diff --git a/cmake/gengetopt/argsdef.c b/cmake/gengetopt/argsdef.c
new file mode 100644 (file)
index 0000000..4b9af45
--- /dev/null
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt 
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU General Public License as published by 
+ * the Free Software Foundation; either version 3, or (at your option) 
+ * any later version. 
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details. 
+ *
+ * You should have received a copy of the GNU General Public License along 
+ * with gengetopt; see the file COPYING. If not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#include "argsdef.h"
+
+const char * arg_names [] = { (const char*)0, (const char*)0, "STRING", "INT",
+        "SHORT", "LONG", "FLOAT", "DOUBLE", "LONGDOUBLE", "LONGLONG", "ENUM" };
+
+const char * arg_type_constants [] = { "ARG_NO", "ARG_FLAG", "ARG_STRING",
+        "ARG_INT", "ARG_SHORT", "ARG_LONG", "ARG_FLOAT", "ARG_DOUBLE",
+        "ARG_LONGDOUBLE", "ARG_LONGLONG", "ARG_ENUM" };
+
+const char * arg_types [] = { (const char*)0, "int", "char *", "int", "short",
+        "long", "float", "double", "long double", "long long int", "enum" };
+
+const char * arg_types_names [] = { (const char*)0, "int", "string", "int",
+        "short", "long", "float", "double", "longdouble", "longlong", "int" };
+
diff --git a/cmake/gengetopt/argsdef.h b/cmake/gengetopt/argsdef.h
new file mode 100644 (file)
index 0000000..d296473
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt 
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU General Public License as published by 
+ * the Free Software Foundation; either version 3, or (at your option) 
+ * any later version. 
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details. 
+ *
+ * You should have received a copy of the GNU General Public License along 
+ * with gengetopt; see the file COPYING. If not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef GENGETOPT_ARGSDEF_H
+#define GENGETOPT_ARGSDEF_H
+
+#define ARG_NO         0
+#define ARG_FLAG       1
+#define ARG_STRING     2
+#define ARG_INT                3
+#define ARG_SHORT      4
+#define ARG_LONG       5
+#define ARG_FLOAT      6
+#define ARG_DOUBLE     7
+#define ARG_LONGDOUBLE 8
+#define ARG_LONGLONG   9
+#define ARG_ENUM    10
+
+/** corresponding strings for above defines */
+extern const char * arg_type_constants [];
+/** symbolic names for argument types */
+extern const char * arg_names [];
+/** corresponding C types */
+extern const char * arg_types [];
+/** string representation of types */
+extern const char * arg_types_names [];
+
+#define ARGS_STRUCT "args_info"
+
+#endif /* GENGETOPT_ARGSDEF_H */
+
diff --git a/cmake/gengetopt/cmdline.c b/cmake/gengetopt/cmdline.c
new file mode 100644 (file)
index 0000000..1e7523c
--- /dev/null
@@ -0,0 +1,1287 @@
+/*
+  File autogenerated by gengetopt version 2.22.4
+  generated with the following command:
+  ../src/gengetopt --input=../../src/cmdline.ggo --output-dir=../../src --no-handle-version --no-handle-help --no-handle-error --string-parser
+
+  The developers of gengetopt consider the fixed text that goes in all
+  gengetopt output files to be in the public domain:
+  we make no copyright claims on it.
+*/
+
+/* If we use autoconf.  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef FIX_UNUSED
+#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
+#endif
+
+#include <getopt.h>
+
+#include "cmdline.h"
+
+const char *gengetopt_args_info_purpose = "This program generates a C function that uses getopt_long function\nto parse the command line options, validate them and fill a struct.";
+
+const char *gengetopt_args_info_usage = "Usage: " CMDLINE_PARSER_PACKAGE " [OPTIONS]...";
+
+const char *gengetopt_args_info_description = "";
+
+const char *gengetopt_args_info_detailed_help[] = {
+  "  -h, --help                    Print help and exit",
+  "      --detailed-help           Print help, including all details and hidden \n                                  options, and exit",
+  "  -V, --version                 Print version and exit",
+  "\nMain options:",
+  "",
+  "  -i, --input=filename          input file (default std input)",
+  "  -f, --func-name=name          name of generated function  \n                                  (default=`cmdline_parser')",
+  "  -a, --arg-struct-name=name    name of generated args info struct  \n                                  (default=`gengetopt_args_info')",
+  "  -F, --file-name=name          name of generated file  (default=`cmdline')",
+  "      --output-dir=path         output directory",
+  "  \n  if this option is not specified, the files are generated in the current \n  directory.\n",
+  "      --header-output-dir=path  header output directory",
+  "      --src-output-dir=path     source output directory",
+  "  -c, --c-extension=ext         extension of c file  (default=`c')",
+  "  -H, --header-extension=ext    extension of header file  (default=`h')",
+  "  -l, --long-help               long usage line in help",
+  "  \n  The usage line will print all the options, e.g.,\n\n  sample1 -iINT|--int-opt=INT [-h|--help]\n",
+  "      --default-optional        by default, an option is considered optional if \n                                  not specified otherwise",
+  "  -u, --unamed-opts[=STRING]    accept options without names (e.g., file names) \n                                   (default=`FILES')",
+  "\nThe parser generated is thought to be used to parse the command line arguments. \nHowever, you can also generate parsers for configuration files, or strings that \ncontain the arguments to parse, by using the following two options.\n",
+  "  -C, --conf-parser             generate a config file parser",
+  "  -S, --string-parser           generate a string parser (the string contains \n                                  the command line)",
+  "",
+  "\nAdditional options:",
+  "  -G, --include-getopt          adds the code for getopt_long in the generated \n                                  C file",
+  "  -n, --no-handle-help          do not handle --help|-h automatically",
+  "  \n  If --no-handle-help is specified, the command line option --help|-h will not \n  be handled automatically, so the programmer will be able to print some other \n  information; then the function for printing the standard help output can be \n  used; this function is called <parser-name>_print_help.\n\n  Notice that, although the programmer can handle --help|-h manually, the \n  parser will return after finding such option: the other command line options, \n  if any, will be ignored.  In case you want to have full control on --help|-h, \n  you should use --ho-help.\n",
+  "      --no-help                 do not add --help|-h automatically",
+  "  \n  With this option you can disable the automatic addition of options --help|-h. \n  The programmer will then be able to add this option in the input file and \n  handle it as he sees fit.  Notice that --no-help will also disable the \n  automatic options --detailed-help and --full-help.\n\n  The programmer can still define options with short character h as he wants, \n  but he cannot define options help, unless he specifies --no-help (otherwise \n  an error will be printed).\n",
+  "  -N, --no-handle-version       do not handle --version|-V automatically",
+  "      --no-version              do not add --version|-V automatically",
+  "  \n  See above the details about --no-handle-help and --no-help, respectively.\n",
+  "  -e, --no-handle-error         do not exit on errors",
+  "  \n  With this option, if the generated parser encounters an error (e.g., an \n  unknown option) it does not make the main program exit; instead, the parser \n  function returns a value different 0, and the main program can print a help \n  message.\n",
+  "      --show-required[=STRING]  in the output of help will specify which \n                                  options are mandatory, by using the optional \n                                  passed string  (default=`(mandatory)')",
+  "  -g, --gen-version             put gengetopt version in the generated file  \n                                  (default=on)",
+  "      --set-package=STRING      set the package name (override package defined \n                                  in the .ggo file)",
+  "      --set-version=STRING      set the version number (override version \n                                  defined in the .ggo file)",
+  "      --show-help               show the output of --help instead of generating \n                                  code",
+  "      --show-full-help          show the output of --full-help (i.e., including \n                                  hidden options) instead of generating code",
+  "      --show-detailed-help      show the output of --detailed-help (i.e., \n                                  including details and hidden options) instead \n                                  of generating code",
+  "      --show-version            show the output of --version instead of \n                                  generating code",
+  "\nPlease refer to the info manual for further explanations.",
+    0
+};
+
+static void
+init_help_array(void)
+{
+  gengetopt_args_info_help[0] = gengetopt_args_info_detailed_help[0];
+  gengetopt_args_info_help[1] = gengetopt_args_info_detailed_help[1];
+  gengetopt_args_info_help[2] = gengetopt_args_info_detailed_help[2];
+  gengetopt_args_info_help[3] = gengetopt_args_info_detailed_help[3];
+  gengetopt_args_info_help[4] = gengetopt_args_info_detailed_help[4];
+  gengetopt_args_info_help[5] = gengetopt_args_info_detailed_help[5];
+  gengetopt_args_info_help[6] = gengetopt_args_info_detailed_help[6];
+  gengetopt_args_info_help[7] = gengetopt_args_info_detailed_help[7];
+  gengetopt_args_info_help[8] = gengetopt_args_info_detailed_help[8];
+  gengetopt_args_info_help[9] = gengetopt_args_info_detailed_help[9];
+  gengetopt_args_info_help[10] = gengetopt_args_info_detailed_help[11];
+  gengetopt_args_info_help[11] = gengetopt_args_info_detailed_help[12];
+  gengetopt_args_info_help[12] = gengetopt_args_info_detailed_help[13];
+  gengetopt_args_info_help[13] = gengetopt_args_info_detailed_help[14];
+  gengetopt_args_info_help[14] = gengetopt_args_info_detailed_help[15];
+  gengetopt_args_info_help[15] = gengetopt_args_info_detailed_help[17];
+  gengetopt_args_info_help[16] = gengetopt_args_info_detailed_help[18];
+  gengetopt_args_info_help[17] = gengetopt_args_info_detailed_help[19];
+  gengetopt_args_info_help[18] = gengetopt_args_info_detailed_help[20];
+  gengetopt_args_info_help[19] = gengetopt_args_info_detailed_help[21];
+  gengetopt_args_info_help[20] = gengetopt_args_info_detailed_help[22];
+  gengetopt_args_info_help[21] = gengetopt_args_info_detailed_help[23];
+  gengetopt_args_info_help[22] = gengetopt_args_info_detailed_help[24];
+  gengetopt_args_info_help[23] = gengetopt_args_info_detailed_help[25];
+  gengetopt_args_info_help[24] = gengetopt_args_info_detailed_help[27];
+  gengetopt_args_info_help[25] = gengetopt_args_info_detailed_help[29];
+  gengetopt_args_info_help[26] = gengetopt_args_info_detailed_help[30];
+  gengetopt_args_info_help[27] = gengetopt_args_info_detailed_help[32];
+  gengetopt_args_info_help[28] = gengetopt_args_info_detailed_help[34];
+  gengetopt_args_info_help[29] = gengetopt_args_info_detailed_help[35];
+  gengetopt_args_info_help[30] = gengetopt_args_info_detailed_help[36];
+  gengetopt_args_info_help[31] = gengetopt_args_info_detailed_help[37];
+  gengetopt_args_info_help[32] = gengetopt_args_info_detailed_help[38];
+  gengetopt_args_info_help[33] = gengetopt_args_info_detailed_help[39];
+  gengetopt_args_info_help[34] = gengetopt_args_info_detailed_help[40];
+  gengetopt_args_info_help[35] = gengetopt_args_info_detailed_help[41];
+  gengetopt_args_info_help[36] = gengetopt_args_info_detailed_help[42];
+  gengetopt_args_info_help[37] = 0; 
+  
+}
+
+const char *gengetopt_args_info_help[38];
+
+typedef enum {ARG_NO
+  , ARG_FLAG
+  , ARG_STRING
+} cmdline_parser_arg_type;
+
+static
+void clear_given (struct gengetopt_args_info *args_info);
+static
+void clear_args (struct gengetopt_args_info *args_info);
+
+static int
+cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info,
+                        struct cmdline_parser_params *params, const char *additional_error);
+
+struct line_list
+{
+  char * string_arg;
+  struct line_list * next;
+};
+
+static struct line_list *cmd_line_list = 0;
+static struct line_list *cmd_line_list_tmp = 0;
+
+static void
+free_cmd_list(void)
+{
+  /* free the list of a previous call */
+  if (cmd_line_list)
+    {
+      while (cmd_line_list) {
+        cmd_line_list_tmp = cmd_line_list;
+        cmd_line_list = cmd_line_list->next;
+        free (cmd_line_list_tmp->string_arg);
+        free (cmd_line_list_tmp);
+      }
+    }
+}
+
+
+static char *
+gengetopt_strdup (const char *s);
+
+static
+void clear_given (struct gengetopt_args_info *args_info)
+{
+  args_info->help_given = 0 ;
+  args_info->detailed_help_given = 0 ;
+  args_info->version_given = 0 ;
+  args_info->input_given = 0 ;
+  args_info->func_name_given = 0 ;
+  args_info->arg_struct_name_given = 0 ;
+  args_info->file_name_given = 0 ;
+  args_info->output_dir_given = 0 ;
+  args_info->header_output_dir_given = 0 ;
+  args_info->src_output_dir_given = 0 ;
+  args_info->c_extension_given = 0 ;
+  args_info->header_extension_given = 0 ;
+  args_info->long_help_given = 0 ;
+  args_info->default_optional_given = 0 ;
+  args_info->unamed_opts_given = 0 ;
+  args_info->conf_parser_given = 0 ;
+  args_info->string_parser_given = 0 ;
+  args_info->include_getopt_given = 0 ;
+  args_info->no_handle_help_given = 0 ;
+  args_info->no_help_given = 0 ;
+  args_info->no_handle_version_given = 0 ;
+  args_info->no_version_given = 0 ;
+  args_info->no_handle_error_given = 0 ;
+  args_info->show_required_given = 0 ;
+  args_info->gen_version_given = 0 ;
+  args_info->set_package_given = 0 ;
+  args_info->set_version_given = 0 ;
+  args_info->show_help_given = 0 ;
+  args_info->show_full_help_given = 0 ;
+  args_info->show_detailed_help_given = 0 ;
+  args_info->show_version_given = 0 ;
+}
+
+static
+void clear_args (struct gengetopt_args_info *args_info)
+{
+  FIX_UNUSED (args_info);
+  args_info->input_arg = NULL;
+  args_info->input_orig = NULL;
+  args_info->func_name_arg = gengetopt_strdup ("cmdline_parser");
+  args_info->func_name_orig = NULL;
+  args_info->arg_struct_name_arg = gengetopt_strdup ("gengetopt_args_info");
+  args_info->arg_struct_name_orig = NULL;
+  args_info->file_name_arg = gengetopt_strdup ("cmdline");
+  args_info->file_name_orig = NULL;
+  args_info->output_dir_arg = NULL;
+  args_info->output_dir_orig = NULL;
+  args_info->header_output_dir_arg = NULL;
+  args_info->header_output_dir_orig = NULL;
+  args_info->src_output_dir_arg = NULL;
+  args_info->src_output_dir_orig = NULL;
+  args_info->c_extension_arg = gengetopt_strdup ("c");
+  args_info->c_extension_orig = NULL;
+  args_info->header_extension_arg = gengetopt_strdup ("h");
+  args_info->header_extension_orig = NULL;
+  args_info->unamed_opts_arg = gengetopt_strdup ("FILES");
+  args_info->unamed_opts_orig = NULL;
+  args_info->show_required_arg = gengetopt_strdup ("(mandatory)");
+  args_info->show_required_orig = NULL;
+  args_info->gen_version_flag = 1;
+  args_info->set_package_arg = NULL;
+  args_info->set_package_orig = NULL;
+  args_info->set_version_arg = NULL;
+  args_info->set_version_orig = NULL;
+  
+}
+
+static
+void init_args_info(struct gengetopt_args_info *args_info)
+{
+
+  init_help_array(); 
+  args_info->help_help = gengetopt_args_info_detailed_help[0] ;
+  args_info->detailed_help_help = gengetopt_args_info_detailed_help[1] ;
+  args_info->version_help = gengetopt_args_info_detailed_help[2] ;
+  args_info->input_help = gengetopt_args_info_detailed_help[5] ;
+  args_info->func_name_help = gengetopt_args_info_detailed_help[6] ;
+  args_info->arg_struct_name_help = gengetopt_args_info_detailed_help[7] ;
+  args_info->file_name_help = gengetopt_args_info_detailed_help[8] ;
+  args_info->output_dir_help = gengetopt_args_info_detailed_help[9] ;
+  args_info->header_output_dir_help = gengetopt_args_info_detailed_help[11] ;
+  args_info->src_output_dir_help = gengetopt_args_info_detailed_help[12] ;
+  args_info->c_extension_help = gengetopt_args_info_detailed_help[13] ;
+  args_info->header_extension_help = gengetopt_args_info_detailed_help[14] ;
+  args_info->long_help_help = gengetopt_args_info_detailed_help[15] ;
+  args_info->default_optional_help = gengetopt_args_info_detailed_help[17] ;
+  args_info->unamed_opts_help = gengetopt_args_info_detailed_help[18] ;
+  args_info->conf_parser_help = gengetopt_args_info_detailed_help[20] ;
+  args_info->string_parser_help = gengetopt_args_info_detailed_help[21] ;
+  args_info->include_getopt_help = gengetopt_args_info_detailed_help[24] ;
+  args_info->no_handle_help_help = gengetopt_args_info_detailed_help[25] ;
+  args_info->no_help_help = gengetopt_args_info_detailed_help[27] ;
+  args_info->no_handle_version_help = gengetopt_args_info_detailed_help[29] ;
+  args_info->no_version_help = gengetopt_args_info_detailed_help[30] ;
+  args_info->no_handle_error_help = gengetopt_args_info_detailed_help[32] ;
+  args_info->show_required_help = gengetopt_args_info_detailed_help[34] ;
+  args_info->gen_version_help = gengetopt_args_info_detailed_help[35] ;
+  args_info->set_package_help = gengetopt_args_info_detailed_help[36] ;
+  args_info->set_version_help = gengetopt_args_info_detailed_help[37] ;
+  args_info->show_help_help = gengetopt_args_info_detailed_help[38] ;
+  args_info->show_full_help_help = gengetopt_args_info_detailed_help[39] ;
+  args_info->show_detailed_help_help = gengetopt_args_info_detailed_help[40] ;
+  args_info->show_version_help = gengetopt_args_info_detailed_help[41] ;
+  
+}
+
+void
+cmdline_parser_print_version (void)
+{
+  printf ("%s %s\n",
+     (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE),
+     CMDLINE_PARSER_VERSION);
+}
+
+static void print_help_common(void) {
+  cmdline_parser_print_version ();
+
+  if (strlen(gengetopt_args_info_purpose) > 0)
+    printf("\n%s\n", gengetopt_args_info_purpose);
+
+  if (strlen(gengetopt_args_info_usage) > 0)
+    printf("\n%s\n", gengetopt_args_info_usage);
+
+  printf("\n");
+
+  if (strlen(gengetopt_args_info_description) > 0)
+    printf("%s\n\n", gengetopt_args_info_description);
+}
+
+void
+cmdline_parser_print_help (void)
+{
+  int i = 0;
+  print_help_common();
+  while (gengetopt_args_info_help[i])
+    printf("%s\n", gengetopt_args_info_help[i++]);
+}
+
+void
+cmdline_parser_print_detailed_help (void)
+{
+  int i = 0;
+  print_help_common();
+  while (gengetopt_args_info_detailed_help[i])
+    printf("%s\n", gengetopt_args_info_detailed_help[i++]);
+}
+
+void
+cmdline_parser_init (struct gengetopt_args_info *args_info)
+{
+  clear_given (args_info);
+  clear_args (args_info);
+  init_args_info (args_info);
+}
+
+void
+cmdline_parser_params_init(struct cmdline_parser_params *params)
+{
+  if (params)
+    { 
+      params->override = 0;
+      params->initialize = 1;
+      params->check_required = 1;
+      params->check_ambiguity = 0;
+      params->print_errors = 1;
+    }
+}
+
+struct cmdline_parser_params *
+cmdline_parser_params_create(void)
+{
+  struct cmdline_parser_params *params = 
+    (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params));
+  cmdline_parser_params_init(params);  
+  return params;
+}
+
+static void
+free_string_field (char **s)
+{
+  if (*s)
+    {
+      free (*s);
+      *s = 0;
+    }
+}
+
+
+static void
+cmdline_parser_release (struct gengetopt_args_info *args_info)
+{
+
+  free_string_field (&(args_info->input_arg));
+  free_string_field (&(args_info->input_orig));
+  free_string_field (&(args_info->func_name_arg));
+  free_string_field (&(args_info->func_name_orig));
+  free_string_field (&(args_info->arg_struct_name_arg));
+  free_string_field (&(args_info->arg_struct_name_orig));
+  free_string_field (&(args_info->file_name_arg));
+  free_string_field (&(args_info->file_name_orig));
+  free_string_field (&(args_info->output_dir_arg));
+  free_string_field (&(args_info->output_dir_orig));
+  free_string_field (&(args_info->header_output_dir_arg));
+  free_string_field (&(args_info->header_output_dir_orig));
+  free_string_field (&(args_info->src_output_dir_arg));
+  free_string_field (&(args_info->src_output_dir_orig));
+  free_string_field (&(args_info->c_extension_arg));
+  free_string_field (&(args_info->c_extension_orig));
+  free_string_field (&(args_info->header_extension_arg));
+  free_string_field (&(args_info->header_extension_orig));
+  free_string_field (&(args_info->unamed_opts_arg));
+  free_string_field (&(args_info->unamed_opts_orig));
+  free_string_field (&(args_info->show_required_arg));
+  free_string_field (&(args_info->show_required_orig));
+  free_string_field (&(args_info->set_package_arg));
+  free_string_field (&(args_info->set_package_orig));
+  free_string_field (&(args_info->set_version_arg));
+  free_string_field (&(args_info->set_version_orig));
+  
+  
+
+  clear_given (args_info);
+}
+
+
+static void
+write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
+{
+  FIX_UNUSED (values);
+  if (arg) {
+    fprintf(outfile, "%s=\"%s\"\n", opt, arg);
+  } else {
+    fprintf(outfile, "%s\n", opt);
+  }
+}
+
+
+int
+cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
+{
+  int i = 0;
+
+  if (!outfile)
+    {
+      fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE);
+      return EXIT_FAILURE;
+    }
+
+  if (args_info->help_given)
+    write_into_file(outfile, "help", 0, 0 );
+  if (args_info->detailed_help_given)
+    write_into_file(outfile, "detailed-help", 0, 0 );
+  if (args_info->version_given)
+    write_into_file(outfile, "version", 0, 0 );
+  if (args_info->input_given)
+    write_into_file(outfile, "input", args_info->input_orig, 0);
+  if (args_info->func_name_given)
+    write_into_file(outfile, "func-name", args_info->func_name_orig, 0);
+  if (args_info->arg_struct_name_given)
+    write_into_file(outfile, "arg-struct-name", args_info->arg_struct_name_orig, 0);
+  if (args_info->file_name_given)
+    write_into_file(outfile, "file-name", args_info->file_name_orig, 0);
+  if (args_info->output_dir_given)
+    write_into_file(outfile, "output-dir", args_info->output_dir_orig, 0);
+  if (args_info->header_output_dir_given)
+    write_into_file(outfile, "header-output-dir", args_info->header_output_dir_orig, 0);
+  if (args_info->src_output_dir_given)
+    write_into_file(outfile, "src-output-dir", args_info->src_output_dir_orig, 0);
+  if (args_info->c_extension_given)
+    write_into_file(outfile, "c-extension", args_info->c_extension_orig, 0);
+  if (args_info->header_extension_given)
+    write_into_file(outfile, "header-extension", args_info->header_extension_orig, 0);
+  if (args_info->long_help_given)
+    write_into_file(outfile, "long-help", 0, 0 );
+  if (args_info->default_optional_given)
+    write_into_file(outfile, "default-optional", 0, 0 );
+  if (args_info->unamed_opts_given)
+    write_into_file(outfile, "unamed-opts", args_info->unamed_opts_orig, 0);
+  if (args_info->conf_parser_given)
+    write_into_file(outfile, "conf-parser", 0, 0 );
+  if (args_info->string_parser_given)
+    write_into_file(outfile, "string-parser", 0, 0 );
+  if (args_info->include_getopt_given)
+    write_into_file(outfile, "include-getopt", 0, 0 );
+  if (args_info->no_handle_help_given)
+    write_into_file(outfile, "no-handle-help", 0, 0 );
+  if (args_info->no_help_given)
+    write_into_file(outfile, "no-help", 0, 0 );
+  if (args_info->no_handle_version_given)
+    write_into_file(outfile, "no-handle-version", 0, 0 );
+  if (args_info->no_version_given)
+    write_into_file(outfile, "no-version", 0, 0 );
+  if (args_info->no_handle_error_given)
+    write_into_file(outfile, "no-handle-error", 0, 0 );
+  if (args_info->show_required_given)
+    write_into_file(outfile, "show-required", args_info->show_required_orig, 0);
+  if (args_info->gen_version_given)
+    write_into_file(outfile, "gen-version", 0, 0 );
+  if (args_info->set_package_given)
+    write_into_file(outfile, "set-package", args_info->set_package_orig, 0);
+  if (args_info->set_version_given)
+    write_into_file(outfile, "set-version", args_info->set_version_orig, 0);
+  if (args_info->show_help_given)
+    write_into_file(outfile, "show-help", 0, 0 );
+  if (args_info->show_full_help_given)
+    write_into_file(outfile, "show-full-help", 0, 0 );
+  if (args_info->show_detailed_help_given)
+    write_into_file(outfile, "show-detailed-help", 0, 0 );
+  if (args_info->show_version_given)
+    write_into_file(outfile, "show-version", 0, 0 );
+  
+
+  i = EXIT_SUCCESS;
+  return i;
+}
+
+int
+cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
+{
+  FILE *outfile;
+  int i = 0;
+
+  outfile = fopen(filename, "w");
+
+  if (!outfile)
+    {
+      fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
+      return EXIT_FAILURE;
+    }
+
+  i = cmdline_parser_dump(outfile, args_info);
+  fclose (outfile);
+
+  return i;
+}
+
+void
+cmdline_parser_free (struct gengetopt_args_info *args_info)
+{
+  cmdline_parser_release (args_info);
+}
+
+/** @brief replacement of strdup, which is not standard */
+char *
+gengetopt_strdup (const char *s)
+{
+  char *result = 0;
+  if (!s)
+    return result;
+
+  result = (char*)malloc(strlen(s) + 1);
+  if (result == (char*)0)
+    return (char*)0;
+  strcpy(result, s);
+  return result;
+}
+
+int
+cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info)
+{
+  return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
+}
+
+int
+cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
+                   struct cmdline_parser_params *params)
+{
+  int result;
+  result = cmdline_parser_internal (argc, argv, args_info, params, 0);
+
+  return result;
+}
+
+int
+cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
+{
+  int result;
+  struct cmdline_parser_params params;
+  
+  params.override = override;
+  params.initialize = initialize;
+  params.check_required = check_required;
+  params.check_ambiguity = 0;
+  params.print_errors = 1;
+
+  result = cmdline_parser_internal (argc, argv, args_info, &params, 0);
+
+  return result;
+}
+
+int
+cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
+{
+  FIX_UNUSED (args_info);
+  FIX_UNUSED (prog_name);
+  return EXIT_SUCCESS;
+}
+
+
+static char *package_name = 0;
+
+/**
+ * @brief updates an option
+ * @param field the generic pointer to the field to update
+ * @param orig_field the pointer to the orig field
+ * @param field_given the pointer to the number of occurrence of this option
+ * @param prev_given the pointer to the number of occurrence already seen
+ * @param value the argument for this option (if null no arg was specified)
+ * @param possible_values the possible values for this option (if specified)
+ * @param default_value the default value (in case the option only accepts fixed values)
+ * @param arg_type the type of this option
+ * @param check_ambiguity @see cmdline_parser_params.check_ambiguity
+ * @param override @see cmdline_parser_params.override
+ * @param no_free whether to free a possible previous value
+ * @param multiple_option whether this is a multiple option
+ * @param long_opt the corresponding long option
+ * @param short_opt the corresponding short option (or '-' if none)
+ * @param additional_error possible further error specification
+ */
+static
+int update_arg(void *field, char **orig_field,
+               unsigned int *field_given, unsigned int *prev_given, 
+               char *value, const char *possible_values[],
+               const char *default_value,
+               cmdline_parser_arg_type arg_type,
+               int check_ambiguity, int override,
+               int no_free, int multiple_option,
+               const char *long_opt, char short_opt,
+               const char *additional_error)
+{
+  char *stop_char = 0;
+  const char *val = value;
+  int found;
+  char **string_field;
+  FIX_UNUSED (field);
+
+  stop_char = 0;
+  found = 0;
+
+  if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
+    {
+      if (short_opt != '-')
+        fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", 
+               package_name, long_opt, short_opt,
+               (additional_error ? additional_error : ""));
+      else
+        fprintf (stderr, "%s: `--%s' option given more than once%s\n", 
+               package_name, long_opt,
+               (additional_error ? additional_error : ""));
+      return 1; /* failure */
+    }
+
+  FIX_UNUSED (default_value);
+    
+  if (field_given && *field_given && ! override)
+    return 0;
+  if (prev_given)
+    (*prev_given)++;
+  if (field_given)
+    (*field_given)++;
+  if (possible_values)
+    val = possible_values[found];
+
+  switch(arg_type) {
+  case ARG_FLAG:
+    *((int *)field) = !*((int *)field);
+    break;
+  case ARG_STRING:
+    if (val) {
+      string_field = (char **)field;
+      if (!no_free && *string_field)
+        free (*string_field); /* free previous string */
+      *string_field = gengetopt_strdup (val);
+    }
+    break;
+  default:
+    break;
+  };
+
+
+  /* store the original value */
+  switch(arg_type) {
+  case ARG_NO:
+  case ARG_FLAG:
+    break;
+  default:
+    if (value && orig_field) {
+      if (no_free) {
+        *orig_field = value;
+      } else {
+        if (*orig_field)
+          free (*orig_field); /* free previous string */
+        *orig_field = gengetopt_strdup (value);
+      }
+    }
+  };
+
+  return 0; /* OK */
+}
+
+
+int
+cmdline_parser_internal (
+  int argc, char **argv, struct gengetopt_args_info *args_info,
+                        struct cmdline_parser_params *params, const char *additional_error)
+{
+  int c;       /* Character of the parsed option.  */
+
+  int error = 0;
+  struct gengetopt_args_info local_args_info;
+  
+  int override;
+  int initialize;
+  int check_required;
+  int check_ambiguity;
+  
+  package_name = argv[0];
+  
+  override = params->override;
+  initialize = params->initialize;
+  check_required = params->check_required;
+  check_ambiguity = params->check_ambiguity;
+
+  if (initialize)
+    cmdline_parser_init (args_info);
+
+  cmdline_parser_init (&local_args_info);
+
+  optarg = 0;
+  optind = 0;
+  opterr = params->print_errors;
+  optopt = '?';
+
+  while (1)
+    {
+      int option_index = 0;
+
+      static struct option long_options[] = {
+        { "help",      0, NULL, 'h' },
+        { "detailed-help",     0, NULL, 0 },
+        { "version",   0, NULL, 'V' },
+        { "input",     1, NULL, 'i' },
+        { "func-name", 1, NULL, 'f' },
+        { "arg-struct-name",   1, NULL, 'a' },
+        { "file-name", 1, NULL, 'F' },
+        { "output-dir",        1, NULL, 0 },
+        { "header-output-dir", 1, NULL, 0 },
+        { "src-output-dir",    1, NULL, 0 },
+        { "c-extension",       1, NULL, 'c' },
+        { "header-extension",  1, NULL, 'H' },
+        { "long-help", 0, NULL, 'l' },
+        { "default-optional",  0, NULL, 0 },
+        { "unamed-opts",       2, NULL, 'u' },
+        { "conf-parser",       0, NULL, 'C' },
+        { "string-parser",     0, NULL, 'S' },
+        { "include-getopt",    0, NULL, 'G' },
+        { "no-handle-help",    0, NULL, 'n' },
+        { "no-help",   0, NULL, 0 },
+        { "no-handle-version", 0, NULL, 'N' },
+        { "no-version",        0, NULL, 0 },
+        { "no-handle-error",   0, NULL, 'e' },
+        { "show-required",     2, NULL, 0 },
+        { "gen-version",       0, NULL, 'g' },
+        { "set-package",       1, NULL, 0 },
+        { "set-version",       1, NULL, 0 },
+        { "show-help", 0, NULL, 0 },
+        { "show-full-help",    0, NULL, 0 },
+        { "show-detailed-help",        0, NULL, 0 },
+        { "show-version",      0, NULL, 0 },
+        { 0,  0, 0, 0 }
+      };
+
+      c = getopt_long (argc, argv, "hVi:f:a:F:c:H:lu::CSGnNeg", long_options, &option_index);
+
+      if (c == -1) break;      /* Exit from `while (1)' loop.  */
+
+      switch (c)
+        {
+        case 'h':      /* Print help and exit.  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->help_given),
+              &(local_args_info.help_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "help", 'h',
+              additional_error))
+            goto failure;
+          cmdline_parser_free (&local_args_info);
+          return 0;
+        
+          break;
+        case 'V':      /* Print version and exit.  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->version_given),
+              &(local_args_info.version_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "version", 'V',
+              additional_error))
+            goto failure;
+          cmdline_parser_free (&local_args_info);
+          return 0;
+        
+          break;
+        case 'i':      /* input file (default std input).  */
+        
+        
+          if (update_arg( (void *)&(args_info->input_arg), 
+               &(args_info->input_orig), &(args_info->input_given),
+              &(local_args_info.input_given), optarg, 0, 0, ARG_STRING,
+              check_ambiguity, override, 0, 0,
+              "input", 'i',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'f':      /* name of generated function.  */
+        
+        
+          if (update_arg( (void *)&(args_info->func_name_arg), 
+               &(args_info->func_name_orig), &(args_info->func_name_given),
+              &(local_args_info.func_name_given), optarg, 0, "cmdline_parser", ARG_STRING,
+              check_ambiguity, override, 0, 0,
+              "func-name", 'f',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'a':      /* name of generated args info struct.  */
+        
+        
+          if (update_arg( (void *)&(args_info->arg_struct_name_arg), 
+               &(args_info->arg_struct_name_orig), &(args_info->arg_struct_name_given),
+              &(local_args_info.arg_struct_name_given), optarg, 0, "gengetopt_args_info", ARG_STRING,
+              check_ambiguity, override, 0, 0,
+              "arg-struct-name", 'a',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'F':      /* name of generated file.  */
+        
+        
+          if (update_arg( (void *)&(args_info->file_name_arg), 
+               &(args_info->file_name_orig), &(args_info->file_name_given),
+              &(local_args_info.file_name_given), optarg, 0, "cmdline", ARG_STRING,
+              check_ambiguity, override, 0, 0,
+              "file-name", 'F',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'c':      /* extension of c file.  */
+        
+        
+          if (update_arg( (void *)&(args_info->c_extension_arg), 
+               &(args_info->c_extension_orig), &(args_info->c_extension_given),
+              &(local_args_info.c_extension_given), optarg, 0, "c", ARG_STRING,
+              check_ambiguity, override, 0, 0,
+              "c-extension", 'c',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'H':      /* extension of header file.  */
+        
+        
+          if (update_arg( (void *)&(args_info->header_extension_arg), 
+               &(args_info->header_extension_orig), &(args_info->header_extension_given),
+              &(local_args_info.header_extension_given), optarg, 0, "h", ARG_STRING,
+              check_ambiguity, override, 0, 0,
+              "header-extension", 'H',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'l':      /* long usage line in help.  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->long_help_given),
+              &(local_args_info.long_help_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "long-help", 'l',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'u':      /* accept options without names (e.g., file names).  */
+        
+        
+          if (update_arg( (void *)&(args_info->unamed_opts_arg), 
+               &(args_info->unamed_opts_orig), &(args_info->unamed_opts_given),
+              &(local_args_info.unamed_opts_given), optarg, 0, "FILES", ARG_STRING,
+              check_ambiguity, override, 0, 0,
+              "unamed-opts", 'u',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'C':      /* generate a config file parser.  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->conf_parser_given),
+              &(local_args_info.conf_parser_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "conf-parser", 'C',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'S':      /* generate a string parser (the string contains the command line).  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->string_parser_given),
+              &(local_args_info.string_parser_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "string-parser", 'S',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'G':      /* adds the code for getopt_long in the generated C file.  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->include_getopt_given),
+              &(local_args_info.include_getopt_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "include-getopt", 'G',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'n':      /* do not handle --help|-h automatically.  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->no_handle_help_given),
+              &(local_args_info.no_handle_help_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "no-handle-help", 'n',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'N':      /* do not handle --version|-V automatically.  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->no_handle_version_given),
+              &(local_args_info.no_handle_version_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "no-handle-version", 'N',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'e':      /* do not exit on errors.  */
+        
+        
+          if (update_arg( 0 , 
+               0 , &(args_info->no_handle_error_given),
+              &(local_args_info.no_handle_error_given), optarg, 0, 0, ARG_NO,
+              check_ambiguity, override, 0, 0,
+              "no-handle-error", 'e',
+              additional_error))
+            goto failure;
+        
+          break;
+        case 'g':      /* put gengetopt version in the generated file.  */
+        
+        
+          if (update_arg((void *)&(args_info->gen_version_flag), 0, &(args_info->gen_version_given),
+              &(local_args_info.gen_version_given), optarg, 0, 0, ARG_FLAG,
+              check_ambiguity, override, 1, 0, "gen-version", 'g',
+              additional_error))
+            goto failure;
+        
+          break;
+
+        case 0:        /* Long option with no short option */
+          /* Print help, including all details and hidden options, and exit.  */
+          if (strcmp (long_options[option_index].name, "detailed-help") == 0)
+          {
+          
+          
+            if (update_arg( 0 , 
+                 0 , &(args_info->detailed_help_given),
+                &(local_args_info.detailed_help_given), optarg, 0, 0, ARG_NO,
+                check_ambiguity, override, 0, 0,
+                "detailed-help", '-',
+                additional_error))
+              goto failure;
+            cmdline_parser_free (&local_args_info);
+            return 0;
+          
+          }
+          /* output directory.  */
+          else if (strcmp (long_options[option_index].name, "output-dir") == 0)
+          {
+          
+          
+            if (update_arg( (void *)&(args_info->output_dir_arg), 
+                 &(args_info->output_dir_orig), &(args_info->output_dir_given),
+                &(local_args_info.output_dir_given), optarg, 0, 0, ARG_STRING,
+                check_ambiguity, override, 0, 0,
+                "output-dir", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* header output directory.  */
+          else if (strcmp (long_options[option_index].name, "header-output-dir") == 0)
+          {
+          
+          
+            if (update_arg( (void *)&(args_info->header_output_dir_arg), 
+                 &(args_info->header_output_dir_orig), &(args_info->header_output_dir_given),
+                &(local_args_info.header_output_dir_given), optarg, 0, 0, ARG_STRING,
+                check_ambiguity, override, 0, 0,
+                "header-output-dir", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* source output directory.  */
+          else if (strcmp (long_options[option_index].name, "src-output-dir") == 0)
+          {
+          
+          
+            if (update_arg( (void *)&(args_info->src_output_dir_arg), 
+                 &(args_info->src_output_dir_orig), &(args_info->src_output_dir_given),
+                &(local_args_info.src_output_dir_given), optarg, 0, 0, ARG_STRING,
+                check_ambiguity, override, 0, 0,
+                "src-output-dir", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* by default, an option is considered optional if not specified otherwise.  */
+          else if (strcmp (long_options[option_index].name, "default-optional") == 0)
+          {
+          
+          
+            if (update_arg( 0 , 
+                 0 , &(args_info->default_optional_given),
+                &(local_args_info.default_optional_given), optarg, 0, 0, ARG_NO,
+                check_ambiguity, override, 0, 0,
+                "default-optional", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* do not add --help|-h automatically.  */
+          else if (strcmp (long_options[option_index].name, "no-help") == 0)
+          {
+          
+          
+            if (update_arg( 0 , 
+                 0 , &(args_info->no_help_given),
+                &(local_args_info.no_help_given), optarg, 0, 0, ARG_NO,
+                check_ambiguity, override, 0, 0,
+                "no-help", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* do not add --version|-V automatically.  */
+          else if (strcmp (long_options[option_index].name, "no-version") == 0)
+          {
+          
+          
+            if (update_arg( 0 , 
+                 0 , &(args_info->no_version_given),
+                &(local_args_info.no_version_given), optarg, 0, 0, ARG_NO,
+                check_ambiguity, override, 0, 0,
+                "no-version", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* in the output of help will specify which options are mandatory, by using the optional passed string.  */
+          else if (strcmp (long_options[option_index].name, "show-required") == 0)
+          {
+          
+          
+            if (update_arg( (void *)&(args_info->show_required_arg), 
+                 &(args_info->show_required_orig), &(args_info->show_required_given),
+                &(local_args_info.show_required_given), optarg, 0, "(mandatory)", ARG_STRING,
+                check_ambiguity, override, 0, 0,
+                "show-required", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* set the package name (override package defined in the .ggo file).  */
+          else if (strcmp (long_options[option_index].name, "set-package") == 0)
+          {
+          
+          
+            if (update_arg( (void *)&(args_info->set_package_arg), 
+                 &(args_info->set_package_orig), &(args_info->set_package_given),
+                &(local_args_info.set_package_given), optarg, 0, 0, ARG_STRING,
+                check_ambiguity, override, 0, 0,
+                "set-package", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* set the version number (override version defined in the .ggo file).  */
+          else if (strcmp (long_options[option_index].name, "set-version") == 0)
+          {
+          
+          
+            if (update_arg( (void *)&(args_info->set_version_arg), 
+                 &(args_info->set_version_orig), &(args_info->set_version_given),
+                &(local_args_info.set_version_given), optarg, 0, 0, ARG_STRING,
+                check_ambiguity, override, 0, 0,
+                "set-version", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* show the output of --help instead of generating code.  */
+          else if (strcmp (long_options[option_index].name, "show-help") == 0)
+          {
+          
+          
+            if (update_arg( 0 , 
+                 0 , &(args_info->show_help_given),
+                &(local_args_info.show_help_given), optarg, 0, 0, ARG_NO,
+                check_ambiguity, override, 0, 0,
+                "show-help", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* show the output of --full-help (i.e., including hidden options) instead of generating code.  */
+          else if (strcmp (long_options[option_index].name, "show-full-help") == 0)
+          {
+          
+          
+            if (update_arg( 0 , 
+                 0 , &(args_info->show_full_help_given),
+                &(local_args_info.show_full_help_given), optarg, 0, 0, ARG_NO,
+                check_ambiguity, override, 0, 0,
+                "show-full-help", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* show the output of --detailed-help (i.e., including details and hidden options) instead of generating code.  */
+          else if (strcmp (long_options[option_index].name, "show-detailed-help") == 0)
+          {
+          
+          
+            if (update_arg( 0 , 
+                 0 , &(args_info->show_detailed_help_given),
+                &(local_args_info.show_detailed_help_given), optarg, 0, 0, ARG_NO,
+                check_ambiguity, override, 0, 0,
+                "show-detailed-help", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          /* show the output of --version instead of generating code.  */
+          else if (strcmp (long_options[option_index].name, "show-version") == 0)
+          {
+          
+          
+            if (update_arg( 0 , 
+                 0 , &(args_info->show_version_given),
+                &(local_args_info.show_version_given), optarg, 0, 0, ARG_NO,
+                check_ambiguity, override, 0, 0,
+                "show-version", '-',
+                additional_error))
+              goto failure;
+          
+          }
+          
+          break;
+        case '?':      /* Invalid option.  */
+          /* `getopt_long' already printed an error message.  */
+          goto failure;
+
+        default:       /* bug: option not considered.  */
+          fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
+          abort ();
+        } /* switch */
+    } /* while */
+
+
+
+
+  cmdline_parser_release (&local_args_info);
+
+  if ( error )
+    return (EXIT_FAILURE);
+
+  return 0;
+
+failure:
+  
+  cmdline_parser_release (&local_args_info);
+  return (EXIT_FAILURE);
+}
+
+static unsigned int
+cmdline_parser_create_argv(const char *cmdline_, char ***argv_ptr, const char *prog_name)
+{
+  char *cmdline, *p;
+  size_t n = 0, j;
+  int i;
+
+  if (prog_name) {
+    cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));
+    cmd_line_list_tmp->next = cmd_line_list;
+    cmd_line_list = cmd_line_list_tmp;
+    cmd_line_list->string_arg = gengetopt_strdup (prog_name);
+
+    ++n;
+  }
+
+  cmdline = gengetopt_strdup(cmdline_);
+  p = cmdline;
+
+  while (p && strlen(p))
+    {
+      j = strcspn(p, " \t");
+      ++n;
+      if (j && j < strlen(p))
+        {
+          p[j] = '\0';
+
+          cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));
+          cmd_line_list_tmp->next = cmd_line_list;
+          cmd_line_list = cmd_line_list_tmp;
+          cmd_line_list->string_arg = gengetopt_strdup (p);
+
+          p += (j+1);
+          p += strspn(p, " \t");
+        }
+      else
+        {
+          cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));
+          cmd_line_list_tmp->next = cmd_line_list;
+          cmd_line_list = cmd_line_list_tmp;
+          cmd_line_list->string_arg = gengetopt_strdup (p);
+
+          break;
+        }
+    }
+
+  *argv_ptr = (char **) malloc((n + 1) * sizeof(char *));
+  cmd_line_list_tmp = cmd_line_list;
+  for (i = (n-1); i >= 0; --i)
+    {
+      (*argv_ptr)[i] = cmd_line_list_tmp->string_arg;
+      cmd_line_list_tmp = cmd_line_list_tmp->next;
+    }
+
+  (*argv_ptr)[n] = 0;
+
+  free(cmdline);
+  return n;
+}
+
+int
+cmdline_parser_string(const char *cmdline, struct gengetopt_args_info *args_info, const char *prog_name)
+{
+  return cmdline_parser_string2(cmdline, args_info, prog_name, 0, 1, 1);
+}
+
+int
+cmdline_parser_string2(const char *cmdline, struct gengetopt_args_info *args_info, const char *prog_name,
+    int override, int initialize, int check_required)
+{
+  struct cmdline_parser_params params;
+
+  params.override = override;
+  params.initialize = initialize;
+  params.check_required = check_required;
+  params.check_ambiguity = 0;
+  params.print_errors = 1;
+
+  return cmdline_parser_string_ext(cmdline, args_info, prog_name, &params);
+}
+
+int
+cmdline_parser_string_ext(const char *cmdline, struct gengetopt_args_info *args_info, const char *prog_name,
+    struct cmdline_parser_params *params)
+{
+  char **argv_ptr = 0;
+  int result;
+  unsigned int argc;
+  
+  argc = cmdline_parser_create_argv(cmdline, &argv_ptr, prog_name);
+  
+  result =
+    cmdline_parser_internal (argc, argv_ptr, args_info, params, 0);
+  
+  if (argv_ptr)
+    {
+      free (argv_ptr);
+    }
+
+  free_cmd_list();
+  
+  return result;
+}
+
diff --git a/cmake/gengetopt/cmdline.ggo b/cmake/gengetopt/cmdline.ggo
new file mode 100644 (file)
index 0000000..d80ef5a
--- /dev/null
@@ -0,0 +1,147 @@
+# Copyright (C) 1999-2010  Free Software Foundation, Inc.
+#
+# This file is part of GNU gengetopt
+#
+# GNU gengetopt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU gengetopt is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with gengetopt; see the file COPYING. If not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+# Specification file format:
+#
+# This file consist in lines of sentences with the following format:
+#
+#         package <packname>
+#         version <version>
+#         purpose <string>
+#         option <long> <short> <desc> <argtype> <required>
+#         option <long> <short> <desc> flag      <onoff>
+#         option <long> <short> <desc> <required>
+#         ... # ...
+#
+# Where:
+#
+# <packname> = Double quoted string.
+# <version>  = Double quoted string.
+# <purpose>  = What the program does
+#              Double quoted string (even on more than one line)
+# <long>     = Double quoted string with upper and lower case chars, digits,
+#              '-' and '.'.  No spaces allowed.
+# <short>    = A single upper or lower case char, or a digit.
+# <desc>     = String with upper and lower case chars, digits, '-', '.' and
+#              spaces.
+# <argtype>  = string, int, short, long, float, double, longdouble or longlong.
+# <required> = required or optional.
+# <onoff>    = on or off.
+# Comments begins with '#' in any place of the line and ends in the
+# end of line.
+# The third form of option is used if the option does not take an argument;
+# it must not be required.
+
+
+# Name of our program
+#package "gengetopt"       # we don't use it: we're using automake
+# Version of our program
+#version "1.0.1"           # we don't use it: we're using automake
+
+purpose "This program generates a C function that uses getopt_long function
+to parse the command line options, validate them and fill a struct."
+
+# options that will be added to command line options of gengetopt
+args "--no-handle-version --no-handle-help --no-handle-error --string-parser"
+
+# Options
+
+section "Main options"
+
+text ""
+
+option  "input"         i "input file (default std input)"  string typestr="filename"     optional
+option  "func-name"     f "name of generated function" string typestr="name"  default="cmdline_parser"   optional
+option  "arg-struct-name" a "name of generated args info struct" string typestr="name"  default="gengetopt_args_info"   optional
+option  "file-name"     F "name of generated file"  string typestr="name"  default="cmdline"     optional
+option  "output-dir"     - "output directory"  string typestr="path"  optional
+       details="\nif this option is not specified, the \
+files are generated in the current directory.\n"
+option  "header-output-dir"     - "header output directory"  string typestr="path" optional
+option  "src-output-dir"     - "source output directory"  string typestr="path" optional
+option  "c-extension"   c "extension of c file" string typestr="ext" default="c" optional
+option  "header-extension"   H "extension of header file" string typestr="ext" default="h" optional
+option  "long-help"     l "long usage line in help" optional
+       details="\nThe usage line will print all the options, e.g.,
+
+sample1 -iINT|--int-opt=INT [-h|--help]\n"
+option  "default-optional"     - "by default, an option is considered optional if not specified otherwise" optional
+option  "unamed-opts"   u "accept options without names (e.g., file names)" string default="FILES" optional argoptional
+
+text "\nThe parser generated is thought to be used to parse the command line arguments. "
+text "However, you can also generate parsers for configuration files, or strings "
+text "that contain the arguments to parse, by using the following two options.\n"
+
+option  "conf-parser" C "generate a config file parser" optional
+option  "string-parser" S "generate a string parser (the string contains the command line)" optional
+
+text ""
+
+section "Additional options"
+
+option  "include-getopt" G "adds the code for getopt_long in the generated C file" optional
+
+option  "no-handle-help"   n "do not handle --help|-h automatically" optional
+       details="\nIf --no-handle-help is specified, the command line option \
+--help|-h will not be handled automatically, so the programmer will be able \
+to print some \
+other information; then the function for printing the standard help \
+output can be used; this function is called \
+<parser-name>_print_help.\n\nNotice \
+that, although the programmer can handle --help|-h manually, the \
+parser will return after finding such option: the other command \
+line options, if any, will be ignored.  In case you want to have full \
+control on --help|-h, you should use --ho-help.\n"
+       
+option  "no-help"   - "do not add --help|-h automatically" optional
+       details="\nWith this option you can disable the \
+automatic addition of options --help|-h. The programmer \ 
+will then be able to add this option in \
+the input file and handle it as he sees fit.  Notice that \
+--no-help will also disable the automatic options \
+--detailed-help and --full-help.
+
+The programmer can still \
+define options with short character h as he wants, \
+but he cannot define options help, unless he \
+specifies --no-help \
+(otherwise an error will be printed).\n"
+
+option  "no-handle-version"  N  "do not handle --version|-V automatically" optional
+option  "no-version"  -  "do not add --version|-V automatically" optional
+       details="\nSee above the details about \
+--no-handle-help and --no-help, respectively.\n"
+
+option  "no-handle-error" e "do not exit on errors" optional
+       details="\nWith this option, if the generated parser encounters an error \
+(e.g., an unknown option) it does not make the main program exit; instead, the parser \
+function returns a value different 0, and the main program can print a help message.\n"
+
+option  "show-required"   - "in the output of help will specify which options are mandatory, \
+by using the optional passed string" string default="(mandatory)" optional argoptional
+
+option  "gen-version" g "put gengetopt version in the generated file" flag on
+option  "set-package" - "set the package name (override package defined in the .ggo file)" string optional
+option  "set-version" - "set the version number (override version defined in the .ggo file)" string optional
+option  "show-help" - "show the output of --help instead of generating code" optional
+option  "show-full-help" - "show the output of --full-help (i.e., including hidden options) instead of generating code" optional
+option  "show-detailed-help" - "show the output of --detailed-help (i.e., including details and hidden options) instead of generating code" optional
+option  "show-version" - "show the output of --version instead of generating code" optional
+
+text "\nPlease refer to the info manual for further explanations."
diff --git a/cmake/gengetopt/cmdline.h b/cmake/gengetopt/cmdline.h
new file mode 100644 (file)
index 0000000..138ea0a
--- /dev/null
@@ -0,0 +1,304 @@
+/** @file cmdline.h
+ *  @brief The header file for the command line option parser
+ *  generated by GNU Gengetopt version 2.22.4
+ *  http://www.gnu.org/software/gengetopt.
+ *  DO NOT modify this file, since it can be overwritten
+ *  @author GNU Gengetopt by Lorenzo Bettini */
+
+#ifndef CMDLINE_H
+#define CMDLINE_H
+
+/* If we use autoconf.  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h> /* for FILE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef CMDLINE_PARSER_PACKAGE
+/** @brief the program name (used for printing errors) */
+#define CMDLINE_PARSER_PACKAGE PACKAGE
+#endif
+
+#ifndef CMDLINE_PARSER_PACKAGE_NAME
+/** @brief the complete program name (used for help and version) */
+#ifdef PACKAGE_NAME
+#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE_NAME
+#else
+#define CMDLINE_PARSER_PACKAGE_NAME PACKAGE
+#endif
+#endif
+
+#ifndef CMDLINE_PARSER_VERSION
+/** @brief the program version */
+#define CMDLINE_PARSER_VERSION VERSION
+#endif
+
+/** @brief Where the command line options are stored */
+struct gengetopt_args_info
+{
+  const char *help_help; /**< @brief Print help and exit help description.  */
+  const char *detailed_help_help; /**< @brief Print help, including all details and hidden options, and exit help description.  */
+  const char *version_help; /**< @brief Print version and exit help description.  */
+  char * input_arg;    /**< @brief input file (default std input).  */
+  char * input_orig;   /**< @brief input file (default std input) original value given at command line.  */
+  const char *input_help; /**< @brief input file (default std input) help description.  */
+  char * func_name_arg;        /**< @brief name of generated function (default='cmdline_parser').  */
+  char * func_name_orig;       /**< @brief name of generated function original value given at command line.  */
+  const char *func_name_help; /**< @brief name of generated function help description.  */
+  char * arg_struct_name_arg;  /**< @brief name of generated args info struct (default='gengetopt_args_info').  */
+  char * arg_struct_name_orig; /**< @brief name of generated args info struct original value given at command line.  */
+  const char *arg_struct_name_help; /**< @brief name of generated args info struct help description.  */
+  char * file_name_arg;        /**< @brief name of generated file (default='cmdline').  */
+  char * file_name_orig;       /**< @brief name of generated file original value given at command line.  */
+  const char *file_name_help; /**< @brief name of generated file help description.  */
+  char * output_dir_arg;       /**< @brief output directory.  */
+  char * output_dir_orig;      /**< @brief output directory original value given at command line.  */
+  const char *output_dir_help; /**< @brief output directory help description.  */
+  char * header_output_dir_arg;        /**< @brief header output directory.  */
+  char * header_output_dir_orig;       /**< @brief header output directory original value given at command line.  */
+  const char *header_output_dir_help; /**< @brief header output directory help description.  */
+  char * src_output_dir_arg;   /**< @brief source output directory.  */
+  char * src_output_dir_orig;  /**< @brief source output directory original value given at command line.  */
+  const char *src_output_dir_help; /**< @brief source output directory help description.  */
+  char * c_extension_arg;      /**< @brief extension of c file (default='c').  */
+  char * c_extension_orig;     /**< @brief extension of c file original value given at command line.  */
+  const char *c_extension_help; /**< @brief extension of c file help description.  */
+  char * header_extension_arg; /**< @brief extension of header file (default='h').  */
+  char * header_extension_orig;        /**< @brief extension of header file original value given at command line.  */
+  const char *header_extension_help; /**< @brief extension of header file help description.  */
+  const char *long_help_help; /**< @brief long usage line in help help description.  */
+  const char *default_optional_help; /**< @brief by default, an option is considered optional if not specified otherwise help description.  */
+  char * unamed_opts_arg;      /**< @brief accept options without names (e.g., file names) (default='FILES').  */
+  char * unamed_opts_orig;     /**< @brief accept options without names (e.g., file names) original value given at command line.  */
+  const char *unamed_opts_help; /**< @brief accept options without names (e.g., file names) help description.  */
+  const char *conf_parser_help; /**< @brief generate a config file parser help description.  */
+  const char *string_parser_help; /**< @brief generate a string parser (the string contains the command line) help description.  */
+  const char *include_getopt_help; /**< @brief adds the code for getopt_long in the generated C file help description.  */
+  const char *no_handle_help_help; /**< @brief do not handle --help|-h automatically help description.  */
+  const char *no_help_help; /**< @brief do not add --help|-h automatically help description.  */
+  const char *no_handle_version_help; /**< @brief do not handle --version|-V automatically help description.  */
+  const char *no_version_help; /**< @brief do not add --version|-V automatically help description.  */
+  const char *no_handle_error_help; /**< @brief do not exit on errors help description.  */
+  char * show_required_arg;    /**< @brief in the output of help will specify which options are mandatory, by using the optional passed string (default='(mandatory)').  */
+  char * show_required_orig;   /**< @brief in the output of help will specify which options are mandatory, by using the optional passed string original value given at command line.  */
+  const char *show_required_help; /**< @brief in the output of help will specify which options are mandatory, by using the optional passed string help description.  */
+  int gen_version_flag;        /**< @brief put gengetopt version in the generated file (default=on).  */
+  const char *gen_version_help; /**< @brief put gengetopt version in the generated file help description.  */
+  char * set_package_arg;      /**< @brief set the package name (override package defined in the .ggo file).  */
+  char * set_package_orig;     /**< @brief set the package name (override package defined in the .ggo file) original value given at command line.  */
+  const char *set_package_help; /**< @brief set the package name (override package defined in the .ggo file) help description.  */
+  char * set_version_arg;      /**< @brief set the version number (override version defined in the .ggo file).  */
+  char * set_version_orig;     /**< @brief set the version number (override version defined in the .ggo file) original value given at command line.  */
+  const char *set_version_help; /**< @brief set the version number (override version defined in the .ggo file) help description.  */
+  const char *show_help_help; /**< @brief show the output of --help instead of generating code help description.  */
+  const char *show_full_help_help; /**< @brief show the output of --full-help (i.e., including hidden options) instead of generating code help description.  */
+  const char *show_detailed_help_help; /**< @brief show the output of --detailed-help (i.e., including details and hidden options) instead of generating code help description.  */
+  const char *show_version_help; /**< @brief show the output of --version instead of generating code help description.  */
+  
+  unsigned int help_given ;    /**< @brief Whether help was given.  */
+  unsigned int detailed_help_given ;   /**< @brief Whether detailed-help was given.  */
+  unsigned int version_given ; /**< @brief Whether version was given.  */
+  unsigned int input_given ;   /**< @brief Whether input was given.  */
+  unsigned int func_name_given ;       /**< @brief Whether func-name was given.  */
+  unsigned int arg_struct_name_given ; /**< @brief Whether arg-struct-name was given.  */
+  unsigned int file_name_given ;       /**< @brief Whether file-name was given.  */
+  unsigned int output_dir_given ;      /**< @brief Whether output-dir was given.  */
+  unsigned int header_output_dir_given ;       /**< @brief Whether header-output-dir was given.  */
+  unsigned int src_output_dir_given ;  /**< @brief Whether src-output-dir was given.  */
+  unsigned int c_extension_given ;     /**< @brief Whether c-extension was given.  */
+  unsigned int header_extension_given ;        /**< @brief Whether header-extension was given.  */
+  unsigned int long_help_given ;       /**< @brief Whether long-help was given.  */
+  unsigned int default_optional_given ;        /**< @brief Whether default-optional was given.  */
+  unsigned int unamed_opts_given ;     /**< @brief Whether unamed-opts was given.  */
+  unsigned int conf_parser_given ;     /**< @brief Whether conf-parser was given.  */
+  unsigned int string_parser_given ;   /**< @brief Whether string-parser was given.  */
+  unsigned int include_getopt_given ;  /**< @brief Whether include-getopt was given.  */
+  unsigned int no_handle_help_given ;  /**< @brief Whether no-handle-help was given.  */
+  unsigned int no_help_given ; /**< @brief Whether no-help was given.  */
+  unsigned int no_handle_version_given ;       /**< @brief Whether no-handle-version was given.  */
+  unsigned int no_version_given ;      /**< @brief Whether no-version was given.  */
+  unsigned int no_handle_error_given ; /**< @brief Whether no-handle-error was given.  */
+  unsigned int show_required_given ;   /**< @brief Whether show-required was given.  */
+  unsigned int gen_version_given ;     /**< @brief Whether gen-version was given.  */
+  unsigned int set_package_given ;     /**< @brief Whether set-package was given.  */
+  unsigned int set_version_given ;     /**< @brief Whether set-version was given.  */
+  unsigned int show_help_given ;       /**< @brief Whether show-help was given.  */
+  unsigned int show_full_help_given ;  /**< @brief Whether show-full-help was given.  */
+  unsigned int show_detailed_help_given ;      /**< @brief Whether show-detailed-help was given.  */
+  unsigned int show_version_given ;    /**< @brief Whether show-version was given.  */
+
+} ;
+
+/** @brief The additional parameters to pass to parser functions */
+struct cmdline_parser_params
+{
+  int override; /**< @brief whether to override possibly already present options (default 0) */
+  int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */
+  int check_required; /**< @brief whether to check that all required options were provided (default 1) */
+  int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */
+  int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */
+} ;
+
+/** @brief the purpose string of the program */
+extern const char *gengetopt_args_info_purpose;
+/** @brief the usage string of the program */
+extern const char *gengetopt_args_info_usage;
+/** @brief all the lines making the help output */
+extern const char *gengetopt_args_info_help[];
+/** @brief all the lines making the detailed help output (including hidden options and details) */
+extern const char *gengetopt_args_info_detailed_help[];
+
+/**
+ * The command line parser
+ * @param argc the number of command line options
+ * @param argv the command line options
+ * @param args_info the structure where option information will be stored
+ * @return 0 if everything went fine, NON 0 if an error took place
+ */
+int cmdline_parser (int argc, char **argv,
+  struct gengetopt_args_info *args_info);
+
+/**
+ * The command line parser (version with additional parameters - deprecated)
+ * @param argc the number of command line options
+ * @param argv the command line options
+ * @param args_info the structure where option information will be stored
+ * @param override whether to override possibly already present options
+ * @param initialize whether to initialize the option structure my_args_info
+ * @param check_required whether to check that all required options were provided
+ * @return 0 if everything went fine, NON 0 if an error took place
+ * @deprecated use cmdline_parser_ext() instead
+ */
+int cmdline_parser2 (int argc, char **argv,
+  struct gengetopt_args_info *args_info,
+  int override, int initialize, int check_required);
+
+/**
+ * The command line parser (version with additional parameters)
+ * @param argc the number of command line options
+ * @param argv the command line options
+ * @param args_info the structure where option information will be stored
+ * @param params additional parameters for the parser
+ * @return 0 if everything went fine, NON 0 if an error took place
+ */
+int cmdline_parser_ext (int argc, char **argv,
+  struct gengetopt_args_info *args_info,
+  struct cmdline_parser_params *params);
+
+/**
+ * Save the contents of the option struct into an already open FILE stream.
+ * @param outfile the stream where to dump options
+ * @param args_info the option struct to dump
+ * @return 0 if everything went fine, NON 0 if an error took place
+ */
+int cmdline_parser_dump(FILE *outfile,
+  struct gengetopt_args_info *args_info);
+
+/**
+ * Save the contents of the option struct into a (text) file.
+ * This file can be read by the config file parser (if generated by gengetopt)
+ * @param filename the file where to save
+ * @param args_info the option struct to save
+ * @return 0 if everything went fine, NON 0 if an error took place
+ */
+int cmdline_parser_file_save(const char *filename,
+  struct gengetopt_args_info *args_info);
+
+/**
+ * Print the help
+ */
+void cmdline_parser_print_help(void);
+/**
+ * Print the detailed help (including hidden options and details)
+ */
+void cmdline_parser_print_detailed_help(void);
+/**
+ * Print the version
+ */
+void cmdline_parser_print_version(void);
+
+/**
+ * Initializes all the fields a cmdline_parser_params structure 
+ * to their default values
+ * @param params the structure to initialize
+ */
+void cmdline_parser_params_init(struct cmdline_parser_params *params);
+
+/**
+ * Allocates dynamically a cmdline_parser_params structure and initializes
+ * all its fields to their default values
+ * @return the created and initialized cmdline_parser_params structure
+ */
+struct cmdline_parser_params *cmdline_parser_params_create(void);
+
+/**
+ * Initializes the passed gengetopt_args_info structure's fields
+ * (also set default values for options that have a default)
+ * @param args_info the structure to initialize
+ */
+void cmdline_parser_init (struct gengetopt_args_info *args_info);
+/**
+ * Deallocates the string fields of the gengetopt_args_info structure
+ * (but does not deallocate the structure itself)
+ * @param args_info the structure to deallocate
+ */
+void cmdline_parser_free (struct gengetopt_args_info *args_info);
+
+/**
+ * The string parser (interprets the passed string as a command line)
+ * @param cmdline the command line stirng
+ * @param args_info the structure where option information will be stored
+ * @param prog_name the name of the program that will be used to print
+ *   possible errors
+ * @return 0 if everything went fine, NON 0 if an error took place
+ */
+int cmdline_parser_string (const char *cmdline, struct gengetopt_args_info *args_info,
+  const char *prog_name);
+/**
+ * The string parser (version with additional parameters - deprecated)
+ * @param cmdline the command line stirng
+ * @param args_info the structure where option information will be stored
+ * @param prog_name the name of the program that will be used to print
+ *   possible errors
+ * @param override whether to override possibly already present options
+ * @param initialize whether to initialize the option structure my_args_info
+ * @param check_required whether to check that all required options were provided
+ * @return 0 if everything went fine, NON 0 if an error took place
+ * @deprecated use cmdline_parser_string_ext() instead
+ */
+int cmdline_parser_string2 (const char *cmdline, struct gengetopt_args_info *args_info,
+  const char *prog_name,
+  int override, int initialize, int check_required);
+/**
+ * The string parser (version with additional parameters)
+ * @param cmdline the command line stirng
+ * @param args_info the structure where option information will be stored
+ * @param prog_name the name of the program that will be used to print
+ *   possible errors
+ * @param params additional parameters for the parser
+ * @return 0 if everything went fine, NON 0 if an error took place
+ */
+int cmdline_parser_string_ext (const char *cmdline, struct gengetopt_args_info *args_info,
+  const char *prog_name,
+  struct cmdline_parser_params *params);
+
+/**
+ * Checks that all the required options were specified
+ * @param args_info the structure to check
+ * @param prog_name the name of the program that will be used to print
+ *   possible errors
+ * @return
+ */
+int cmdline_parser_required (struct gengetopt_args_info *args_info,
+  const char *prog_name);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* CMDLINE_H */
diff --git a/cmake/gengetopt/errorcodes.h b/cmake/gengetopt/errorcodes.h
new file mode 100644 (file)
index 0000000..c81ded0
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// C++ Interface: errorcodes
+//
+// Description: 
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef ERRORCODES_H
+#define ERRORCODES_H
+
+#define NOT_ENOUGH_MEMORY 1
+#define REQ_LONG_OPTION 2
+#define REQ_SHORT_OPTION 3
+#define FOUND_BUG 4
+#define GROUP_UNDEFINED 5
+#define INVALID_DEFAULT_VALUE 6
+#define NOT_REQUESTED_TYPE 7
+#define NOT_VALID_SPECIFICATION 8
+#define SPECIFY_FLAG_STAT 9
+#define NOT_GROUP_OPTION 10
+#define SPECIFY_GROUP 11
+#define INVALID_NUMERIC_VALUE 12
+#define INVALID_ENUM_TYPE_USE 13
+#define MODE_UNDEFINED 14
+#define NOT_MODE_OPTION 15
+#define SPECIFY_MODE 16
+#define HELP_REDEFINED 17
+#define VERSION_REDEFINED 18
+
+#endif
diff --git a/cmake/gengetopt/fileutils.cpp b/cmake/gengetopt/fileutils.cpp
new file mode 100644 (file)
index 0000000..d97782c
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// C++ Implementation: fileutils
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include "fileutils.h"
+
+using namespace std;
+
+char *
+create_filename (char *name, char *ext)
+{
+  char *filename ;
+
+  filename = (char *) malloc (strlen (name) + strlen (ext) + 2);
+  /* 2 = 1 for the . and one for the '\0' */
+  if (! filename)
+    {
+      fprintf (stderr, "Error in memory allocation! %s %d\n",
+               __FILE__, __LINE__);
+      abort ();
+    }
+
+  sprintf (filename, "%s.%s", name, ext);
+
+  return filename ;
+}
+
+ofstream *
+open_fstream (const char *filename)
+{
+  ofstream *fstream = new ofstream (filename);
+
+  if ( ! (*fstream) )
+    {
+      fprintf( stderr, "Error creating %s\n", filename ) ;
+      abort() ;
+    }
+
+  return fstream;
+}
diff --git a/cmake/gengetopt/fileutils.h b/cmake/gengetopt/fileutils.h
new file mode 100644 (file)
index 0000000..013b7a6
--- /dev/null
@@ -0,0 +1,23 @@
+//
+// C++ Interface: fileutils
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef FILEUTILS_H
+#define FILEUTILS_H
+
+#include <fstream>
+
+using std::ofstream;
+
+char *create_filename (char *name, char *ext);
+ofstream *open_fstream (const char *filename);
+
+#endif
diff --git a/cmake/gengetopt/gengetopt.cc b/cmake/gengetopt/gengetopt.cc
new file mode 100644 (file)
index 0000000..8ad790e
--- /dev/null
@@ -0,0 +1,950 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+void gengetopt_free (void);
+
+/* The following one is generated by gengetopt itself */
+#include "cmdline.h"
+
+extern int yyparse () ;
+
+#include "gengetopt.h"
+#include "errorcodes.h"
+
+#include "argsdef.h"
+#include "global_opts.h"
+
+#include "my_sstream.h"
+#include "my_string.h"
+
+#include "gm.h"
+#include "groups.h"
+#include "gm_utils.h"
+
+#include "skels/copyright.h"
+
+#include "yyerror.h"
+#include "globals.h"
+
+char * gengetopt_package = NULL;
+char * gengetopt_version = NULL;
+char * gengetopt_purpose = NULL;
+char * gengetopt_description = NULL;
+char * gengetopt_usage = NULL;
+
+modes_collection_t gengetopt_modes;
+
+int gengetopt_count_line = 1;
+char * gengetopt_input_filename = 0;
+char *current_section = 0;
+char *current_section_desc = 0;
+char *current_text = 0;
+char *current_args = 0;
+
+/// whether, if not specified, an option is considered optional
+bool default_to_optional = false;
+
+int canonize_vars (void);
+static void set_default_required_properties(void);
+
+static void print_copyright();
+static void print_reportbugs();
+
+static void output_formatted_string(const string &);
+
+static bool check_dependencies();
+
+static int gengetopt_create_option (gengetopt_option *&opt, const char * long_opt, char short_opt,
+                          const char * desc,
+                          int type, int flagstat, int required,
+                          const char *default_value,
+                          const char * group_value,
+                          const char * mode_value,
+                          const char * type_str,
+                          const AcceptedValues *acceptedvalues,
+                          int multiple = 0,
+                          int argoptional = 0);
+
+
+#include <algorithm>
+#include <iterator>
+
+using namespace std;
+
+/// the structure for command line arguments
+struct gengetopt_args_info args_info ;
+
+int
+main (int argc, char **argv)
+{
+  char *cmdline_parser_name ; /* name of the generated function */
+  char *cmdline_filename ; /* name of generated file */
+  char *c_ext ; /* extenstion of c file */
+  char *header_ext  ; /* extenstion of header file */
+  string output_dir, header_output_dir, src_output_dir; /* output directory (default empty -> current dir)*/
+
+  int i, has_help, has_version;
+  FILE *input_file ;
+
+  if (cmdline_parser (argc, argv, &args_info) != 0) {
+      fprintf (stderr, "Run gengetopt --help to see the list of options.\n");
+      exit(1) ;
+  }
+
+  if (args_info.help_given)
+  {
+    cmdline_parser_print_help ();
+    print_reportbugs ();
+    exit (0);
+  }
+
+  if (args_info.detailed_help_given)
+    {
+      cmdline_parser_print_detailed_help ();
+      print_reportbugs ();
+      exit (0);
+    }
+
+  if (args_info.version_given)
+  {
+    cmdline_parser_print_version ();
+    print_copyright ();
+    exit (0);
+  }
+
+  if ( args_info.input_arg )
+    {
+      gengetopt_input_filename = strdup (args_info.input_arg);
+      input_file = freopen (args_info.input_arg, "r", stdin) ;
+      if (!input_file)
+        {
+          fprintf (stderr, "Error opening input file: %s\n",
+                   args_info.input_arg);
+          exit (1);
+        }
+    } /* else standard input is used */
+
+  if (yyparse () != 0) {
+        gengetopt_free ();
+        return 1;
+  }
+
+  // check whether some options were given in the input file
+  bool no_options = (gengetopt_options.size() == 0);
+
+  if (current_args) {
+    // parse the arguments passed in the "args" part of the input file
+    // by possibily overriding those given at command line
+    if (cmdline_parser_string2 (current_args, &args_info, "gengetopt", 1, 0, 0) != 0) {
+      fprintf (stderr, "Error in the args specification of the input_file.\n");
+      exit(1) ;
+    }
+  }
+
+  cmdline_parser_name = args_info.func_name_arg ;
+  cmdline_filename = args_info.file_name_arg ;
+  c_ext = args_info.c_extension_arg;
+  header_ext = args_info.header_extension_arg;
+
+  default_to_optional = args_info.default_optional_given;
+
+  // now set the default "required" property for options
+  set_default_required_properties();
+
+  if (! check_dependencies()) {
+    gengetopt_free();
+    return 1;
+  }
+
+  // insert options for help and version if not already present
+  gengetopt_option *opt;
+
+  if (current_section)
+    free(current_section);
+  current_section = 0;
+
+  has_version = gengetopt_has_option (VERSION_LONG_OPT, VERSION_SHORT_OPT);
+
+  if (has_version != REQ_LONG_OPTION && !args_info.no_version_given) {
+    gengetopt_create_option (opt, VERSION_LONG_OPT, has_version ? '-' : VERSION_SHORT_OPT,
+                                 VERSION_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0, 0);
+    gengetopt_options.push_front(opt);
+  }
+
+  if (!args_info.no_help_given && has_hidden_options() && gengetopt_has_option(FULL_HELP_LONG_OPT, 0) == 0) {
+      gengetopt_create_option (opt, FULL_HELP_LONG_OPT, '-',
+                               FULL_HELP_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0, 0);
+      gengetopt_options.push_front(opt);
+  }
+
+  if (!args_info.no_help_given && has_options_with_details() && gengetopt_has_option(DETAILED_HELP_LONG_OPT, 0) == 0) {
+      gengetopt_create_option (opt, DETAILED_HELP_LONG_OPT, '-',
+              DETAILED_HELP_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0, 0);
+      gengetopt_options.push_front(opt);
+  }
+
+  has_help = gengetopt_has_option(HELP_LONG_OPT, HELP_SHORT_OPT);
+
+  if (has_help != REQ_LONG_OPTION && !args_info.no_help_given) {
+    gengetopt_create_option (opt, HELP_LONG_OPT, has_help ? '-' : HELP_SHORT_OPT,
+                                 HELP_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0, 0);
+    gengetopt_options.push_front(opt);
+  }
+
+  // check whether there's pending text after all options and
+  // in case, set it to the last option
+  if (current_text && gengetopt_options.size()) {
+    gengetopt_options.back()->text_after = current_text;
+    gengetopt_set_text(0);
+  }
+
+  if (canonize_vars ()) {
+        gengetopt_free ();
+        return 1;
+  }
+
+  if (args_info.set_package_given) {
+    if (gengetopt_package)
+      free (gengetopt_package);
+    gengetopt_package = args_info.set_package_arg;
+  }
+
+  if (args_info.set_version_given) {
+    if (gengetopt_version)
+      free (gengetopt_version);
+    gengetopt_version = args_info.set_version_arg;
+  }
+
+  ostringstream command_line;
+  for ( i = 0; i < argc ; ++i )
+      command_line << argv[i] << " ";
+
+  // add also possible args specification in the input file
+  if (current_args)
+    command_line << current_args;
+
+  if (args_info.output_dir_given)
+      output_dir = args_info.output_dir_arg;
+  if (args_info.header_output_dir_given)
+      header_output_dir = args_info.header_output_dir_arg;
+  if (args_info.src_output_dir_given)
+      src_output_dir = args_info.src_output_dir_arg;
+
+  CmdlineParserCreator cmdline_parser_creator
+    (cmdline_parser_name,
+     args_info.arg_struct_name_arg,
+     (args_info.unamed_opts_given ? args_info.unamed_opts_arg : 0),
+     cmdline_filename,
+     header_ext,
+     c_ext,
+     args_info.long_help_given,
+     args_info.no_handle_help_given,
+     args_info.no_help_given,
+     args_info.no_handle_version_given,
+     args_info.no_version_given,
+     args_info.no_handle_error_given,
+     args_info.conf_parser_given,
+     args_info.string_parser_given,
+     args_info.gen_version_flag,
+     args_info.include_getopt_given,
+     no_options,
+     command_line.str (),
+     output_dir,
+     header_output_dir,
+     src_output_dir,
+     (args_info.show_required_given ? args_info.show_required_arg : ""));
+
+  if (! gengetopt_package && (args_info.show_version_given || args_info.show_help_given))
+    {
+      cerr << "package not defined; please specify it with --set-package" << endl;
+      return 1;
+    }
+  else if (! gengetopt_version && (args_info.show_version_given || args_info.show_help_given))
+    {
+      cerr << "version not defined; please specify it with --set-version" << endl;
+      return 1;
+    }
+  else if (args_info.show_version_given)
+    {
+      cout << gengetopt_package << " " << gengetopt_version << endl;
+    }
+  else if (args_info.show_help_given ||
+          args_info.show_full_help_given || args_info.show_detailed_help_given)
+    {
+      cout << gengetopt_package << " " << gengetopt_version << "\n" << endl;
+
+      if (gengetopt_purpose) {
+        output_formatted_string(cmdline_parser_creator.generate_purpose());
+        cout << endl;
+      }
+
+      output_formatted_string("Usage: " +
+        cmdline_parser_creator.generate_usage_string(false) + "\n");
+
+      if (gengetopt_description) {
+        output_formatted_string(cmdline_parser_creator.generate_description());
+        cout << endl;
+      }
+
+      // if --show-full-help is specified we have to generate also hidden options
+      OptionHelpList *option_list =
+          cmdline_parser_creator.generate_help_option_list(args_info.show_full_help_given, args_info.show_detailed_help_given);
+
+      std::for_each(option_list->begin(), option_list->end(),
+              output_formatted_string);
+
+      delete option_list;
+    }
+  else if (cmdline_parser_creator.generate ())
+    {
+        gengetopt_free ();
+        return 1;
+    }
+
+  gengetopt_free ();
+
+  return 0;
+}
+
+void
+output_formatted_string(const string &s)
+{
+  for (string::const_iterator it = s.begin(); it != s.end(); ++it)
+    {
+      if (*it == '\\' && ((it+1) != s.end()) && *(it+1) == 'n') {
+        cout << "\n";
+        ++it;
+      } else if (*it == '\\' && ((it+1) != s.end()) && *(it+1) == '"') {
+        cout << "\"";
+        ++it;
+      } else
+        cout << *it;
+    }
+
+  cout << endl;
+}
+
+/* ************* */
+
+int
+gengetopt_define_package (char * s)
+{
+        gengetopt_package = strdup (s);
+        if (gengetopt_package == NULL)
+                return 1;
+        return 0;
+}
+
+int
+gengetopt_define_version (char * s)
+{
+        gengetopt_version = strdup (s);
+        if (gengetopt_version == NULL)
+                return 1;
+        return 0;
+}
+
+int
+gengetopt_define_purpose (char * s)
+{
+  gengetopt_purpose = strdup (s);
+  if (gengetopt_purpose == NULL)
+    return 1;
+  return 0;
+}
+
+int
+gengetopt_define_description (char * s)
+{
+  gengetopt_description = strdup (s);
+  if (gengetopt_description == NULL)
+    return 1;
+  return 0;
+}
+
+int gengetopt_define_usage (char * s)
+{
+  gengetopt_usage = strdup (s);
+  if (gengetopt_usage == NULL)
+    return 1;
+  return 0;
+}
+
+int
+gengetopt_add_group (const char *s, const char *desc, int required)
+{
+  string group_desc;
+  if (desc)
+    group_desc = desc;
+  if ( !gengetopt_groups.insert
+       (make_pair(string(s),Group (group_desc, required != 0))).second )
+    return 1;
+  else
+    return 0;
+}
+
+int
+gengetopt_add_mode (const char *s, const char *desc)
+{
+  string mode_desc;
+  if (desc)
+    mode_desc = desc;
+  if ( !gengetopt_modes.insert
+       (make_pair(string(s),Mode (mode_desc))).second )
+    return 1;
+  else
+    return 0;
+}
+
+void
+gengetopt_set_section (const char * s, const char *desc)
+{
+  if (current_section)
+    free (current_section);
+  if (current_section_desc)
+    free (current_section_desc);
+  current_section = strdup (s);
+  if (desc)
+    current_section_desc = strdup (desc);
+  else
+    current_section_desc = 0;
+}
+
+void
+gengetopt_set_text (const char * desc)
+{
+  /*
+  no need to free it, since it will be then owned by the
+  option only
+
+  if (current_text)
+    free (current_text);
+  */
+
+  // the current text is reset
+  if (!desc) {
+    current_text = 0;
+    return;
+  }
+
+  if (current_text) {
+    // a previous text was collected, so we append the new text
+    // to the current one.
+    string buffer = current_text;
+    buffer += desc;
+    current_text = strdup(buffer.c_str());
+    return;
+  }
+
+  // otherwise simply copy the passed text
+  current_text = strdup (desc);
+}
+
+void gengetopt_set_args(const char *a)
+{
+  if (current_args)
+    free(current_args);
+
+  if (a)
+    current_args = strdup(a);
+  else
+    current_args = 0;
+}
+
+int
+gengetopt_has_option (const char * long_opt, char short_opt)
+{
+  gengetopt_option * n;
+
+  for (gengetopt_option_list::const_iterator it = gengetopt_options.begin();
+       it != gengetopt_options.end(); ++it)
+    {
+      n = *it;
+      if (!strcmp (n->long_opt, long_opt)) return REQ_LONG_OPTION;
+      if (short_opt && n->short_opt == short_opt)
+        return REQ_SHORT_OPTION;
+    }
+
+  return 0;
+}
+
+bool check_numeric_validity(const char *val, int opt_type)
+{
+    char *end_of_string, *expected_eos;
+
+    expected_eos = (char *) (val + strlen(val));
+
+    switch ( opt_type )
+      {
+      case ARG_INT :
+      case ARG_SHORT :
+      case ARG_LONG :
+      case ARG_LONGLONG :
+        (void) strtol(val, &end_of_string, 0);
+        break;
+
+      case ARG_FLOAT:
+      case ARG_DOUBLE:
+      case ARG_LONGDOUBLE:
+        (void) strtod(val, &end_of_string);
+        break;
+
+      default :
+        // This will allow us to factorise as a single line the
+        // test for correctness of the default value
+        end_of_string = expected_eos;
+        break;
+      }
+    return ( end_of_string == expected_eos );
+}
+
+bool
+check_values(const AcceptedValues *acceptedvalues, int opt_type)
+{
+    for (AcceptedValues::const_iterator it = acceptedvalues->begin();
+        it != acceptedvalues->end(); ++it) {
+        if (!check_numeric_validity((*it).c_str(), opt_type))
+            return false;
+    }
+
+    return true;
+}
+
+int
+gengetopt_create_option (gengetopt_option *&n, const char * long_opt, char short_opt,
+                      const char * desc,
+                      int type, int flagstat, int required,
+                      const char * default_value,
+                      const char * group_value,
+                      const char * mode_value,
+                      const char * type_str,
+                      const AcceptedValues *acceptedvalues,
+                      int multiple,
+                      int argoptional)
+{
+  if ((long_opt == NULL) ||
+      (long_opt[0] == 0) ||
+      (desc == NULL))
+    return FOUND_BUG;
+
+  n = new gengetopt_option;
+  if (n == NULL)
+    return NOT_ENOUGH_MEMORY;
+
+  // here we will set required anyway
+  n->required_set = true;
+
+  n->long_opt = strdup (long_opt);
+  if (n->long_opt == NULL)
+    {
+      free (n);
+      return NOT_ENOUGH_MEMORY;
+    }
+
+  n->desc = strdup (desc);
+  if (n->desc == NULL)
+    {
+      free (n->long_opt);
+      free (n);
+      return NOT_ENOUGH_MEMORY;
+    }
+
+  n->short_opt = ((short_opt == '-') ? 0 : short_opt);
+  n->type = type;
+  n->flagstat = flagstat;
+  n->required = required;
+  n->multiple = (multiple != 0);
+  n->arg_is_optional = (argoptional != 0);
+
+  if (type_str != 0)
+    n->type_str = strdup(type_str);
+  else
+    n->type_str = NULL;
+
+  n->section = 0;
+  n->section_desc = 0;
+  if (current_section)
+    n->section = strdup (current_section);
+  if (current_section_desc)
+    n->section_desc = strdup (current_section_desc);
+
+  if (group_value != 0)
+    {
+      n->group_value = strdup(group_value);
+      n->required = 0;
+      groups_collection_t::const_iterator it =
+        gengetopt_groups.find(string(n->group_value));
+      if (it == gengetopt_groups.end())
+        return GROUP_UNDEFINED;
+      n->group_desc = strdup (it->second.desc.c_str ());
+    }
+  else
+    {
+      n->group_value = 0;
+    }
+
+  if (mode_value != 0) {
+      n->mode_value = strdup(mode_value);
+      modes_collection_t::const_iterator it =
+          gengetopt_modes.find(string(n->mode_value));
+      if (it == gengetopt_modes.end())
+          return MODE_UNDEFINED;
+      n->mode_desc = strdup (it->second.desc.c_str ());
+  } else {
+      n->mode_value = 0;
+  }
+
+  if (n->group_value && n->mode_value)
+      return FOUND_BUG;
+
+
+  n->acceptedvalues = acceptedvalues;
+
+  // if (acceptedvalues && type != ARG_NO)
+  // return NOT_REQUESTED_TYPE;
+
+  if (acceptedvalues && ! (n->type))
+    n->type = ARG_STRING;
+
+  n->default_string = 0;
+  n->default_given = (default_value != 0);
+  if (n->default_given)
+    {
+      n->default_string = strdup (default_value);
+      if ( ! check_numeric_validity(default_value, n->type) )
+        {
+          free (n);
+          return INVALID_DEFAULT_VALUE;
+        }
+
+      if (acceptedvalues)
+        {
+          if (! acceptedvalues->contains(n->default_string))
+            return INVALID_DEFAULT_VALUE;
+        }
+    }
+
+  if (acceptedvalues) {
+      if (!check_values(acceptedvalues, n->type))
+          return INVALID_NUMERIC_VALUE;
+  }
+
+  n->var_arg = NULL;
+
+  return 0;
+}
+
+int
+gengetopt_check_option (gengetopt_option *n, bool groupoption, bool modeoption)
+{
+  if ((n->long_opt == NULL) ||
+      (n->long_opt[0] == 0) ||
+      (n->desc == NULL))
+    return FOUND_BUG;
+
+  if (strcmp(n->long_opt, HELP_LONG_OPT) == 0 && !args_info.no_help_given)
+      return HELP_REDEFINED;
+
+  if (strcmp(n->long_opt, VERSION_LONG_OPT) == 0 && !args_info.no_version_given)
+      return VERSION_REDEFINED;
+
+  n->section = 0;
+  n->section_desc = 0;
+  if (current_section)
+    n->section = strdup (current_section);
+  if (current_section_desc)
+    n->section_desc = strdup (current_section_desc);
+
+  n->text_before = current_text;
+  // reset the description
+  gengetopt_set_text(0);
+
+  if (n->group_value != 0)
+  {
+      if (! groupoption)
+          return NOT_GROUP_OPTION;
+
+      n->required = 0;
+      n->required_set = true;
+
+      groups_collection_t::const_iterator it =
+          gengetopt_groups.find(string(n->group_value));
+      if (it == gengetopt_groups.end())
+          return GROUP_UNDEFINED;
+      n->group_desc = strdup (it->second.desc.c_str ());
+  }
+  else
+  {
+      if (groupoption)
+          return SPECIFY_GROUP;
+  }
+
+  if (n->mode_value != 0)
+  {
+      if (! modeoption)
+          return NOT_MODE_OPTION;
+
+      modes_collection_t::const_iterator it =
+          gengetopt_modes.find(string(n->mode_value));
+      if (it == gengetopt_modes.end())
+          return MODE_UNDEFINED;
+      n->mode_desc = strdup (it->second.desc.c_str ());
+  }
+  else
+  {
+      if (modeoption)
+          return SPECIFY_MODE;
+  }
+
+  if (n->group_value && n->mode_value)
+      return FOUND_BUG;
+
+  // now we have to check for flag options
+  if (n->type == ARG_FLAG)
+  {
+    if (n->flagstat < 0)
+      return SPECIFY_FLAG_STAT;
+
+    if (n->default_string || n->multiple || n->arg_is_optional
+        || n->type_str || n->acceptedvalues || n->required_set)
+      return NOT_VALID_SPECIFICATION;
+
+    n->required = 0;
+    n->required_set = true;
+  }
+  else
+  {
+    if (n->flagstat >= 0)
+      return NOT_VALID_SPECIFICATION;
+  }
+
+  // enum type can only be specified with options with values
+  if (n->type == ARG_ENUM && !(n->acceptedvalues)) {
+      return INVALID_ENUM_TYPE_USE;
+  }
+
+  // if (acceptedvalues && type != ARG_NO)
+  // return NOT_REQUESTED_TYPE;
+
+  if (n->acceptedvalues && ! (n->type))
+    n->type = ARG_STRING;
+
+  n->default_given = (n->default_string != 0);
+  if (n->default_given)
+    {
+      if ( !check_numeric_validity(n->default_string, n->type) )
+        {
+          return INVALID_DEFAULT_VALUE;
+        }
+
+      if (n->acceptedvalues)
+        {
+          if (! n->acceptedvalues->contains(n->default_string))
+            return INVALID_DEFAULT_VALUE;
+        }
+    }
+
+  if (n->acceptedvalues) {
+      if (!check_values(n->acceptedvalues, n->type))
+          return INVALID_NUMERIC_VALUE;
+  }
+
+  n->var_arg = NULL;
+
+  return 0;
+}
+
+int
+gengetopt_add_option (const char * long_opt, char short_opt,
+                      const char * desc,
+                      int type, int flagstat, int required,
+                      const char * default_value,
+                      const char * group_value,
+                      const char * mode_value,
+                      const char * type_str,
+                      const AcceptedValues *acceptedvalues,
+                      int multiple,
+                      int argoptional)
+{
+  gengetopt_option * n;
+
+  /* search for collisions */
+  int res = gengetopt_has_option(long_opt, short_opt);
+  if (res != 0)
+    return res;
+
+  res = gengetopt_create_option(n, long_opt, short_opt,
+    desc, type, flagstat, required, default_value, group_value, mode_value,
+    type_str, acceptedvalues, multiple, argoptional);
+  if (res != 0)
+    return res;
+
+  gengetopt_options.push_back(n);
+
+  return 0;
+}
+
+int
+gengetopt_add_option (gengetopt_option * n)
+{
+  /* search for collisions */
+  int res = gengetopt_has_option(n);
+  if (res != 0)
+    return res;
+
+  gengetopt_options.push_back(n);
+
+  return 0;
+}
+
+int
+gengetopt_has_option (gengetopt_option * opt)
+{
+  gengetopt_option * n;
+
+  for (gengetopt_option_list::const_iterator it = gengetopt_options.begin();
+       it != gengetopt_options.end(); ++it)
+    {
+      n = *it;
+      if (!strcmp (n->long_opt, opt->long_opt))
+        return REQ_LONG_OPTION;
+      if (opt->short_opt && n->short_opt == opt->short_opt)
+        return REQ_SHORT_OPTION;
+    }
+
+  return 0;
+}
+
+bool
+check_dependencies()
+{
+  gengetopt_option * n;
+  bool result = true;
+
+  for (gengetopt_option_list::const_iterator it = gengetopt_options.begin();
+       it != gengetopt_options.end(); ++it)
+  {
+    n = *it;
+    if (n->dependon) {
+        if (strcmp(n->dependon, n->long_opt) == 0) {
+            yyerror(n, "option depends on itself");
+            result = false;
+            continue;
+        }
+
+        bool found = false;
+        for (gengetopt_option_list::const_iterator it2 = gengetopt_options.begin();
+            it2 != gengetopt_options.end(); ++it2)
+        {
+            if (strcmp(n->dependon, (*it2)->long_opt) == 0) {
+                found = true;
+                break;
+            }
+        }
+
+        if (! found) {
+            yyerror (n, "option depends on undefined option");
+            result = false;
+        }
+    }
+  }
+
+  return result;
+}
+
+void
+gengetopt_free (void)
+{
+  gengetopt_option *p;
+
+  if (gengetopt_package != NULL)
+    free (gengetopt_package);
+
+  for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it != gengetopt_options.end(); ++it)
+  {
+        p = *it;
+        if (p->long_opt != NULL) free (p->long_opt);
+        if (p->desc != NULL) free (p->desc);
+        if (p->var_arg != NULL) free (p->var_arg);
+        if (p->acceptedvalues) delete p->acceptedvalues;
+        delete p;
+  }
+}
+
+static void
+canonize_var (gengetopt_option *p)
+{
+  char *pvar;
+
+  p->var_arg = strdup (p->long_opt);
+  if (p->var_arg == NULL) {
+      printf ("gengetopt: not enough memory to canonize vars\n");
+      abort();
+  }
+
+  for (pvar = p->var_arg; *pvar; pvar++)
+    if (*pvar == '.' || *pvar == '-') *pvar = '_';
+}
+
+int
+canonize_vars (void)
+{
+  for_each(gengetopt_options.begin(), gengetopt_options.end(), canonize_var);
+
+  return 0;
+}
+
+static void
+set_default_required_prop (gengetopt_option *p)
+{
+    if (!p->required_set)
+        p->required = (default_to_optional ? 0 : 1);
+}
+
+static void set_default_required_properties(void)
+{
+  for_each(gengetopt_options.begin(), gengetopt_options.end(), set_default_required_prop);
+}
+
+void
+print_copyright()
+{
+  copyright_gen_class copyright_g;
+
+  copyright_g.set_year ("1999-2009");
+  copyright_g.generate_copyright (cout);
+}
+
+void
+print_reportbugs()
+{
+  cout << endl;
+  cout << "Maintained by Lorenzo Bettini <http://www.lorenzobettini.it>" << endl;
+  cout << "Report bugs to <bug-gengetopt at gnu.org>" << endl;
+}
diff --git a/cmake/gengetopt/gengetopt.h b/cmake/gengetopt/gengetopt.h
new file mode 100644 (file)
index 0000000..c464ea2
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GENGETOPT_H
+#define _GENGETOPT_H
+
+#include "acceptedvalues.h"
+#include "ggos.h"
+
+int gengetopt_define_package (char * s) ;
+int gengetopt_define_version (char * s) ;
+int gengetopt_define_purpose (char * s) ;
+int gengetopt_define_description (char * s) ;
+int gengetopt_define_usage (char * s) ;
+
+/**
+ * Sets the "global" section specification that will be then set
+ * in the following options
+ * @param s The section
+ * @param sd The section description
+ */
+void gengetopt_set_section (const char * s, const char *sd) ;
+
+/**
+ * Sets the "global" text string that will be inserted in
+ * a specific field of the next option
+ * @param desc The text string
+ */
+void gengetopt_set_text (const char * desc) ;
+
+/**
+ * Sets the "global" text string containing the arguments
+ * that complement the command line arguments of gengetopt.
+ * @param args
+ */
+void gengetopt_set_args (const char *args);
+
+int gengetopt_add_group (const char * s, const char *desc, int required) ;
+int gengetopt_add_mode (const char * s, const char *desc) ;
+
+int gengetopt_has_option (const char * long_opt, char short_opt);
+int gengetopt_add_option (const char * long_opt, char short_opt,
+                          const char * desc,
+                          int type, int flagstat, int required,
+                          const char *default_value,
+                          const char * group_value,
+                          const char * mode_value,
+                          const char * type_str,
+                          const AcceptedValues *acceptedvalues,
+                          int multiple = 0,
+                          int argoptional = 0);
+
+int gengetopt_has_option (gengetopt_option *opt);
+int gengetopt_check_option (gengetopt_option *opt,
+    bool groupoption = false, bool modeoption = false);
+int gengetopt_add_option (gengetopt_option *opt);
+
+#endif /* _GENGETOPT_H */
diff --git a/cmake/gengetopt/getopt.c b/cmake/gengetopt/getopt.c
new file mode 100644 (file)
index 0000000..9fb69b1
--- /dev/null
@@ -0,0 +1,1055 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to drepper@gnu.org
+   before changing it!
+   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+       Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+\f
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+# ifndef const
+#  define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#  define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library.  */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+#  include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.  */
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+#  include <libintl.h>
+#  ifndef _
+#   define _(msgid)    gettext (msgid)
+#  endif
+# else
+#  define _(msgid)     (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+\f
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+# include <string.h>
+# define my_index      strchr
+#else
+
+# if HAVE_STRING_H
+#  include <string.h>
+# else
+#  include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+       return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.  */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+   That was relevant to code that was here before.  */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+   and has done so at least since version 2.4.5. -- rms.  */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+\f
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Stored original parameters.
+   XXX This is no good solution.  We should rather copy the args so
+   that we can compare them later.  But we must not use malloc(3).  */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+#  define SWAP_FLAGS(ch1, ch2) \
+  if (nonoption_flags_len > 0)                                               \
+    {                                                                        \
+      char __tmp = __getopt_nonoption_flags[ch1];                            \
+      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
+      __getopt_nonoption_flags[ch2] = __tmp;                                 \
+    }
+# else
+#  define SWAP_FLAGS(ch1, ch2)
+# endif
+#else  /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  /* First make sure the handling of the `__getopt_nonoption_flags'
+     string can work normally.  Our top argument must be in the range
+     of the string.  */
+  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+    {
+      /* We must extend the array.  The user plays games with us and
+        presents new arguments.  */
+      char *new_str = malloc (top + 1);
+      if (new_str == NULL)
+       nonoption_flags_len = nonoption_flags_max_len = 0;
+      else
+       {
+         memset (__mempcpy (new_str, __getopt_nonoption_flags,
+                            nonoption_flags_max_len),
+                 '\0', top + 1 - nonoption_flags_max_len);
+         nonoption_flags_max_len = top + 1;
+         __getopt_nonoption_flags = new_str;
+       }
+    }
+#endif
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+       {
+         /* Bottom segment is the short one.  */
+         int len = middle - bottom;
+         register int i;
+
+         /* Swap it with the top part of the top segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[top - (middle - bottom) + i];
+             argv[top - (middle - bottom) + i] = tem;
+             SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+           }
+         /* Exclude the moved bottom segment from further swapping.  */
+         top -= len;
+       }
+      else
+       {
+         /* Top segment is the short one.  */
+         int len = top - middle;
+         register int i;
+
+         /* Swap it with the bottom part of the bottom segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[middle + i];
+             argv[middle + i] = tem;
+             SWAP_FLAGS (bottom + i, middle + i);
+           }
+         /* Exclude the moved top segment from further swapping.  */
+         bottom += len;
+       }
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  first_nonopt = last_nonopt = optind;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  if (posixly_correct == NULL
+      && argc == __libc_argc && argv == __libc_argv)
+    {
+      if (nonoption_flags_max_len == 0)
+       {
+         if (__getopt_nonoption_flags == NULL
+             || __getopt_nonoption_flags[0] == '\0')
+           nonoption_flags_max_len = -1;
+         else
+           {
+             const char *orig_str = __getopt_nonoption_flags;
+             int len = nonoption_flags_max_len = strlen (orig_str);
+             if (nonoption_flags_max_len < argc)
+               nonoption_flags_max_len = argc;
+             __getopt_nonoption_flags =
+               (char *) malloc (nonoption_flags_max_len);
+             if (__getopt_nonoption_flags == NULL)
+               nonoption_flags_max_len = -1;
+             else
+               memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+                       '\0', nonoption_flags_max_len - len);
+           }
+       }
+      nonoption_flags_len = nonoption_flags_max_len;
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+\f
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns -1.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int print_errors = opterr;
+  if (optstring[0] == ':')
+    print_errors = 0;
+
+  if (argc < 1)
+    return -1;
+
+  optarg = NULL;
+
+  if (optind == 0 || !__getopt_initialized)
+    {
+      if (optind == 0)
+       optind = 1;     /* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring);
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'              \
+                     || (optind < nonoption_flags_len                        \
+                         && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+        moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > optind)
+       last_nonopt = optind;
+      if (first_nonopt > optind)
+       first_nonopt = optind;
+
+      if (ordering == PERMUTE)
+       {
+         /* If we have just processed some options following some non-options,
+            exchange them so that the options come first.  */
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc && NONOPTION_P)
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* The special ARGV-element `--' means premature end of options.
+        Skip it like a null option,
+        then exchange with previous non-options as if it were an option,
+        then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* Set the next-arg-index to point at the non-options
+            that we previously skipped, so the caller will digest them.  */
+         if (first_nonopt != last_nonopt)
+           optind = first_nonopt;
+         return -1;
+       }
+
+      /* If we have come to a non-option and did not permute it,
+        either stop the scan or describe it to the caller and pass it by.  */
+
+      if (NONOPTION_P)
+       {
+         if (ordering == REQUIRE_ORDER)
+           return -1;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Skip the initial punctuation.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[optind][1] == '-'
+         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+       /* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+        or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+       if (!strncmp (p->name, nextchar, nameend - nextchar))
+         {
+           if ((unsigned int) (nameend - nextchar)
+               == (unsigned int) strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else if (long_only
+                    || pfound->has_arg != p->has_arg
+                    || pfound->flag != p->flag
+                    || pfound->val != p->val)
+             /* Second or later nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (print_errors)
+           fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+                    argv[0], argv[optind]);
+         nextchar += strlen (nextchar);
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*nameend)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = nameend + 1;
+             else
+               {
+                 if (print_errors)
+                   {
+                     if (argv[optind - 1][1] == '-')
+                       /* --option */
+                       fprintf (stderr,
+                                _("%s: option `--%s' doesn't allow an argument\n"),
+                                argv[0], pfound->name);
+                     else
+                       /* +option or -option */
+                       fprintf (stderr,
+                                _("%s: option `%c%s' doesn't allow an argument\n"),
+                                argv[0], argv[optind - 1][0], pfound->name);
+                   }
+
+                 nextchar += strlen (nextchar);
+
+                 optopt = pfound->val;
+                 return '?';
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (optind < argc)
+               optarg = argv[optind++];
+             else
+               {
+                 if (print_errors)
+                   fprintf (stderr,
+                          _("%s: option `%s' requires an argument\n"),
+                          argv[0], argv[optind - 1]);
+                 nextchar += strlen (nextchar);
+                 optopt = pfound->val;
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+         || my_index (optstring, *nextchar) == NULL)
+       {
+         if (print_errors)
+           {
+             if (argv[optind][1] == '-')
+               /* --option */
+               fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+                        argv[0], nextchar);
+             else
+               /* +option or -option */
+               fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+                        argv[0], argv[optind][0], nextchar);
+           }
+         nextchar = (char *) "";
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (print_errors)
+         {
+           if (posixly_correct)
+             /* 1003.2 specifies the format of this message.  */
+             fprintf (stderr, _("%s: illegal option -- %c\n"),
+                      argv[0], c);
+           else
+             fprintf (stderr, _("%s: invalid option -- %c\n"),
+                      argv[0], c);
+         }
+       optopt = c;
+       return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+       char *nameend;
+       const struct option *p;
+       const struct option *pfound = NULL;
+       int exact = 0;
+       int ambig = 0;
+       int indfound = 0;
+       int option_index;
+
+       /* This is an option that requires an argument.  */
+       if (*nextchar != '\0')
+         {
+           optarg = nextchar;
+           /* If we end this ARGV-element by taking the rest as an arg,
+              we must advance to the next element now.  */
+           optind++;
+         }
+       else if (optind == argc)
+         {
+           if (print_errors)
+             {
+               /* 1003.2 specifies the format of this message.  */
+               fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+                        argv[0], c);
+             }
+           optopt = c;
+           if (optstring[0] == ':')
+             c = ':';
+           else
+             c = '?';
+           return c;
+         }
+       else
+         /* We already incremented `optind' once;
+            increment it again when taking next ARGV-elt as argument.  */
+         optarg = argv[optind++];
+
+       /* optarg is now the argument, see if it's in the
+          table of longopts.  */
+
+       for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+         /* Do nothing.  */ ;
+
+       /* Test all long options for either exact match
+          or abbreviated matches.  */
+       for (p = longopts, option_index = 0; p->name; p++, option_index++)
+         if (!strncmp (p->name, nextchar, nameend - nextchar))
+           {
+             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+               {
+                 /* Exact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+                 exact = 1;
+                 break;
+               }
+             else if (pfound == NULL)
+               {
+                 /* First nonexact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+               }
+             else
+               /* Second or later nonexact match found.  */
+               ambig = 1;
+           }
+       if (ambig && !exact)
+         {
+           if (print_errors)
+             fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+                      argv[0], argv[optind]);
+           nextchar += strlen (nextchar);
+           optind++;
+           return '?';
+         }
+       if (pfound != NULL)
+         {
+           option_index = indfound;
+           if (*nameend)
+             {
+               /* Don't test has_arg with >, because some C compilers don't
+                  allow it to be used on enums.  */
+               if (pfound->has_arg)
+                 optarg = nameend + 1;
+               else
+                 {
+                   if (print_errors)
+                     fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+                              argv[0], pfound->name);
+
+                   nextchar += strlen (nextchar);
+                   return '?';
+                 }
+             }
+           else if (pfound->has_arg == 1)
+             {
+               if (optind < argc)
+                 optarg = argv[optind++];
+               else
+                 {
+                   if (print_errors)
+                     fprintf (stderr,
+                              _("%s: option `%s' requires an argument\n"),
+                              argv[0], argv[optind - 1]);
+                   nextchar += strlen (nextchar);
+                   return optstring[0] == ':' ? ':' : '?';
+                 }
+             }
+           nextchar += strlen (nextchar);
+           if (longind != NULL)
+             *longind = option_index;
+           if (pfound->flag)
+             {
+               *(pfound->flag) = pfound->val;
+               return 0;
+             }
+           return pfound->val;
+         }
+         nextchar = NULL;
+         return 'W';   /* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = NULL;
+           nextchar = NULL;
+         }
+       else
+         {
+           /* This is an option that requires an argument.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               /* If we end this ARGV-element by taking the rest as an arg,
+                  we must advance to the next element now.  */
+               optind++;
+             }
+           else if (optind == argc)
+             {
+               if (print_errors)
+                 {
+                   /* 1003.2 specifies the format of this message.  */
+                   fprintf (stderr,
+                            _("%s: option requires an argument -- %c\n"),
+                            argv[0], c);
+                 }
+               optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/cmake/gengetopt/getopt1.c b/cmake/gengetopt/getopt1.c
new file mode 100644 (file)
index 0000000..22a7efb
--- /dev/null
@@ -0,0 +1,188 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+     Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+\f
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef        NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+       {"add", 1, 0, 0},
+       {"append", 0, 0, 0},
+       {"delete", 1, 0, 0},
+       {"verbose", 0, 0, 0},
+       {"create", 0, 0, 0},
+       {"file", 1, 0, 0},
+       {0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+                      long_options, &option_index);
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case 0:
+         printf ("option %s", long_options[option_index].name);
+         if (optarg)
+           printf (" with arg %s", optarg);
+         printf ("\n");
+         break;
+
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case 'd':
+         printf ("option d with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/cmake/gengetopt/ggo_options.h b/cmake/gengetopt/ggo_options.h
new file mode 100644 (file)
index 0000000..f3b218e
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef GGO_OPTIONS_H
+#define GGO_OPTIONS_H
+
+#include "ggos.h"
+
+extern gengetopt_option_list gengetopt_options;
+
+#define foropt for (gengetopt_option_list::iterator it = gengetopt_options.begin();             \
+                    it != gengetopt_options.end() && (opt = *it); \
+                    ++it)
+
+#endif /* GGO_OPTIONS_H */
diff --git a/cmake/gengetopt/ggos.cpp b/cmake/gengetopt/ggos.cpp
new file mode 100644 (file)
index 0000000..11e92a3
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// C++ Implementation: ggos
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2005-2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "ggos.h"
+
+using namespace std;
+
+gengetopt_option::gengetopt_option() :
+    short_opt(0), long_opt(0), desc(0), type(ARG_NO), flagstat(-1),
+            required(1), required_set(false), var_arg(0), default_string(0),
+            group_value(0), group_desc(0),
+            mode_value(0), mode_desc(0),
+            multiple(false),
+            arg_is_optional(false), hidden(false), type_str(0),
+            acceptedvalues(0), section(0), section_desc(0), dependon(0),
+            text_before(0), text_after(0), details(0), filename(0), linenum(0) {
+}
+
+ostream & operator <<(std::ostream &s, gengetopt_option &opt) {
+    s << "long: " << opt.long_opt << ", short: " << opt.short_opt << "\n"
+            << "desc: " << opt.desc;
+
+    s << endl;
+
+    return s;
+}
diff --git a/cmake/gengetopt/ggos.h b/cmake/gengetopt/ggos.h
new file mode 100644 (file)
index 0000000..e2c96f5
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+This file is licensed to you under the license specified in the included file
+`LICENSE'. Look there for further details.
+*/
+
+
+#ifndef _GENGETOPT_GGOS_H
+#define _GENGETOPT_GGOS_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <list>
+#include <iostream>
+
+#include "acceptedvalues.h"
+#include "argsdef.h"
+
+/**
+ * The structure for storing an option specified in the .ggo file
+ */
+struct gengetopt_option
+{
+  char short_opt; /**< the short option specification (one char) */
+  char * long_opt; /**< the short option specification */
+  char * desc; /**< the option description */
+  int type; /**< the type of the option (possible values in `argsdef.h') */
+  int flagstat ; /**< if the option is of type flag, this indicates its state (on/off) */
+  int required; /**< whether the option required */
+  bool required_set; /**< whether the required property was set */
+  char * var_arg; /**< canonized long_opt + "_arg" = argument var */
+  int default_given ; /**< if a default is given */
+  char * default_string ; /**< default value for this option, if string */
+  char * group_value; /**< group name, if it's part of an option group */
+  char * group_desc; /**< group description, if it's part of an option group */
+  char * mode_value; /**< mode name, if it's part of an option mode */
+  char * mode_desc; /**< mode description, if it's part of an option mode */
+  bool multiple; /**< whether this option can be given more than once */
+  char * multiple_min; /**< minimum occurrences of a multiple option (-1: not specified) */
+  char * multiple_max; /**< maximum occurrences of a multiple option (-1: not specified) */
+  bool arg_is_optional; /**< whether the argument is optional */
+  bool hidden; /**< whether this option will be hidden from the help output */
+  char *type_str; /**< Alternative name for type,
+                     e.g. "URL" or "SECONDS" */
+  const AcceptedValues *acceptedvalues; /**< values that can be passed to this option */
+  char *section; /**< the section of this option */
+  char *section_desc; /**< the description associated with the possible section */
+  char *dependon; /**< the name of the option this one depends on */
+
+  char *text_before; /**< a possible text specified before this option */
+  char *text_after; /**< a possible text specified after this option */
+  
+  char *details; /**< possible further details for this option that will be
+  printed only if --detailed-help is specified */
+
+  /**< parser information */
+  char *filename; /**< source file */
+  int linenum; /**< line number */
+
+  gengetopt_option();
+};
+
+/** the list storing gengetopt options */
+typedef std::list<gengetopt_option *> gengetopt_option_list;
+
+std::ostream & operator <<(std::ostream &s, gengetopt_option &opt);
+
+#endif /* _GENGETOPT_GGOS_H */
diff --git a/cmake/gengetopt/global_opts.h b/cmake/gengetopt/global_opts.h
new file mode 100644 (file)
index 0000000..8332c69
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt 
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU General Public License as published by 
+ * the Free Software Foundation; either version 3, or (at your option) 
+ * any later version. 
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details. 
+ *
+ * You should have received a copy of the GNU General Public License along 
+ * with gengetopt; see the file COPYING. If not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef GLOBAL_OPTS_H
+#define GLOBAL_OPTS_H
+
+#define HELP_LONG_OPT "help"
+#define HELP_SHORT_OPT 'h'
+#define HELP_SHORT_OPT_STR "h"
+#define HELP_OPT_DESCR "Print help and exit"
+
+#define FULL_HELP_LONG_OPT "full-help"
+#define FULL_HELP_LONG_OPT_FIELD "full_help"
+#define FULL_HELP_OPT_DESCR "Print help, including hidden options, and exit"
+
+#define DETAILED_HELP_LONG_OPT "detailed-help"
+#define DETAILED_HELP_LONG_OPT_FIELD "detailed_help"
+#define DETAILED_HELP_OPT_DESCR "Print help, including all details and hidden options, and exit"
+
+#define VERSION_LONG_OPT "version"
+#define VERSION_SHORT_OPT 'V'
+#define VERSION_SHORT_OPT_STR "V"
+#define VERSION_OPT_DESCR "Print version and exit"
+
+#endif /* GLOBAL_OPTS_H */
diff --git a/cmake/gengetopt/globals.cpp b/cmake/gengetopt/globals.cpp
new file mode 100644 (file)
index 0000000..6057d5d
--- /dev/null
@@ -0,0 +1,25 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "globals.h"
+
+gengetopt_option_list gengetopt_options;
+
+groups_collection_t gengetopt_groups;
diff --git a/cmake/gengetopt/globals.h b/cmake/gengetopt/globals.h
new file mode 100644 (file)
index 0000000..ce7cba1
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 1999-2010  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLOBALS_H_
+#define GLOBALS_H_
+
+#include "ggos.h"
+#include "groups.h"
+
+extern gengetopt_option_list gengetopt_options;
+
+extern groups_collection_t gengetopt_groups;
+
+#endif /* GLOBALS_H_ */
diff --git a/cmake/gengetopt/gm.cc b/cmake/gengetopt/gm.cc
new file mode 100644 (file)
index 0000000..0e7b70a
--- /dev/null
@@ -0,0 +1,2042 @@
+/**
+ * Copyright (C) 1999-2010  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <string>
+#include <set>
+#include <algorithm> // for pair
+
+#include <fstream>
+
+extern "C"
+{
+#include "argsdef.h"
+#include "global_opts.h"
+};
+
+#include "ggo_options.h"
+
+#include "gm.h"
+#include "my_sstream.h"
+
+#include "groups.h"
+#include "skels/option_arg.h"
+#include "skels/required_option.h"
+#include "skels/dependant_option.h"
+#include "skels/generic_option.h"
+#include "skels/group_option.h"
+#include "skels/group_counter.h"
+#include "skels/handle_help.h"
+#include "skels/handle_version.h"
+#include "skels/print_help_string.h"
+#include "skels/multiple_opt_list.h"
+#include "skels/multiple_fill_array.h"
+#include "skels/free_string.h"
+#include "skels/free_multiple.h"
+#include "skels/reset_group.h"
+#include "skels/exit_failure.h"
+#include "skels/update_given.h"
+#include "skels/given_field.h"
+#include "skels/clear_given.h"
+#include "skels/clear_arg.h"
+#include "skels/free_list.h"
+#include "skels/file_save.h"
+#include "skels/file_save_multiple.h"
+#include "skels/init_args_info.h"
+#include "skels/custom_getopt_gen.h"
+#include "skels/check_modes.h"
+#include "skels/enum_decl.h"
+#include "gm_utils.h"
+#include "fileutils.h"
+
+#ifndef FIX_UNUSED
+#define FIX_UNUSED(X) (void) (X)
+#endif // FIX_UNUSED
+
+#define MAX_STARTING_COLUMN 32
+
+#define EXE_NAME "argv[0]"
+
+#define PARSER_NAME_PREFIX (c_source_gen_class::parser_name + "_")
+#define OPTION_VALUES_NAME(n) (PARSER_NAME_PREFIX + n + "_values")
+
+using std::endl;
+using std::set;
+
+extern char * gengetopt_package;
+extern char * gengetopt_version;
+extern char * gengetopt_purpose;
+extern char * gengetopt_description;
+extern char * gengetopt_usage;
+extern char * gengetopt_input_filename;
+
+extern groups_collection_t gengetopt_groups;
+extern modes_collection_t gengetopt_modes;
+
+// a map where for each mode we store the corresponding given field names
+// and the options
+typedef std::pair<string, string> OptionValueElem;
+typedef std::list<OptionValueElem> ModeOptions;
+typedef std::map<string, ModeOptions> ModeOptionMap;
+
+static ModeOptionMap modeOptionMap;
+
+static const ModeOptionMap &getModeOptionMap() {
+    if (modeOptionMap.size() == 0) {
+        // it's the first time, so we build it
+        struct gengetopt_option * opt;
+        foropt {
+            if (opt->mode_value) {
+                modeOptionMap[opt->mode_value].push_back
+                (std::make_pair("args_info->" + string(opt->var_arg) + "_given",
+                        string("\"--") + opt->long_opt + "\""));
+            }
+        }
+    }
+
+    return modeOptionMap;
+}
+
+// a map associating to a mode the list of gengetopt_options
+typedef std::map<string, gengetopt_option_list> ModeOptMap;
+
+static ModeOptMap modeOptMap;
+
+static const ModeOptMap &getModeOptMap() {
+    if (modeOptMap.size() == 0) {
+        // it's the first time, so we build it
+        struct gengetopt_option * opt;
+        foropt {
+            if (opt->mode_value) {
+                modeOptMap[opt->mode_value].push_back(opt);
+            }
+        }
+    }
+
+    return modeOptMap;
+}
+
+static void _generate_option_arg(ostream &stream,
+                                 unsigned int indent,
+                                 struct gengetopt_option * opt);
+
+static void
+generate_help_desc_print(ostream &stream,
+                         unsigned int desc_column,
+                         const char *descript, const char *defval,
+                         const string &values,
+                         const string &show_required_string);
+
+CmdlineParserCreator::CmdlineParserCreator (char *function_name,
+                                            char *struct_name,
+                                            char *unamed_options_,
+                                            char *filename_,
+                                            char *header_ext, char *c_ext,
+                                            bool long_help_,
+                                            bool no_handle_help_,
+                                            bool no_help_,
+                                            bool no_handle_version_,
+                                            bool no_version_,
+                                            bool no_handle_error_,
+                                            bool conf_parser_,
+                                            bool string_parser_,
+                                            bool gen_version,
+                                            bool gen_getopt,
+                                            bool no_options_,
+                                            const string &comment_,
+                                            const string &outdir,
+                                            const string &header_outdir,
+                                            const string &src_outdir,
+                                            const string &show_required) :
+  filename (filename_),
+  args_info_name (struct_name),
+  output_dir (outdir),
+  header_output_dir (header_outdir),
+  src_output_dir (src_outdir),
+  comment (comment_),
+  unamed_options (unamed_options_),
+  show_required_string (show_required),
+  long_help (long_help_), no_handle_help (no_handle_help_),
+  no_help (no_help_),
+  no_handle_version (no_handle_version_),
+  no_version (no_version_),
+  no_handle_error (no_handle_error_),
+  conf_parser (conf_parser_), string_parser (string_parser_),
+  gen_gengetopt_version (gen_version),
+  tab_indentation (0)
+{
+  parser_function_name = canonize_names (function_name);
+  c_filename = create_filename (filename, c_ext);
+  header_filename = create_filename (filename, header_ext);
+
+  // header_gen_class
+  const string stripped_header_file_name = strip_path (filename);
+  set_header_file_name (stripped_header_file_name);
+  header_gen_class::set_header_file_ext (header_ext);
+  c_source_gen_class::set_header_file_ext (header_ext);
+  if (gen_gengetopt_version)
+    header_gen_class::set_generator_version
+      ("version " VERSION);
+  const string my_ifndefname =
+    to_upper (strip_path (stripped_header_file_name));
+  set_ifndefname (canonize_names (my_ifndefname.c_str ()));
+  header_gen_class::set_parser_name (parser_function_name);
+  const string my_package_var_name =
+    to_upper (parser_function_name) + "_PACKAGE";
+  const string my_version_var_name =
+    to_upper (parser_function_name) + "_VERSION";
+  header_gen_class::set_package_var_name (my_package_var_name);
+  c_source_gen_class::set_package_var_name (my_package_var_name);
+  header_gen_class::set_version_var_name (my_version_var_name);
+  c_source_gen_class::set_version_var_name (my_version_var_name);
+  header_gen_class::set_args_info (args_info_name);
+  c_source_gen_class::set_args_info (args_info_name);
+  const string uppersand = "\"";
+
+  // if no_options then we don't need to generate update_arg,
+  // but if we need to handle help or version we still need to generate it
+  set_no_options (no_options_ && !no_handle_help && !no_handle_version);
+
+  if (gengetopt_package)
+    set_package_var_val
+      (uppersand + gengetopt_package + uppersand);
+  else
+    set_package_var_val ("PACKAGE");
+
+  if (gengetopt_version)
+    set_version_var_val
+      (uppersand + gengetopt_version + uppersand);
+  else
+    set_version_var_val ("VERSION");
+
+  header_gen_class::set_generate_config_parser (conf_parser);
+
+  header_gen_class::set_generate_string_parser (string_parser);
+  c_source_gen_class::set_generate_string_parser (string_parser);
+
+  // c_source_gen_class
+  set_command_line (comment);
+  if (gen_gengetopt_version)
+    c_source_gen_class::set_generator_version
+      ("version " VERSION);
+  c_source_gen_class::set_parser_name (parser_function_name);
+  set_source_name (filename);
+
+  ostringstream exit_failure_str;
+  exit_failure_gen_class exit_gen;
+  exit_gen.set_parser_name (c_source_gen_class::parser_name);
+  exit_gen.set_handle_error (! no_handle_error);
+  exit_gen.generate_exit_failure (exit_failure_str);
+  set_final_exit (exit_failure_str.str ());
+
+  set_conf_parser (conf_parser);
+  set_cmd_list (conf_parser || string_parser);
+  set_include_getopt (gen_getopt);
+
+  struct gengetopt_option * opt;
+  gen_strdup = (unamed_options != 0 || conf_parser || string_parser);
+
+  if (! gen_strdup)
+    {
+      foropt
+        if (opt->type != ARG_FLAG || opt->type != ARG_NO) {
+          gen_strdup = true;
+          break;
+        }
+    }
+
+  set_do_generate_strdup(gen_strdup);
+  set_check_possible_values(has_values());
+  set_multiple_token_functions(has_multiple_options_with_type());
+  set_multiple_options_with_default(has_multiple_options_with_default());
+  set_multiple_options(has_multiple_options());
+  set_multiple_options_string(has_multiple_options_string());
+  set_multiple_options_all_string(has_multiple_options_all_string());
+  set_has_typed_options(has_options_with_type());
+  set_has_modes(has_options_with_mode());
+  set_handle_unamed(unamed_options);
+  set_check_required_options(has_required() || has_dependencies() || has_multiple_options());
+  set_purpose(generate_purpose());
+  set_description(generate_description());
+  set_no_package((gengetopt_package == 0));
+  c_source_gen_class::set_has_hidden(has_hidden_options());
+  header_gen_class::set_has_hidden(c_source_gen_class::has_hidden);
+  c_source_gen_class::set_has_details(has_options_with_details());
+  header_gen_class::set_has_details(c_source_gen_class::has_details);
+
+  set_has_arg_types();
+}
+
+void CmdlineParserCreator::set_has_arg_types() {
+    struct gengetopt_option * opt;
+
+    set_has_arg_flag(false);
+    set_has_arg_string(false);
+    set_has_arg_int(false);
+    set_has_arg_short(false);
+    set_has_arg_long(false);
+    set_has_arg_float(false);
+    set_has_arg_double(false);
+    set_has_arg_longdouble(false);
+    set_has_arg_longlong(false);
+
+    foropt
+    {
+        switch (opt->type) {
+        case ARG_NO:
+            break;
+        case ARG_FLAG:
+            set_has_arg_flag(true);
+            break;
+        case ARG_STRING:
+            set_has_arg_string(true);
+            break;
+        case ARG_INT:
+            set_has_arg_int(true);
+            break;
+        case ARG_SHORT:
+            set_has_arg_short(true);
+            break;
+        case ARG_LONG:
+            set_has_arg_long(true);
+            break;
+        case ARG_FLOAT:
+            set_has_arg_float(true);
+            break;
+        case ARG_DOUBLE:
+            set_has_arg_double(true);
+            break;
+        case ARG_LONGDOUBLE:
+            set_has_arg_longdouble(true);
+            break;
+        case ARG_LONGLONG:
+            set_has_arg_longlong(true);
+            break;
+        case ARG_ENUM:
+            set_has_arg_enum(true);
+            break;
+        default:
+            fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
+                    __FILE__, __LINE__);
+            abort ();
+        }
+    }
+
+}
+
+void
+CmdlineParserCreator::generateBreak(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+
+  stream << endl;
+  stream << indent_str;
+  stream << "break;";
+}
+
+int
+CmdlineParserCreator::generate ()
+{
+  int head_result;
+
+  head_result = generate_header_file ();
+  if (head_result)
+    return head_result;
+
+  return generate_source ();
+}
+
+int
+CmdlineParserCreator::generate_header_file ()
+{
+  if (! gengetopt_options.size())
+    {
+      fprintf (stderr, "gengetopt: none option given\n");
+      return 1;
+    }
+
+  /* ****************************************************** */
+  /* HEADER FILE******************************************* */
+  /* ****************************************************** */
+
+    string header_file = header_filename;
+    if (header_output_dir.size())
+        header_file = header_output_dir + "/" + header_file;
+    else if (output_dir.size())
+        header_file = output_dir + "/" + header_file;
+
+    ofstream *output_file = open_fstream
+            (header_file.c_str());
+    generate_header (*output_file);
+    output_file->close ();
+    delete output_file;
+
+    return 0;
+}
+
+/**
+ * generate the enum value from a given option
+ * @param name the (canonized) name of the option
+ * @param val the value of the option
+ * @return the enum value string
+ */
+static const string from_value_to_enum(const string &name, const string &val) {
+    return name + "_arg_" + canonize_enum(val);
+}
+
+void
+CmdlineParserCreator::generate_enum_types(ostream &stream,
+                                          unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  FIX_UNUSED (indent);
+
+  if (has_arg_enum)
+      stream << endl;
+
+  foropt {
+    // if type is enum then it should also have values (checked during parsing)
+    // but it's better to check it
+    if (opt->type == ARG_ENUM) {
+        if (! (opt->acceptedvalues)) {
+            fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
+                            __FILE__, __LINE__);
+            abort ();
+        }
+        ostringstream enum_values;
+        enum_decl_gen_class enum_gen;
+        enum_gen.set_var_arg(opt->var_arg);
+        for (AcceptedValues::const_iterator it = opt->acceptedvalues->begin();
+            it != opt->acceptedvalues->end(); ++it) {
+            enum_values << ", ";
+            // the first enum element is set to 0
+            enum_values << from_value_to_enum(opt->var_arg, *it);
+            if (it == opt->acceptedvalues->begin())
+                enum_values << " = 0";
+
+        }
+        enum_gen.set_enum_values(enum_values.str());
+        enum_gen.generate_enum_decl(stream);
+    }
+  }
+}
+
+void
+CmdlineParserCreator::generate_option_arg(ostream &stream,
+                                          unsigned int indent)
+{
+  struct gengetopt_option * opt;
+
+  foropt {
+    _generate_option_arg (stream, indent, opt);
+  }
+}
+
+void
+_generate_option_arg(ostream &stream,
+                     unsigned int indent,
+                     struct gengetopt_option *opt)
+{
+  option_arg_gen_class option_arg_gen;
+
+  string type = "";
+  if (opt->type)
+      type = arg_types[opt->type];
+  string origtype = "char *";
+
+  if (opt->multiple) {
+    type += "*";
+    origtype += "*";
+    option_arg_gen.set_multiple(true);
+  } else {
+    option_arg_gen.set_multiple(false);
+  }
+
+  option_arg_gen.set_type(type);
+  option_arg_gen.set_origtype(origtype);
+  option_arg_gen.set_flag_arg((opt->type == ARG_FLAG));
+  option_arg_gen.set_desc(opt->desc);
+  option_arg_gen.set_name(opt->var_arg);
+  option_arg_gen.set_has_arg(opt->type != ARG_NO);
+  option_arg_gen.set_has_enum(opt->type == ARG_ENUM);
+
+  if (opt->default_given)
+    {
+      option_arg_gen.set_has_default(true);
+      option_arg_gen.set_default_value(opt->default_string);
+    }
+
+  if (opt->type == ARG_FLAG)
+    {
+      option_arg_gen.set_default_on(opt->flagstat);
+    }
+
+  if (opt->type == ARG_LONGLONG)
+    {
+      // the fallback type in case longlong is not supported by the compiler
+      string longtype = arg_types[ARG_LONG];
+      if (opt->multiple)
+          longtype += "*";
+
+      option_arg_gen.set_long_long_arg(true);
+      option_arg_gen.set_longtype(longtype);
+    }
+
+  option_arg_gen.generate_option_arg(stream, indent);
+}
+
+void
+CmdlineParserCreator::generate_option_given(ostream &stream,
+                                            unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  string indent_str (indent, ' ');
+  bool first = true;
+  given_field_gen_class given_gen;
+
+  foropt
+    {
+      switch (opt->type) {
+      case ARG_NO:
+      case ARG_FLAG:
+      case ARG_STRING:
+      case ARG_INT:
+      case ARG_SHORT:
+      case ARG_LONG:
+      case ARG_FLOAT:
+      case ARG_DOUBLE:
+      case ARG_LONGDOUBLE:
+      case ARG_LONGLONG:
+      case ARG_ENUM:
+          break;
+      default:
+        fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
+                 __FILE__, __LINE__);
+        abort ();
+      }
+      if (! first)
+        stream << indent_str;
+      else
+        first = false;
+
+      given_gen.set_arg_name (opt->var_arg);
+      given_gen.set_long_opt (opt->long_opt);
+      given_gen.set_group (opt->multiple && opt->group_value);
+      given_gen.generate_given_field (stream);
+    }
+
+  if (unamed_options)
+    {
+      stream << endl;
+      stream << indent_str;
+      stream << "char **inputs ; /**< @brief unamed options (options without names) */\n" ;
+      stream << indent_str;
+      stream << "unsigned inputs_num ; /**< @brief unamed options number */" ;
+    }
+}
+
+void
+CmdlineParserCreator::generate_option_values_decl(ostream &stream,
+                                                  unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  bool first = true;
+  FIX_UNUSED (indent);
+
+  foropt
+    {
+      if (opt->acceptedvalues) {
+        if (first) {
+          first = false;
+        }
+
+        stream << "extern const char *" << OPTION_VALUES_NAME(opt->var_arg) <<
+          "[];  /**< @brief Possible values for " << opt->long_opt << ". */\n";
+      }
+    }
+
+  if (! first)
+    stream << "\n";
+}
+
+void
+CmdlineParserCreator::generate_option_values(ostream &stream,
+                                             unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  bool first = true;
+  FIX_UNUSED (indent);
+
+  foropt
+    {
+      if (opt->acceptedvalues) {
+        if (first) {
+          first = false;
+        }
+
+        stream << "const char *" << OPTION_VALUES_NAME(opt->var_arg) <<
+          "[] = {" << opt->acceptedvalues->toString(false) <<
+          ", 0}; /*< Possible values for " << opt->long_opt << ". */\n";
+      }
+    }
+
+  if (! first)
+    stream << "\n";
+}
+
+static void generate_option_usage_string(gengetopt_option * opt, ostream &usage) {
+    const char   *type_str;
+
+    usage << " ";
+
+    if (!opt->required)
+        usage << "[";
+
+    switch (opt->type) {
+    case ARG_NO:
+    case ARG_FLAG:
+        if (opt->short_opt)
+            usage << "-" << opt->short_opt << "|";
+        usage << "--" << opt->long_opt;
+        break;
+    case ARG_INT:
+    case ARG_SHORT:
+    case ARG_LONG:
+    case ARG_FLOAT:
+    case ARG_DOUBLE:
+    case ARG_LONGDOUBLE:
+    case ARG_LONGLONG:
+    case ARG_STRING:
+    case ARG_ENUM:
+        if (opt->type_str)
+            type_str = opt->type_str;
+        else
+            type_str = arg_names[opt->type];
+
+        if (opt->short_opt)
+            usage << "-" << opt->short_opt << type_str << "|";
+        usage << "--" << opt->long_opt << "=" << type_str;
+
+        break;
+    default: fprintf (stderr, "gengetopt: bug found in %s:%d!!\n",
+            __FILE__, __LINE__);
+    abort ();
+    }
+
+    if (!opt->required)
+        usage << "]";
+}
+
+const string
+CmdlineParserCreator::generate_usage_string(bool use_config_package)
+{
+  FIX_UNUSED (use_config_package);
+  // if specified by the programmer, the usage string has the precedence
+  if (gengetopt_usage) {
+    return gengetopt_usage;
+  }
+
+  struct gengetopt_option * opt;
+  ostringstream usage;
+
+  // otherwise the config.h package constant will be used
+  if (gengetopt_package)
+    usage << gengetopt_package;
+
+  if ( long_help ) {
+      // we first generate usage strings of required options
+      // handle mode options separately
+      foropt
+          if (opt->required && !opt->hidden && !opt->mode_value) {
+              generate_option_usage_string(opt, usage);
+          }
+
+      foropt
+          if (!opt->required && !opt->hidden && !opt->mode_value) {
+              generate_option_usage_string(opt, usage);
+          }
+  } else { /* if not long help we generate it as GNU standards */
+      usage << " [OPTIONS]...";
+  }
+
+  string wrapped;
+
+  if ( unamed_options )
+      usage << " [" << unamed_options << "]...";
+
+  wrap_cstr ( wrapped, strlen("Usage: "), 2, usage.str() );
+
+  // now deal with modes
+  if (has_modes && long_help) {
+      const ModeOptMap &modeOptMap = getModeOptMap();
+
+      for (ModeOptMap::const_iterator map_it = modeOptMap.begin(); map_it != modeOptMap.end(); ++map_it) {
+          string mode_line; // a mode alternative in the usage string
+          gengetopt_option_list::const_iterator opt_it;
+          usage.str(""); // reset the usage string buffer
+
+          for (opt_it = map_it->second.begin(); opt_it != map_it->second.end(); ++opt_it) {
+              if (((*opt_it)->required) && !((*opt_it)->hidden)) {
+                  generate_option_usage_string(*opt_it, usage);
+              }
+          }
+
+          for (opt_it = map_it->second.begin(); opt_it != map_it->second.end(); ++opt_it) {
+              if (!((*opt_it)->required) && !((*opt_it)->hidden)) {
+                  generate_option_usage_string(*opt_it, usage);
+              }
+          }
+
+          wrap_cstr ( mode_line, strlen("  or : "), 2, gengetopt_package + usage.str() );
+          wrapped += "\\n  or : ";
+          wrapped += mode_line;
+      }
+  }
+
+  return wrapped;
+}
+
+static void
+generate_help_desc_print(ostream &stream,
+                         unsigned int desc_column,
+                         const char *descript, const char *defval,
+                         const string &values,
+                         const string &show_required_string)
+{
+  string desc;
+  string desc_with_default = descript;
+
+  if (defval || values.size()) {
+      desc_with_default += "  (";
+
+      if (values.size()) {
+        desc_with_default += "possible values=";
+        desc_with_default += values;
+        if (defval)
+          desc_with_default += " ";
+      }
+
+      if (defval) {
+        desc_with_default += "default=";
+        desc_with_default += defval;
+      }
+
+      desc_with_default += ")";
+  }
+
+  if (show_required_string != "")
+    desc_with_default += " " + show_required_string;
+
+  wrap_cstr ( desc, desc_column, 2, desc_with_default );
+
+  stream << desc;
+}
+
+
+void
+CmdlineParserCreator::generate_help_option_print_from_lists(ostream &stream,
+        unsigned int indent, OptionHelpList *full_option_list,
+        OptionHelpList *option_list, const std::string &target_array,
+        const std::string &source_array) {
+    print_help_string_gen_class print_gen;
+
+    // the index into the help arrays
+    int i = 0, full_i = 0;
+    // num of help strings
+    int help_num = 0;
+
+    print_gen.set_target(target_array);
+    print_gen.set_from(source_array);
+    print_gen.set_shared(true);
+    print_gen.set_last(false);
+
+    OptionHelpList::const_iterator it = option_list->begin();
+    OptionHelpList::const_iterator it2 = full_option_list->begin();
+    // the second list is surely longer so we scan that one
+    for (; it != option_list->end() && it2 != full_option_list->end(); ++it2)
+    {
+        if (*it == *it2) {
+            // when the two strings are the same it means that's a non-hidden
+            // option, so we share it with the full help array
+            ostringstream converted_int;
+            converted_int << i;
+
+            // the index into the help array
+            print_gen.set_index(converted_int.str());
+
+            converted_int.str("");
+            converted_int << full_i;
+
+            // the index into the full help array
+            print_gen.set_full_index(converted_int.str());
+            print_gen.generate_print_help_string(stream, indent);
+
+            ++help_num;
+            ++i;
+            ++it;
+        }
+        ++full_i;
+    }
+
+    ostringstream converted_int;
+    converted_int << help_num;
+
+    // the final 0
+    print_gen.set_last(true);
+    print_gen.set_index(converted_int.str());
+    print_gen.generate_print_help_string(stream, indent);
+
+    // we increment it to store the final 0
+    converted_int.str("");
+    converted_int << ++help_num;
+
+    set_help_string_num(converted_int.str());
+
+}
+
+void
+CmdlineParserCreator::generate_help_option_print(ostream &stream,
+                                                 unsigned int indent)
+{
+    OptionHelpList *option_list = generate_help_option_list();
+
+    if (!c_source_gen_class::has_hidden && !c_source_gen_class::has_details) {
+        print_help_string_gen_class print_gen;
+        print_gen.set_shared(false);
+
+        // simple help generation
+        for (OptionHelpList::const_iterator it = option_list->begin();
+        it != option_list->end(); ++it)
+        {
+            print_gen.set_helpstring(*it);
+            print_gen.generate_print_help_string(stream, indent);
+        }
+    } else {
+        // in order to avoid generating the same help string twice, and thus
+        // to save memory, in case of hidden options (or details), we try to share most
+        // of the strings with the full help array
+        OptionHelpList *full_option_list = generate_help_option_list(true, true);
+
+        generate_help_option_print_from_lists
+        (stream, indent, full_option_list, option_list,
+                c_source_gen_class::args_info + "_help",
+                (c_source_gen_class::has_details ?
+                        c_source_gen_class::args_info + "_detailed_help" :
+                            c_source_gen_class::args_info + "_full_help"));
+
+        delete full_option_list;
+    }
+
+    delete option_list;
+}
+
+void
+CmdlineParserCreator::generate_full_help_option_print(ostream &stream,
+        unsigned int indent)
+{
+    // generate also hidden options
+    OptionHelpList *option_list = generate_help_option_list(true);
+
+    if (!c_source_gen_class::has_details) {
+        print_help_string_gen_class print_gen;
+        print_gen.set_shared(false);
+
+        for (OptionHelpList::const_iterator it = option_list->begin();
+        it != option_list->end(); ++it)
+        {
+            print_gen.set_helpstring(*it);
+            print_gen.generate_print_help_string(stream, indent);
+        }
+    } else {
+        // in order to avoid generating the same help string twice, and thus
+        // to save memory, in case of options with details, we try to share most
+        // of the strings with the full help array
+        OptionHelpList *full_option_list = generate_help_option_list(true, true);
+
+        generate_help_option_print_from_lists
+        (stream, indent, full_option_list, option_list,
+                c_source_gen_class::args_info + "_full_help",
+                c_source_gen_class::args_info + "_detailed_help");
+
+        delete full_option_list;
+    }
+
+    delete option_list;
+}
+
+void
+CmdlineParserCreator::generate_detailed_help_option_print(ostream &stream,
+        unsigned int indent)
+{
+    // generate also hidden options and details
+    OptionHelpList *option_list = generate_help_option_list(true, true);
+
+    print_help_string_gen_class print_gen;
+    print_gen.set_shared(false);
+
+    for (OptionHelpList::const_iterator it = option_list->begin();
+         it != option_list->end(); ++it)
+    {
+        print_gen.set_helpstring(*it);
+        print_gen.generate_print_help_string(stream, indent);
+    }
+
+    delete option_list;
+}
+
+void
+CmdlineParserCreator::generate_init_args_info(ostream &stream, unsigned int indent)
+{
+    struct gengetopt_option * opt;
+    init_args_info_gen_class init_args_info_gen;
+    int i = 0;
+    ostringstream index;
+
+    string help_string = c_source_gen_class::args_info;
+
+    if (c_source_gen_class::has_details) {
+        help_string += "_detailed_help";
+    } else if (c_source_gen_class::has_hidden) {
+        help_string += "_full_help";
+    } else {
+        help_string += "_help";
+    }
+    init_args_info_gen.set_help_strings(help_string);
+
+    const char *current_section = 0, *current_group = 0, *current_mode = 0;
+
+    // we have to skip section description references (that appear in the help vector)
+    foropt {
+        index.str("");
+
+        if (opt->section) {
+          if (!current_section || (strcmp(current_section, opt->section) != 0)) {
+            // a different section reference, skip it
+            current_section = opt->section;
+            ++i;
+
+            if (opt->section_desc) {
+              // section description takes another line, thus we have to skip this too
+              ++i;
+            }
+          }
+        }
+
+        // skip group desc
+        if (opt->group_value) {
+            if (!current_group || strcmp(current_group, opt->group_value) != 0) {
+                current_group = opt->group_value;
+                ++i;
+            }
+        }
+
+        // skip mode desc
+        if (opt->mode_value) {
+            if (!current_mode || strcmp(current_mode, opt->mode_value) != 0) {
+                current_mode = opt->mode_value;
+                ++i;
+            }
+        }
+
+        // also skip the text before
+        if (opt->text_before)
+            ++i;
+
+        index << i++;
+
+        init_args_info_gen.set_var_arg(opt->var_arg);
+        init_args_info_gen.set_num(index.str());
+
+        if (opt->multiple) {
+            init_args_info_gen.set_multiple(true);
+            init_args_info_gen.set_min(opt->multiple_min);
+            init_args_info_gen.set_max(opt->multiple_max);
+        } else {
+            init_args_info_gen.set_multiple(false);
+        }
+
+        init_args_info_gen.generate_init_args_info(stream, indent);
+
+        // skip the details
+        if (opt->details)
+            ++i;
+
+        // skip the text after
+        if (opt->text_after)
+            ++i;
+
+    }
+}
+
+void CmdlineParserCreator::generate_custom_getopt(ostream &stream, unsigned int indent)
+{
+    custom_getopt_gen_gen_class custom_getopt;
+
+    custom_getopt.generate_custom_getopt_gen (stream, indent);
+}
+
+const string
+CmdlineParserCreator::generate_purpose()
+{
+  string wrapped_purpose;
+
+  if (gengetopt_purpose != NULL)
+    {
+      wrap_cstr(wrapped_purpose, 0, 0, gengetopt_purpose);
+    }
+
+  return wrapped_purpose;
+}
+
+const string
+CmdlineParserCreator::generate_description()
+{
+  string wrapped_description;
+
+  if (gengetopt_description != NULL)
+    {
+      wrap_cstr(wrapped_description, 0, 0, gengetopt_description);
+    }
+
+  return wrapped_description;
+}
+
+
+OptionHelpList *
+CmdlineParserCreator::generate_help_option_list(bool generate_hidden, bool generate_details)
+{
+  OptionHelpList *option_list = new OptionHelpList;
+
+  unsigned long desc_col;
+  struct gengetopt_option * opt;
+
+  int           type_len;
+  const char   *type_str;
+  ostringstream stream;
+
+  // if we want to generate details then we will also generate hidden options
+  if (generate_details)
+      generate_hidden = true;
+
+  /* calculate columns */
+  desc_col = 0;
+  foropt {
+    // if (opt->hidden && !generate_hidden)
+    //    continue;
+    // when computing columns, we also consider hidden_options, so that
+    // the --help and --full-help will be aligned just the same
+    // IMPORTANT: this is also crucial due to how the help string array
+    // is built starting from the full-help string array:
+    // we iterate over the two lists of options and check whether the
+    // corresponding strings are the same; thus, the help strings must
+    // have the same space alignments, otherwise they're not equal
+
+    unsigned int width = 2 + 4 + 2;  // ws + "-a, " + ws
+
+    width += strlen (opt->long_opt) + 2;  // "--"
+
+    if ((opt->type != ARG_FLAG) &&
+        (opt->type != ARG_NO))
+      {
+        if (opt->type_str)
+          type_str = opt->type_str;
+        else
+          type_str = arg_names[opt->type];
+        type_len = strlen(type_str);
+
+        width += type_len + 1;        // "="
+
+        if (opt->arg_is_optional)
+          width += 2; // "[" and "]"
+      }
+
+    if (width > desc_col)
+      desc_col = width;
+  }
+
+  if (desc_col > MAX_STARTING_COLUMN)
+    desc_col = MAX_STARTING_COLUMN;
+
+  /* print justified options */
+  char *prev_group = 0;
+  char *prev_mode = 0;
+  char *curr_section = 0;
+  bool first_option = true;
+
+  foropt
+    {
+      // if the option is hidden, avoid to print a section containing only
+      // hidden options
+      if (opt->section &&
+              (!curr_section || strcmp (curr_section, opt->section)) &&
+              (!opt->hidden || generate_hidden))
+      {
+          curr_section = opt->section;
+
+          ostringstream sec_string;
+
+          if (! first_option)
+              sec_string << "\\n";
+
+          sec_string << opt->section << ":" ;
+
+          string wrapped_def;
+          wrap_cstr(wrapped_def, 0, 0, sec_string.str());
+          option_list->push_back(wrapped_def);
+
+          if (opt->section_desc)
+          {
+              string wrapped_desc ( 2, ' ');
+              wrap_cstr ( wrapped_desc, 2, 0, opt->section_desc );
+
+              option_list->push_back(wrapped_desc);
+          }
+      }
+
+      if (opt->group_value &&
+              (! prev_group || strcmp (opt->group_value, prev_group) != 0))
+      {
+          string group_string = "\\n Group: ";
+          string wrapped_desc;
+
+          if (opt->group_desc && strlen (opt->group_desc))
+          {
+              wrapped_desc = "\\n  ";
+              wrap_cstr (wrapped_desc, 2, 0, opt->group_desc);
+          }
+
+          group_string += opt->group_value + wrapped_desc;
+
+          option_list->push_back (group_string);
+
+          prev_group = opt->group_value;
+      }
+
+      if (opt->mode_value &&
+              (! prev_mode || strcmp (opt->mode_value, prev_mode) != 0))
+      {
+          string mode_string = "\\n Mode: ";
+          string wrapped_desc;
+
+          if (opt->mode_desc && strlen (opt->mode_desc))
+          {
+              wrapped_desc = "\\n  ";
+              wrap_cstr (wrapped_desc, 2, 0, opt->mode_desc);
+          }
+
+          mode_string += opt->mode_value + wrapped_desc;
+
+          option_list->push_back (mode_string);
+
+          prev_mode = opt->mode_value;
+      }
+
+      // a possible description to be printed before this option
+      if (opt->text_before)
+      {
+          string wrapped_desc;
+          wrap_cstr ( wrapped_desc, 0, 0, opt->text_before);
+
+          option_list->push_back(wrapped_desc);
+      }
+
+      if (!opt->hidden || generate_hidden) {
+          first_option = false;
+          const char * def_val = NULL;
+          string def_str = "`";
+
+          ostringstream option_stream;
+
+          if (opt->type == ARG_FLAG || opt->type == ARG_NO)
+          {
+              def_val = NULL;
+
+              if (opt->short_opt)
+                  option_stream << "  -" << opt->short_opt << ", ";
+              else
+                  option_stream << "      ";
+
+              option_stream << "--" << opt->long_opt;
+
+              if (opt->type == ARG_FLAG)
+                  def_val = opt->flagstat ? "on" : "off";
+          }
+          else
+          {
+              def_val = NULL;
+
+              if (opt->type_str)
+                  type_str = opt->type_str;
+              else
+                  type_str = arg_names[opt->type];
+
+              type_len = strlen(type_str);
+
+              if (opt->short_opt)
+              {
+                  option_stream << "  -" << opt->short_opt << ", ";
+              }
+              else
+              {
+                  option_stream << "      ";
+              }
+
+              bool arg_optional = opt->arg_is_optional;
+              option_stream << "--" << opt->long_opt
+              << (arg_optional ? "[" : "")
+              << "=" << type_str
+              << (arg_optional ? "]" : "");
+
+              if (opt->default_string)
+              {
+                  def_str += opt->default_string;
+                  def_str += "'";
+                  def_val = def_str.c_str();
+              }
+          }
+
+          const string &option_string = option_stream.str();
+          stream << option_string;
+          const char *opt_desc = opt->desc;
+
+          if ((option_string.size() >= MAX_STARTING_COLUMN) ||
+                  (desc_col <= option_string.size()))
+          {
+              string indent (MAX_STARTING_COLUMN, ' ');
+              stream << "\\n" << indent;
+          }
+          else
+          {
+              string indent (desc_col - option_string.size(), ' ');
+              stream << indent;
+          }
+
+          generate_help_desc_print(stream, desc_col, opt_desc, def_val,
+                  (opt->acceptedvalues ? opt->acceptedvalues->toString() : ""),
+                  (opt->required && show_required_string != "" ? show_required_string : ""));
+
+          option_list->push_back(stream.str());
+          stream.str("");
+      }
+
+      // before the text after we generate details if we need to
+      if (opt->details && generate_details) {
+          string wrapped_desc ( 2, ' ');
+          // details are indented
+          wrap_cstr ( wrapped_desc, 2, 0, opt->details);
+
+          option_list->push_back(wrapped_desc);
+      }
+
+      // a possible description to be printed after this option
+      if (opt->text_after)
+      {
+          string wrapped_desc;
+          wrap_cstr ( wrapped_desc, 0, 0, opt->text_after);
+
+          option_list->push_back(wrapped_desc);
+      }
+    }
+
+  return option_list;
+}
+
+template <typename Collection>
+void generate_counter_init(const Collection &collection, const string &name, ostream &stream, unsigned int indent)
+{
+    string indent_str (indent, ' ');
+    typename Collection::const_iterator end = collection.end();
+
+    for ( typename Collection::const_iterator idx = collection.begin(); idx != end; ++idx)
+    {
+        stream << indent_str;
+        stream << ARGS_STRUCT << "->" << canonize_name (idx->first) << "_" <<
+            name << "_counter = 0 ;";
+        stream << endl;
+    }
+}
+
+void
+CmdlineParserCreator::generate_given_init(ostream &stream,
+                                          unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  string indent_str (indent, ' ');
+  clear_given_gen_class clear_given;
+  clear_given.set_arg_struct(ARGS_STRUCT);
+
+  /* now we initialize "given" fields */
+  foropt
+    {
+      stream << indent_str;
+      clear_given.set_var_arg(opt->var_arg);
+      clear_given.set_group(opt->multiple && opt->group_value);
+      clear_given.generate_clear_given(stream);
+    }
+
+  // for group counter initialization
+  generate_counter_init(gengetopt_groups, "group", stream, indent);
+
+  // for mode counter initialization
+  generate_counter_init(gengetopt_modes, "mode", stream, indent);
+}
+
+void
+CmdlineParserCreator::generate_reset_groups(ostream &stream, unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  string indent_str (indent, ' ');
+  ostringstream body;
+  reset_group_gen_class reset_group;
+  clear_given_gen_class clear_given;
+  clear_given.set_arg_struct(ARGS_STRUCT);
+
+  reset_group.set_args_info (c_source_gen_class::args_info);
+
+  groups_collection_t::const_iterator end = gengetopt_groups.end();
+  for ( groups_collection_t::const_iterator idx = gengetopt_groups.begin();
+        idx != end; ++idx)
+    {
+      body.str ("");
+      bool found_option = false;
+      bool multiple_arg = false;
+
+      foropt
+      {
+        if (opt->group_value && strcmp(opt->group_value, idx->first.c_str()) == 0)
+          {
+            /* now we reset "given" fields */
+            stream << indent_str;
+            clear_given.set_var_arg(opt->var_arg);
+            if (opt->multiple && opt->group_value)
+              multiple_arg = true;
+            clear_given.set_group(opt->multiple && opt->group_value);
+            clear_given.generate_clear_given(body);
+
+            free_option (opt, body, indent);
+            found_option = true;
+          }
+      }
+
+      if (found_option)
+        {
+          reset_group.set_name (canonize_name (idx->first));
+          reset_group.set_body (body.str ());
+          reset_group.generate_reset_group (stream);
+        }
+    }
+}
+
+void
+CmdlineParserCreator::free_option(struct gengetopt_option *opt,
+                                  ostream &stream, unsigned int indent)
+{
+  if (opt->type == ARG_NO)
+    return;
+
+  if (opt->type != ARG_FLAG)
+    {
+      if (opt->multiple)
+        {
+          free_multiple_gen_class free_multiple;
+          free_multiple.set_has_string_type(opt->type == ARG_STRING);
+          free_multiple.set_structure (ARGS_STRUCT);
+
+          free_multiple.set_opt_var (opt->var_arg);
+          free_multiple.generate_free_multiple
+            (stream, indent);
+        }
+      else
+        {
+          free_string_gen_class free_string;
+          free_string.set_has_string_type(opt->type == ARG_STRING);
+          free_string.set_structure (ARGS_STRUCT);
+
+          free_string.set_opt_var (opt->var_arg);
+          free_string.generate_free_string (stream, indent);
+        }
+    }
+}
+
+void
+CmdlineParserCreator::generate_list_def(ostream &stream, unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  string indent_str (indent, ' ');
+  multiple_opt_list_gen_class multiple_opt_list;
+
+  /* define linked-list structs for multiple options */
+  foropt
+    {
+      if (opt->multiple)
+        {
+          if (opt->type)
+            {
+              stream << indent_str;
+              multiple_opt_list.set_arg_name (opt->var_arg);
+              multiple_opt_list.generate_multiple_opt_list (stream, indent);
+              stream << endl;
+            }
+        }
+    }
+}
+
+void
+CmdlineParserCreator::generate_multiple_fill_array(ostream &stream, unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  string indent_str (indent, ' ');
+  multiple_fill_array_gen_class filler;
+
+  /* copy linked list into the array */
+  foropt
+    {
+      if (opt->multiple && opt->type)
+        {
+          stream << indent_str;
+          filler.set_option_var_name (opt->var_arg);
+          filler.set_arg_type(arg_type_constants[opt->type]);
+          filler.set_type (arg_types_names[opt->type]);
+          string default_string = "0";
+          if (opt->default_string) {
+              if (opt->type == ARG_STRING)
+                  default_string = string("\"") + opt->default_string + "\"";
+              else if (opt->type == ARG_ENUM)
+                  default_string = from_value_to_enum(opt->var_arg, opt->default_string);
+              else
+                  default_string = opt->default_string;
+          }
+          filler.set_default_value (default_string);
+
+          filler.generate_multiple_fill_array (stream, indent);
+
+          stream << endl;
+        }
+    }
+}
+
+void
+CmdlineParserCreator::generate_update_multiple_given(ostream &stream, unsigned int indent)
+{
+  if (! has_multiple_options())
+    return;
+
+  string indent_str (indent, ' ');
+
+  stream << endl;
+  stream << indent_str;
+
+  update_given_gen_class update_given_gen;
+  struct gengetopt_option * opt;
+
+  foropt
+    {
+      if (opt->multiple)
+        {
+          update_given_gen.set_option_var_name (opt->var_arg);
+          update_given_gen.generate_update_given (stream, indent);
+        }
+    }
+}
+
+void
+CmdlineParserCreator::generate_check_modes(ostream &stream, unsigned int indent)
+{
+    // no need to check for conflict if there's only one mode
+    if (gengetopt_modes.size() < 2)
+        return;
+
+    string indent_str (indent, ' ');
+
+    stream << endl;
+    stream << indent_str;
+
+    const ModeOptionMap &modeOptionMap = getModeOptionMap();
+
+    check_modes_gen_class check_modes_gen;
+
+    // now we check each mode options against every other mode options:
+    // the first one with the other n-1, the second one with the other n-2, etc.
+    ModeOptionMap::const_iterator map_it1, map_it2;
+    for (ModeOptionMap::const_iterator map_it = modeOptionMap.begin(); map_it != modeOptionMap.end(); ++map_it) {
+        map_it1 = map_it;
+        ++map_it;
+        if (map_it == modeOptionMap.end())
+            break;
+        for (map_it2 = map_it; map_it2 != modeOptionMap.end(); ++map_it2) {
+            const string mode1 = canonize_name(map_it1->first);
+            const string mode2 = canonize_name(map_it2->first);
+
+            check_modes_gen.set_mode1_name(mode1);
+            check_modes_gen.set_mode2_name(mode2);
+
+            ostringstream mode1_given, mode2_given, mode1_options, mode2_options;
+
+            std::for_each(map_it1->second.begin(), map_it1->second.end(), pair_print_f<OptionValueElem>(mode1_given, mode1_options));
+            std::for_each(map_it2->second.begin(), map_it2->second.end(), pair_print_f<OptionValueElem>(mode2_given, mode2_options));
+
+            check_modes_gen.set_mode1_given_fields(mode1_given.str());
+            check_modes_gen.set_mode1_options(mode1_options.str());
+            check_modes_gen.set_mode2_given_fields(mode2_given.str());
+            check_modes_gen.set_mode2_options(mode2_options.str());
+
+            check_modes_gen.generate_check_modes(stream, indent);
+        }
+        map_it = map_it1;
+    }
+}
+
+void
+CmdlineParserCreator::generate_clear_arg(ostream &stream, unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  clear_arg_gen_class clear_arg;
+
+  /* now we initialize value fields */
+  foropt
+    {
+      if (opt->type == ARG_NO)
+        continue;
+
+      clear_arg.set_name(opt->var_arg);
+      clear_arg.set_suffix("arg");
+      clear_arg.set_value("NULL");
+      clear_arg.set_has_orig(opt->type != ARG_FLAG);
+      clear_arg.set_has_arg(false);
+
+      if (opt->multiple && opt->type)
+        {
+          clear_arg.set_has_arg(true);
+        }
+      else if (opt->type == ARG_STRING)
+        {
+          clear_arg.set_has_arg(true);
+          if (opt->default_given)
+            clear_arg.set_value
+                ("gengetopt_strdup (\"" + string(opt->default_string) +
+                "\")");
+        }
+      else if (opt->type == ARG_FLAG)
+        {
+          clear_arg.set_has_arg(true);
+          clear_arg.set_suffix("flag");
+          clear_arg.set_value(opt->flagstat ? "1" : "0");
+        }
+      else if (opt->type == ARG_ENUM)
+      {
+        // initialize enum arguments to -1 (unless they have a default)
+        clear_arg.set_has_arg(true);
+        if (opt->default_given)
+            clear_arg.set_value(from_value_to_enum(opt->var_arg, opt->default_string));
+        else
+            clear_arg.set_value(string(opt->var_arg) + "__NULL");
+      }
+      else if (opt->default_given)
+        {
+          clear_arg.set_has_arg(true);
+          clear_arg.set_value(opt->default_string);
+        }
+
+      clear_arg.generate_clear_arg(stream, indent);
+    }
+}
+
+void
+CmdlineParserCreator::generate_long_option_struct(ostream &stream,
+                                                  unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  struct gengetopt_option * opt;
+
+  foropt
+    {
+      stream << indent_str;
+
+      stream << "{ \"" << opt->long_opt << "\",\t"
+             << (opt->type == ARG_NO || opt->type == ARG_FLAG ? 0 :
+                 (opt->arg_is_optional ? 2 : 1))
+             << ", NULL, ";
+
+      if (opt->short_opt)
+        stream << "\'" << opt->short_opt << "\'";
+      else
+        stream << "0";
+
+      stream << " }," << endl;
+    }
+}
+
+string
+CmdlineParserCreator::generate_getopt_string()
+{
+  struct gengetopt_option * opt;
+  ostringstream built_getopt_string;
+
+  foropt
+    if (opt->short_opt)
+      {
+        built_getopt_string << opt->short_opt <<
+          (opt->type == ARG_NO || opt->type == ARG_FLAG ? "" : ":");
+        built_getopt_string <<
+          (opt->arg_is_optional ? ":" : "");
+      }
+
+  return built_getopt_string.str ();
+}
+
+void
+CmdlineParserCreator::generate_handle_no_short_option(ostream &stream,
+                                                      unsigned int indent)
+{
+  handle_options(stream, indent, false);
+}
+
+void
+CmdlineParserCreator::generate_handle_option(ostream &stream,
+                                             unsigned int indent)
+{
+  handle_options(stream, indent, true);
+}
+
+void
+CmdlineParserCreator::handle_options(ostream &stream, unsigned int indent, bool has_short)
+{
+  struct gengetopt_option * opt;
+  generic_option_gen_class option_gen;
+  string indent_str (indent, ' ');
+  bool first = true;
+
+  option_gen.set_has_short_option (has_short);
+
+  // by default we handle '?' case in the switch
+  // unless the user defined a short option as ?
+  set_handle_question_mark(true);
+
+  foropt
+    {
+      if (opt->short_opt == '?')
+          set_handle_question_mark(false);
+
+      if ((has_short && opt->short_opt) || (!has_short && !opt->short_opt))
+        {
+          if (has_short || first)
+            stream << indent_str;
+
+          option_gen.set_option_comment (opt->desc);
+          option_gen.set_long_option (opt->long_opt);
+          option_gen.set_short_option(opt->short_opt ? string (1, opt->short_opt) : "-");
+          option_gen.set_option_var_name (opt->var_arg);
+          option_gen.set_final_instructions("");
+
+          if (!no_help && ((opt->short_opt == HELP_SHORT_OPT &&
+                  strcmp(opt->long_opt, HELP_LONG_OPT) == 0)
+                  || strcmp(opt->long_opt, HELP_LONG_OPT) == 0
+                  || strcmp(opt->long_opt, FULL_HELP_LONG_OPT) == 0
+                  || strcmp(opt->long_opt, DETAILED_HELP_LONG_OPT) == 0)) {
+              bool full_help = (strcmp(opt->long_opt, FULL_HELP_LONG_OPT) == 0);
+              bool detailed_help = (strcmp(opt->long_opt, DETAILED_HELP_LONG_OPT) == 0);
+              if (no_handle_help) {
+                    // we use the final_instructions parameter to call the free function
+                    // and to return 0
+                    const string final_instructions =
+                    parser_function_name +
+                    string("_free (&local_args_info);\nreturn 0;");
+
+                    option_gen.set_final_instructions(final_instructions);
+
+                    if (full_help) {
+                        option_gen.set_long_option (FULL_HELP_LONG_OPT);
+                        option_gen.set_option_comment (FULL_HELP_OPT_DESCR);
+                    } else if (detailed_help) {
+                        option_gen.set_long_option (DETAILED_HELP_LONG_OPT);
+                        option_gen.set_option_comment (DETAILED_HELP_OPT_DESCR);
+                    } else {
+                        option_gen.set_long_option (HELP_LONG_OPT);
+                        option_gen.set_short_option (HELP_SHORT_OPT_STR);
+                        option_gen.set_option_comment (HELP_OPT_DESCR);
+                    }
+                    //option_gen.set_has_short_option (!full_help);
+              } else {
+                  handle_help_gen_class help_gen;
+                  help_gen.set_parser_name (parser_function_name);
+                  help_gen.set_full_help(full_help);
+                  help_gen.set_detailed_help(detailed_help);
+                  help_gen.set_short_opt(opt->short_opt == HELP_SHORT_OPT);
+                  help_gen.generate_handle_help (stream, indent);
+                  stream << endl;
+                  stream << endl;
+                  continue;
+              }
+          }
+
+          if (!no_version && ((opt->short_opt == VERSION_SHORT_OPT && strcmp(opt->long_opt, VERSION_LONG_OPT) == 0)
+                  || strcmp(opt->long_opt, VERSION_LONG_OPT) == 0)) {
+              if (no_handle_version) {
+                  option_gen.set_long_option (VERSION_LONG_OPT);
+                  option_gen.set_short_option (VERSION_SHORT_OPT_STR);
+                  option_gen.set_option_comment (VERSION_OPT_DESCR);
+                  //option_gen.set_has_short_option (true);
+
+                  // we use the final_instrauctions parameter to call the free function
+                  // and to return 0
+                  const string final_instructions =
+                      parser_function_name +
+                      string("_free (&local_args_info);\nreturn 0;");
+
+                  option_gen.set_final_instructions(final_instructions);
+              } else {
+                  handle_version_gen_class version_gen;
+                  version_gen.set_parser_name (parser_function_name);
+                  version_gen.set_short_opt (opt->short_opt == VERSION_SHORT_OPT);
+                  version_gen.generate_handle_version (stream, indent);
+                  stream << endl;
+                  stream << endl;
+                  continue;
+              }
+          }
+
+          if (opt->acceptedvalues != 0)
+              option_gen.set_possible_values (OPTION_VALUES_NAME(opt->var_arg));
+          else
+              option_gen.set_possible_values ("0");
+
+          string default_string = "0";
+          if (opt->default_string)
+              default_string = string("\"") + opt->default_string + "\"";
+          option_gen.set_default_value (default_string);
+
+          option_gen.set_arg_type(arg_type_constants[opt->type]);
+
+          if (opt->group_value) {
+              option_gen.set_group_var_name (canonize_name (opt->group_value));
+              option_gen.set_option_has_group(true);
+          } else
+              option_gen.set_option_has_group(false);
+
+          if (opt->mode_value) {
+              // we reuse the variable group_var_name also for modes
+              option_gen.set_group_var_name (canonize_name (opt->mode_value));
+              option_gen.set_option_has_mode(true);
+          } else
+              option_gen.set_option_has_mode(false);
+
+          option_gen.set_option_has_type(opt->type != 0);
+
+          if (opt->multiple) {
+              option_gen.set_multiple(true);
+              option_gen.set_structure (string (opt->var_arg) + "_list");
+          } else {
+              option_gen.set_multiple(false);
+              option_gen.set_structure (ARGS_STRUCT);
+          }
+
+          option_gen.generate_generic_option (stream, indent);
+
+          if (has_short)
+            {
+              stream << endl;
+            }
+
+          if (first && !has_short)
+            {
+              first = false;
+              option_gen.set_gen_else ("else ");
+            }
+        }
+    }
+
+  if (! first && !has_short) // something has been generated
+    {
+      generateBreak(stream, indent);
+      stream << endl;
+    }
+}
+
+#define GROUP_REQUIRED_COMPARISON "!="
+#define GROUP_NOT_REQUIRED_COMPARISON ">"
+#define GROUP_REQUIRED_MESSAGE "One"
+#define GROUP_NOT_REQUIRED_MESSAGE "At most one"
+
+void
+CmdlineParserCreator::generate_handle_group(ostream &stream,
+                                            unsigned int indent)
+{
+  group_option_gen_class opt_gen;
+  string indent_str (indent, ' ');
+  opt_gen.set_package_var_name (EXE_NAME);
+
+  opt_gen.set_Comparison_rule(GROUP_NOT_REQUIRED_COMPARISON " 1");
+
+  groups_collection_t::const_iterator end = gengetopt_groups.end();
+  for ( groups_collection_t::const_iterator idx = gengetopt_groups.begin();
+        idx != end; ++idx)
+    {
+      stream << indent_str;
+      opt_gen.set_group_name (idx->first);
+      opt_gen.set_group_var_name (canonize_name (idx->first));
+      if (idx->second.required)
+        {
+          opt_gen.set_number_required(GROUP_REQUIRED_MESSAGE);
+        }
+      else
+        {
+          opt_gen.set_number_required(GROUP_NOT_REQUIRED_MESSAGE);
+        }
+
+      opt_gen.generate_group_option (stream, indent);
+      stream << endl;
+    }
+}
+
+void
+CmdlineParserCreator::generate_handle_required(ostream &stream,
+                                               unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  required_option_gen_class opt_gen;
+  opt_gen.set_package_var_name ("prog_name");
+
+  /* write test for required options or for multiple options
+     (occurrence number check) */
+  foropt
+    if ( opt->required || opt->multiple )
+      {
+        if (opt->mode_value) {
+            opt_gen.set_mode_condition("args_info->" +
+                    canonize_name(opt->mode_value) + "_mode_counter && ");
+        } else {
+            opt_gen.set_mode_condition("");
+        }
+
+        // build the option command line representation
+        ostringstream req_opt;
+        req_opt << "'--" << opt->long_opt << "'";
+        if (opt->short_opt)
+          req_opt << " ('-" << opt->short_opt << "')";
+
+        opt_gen.set_option_var_name (opt->var_arg);
+        opt_gen.set_option_descr (req_opt.str ());
+
+        // if the option is required this is the standard check
+        if (opt->required) {
+          opt_gen.set_checkrange(false);
+
+          opt_gen.generate_required_option (stream, indent);
+        }
+
+        // if the option is multiple we generate also the
+        // occurrence range check
+        if (opt->multiple) {
+          opt_gen.set_checkrange(true);
+
+          opt_gen.generate_required_option (stream, indent);
+        }
+
+        // notice that the above ifs are not mutual exclusive:
+        // a multiple option can have a range check without being
+        // required.
+      }
+
+  // now generate the checks for required group options
+  group_option_gen_class group_opt_gen;
+  group_opt_gen.set_package_var_name ("prog_name");
+
+  group_opt_gen.set_Comparison_rule("== 0");
+  group_opt_gen.set_number_required(GROUP_REQUIRED_MESSAGE);
+
+  groups_collection_t::const_iterator end = gengetopt_groups.end();
+  for ( groups_collection_t::const_iterator idx = gengetopt_groups.begin();
+        idx != end; ++idx)
+  {
+    if (idx->second.required)
+    {
+      group_opt_gen.set_group_name (idx->first);
+      group_opt_gen.set_group_var_name (canonize_name (idx->first));
+
+      group_opt_gen.generate_group_option (stream, indent);
+      stream << endl;
+    }
+  }
+}
+
+void
+CmdlineParserCreator::generate_handle_dependencies(ostream &stream,
+                                               unsigned int indent)
+{
+  struct gengetopt_option * opt;
+  dependant_option_gen_class opt_gen;
+  opt_gen.set_package_var_name ("prog_name");
+  string indent_str (indent, ' ');
+
+  /* write test for required options */
+  foropt
+    if ( opt->dependon )
+      {
+        stream << indent_str;
+
+        ostringstream req_opt;
+        req_opt << "'--" << opt->long_opt << "'";
+        if (opt->short_opt)
+          req_opt << " ('-" << opt->short_opt << "')";
+
+        opt_gen.set_option_var_name (opt->var_arg);
+        opt_gen.set_dep_option (canonize_name(opt->dependon));
+        opt_gen.set_option_descr (req_opt.str ());
+        opt_gen.set_dep_option_descr (opt->dependon);
+
+        opt_gen.generate_dependant_option (stream, indent);
+
+        stream << endl;
+      }
+}
+
+template <typename Collection>
+void generate_counters(const Collection &collection, const string &name, ostream &stream, unsigned int indent)
+{
+    group_counter_gen_class counter_gen;
+    string indent_str (indent, ' ');
+
+    counter_gen.set_name(name);
+
+    typename Collection::const_iterator end = collection.end();
+    for ( typename Collection::const_iterator idx = collection.begin(); idx != end; ++idx) {
+        stream << indent_str;
+        counter_gen.set_group_name (canonize_name (idx->first));
+        counter_gen.generate_group_counter (stream, indent);
+        stream << endl;
+    }
+}
+
+void
+CmdlineParserCreator::generate_group_counters(ostream &stream,
+                                              unsigned int indent)
+{
+    generate_counters(gengetopt_groups, "group", stream, indent);
+}
+
+void
+CmdlineParserCreator::generate_mode_counters(ostream &stream,
+                                              unsigned int indent)
+{
+    // we can reuse group counter gen class also for modes
+    generate_counters(gengetopt_modes, "mode", stream, indent);
+}
+
+int
+CmdlineParserCreator::generate_source ()
+{
+  /* ****************************************************** */
+  /* ********************************************** C FILE  */
+  /* ****************************************************** */
+
+  set_usage_string (generate_usage_string ());
+  set_getopt_string (generate_getopt_string ());
+
+  string output_source = c_filename;
+
+  if (src_output_dir.size())
+      output_source = src_output_dir + "/" + output_source;
+  else if (output_dir.size())
+      output_source = output_dir + "/" + output_source;
+
+  ofstream *output_file = open_fstream (output_source.c_str());
+  generate_c_source (*output_file);
+  output_file->close ();
+  delete output_file;
+
+  return 0;
+}
+
+void
+CmdlineParserCreator::generate_free(ostream &stream,
+                                    unsigned int indent)
+{
+  struct gengetopt_option * opt;
+
+  foropt
+    {
+      free_option (opt, stream, indent);
+    }
+}
+
+void
+CmdlineParserCreator::generate_list_free(ostream &stream,
+                                         unsigned int indent)
+{
+  struct gengetopt_option * opt;
+
+  if (! has_multiple_options())
+    return;
+
+  free_list_gen_class free_list;
+
+  foropt
+    {
+      if (opt->multiple && opt->type) {
+        free_list.set_list_name(opt->var_arg);
+        free_list.set_string_list(opt->type == ARG_STRING);
+        free_list.generate_free_list(stream, indent);
+      }
+    }
+}
+
+void
+CmdlineParserCreator::generate_file_save_loop(ostream &stream, unsigned int indent)
+{
+  struct gengetopt_option * opt;
+
+  file_save_multiple_gen_class file_save_multiple;
+  file_save_gen_class file_save;
+
+  const string suffix = "_orig";
+  const string suffix_given = "_given";
+
+  foropt {
+    if (opt->multiple) {
+      file_save_multiple.set_has_arg(opt->type != ARG_NO);
+      file_save_multiple.set_opt_var(opt->var_arg);
+      file_save_multiple.set_opt_name(opt->long_opt);
+      file_save_multiple.set_values
+          ((opt->acceptedvalues ? OPTION_VALUES_NAME(opt->var_arg) : "0"));
+
+      file_save_multiple.generate_file_save_multiple(stream, indent);
+    } else {
+      file_save.set_opt_name(opt->long_opt);
+      file_save.set_given(opt->var_arg + suffix_given);
+      file_save.set_values
+          ((opt->acceptedvalues ? OPTION_VALUES_NAME(opt->var_arg) : "0"));
+
+      if (opt->type != ARG_NO && opt->type != ARG_FLAG) {
+        file_save.set_arg(opt->var_arg + suffix + (opt->multiple ? " [i]" : ""));
+      } else {
+        file_save.set_arg("");
+      }
+      file_save.generate_file_save(stream, indent);
+    }
+  }
+}
+
+
diff --git a/cmake/gengetopt/gm.h b/cmake/gengetopt/gm.h
new file mode 100644 (file)
index 0000000..ffd25db
--- /dev/null
@@ -0,0 +1,189 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GM_H
+#define _GM_H
+
+#include "skels/header.h"
+#include "skels/c_source.h"
+
+#include <list>
+#include <string>
+
+#define TAB_LEN 2
+
+struct gengetopt_option;
+
+typedef std::list<std::string> OptionHelpList;
+
+class CmdlineParserCreator : public header_gen_class, public c_source_gen_class
+{
+ protected:
+  char *parser_function_name;
+  char *filename;
+  char *args_info_name;
+  char *header_filename;
+  char *c_filename;
+  string output_dir;
+  string header_output_dir;
+  string src_output_dir;
+  string comment;
+  char *unamed_options;
+  string show_required_string;
+
+  bool long_help;
+  bool no_handle_help;
+  bool no_help;
+  bool no_handle_version;
+  bool no_version;
+  bool no_handle_error;
+  bool conf_parser;
+  bool string_parser;
+  bool gen_gengetopt_version;
+  bool gen_strdup;
+
+  unsigned int tab_indentation ; /* tab indentation level */
+
+  void inc_indent()
+    {
+      tab_indentation += TAB_LEN ;
+    }
+
+  void dec_indent()
+    {
+      tab_indentation -= TAB_LEN ;
+    }
+
+  void indent()
+    {
+      unsigned int i ;
+
+      for ( i = 1 ; i <= tab_indentation ; ++i )
+        printf (" ");
+    }
+
+  void free_option(struct gengetopt_option *opt,
+                   ostream &stream, unsigned int indent);
+
+  int generate_header_file();
+  int generate_source();
+
+  string generate_getopt_string();
+
+  // to be implemented in header_gen_class
+  virtual void generate_enum_types(ostream &stream, unsigned int indent);
+  virtual void generate_option_arg(ostream &stream, unsigned int indent);
+  virtual void generate_option_given(ostream &stream, unsigned int indent);
+  virtual void generate_option_values_decl(ostream &stream, unsigned int indent);
+
+  // to be implemented in c_source_gen_class
+  virtual void generate_clear_arg(ostream &stream, unsigned int indent);
+  virtual void generate_given_init(ostream &stream, unsigned int indent);
+  virtual void generate_option_values(ostream &stream, unsigned int indent);
+
+  virtual void generate_handle_no_short_option(ostream &stream,
+                                               unsigned int indent);
+  virtual void generate_handle_option(ostream &stream, unsigned int indent);
+  virtual void generate_handle_required(ostream &stream, unsigned int indent);
+  virtual void generate_handle_dependencies(ostream &stream, unsigned int indent);
+  virtual void generate_handle_group(ostream &stream, unsigned int indent);
+  virtual void generate_group_counters(ostream &stream, unsigned int indent);
+  virtual void generate_mode_counters(ostream &stream, unsigned int indent);
+  virtual void generate_help_option_print(ostream &stream,
+                                          unsigned int indent);
+  virtual void generate_full_help_option_print(ostream &stream,
+                                          unsigned int indent);
+  virtual void generate_detailed_help_option_print(ostream &stream,
+                                          unsigned int indent);
+  virtual void generate_long_option_struct(ostream &stream,
+                                           unsigned int indent);
+  virtual void generate_reset_groups(ostream &stream, unsigned int indent);
+
+  virtual void generate_free(ostream &stream, unsigned int indent);
+  virtual void generate_list_free(ostream &stream, unsigned int indent);
+
+  virtual void generate_file_save_loop(ostream &stream, unsigned int indent);
+  virtual void generate_init_args_info(ostream &stream, unsigned int indent);
+
+  virtual void generate_custom_getopt(ostream &stream, unsigned int indent);
+
+  void generateBreak(ostream &stream, unsigned int indent = 0);
+
+  void handle_options(ostream &, unsigned int, bool has_short);
+
+ public:
+
+  CmdlineParserCreator (char *function_name, char *struct_name,
+                        char *unamed_options,
+                        char *filename, char *header_ext, char *c_ext,
+                        bool long_help,
+                        bool no_handle_help, bool no_help,
+                        bool no_handle_version, bool no_version,
+                        bool no_handle_error, bool conf_parser, bool string_parser,
+                        bool gen_version, bool gen_getopt, bool no_options,
+                        const string &comment,
+                        const string &outdir,
+                        const string &header_outdir,
+                        const string &src_outdir,
+                        const string &show_required);
+
+  int generate();
+
+  virtual void generate_list_def(ostream &stream, unsigned int indent);
+  virtual void generate_multiple_fill_array(ostream &stream, unsigned int indent);
+  virtual void generate_update_multiple_given(ostream &stream, unsigned int indent);
+  virtual void generate_check_modes(ostream &stream, unsigned int indent);
+
+  const string generate_purpose();
+  const string generate_description();
+  const string generate_usage_string(bool use_config_package = true);
+
+  /**
+   * generate a list of option descriptions that will be printed in the
+   * help output
+   * 
+   * @param generate_hidden if true, include also the hidden options
+   * @param generate_details if true, include also the hidden options and
+   * details for options that have them.
+   */
+  OptionHelpList *generate_help_option_list(bool generate_hidden = false,
+          bool generate_details = false);
+  
+  /**
+   * generate the sharing between a list of help string, using the
+   * complete_list as the list with all the strings (both for hidden
+   * options and details, e.g.) and the smaller_list as the list
+   * with less strings
+   * 
+   * @param target_array the name of the array to copy to
+   * @param source_array the name of the array to copy from
+   */
+  void generate_help_option_print_from_lists(ostream &stream,
+          unsigned int indent, OptionHelpList *complete_list,
+          OptionHelpList *smaller_list, const std::string &target_array,
+          const std::string &source_array);
+  
+  /**
+   * Sets the has_arg_XXX by inspecting all the options types
+   */
+  void set_has_arg_types();
+};
+
+#endif /* _GM_H */
diff --git a/cmake/gengetopt/gm_utils.cpp b/cmake/gengetopt/gm_utils.cpp
new file mode 100644 (file)
index 0000000..229a00c
--- /dev/null
@@ -0,0 +1,335 @@
+//
+// C++ Implementation: gm_utils
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "gm_utils.h"
+#include "my_sstream.h"
+#include "ggo_options.h"
+#include "argsdef.h"
+#include "groups.h"
+
+extern groups_collection_t gengetopt_groups;
+
+char *
+canonize_names(const char *name) {
+    char *pvar;
+    char *p;
+
+    pvar = strdup(name);
+
+    for (p = pvar; *p; ++p)
+        if (*p == '.' || *p == '-')
+            *p = '_';
+
+    return pvar;
+}
+
+// remove the path from the file name
+const string strip_path(const string &s) {
+    string::size_type pos_of_sep;
+
+    pos_of_sep = s.rfind("/");
+    if (pos_of_sep == string::npos)
+        pos_of_sep = s.rfind("\\"); // try also with DOS path sep
+
+    if (pos_of_sep == string::npos)
+        return s; // no path
+
+    return s.substr(pos_of_sep + 1);
+}
+
+const string to_upper(const string &old) {
+    string upper = old;
+
+    for (string::iterator s = upper.begin(); s != upper.end(); ++s)
+        *s = toupper(*s);
+
+    return upper;
+}
+
+const string canonize_name(const string &old) {
+    string canonized = old;
+
+    for (string::iterator s = canonized.begin(); s != canonized.end(); ++s)
+        if (*s == '.' || *s == '-' || *s == ' ')
+            *s = '_';
+
+    return canonized;
+}
+
+const string canonize_enum(const string &old) {
+    string canonized;
+
+    for (string::const_iterator s = old.begin(); s != old.end(); ++s)
+        if (*s == '-')
+            canonized += "MINUS_";
+        else if (*s == '+')
+            canonized += "PLUS_";
+        else
+            canonized += *s;
+
+    return canonized;
+}
+
+bool has_multiple_options_all_string() {
+    if (!has_multiple_options())
+        return false;
+
+    struct gengetopt_option * opt = 0;
+
+    foropt {
+        if (opt->multiple && (opt->type && opt->type != ARG_STRING))
+            return false;
+    }
+
+    return true;
+}
+
+bool has_multiple_options_string() {
+    if (!has_multiple_options())
+        return false;
+
+    struct gengetopt_option * opt = 0;
+
+    foropt {
+        if (opt->multiple && opt->type == ARG_STRING)
+            return true;
+    }
+
+    return false;
+}
+
+bool has_multiple_options() {
+    struct gengetopt_option * opt = 0;
+
+    foropt {
+        if (opt->multiple)
+            return true;
+    }
+
+    return false;
+}
+
+bool has_multiple_options_with_type() {
+    gengetopt_option * opt = 0;
+
+    for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+            != gengetopt_options.end() && (opt = *it); ++it)
+        if (opt->multiple && opt->type)
+            return true;
+
+    return false;
+}
+
+bool has_multiple_options_with_default() {
+    gengetopt_option * opt = 0;
+
+    for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+            != gengetopt_options.end() && (opt = *it); ++it)
+        if (opt->multiple && opt->default_given)
+            return true;
+
+    return false;
+}
+
+bool has_options_with_details() {
+    gengetopt_option * opt = 0;
+
+    for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+            != gengetopt_options.end() && (opt = *it); ++it)
+        if (opt->details)
+            return true;
+
+    return false;
+}
+
+bool has_options_with_type() {
+    gengetopt_option * opt = 0;
+
+    for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+            != gengetopt_options.end() && (opt = *it); ++it)
+        if (opt->type && opt->type != ARG_FLAG)
+            return true;
+
+    return false;
+}
+
+bool has_options_with_mode() {
+    gengetopt_option * opt = 0;
+
+    for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+            != gengetopt_options.end() && (opt = *it); ++it)
+        if (opt->mode_value)
+            return true;
+
+    return false;
+}
+
+bool has_required() {
+    struct gengetopt_option * opt = 0;
+
+    foropt {
+        if (opt->required)
+            return true;
+    }
+
+    groups_collection_t::const_iterator end = gengetopt_groups.end();
+    for (groups_collection_t::const_iterator idx = gengetopt_groups.begin(); idx
+            != end; ++idx) {
+        if (idx->second.required) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool has_dependencies() {
+    struct gengetopt_option * opt = 0;
+
+    foropt {
+        if (opt->dependon)
+            return true;
+    }
+
+    return false;
+}
+
+bool has_options() {
+    struct gengetopt_option * opt = 0;
+
+    foropt {
+        if (opt->short_opt) {
+            if (opt->short_opt != 'h' && opt->short_opt != 'V')
+                return true;
+        }
+    }
+
+    return false;
+}
+
+bool has_hidden_options() {
+    struct gengetopt_option * opt = 0;
+
+    foropt {
+        if (opt->hidden) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool has_values() {
+    struct gengetopt_option * opt = 0;
+
+    for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
+            != gengetopt_options.end(); ++it) {
+        opt = *it;
+        if (opt->acceptedvalues) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+int not_newlines(const string &buf, int &num_of_newlines) {
+    num_of_newlines = 0;
+    // searches for the first non newline char
+    string::size_type notnewline = buf.find_first_not_of("\r\n");
+
+    if (notnewline == string::npos) {
+        // a string made only of newlines
+        num_of_newlines = buf.size();
+        return num_of_newlines;
+    }
+
+    if (notnewline) {
+        // everything before the non newline char is a newline
+        num_of_newlines = notnewline;
+        return notnewline;
+    }
+
+    return 0;
+}
+
+void wrap_cstr(string& wrapped, unsigned int from_column,
+        unsigned int second_indent, const string &orig) {
+    int next_space = from_column;
+    string next_word;
+    const char * out_buf = orig.c_str();
+    ostringstream stream;
+    const unsigned int second_line_column = from_column + second_indent;
+    string indent(second_line_column, ' ');
+    int newline_chars = 0;
+    int num_of_newlines = 0;
+
+    while (*out_buf) {
+        // check for a new line
+        if (*out_buf) {
+            if ((newline_chars = not_newlines(out_buf, num_of_newlines))) {
+                for (int i = 1; i <= num_of_newlines; ++i)
+                    stream << "\\n";
+
+                out_buf += newline_chars;
+
+                if (*out_buf) {
+                    stream << indent;
+                    next_space = second_line_column;
+                    continue;
+                } else
+                    break;
+            } else {
+                stream << *out_buf++;
+                next_space++;
+            }
+        }
+        // search next whitespace, i.e., next word
+        while ((*out_buf) && (*out_buf != ' ') &&
+                !not_newlines(out_buf, num_of_newlines)) {
+            next_word += *out_buf++;
+            next_space++;
+        }
+
+        // wrap line if it's too long
+        if (next_space > 79) {
+            stream << "\\n" << indent << next_word;
+            next_space = second_line_column + next_word.size();
+        } else
+            stream << next_word; // simply write word
+
+        next_word = "";
+    }
+
+    wrapped += stream.str();
+}
+
+bool is_numeric(const gengetopt_option *opt) {
+    switch (opt->type) {
+    case ARG_INT:
+    case ARG_SHORT:
+    case ARG_LONG:
+    case ARG_FLOAT:
+    case ARG_DOUBLE:
+    case ARG_LONGDOUBLE:
+    case ARG_LONGLONG:
+        return true;
+    default:
+        return false;
+    }
+}
diff --git a/cmake/gengetopt/gm_utils.h b/cmake/gengetopt/gm_utils.h
new file mode 100644 (file)
index 0000000..3f1c71b
--- /dev/null
@@ -0,0 +1,131 @@
+//
+// C++ Interface: gm_utils
+//
+// Description:
+//
+//
+// Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef GM_UTILS_H
+#define GM_UTILS_H
+
+#include <string>
+#include <iostream>
+
+#include "ggos.h"
+
+using std::string;
+
+/**
+ * @param name
+ * @return a copy of the string passed after canonizing it (i.e. '-' and
+ * '.' are transformed in '_').
+ */
+char *canonize_names(const char * name);
+
+/**
+ * @param name
+ * @return a copy of the string passed after canonizing it (i.e. '-' and
+ * '.' are transformed in '_').
+ */
+const string canonize_name(const string &name);
+
+/**
+ * @param s the string representing an enum value
+ * @return a copy of the string passed after canonizing it (i.e. '-' and
+ * becomes _MINUS_, '+' becomes _PLUS_)
+ */
+const string canonize_enum(const string &s);
+
+const string strip_path(const string &);
+const string to_upper(const string &);
+
+/**
+ * All multiple options are of type string
+ * @return All multiple options are of type string
+ */
+bool has_multiple_options_all_string();
+
+/**
+ * Has multiple options and at least one is of type string
+ * @return Has multiple options and at least one is of type string
+ */
+bool has_multiple_options_string();
+
+/**
+ * Has multiple options and at least one has a default value
+ * @return Has multiple options and at least one has a default value
+ */
+bool has_multiple_options_with_default();
+
+bool has_multiple_options();
+bool has_multiple_options_with_type();
+bool has_required();
+bool has_dependencies();
+bool has_options_with_type();
+bool has_options_with_mode();
+bool has_options();
+bool has_hidden_options();
+bool has_options_with_details();
+bool has_values();
+
+/**
+ * Whether the specified option deals with number
+ *
+ * @param opt
+ * @return
+ */
+bool is_numeric(const gengetopt_option *opt);
+
+/**
+ * Performs word wrapping on the passed string (and return the result in the first
+ * parameter).
+ *
+ * @param wrapped the output parameter
+ * @param from_column the string start from this column
+ * @param second_indent an additional indentation for lines after the
+ * first one
+ * @param orig the original string that must be wrapped
+ */
+void wrap_cstr (string &wrapped, unsigned int from_column, unsigned int second_indent, const string &orig);
+
+/**
+ * Searches for characters which are not newlines.
+ *
+ * @param buf where to search for new characters
+ * @param num_of_newlines where the number of newlines
+ * before the first non newline char will be stored
+ * @return the position in the string after the (possible) new line char
+ */
+int not_newlines(const string &buf, int &num_of_newlines);
+
+/**
+ * Function object to print something into a stream (to be used with for_each)
+ */
+template<class T>
+struct print_f : public std::unary_function<T, void>
+{
+    print_f(std::ostream& out, const string &s = ", ") : os(out), sep(s) {}
+    void operator() (T x) { os << x << sep; }
+    std::ostream& os;
+    const string &sep;
+};
+
+/**
+ * Function object to print a pair into two streams (to be used with for_each)
+ */
+template<class T>
+struct pair_print_f : public std::unary_function<T, void>
+{
+    pair_print_f(std::ostream& out1, std::ostream& out2, const string &s = ", ") :
+        os1(out1), os2(out2), sep(s) {}
+    void operator() (T x) { os1 << x.first << sep; os2 << x.second << sep;}
+    std::ostream &os1, &os2;
+    const string &sep;
+};
+
+#endif
diff --git a/cmake/gengetopt/gnugetopt.h b/cmake/gengetopt/gnugetopt.h
new file mode 100644 (file)
index 0000000..a1b8dd6
--- /dev/null
@@ -0,0 +1,180 @@
+/* Declarations for getopt.
+   Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+   standalone, or this is the first header included in the source file.
+   If we are being used with glibc, we need to include <features.h>, but
+   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
+   not defined, include <ctype.h>, which will pull in <features.h> for us
+   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
+   doesn't flood the namespace with stuff the way some other headers do.)  */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+  const char *name;
+# else
+  char *name;
+# endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+# define no_argument           0
+# define required_argument     1
+# define optional_argument     2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+   arguments in ARGV (ARGC of them, minus the program name) for
+   options given in OPTS.
+
+   Return the option character from OPTS just read.  Return -1 when
+   there are no more options.  For unrecognized options, or options
+   missing arguments, `optopt' is set to the option letter, and '?' is
+   returned.
+
+   The OPTS string is a list of characters which are recognized option
+   letters, optionally followed by colons, specifying that that letter
+   takes an argument, to be placed in `optarg'.
+
+   If a letter in OPTS is followed by two colons, its argument is
+   optional.  This behavior is specific to the GNU `getopt'.
+
+   The argument `--' causes premature termination of argument
+   scanning, explicitly telling `getopt' that there are no more
+   options.
+
+   If OPTS begins with `--', then non-option arguments are treated as
+   arguments to the option '\0'.  This behavior is specific to the GNU
+   `getopt'.  */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
+                       const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int __argc, char *const *__argv,
+                            const char *__shortopts,
+                            const struct option *__longopts, int *__longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int __argc, char *const *__argv,
+                            const char *__shortopts,
+                            const struct option *__longopts, int *__longind,
+                            int __long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations.  */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/cmake/gengetopt/groups.h b/cmake/gengetopt/groups.h
new file mode 100644 (file)
index 0000000..2b02b24
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt 
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU General Public License as published by 
+ * the Free Software Foundation; either version 3, or (at your option) 
+ * any later version. 
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details. 
+ *
+ * You should have received a copy of the GNU General Public License along 
+ * with gengetopt; see the file COPYING. If not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef GGO_GROUPS_H
+#define GGO_GROUPS_H
+
+#include "my_string.h"
+#include "my_map.h"
+
+/**
+ * Represents a group of options
+ */
+struct Group
+{
+  string desc;
+  bool required;
+
+  Group(const string &s, bool r) : desc (s), required (r) {}
+};
+
+typedef map<string,Group> groups_collection_t;
+
+/**
+ * Represents a mode of options
+ */
+struct Mode
+{
+  string desc;
+
+  Mode(const string &s) : desc (s) {}
+};
+
+typedef map<string,Mode> modes_collection_t;
+
+#endif // GROUPS_H
diff --git a/cmake/gengetopt/include_cygwin/getopt.h b/cmake/gengetopt/include_cygwin/getopt.h
new file mode 100644 (file)
index 0000000..0c1c8c9
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1987, 1993, 1994, 1996
+ *  The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *  This product includes software developed by the University of
+ *  California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef _COMPILING_NEWLIB
+#include_next "getopt.h"
+#else
+#ifndef __GETOPT_H__
+#define __GETOPT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __INSIDE_CYGWIN__
+extern int __declspec(dllimport) opterr;       /* if error message should be printed */
+extern int __declspec(dllimport) optind;       /* index into parent argv vector */
+extern int __declspec(dllimport) optopt;       /* character checked for validity */
+extern int __declspec(dllimport) optreset;     /* reset getopt */
+extern char __declspec(dllimport) *optarg;     /* argument associated with option */
+#endif
+
+int getopt (int, char * const *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GETOPT_H__ */
+
+#ifndef __UNISTD_GETOPT__
+#ifndef __GETOPT_LONG_H__
+#define __GETOPT_LONG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct option {
+       const char *name;
+       int  has_arg;
+       int *flag;
+       int val;
+};
+
+int getopt_long (int, char *const *, const char *, const struct option *, int *);
+int getopt_long_only (int, char *const *, const char *, const struct option *, int *);
+
+#ifndef HAVE_DECL_GETOPT
+#define HAVE_DECL_GETOPT 1
+#endif
+
+#define no_argument             0
+#define required_argument       1
+#define optional_argument       2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GETOPT_LONG_H__ */
+#endif /* __UNISTD_GETOPT__ */
+#endif /*_INSIDE_NEWLIB*/
diff --git a/cmake/gengetopt/my_map.h b/cmake/gengetopt/my_map.h
new file mode 100644 (file)
index 0000000..8da8507
--- /dev/null
@@ -0,0 +1,17 @@
+// handle namespaces
+
+#ifndef _MY_MAP_H
+#define _MY_MAP_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <map>
+
+#ifdef HAVE_NAMESPACES
+using std::map;
+using std::make_pair;
+#endif
+
+#endif // _MY_MAP_H
diff --git a/cmake/gengetopt/my_sstream.h b/cmake/gengetopt/my_sstream.h
new file mode 100644 (file)
index 0000000..ace2bdd
--- /dev/null
@@ -0,0 +1,15 @@
+// deal with namespace problems
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#ifdef HAVE_SSTREAM
+#include <sstream>
+#else
+#include "includes/sstream"
+#endif
+
+#ifdef HAVE_NAMESPACES
+using std::ostringstream;
+#endif
diff --git a/cmake/gengetopt/my_string.h b/cmake/gengetopt/my_string.h
new file mode 100644 (file)
index 0000000..e22d2c7
--- /dev/null
@@ -0,0 +1,11 @@
+// deal with namespace problems
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif // HAVE_CONFIG_H
+
+#include <string>
+
+#ifdef HAVE_NAMESPACES
+using std::string;
+#endif
diff --git a/cmake/gengetopt/parser.cc b/cmake/gengetopt/parser.cc
new file mode 100644 (file)
index 0000000..8c1bc53
--- /dev/null
@@ -0,0 +1,2432 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+   
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+   
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.4.1"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 1
+
+
+
+/* Copy the first part of user declarations.  */
+
+/* Line 189 of yacc.c  */
+#line 22 "../../src/parser.yy"
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <string>
+
+#include "my_sstream.h"
+
+#include "acceptedvalues.h"
+
+#include "argsdef.h"
+
+#include "gengetopt.h"
+#include "errorcodes.h"
+#include "ggos.h"
+#include "yyerror.h"
+
+extern int gengetopt_count_line;
+extern char * gengetopt_input_filename;
+
+static int gengetopt_package_given = 0;
+static int gengetopt_version_given = 0;
+static int gengetopt_purpose_given = 0;
+static int gengetopt_usage_given = 0;
+static int gengetopt_description_given = 0;
+
+/// the last option parsed
+static gengetopt_option *current_option = 0;
+
+extern int yylex (void) ;
+
+//#define YYERROR_VERBOSE 1
+
+void check_result(int o, gengetopt_option *opt)
+{
+  if (o)
+    {
+        ostringstream err;
+
+    switch (o)
+    {
+    case NOT_ENOUGH_MEMORY:
+        yyerror (opt, "not enough memory");
+       break;
+    case REQ_LONG_OPTION:
+        err << "long option redefined \'" << opt->long_opt << "\'";
+        yyerror (opt, err.str().c_str());
+               break;
+    case REQ_SHORT_OPTION:
+        err << "short option redefined \'" << opt->short_opt << "\'";
+        yyerror (opt, err.str().c_str());
+        break;
+    case FOUND_BUG:
+        yyerror (opt, "bug found!!");
+        break;
+    case GROUP_UNDEFINED:
+        yyerror (opt, "group undefined");
+        break;
+    case MODE_UNDEFINED:
+        yyerror (opt, "mode undefined");
+        break;
+    case INVALID_DEFAULT_VALUE:
+        yyerror (opt, "invalid default value");
+        break;
+    case NOT_REQUESTED_TYPE:
+        yyerror (opt, "type specification not requested");
+        break;
+    case NOT_VALID_SPECIFICATION:
+      yyerror (opt, "invalid specification for this kind of option");
+      break;
+    case SPECIFY_FLAG_STAT:
+      yyerror (opt, "you must specify the default flag status");
+      break;
+    case NOT_GROUP_OPTION:
+      yyerror (opt, "group specification for a non group option");
+      break;
+    case NOT_MODE_OPTION:
+      yyerror (opt, "mode specification for an option not belonging to a mode");
+      break;
+    case SPECIFY_GROUP:
+      yyerror (opt, "missing group specification");
+      break;
+    case SPECIFY_MODE:
+      yyerror (opt, "missing mode specification");
+      break;
+    case INVALID_NUMERIC_VALUE:
+        yyerror (opt, "invalid numeric value");
+        break;
+    case INVALID_ENUM_TYPE_USE:
+       yyerror (opt, "enum type can only be specified for options with values");
+        break;
+    case HELP_REDEFINED:
+       yyerror (opt, "if you want to redefine --help, please use option --no-help");
+        break;
+    case VERSION_REDEFINED:
+       yyerror (opt, "if you want to redefine --version, please use option --no-version");
+        break;
+    }
+  }
+}
+
+/* the number of allowed occurrences of a multiple option */
+struct multiple_size
+{
+    /* these strings are allocated dynamically and NOT
+      automatically freed upon destruction */
+    char *min;
+    char *max;
+
+    /* if no limit is specified then initialized to 0.
+       if the same size is specified for min and max, it means that an exact
+       number of occurrences is required*/
+    multiple_size(const char *m = "0", const char *M = "0") :
+        min(strdup(m)), max(strdup(M))
+    {}
+};
+
+#define check_error if (o) YYERROR;
+
+
+
+/* Line 189 of yacc.c  */
+#line 200 "../../src/parser.cc"
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     TOK_PACKAGE = 258,
+     TOK_VERSION = 259,
+     TOK_OPTION = 260,
+     TOK_DEFGROUP = 261,
+     TOK_GROUPOPTION = 262,
+     TOK_DEFMODE = 263,
+     TOK_MODEOPTION = 264,
+     TOK_YES = 265,
+     TOK_NO = 266,
+     TOK_ON = 267,
+     TOK_OFF = 268,
+     TOK_FLAG = 269,
+     TOK_PURPOSE = 270,
+     TOK_DESCRIPTION = 271,
+     TOK_USAGE = 272,
+     TOK_DEFAULT = 273,
+     TOK_GROUP = 274,
+     TOK_GROUPDESC = 275,
+     TOK_MODE = 276,
+     TOK_MODEDESC = 277,
+     TOK_MULTIPLE = 278,
+     TOK_ARGOPTIONAL = 279,
+     TOK_TYPESTR = 280,
+     TOK_SECTION = 281,
+     TOK_DETAILS = 282,
+     TOK_SECTIONDESC = 283,
+     TOK_TEXT = 284,
+     TOK_ARGS = 285,
+     TOK_VALUES = 286,
+     TOK_HIDDEN = 287,
+     TOK_DEPENDON = 288,
+     TOK_STRING = 289,
+     TOK_CHAR = 290,
+     TOK_ARGTYPE = 291,
+     TOK_SIZE = 292
+   };
+#endif
+/* Tokens.  */
+#define TOK_PACKAGE 258
+#define TOK_VERSION 259
+#define TOK_OPTION 260
+#define TOK_DEFGROUP 261
+#define TOK_GROUPOPTION 262
+#define TOK_DEFMODE 263
+#define TOK_MODEOPTION 264
+#define TOK_YES 265
+#define TOK_NO 266
+#define TOK_ON 267
+#define TOK_OFF 268
+#define TOK_FLAG 269
+#define TOK_PURPOSE 270
+#define TOK_DESCRIPTION 271
+#define TOK_USAGE 272
+#define TOK_DEFAULT 273
+#define TOK_GROUP 274
+#define TOK_GROUPDESC 275
+#define TOK_MODE 276
+#define TOK_MODEDESC 277
+#define TOK_MULTIPLE 278
+#define TOK_ARGOPTIONAL 279
+#define TOK_TYPESTR 280
+#define TOK_SECTION 281
+#define TOK_DETAILS 282
+#define TOK_SECTIONDESC 283
+#define TOK_TEXT 284
+#define TOK_ARGS 285
+#define TOK_VALUES 286
+#define TOK_HIDDEN 287
+#define TOK_DEPENDON 288
+#define TOK_STRING 289
+#define TOK_CHAR 290
+#define TOK_ARGTYPE 291
+#define TOK_SIZE 292
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 214 of yacc.c  */
+#line 148 "../../src/parser.yy"
+
+    char   *str;
+    char    chr;
+    int            argtype;
+    int            boolean;
+    class AcceptedValues *ValueList;
+    struct gengetopt_option *gengetopt_option;
+    struct multiple_size *multiple_size;
+
+
+
+/* Line 214 of yacc.c  */
+#line 322 "../../src/parser.cc"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 264 of yacc.c  */
+#line 347 "../../src/parser.cc"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+    int yyi;
+#endif
+{
+  return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+            && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+        || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+            && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+  YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+      + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                          \
+    do                                                                 \
+      {                                                                        \
+       YYSIZE_T yynewbytes;                                            \
+       YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+       Stack = &yyptr->Stack_alloc;                                    \
+       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  43
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   92
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  43
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  27
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  66
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  116
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   292
+
+#define YYTRANSLATE(YYX)                                               \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      40,    41,     2,     2,    39,    42,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    38,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint8 yyprhs[] =
+{
+       0,     0,     3,     4,     7,     9,    11,    13,    15,    17,
+      19,    21,    23,    25,    27,    29,    31,    33,    36,    39,
+      42,    45,    48,    52,    55,    58,    63,    67,    73,    79,
+      85,    87,    90,    93,    98,   103,   108,   113,   118,   123,
+     128,   131,   135,   138,   141,   144,   145,   147,   149,   150,
+     152,   154,   156,   158,   159,   163,   164,   168,   169,   173,
+     175,   179,   181,   182,   186,   191,   196
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      44,     0,    -1,    -1,    45,    44,    -1,    46,    -1,    47,
+      -1,    53,    -1,    48,    -1,    49,    -1,    50,    -1,    51,
+      -1,    56,    -1,    52,    -1,    57,    -1,    54,    -1,    58,
+      -1,    55,    -1,     3,    34,    -1,     4,    34,    -1,    15,
+      59,    -1,    16,    59,    -1,    17,    59,    -1,    26,    59,
+      66,    -1,    29,    59,    -1,    30,    34,    -1,     6,    34,
+      64,    62,    -1,     8,    34,    65,    -1,     5,    34,    35,
+      59,    60,    -1,     7,    34,    35,    59,    60,    -1,     9,
+      34,    35,    59,    60,    -1,    34,    -1,    60,    63,    -1,
+      60,    36,    -1,    60,    25,    38,    34,    -1,    60,    27,
+      38,    59,    -1,    60,    31,    38,    67,    -1,    60,    18,
+      38,    34,    -1,    60,    19,    38,    34,    -1,    60,    21,
+      38,    34,    -1,    60,    33,    38,    34,    -1,    60,    24,
+      -1,    60,    23,    69,    -1,    60,    14,    -1,    60,    32,
+      -1,    60,    61,    -1,    -1,    12,    -1,    13,    -1,    -1,
+      10,    -1,    11,    -1,    10,    -1,    11,    -1,    -1,    20,
+      38,    34,    -1,    -1,    22,    38,    34,    -1,    -1,    28,
+      38,    34,    -1,    68,    -1,    67,    39,    68,    -1,    34,
+      -1,    -1,    40,    37,    41,    -1,    40,    37,    42,    41,
+      -1,    40,    42,    37,    41,    -1,    40,    37,    42,    37,
+      41,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   209,   209,   211,   216,   217,   218,   219,   220,   221,
+     222,   223,   224,   225,   226,   227,   228,   233,   253,   273,
+     293,   313,   334,   341,   358,   365,   376,   387,   407,   426,
+     448,   451,   457,   462,   467,   472,   477,   482,   487,   492,
+     497,   502,   510,   515,   520,   525,   529,   530,   534,   535,
+     536,   540,   541,   545,   546,   550,   551,   555,   556,   560,
+     561,   565,   569,   570,   571,   572,   573
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "\"package\"", "\"version\"",
+  "\"option\"", "\"defgroup\"", "\"groupoption\"", "\"defmode\"",
+  "\"modeoption\"", "\"yes\"", "\"no\"", "\"on\"", "\"off\"", "\"flag\"",
+  "\"purpose\"", "\"description\"", "\"usage\"", "\"default\"",
+  "\"group\"", "\"groupdesc\"", "\"mode\"", "\"modedesc\"", "\"multiple\"",
+  "\"argoptional\"", "\"typestr\"", "\"section\"", "\"details\"",
+  "\"sectiondesc\"", "\"text\"", "\"args\"", "\"values\"", "\"hidden\"",
+  "\"dependon\"", "TOK_STRING", "TOK_CHAR", "TOK_ARGTYPE", "TOK_SIZE",
+  "'='", "','", "'('", "')'", "'-'", "$accept", "input", "statement",
+  "package", "version", "purpose", "description", "usage", "sectiondef",
+  "text", "args", "groupdef", "modedef", "option", "groupoption",
+  "modeoption", "quoted_string", "option_parts", "req_onoff",
+  "optional_yesno", "opt_yesno", "opt_groupdesc", "opt_modedesc",
+  "opt_sectiondesc", "listofvalues", "acceptedvalue", "multiple_size", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,    61,    44,
+      40,    41,    45
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    43,    44,    44,    45,    45,    45,    45,    45,    45,
+      45,    45,    45,    45,    45,    45,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    57,    58,
+      59,    60,    60,    60,    60,    60,    60,    60,    60,    60,
+      60,    60,    60,    60,    60,    60,    61,    61,    62,    62,
+      62,    63,    63,    64,    64,    65,    65,    66,    66,    67,
+      67,    68,    69,    69,    69,    69,    69
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     2,     2,     2,
+       2,     2,     3,     2,     2,     4,     3,     5,     5,     5,
+       1,     2,     2,     4,     4,     4,     4,     4,     4,     4,
+       2,     3,     2,     2,     2,     0,     1,     1,     0,     1,
+       1,     1,     1,     0,     3,     0,     3,     0,     3,     1,
+       3,     1,     0,     3,     4,     4,     5
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       2,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     2,     4,     5,     7,     8,
+       9,    10,    12,     6,    14,    16,    11,    13,    15,    17,
+      18,     0,    53,     0,    55,     0,    30,    19,    20,    21,
+      57,    23,    24,     1,     3,     0,     0,    48,     0,     0,
+      26,     0,     0,    22,    45,     0,    49,    50,    25,    45,
+       0,    45,     0,    27,    54,    28,    56,    29,    58,    51,
+      52,    46,    47,    42,     0,     0,     0,    62,    40,     0,
+       0,     0,    43,     0,    32,    44,    31,     0,     0,     0,
+       0,    41,     0,     0,     0,     0,    36,    37,    38,     0,
+       0,    33,    34,    61,    35,    59,    39,    63,     0,     0,
+       0,     0,    64,    65,    60,    66
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    37,    63,    85,    58,
+      86,    47,    50,    53,   104,   105,    91
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -40
+static const yytype_int8 yypact[] =
+{
+       1,   -13,    -8,    -6,    -5,    -2,    -1,     0,     3,     3,
+       3,     3,     3,     4,    25,     1,   -40,   -40,   -40,   -40,
+     -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,
+     -40,     5,    15,     6,    26,    14,   -40,   -40,   -40,   -40,
+      22,   -40,   -40,   -40,   -40,     3,    17,     2,     3,    21,
+     -40,     3,    23,   -40,   -40,    19,   -40,   -40,   -40,   -40,
+      28,   -40,    29,    33,   -40,    33,   -40,    33,   -40,   -40,
+     -40,   -40,   -40,   -40,    30,    32,    34,    27,   -40,    35,
+      36,    37,   -40,    38,   -40,   -40,   -40,    43,    44,    45,
+     -23,   -40,    46,     3,    47,    48,   -40,   -40,   -40,   -18,
+      49,   -40,   -40,   -40,    50,   -40,   -40,   -40,   -26,    42,
+      47,    51,   -40,   -40,   -40,   -40
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -40,    56,   -40,   -40,   -40,   -40,   -40,   -40,   -40,   -40,
+     -40,   -40,   -40,   -40,   -40,   -40,    -9,   -39,   -40,   -40,
+     -40,   -40,   -40,   -40,   -40,   -25,   -40
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+      38,    39,    40,    41,     1,     2,     3,     4,     5,     6,
+       7,   111,    56,    57,    99,   112,     8,     9,    10,   100,
+      65,    29,    67,   107,   108,    43,    30,    11,    31,    32,
+      12,    13,    33,    34,    35,    46,    54,    36,    42,    59,
+      45,    48,    61,    69,    70,    71,    72,    73,    49,    51,
+      52,    74,    75,    64,    76,    55,    77,    78,    79,    60,
+      80,    62,    66,    68,    81,    82,    83,    90,    87,    84,
+      88,    44,    89,    92,    93,    94,    95,    96,    97,    98,
+     101,   103,   106,   113,   102,   114,   109,     0,     0,   110,
+       0,     0,   115
+};
+
+static const yytype_int8 yycheck[] =
+{
+       9,    10,    11,    12,     3,     4,     5,     6,     7,     8,
+       9,    37,    10,    11,    37,    41,    15,    16,    17,    42,
+      59,    34,    61,    41,    42,     0,    34,    26,    34,    34,
+      29,    30,    34,    34,    34,    20,    45,    34,    34,    48,
+      35,    35,    51,    10,    11,    12,    13,    14,    22,    35,
+      28,    18,    19,    34,    21,    38,    23,    24,    25,    38,
+      27,    38,    34,    34,    31,    32,    33,    40,    38,    36,
+      38,    15,    38,    38,    38,    38,    38,    34,    34,    34,
+      34,    34,    34,    41,    93,   110,    37,    -1,    -1,    39,
+      -1,    -1,    41
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     3,     4,     5,     6,     7,     8,     9,    15,    16,
+      17,    26,    29,    30,    44,    45,    46,    47,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    57,    58,    34,
+      34,    34,    34,    34,    34,    34,    34,    59,    59,    59,
+      59,    59,    34,     0,    44,    35,    20,    64,    35,    22,
+      65,    35,    28,    66,    59,    38,    10,    11,    62,    59,
+      38,    59,    38,    60,    34,    60,    34,    60,    34,    10,
+      11,    12,    13,    14,    18,    19,    21,    23,    24,    25,
+      27,    31,    32,    33,    36,    61,    63,    38,    38,    38,
+      40,    69,    38,    38,    38,    38,    34,    34,    34,    37,
+      42,    34,    59,    34,    67,    68,    34,    41,    42,    37,
+      39,    37,    41,    41,    68,    41
+};
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                (-2)
+#define YYEOF          0
+
+#define YYACCEPT       goto yyacceptlab
+#define YYABORT                goto yyabortlab
+#define YYERROR                goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL         goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                 \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK (1);                                          \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;                                                 \
+    }                                                          \
+while (YYID (0))
+
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (YYID (N))                                                    \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+             (Loc).first_line, (Loc).first_column,     \
+             (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                       \
+do {                                           \
+  if (yydebug)                                 \
+    YYFPRINTF Args;                            \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                   \
+do {                                                                     \
+  if (yydebug)                                                           \
+    {                                                                    \
+      YYFPRINTF (stderr, "%s ", Title);                                          \
+      yy_symbol_print (stderr,                                           \
+                 Type, Value, Location); \
+      YYFPRINTF (stderr, "\n");                                                  \
+    }                                                                    \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+#endif
+{
+  if (!yyvaluep)
+    return;
+  YYUSE (yylocationp);
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+       break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                           \
+do {                                                           \
+  if (yydebug)                                                 \
+    yy_stack_print ((Bottom), (Top));                          \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule)
+    YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
+    int yyrule;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+            yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+                      &(yyvsp[(yyi + 1) - (yynrhs)])
+                      , &(yylsp[(yyi + 1) - (yynrhs)])                );
+      YYFPRINTF (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)         \
+do {                                   \
+  if (yydebug)                         \
+    yy_reduce_print (yyvsp, yylsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef        YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+       switch (*++yyp)
+         {
+         case '\'':
+         case ',':
+           goto do_not_strip_quotes;
+
+         case '\\':
+           if (*++yyp != '\\')
+             goto do_not_strip_quotes;
+           /* Fall through.  */
+         default:
+           if (yyres)
+             yyres[yyn] = *yyp;
+           yyn++;
+           break;
+
+         case '"':
+           if (yyres)
+             yyres[yyn] = '\0';
+           return yyn;
+         }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+        constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+                   + sizeof yyexpecting - 1
+                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                      * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+        YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+         {
+           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+             {
+               yycount = 1;
+               yysize = yysize0;
+               yyformat[sizeof yyunexpected - 1] = '\0';
+               break;
+             }
+           yyarg[yycount++] = yytname[yyx];
+           yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+           yysize_overflow |= (yysize1 < yysize);
+           yysize = yysize1;
+           yyfmt = yystpcpy (yyfmt, yyprefix);
+           yyprefix = yyor;
+         }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+       return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+       {
+         /* Avoid sprintf, as that infringes on the user's name space.
+            Don't have undefined behavior even if the translation
+            produced a string with the wrong number of "%s"s.  */
+         char *yyp = yyresult;
+         int yyi = 0;
+         while ((*yyp = *yyf) != '\0')
+           {
+             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+               {
+                 yyp += yytnamerr (yyp, yyarg[yyi++]);
+                 yyf += 2;
+               }
+             else
+               {
+                 yyp++;
+                 yyf++;
+               }
+           }
+       }
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+\f
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+#endif
+{
+  YYUSE (yyvaluep);
+  YYUSE (yylocationp);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+       break;
+    }
+}
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+/* Location data for the lookahead symbol.  */
+YYLTYPE yylloc;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse.  |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.
+       `yyls': related to locations.
+
+       Refer to the stacks thru separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    /* The location stack.  */
+    YYLTYPE yylsa[YYINITDEPTH];
+    YYLTYPE *yyls;
+    YYLTYPE *yylsp;
+
+    /* The locations where the error started and ended.  */
+    YYLTYPE yyerror_range[2];
+
+    YYSIZE_T yystacksize;
+
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  yytoken = 0;
+  yyss = yyssa;
+  yyvs = yyvsa;
+  yyls = yylsa;
+  yystacksize = YYINITDEPTH;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+  yyssp = yyss;
+  yyvsp = yyvs;
+  yylsp = yyls;
+
+#if YYLTYPE_IS_TRIVIAL
+  /* Initialize the default location before parsing starts.  */
+  yylloc.first_line   = yylloc.last_line   = 1;
+  yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+       /* Give user a chance to reallocate the stack.  Use copies of
+          these so that the &'s don't force the real ones into
+          memory.  */
+       YYSTYPE *yyvs1 = yyvs;
+       yytype_int16 *yyss1 = yyss;
+       YYLTYPE *yyls1 = yyls;
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  This used to be a
+          conditional around just the two extra args, but that might
+          be undefined if yyoverflow is a macro.  */
+       yyoverflow (YY_("memory exhausted"),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+                   &yyls1, yysize * sizeof (*yylsp),
+                   &yystacksize);
+
+       yyls = yyls1;
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+       goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+       yystacksize = YYMAXDEPTH;
+
+      {
+       yytype_int16 *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyexhaustedlab;
+       YYSTACK_RELOCATE (yyss_alloc, yyss);
+       YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+       YYSTACK_RELOCATE (yyls_alloc, yyls);
+#  undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+       YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+  *++yylsp = yylloc;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+  /* Default location.  */
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 17:
+
+/* Line 1455 of yacc.c  */
+#line 234 "../../src/parser.yy"
+    {
+             if (gengetopt_package_given)
+               {
+                 yyerror ("package redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_package_given = 1;
+                 if (gengetopt_define_package ((yyvsp[(2) - (2)].str)))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+    break;
+
+  case 18:
+
+/* Line 1455 of yacc.c  */
+#line 254 "../../src/parser.yy"
+    {
+             if (gengetopt_version_given)
+               {
+                 yyerror ("version redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_version_given = 1;
+                 if (gengetopt_define_version ((yyvsp[(2) - (2)].str)))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+    break;
+
+  case 19:
+
+/* Line 1455 of yacc.c  */
+#line 274 "../../src/parser.yy"
+    {
+             if (gengetopt_purpose_given)
+               {
+                 yyerror ("purpose redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_purpose_given = 1;
+                 if (gengetopt_define_purpose ((yyvsp[(2) - (2)].str)))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+    break;
+
+  case 20:
+
+/* Line 1455 of yacc.c  */
+#line 294 "../../src/parser.yy"
+    {
+             if (gengetopt_description_given)
+               {
+                 yyerror ("description redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_description_given = 1;
+                 if (gengetopt_define_description ((yyvsp[(2) - (2)].str)))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+    break;
+
+  case 21:
+
+/* Line 1455 of yacc.c  */
+#line 314 "../../src/parser.yy"
+    {
+      if (gengetopt_usage_given)
+      {
+         yyerror ("usage redefined");
+         YYERROR;
+      }
+      else
+      {
+         gengetopt_usage_given = 1;
+         if (gengetopt_define_usage ((yyvsp[(2) - (2)].str)))
+          {
+             yyerror ("not enough memory");
+             YYERROR;
+          }
+      }
+  }
+    break;
+
+  case 22:
+
+/* Line 1455 of yacc.c  */
+#line 335 "../../src/parser.yy"
+    {
+                gengetopt_set_section ((yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str));
+              }
+    break;
+
+  case 23:
+
+/* Line 1455 of yacc.c  */
+#line 342 "../../src/parser.yy"
+    {
+               if (current_option) {
+                       std::string current_option_text;
+                       if (current_option->text_after) {
+                               current_option_text = std::string(current_option->text_after) + (yyvsp[(2) - (2)].str);
+                               current_option->text_after = strdup(current_option_text.c_str()); 
+                       } else {
+                               current_option->text_after = strdup((yyvsp[(2) - (2)].str));
+                       }
+               } else {
+                                       gengetopt_set_text((yyvsp[(2) - (2)].str));
+                               }
+            }
+    break;
+
+  case 24:
+
+/* Line 1455 of yacc.c  */
+#line 359 "../../src/parser.yy"
+    {
+  gengetopt_set_args((yyvsp[(2) - (2)].str));
+            }
+    break;
+
+  case 25:
+
+/* Line 1455 of yacc.c  */
+#line 366 "../../src/parser.yy"
+    {
+              if (gengetopt_add_group ((yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].str), (yyvsp[(4) - (4)].boolean)))
+                {
+                       yyerror ("group redefined");
+                       YYERROR;
+                 }
+           }
+    break;
+
+  case 26:
+
+/* Line 1455 of yacc.c  */
+#line 377 "../../src/parser.yy"
+    {
+              if (gengetopt_add_mode ((yyvsp[(2) - (3)].str), (yyvsp[(3) - (3)].str)))
+                {
+                       yyerror ("mode redefined");
+                       YYERROR;
+                 }
+           }
+    break;
+
+  case 27:
+
+/* Line 1455 of yacc.c  */
+#line 389 "../../src/parser.yy"
+    {
+          (yyvsp[(5) - (5)].gengetopt_option)->filename = gengetopt_input_filename;
+          (yyvsp[(5) - (5)].gengetopt_option)->linenum = (yylsp[(1) - (5)]).first_line;
+             (yyvsp[(5) - (5)].gengetopt_option)->long_opt = strdup((yyvsp[(2) - (5)].str));
+             if ((yyvsp[(3) - (5)].chr) != '-')
+               (yyvsp[(5) - (5)].gengetopt_option)->short_opt = (yyvsp[(3) - (5)].chr);
+             (yyvsp[(5) - (5)].gengetopt_option)->desc = strdup((yyvsp[(4) - (5)].str));
+             int o = gengetopt_check_option ((yyvsp[(5) - (5)].gengetopt_option), false);
+             check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+          check_error;
+             o = gengetopt_add_option ((yyvsp[(5) - (5)].gengetopt_option));
+             check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+             check_error;
+             current_option = (yyvsp[(5) - (5)].gengetopt_option);
+           }
+    break;
+
+  case 28:
+
+/* Line 1455 of yacc.c  */
+#line 409 "../../src/parser.yy"
+    {
+          (yyvsp[(5) - (5)].gengetopt_option)->filename = gengetopt_input_filename;
+          (yyvsp[(5) - (5)].gengetopt_option)->linenum = (yylsp[(1) - (5)]).first_line;
+             (yyvsp[(5) - (5)].gengetopt_option)->long_opt = strdup((yyvsp[(2) - (5)].str));
+          if ((yyvsp[(3) - (5)].chr) != '-')
+            (yyvsp[(5) - (5)].gengetopt_option)->short_opt = (yyvsp[(3) - (5)].chr);
+          (yyvsp[(5) - (5)].gengetopt_option)->desc = strdup((yyvsp[(4) - (5)].str));
+          int o = gengetopt_check_option ((yyvsp[(5) - (5)].gengetopt_option), true);
+          check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+          check_error;
+          o = gengetopt_add_option ((yyvsp[(5) - (5)].gengetopt_option));
+          check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+          check_error;
+           }
+    break;
+
+  case 29:
+
+/* Line 1455 of yacc.c  */
+#line 428 "../../src/parser.yy"
+    {
+          (yyvsp[(5) - (5)].gengetopt_option)->filename = gengetopt_input_filename;
+          (yyvsp[(5) - (5)].gengetopt_option)->linenum = (yylsp[(1) - (5)]).first_line;
+             (yyvsp[(5) - (5)].gengetopt_option)->long_opt = strdup((yyvsp[(2) - (5)].str));
+          if ((yyvsp[(3) - (5)].chr) != '-')
+            (yyvsp[(5) - (5)].gengetopt_option)->short_opt = (yyvsp[(3) - (5)].chr);
+          (yyvsp[(5) - (5)].gengetopt_option)->desc = strdup((yyvsp[(4) - (5)].str));
+          int o = gengetopt_check_option ((yyvsp[(5) - (5)].gengetopt_option), false, true);
+          check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+          check_error;
+          o = gengetopt_add_option ((yyvsp[(5) - (5)].gengetopt_option));
+          check_result(o, (yyvsp[(5) - (5)].gengetopt_option));
+          check_error;
+           }
+    break;
+
+  case 31:
+
+/* Line 1455 of yacc.c  */
+#line 452 "../../src/parser.yy"
+    {
+                               (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+                               (yyval.gengetopt_option)->required = (yyvsp[(2) - (2)].boolean);
+                               (yyval.gengetopt_option)->required_set = true;
+                         }
+    break;
+
+  case 32:
+
+/* Line 1455 of yacc.c  */
+#line 458 "../../src/parser.yy"
+    {
+                               (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+                               (yyval.gengetopt_option)->type = (yyvsp[(2) - (2)].argtype);
+                         }
+    break;
+
+  case 33:
+
+/* Line 1455 of yacc.c  */
+#line 463 "../../src/parser.yy"
+    {
+                               (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+                               (yyval.gengetopt_option)->type_str = strdup((yyvsp[(4) - (4)].str));
+                         }
+    break;
+
+  case 34:
+
+/* Line 1455 of yacc.c  */
+#line 468 "../../src/parser.yy"
+    {
+                               (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+                               (yyval.gengetopt_option)->details = strdup((yyvsp[(4) - (4)].str));
+                         }
+    break;
+
+  case 35:
+
+/* Line 1455 of yacc.c  */
+#line 473 "../../src/parser.yy"
+    {
+                               (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+                               (yyval.gengetopt_option)->acceptedvalues = (yyvsp[(4) - (4)].ValueList);
+                         }
+    break;
+
+  case 36:
+
+/* Line 1455 of yacc.c  */
+#line 478 "../../src/parser.yy"
+    {
+                               (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+                               (yyval.gengetopt_option)->default_string = strdup((yyvsp[(4) - (4)].str));
+                         }
+    break;
+
+  case 37:
+
+/* Line 1455 of yacc.c  */
+#line 483 "../../src/parser.yy"
+    {
+                (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+                (yyval.gengetopt_option)->group_value = strdup((yyvsp[(4) - (4)].str));
+              }
+    break;
+
+  case 38:
+
+/* Line 1455 of yacc.c  */
+#line 488 "../../src/parser.yy"
+    {
+                (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+                (yyval.gengetopt_option)->mode_value = strdup((yyvsp[(4) - (4)].str));
+              }
+    break;
+
+  case 39:
+
+/* Line 1455 of yacc.c  */
+#line 493 "../../src/parser.yy"
+    {
+                (yyval.gengetopt_option) = (yyvsp[(1) - (4)].gengetopt_option);
+                (yyval.gengetopt_option)->dependon = strdup((yyvsp[(4) - (4)].str));
+              }
+    break;
+
+  case 40:
+
+/* Line 1455 of yacc.c  */
+#line 498 "../../src/parser.yy"
+    {
+                               (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+                               (yyval.gengetopt_option)->arg_is_optional = true;
+                         }
+    break;
+
+  case 41:
+
+/* Line 1455 of yacc.c  */
+#line 503 "../../src/parser.yy"
+    {
+                               (yyval.gengetopt_option) = (yyvsp[(1) - (3)].gengetopt_option);
+                               (yyval.gengetopt_option)->multiple = true;
+                (yyval.gengetopt_option)->multiple_min = (yyvsp[(3) - (3)].multiple_size)->min;
+                (yyval.gengetopt_option)->multiple_max = (yyvsp[(3) - (3)].multiple_size)->max;
+                delete (yyvsp[(3) - (3)].multiple_size);
+                         }
+    break;
+
+  case 42:
+
+/* Line 1455 of yacc.c  */
+#line 511 "../../src/parser.yy"
+    {
+          (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+          (yyval.gengetopt_option)->type = ARG_FLAG;
+        }
+    break;
+
+  case 43:
+
+/* Line 1455 of yacc.c  */
+#line 516 "../../src/parser.yy"
+    {
+          (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+          (yyval.gengetopt_option)->hidden = true;
+        }
+    break;
+
+  case 44:
+
+/* Line 1455 of yacc.c  */
+#line 521 "../../src/parser.yy"
+    {
+          (yyval.gengetopt_option) = (yyvsp[(1) - (2)].gengetopt_option);
+          (yyval.gengetopt_option)->flagstat = (yyvsp[(2) - (2)].boolean);
+        }
+    break;
+
+  case 45:
+
+/* Line 1455 of yacc.c  */
+#line 525 "../../src/parser.yy"
+    { (yyval.gengetopt_option) = new gengetopt_option; }
+    break;
+
+  case 46:
+
+/* Line 1455 of yacc.c  */
+#line 529 "../../src/parser.yy"
+    { (yyval.boolean) = 1; }
+    break;
+
+  case 47:
+
+/* Line 1455 of yacc.c  */
+#line 530 "../../src/parser.yy"
+    { (yyval.boolean) = 0; }
+    break;
+
+  case 48:
+
+/* Line 1455 of yacc.c  */
+#line 534 "../../src/parser.yy"
+    { (yyval.boolean) = 0; }
+    break;
+
+  case 49:
+
+/* Line 1455 of yacc.c  */
+#line 535 "../../src/parser.yy"
+    { (yyval.boolean) = 1; }
+    break;
+
+  case 50:
+
+/* Line 1455 of yacc.c  */
+#line 536 "../../src/parser.yy"
+    { (yyval.boolean) = 0; }
+    break;
+
+  case 51:
+
+/* Line 1455 of yacc.c  */
+#line 540 "../../src/parser.yy"
+    { (yyval.boolean) = 1; }
+    break;
+
+  case 52:
+
+/* Line 1455 of yacc.c  */
+#line 541 "../../src/parser.yy"
+    { (yyval.boolean) = 0; }
+    break;
+
+  case 53:
+
+/* Line 1455 of yacc.c  */
+#line 545 "../../src/parser.yy"
+    { (yyval.str) = 0; }
+    break;
+
+  case 54:
+
+/* Line 1455 of yacc.c  */
+#line 546 "../../src/parser.yy"
+    { (yyval.str) = (yyvsp[(3) - (3)].str); }
+    break;
+
+  case 55:
+
+/* Line 1455 of yacc.c  */
+#line 550 "../../src/parser.yy"
+    { (yyval.str) = 0; }
+    break;
+
+  case 56:
+
+/* Line 1455 of yacc.c  */
+#line 551 "../../src/parser.yy"
+    { (yyval.str) = (yyvsp[(3) - (3)].str); }
+    break;
+
+  case 57:
+
+/* Line 1455 of yacc.c  */
+#line 555 "../../src/parser.yy"
+    { (yyval.str) = 0; }
+    break;
+
+  case 58:
+
+/* Line 1455 of yacc.c  */
+#line 556 "../../src/parser.yy"
+    { (yyval.str) = (yyvsp[(3) - (3)].str); }
+    break;
+
+  case 59:
+
+/* Line 1455 of yacc.c  */
+#line 560 "../../src/parser.yy"
+    { (yyval.ValueList) = new AcceptedValues; (yyval.ValueList)->insert((yyvsp[(1) - (1)].str)); }
+    break;
+
+  case 60:
+
+/* Line 1455 of yacc.c  */
+#line 561 "../../src/parser.yy"
+    { (yyvsp[(1) - (3)].ValueList)->insert((yyvsp[(3) - (3)].str)); (yyval.ValueList) = (yyvsp[(1) - (3)].ValueList); }
+    break;
+
+  case 61:
+
+/* Line 1455 of yacc.c  */
+#line 565 "../../src/parser.yy"
+    { (yyval.str) = (yyvsp[(1) - (1)].str); }
+    break;
+
+  case 62:
+
+/* Line 1455 of yacc.c  */
+#line 569 "../../src/parser.yy"
+    { (yyval.multiple_size) = new multiple_size; }
+    break;
+
+  case 63:
+
+/* Line 1455 of yacc.c  */
+#line 570 "../../src/parser.yy"
+    { (yyval.multiple_size) = new multiple_size((yyvsp[(2) - (3)].str), (yyvsp[(2) - (3)].str)); }
+    break;
+
+  case 64:
+
+/* Line 1455 of yacc.c  */
+#line 571 "../../src/parser.yy"
+    { (yyval.multiple_size) = new multiple_size((yyvsp[(2) - (4)].str), "0"); free((yyvsp[(2) - (4)].str)); }
+    break;
+
+  case 65:
+
+/* Line 1455 of yacc.c  */
+#line 572 "../../src/parser.yy"
+    { (yyval.multiple_size) = new multiple_size("0", (yyvsp[(3) - (4)].str)); free((yyvsp[(3) - (4)].str)); }
+    break;
+
+  case 66:
+
+/* Line 1455 of yacc.c  */
+#line 573 "../../src/parser.yy"
+    { (yyval.multiple_size) = new multiple_size((yyvsp[(2) - (5)].str), (yyvsp[(4) - (5)].str)); free((yyvsp[(2) - (5)].str)); free((yyvsp[(4) - (5)].str)); }
+    break;
+
+
+
+/* Line 1455 of yacc.c  */
+#line 2212 "../../src/parser.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+  *++yylsp = yyloc;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (YY_("syntax error"));
+#else
+      {
+       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+         {
+           YYSIZE_T yyalloc = 2 * yysize;
+           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+             yyalloc = YYSTACK_ALLOC_MAXIMUM;
+           if (yymsg != yymsgbuf)
+             YYSTACK_FREE (yymsg);
+           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+           if (yymsg)
+             yymsg_alloc = yyalloc;
+           else
+             {
+               yymsg = yymsgbuf;
+               yymsg_alloc = sizeof yymsgbuf;
+             }
+         }
+
+       if (0 < yysize && yysize <= yymsg_alloc)
+         {
+           (void) yysyntax_error (yymsg, yystate, yychar);
+           yyerror (yymsg);
+         }
+       else
+         {
+           yyerror (YY_("syntax error"));
+           if (yysize != 0)
+             goto yyexhaustedlab;
+         }
+      }
+#endif
+    }
+
+  yyerror_range[0] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+        error, discard it.  */
+
+      if (yychar <= YYEOF)
+       {
+         /* Return failure if at end of input.  */
+         if (yychar == YYEOF)
+           YYABORT;
+       }
+      else
+       {
+         yydestruct ("Error: discarding",
+                     yytoken, &yylval, &yylloc);
+         yychar = YYEMPTY;
+       }
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  yyerror_range[0] = yylsp[1-yylen];
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+       {
+         yyn += YYTERROR;
+         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+           {
+             yyn = yytable[yyn];
+             if (0 < yyn)
+               break;
+           }
+       }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+       YYABORT;
+
+      yyerror_range[0] = *yylsp;
+      yydestruct ("Error: popping",
+                 yystos[yystate], yyvsp, yylsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  *++yyvsp = yylval;
+
+  yyerror_range[1] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the lookahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval, &yylloc);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                 yystos[*yyssp], yyvsp, yylsp);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
+/* Line 1675 of yacc.c  */
+#line 576 "../../src/parser.yy"
+
+
diff --git a/cmake/gengetopt/parser.h b/cmake/gengetopt/parser.h
new file mode 100644 (file)
index 0000000..40cd85f
--- /dev/null
@@ -0,0 +1,160 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+   
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+   
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     TOK_PACKAGE = 258,
+     TOK_VERSION = 259,
+     TOK_OPTION = 260,
+     TOK_DEFGROUP = 261,
+     TOK_GROUPOPTION = 262,
+     TOK_DEFMODE = 263,
+     TOK_MODEOPTION = 264,
+     TOK_YES = 265,
+     TOK_NO = 266,
+     TOK_ON = 267,
+     TOK_OFF = 268,
+     TOK_FLAG = 269,
+     TOK_PURPOSE = 270,
+     TOK_DESCRIPTION = 271,
+     TOK_USAGE = 272,
+     TOK_DEFAULT = 273,
+     TOK_GROUP = 274,
+     TOK_GROUPDESC = 275,
+     TOK_MODE = 276,
+     TOK_MODEDESC = 277,
+     TOK_MULTIPLE = 278,
+     TOK_ARGOPTIONAL = 279,
+     TOK_TYPESTR = 280,
+     TOK_SECTION = 281,
+     TOK_DETAILS = 282,
+     TOK_SECTIONDESC = 283,
+     TOK_TEXT = 284,
+     TOK_ARGS = 285,
+     TOK_VALUES = 286,
+     TOK_HIDDEN = 287,
+     TOK_DEPENDON = 288,
+     TOK_STRING = 289,
+     TOK_CHAR = 290,
+     TOK_ARGTYPE = 291,
+     TOK_SIZE = 292
+   };
+#endif
+/* Tokens.  */
+#define TOK_PACKAGE 258
+#define TOK_VERSION 259
+#define TOK_OPTION 260
+#define TOK_DEFGROUP 261
+#define TOK_GROUPOPTION 262
+#define TOK_DEFMODE 263
+#define TOK_MODEOPTION 264
+#define TOK_YES 265
+#define TOK_NO 266
+#define TOK_ON 267
+#define TOK_OFF 268
+#define TOK_FLAG 269
+#define TOK_PURPOSE 270
+#define TOK_DESCRIPTION 271
+#define TOK_USAGE 272
+#define TOK_DEFAULT 273
+#define TOK_GROUP 274
+#define TOK_GROUPDESC 275
+#define TOK_MODE 276
+#define TOK_MODEDESC 277
+#define TOK_MULTIPLE 278
+#define TOK_ARGOPTIONAL 279
+#define TOK_TYPESTR 280
+#define TOK_SECTION 281
+#define TOK_DETAILS 282
+#define TOK_SECTIONDESC 283
+#define TOK_TEXT 284
+#define TOK_ARGS 285
+#define TOK_VALUES 286
+#define TOK_HIDDEN 287
+#define TOK_DEPENDON 288
+#define TOK_STRING 289
+#define TOK_CHAR 290
+#define TOK_ARGTYPE 291
+#define TOK_SIZE 292
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 1676 of yacc.c  */
+#line 148 "../../src/parser.yy"
+
+    char   *str;
+    char    chr;
+    int            argtype;
+    int            boolean;
+    class AcceptedValues *ValueList;
+    struct gengetopt_option *gengetopt_option;
+    struct multiple_size *multiple_size;
+
+
+
+/* Line 1676 of yacc.c  */
+#line 138 "../../src/parser.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+extern YYSTYPE yylval;
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYLTYPE yylloc;
+
diff --git a/cmake/gengetopt/parser.yy b/cmake/gengetopt/parser.yy
new file mode 100644 (file)
index 0000000..d0a60e0
--- /dev/null
@@ -0,0 +1,576 @@
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+%{
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <string>
+
+#include "my_sstream.h"
+
+#include "acceptedvalues.h"
+
+#include "argsdef.h"
+
+#include "gengetopt.h"
+#include "errorcodes.h"
+#include "ggos.h"
+#include "yyerror.h"
+
+extern int gengetopt_count_line;
+extern char * gengetopt_input_filename;
+
+static int gengetopt_package_given = 0;
+static int gengetopt_version_given = 0;
+static int gengetopt_purpose_given = 0;
+static int gengetopt_usage_given = 0;
+static int gengetopt_description_given = 0;
+
+/// the last option parsed
+static gengetopt_option *current_option = 0;
+
+extern int yylex (void) ;
+
+//#define YYERROR_VERBOSE 1
+
+void check_result(int o, gengetopt_option *opt)
+{
+  if (o)
+    {
+        ostringstream err;
+
+    switch (o)
+    {
+    case NOT_ENOUGH_MEMORY:
+        yyerror (opt, "not enough memory");
+       break;
+    case REQ_LONG_OPTION:
+        err << "long option redefined \'" << opt->long_opt << "\'";
+        yyerror (opt, err.str().c_str());
+               break;
+    case REQ_SHORT_OPTION:
+        err << "short option redefined \'" << opt->short_opt << "\'";
+        yyerror (opt, err.str().c_str());
+        break;
+    case FOUND_BUG:
+        yyerror (opt, "bug found!!");
+        break;
+    case GROUP_UNDEFINED:
+        yyerror (opt, "group undefined");
+        break;
+    case MODE_UNDEFINED:
+        yyerror (opt, "mode undefined");
+        break;
+    case INVALID_DEFAULT_VALUE:
+        yyerror (opt, "invalid default value");
+        break;
+    case NOT_REQUESTED_TYPE:
+        yyerror (opt, "type specification not requested");
+        break;
+    case NOT_VALID_SPECIFICATION:
+      yyerror (opt, "invalid specification for this kind of option");
+      break;
+    case SPECIFY_FLAG_STAT:
+      yyerror (opt, "you must specify the default flag status");
+      break;
+    case NOT_GROUP_OPTION:
+      yyerror (opt, "group specification for a non group option");
+      break;
+    case NOT_MODE_OPTION:
+      yyerror (opt, "mode specification for an option not belonging to a mode");
+      break;
+    case SPECIFY_GROUP:
+      yyerror (opt, "missing group specification");
+      break;
+    case SPECIFY_MODE:
+      yyerror (opt, "missing mode specification");
+      break;
+    case INVALID_NUMERIC_VALUE:
+        yyerror (opt, "invalid numeric value");
+        break;
+    case INVALID_ENUM_TYPE_USE:
+       yyerror (opt, "enum type can only be specified for options with values");
+        break;
+    case HELP_REDEFINED:
+       yyerror (opt, "if you want to redefine --help, please use option --no-help");
+        break;
+    case VERSION_REDEFINED:
+       yyerror (opt, "if you want to redefine --version, please use option --no-version");
+        break;
+    }
+  }
+}
+
+/* the number of allowed occurrences of a multiple option */
+struct multiple_size
+{
+    /* these strings are allocated dynamically and NOT
+      automatically freed upon destruction */
+    char *min;
+    char *max;
+
+    /* if no limit is specified then initialized to 0.
+       if the same size is specified for min and max, it means that an exact
+       number of occurrences is required*/
+    multiple_size(const char *m = "0", const char *M = "0") :
+        min(strdup(m)), max(strdup(M))
+    {}
+};
+
+#define check_error if (o) YYERROR;
+
+%}
+
+%union {
+    char   *str;
+    char    chr;
+    int            argtype;
+    int            boolean;
+    class AcceptedValues *ValueList;
+    struct gengetopt_option *gengetopt_option;
+    struct multiple_size *multiple_size;
+}
+
+%token             TOK_PACKAGE         "package"
+%token              TOK_VERSION                "version"
+%token              TOK_OPTION         "option"
+%token              TOK_DEFGROUP       "defgroup"
+%token              TOK_GROUPOPTION    "groupoption"
+%token              TOK_DEFMODE                "defmode"
+%token              TOK_MODEOPTION     "modeoption"
+%token              TOK_YES            "yes"
+%token              TOK_NO             "no"
+%token              TOK_ON             "on"
+%token              TOK_OFF            "off"
+%token              TOK_FLAG           "flag"
+%token              TOK_PURPOSE                "purpose"
+%token              TOK_DESCRIPTION    "description"
+%token              TOK_USAGE          "usage"
+%token              TOK_DEFAULT                "default"
+%token              TOK_GROUP          "group"
+%token              TOK_GROUPDESC      "groupdesc"
+%token              TOK_MODE           "mode"
+%token              TOK_MODEDESC       "modedesc"
+%token              TOK_MULTIPLE       "multiple"
+%token              TOK_ARGOPTIONAL    "argoptional"
+%token              TOK_TYPESTR                "typestr"
+%token              TOK_SECTION                "section"
+%token              TOK_DETAILS                "details"
+%token              TOK_SECTIONDESC    "sectiondesc"
+%token              TOK_TEXT           "text"
+%token              TOK_ARGS           "args"
+%token              TOK_VALUES          "values"
+%token              TOK_HIDDEN      "hidden"
+%token              TOK_DEPENDON      "dependon"
+%token <str>        TOK_STRING
+%token <chr>        TOK_CHAR
+%token <argtype>    TOK_ARGTYPE
+%token <str>        TOK_SIZE
+
+%type  <boolean>    req_onoff
+%type  <boolean>    opt_yesno optional_yesno
+%type  <str>        quoted_string
+%type  <str>        opt_groupdesc
+%type  <str>        opt_sectiondesc
+%type  <str>        opt_modedesc
+%type  <ValueList>  listofvalues
+%type  <str>        acceptedvalue
+%type  <gengetopt_option> option_parts
+%type  <multiple_size> multiple_size
+
+
+%% /* ====================================================================== */
+
+
+input
+       : /* empty */
+       | statement input
+       ;
+
+
+statement
+       : package
+       | version
+       | args
+       | purpose
+       | description
+       | usage
+       | sectiondef
+       | option
+       | text
+       | groupoption
+       | groupdef
+       | modeoption
+       | modedef
+       ;
+
+
+package
+       : TOK_PACKAGE TOK_STRING
+           {
+             if (gengetopt_package_given)
+               {
+                 yyerror ("package redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_package_given = 1;
+                 if (gengetopt_define_package ($2))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+       ;
+
+version
+       : TOK_VERSION TOK_STRING
+           {
+             if (gengetopt_version_given)
+               {
+                 yyerror ("version redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_version_given = 1;
+                 if (gengetopt_define_version ($2))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+       ;
+
+purpose
+       : TOK_PURPOSE quoted_string
+           {
+             if (gengetopt_purpose_given)
+               {
+                 yyerror ("purpose redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_purpose_given = 1;
+                 if (gengetopt_define_purpose ($2))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+       ;
+
+description
+       : TOK_DESCRIPTION quoted_string
+           {
+             if (gengetopt_description_given)
+               {
+                 yyerror ("description redefined");
+                 YYERROR;
+               }
+             else
+               {
+                 gengetopt_description_given = 1;
+                 if (gengetopt_define_description ($2))
+                   {
+                     yyerror ("not enough memory");
+                     YYERROR;
+                   }
+               }
+           }
+       ;
+
+usage
+  : TOK_USAGE quoted_string
+  {
+      if (gengetopt_usage_given)
+      {
+         yyerror ("usage redefined");
+         YYERROR;
+      }
+      else
+      {
+         gengetopt_usage_given = 1;
+         if (gengetopt_define_usage ($2))
+          {
+             yyerror ("not enough memory");
+             YYERROR;
+          }
+      }
+  }
+        ;
+
+
+sectiondef
+          : TOK_SECTION quoted_string opt_sectiondesc
+              {
+                gengetopt_set_section ($2, $3);
+              }
+          ;
+
+text
+  : TOK_TEXT quoted_string
+            {
+               if (current_option) {
+                       std::string current_option_text;
+                       if (current_option->text_after) {
+                               current_option_text = std::string(current_option->text_after) + $2;
+                               current_option->text_after = strdup(current_option_text.c_str()); 
+                       } else {
+                               current_option->text_after = strdup($2);
+                       }
+               } else {
+                                       gengetopt_set_text($2);
+                               }
+            }
+        ;
+
+args
+  : TOK_ARGS TOK_STRING
+            {
+  gengetopt_set_args($2);
+            }
+        ;
+
+groupdef
+       : TOK_DEFGROUP TOK_STRING opt_groupdesc optional_yesno
+           {
+              if (gengetopt_add_group ($2, $3, $4))
+                {
+                       yyerror ("group redefined");
+                       YYERROR;
+                 }
+           }
+       ;
+
+modedef
+       : TOK_DEFMODE TOK_STRING opt_modedesc
+           {
+              if (gengetopt_add_mode ($2, $3))
+                {
+                       yyerror ("mode redefined");
+                       YYERROR;
+                 }
+           }
+       ;
+
+option
+       : TOK_OPTION TOK_STRING TOK_CHAR quoted_string
+               option_parts
+           {
+          $5->filename = gengetopt_input_filename;
+          $5->linenum = @1.first_line;
+             $5->long_opt = strdup($2);
+             if ($3 != '-')
+               $5->short_opt = $3;
+             $5->desc = strdup($4);
+             int o = gengetopt_check_option ($5, false);
+             check_result(o, $5);
+          check_error;
+             o = gengetopt_add_option ($5);
+             check_result(o, $5);
+             check_error;
+             current_option = $5;
+           }
+       ;
+
+groupoption
+       : TOK_GROUPOPTION TOK_STRING TOK_CHAR quoted_string
+                option_parts
+           {
+          $5->filename = gengetopt_input_filename;
+          $5->linenum = @1.first_line;
+             $5->long_opt = strdup($2);
+          if ($3 != '-')
+            $5->short_opt = $3;
+          $5->desc = strdup($4);
+          int o = gengetopt_check_option ($5, true);
+          check_result(o, $5);
+          check_error;
+          o = gengetopt_add_option ($5);
+          check_result(o, $5);
+          check_error;
+           }
+        ;
+
+modeoption
+       : TOK_MODEOPTION TOK_STRING TOK_CHAR quoted_string
+                option_parts
+           {
+          $5->filename = gengetopt_input_filename;
+          $5->linenum = @1.first_line;
+             $5->long_opt = strdup($2);
+          if ($3 != '-')
+            $5->short_opt = $3;
+          $5->desc = strdup($4);
+          int o = gengetopt_check_option ($5, false, true);
+          check_result(o, $5);
+          check_error;
+          o = gengetopt_add_option ($5);
+          check_result(o, $5);
+          check_error;
+           }
+        ;
+
+
+/* ---------------------------------------------------------------------- */
+
+quoted_string
+       : TOK_STRING
+       ;
+
+option_parts: option_parts opt_yesno
+                         {
+                               $$ = $1;
+                               $$->required = $2;
+                               $$->required_set = true;
+                         }
+                       | option_parts TOK_ARGTYPE
+                         {
+                               $$ = $1;
+                               $$->type = $2;
+                         }
+                       | option_parts TOK_TYPESTR '=' TOK_STRING
+                         {
+                               $$ = $1;
+                               $$->type_str = strdup($4);
+                         }
+                       | option_parts TOK_DETAILS '=' quoted_string
+                         {
+                               $$ = $1;
+                               $$->details = strdup($4);
+                         }
+                       | option_parts TOK_VALUES '=' listofvalues
+                         {
+                               $$ = $1;
+                               $$->acceptedvalues = $4;
+                         }
+                       | option_parts TOK_DEFAULT '=' TOK_STRING
+                         {
+                               $$ = $1;
+                               $$->default_string = strdup($4);
+                         }
+            | option_parts TOK_GROUP '=' TOK_STRING
+              {
+                $$ = $1;
+                $$->group_value = strdup($4);
+              }
+            | option_parts TOK_MODE '=' TOK_STRING
+              {
+                $$ = $1;
+                $$->mode_value = strdup($4);
+              }
+            | option_parts TOK_DEPENDON '=' TOK_STRING
+              {
+                $$ = $1;
+                $$->dependon = strdup($4);
+              }
+                       | option_parts TOK_ARGOPTIONAL
+                         {
+                               $$ = $1;
+                               $$->arg_is_optional = true;
+                         }
+                       | option_parts TOK_MULTIPLE multiple_size
+                         {
+                               $$ = $1;
+                               $$->multiple = true;
+                $$->multiple_min = $3->min;
+                $$->multiple_max = $3->max;
+                delete $3;
+                         }
+      | option_parts TOK_FLAG
+        {
+          $$ = $1;
+          $$->type = ARG_FLAG;
+        }
+      | option_parts TOK_HIDDEN
+        {
+          $$ = $1;
+          $$->hidden = true;
+        }
+      | option_parts req_onoff
+        {
+          $$ = $1;
+          $$->flagstat = $2;
+        }
+      | { $$ = new gengetopt_option; }
+      ;
+
+req_onoff
+       : TOK_ON        { $$ = 1; }
+       | TOK_OFF       { $$ = 0; }
+       ;
+
+optional_yesno
+       : /* empty */   { $$ = 0; }
+       | TOK_YES       { $$ = 1; }
+       | TOK_NO        { $$ = 0; }
+       ;
+
+opt_yesno
+    : TOK_YES   { $$ = 1; }
+    | TOK_NO    { $$ = 0; }
+    ;
+
+opt_groupdesc
+       : /* empty */                   { $$ = 0; }
+        | TOK_GROUPDESC '=' TOK_STRING { $$ = $3; }
+       ;
+
+opt_modedesc
+       : /* empty */                   { $$ = 0; }
+        | TOK_MODEDESC '=' TOK_STRING  { $$ = $3; }
+       ;
+
+opt_sectiondesc
+        : /* empty */                  { $$ = 0; }
+        | TOK_SECTIONDESC '=' TOK_STRING       { $$ = $3; }
+        ;
+
+listofvalues
+        : acceptedvalue { $$ = new AcceptedValues; $$->insert($1); }
+        | listofvalues ',' acceptedvalue { $1->insert($3); $$ = $1; }
+        ;
+
+acceptedvalue
+        : TOK_STRING { $$ = $1; }
+        ;
+
+multiple_size
+    : { $$ = new multiple_size; }
+    | '(' TOK_SIZE ')' { $$ = new multiple_size($2, $2); }
+    | '(' TOK_SIZE '-' ')' { $$ = new multiple_size($2, "0"); free($2); }
+    | '(' '-' TOK_SIZE  ')' { $$ = new multiple_size("0", $3); free($3); }
+    | '(' TOK_SIZE '-' TOK_SIZE  ')' { $$ = new multiple_size($2, $4); free($2); free($4); }
+    ;
+
+%%
diff --git a/cmake/gengetopt/scanner.cc b/cmake/gengetopt/scanner.cc
new file mode 100644 (file)
index 0000000..06ee13e
--- /dev/null
@@ -0,0 +1,2364 @@
+#line 2 "../../src/scanner.cc"
+
+#line 4 "../../src/scanner.cc"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else  /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                int yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               *yy_cp = (yy_hold_char); \
+               YY_RESTORE_YY_MORE_OFFSET \
+               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+               } \
+       while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+       {
+       FILE *yy_input_file;
+
+       char *yy_ch_buf;                /* input buffer */
+       char *yy_buf_pos;               /* current position in input buffer */
+
+       /* Size of input buffer in bytes, not including room for EOB
+        * characters.
+        */
+       yy_size_t yy_buf_size;
+
+       /* Number of characters read into yy_ch_buf, not including EOB
+        * characters.
+        */
+       int yy_n_chars;
+
+       /* Whether we "own" the buffer - i.e., we know we created it,
+        * and can realloc() it to grow it, and should free() it to
+        * delete it.
+        */
+       int yy_is_our_buffer;
+
+       /* Whether this is an "interactive" input source; if so, and
+        * if we're using stdio for input, then we want to use getc()
+        * instead of fread(), to make sure we stop fetching input after
+        * each newline.
+        */
+       int yy_is_interactive;
+
+       /* Whether we're considered to be at the beginning of a line.
+        * If so, '^' rules will be active on the next match, otherwise
+        * not.
+        */
+       int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+       /* Whether to try to fill the input buffer when we reach the
+        * end of it.
+        */
+       int yy_fill_buffer;
+
+       int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+       /* When an EOF's been seen but there's still some text to process
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+        * shouldn't try reading from the input source any more.  We might
+        * still have a bunch of tokens to match, though, because of
+        * possible backing-up.
+        *
+        * When we actually see the EOF, we change the status to "new"
+        * (via yyrestart()), so that the user can continue scanning by
+        * just pointing yyin at a new input file.
+        */
+#define YY_BUFFER_EOF_PENDING 2
+
+       };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;                /* whether we need to initialize */
+static int yy_start = 0;       /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file  );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
+void yy_delete_buffer (YY_BUFFER_STATE b  );
+void yy_flush_buffer (YY_BUFFER_STATE b  );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+
+void *yyalloc (yy_size_t  );
+void *yyrealloc (void *,yy_size_t  );
+void yyfree (void *  );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       }
+
+#define yy_set_bol(at_bol) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+       (yytext_ptr) = yy_bp; \
+       yyleng = (size_t) (yy_cp - yy_bp); \
+       (yy_hold_char) = *yy_cp; \
+       *yy_cp = '\0'; \
+       (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 62
+#define YY_END_OF_BUFFER 63
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+       {
+       flex_int32_t yy_verify;
+       flex_int32_t yy_nxt;
+       };
+static yyconst flex_int16_t yy_accept[246] =
+    {   0,
+        0,    0,    0,    0,    0,    0,   63,   61,   57,   59,
+       60,   56,   48,   58,   43,   42,   47,   41,   47,   47,
+       47,   47,   47,   47,   47,   47,   47,   47,   47,   47,
+       47,   47,   47,   47,   47,   47,   62,   46,   44,   45,
+       55,   51,   55,   54,   55,   57,   59,   56,   58,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+       15,    0,   18,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,   45,   51,   52,    0,
+       53,    0,   50,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    2,    0,    0,    0,   19,    0,
+
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,   14,   49,    0,   40,    0,    0,    0,    0,    0,
+        0,    0,    9,   17,    0,    0,    0,    4,   28,    0,
+        0,    0,    0,    0,    0,    0,    0,   39,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        5,   25,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    3,    0,    0,   22,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    6,    0,    0,   36,
+        0,    0,    0,    0,    0,   16,    0,    0,    0,    0,
+        1,    0,   35,    0,    0,   23,    0,   30,    0,    0,
+
+       38,    0,    0,    0,    0,    0,    0,    0,    0,   10,
+       20,    0,   34,   24,   11,    0,   27,   37,    0,    0,
+        0,    0,    8,   29,    0,   31,    0,    0,    0,   26,
+        0,    0,    0,    0,    0,    0,    0,    7,   13,    0,
+       32,   21,   12,   33,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    5,    1,    6,    7,    1,    1,    1,    1,    8,
+        9,    1,    1,   10,   11,    1,    1,   12,   12,   12,
+       12,   12,   12,   12,   12,   12,   12,    1,    1,    1,
+       13,    1,   14,    1,   15,   15,   15,   15,   15,   15,
+       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
+        1,   16,    1,    1,    1,    1,   17,   18,   19,   20,
+
+       21,   22,   23,   24,   25,   15,   26,   27,   28,   29,
+       30,   31,   32,   33,   34,   35,   36,   37,   15,   38,
+       39,   15,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[40] =
+    {   0,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[250] =
+    {   0,
+        0,    0,   37,   47,   39,   57,  271,  272,  268,    0,
+      272,  264,  272,    0,  272,  272,  272,  272,  235,   32,
+      238,  239,  232,  239,  234,  232,   34,  231,   43,   30,
+      239,   47,   36,  225,   59,  237,  272,  272,  272,  245,
+      272,  253,  272,  272,   78,  253,    0,  249,    0,  230,
+       55,  216,  215,   61,  220,  229,  213,  218,  226,  218,
+      272,  222,  272,  208,  223,  208,  208,  220,  208,  204,
+      198,  204,  217,  206,  199,  197,  218,  226,  272,   64,
+      272,  199,  272,   58,   70,  206,  207,  208,  206,  195,
+      199,  204,  184,  199,  272,  195,  196,  181,  272,  190,
+
+      188,  182,  176,  176,  177,  184,  173,  186,  183,  169,
+      170,  272,  272,  172,  272,  166,  168,  170,  170,  165,
+      172,  169,  272,  272,  160,  163,  172,   75,   76,  167,
+      161,  173,  159,  163,  162,  151,  156,  272,  150,  162,
+      161,  156,  145,  152,  148,  157,  156,  150,  147,  152,
+      272,   79,  143,  141,  140,  148,  137,  136,  137,  142,
+      130,  130,  132,  272,  138,  125,  272,  125,  128,  132,
+      121,  119,  133,  123,  121,  117,  272,  129,  118,  272,
+      112,  118,  112,  110,  117,  126,  121,  120,  119,  110,
+      272,  105,  272,  108,  106,  272,  104,  272,  105,   98,
+
+      272,   98,   96,  112,  106,  109,  102,  105,   98,  272,
+      272,  104,  103,  272,  272,   93,  272,  272,   96,  101,
+       94,   91,  272,  272,   87,  272,   95,   98,   84,  272,
+       78,   84,   75,   69,   74,   71,   68,  272,  272,   66,
+      272,  272,  272,  272,  272,  109,  111,   78,   51
+    } ;
+
+static yyconst flex_int16_t yy_def[250] =
+    {   0,
+      245,    1,  246,  246,  247,  247,  245,  245,  245,  248,
+      245,  245,  245,  249,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  248,  245,  249,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,    0,  245,  245,  245,  245
+    } ;
+
+static yyconst flex_int16_t yy_nxt[312] =
+    {   0,
+        8,    9,   10,   11,   12,   13,   14,   15,    8,   16,
+       17,   17,   18,   17,   17,    8,   19,   17,   17,   20,
+       21,   22,   23,   24,   25,   17,   26,   27,   28,   29,
+       30,   17,   31,   32,   33,   34,   35,   17,   36,   37,
+       11,   42,   43,   14,   44,   38,   65,   39,   40,   37,
+       11,   49,   51,   14,   45,   38,   71,   39,   40,   42,
+       43,   52,   44,   59,   62,   66,   79,   68,   80,   60,
+       69,   63,   45,   64,   72,   74,   85,   91,   47,   75,
+       79,   70,   80,   81,  244,   86,  116,  114,   87,   88,
+       92,  115,  117,   82,  154,  156,  243,  118,  178,  242,
+
+      241,  155,  240,  239,  238,  157,   83,  237,  179,    8,
+        8,   41,   41,  236,  235,  234,  233,  232,  231,  230,
+      229,  228,  227,  112,   61,  226,  225,  224,  223,  222,
+      221,  220,  219,  218,  217,  216,  215,  214,  213,  212,
+      211,  210,  209,  208,  207,  206,  205,  204,  203,  202,
+      201,  200,  199,  198,  197,  196,  195,  194,  193,  192,
+      191,  190,  189,  188,  187,  186,  185,  184,  183,  182,
+      181,  180,  177,  176,  175,  174,  173,  172,  171,  170,
+      169,  168,  167,  166,  165,  164,  163,  162,  161,  160,
+      159,  158,  153,  152,  151,  150,  149,  148,  147,  146,
+
+      145,  144,  143,  142,  141,  140,  139,  138,  137,  136,
+      135,  134,  133,  132,  131,  130,  129,  128,  127,  126,
+      125,  124,  123,  122,  121,  120,  119,  113,   78,   77,
+      112,  111,  110,  109,  108,  107,  106,  105,  104,  103,
+      102,  101,  100,   99,   98,   97,   96,   95,   94,   93,
+       90,   89,   84,   48,   46,   78,   77,   76,   73,   67,
+       61,   58,   57,   56,   55,   54,   53,   50,   48,   46,
+      245,    7,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245
+    } ;
+
+static yyconst flex_int16_t yy_chk[312] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    3,
+        3,    5,    5,    3,    5,    3,   30,    3,    3,    4,
+        4,  249,   20,    4,    5,    4,   33,    4,    4,    6,
+        6,   20,    6,   27,   29,   30,   80,   32,   80,   27,
+       32,   29,    6,   29,   33,   35,   51,   54,  248,   35,
+       45,   32,   45,   45,  240,   51,   85,   84,   51,   51,
+       54,   84,   85,   45,  128,  129,  237,   85,  152,  236,
+
+      235,  128,  234,  233,  232,  129,   45,  231,  152,  246,
+      246,  247,  247,  229,  228,  227,  225,  222,  221,  220,
+      219,  216,  213,  212,  209,  208,  207,  206,  205,  204,
+      203,  202,  200,  199,  197,  195,  194,  192,  190,  189,
+      188,  187,  186,  185,  184,  183,  182,  181,  179,  178,
+      176,  175,  174,  173,  172,  171,  170,  169,  168,  166,
+      165,  163,  162,  161,  160,  159,  158,  157,  156,  155,
+      154,  153,  150,  149,  148,  147,  146,  145,  144,  143,
+      142,  141,  140,  139,  137,  136,  135,  134,  133,  132,
+      131,  130,  127,  126,  125,  122,  121,  120,  119,  118,
+
+      117,  116,  114,  111,  110,  109,  108,  107,  106,  105,
+      104,  103,  102,  101,  100,   98,   97,   96,   94,   93,
+       92,   91,   90,   89,   88,   87,   86,   82,   78,   77,
+       76,   75,   74,   73,   72,   71,   70,   69,   68,   67,
+       66,   65,   64,   62,   60,   59,   58,   57,   56,   55,
+       53,   52,   50,   48,   46,   42,   40,   36,   34,   31,
+       28,   26,   25,   24,   23,   22,   21,   19,   12,    9,
+        7,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+
+      245,  245,  245,  245,  245,  245,  245,  245,  245,  245,
+      245
+    } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[63] =
+    {   0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 
+    0, 0, 0,     };
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "../../src/scanner.ll"
+/**
+ * Copyright (C) 1999-2007  Free Software Foundation, Inc.
+ *
+ * This file is part of GNU gengetopt
+ *
+ * GNU gengetopt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU gengetopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with gengetopt; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 23 "../../src/scanner.ll"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "argsdef.h"
+#include "parser.h"
+extern int gengetopt_count_line;
+
+#include "my_sstream.h"
+
+static void update_count_line (char *str);
+static void updateTokenInfo (int pos);
+
+// the buffer for strings (possibly spanning more lines)
+static std::ostringstream buff;
+
+static void buffer(const char *s);
+static char *flush_buffer();
+
+#define LINEBUF_LEN 1024
+
+#define PUSH(s) yy_push_state(s);
+#define POP() yy_pop_state();
+
+int tokenpos = 0;
+char linebuf[LINEBUF_LEN] ; /* current line */
+
+//#define DEBUG_SCANNER
+#ifdef DEBUG_SCANNER
+#include <iostream> // for debug
+#define DEB(s) std::cerr << s << std::endl;
+#define DEB2(s,s2) std::cerr << s << ": " << s2 << std::endl;
+#else
+#define DEB(s)
+#define DEB2(s,s2)
+#endif
+
+
+#line 692 "../../src/scanner.cc"
+
+#define INITIAL 0
+#define SIZE_STATE 1
+#define STRING_STATE 2
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag  );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *yyget_in (void );
+
+void yyset_in  (FILE * in_str  );
+
+FILE *yyget_out (void );
+
+void yyset_out  (FILE * out_str  );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number  );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+        static int yy_start_stack_ptr = 0;
+        static int yy_start_stack_depth = 0;
+        static int *yy_start_stack = NULL;
+    
+    static void yy_push_state (int new_state );
+    
+    static void yy_pop_state (void );
+    
+    static int yy_top_state (void );
+    
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+               { \
+               int c = '*'; \
+               size_t n; \
+               for ( n = 0; n < max_size && \
+                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+                       buf[n] = (char) c; \
+               if ( c == '\n' ) \
+                       buf[n++] = (char) c; \
+               if ( c == EOF && ferror( yyin ) ) \
+                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
+               result = n; \
+               } \
+       else \
+               { \
+               errno=0; \
+               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+                       { \
+                       if( errno != EINTR) \
+                               { \
+                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
+                               break; \
+                               } \
+                       errno=0; \
+                       clearerr(yyin); \
+                       } \
+               }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+       YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp, *yy_bp;
+       register int yy_act;
+    
+#line 71 "../../src/scanner.ll"
+
+
+
+#line 893 "../../src/scanner.cc"
+
+       if ( !(yy_init) )
+               {
+               (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+               YY_USER_INIT;
+#endif
+
+               if ( ! (yy_start) )
+                       (yy_start) = 1; /* first start state */
+
+               if ( ! yyin )
+                       yyin = stdin;
+
+               if ( ! yyout )
+                       yyout = stdout;
+
+               if ( ! YY_CURRENT_BUFFER ) {
+                       yyensure_buffer_stack ();
+                       YY_CURRENT_BUFFER_LVALUE =
+                               yy_create_buffer(yyin,YY_BUF_SIZE );
+               }
+
+               yy_load_buffer_state( );
+               }
+
+       while ( 1 )             /* loops until end-of-file is reached */
+               {
+               yy_cp = (yy_c_buf_p);
+
+               /* Support of yytext. */
+               *yy_cp = (yy_hold_char);
+
+               /* yy_bp points to the position in yy_ch_buf of the start of
+                * the current run.
+                */
+               yy_bp = yy_cp;
+
+               yy_current_state = (yy_start);
+yy_match:
+               do
+                       {
+                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+                       if ( yy_accept[yy_current_state] )
+                               {
+                               (yy_last_accepting_state) = yy_current_state;
+                               (yy_last_accepting_cpos) = yy_cp;
+                               }
+                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                               {
+                               yy_current_state = (int) yy_def[yy_current_state];
+                               if ( yy_current_state >= 246 )
+                                       yy_c = yy_meta[(unsigned int) yy_c];
+                               }
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                       ++yy_cp;
+                       }
+               while ( yy_base[yy_current_state] != 272 );
+
+yy_find_action:
+               yy_act = yy_accept[yy_current_state];
+               if ( yy_act == 0 )
+                       { /* have to back up */
+                       yy_cp = (yy_last_accepting_cpos);
+                       yy_current_state = (yy_last_accepting_state);
+                       yy_act = yy_accept[yy_current_state];
+                       }
+
+               YY_DO_BEFORE_ACTION;
+
+               if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+                       {
+                       int yyl;
+                       for ( yyl = 0; yyl < yyleng; ++yyl )
+                               if ( yytext[yyl] == '\n' )
+                                          
+    yylineno++;
+;
+                       }
+
+do_action:     /* This label is used only to access EOF actions. */
+
+               switch ( yy_act )
+       { /* beginning of action switch */
+                       case 0: /* must back up */
+                       /* undo the effects of YY_DO_BEFORE_ACTION */
+                       *yy_cp = (yy_hold_char);
+                       yy_cp = (yy_last_accepting_cpos);
+                       yy_current_state = (yy_last_accepting_state);
+                       goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 74 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_STRING; return TOK_ARGTYPE;
+       YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 75 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_INT; return TOK_ARGTYPE;
+       YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 76 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_SHORT; return TOK_ARGTYPE;
+       YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 77 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_LONG; return TOK_ARGTYPE;
+       YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 78 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_FLOAT; return TOK_ARGTYPE;
+       YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 79 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_DOUBLE; return TOK_ARGTYPE;
+       YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 80 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_LONGDOUBLE; return TOK_ARGTYPE;
+       YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 81 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_LONGLONG; return TOK_ARGTYPE;
+       YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 82 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.argtype = ARG_ENUM; return TOK_ARGTYPE;
+       YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 84 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_PACKAGE;
+       YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 85 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_VERSION;
+       YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 86 "../../src/scanner.ll"
+updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_GROUPOPTION;
+       YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 87 "../../src/scanner.ll"
+updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_MODEOPTION;
+       YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 88 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_YES;
+       YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 89 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_NO;
+       YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 90 "../../src/scanner.ll"
+updateTokenInfo (-1); yylloc.first_line = gengetopt_count_line; return TOK_OPTION;
+       YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 91 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_FLAG;
+       YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 92 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_ON;
+       YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 93 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_OFF;
+       YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 94 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_PURPOSE;
+       YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 95 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DESCRIPTION;
+       YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 96 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_USAGE;
+       YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 97 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DEFAULT;
+       YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 98 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_TYPESTR;
+       YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 99 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_GROUP;
+       YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 100 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_GROUPDESC;
+       YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 101 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DEFGROUP;
+       YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 102 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_MODE;
+       YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 103 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_MODEDESC;
+       YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 104 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DEFMODE;
+       YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 105 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_MULTIPLE;
+       YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 106 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_ARGOPTIONAL;
+       YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 107 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_SECTIONDESC;
+       YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 108 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_SECTION;
+       YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 109 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_VALUES;
+       YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 110 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_HIDDEN;
+       YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 111 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DEPENDON;
+       YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 112 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_DETAILS;
+       YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 113 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_TEXT;
+       YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 114 "../../src/scanner.ll"
+updateTokenInfo (-1); return TOK_ARGS;
+       YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 116 "../../src/scanner.ll"
+{ updateTokenInfo (-1); return '='; }
+       YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 117 "../../src/scanner.ll"
+{ updateTokenInfo (-1); return ','; }
+       YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 119 "../../src/scanner.ll"
+{ PUSH(SIZE_STATE); updateTokenInfo (-1); return '('; }
+       YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 120 "../../src/scanner.ll"
+{ updateTokenInfo (-1); return '-'; }
+       YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 121 "../../src/scanner.ll"
+{ updateTokenInfo (-1); yylval.str = strdup(yytext); return TOK_SIZE; }
+       YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 122 "../../src/scanner.ll"
+{ POP(); updateTokenInfo (-1); return ')'; }
+       YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 124 "../../src/scanner.ll"
+updateTokenInfo (-1); yylval.chr = yytext[0]; return TOK_CHAR;
+       YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 126 "../../src/scanner.ll"
+{ updateTokenInfo (-1); DEB("start string"); PUSH(STRING_STATE) ; }
+       YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 127 "../../src/scanner.ll"
+{ updateTokenInfo (2); buffer("\\\\n"); }
+       YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 128 "../../src/scanner.ll"
+{ updateTokenInfo (1); buffer("\n"); }
+       YY_BREAK
+case 51:
+/* rule 51 can match eol */
+YY_RULE_SETUP
+#line 129 "../../src/scanner.ll"
+{  update_count_line (yytext); buffer( yytext ) ; }
+       YY_BREAK
+case 52:
+/* rule 52 can match eol */
+YY_RULE_SETUP
+#line 130 "../../src/scanner.ll"
+{ update_count_line (yytext); /* a line break */ }
+       YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 131 "../../src/scanner.ll"
+{ updateTokenInfo (-1); buffer(yytext); }
+       YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 132 "../../src/scanner.ll"
+{ updateTokenInfo (-1); DEB("end string"); POP() ; yylval.str = flush_buffer(); return TOK_STRING; }
+       YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 133 "../../src/scanner.ll"
+{  updateTokenInfo (-1); buffer( yytext ) ; }
+       YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 135 "../../src/scanner.ll"
+updateTokenInfo (-1);
+       YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 136 "../../src/scanner.ll"
+updateTokenInfo (8*yyleng);
+       YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 138 "../../src/scanner.ll"
+/* comments begin with # in any place (but strings) */
+       YY_BREAK
+case 59:
+/* rule 59 can match eol */
+YY_RULE_SETUP
+#line 139 "../../src/scanner.ll"
+update_count_line (0); yyless(1) ; /* give back all but the \n to rescan */
+       YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 141 "../../src/scanner.ll"
+{}
+       YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 143 "../../src/scanner.ll"
+{
+  return 1000; /* little hack to produce a parse error too. */
+}
+       YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 147 "../../src/scanner.ll"
+ECHO;
+       YY_BREAK
+#line 1301 "../../src/scanner.cc"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(SIZE_STATE):
+case YY_STATE_EOF(STRING_STATE):
+       yyterminate();
+
+       case YY_END_OF_BUFFER:
+               {
+               /* Amount of text matched not including the EOB char. */
+               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = (yy_hold_char);
+               YY_RESTORE_YY_MORE_OFFSET
+
+               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+                       /* We're scanning a new file or input source.  It's
+                        * possible that this happened because the user
+                        * just pointed yyin at a new source and called
+                        * yylex().  If so, then we have to assure
+                        * consistency between YY_CURRENT_BUFFER and our
+                        * globals.  Here is the right place to do so, because
+                        * this is the first action (other than possibly a
+                        * back-up) that will match for the new input source.
+                        */
+                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                       }
+
+               /* Note that here we test for yy_c_buf_p "<=" to the position
+                * of the first EOB in the buffer, since yy_c_buf_p will
+                * already have been incremented past the NUL character
+                * (since all states make transitions on EOB to the
+                * end-of-buffer state).  Contrast this with the test
+                * in input().
+                */
+               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+                       { /* This was really a NUL. */
+                       yy_state_type yy_next_state;
+
+                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+                       yy_current_state = yy_get_previous_state(  );
+
+                       /* Okay, we're now positioned to make the NUL
+                        * transition.  We couldn't have
+                        * yy_get_previous_state() go ahead and do it
+                        * for us because it doesn't know how to deal
+                        * with the possibility of jamming (and we don't
+                        * want to build jamming into it because then it
+                        * will run more slowly).
+                        */
+
+                       yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+                       if ( yy_next_state )
+                               {
+                               /* Consume the NUL. */
+                               yy_cp = ++(yy_c_buf_p);
+                               yy_current_state = yy_next_state;
+                               goto yy_match;
+                               }
+
+                       else
+                               {
+                               yy_cp = (yy_c_buf_p);
+                               goto yy_find_action;
+                               }
+                       }
+
+               else switch ( yy_get_next_buffer(  ) )
+                       {
+                       case EOB_ACT_END_OF_FILE:
+                               {
+                               (yy_did_buffer_switch_on_eof) = 0;
+
+                               if ( yywrap( ) )
+                                       {
+                                       /* Note: because we've taken care in
+                                        * yy_get_next_buffer() to have set up
+                                        * yytext, we can now set up
+                                        * yy_c_buf_p so that if some total
+                                        * hoser (like flex itself) wants to
+                                        * call the scanner after we return the
+                                        * YY_NULL, it'll still work - another
+                                        * YY_NULL will get returned.
+                                        */
+                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+                                       yy_act = YY_STATE_EOF(YY_START);
+                                       goto do_action;
+                                       }
+
+                               else
+                                       {
+                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                               YY_NEW_FILE;
+                                       }
+                               break;
+                               }
+
+                       case EOB_ACT_CONTINUE_SCAN:
+                               (yy_c_buf_p) =
+                                       (yytext_ptr) + yy_amount_of_matched_text;
+
+                               yy_current_state = yy_get_previous_state(  );
+
+                               yy_cp = (yy_c_buf_p);
+                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               goto yy_match;
+
+                       case EOB_ACT_LAST_MATCH:
+                               (yy_c_buf_p) =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+                               yy_current_state = yy_get_previous_state(  );
+
+                               yy_cp = (yy_c_buf_p);
+                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               goto yy_find_action;
+                       }
+               break;
+               }
+
+       default:
+               YY_FATAL_ERROR(
+                       "fatal flex scanner internal error--no action found" );
+       } /* end of action switch */
+               } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *     EOB_ACT_LAST_MATCH -
+ *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *     EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+       register char *source = (yytext_ptr);
+       register int number_to_move, i;
+       int ret_val;
+
+       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+               YY_FATAL_ERROR(
+               "fatal flex scanner internal error--end of buffer missed" );
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+               { /* Don't try to fill the buffer, so this is an EOF. */
+               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+                       {
+                       /* We matched a single character, the EOB, so
+                        * treat this as a final EOF.
+                        */
+                       return EOB_ACT_END_OF_FILE;
+                       }
+
+               else
+                       {
+                       /* We matched some text prior to the EOB, first
+                        * process it.
+                        */
+                       return EOB_ACT_LAST_MATCH;
+                       }
+               }
+
+       /* Try to read more data. */
+
+       /* First move last chars to start of buffer. */
+       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+       for ( i = 0; i < number_to_move; ++i )
+               *(dest++) = *(source++);
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+               /* don't do the read, it's not guaranteed to return an EOF,
+                * just force an EOF
+                */
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+       else
+               {
+                       int num_to_read =
+                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+               while ( num_to_read <= 0 )
+                       { /* Not enough room in the buffer - grow it. */
+
+                       /* just a shorter name for the current buffer */
+                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+                       int yy_c_buf_p_offset =
+                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+                       if ( b->yy_is_our_buffer )
+                               {
+                               int new_size = b->yy_buf_size * 2;
+
+                               if ( new_size <= 0 )
+                                       b->yy_buf_size += b->yy_buf_size / 8;
+                               else
+                                       b->yy_buf_size *= 2;
+
+                               b->yy_ch_buf = (char *)
+                                       /* Include room in for 2 EOB chars. */
+                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+                               }
+                       else
+                               /* Can't grow it, we don't own it. */
+                               b->yy_ch_buf = 0;
+
+                       if ( ! b->yy_ch_buf )
+                               YY_FATAL_ERROR(
+                               "fatal error - scanner input buffer overflow" );
+
+                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                                               number_to_move - 1;
+
+                       }
+
+               if ( num_to_read > YY_READ_BUF_SIZE )
+                       num_to_read = YY_READ_BUF_SIZE;
+
+               /* Read in more data. */
+               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+                       (yy_n_chars), (size_t) num_to_read );
+
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       if ( (yy_n_chars) == 0 )
+               {
+               if ( number_to_move == YY_MORE_ADJ )
+                       {
+                       ret_val = EOB_ACT_END_OF_FILE;
+                       yyrestart(yyin  );
+                       }
+
+               else
+                       {
+                       ret_val = EOB_ACT_LAST_MATCH;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                               YY_BUFFER_EOF_PENDING;
+                       }
+               }
+
+       else
+               ret_val = EOB_ACT_CONTINUE_SCAN;
+
+       if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+               /* Extend the array by 50%, plus the number we really need. */
+               yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+       }
+
+       (yy_n_chars) += number_to_move;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+       return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp;
+    
+       yy_current_state = (yy_start);
+
+       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+               {
+               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+               if ( yy_accept[yy_current_state] )
+                       {
+                       (yy_last_accepting_state) = yy_current_state;
+                       (yy_last_accepting_cpos) = yy_cp;
+                       }
+               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                       {
+                       yy_current_state = (int) yy_def[yy_current_state];
+                       if ( yy_current_state >= 246 )
+                               yy_c = yy_meta[(unsigned int) yy_c];
+                       }
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+               }
+
+       return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *     next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+       register int yy_is_jam;
+       register char *yy_cp = (yy_c_buf_p);
+
+       register YY_CHAR yy_c = 1;
+       if ( yy_accept[yy_current_state] )
+               {
+               (yy_last_accepting_state) = yy_current_state;
+               (yy_last_accepting_cpos) = yy_cp;
+               }
+       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+               {
+               yy_current_state = (int) yy_def[yy_current_state];
+               if ( yy_current_state >= 246 )
+                       yy_c = yy_meta[(unsigned int) yy_c];
+               }
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+       yy_is_jam = (yy_current_state == 245);
+
+       return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+       int c;
+    
+       *(yy_c_buf_p) = (yy_hold_char);
+
+       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+               {
+               /* yy_c_buf_p now points to the character we want to return.
+                * If this occurs *before* the EOB characters, then it's a
+                * valid NUL; if not, then we've hit the end of the buffer.
+                */
+               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+                       /* This was really a NUL. */
+                       *(yy_c_buf_p) = '\0';
+
+               else
+                       { /* need more input */
+                       int offset = (yy_c_buf_p) - (yytext_ptr);
+                       ++(yy_c_buf_p);
+
+                       switch ( yy_get_next_buffer(  ) )
+                               {
+                               case EOB_ACT_LAST_MATCH:
+                                       /* This happens because yy_g_n_b()
+                                        * sees that we've accumulated a
+                                        * token and flags that we need to
+                                        * try matching the token before
+                                        * proceeding.  But for input(),
+                                        * there's no matching to consider.
+                                        * So convert the EOB_ACT_LAST_MATCH
+                                        * to EOB_ACT_END_OF_FILE.
+                                        */
+
+                                       /* Reset buffer status. */
+                                       yyrestart(yyin );
+
+                                       /*FALLTHROUGH*/
+
+                               case EOB_ACT_END_OF_FILE:
+                                       {
+                                       if ( yywrap( ) )
+                                               return EOF;
+
+                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                               YY_NEW_FILE;
+#ifdef __cplusplus
+                                       return yyinput();
+#else
+                                       return input();
+#endif
+                                       }
+
+                               case EOB_ACT_CONTINUE_SCAN:
+                                       (yy_c_buf_p) = (yytext_ptr) + offset;
+                                       break;
+                               }
+                       }
+               }
+
+       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
+       *(yy_c_buf_p) = '\0';   /* preserve yytext */
+       (yy_hold_char) = *++(yy_c_buf_p);
+
+       if ( c == '\n' )
+                  
+    yylineno++;
+;
+
+       return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file )
+{
+    
+       if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack ();
+               YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer(yyin,YY_BUF_SIZE );
+       }
+
+       yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+       yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+       /* TODO. We should be able to replace this entire function body
+        * with
+        *              yypop_buffer_state();
+        *              yypush_buffer_state(new_buffer);
+     */
+       yyensure_buffer_stack ();
+       if ( YY_CURRENT_BUFFER == new_buffer )
+               return;
+
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *(yy_c_buf_p) = (yy_hold_char);
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+       yy_load_buffer_state( );
+
+       /* We don't actually know whether we did this switch during
+        * EOF (yywrap()) processing, but the only time this flag
+        * is looked at is after yywrap() is called, so it's safe
+        * to go ahead and always set it.
+        */
+       (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state  (void)
+{
+       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+       (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
+{
+       YY_BUFFER_STATE b;
+    
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_buf_size = size;
+
+       /* yy_ch_buf has to be 2 characters longer than the size given because
+        * we need to put in 2 end-of-buffer characters.
+        */
+       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+       if ( ! b->yy_ch_buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_is_our_buffer = 1;
+
+       yy_init_buffer(b,file );
+
+       return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * 
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+       if ( ! b )
+               return;
+
+       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+       if ( b->yy_is_our_buffer )
+               yyfree((void *) b->yy_ch_buf  );
+
+       yyfree((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+       int oerrno = errno;
+    
+       yy_flush_buffer(b );
+
+       b->yy_input_file = file;
+       b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+       errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b )
+{
+       if ( ! b )
+               return;
+
+       b->yy_n_chars = 0;
+
+       /* We always need two end-of-buffer characters.  The first causes
+        * a transition to the end-of-buffer state.  The second causes
+        * a jam in that state.
+        */
+       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+       b->yy_buf_pos = &b->yy_ch_buf[0];
+
+       b->yy_at_bol = 1;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       if ( b == YY_CURRENT_BUFFER )
+               yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+       if (new_buffer == NULL)
+               return;
+
+       yyensure_buffer_stack();
+
+       /* This block is copied from yy_switch_to_buffer. */
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *(yy_c_buf_p) = (yy_hold_char);
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       /* Only push if top exists. Otherwise, replace top. */
+       if (YY_CURRENT_BUFFER)
+               (yy_buffer_stack_top)++;
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+       /* copied from yy_switch_to_buffer. */
+       yy_load_buffer_state( );
+       (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void yypop_buffer_state (void)
+{
+       if (!YY_CURRENT_BUFFER)
+               return;
+
+       yy_delete_buffer(YY_CURRENT_BUFFER );
+       YY_CURRENT_BUFFER_LVALUE = NULL;
+       if ((yy_buffer_stack_top) > 0)
+               --(yy_buffer_stack_top);
+
+       if (YY_CURRENT_BUFFER) {
+               yy_load_buffer_state( );
+               (yy_did_buffer_switch_on_eof) = 1;
+       }
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+       int num_to_alloc;
+    
+       if (!(yy_buffer_stack)) {
+
+               /* First allocation is just for 2 elements, since we don't know if this
+                * scanner will even need a stack. We use 2 instead of 1 to avoid an
+                * immediate realloc on the next call.
+         */
+               num_to_alloc = 1;
+               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+                                                                 
+               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+                               
+               (yy_buffer_stack_max) = num_to_alloc;
+               (yy_buffer_stack_top) = 0;
+               return;
+       }
+
+       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+               /* Increase the buffer to prepare for a possible push. */
+               int grow_size = 8 /* arbitrary grow size */;
+
+               num_to_alloc = (yy_buffer_stack_max) + grow_size;
+               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+                                                               ((yy_buffer_stack),
+                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+               /* zero only the new slots.*/
+               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+               (yy_buffer_stack_max) = num_to_alloc;
+       }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+{
+       YY_BUFFER_STATE b;
+    
+       if ( size < 2 ||
+            base[size-2] != YY_END_OF_BUFFER_CHAR ||
+            base[size-1] != YY_END_OF_BUFFER_CHAR )
+               /* They forgot to leave room for the EOB's. */
+               return 0;
+
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
+       b->yy_buf_pos = b->yy_ch_buf = base;
+       b->yy_is_our_buffer = 0;
+       b->yy_input_file = 0;
+       b->yy_n_chars = b->yy_buf_size;
+       b->yy_is_interactive = 0;
+       b->yy_at_bol = 1;
+       b->yy_fill_buffer = 0;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       yy_switch_to_buffer(b  );
+
+       return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+    
+       return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+       YY_BUFFER_STATE b;
+       char *buf;
+       yy_size_t n;
+       int i;
+    
+       /* Get memory for full buffer, including space for trailing EOB's. */
+       n = _yybytes_len + 2;
+       buf = (char *) yyalloc(n  );
+       if ( ! buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+       for ( i = 0; i < _yybytes_len; ++i )
+               buf[i] = yybytes[i];
+
+       buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+       b = yy_scan_buffer(buf,n );
+       if ( ! b )
+               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+       /* It's okay to grow etc. this buffer, and we should throw it
+        * away when we're done.
+        */
+       b->yy_is_our_buffer = 1;
+
+       return b;
+}
+
+    static void yy_push_state (int  new_state )
+{
+       if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) )
+               {
+               yy_size_t new_size;
+
+               (yy_start_stack_depth) += YY_START_STACK_INCR;
+               new_size = (yy_start_stack_depth) * sizeof( int );
+
+               if ( ! (yy_start_stack) )
+                       (yy_start_stack) = (int *) yyalloc(new_size  );
+
+               else
+                       (yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size  );
+
+               if ( ! (yy_start_stack) )
+                       YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+               }
+
+       (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START;
+
+       BEGIN(new_state);
+}
+
+    static void yy_pop_state  (void)
+{
+       if ( --(yy_start_stack_ptr) < 0 )
+               YY_FATAL_ERROR( "start-condition stack underflow" );
+
+       BEGIN((yy_start_stack)[(yy_start_stack_ptr)]);
+}
+
+    static int yy_top_state  (void)
+{
+       return (yy_start_stack)[(yy_start_stack_ptr) - 1];
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               yytext[yyleng] = (yy_hold_char); \
+               (yy_c_buf_p) = yytext + yyless_macro_arg; \
+               (yy_hold_char) = *(yy_c_buf_p); \
+               *(yy_c_buf_p) = '\0'; \
+               yyleng = yyless_macro_arg; \
+               } \
+       while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int yyget_lineno  (void)
+{
+        
+    return yylineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *yyget_in  (void)
+{
+        return yyin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *yyget_out  (void)
+{
+        return yyout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int yyget_leng  (void)
+{
+        return yyleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *yyget_text  (void)
+{
+        return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void yyset_lineno (int  line_number )
+{
+    
+    yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  in_str )
+{
+        yyin = in_str ;
+}
+
+void yyset_out (FILE *  out_str )
+{
+        yyout = out_str ;
+}
+
+int yyget_debug  (void)
+{
+        return yy_flex_debug;
+}
+
+void yyset_debug (int  bdebug )
+{
+        yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    /* We do not touch yylineno unless the option is enabled. */
+    yylineno =  1;
+    
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+    (yy_start_stack_ptr) = 0;
+    (yy_start_stack_depth) = 0;
+    (yy_start_stack) =  NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+       while(YY_CURRENT_BUFFER){
+               yy_delete_buffer(YY_CURRENT_BUFFER  );
+               YY_CURRENT_BUFFER_LVALUE = NULL;
+               yypop_buffer_state();
+       }
+
+       /* Destroy the stack itself. */
+       yyfree((yy_buffer_stack) );
+       (yy_buffer_stack) = NULL;
+
+    /* Destroy the start condition stack. */
+        yyfree((yy_start_stack)  );
+        (yy_start_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * yylex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+       register int i;
+       for ( i = 0; i < n; ++i )
+               s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+       register int n;
+       for ( n = 0; s[n]; ++n )
+               ;
+
+       return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size )
+{
+       return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size )
+{
+       /* The cast to (char *) in the following accommodates both
+        * implementations that use char* generic pointers, and those
+        * that use void* generic pointers.  It works with the latter
+        * because both ANSI C and C++ allow castless assignment from
+        * any pointer type to void*, and deal with argument conversions
+        * as though doing an assignment.
+        */
+       return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 147 "../../src/scanner.ll"
+
+
+
+/*
+  Otherwise '\n' within a TOK_MLSTRING would not be counted
+*/
+void
+update_count_line (char *str)
+{
+  if (str)
+    {
+      char *p;
+      for (p = str; *p; ++p)
+        if (*p == '\n') {
+          ++gengetopt_count_line;
+          tokenpos = 0 ; /* reset token position */
+          strncpy (linebuf, ( (p+1) ? p+1 : ""), LINEBUF_LEN - 1);
+        }
+    }
+  else
+    {
+      ++gengetopt_count_line;
+      tokenpos = 0 ; /* reset token position */
+      strncpy (linebuf, yytext+1, LINEBUF_LEN - 1); /* save the next line */
+    }
+}
+
+void
+updateTokenInfo( int pos )
+{
+  if ( pos >= 0 )
+    tokenpos += pos ;
+  else
+    tokenpos += yyleng ;
+}
+
+void buffer(const char *s)
+{
+  buff << s;
+}
+
+char *flush_buffer()
+{
+  char *ret = strdup(buff.str().c_str());
+  buff.str("");
+  return ret;
+}
+
diff --git a/cmake/gengetopt/skels/Makefile.am b/cmake/gengetopt/skels/Makefile.am
new file mode 100644 (file)
index 0000000..3b98eed
--- /dev/null
@@ -0,0 +1,90 @@
+# Copyright (C) 1999-2008 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# if gengen is not installed we simply ignore the changes
+
+SUFFIXES = .h_skel
+
+if NO_GENGEN
+#.h_skel.cc:
+#      echo "Not regenerating $@ since gengen is not installed"
+# better not to use touch, otherwise we will create an empty file in
+# the build directory
+#      touch $@
+
+else
+GENERATE = $(GENGEN)
+
+.h_skel.cc:
+       name="`echo $* | sed 's/^.*\///g'`"; \
+       echo "$$name"; \
+       $(GENERATE) -i $< -F $*.h -f $$name --separate-files --expand-tabs --output-dir=$(srcdir) --force
+endif
+
+INCLUDES = -I@top_srcdir@/src
+
+noinst_LTLIBRARIES = libgen.la
+
+libgen_la_SOURCES = $(BUILT_SOURCES)
+
+BUILT_SOURCES = header.h header.cc c_source.h c_source.cc \
+handle_help.h handle_version.h handle_help.cc handle_version.cc \
+generic_option.h required_option.h dependant_option.h \
+generic_option.cc required_option.cc dependant_option.cc \
+group_counter.h group_option.h \
+group_counter.cc group_option.cc \
+print_help_string.h print_help_string.cc \
+multiple_opt_list.cc multiple_opt_list.h \
+multiple_fill_array.cc multiple_fill_array.h \
+copyright.cc copyright.h \
+free_string.cc free_string.h \
+free_multiple.cc free_multiple.h \
+reset_group.cc reset_group.h \
+exit_failure.cc exit_failure.h \
+update_given.cc update_given.h \
+option_arg.cc option_arg.h \
+given_field.cc given_field.h \
+clear_given.cc clear_given.h \
+clear_arg.cc clear_arg.h \
+free_list.cc free_list.h \
+file_save.cc file_save.h \
+file_save_multiple.cc file_save_multiple.h \
+init_args_info.cc init_args_info.h \
+custom_getopt_gen.cc custom_getopt_gen.h \
+check_modes.cc check_modes.h \
+enum_decl.cc enum_decl.h
+
+EXTRA_DIST = header.h_skel c_source.h_skel handle_help.h_skel \
+handle_version.h_skel generic_option.h_skel \
+required_option.h_skel dependant_option.h_skel \
+group_counter.h_skel group_option.h_skel \
+print_help_string.h_skel \
+multiple_opt_list.h_skel \
+multiple_fill_array.h_skel \
+copyright.h_skel free_string.h_skel \
+free_multiple.h_skel \
+reset_group.h_skel \
+exit_failure.h_skel \
+update_given.h_skel \
+option_arg.h_skel \
+given_field.h_skel \
+clear_given.h_skel \
+clear_arg.h_skel \
+free_list.h_skel \
+file_save.h_skel \
+file_save_multiple.h_skel \
+init_args_info.h_skel \
+custom_getopt_gen.h_skel \
+check_modes.h_skel \
+enum_decl.h_skel \
+$(BUILT_SOURCES)
+
+built-clean:
+       cd @srcdir@ && rm -f $(BUILT_SOURCES)
\ No newline at end of file
diff --git a/cmake/gengetopt/skels/c_source.cc b/cmake/gengetopt/skels/c_source.cc
new file mode 100644 (file)
index 0000000..5120083
--- /dev/null
@@ -0,0 +1,5079 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "c_source.h"
+
+void
+c_source_gen_class::generate_c_source(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  File autogenerated by gengetopt ";
+  generate_string (generator_version, stream, indent + indent_str.length ());
+  stream << "\n";
+  stream << indent_str;
+  stream << "  generated with the following command:";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (command_line, stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  The developers of gengetopt consider the fixed text that goes in all";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  gengetopt output files to be in the public domain:";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  we make no copyright claims on it.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "*/";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/* If we use autoconf.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifdef HAVE_CONFIG_H";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#include \"config.h\"";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#include <stdio.h>";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#include <stdlib.h>";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#include <string.h>";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifndef FIX_UNUSED";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (( ! include_getopt ))
+    {
+      stream << "#include <getopt.h>";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "#include \"";
+  generate_string (source_name, stream, indent + indent_str.length ());
+  stream << ".";
+  generate_string (header_file_ext, stream, indent + indent_str.length ());
+  stream << "\"";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "const char *";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_purpose = \"";
+  generate_string (purpose, stream, indent + indent_str.length ());
+  stream << "\";";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "const char *";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_usage = \"Usage: ";
+  if (no_package)
+    {
+      stream << "\" ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << " \"";
+    }
+  generate_string (usage_string, stream, indent + indent_str.length ());
+  stream << "\";";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "const char *";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_description = \"";
+  generate_string (description, stream, indent + indent_str.length ());
+  stream << "\";";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (( has_hidden || has_details ))
+    {
+      if (has_details)
+        {
+          stream << "const char *";
+          generate_string (args_info, stream, indent + indent_str.length ());
+          stream << "_detailed_help[] = {";
+          stream << "\n";
+          stream << indent_str;
+          indent = 2;
+          stream << "  ";
+          if (detailed_help_option_print.size () > 0)
+            generate_string (detailed_help_option_print, stream, indent + indent_str.length ());
+          else
+            generate_detailed_help_option_print (stream, indent + indent_str.length ());
+          stream << "  0";
+          indent = 0;
+          stream << "\n";
+          stream << indent_str;
+          stream << "};";
+          stream << "\n";
+          stream << indent_str;
+          if (has_hidden)
+            {
+              stream << "static void";
+              stream << "\n";
+              stream << indent_str;
+              stream << "init_full_help_array(void)";
+              stream << "\n";
+              stream << indent_str;
+              stream << "{";
+              stream << "\n";
+              stream << indent_str;
+              indent = 2;
+              stream << "  ";
+              if (full_help_option_print.size () > 0)
+                generate_string (full_help_option_print, stream, indent + indent_str.length ());
+              else
+                generate_full_help_option_print (stream, indent + indent_str.length ());
+              indent = 0;
+              stream << "\n";
+              stream << indent_str;
+              stream << "}";
+              stream << "\n";
+              stream << indent_str;
+              stream << "\n";
+              stream << indent_str;
+              stream << "const char *";
+              generate_string (args_info, stream, indent + indent_str.length ());
+              stream << "_full_help[";
+              generate_string (help_string_num, stream, indent + indent_str.length ());
+              stream << "];";
+              stream << "\n";
+              stream << indent_str;
+            }
+        }
+      else
+        {
+          if (has_hidden)
+            {
+              stream << "const char *";
+              generate_string (args_info, stream, indent + indent_str.length ());
+              stream << "_full_help[] = {";
+              stream << "\n";
+              stream << indent_str;
+              indent = 2;
+              stream << "  ";
+              if (full_help_option_print.size () > 0)
+                generate_string (full_help_option_print, stream, indent + indent_str.length ());
+              else
+                generate_full_help_option_print (stream, indent + indent_str.length ());
+              stream << "  0";
+              indent = 0;
+              stream << "\n";
+              stream << indent_str;
+              stream << "};";
+              stream << "\n";
+              stream << indent_str;
+            }
+        }
+      stream << "\n";
+      stream << indent_str;
+      stream << "static void";
+      stream << "\n";
+      stream << indent_str;
+      stream << "init_help_array(void)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      if (help_option_print.size () > 0)
+        generate_string (help_option_print, stream, indent + indent_str.length ());
+      else
+        generate_help_option_print (stream, indent + indent_str.length ());
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "const char *";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << "_help[";
+      generate_string (help_string_num, stream, indent + indent_str.length ());
+      stream << "];";
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "const char *";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << "_help[] = {";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      if (help_option_print.size () > 0)
+        generate_string (help_option_print, stream, indent + indent_str.length ());
+      else
+        generate_help_option_print (stream, indent + indent_str.length ());
+      stream << "  0";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "};";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "typedef enum {ARG_NO";
+  stream << "\n";
+  stream << indent_str;
+  if (has_arg_flag)
+    {
+      stream << "  , ARG_FLAG";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_string)
+    {
+      stream << "  , ARG_STRING";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_int)
+    {
+      stream << "  , ARG_INT";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_short)
+    {
+      stream << "  , ARG_SHORT";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_long)
+    {
+      stream << "  , ARG_LONG";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_float)
+    {
+      stream << "  , ARG_FLOAT";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_double)
+    {
+      stream << "  , ARG_DOUBLE";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_longdouble)
+    {
+      stream << "  , ARG_LONGDOUBLE";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_longlong)
+    {
+      stream << "  , ARG_LONGLONG";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_arg_enum)
+    {
+      stream << "  , ARG_ENUM";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "} ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_arg_type;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void clear_given (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void clear_args (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_internal (int argc, char **argv, struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                        struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *params, const char *additional_error);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (check_required_options)
+    {
+      stream << "static int";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_required2 (struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info, const char *prog_name, const char *additional_error);";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (cmd_list)
+    {
+      stream << "struct line_list";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char * string_arg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct line_list * next;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "};";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "static struct line_list *cmd_line_list = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "static struct line_list *cmd_line_list_tmp = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "static void";
+      stream << "\n";
+      stream << indent_str;
+      stream << "free_cmd_list(void)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  /* free the list of a previous call */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (cmd_line_list)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      while (cmd_line_list) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        cmd_line_list_tmp = cmd_line_list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        cmd_line_list = cmd_line_list->next;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        free (cmd_line_list_tmp->string_arg);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        free (cmd_line_list_tmp);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  if (option_values.size () > 0)
+    generate_string (option_values, stream, indent + indent_str.length ());
+  else
+    generate_option_values (stream, indent + indent_str.length ());
+  stream << indent_str;
+  if (do_generate_strdup)
+    {
+      stream << "static char *";
+      stream << "\n";
+      stream << indent_str;
+      stream << "gengetopt_strdup (const char *s);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "static";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void clear_given (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  if (given_init.size () > 0)
+    generate_string (given_init, stream, indent + indent_str.length ());
+  else
+    generate_given_init (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void clear_args (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  FIX_UNUSED (args_info);";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  if (clear_arg.size () > 0)
+    generate_string (clear_arg, stream, indent + indent_str.length ());
+  else
+    generate_clear_arg (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void init_args_info(struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  if (( has_hidden && has_details ))
+    {
+      stream << "  init_full_help_array(); ";
+    }
+  stream << "\n";
+  stream << indent_str;
+  if (( has_hidden || has_details ))
+    {
+      stream << "  init_help_array(); ";
+    }
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  if (init_args_info.size () > 0)
+    generate_string (init_args_info, stream, indent + indent_str.length ());
+  else
+    generate_init_args_info (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "void";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_print_version (void)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  printf (\"%s %s\\n\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << "     (strlen(";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << "_NAME) ? ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << "_NAME : ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << "),";
+  stream << "\n";
+  stream << indent_str;
+  indent = 5;
+  stream << "     ";
+  generate_string (version_var_name, stream, indent + indent_str.length ());
+  stream << ");";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static void print_help_common(void) {";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_print_version ();";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (strlen(";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_purpose) > 0)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    printf(\"\\n%s\\n\", ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_purpose);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (strlen(";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_usage) > 0)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    printf(\"\\n%s\\n\", ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_usage);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  printf(\"\\n\");";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (strlen(";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_description) > 0)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    printf(\"%s\\n\\n\", ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_description);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "void";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_print_help (void)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int i = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  print_help_common();";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  while (";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_help[i])";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    printf(\"%s\\n\", ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_help[i++]);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (has_hidden)
+    {
+      stream << "void";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_print_full_help (void)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int i = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  print_help_common();";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while (";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << "_full_help[i])";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    printf(\"%s\\n\", ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << "_full_help[i++]);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_details)
+    {
+      stream << "void";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_print_detailed_help (void)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int i = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  print_help_common();";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while (";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << "_detailed_help[i])";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    printf(\"%s\\n\", ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << "_detailed_help[i++]);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "void";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_init (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  clear_given (args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  clear_args (args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  init_args_info (args_info);";
+  stream << "\n";
+  stream << indent_str;
+  if (handle_unamed)
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "  args_info->inputs = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  args_info->inputs_num = 0;";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "void";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params_init(struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *params)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (params)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    { ";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      params->override = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      params->initialize = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      params->check_required = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      params->check_ambiguity = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      params->print_errors = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params_create(void)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *params = ";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    (struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *)malloc(sizeof(struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params));";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params_init(params);  ";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return params;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (has_typed_options)
+    {
+      stream << "static void";
+      stream << "\n";
+      stream << indent_str;
+      stream << "free_string_field (char **s)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (*s)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      free (*s);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      *s = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  if (multiple_token_functions)
+    {
+      stream << "/** ";
+      stream << "@";
+      stream << "brief generic value variable */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "union generic_value {";
+      stream << "\n";
+      stream << indent_str;
+      if (( has_arg_int || has_arg_enum ))
+        {
+          stream << "    int int_arg;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_short)
+        {
+          stream << "    short short_arg;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_long)
+        {
+          stream << "    long long_arg;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_float)
+        {
+          stream << "    float float_arg;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_double)
+        {
+          stream << "    double double_arg;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longdouble)
+        {
+          stream << "    long double longdouble_arg;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longlong)
+        {
+          stream << "#ifdef HAVE_LONG_LONG";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    long long int longlong_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#else";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    long longlong_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#endif";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "    char *string_arg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    const char *default_string_arg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "};";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "/** ";
+      stream << "@";
+      stream << "brief holds temporary values for multiple options */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "struct generic_list";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  union generic_value arg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *orig;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct generic_list *next;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "};";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "brief add a node at the head of the list ";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "static void add_node(struct generic_list **list) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  new_node->next = *list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  *list = new_node;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  new_node->arg.string_arg = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  new_node->orig = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      if (( ( ! multiple_options_all_string ) && multiple_token_functions ))
+        {
+          stream << "/**";
+          stream << "\n";
+          stream << indent_str;
+          stream << " * The passed arg parameter is NOT set to 0 from this function";
+          stream << "\n";
+          stream << indent_str;
+          stream << " */";
+          stream << "\n";
+          stream << indent_str;
+          stream << "static void";
+          stream << "\n";
+          stream << indent_str;
+          stream << "free_multiple_field(unsigned int len, void *arg, char ***orig)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "{";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  unsigned int i;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  if (arg) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    for (i = 0; i < len; ++i)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        free_string_field(&((*orig)[i]));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "\n";
+          stream << indent_str;
+          stream << "    free (arg);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    free (*orig);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    *orig = 0;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "}";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "\n";
+      stream << indent_str;
+      if (multiple_options_string)
+        {
+          stream << "static void";
+          stream << "\n";
+          stream << indent_str;
+          stream << "free_multiple_string_field(unsigned int len, char ***arg, char ***orig)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "{";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  unsigned int i;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  if (*arg) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    for (i = 0; i < len; ++i)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        free_string_field(&((*arg)[i]));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        free_string_field(&((*orig)[i]));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    free_string_field(&((*arg)[0])); /* free default string */";
+          stream << "\n";
+          stream << indent_str;
+          stream << "\n";
+          stream << indent_str;
+          stream << "    free (*arg);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    *arg = 0;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    free (*orig);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    *orig = 0;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "}";
+          stream << "\n";
+          stream << indent_str;
+        }
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "static void";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_release (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  if (handle_unamed)
+    {
+      stream << "  unsigned int i;";
+    }
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  if (free.size () > 0)
+    generate_string (free, stream, indent + indent_str.length ());
+  else
+    generate_free (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  if (handle_unamed)
+    {
+      stream << "  for (i = 0; i < args_info->inputs_num; ++i)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    free (args_info->inputs [i]);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (args_info->inputs_num)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    free (args_info->inputs);";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "  clear_given (args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (check_possible_values)
+    {
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param val the value to check";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param values the possible values";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "return the index of the matched value:";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * -1 if no value matched,";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * -2 if more than one value has matched";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "static int";
+      stream << "\n";
+      stream << indent_str;
+      stream << "check_possible_values(const char *val, const char *values[])";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int i, found, last;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  size_t len;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (!val)   /* otherwise strlen() crashes below */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return -1; /* -1 means no argument for the option */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  found = last = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  for (i = 0, len = strlen(val); values[i]; ++i)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (strncmp(val, values[i], len) == 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          ++found;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          last = i;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          if (strlen(values[i]) == len)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            return i; /* exact macth no need to check more */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (found == 1) /* one match: OK */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return last;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return (found ? -2 : -1); /* return many values or none matched */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "static void";
+  stream << "\n";
+  stream << indent_str;
+  stream << "write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  if (check_possible_values)
+    {
+      stream << "  int found = -1;";
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "  FIX_UNUSED (values);";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "  if (arg) {";
+  stream << "\n";
+  stream << indent_str;
+  if (check_possible_values)
+    {
+      stream << "    if (values) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      found = check_possible_values(arg, values);      ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    if (found >= 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      fprintf(outfile, \"%s=\\\"%s\\\" # %s\\n\", opt, arg, values[found]);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      fprintf(outfile, \"%s=\\\"%s\\\"\\n\", opt, arg);";
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "    fprintf(outfile, \"%s=\\\"%s\\\"\\n\", opt, arg);";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "  } else {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    fprintf(outfile, \"%s\\n\", opt);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (multiple_options)
+    {
+      stream << "static void";
+      stream << "\n";
+      stream << indent_str;
+      stream << "write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[])";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int i;";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  for (i = 0; i < len; ++i)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    write_into_file(outfile, opt, (arg ? arg[i] : 0), values);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "int";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_dump(FILE *outfile, struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int i = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (!outfile)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      fprintf (stderr, \"%s: cannot dump options to stream\\n\", ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << ");";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      return EXIT_FAILURE;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  if (file_save_loop.size () > 0)
+    generate_string (file_save_loop, stream, indent + indent_str.length ());
+  else
+    generate_file_save_loop (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  i = EXIT_SUCCESS;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return i;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "int";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_file_save(const char *filename, struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  FILE *outfile;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int i = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  outfile = fopen(filename, \"w\");";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (!outfile)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      fprintf (stderr, \"%s: cannot open file for writing: %s\\n\", ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << ", filename);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      return EXIT_FAILURE;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  i = ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_dump(outfile, args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  fclose (outfile);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return i;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "void";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_free (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_release (args_info);";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (do_generate_strdup)
+    {
+      stream << "/** ";
+      stream << "@";
+      stream << "brief replacement of strdup, which is not standard */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "char *";
+      stream << "\n";
+      stream << indent_str;
+      stream << "gengetopt_strdup (const char *s)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *result = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (!s)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return result;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  result = (char*)malloc(strlen(s) + 1);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (result == (char*)0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return (char*)0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  strcpy(result, s);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return result;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (multiple_token_functions)
+    {
+      stream << "static char *";
+      stream << "\n";
+      stream << indent_str;
+      stream << "get_multiple_arg_token(const char *arg)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  const char *tok;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *ret;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  size_t len, num_of_escape, i, j;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (!arg)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  tok = strchr (arg, ',');";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  num_of_escape = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  /* make sure it is not escaped */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while (tok)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (*(tok-1) == '\\\\')";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          /* find the next one */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          tok = strchr (tok+1, ',');";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          ++num_of_escape;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (tok)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    len = (size_t)(tok - arg + 1);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    len = strlen (arg) + 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  len -= num_of_escape;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  ret = (char *) malloc (len);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  i = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  j = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while (arg[i] && (j < len-1))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (arg[i] == '\\\\' && ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        arg[ i + 1 ] && ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        arg[ i + 1 ] == ',')";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        ++i;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      ret[j++] = arg[i++];";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  ret[len-1] = '\\0';";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return ret;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "static const char *";
+      stream << "\n";
+      stream << indent_str;
+      stream << "get_multiple_arg_token_next(const char *arg)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  const char *tok;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (!arg)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  tok = strchr (arg, ',');";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  /* make sure it is not escaped */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while (tok)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (*(tok-1) == '\\\\')";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          /* find the next one */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          tok = strchr (tok+1, ',');";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (! tok || strlen(tok) == 1)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return tok+1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (multiple_options)
+    {
+      stream << "static int";
+      stream << "\n";
+      stream << indent_str;
+      stream << "check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "int";
+      stream << "\n";
+      stream << indent_str;
+      stream << "check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int error = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (option_given && (min > 0 || max > 0))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (min > 0 && max > 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          if (min == max)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              /* specific occurrences */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              if (option_given != (unsigned int) min)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                  fprintf (stderr, \"%s: %s option occurrences must be %d\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                    prog_name, option_desc, min);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                  error = 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          else if (option_given < (unsigned int) min";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                || option_given > (unsigned int) max)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              /* range occurrences */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              fprintf (stderr, \"%s: %s option occurrences must be between %d and %d\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                prog_name, option_desc, min, max);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              error = 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      else if (min > 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          /* at least check */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          if (option_given < min)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              fprintf (stderr, \"%s: %s option occurrences must be at least %d\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                prog_name, option_desc, min);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              error = 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      else if (max > 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          /* at most check */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          if (option_given > max)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              fprintf (stderr, \"%s: %s option occurrences must be at most %d\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                prog_name, option_desc, max);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              error = 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      indent = 4;
+      stream << "    ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return error;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (reset_groups.size () > 0)
+    generate_string (reset_groups, stream, indent + indent_str.length ());
+  else
+    generate_reset_groups (stream, indent + indent_str.length ());
+  stream << indent_str;
+  stream << "int";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << " (int argc, char **argv, struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "2 (argc, argv, args_info, 0, 1, 1);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "int";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_ext (int argc, char **argv, struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                   struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *params)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int result;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  result = ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_internal (argc, argv, args_info, params, 0);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (final_exit, stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "int";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "2 (int argc, char **argv, struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info, int override, int initialize, int check_required)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int result;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params params;";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  params.override = override;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  params.initialize = initialize;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  params.check_required = check_required;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  params.check_ambiguity = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  params.print_errors = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  result = ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_internal (argc, argv, args_info, &params, 0);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (final_exit, stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "int";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_required (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info, const char *prog_name)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  if (check_required_options)
+    {
+      stream << "  int result = EXIT_SUCCESS;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_required2(args_info, prog_name, 0) > 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    result = EXIT_FAILURE;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      generate_string (final_exit, stream, indent + indent_str.length ());
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "  FIX_UNUSED (args_info);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  FIX_UNUSED (prog_name);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return EXIT_SUCCESS;";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (check_required_options)
+    {
+      stream << "int";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_required2 (struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info, const char *prog_name, const char *additional_error)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int error = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  FIX_UNUSED (additional_error);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  /* checks for required options */";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      if (handle_required.size () > 0)
+        generate_string (handle_required, stream, indent + indent_str.length ());
+      else
+        generate_handle_required (stream, indent + indent_str.length ());
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  /* checks for dependences among options */";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      if (handle_dependencies.size () > 0)
+        generate_string (handle_dependencies, stream, indent + indent_str.length ());
+      else
+        generate_handle_dependencies (stream, indent + indent_str.length ());
+      indent = 0;
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return error;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (include_getopt)
+    {
+      if (custom_getopt.size () > 0)
+        generate_string (custom_getopt, stream, indent + indent_str.length ());
+      else
+        generate_custom_getopt (stream, indent + indent_str.length ());
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "static char *package_name = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (( ! no_options ))
+    {
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "brief updates an option";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param field the generic pointer to the field to update";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param orig_field the pointer to the orig field";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param field_given the pointer to the number of occurrence of this option";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param prev_given the pointer to the number of occurrence already seen";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param value the argument for this option (if null no arg was specified)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param possible_values the possible values for this option (if specified)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param default_value the default value (in case the option only accepts fixed values)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param arg_type the type of this option";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param check_ambiguity ";
+      stream << "@";
+      stream << "see ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_params.check_ambiguity";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param override ";
+      stream << "@";
+      stream << "see ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_params.override";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param no_free whether to free a possible previous value";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param multiple_option whether this is a multiple option";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param long_opt the corresponding long option";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param short_opt the corresponding short option (or '-' if none)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param additional_error possible further error specification";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "static";
+      stream << "\n";
+      stream << indent_str;
+      stream << "int update_arg(void *field, char **orig_field,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               unsigned int *field_given, unsigned int *prev_given, ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               char *value, const char *possible_values[],";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               const char *default_value,";
+      stream << "\n";
+      stream << indent_str;
+      indent = 15;
+      stream << "               ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_arg_type arg_type,";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "               int check_ambiguity, int override,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               int no_free, int multiple_option,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               const char *long_opt, char short_opt,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               const char *additional_error)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *stop_char = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  const char *val = value;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int found;";
+      stream << "\n";
+      stream << indent_str;
+      if (has_arg_string)
+        {
+          stream << "  char **string_field;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "  FIX_UNUSED (field);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  stop_char = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  found = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (short_opt != '-')";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        fprintf (stderr, \"%s: `--%s' (`-%c') option given more than once%s\\n\", ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               package_name, long_opt, short_opt,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               (additional_error ? additional_error : \"\"));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        fprintf (stderr, \"%s: `--%s' option given more than once%s\\n\", ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               package_name, long_opt,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               (additional_error ? additional_error : \"\"));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      return 1; /* failure */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      if (check_possible_values)
+        {
+          stream << "  if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      if (short_opt != '-')";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        fprintf (stderr, \"%s: %s argument, \\\"%s\\\", for option `--%s' (`-%c')%s\\n\", ";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          package_name, (found == -2) ? \"ambiguous\" : \"invalid\", value, long_opt, short_opt,";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (additional_error ? additional_error : \"\"));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      else";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        fprintf (stderr, \"%s: %s argument, \\\"%s\\\", for option `--%s'%s\\n\", ";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          package_name, (found == -2) ? \"ambiguous\" : \"invalid\", value, long_opt,";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (additional_error ? additional_error : \"\"));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      return 1; /* failure */";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    }";
+          stream << "\n";
+          stream << indent_str;
+        }
+      else
+        {
+          stream << "  FIX_UNUSED (default_value);";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "    ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (field_given && *field_given && ! override)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (prev_given)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    (*prev_given)++;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (field_given)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    (*field_given)++;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (possible_values)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    val = possible_values[found];";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  switch(arg_type) {";
+      stream << "\n";
+      stream << indent_str;
+      if (has_arg_flag)
+        {
+          stream << "  case ARG_FLAG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    *((int *)field) = !*((int *)field);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_int)
+        {
+          stream << "  case ARG_INT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((int *)field) = strtol (val, &stop_char, 0);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_short)
+        {
+          stream << "  case ARG_SHORT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((short *)field) = (short)strtol (val, &stop_char, 0);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_long)
+        {
+          stream << "  case ARG_LONG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((long *)field) = (long)strtol (val, &stop_char, 0);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_float)
+        {
+          stream << "  case ARG_FLOAT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((float *)field) = (float)strtod (val, &stop_char);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_double)
+        {
+          stream << "  case ARG_DOUBLE:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((double *)field) = strtod (val, &stop_char);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longdouble)
+        {
+          stream << "  case ARG_LONGDOUBLE:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((long double *)field) = (long double)strtod (val, &stop_char);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longlong)
+        {
+          stream << "  case ARG_LONGLONG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#ifdef HAVE_LONG_LONG";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((long long int*)field) = (long long int) strtol (val, &stop_char, 0);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#else";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((long *)field) = (long)strtol (val, &stop_char, 0);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#endif";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_enum)
+        {
+          stream << "  case ARG_ENUM:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) *((int *)field) = found;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_string)
+        {
+          stream << "  case ARG_STRING:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    if (val) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      string_field = (char **)field;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      if (!no_free && *string_field)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        free (*string_field); /* free previous string */";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *string_field = gengetopt_strdup (val);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "  default:";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  };";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      if (( ( ( ( ( ( has_arg_int || has_arg_short ) || has_arg_long ) || has_arg_float ) || has_arg_double ) || has_arg_longdouble ) || has_arg_longlong ))
+        {
+          stream << "  /* check numeric conversion */";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  switch(arg_type) {";
+          stream << "\n";
+          stream << indent_str;
+          if (has_arg_int)
+            {
+              stream << "  case ARG_INT:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          if (has_arg_short)
+            {
+              stream << "  case ARG_SHORT:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          if (has_arg_long)
+            {
+              stream << "  case ARG_LONG:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          if (has_arg_float)
+            {
+              stream << "  case ARG_FLOAT:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          if (has_arg_double)
+            {
+              stream << "  case ARG_DOUBLE:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          if (has_arg_longdouble)
+            {
+              stream << "  case ARG_LONGDOUBLE:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          if (has_arg_longlong)
+            {
+              stream << "  case ARG_LONGLONG:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          stream << "    if (val && !(stop_char && *stop_char == '\\0')) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      fprintf(stderr, \"%s: invalid numeric value: %s\\n\", package_name, val);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      return 1; /* failure */";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    break;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  default:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    ;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  };";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "\n";
+      stream << indent_str;
+      stream << "  /* store the original value */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  switch(arg_type) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  case ARG_NO:";
+      stream << "\n";
+      stream << indent_str;
+      if (has_arg_flag)
+        {
+          stream << "  case ARG_FLAG:";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "    break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  default:";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    if (value && orig_field) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (no_free) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        *orig_field = value;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      } else {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        if (*orig_field)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          free (*orig_field); /* free previous string */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        *orig_field = gengetopt_strdup (value);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  };";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return 0; /* OK */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  if (multiple_token_functions)
+    {
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "brief store information about a multiple option in a temporary list";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param list where to (temporarily) store multiple options";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "static";
+      stream << "\n";
+      stream << indent_str;
+      stream << "int update_multiple_arg_temp(struct generic_list **list,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               unsigned int *prev_given, const char *val,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               const char *possible_values[], const char *default_value,";
+      stream << "\n";
+      stream << indent_str;
+      indent = 15;
+      stream << "               ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_arg_type arg_type,";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "               const char *long_opt, char short_opt,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               const char *additional_error)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  /* store single arguments */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *multi_token;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  const char *multi_next;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (arg_type == ARG_NO) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    (*prev_given)++;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    return 0; /* OK */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  multi_token = get_multiple_arg_token(val);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  multi_next = get_multiple_arg_token_next (val);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while (1)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      add_node (list);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          prev_given, multi_token, possible_values, default_value, ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        if (multi_token) free(multi_token);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        return 1; /* failure */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (multi_next)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          multi_token = get_multiple_arg_token(multi_next);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          multi_next = get_multiple_arg_token_next (multi_next);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return 0; /* OK */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "brief free the passed list (including possible string argument)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "static";
+      stream << "\n";
+      stream << indent_str;
+      stream << "void free_list(struct generic_list *list, short string_arg)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (list) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    struct generic_list *tmp;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    while (list)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        tmp = list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        if (string_arg && list->arg.string_arg)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          free (list->arg.string_arg);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        if (list->orig)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          free (list->orig);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        list = list->next;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        free (tmp);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "brief updates a multiple option starting from the passed list";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "static";
+      stream << "\n";
+      stream << indent_str;
+      stream << "void update_multiple_arg(void *field, char ***orig_field,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "               unsigned int field_given, unsigned int prev_given, union generic_value *default_value,";
+      stream << "\n";
+      stream << indent_str;
+      indent = 15;
+      stream << "               ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_arg_type arg_type,";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "               struct generic_list *list)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int i;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct generic_list *tmp;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (prev_given && list) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    switch(arg_type) {";
+      stream << "\n";
+      stream << indent_str;
+      if (( has_arg_int || has_arg_enum ))
+        {
+          if (has_arg_int)
+            {
+              stream << "    case ARG_INT:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          if (has_arg_enum)
+            {
+              stream << "    case ARG_ENUM:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          stream << "      *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_short)
+        {
+          stream << "    case ARG_SHORT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *((short **)field) = (short *)realloc (*((short **)field), (field_given + prev_given) * sizeof (short)); break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_long)
+        {
+          stream << "    case ARG_LONG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *((long **)field) = (long *)realloc (*((long **)field), (field_given + prev_given) * sizeof (long)); break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_float)
+        {
+          stream << "    case ARG_FLOAT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *((float **)field) = (float *)realloc (*((float **)field), (field_given + prev_given) * sizeof (float)); break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_double)
+        {
+          stream << "    case ARG_DOUBLE:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *((double **)field) = (double *)realloc (*((double **)field), (field_given + prev_given) * sizeof (double)); break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longdouble)
+        {
+          stream << "    case ARG_LONGDOUBLE:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *((long double **)field) = (long double *)realloc (*((long double **)field), (field_given + prev_given) * sizeof (long double)); break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longlong)
+        {
+          stream << "    case ARG_LONGLONG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#ifdef HAVE_LONG_LONG";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *((long long int **)field) = (long long int *)realloc (*((long long int **)field), (field_given + prev_given) * sizeof (long long int)); break;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#else";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *((long **)field) = (long *)realloc (*((long **)field), (field_given + prev_given) * sizeof (long)); break;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#endif";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_string)
+        {
+          stream << "    case ARG_STRING:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "    default:";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    };";
+      stream << "\n";
+      stream << indent_str;
+      indent = 4;
+      stream << "    ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    for (i = (prev_given - 1); i >= 0; --i)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        tmp = list;";
+      stream << "\n";
+      stream << indent_str;
+      indent = 8;
+      stream << "        ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "        switch(arg_type) {";
+      stream << "\n";
+      stream << indent_str;
+      if (has_arg_int)
+        {
+          stream << "        case ARG_INT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((int **)field))[i + field_given] = tmp->arg.int_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_short)
+        {
+          stream << "        case ARG_SHORT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((short **)field))[i + field_given] = tmp->arg.short_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_long)
+        {
+          stream << "        case ARG_LONG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((long **)field))[i + field_given] = tmp->arg.long_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_float)
+        {
+          stream << "        case ARG_FLOAT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((float **)field))[i + field_given] = tmp->arg.float_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_double)
+        {
+          stream << "        case ARG_DOUBLE:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((double **)field))[i + field_given] = tmp->arg.double_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longdouble)
+        {
+          stream << "        case ARG_LONGDOUBLE:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((long double **)field))[i + field_given] = tmp->arg.longdouble_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longlong)
+        {
+          stream << "        case ARG_LONGLONG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#ifdef HAVE_LONG_LONG";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((long long int **)field))[i + field_given] = tmp->arg.longlong_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#else";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((long **)field))[i + field_given] = tmp->arg.longlong_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#endif";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_enum)
+        {
+          stream << "        case ARG_ENUM:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((int **)field))[i + field_given] = tmp->arg.int_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_string)
+        {
+          stream << "        case ARG_STRING:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "        default:";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }        ";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        (*orig_field) [i + field_given] = list->orig;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        list = list->next;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        free (tmp);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  } else { /* set the default value */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    if (default_value && ! field_given) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      switch(arg_type) {";
+      stream << "\n";
+      stream << indent_str;
+      if (( has_arg_int || has_arg_enum ))
+        {
+          if (has_arg_int)
+            {
+              stream << "      case ARG_INT:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          if (has_arg_enum)
+            {
+              stream << "      case ARG_ENUM:";
+              stream << "\n";
+              stream << indent_str;
+            }
+          stream << "        if (! *((int **)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((int **)field) = (int *)malloc (sizeof (int));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((int **)field))[0] = default_value->int_arg; ";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_short)
+        {
+          stream << "      case ARG_SHORT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (! *((short **)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((short **)field) = (short *)malloc (sizeof (short));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((short **)field))[0] = default_value->short_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_long)
+        {
+          stream << "      case ARG_LONG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (! *((long **)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((long **)field) = (long *)malloc (sizeof (long));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((long **)field))[0] = default_value->long_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_float)
+        {
+          stream << "      case ARG_FLOAT:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (! *((float **)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((float **)field) = (float *)malloc (sizeof (float));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((float **)field))[0] = default_value->float_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_double)
+        {
+          stream << "      case ARG_DOUBLE:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (! *((double **)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((double **)field) = (double *)malloc (sizeof (double));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((double **)field))[0] = default_value->double_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longdouble)
+        {
+          stream << "      case ARG_LONGDOUBLE:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (! *((long double **)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((long double **)field) = (long double *)malloc (sizeof (long double));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((long double **)field))[0] = default_value->longdouble_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_longlong)
+        {
+          stream << "      case ARG_LONGLONG:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#ifdef HAVE_LONG_LONG";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (! *((long long int **)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((long long int **)field) = (long long int *)malloc (sizeof (long long int));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((long long int **)field))[0] = default_value->longlong_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#else";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (! *((long **)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((long **)field) = (long *)malloc (sizeof (long));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((long **)field))[0] = default_value->longlong_arg;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "#endif";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (has_arg_string)
+        {
+          stream << "      case ARG_STRING:";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (! *((char ***)field)) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          *((char ***)field) = (char **)malloc (sizeof (char *));";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        break;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "      default: break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (!(*orig_field)) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        *orig_field = (char **) malloc (sizeof (char *));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        (*orig_field)[0] = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_modes)
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "static int check_modes(";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int given1[], const char *options1[],";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                       int given2[], const char *options2[])";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int i = 0, j = 0, errors = 0;";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while (given1[i] >= 0) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    if (given1[i]) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      while (given2[j] >= 0) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        if (given2[j]) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          ++errors;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          fprintf(stderr, \"%s: option %s conflicts with option %s\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                  package_name, options1[i], options2[j]);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        ++j;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    ++i;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  }";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return errors;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "int";
+  stream << "\n";
+  stream << indent_str;
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_internal (";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int argc, char **argv, struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                        struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *params, const char *additional_error)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int c;  /* Character of the parsed option.  */";
+  stream << "\n";
+  stream << indent_str;
+  if (multiple_options_with_default)
+    {
+      stream << "  union generic_value multiple_default_value;";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  if (list_def.size () > 0)
+    generate_string (list_def, stream, indent + indent_str.length ());
+  else
+    generate_list_def (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  stream << "  int error = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " local_args_info;";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int override;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int initialize;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int check_required;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int check_ambiguity;";
+  stream << "\n";
+  stream << indent_str;
+  if (include_getopt)
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *optarg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int optind;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int opterr;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int optopt;";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "  ";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  package_name = argv[0];";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  override = params->override;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  initialize = params->initialize;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  check_required = params->check_required;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  check_ambiguity = params->check_ambiguity;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (initialize)";
+  stream << "\n";
+  stream << indent_str;
+  indent = 4;
+  stream << "    ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_init (args_info);";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_init (&local_args_info);";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  optarg = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  optind = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  opterr = params->print_errors;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  optopt = '?';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  while (1)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      int option_index = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "      static struct option long_options[] = {";
+  stream << "\n";
+  stream << indent_str;
+  indent = 8;
+  if (long_option_struct.size () > 0)
+    generate_string (long_option_struct, stream, indent + indent_str.length ());
+  else
+    generate_long_option_struct (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  stream << "        { 0,  0, 0, 0 }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "      };";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (include_getopt)
+    {
+      stream << "      custom_optarg = optarg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      custom_optind = optind;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      custom_opterr = opterr;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      custom_optopt = optopt;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      c = custom_getopt_long (argc, argv, \"";
+      generate_string (getopt_string, stream, indent + indent_str.length ());
+      stream << "\", long_options, &option_index);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      optarg = custom_optarg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      optind = custom_optind;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      opterr = custom_opterr;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      optopt = custom_optopt;";
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "      c = getopt_long (argc, argv, \"";
+      generate_string (getopt_string, stream, indent + indent_str.length ());
+      stream << "\", long_options, &option_index);";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "      if (c == -1) break; /* Exit from `while (1)' loop.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "      switch (c)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "        {";
+  stream << "\n";
+  stream << indent_str;
+  indent = 8;
+  if (handle_option.size () > 0)
+    generate_string (handle_option, stream, indent + indent_str.length ());
+  else
+    generate_handle_option (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "        case 0:   /* Long option with no short option */";
+  stream << "\n";
+  stream << indent_str;
+  indent = 10;
+  if (handle_no_short_option.size () > 0)
+    generate_string (handle_no_short_option, stream, indent + indent_str.length ());
+  else
+    generate_handle_no_short_option (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  if (handle_question_mark)
+    {
+      stream << "        case '?':     /* Invalid option.  */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          /* `getopt_long' already printed an error message.  */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          goto failure;";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "        default:  /* bug: option not considered.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          fprintf (stderr, \"%s: option unknown: %c%s\\n\", ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << ", c, (additional_error ? additional_error : \"\"));";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          abort ();";
+  stream << "\n";
+  stream << indent_str;
+  stream << "        } /* switch */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    } /* while */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  if (handle_group.size () > 0)
+    generate_string (handle_group, stream, indent + indent_str.length ());
+  else
+    generate_handle_group (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  if (multiple_fill_array.size () > 0)
+    generate_string (multiple_fill_array, stream, indent + indent_str.length ());
+  else
+    generate_multiple_fill_array (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  indent = 2;
+  if (update_multiple_given.size () > 0)
+    generate_string (update_multiple_given, stream, indent + indent_str.length ());
+  else
+    generate_update_multiple_given (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  indent = 2;
+  if (check_modes.size () > 0)
+    generate_string (check_modes, stream, indent + indent_str.length ());
+  else
+    generate_check_modes (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (check_required_options)
+    {
+      stream << "  if (check_required)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      error += ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_required2 (args_info, argv[0], additional_error);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_release (&local_args_info);";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if ( error )";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    return (EXIT_FAILURE);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (handle_unamed)
+    {
+      stream << "  if (optind < argc)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      int i = 0 ;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      int found_prog_name = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* whether program name, i.e., argv[0], is in the remaining args";
+      stream << "\n";
+      stream << indent_str;
+      stream << "         (this may happen with some implementations of getopt,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          but surely not with the one included by gengetopt) */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      if (include_getopt)
+        {
+          
+      
+        }
+      else
+        {
+          stream << "      i = optind;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      while (i < argc)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        if (argv[i++] == argv[0]) {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          found_prog_name = 1;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          break;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "        }";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      i = 0;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "\n";
+      stream << indent_str;
+      stream << "      args_info->inputs_num = argc - optind - found_prog_name;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      args_info->inputs =";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      while (optind < argc)";
+      stream << "\n";
+      stream << indent_str;
+      if (include_getopt)
+        {
+          stream << "        args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      else
+        {
+          stream << "        if (argv[optind++] != argv[0])";
+          stream << "\n";
+          stream << indent_str;
+          stream << "          args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "  return 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "failure:";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  if (list_free.size () > 0)
+    generate_string (list_free, stream, indent + indent_str.length ());
+  else
+    generate_list_free (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_release (&local_args_info);";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return (EXIT_FAILURE);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  if (conf_parser)
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "#ifndef CONFIG_FILE_LINE_SIZE";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#define CONFIG_FILE_LINE_SIZE 2048";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#endif";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#define ADDITIONAL_ERROR \" in configuration file \"";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "#define CONFIG_FILE_LINE_BUFFER_SIZE (CONFIG_FILE_LINE_SIZE+3)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "/* 3 is for \"--\" and \"=\" */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "static int";
+      stream << "\n";
+      stream << indent_str;
+      stream << "_";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_configfile (const char *filename, int *my_argc)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  FILE* file;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char my_argv[CONFIG_FILE_LINE_BUFFER_SIZE+1];";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char linebuf[CONFIG_FILE_LINE_SIZE];";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int line_num = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int result = 0, equal;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *fopt, *farg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *str_index;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  size_t len, next_token;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char delimiter;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if ((file = fopen(filename, \"r\")) == 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      fprintf (stderr, \"%s: Error opening configuration file '%s'\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      indent = 15;
+      stream << "               ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << ", filename);";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      return EXIT_FAILURE;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while ((fgets(linebuf, CONFIG_FILE_LINE_SIZE, file)) != 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      ++line_num;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      my_argv[0] = '\\0';";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      len = strlen(linebuf);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (len > (CONFIG_FILE_LINE_BUFFER_SIZE-1))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          fprintf (stderr, \"%s:%s:%d: Line too long in configuration file\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      indent = 19;
+      stream << "                   ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << ", filename, line_num);";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "          result = EXIT_FAILURE;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* find first non-whitespace character in the line */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      next_token = strspn (linebuf, \" \\t\\r\\n\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      str_index  = linebuf + next_token;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if ( str_index[0] == '\\0' || str_index[0] == '#')";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        continue; /* empty line or comment line is skipped */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      fopt = str_index;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* truncate fopt at the end of the first non-valid character */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      next_token = strcspn (fopt, \" \\t\\r\\n=\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (fopt[next_token] == '\\0') /* the line is over */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          farg  = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          equal = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          goto noarg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* remember if equal sign is present */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      equal = (fopt[next_token] == '=');";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      fopt[next_token++] = '\\0';";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* advance pointers to the next token after the end of fopt */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      next_token += strspn (fopt + next_token, \" \\t\\r\\n\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* check for the presence of equal sign, and if so, skip it */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if ( !equal )";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        if ((equal = (fopt[next_token] == '=')))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            next_token++;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            next_token += strspn (fopt + next_token, \" \\t\\r\\n\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      str_index  += next_token;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* find argument */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      farg = str_index;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if ( farg[0] == '\\\"' || farg[0] == '\\'' )";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        { /* quoted argument */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          str_index = strchr (++farg, str_index[0] ); /* skip opening quote */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          if (! str_index)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              fprintf";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                (stderr,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                 \"%s:%s:%d: unterminated string in configuration file\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      indent = 17;
+      stream << "                 ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << ", filename, line_num);";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "              result = EXIT_FAILURE;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        { /* read up the remaining part up to a delimiter */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          next_token = strcspn (farg, \" \\t\\r\\n#\\'\\\"\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          str_index += next_token;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* truncate farg at the delimiter and store it for further check */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      delimiter = *str_index, *str_index++ = '\\0';";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      /* everything but comment is illegal at the end of line */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (delimiter != '\\0' && delimiter != '#')";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          str_index += strspn(str_index, \" \\t\\r\\n\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          if (*str_index != '\\0' && *str_index != '#')";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              fprintf";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                (stderr,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                 \"%s:%s:%d: malformed string in configuration file\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      indent = 17;
+      stream << "                 ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << ", filename, line_num);";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "              result = EXIT_FAILURE;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "              break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "            }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    noarg:";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (!strcmp(fopt,\"include\")) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        if (farg && *farg) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          result = _";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_configfile(farg, my_argc);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        } else {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          fprintf(stderr, \"%s:%s:%d: include requires a filename argument.\\n\",";
+      stream << "\n";
+      stream << indent_str;
+      indent = 18;
+      stream << "                  ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << ", filename, line_num);";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        continue;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      len = strlen(fopt);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      strcat (my_argv, len > 1 ? \"--\" : \"-\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      strcat (my_argv, fopt);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (len > 1 && ((farg && *farg) || equal))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        strcat (my_argv, \"=\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (farg && *farg)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        strcat (my_argv, farg);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      ++(*my_argc);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "      cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      cmd_line_list_tmp->next = cmd_line_list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      cmd_line_list = cmd_line_list_tmp;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      cmd_line_list->string_arg = gengetopt_strdup(my_argv);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    } /* while */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (file)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    fclose(file);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return result;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "int";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_configfile (";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  const char *filename,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                           struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                           int override, int initialize, int check_required)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_params params;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.override = override;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.initialize = initialize;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.check_required = check_required;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.check_ambiguity = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.print_errors = 1;";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_config_file (filename, args_info, &params);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "int";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_config_file (const char *filename,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                           struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                           struct ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_params *params)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int i, result;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int my_argc = 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char **my_argv_arg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *additional_error;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  /* store the program name */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  cmd_line_list_tmp->next = cmd_line_list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  cmd_line_list = cmd_line_list_tmp;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  cmd_line_list->string_arg = gengetopt_strdup (";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << ");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  result = _";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_configfile(filename, &my_argc);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (result != EXIT_FAILURE) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    my_argv_arg = (char **) malloc((my_argc+1) * sizeof(char *));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    cmd_line_list_tmp = cmd_line_list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    for (i = my_argc - 1; i >= 0; --i) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      my_argv_arg[i] = cmd_line_list_tmp->string_arg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      cmd_line_list_tmp = cmd_line_list_tmp->next;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    my_argv_arg[my_argc] = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    additional_error = (char *)malloc(strlen(filename) + strlen(ADDITIONAL_ERROR) + 1);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    strcpy (additional_error, ADDITIONAL_ERROR);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    strcat (additional_error, filename);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    result =";
+      stream << "\n";
+      stream << indent_str;
+      indent = 6;
+      stream << "      ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_internal (my_argc, my_argv_arg, args_info,";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "                              params,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "                              additional_error);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    free (additional_error);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    free (my_argv_arg);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  free_cmd_list();";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      generate_string (final_exit, stream, indent + indent_str.length ());
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (generate_string_parser)
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "static unsigned int";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_create_argv(const char *cmdline_, char ***argv_ptr, const char *prog_name)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char *cmdline, *p;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  size_t n = 0, j;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int i;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (prog_name) {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    cmd_line_list_tmp->next = cmd_line_list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    cmd_line_list = cmd_line_list_tmp;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    cmd_line_list->string_arg = gengetopt_strdup (prog_name);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    ++n;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  cmdline = gengetopt_strdup(cmdline_);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  p = cmdline;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  while (p && strlen(p))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      j = strcspn(p, \" \\t\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      ++n;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      if (j && j < strlen(p))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          p[j] = '\\0';";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "          cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          cmd_line_list_tmp->next = cmd_line_list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          cmd_line_list = cmd_line_list_tmp;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          cmd_line_list->string_arg = gengetopt_strdup (p);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "          p += (j+1);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          p += strspn(p, \" \\t\");";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          cmd_line_list_tmp->next = cmd_line_list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          cmd_line_list = cmd_line_list_tmp;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "          cmd_line_list->string_arg = gengetopt_strdup (p);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "          break;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "        }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  *argv_ptr = (char **) malloc((n + 1) * sizeof(char *));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  cmd_line_list_tmp = cmd_line_list;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  for (i = (n-1); i >= 0; --i)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      (*argv_ptr)[i] = cmd_line_list_tmp->string_arg;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      cmd_line_list_tmp = cmd_line_list_tmp->next;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  (*argv_ptr)[n] = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  free(cmdline);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return n;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "int";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string(const char *cmdline, struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info, const char *prog_name)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string2(cmdline, args_info, prog_name, 0, 1, 1);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "int";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string2(const char *cmdline, struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info, const char *prog_name,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    int override, int initialize, int check_required)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_params params;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.override = override;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.initialize = initialize;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.check_required = check_required;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.check_ambiguity = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  params.print_errors = 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  return ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string_ext(cmdline, args_info, prog_name, &params);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "int";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string_ext(const char *cmdline, struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info, const char *prog_name,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    struct ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_params *params)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  char **argv_ptr = 0;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int result;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  unsigned int argc;";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  argc = ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_create_argv(cmdline, &argv_ptr, prog_name);";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  result =";
+      stream << "\n";
+      stream << indent_str;
+      indent = 4;
+      stream << "    ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_internal (argc, argv_ptr, args_info, params, 0);";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  if (argv_ptr)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "      free (argv_ptr);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "  free_cmd_list();";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      generate_string (final_exit, stream, indent + indent_str.length ());
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/c_source.h b/cmake/gengetopt/skels/c_source.h
new file mode 100644 (file)
index 0000000..abeb115
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef C_SOURCE_GEN_CLASS_H
+#define C_SOURCE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class c_source_gen_class
+{
+ protected:
+  string args_info;
+  string check_modes;
+  bool check_possible_values;
+  bool check_required_options;
+  string clear_arg;
+  bool cmd_list;
+  string command_line;
+  bool conf_parser;
+  string custom_getopt;
+  string description;
+  string detailed_help_option_print;
+  bool do_generate_strdup;
+  string file_save_loop;
+  string final_exit;
+  string free;
+  string full_help_option_print;
+  bool generate_string_parser;
+  string generator_version;
+  string getopt_string;
+  string given_init;
+  string handle_dependencies;
+  string handle_group;
+  string handle_no_short_option;
+  string handle_option;
+  bool handle_question_mark;
+  string handle_required;
+  bool handle_unamed;
+  bool has_arg_double;
+  bool has_arg_enum;
+  bool has_arg_flag;
+  bool has_arg_float;
+  bool has_arg_int;
+  bool has_arg_long;
+  bool has_arg_longdouble;
+  bool has_arg_longlong;
+  bool has_arg_short;
+  bool has_arg_string;
+  bool has_details;
+  bool has_hidden;
+  bool has_modes;
+  bool has_typed_options;
+  string header_file_ext;
+  string help_option_print;
+  string help_string_num;
+  bool include_getopt;
+  string init_args_info;
+  string list_def;
+  string list_free;
+  string long_option_struct;
+  string multiple_fill_array;
+  bool multiple_options;
+  bool multiple_options_all_string;
+  bool multiple_options_string;
+  bool multiple_options_with_default;
+  bool multiple_token_functions;
+  bool no_options;
+  bool no_package;
+  string option_values;
+  string package_var_name;
+  string parser_name;
+  string purpose;
+  string reset_groups;
+  string source_name;
+  string update_multiple_given;
+  string usage_string;
+  string version_var_name;
+
+ public:
+  c_source_gen_class() :
+    check_possible_values (false), check_required_options (false), cmd_list (false), conf_parser (false), do_generate_strdup (false), generate_string_parser (false), handle_question_mark (false), handle_unamed (false), has_arg_double (false), has_arg_enum (false), has_arg_flag (false), has_arg_float (false), has_arg_int (false), has_arg_long (false), has_arg_longdouble (false), has_arg_longlong (false), has_arg_short (false), has_arg_string (false), has_details (false), has_hidden (false), has_modes (false), has_typed_options (false), include_getopt (false), multiple_options (false), multiple_options_all_string (false), multiple_options_string (false), multiple_options_with_default (false), multiple_token_functions (false), no_options (false), no_package (false)
+  {
+  }
+  
+  c_source_gen_class(const string &_args_info, const string &_check_modes, bool _check_possible_values, bool _check_required_options, const string &_clear_arg, bool _cmd_list, const string &_command_line, bool _conf_parser, const string &_custom_getopt, const string &_description, const string &_detailed_help_option_print, bool _do_generate_strdup, const string &_file_save_loop, const string &_final_exit, const string &_free, const string &_full_help_option_print, bool _generate_string_parser, const string &_generator_version, const string &_getopt_string, const string &_given_init, const string &_handle_dependencies, const string &_handle_group, const string &_handle_no_short_option, const string &_handle_option, bool _handle_question_mark, const string &_handle_required, bool _handle_unamed, bool _has_arg_double, bool _has_arg_enum, bool _has_arg_flag, bool _has_arg_float, bool _has_arg_int, bool _has_arg_long, bool _has_arg_longdouble, bool _has_arg_longlong, bool _has_arg_short, bool _has_arg_string, bool _has_details, bool _has_hidden, bool _has_modes, bool _has_typed_options, const string &_header_file_ext, const string &_help_option_print, const string &_help_string_num, bool _include_getopt, const string &_init_args_info, const string &_list_def, const string &_list_free, const string &_long_option_struct, const string &_multiple_fill_array, bool _multiple_options, bool _multiple_options_all_string, bool _multiple_options_string, bool _multiple_options_with_default, bool _multiple_token_functions, bool _no_options, bool _no_package, const string &_option_values, const string &_package_var_name, const string &_parser_name, const string &_purpose, const string &_reset_groups, const string &_source_name, const string &_update_multiple_given, const string &_usage_string, const string &_version_var_name) :
+    args_info (_args_info), check_modes (_check_modes), check_possible_values (_check_possible_values), check_required_options (_check_required_options), clear_arg (_clear_arg), cmd_list (_cmd_list), command_line (_command_line), conf_parser (_conf_parser), custom_getopt (_custom_getopt), description (_description), detailed_help_option_print (_detailed_help_option_print), do_generate_strdup (_do_generate_strdup), file_save_loop (_file_save_loop), final_exit (_final_exit), free (_free), full_help_option_print (_full_help_option_print), generate_string_parser (_generate_string_parser), generator_version (_generator_version), getopt_string (_getopt_string), given_init (_given_init), handle_dependencies (_handle_dependencies), handle_group (_handle_group), handle_no_short_option (_handle_no_short_option), handle_option (_handle_option), handle_question_mark (_handle_question_mark), handle_required (_handle_required), handle_unamed (_handle_unamed), has_arg_double (_has_arg_double), has_arg_enum (_has_arg_enum), has_arg_flag (_has_arg_flag), has_arg_float (_has_arg_float), has_arg_int (_has_arg_int), has_arg_long (_has_arg_long), has_arg_longdouble (_has_arg_longdouble), has_arg_longlong (_has_arg_longlong), has_arg_short (_has_arg_short), has_arg_string (_has_arg_string), has_details (_has_details), has_hidden (_has_hidden), has_modes (_has_modes), has_typed_options (_has_typed_options), header_file_ext (_header_file_ext), help_option_print (_help_option_print), help_string_num (_help_string_num), include_getopt (_include_getopt), init_args_info (_init_args_info), list_def (_list_def), list_free (_list_free), long_option_struct (_long_option_struct), multiple_fill_array (_multiple_fill_array), multiple_options (_multiple_options), multiple_options_all_string (_multiple_options_all_string), multiple_options_string (_multiple_options_string), multiple_options_with_default (_multiple_options_with_default), multiple_token_functions (_multiple_token_functions), no_options (_no_options), no_package (_no_package), option_values (_option_values), package_var_name (_package_var_name), parser_name (_parser_name), purpose (_purpose), reset_groups (_reset_groups), source_name (_source_name), update_multiple_given (_update_multiple_given), usage_string (_usage_string), version_var_name (_version_var_name)
+  {
+  }
+
+  virtual ~c_source_gen_class()
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_args_info(const string &_args_info)
+  {
+    args_info = _args_info;
+  }
+
+  virtual void generate_check_modes(ostream &stream, unsigned int indent) = 0;
+
+  void set_check_modes(const string &_check_modes)
+  {
+    check_modes = _check_modes;
+  }
+
+  void set_check_possible_values(bool _check_possible_values)
+  {
+    check_possible_values = _check_possible_values;
+  }
+
+  void set_check_required_options(bool _check_required_options)
+  {
+    check_required_options = _check_required_options;
+  }
+
+  virtual void generate_clear_arg(ostream &stream, unsigned int indent) = 0;
+
+  void set_clear_arg(const string &_clear_arg)
+  {
+    clear_arg = _clear_arg;
+  }
+
+  void set_cmd_list(bool _cmd_list)
+  {
+    cmd_list = _cmd_list;
+  }
+
+  void set_command_line(const string &_command_line)
+  {
+    command_line = _command_line;
+  }
+
+  void set_conf_parser(bool _conf_parser)
+  {
+    conf_parser = _conf_parser;
+  }
+
+  virtual void generate_custom_getopt(ostream &stream, unsigned int indent) = 0;
+
+  void set_custom_getopt(const string &_custom_getopt)
+  {
+    custom_getopt = _custom_getopt;
+  }
+
+  void set_description(const string &_description)
+  {
+    description = _description;
+  }
+
+  virtual void generate_detailed_help_option_print(ostream &stream, unsigned int indent) = 0;
+
+  void set_detailed_help_option_print(const string &_detailed_help_option_print)
+  {
+    detailed_help_option_print = _detailed_help_option_print;
+  }
+
+  void set_do_generate_strdup(bool _do_generate_strdup)
+  {
+    do_generate_strdup = _do_generate_strdup;
+  }
+
+  virtual void generate_file_save_loop(ostream &stream, unsigned int indent) = 0;
+
+  void set_file_save_loop(const string &_file_save_loop)
+  {
+    file_save_loop = _file_save_loop;
+  }
+
+  void set_final_exit(const string &_final_exit)
+  {
+    final_exit = _final_exit;
+  }
+
+  virtual void generate_free(ostream &stream, unsigned int indent) = 0;
+
+  void set_free(const string &_free)
+  {
+    free = _free;
+  }
+
+  virtual void generate_full_help_option_print(ostream &stream, unsigned int indent) = 0;
+
+  void set_full_help_option_print(const string &_full_help_option_print)
+  {
+    full_help_option_print = _full_help_option_print;
+  }
+
+  void set_generate_string_parser(bool _generate_string_parser)
+  {
+    generate_string_parser = _generate_string_parser;
+  }
+
+  void set_generator_version(const string &_generator_version)
+  {
+    generator_version = _generator_version;
+  }
+
+  void set_getopt_string(const string &_getopt_string)
+  {
+    getopt_string = _getopt_string;
+  }
+
+  virtual void generate_given_init(ostream &stream, unsigned int indent) = 0;
+
+  void set_given_init(const string &_given_init)
+  {
+    given_init = _given_init;
+  }
+
+  virtual void generate_handle_dependencies(ostream &stream, unsigned int indent) = 0;
+
+  void set_handle_dependencies(const string &_handle_dependencies)
+  {
+    handle_dependencies = _handle_dependencies;
+  }
+
+  virtual void generate_handle_group(ostream &stream, unsigned int indent) = 0;
+
+  void set_handle_group(const string &_handle_group)
+  {
+    handle_group = _handle_group;
+  }
+
+  virtual void generate_handle_no_short_option(ostream &stream, unsigned int indent) = 0;
+
+  void set_handle_no_short_option(const string &_handle_no_short_option)
+  {
+    handle_no_short_option = _handle_no_short_option;
+  }
+
+  virtual void generate_handle_option(ostream &stream, unsigned int indent) = 0;
+
+  void set_handle_option(const string &_handle_option)
+  {
+    handle_option = _handle_option;
+  }
+
+  void set_handle_question_mark(bool _handle_question_mark)
+  {
+    handle_question_mark = _handle_question_mark;
+  }
+
+  virtual void generate_handle_required(ostream &stream, unsigned int indent) = 0;
+
+  void set_handle_required(const string &_handle_required)
+  {
+    handle_required = _handle_required;
+  }
+
+  void set_handle_unamed(bool _handle_unamed)
+  {
+    handle_unamed = _handle_unamed;
+  }
+
+  void set_has_arg_double(bool _has_arg_double)
+  {
+    has_arg_double = _has_arg_double;
+  }
+
+  void set_has_arg_enum(bool _has_arg_enum)
+  {
+    has_arg_enum = _has_arg_enum;
+  }
+
+  void set_has_arg_flag(bool _has_arg_flag)
+  {
+    has_arg_flag = _has_arg_flag;
+  }
+
+  void set_has_arg_float(bool _has_arg_float)
+  {
+    has_arg_float = _has_arg_float;
+  }
+
+  void set_has_arg_int(bool _has_arg_int)
+  {
+    has_arg_int = _has_arg_int;
+  }
+
+  void set_has_arg_long(bool _has_arg_long)
+  {
+    has_arg_long = _has_arg_long;
+  }
+
+  void set_has_arg_longdouble(bool _has_arg_longdouble)
+  {
+    has_arg_longdouble = _has_arg_longdouble;
+  }
+
+  void set_has_arg_longlong(bool _has_arg_longlong)
+  {
+    has_arg_longlong = _has_arg_longlong;
+  }
+
+  void set_has_arg_short(bool _has_arg_short)
+  {
+    has_arg_short = _has_arg_short;
+  }
+
+  void set_has_arg_string(bool _has_arg_string)
+  {
+    has_arg_string = _has_arg_string;
+  }
+
+  void set_has_details(bool _has_details)
+  {
+    has_details = _has_details;
+  }
+
+  void set_has_hidden(bool _has_hidden)
+  {
+    has_hidden = _has_hidden;
+  }
+
+  void set_has_modes(bool _has_modes)
+  {
+    has_modes = _has_modes;
+  }
+
+  void set_has_typed_options(bool _has_typed_options)
+  {
+    has_typed_options = _has_typed_options;
+  }
+
+  void set_header_file_ext(const string &_header_file_ext)
+  {
+    header_file_ext = _header_file_ext;
+  }
+
+  virtual void generate_help_option_print(ostream &stream, unsigned int indent) = 0;
+
+  void set_help_option_print(const string &_help_option_print)
+  {
+    help_option_print = _help_option_print;
+  }
+
+  void set_help_string_num(const string &_help_string_num)
+  {
+    help_string_num = _help_string_num;
+  }
+
+  void set_include_getopt(bool _include_getopt)
+  {
+    include_getopt = _include_getopt;
+  }
+
+  virtual void generate_init_args_info(ostream &stream, unsigned int indent) = 0;
+
+  void set_init_args_info(const string &_init_args_info)
+  {
+    init_args_info = _init_args_info;
+  }
+
+  virtual void generate_list_def(ostream &stream, unsigned int indent) = 0;
+
+  void set_list_def(const string &_list_def)
+  {
+    list_def = _list_def;
+  }
+
+  virtual void generate_list_free(ostream &stream, unsigned int indent) = 0;
+
+  void set_list_free(const string &_list_free)
+  {
+    list_free = _list_free;
+  }
+
+  virtual void generate_long_option_struct(ostream &stream, unsigned int indent) = 0;
+
+  void set_long_option_struct(const string &_long_option_struct)
+  {
+    long_option_struct = _long_option_struct;
+  }
+
+  virtual void generate_multiple_fill_array(ostream &stream, unsigned int indent) = 0;
+
+  void set_multiple_fill_array(const string &_multiple_fill_array)
+  {
+    multiple_fill_array = _multiple_fill_array;
+  }
+
+  void set_multiple_options(bool _multiple_options)
+  {
+    multiple_options = _multiple_options;
+  }
+
+  void set_multiple_options_all_string(bool _multiple_options_all_string)
+  {
+    multiple_options_all_string = _multiple_options_all_string;
+  }
+
+  void set_multiple_options_string(bool _multiple_options_string)
+  {
+    multiple_options_string = _multiple_options_string;
+  }
+
+  void set_multiple_options_with_default(bool _multiple_options_with_default)
+  {
+    multiple_options_with_default = _multiple_options_with_default;
+  }
+
+  void set_multiple_token_functions(bool _multiple_token_functions)
+  {
+    multiple_token_functions = _multiple_token_functions;
+  }
+
+  void set_no_options(bool _no_options)
+  {
+    no_options = _no_options;
+  }
+
+  void set_no_package(bool _no_package)
+  {
+    no_package = _no_package;
+  }
+
+  virtual void generate_option_values(ostream &stream, unsigned int indent) = 0;
+
+  void set_option_values(const string &_option_values)
+  {
+    option_values = _option_values;
+  }
+
+  void set_package_var_name(const string &_package_var_name)
+  {
+    package_var_name = _package_var_name;
+  }
+
+  void set_parser_name(const string &_parser_name)
+  {
+    parser_name = _parser_name;
+  }
+
+  void set_purpose(const string &_purpose)
+  {
+    purpose = _purpose;
+  }
+
+  virtual void generate_reset_groups(ostream &stream, unsigned int indent) = 0;
+
+  void set_reset_groups(const string &_reset_groups)
+  {
+    reset_groups = _reset_groups;
+  }
+
+  void set_source_name(const string &_source_name)
+  {
+    source_name = _source_name;
+  }
+
+  virtual void generate_update_multiple_given(ostream &stream, unsigned int indent) = 0;
+
+  void set_update_multiple_given(const string &_update_multiple_given)
+  {
+    update_multiple_given = _update_multiple_given;
+  }
+
+  void set_usage_string(const string &_usage_string)
+  {
+    usage_string = _usage_string;
+  }
+
+  void set_version_var_name(const string &_version_var_name)
+  {
+    version_var_name = _version_var_name;
+  }
+
+  void generate_c_source(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // C_SOURCE_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/check_modes.cc b/cmake/gengetopt/skels/check_modes.cc
new file mode 100644 (file)
index 0000000..fd197cd
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "check_modes.h"
+
+void
+check_modes_gen_class::generate_check_modes(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "if (args_info->";
+  generate_string (mode1_name, stream, indent + indent_str.length ());
+  stream << "_mode_counter && args_info->";
+  generate_string (mode2_name, stream, indent + indent_str.length ());
+  stream << "_mode_counter) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int ";
+  generate_string (mode1_name, stream, indent + indent_str.length ());
+  stream << "_given[] = {";
+  generate_string (mode1_given_fields, stream, indent + indent_str.length ());
+  stream << " -1};";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const char *";
+  generate_string (mode1_name, stream, indent + indent_str.length ());
+  stream << "_desc[] = {";
+  generate_string (mode1_options, stream, indent + indent_str.length ());
+  stream << " 0};";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int ";
+  generate_string (mode2_name, stream, indent + indent_str.length ());
+  stream << "_given[] = {";
+  generate_string (mode2_given_fields, stream, indent + indent_str.length ());
+  stream << " -1};";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const char *";
+  generate_string (mode2_name, stream, indent + indent_str.length ());
+  stream << "_desc[] = {";
+  generate_string (mode2_options, stream, indent + indent_str.length ());
+  stream << " 0};";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  error += check_modes(";
+  generate_string (mode1_name, stream, indent + indent_str.length ());
+  stream << "_given, ";
+  generate_string (mode1_name, stream, indent + indent_str.length ());
+  stream << "_desc, ";
+  generate_string (mode2_name, stream, indent + indent_str.length ());
+  stream << "_given, ";
+  generate_string (mode2_name, stream, indent + indent_str.length ());
+  stream << "_desc);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/check_modes.h b/cmake/gengetopt/skels/check_modes.h
new file mode 100644 (file)
index 0000000..1ac5449
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CHECK_MODES_GEN_CLASS_H
+#define CHECK_MODES_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class check_modes_gen_class
+{
+ protected:
+  string mode1_given_fields;
+  string mode1_name;
+  string mode1_options;
+  string mode2_given_fields;
+  string mode2_name;
+  string mode2_options;
+
+ public:
+  check_modes_gen_class()
+  {
+  }
+  
+  check_modes_gen_class(const string &_mode1_given_fields, const string &_mode1_name, const string &_mode1_options, const string &_mode2_given_fields, const string &_mode2_name, const string &_mode2_options) :
+    mode1_given_fields (_mode1_given_fields), mode1_name (_mode1_name), mode1_options (_mode1_options), mode2_given_fields (_mode2_given_fields), mode2_name (_mode2_name), mode2_options (_mode2_options)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_mode1_given_fields(const string &_mode1_given_fields)
+  {
+    mode1_given_fields = _mode1_given_fields;
+  }
+
+  void set_mode1_name(const string &_mode1_name)
+  {
+    mode1_name = _mode1_name;
+  }
+
+  void set_mode1_options(const string &_mode1_options)
+  {
+    mode1_options = _mode1_options;
+  }
+
+  void set_mode2_given_fields(const string &_mode2_given_fields)
+  {
+    mode2_given_fields = _mode2_given_fields;
+  }
+
+  void set_mode2_name(const string &_mode2_name)
+  {
+    mode2_name = _mode2_name;
+  }
+
+  void set_mode2_options(const string &_mode2_options)
+  {
+    mode2_options = _mode2_options;
+  }
+
+  void generate_check_modes(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // CHECK_MODES_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/clear_arg.cc b/cmake/gengetopt/skels/clear_arg.cc
new file mode 100644 (file)
index 0000000..43324d3
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "clear_arg.h"
+
+void
+clear_arg_gen_class::generate_clear_arg(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (has_arg)
+    {
+      stream << "args_info->";
+      generate_string (name, stream, indent + indent_str.length ());
+      stream << "_";
+      generate_string (suffix, stream, indent + indent_str.length ());
+      stream << " = ";
+      generate_string (value, stream, indent + indent_str.length ());
+      stream << ";";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_orig)
+    {
+      stream << "args_info->";
+      generate_string (name, stream, indent + indent_str.length ());
+      stream << "_orig = NULL;";
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/clear_arg.h b/cmake/gengetopt/skels/clear_arg.h
new file mode 100644 (file)
index 0000000..bf4bb14
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CLEAR_ARG_GEN_CLASS_H
+#define CLEAR_ARG_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class clear_arg_gen_class
+{
+ protected:
+  bool has_arg;
+  bool has_orig;
+  string name;
+  string suffix;
+  string value;
+
+ public:
+  clear_arg_gen_class() :
+    has_arg (false), has_orig (false)
+  {
+  }
+  
+  clear_arg_gen_class(bool _has_arg, bool _has_orig, const string &_name, const string &_suffix, const string &_value) :
+    has_arg (_has_arg), has_orig (_has_orig), name (_name), suffix (_suffix), value (_value)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_has_arg(bool _has_arg)
+  {
+    has_arg = _has_arg;
+  }
+
+  void set_has_orig(bool _has_orig)
+  {
+    has_orig = _has_orig;
+  }
+
+  void set_name(const string &_name)
+  {
+    name = _name;
+  }
+
+  void set_suffix(const string &_suffix)
+  {
+    suffix = _suffix;
+  }
+
+  void set_value(const string &_value)
+  {
+    value = _value;
+  }
+
+  void generate_clear_arg(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // CLEAR_ARG_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/clear_given.cc b/cmake/gengetopt/skels/clear_given.cc
new file mode 100644 (file)
index 0000000..3e15732
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "clear_given.h"
+
+void
+clear_given_gen_class::generate_clear_given(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  generate_string (arg_struct, stream, indent + indent_str.length ());
+  stream << "->";
+  generate_string (var_arg, stream, indent + indent_str.length ());
+  stream << "_given = 0 ;";
+  if (group)
+    {
+      indent = 1;
+      stream << " ";
+      generate_string (arg_struct, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (var_arg, stream, indent + indent_str.length ());
+      stream << "_group = 0 ;";
+    }
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/clear_given.h b/cmake/gengetopt/skels/clear_given.h
new file mode 100644 (file)
index 0000000..6853b25
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CLEAR_GIVEN_GEN_CLASS_H
+#define CLEAR_GIVEN_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class clear_given_gen_class
+{
+ protected:
+  string arg_struct;
+  bool group;
+  string var_arg;
+
+ public:
+  clear_given_gen_class() :
+    group (false)
+  {
+  }
+  
+  clear_given_gen_class(const string &_arg_struct, bool _group, const string &_var_arg) :
+    arg_struct (_arg_struct), group (_group), var_arg (_var_arg)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_arg_struct(const string &_arg_struct)
+  {
+    arg_struct = _arg_struct;
+  }
+
+  void set_group(bool _group)
+  {
+    group = _group;
+  }
+
+  void set_var_arg(const string &_var_arg)
+  {
+    var_arg = _var_arg;
+  }
+
+  void generate_clear_given(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // CLEAR_GIVEN_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/copyright.cc b/cmake/gengetopt/skels/copyright.cc
new file mode 100644 (file)
index 0000000..f0f726b
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "copyright.h"
+
+void
+copyright_gen_class::generate_copyright(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "Copyright (C) ";
+  generate_string (year, stream, indent + indent_str.length ());
+  stream << "  Free Software Foundation Inc.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "This program comes with ABSOLUTELY NO WARRANTY; for details";
+  stream << "\n";
+  stream << indent_str;
+  stream << "please see the file 'COPYING' supplied with the source code.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "This is free software, and you are welcome to redistribute it";
+  stream << "\n";
+  stream << indent_str;
+  stream << "under certain conditions; again, see 'COPYING' for details.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "This program is released under the GNU General Public License.";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/copyright.h b/cmake/gengetopt/skels/copyright.h
new file mode 100644 (file)
index 0000000..3b07bc8
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef COPYRIGHT_GEN_CLASS_H
+#define COPYRIGHT_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class copyright_gen_class
+{
+ protected:
+  string year;
+
+ public:
+  copyright_gen_class()
+  {
+  }
+  
+  copyright_gen_class(const string &_year) :
+    year (_year)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_year(const string &_year)
+  {
+    year = _year;
+  }
+
+  void generate_copyright(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // COPYRIGHT_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/custom_getopt_gen.cc b/cmake/gengetopt/skels/custom_getopt_gen.cc
new file mode 100644 (file)
index 0000000..d0ff3ff
--- /dev/null
@@ -0,0 +1,1750 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "custom_getopt_gen.h"
+
+void
+custom_getopt_gen_gen_class::generate_custom_getopt_gen(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Extracted from the glibc source tree, version 2.3.6";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Licensed under the GPL as per the whole glibc source tree.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * This file was modified so that getopt_long can be called";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * many times without risking previous memory to be spoiled.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Modified by Andre Noll and Lorenzo Bettini for use in";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * GNU gengetopt generated files.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/* ";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * we must include anything we need since this file is not thought to be";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * inserted in a file already using getopt.h";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Lorenzo";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "struct option";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const char *name;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /* has_arg can't be an enum because some compilers complain about";
+  stream << "\n";
+  stream << indent_str;
+  stream << "     type mismatches in all the code that assumes it is an int.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int has_arg;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int *flag;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int val;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "};";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/* This version of `getopt' appears to the caller like standard Unix `getopt'";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   but it behaves differently for the user, since it allows the user";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   to intersperse the options with the other arguments.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "   As `getopt' works, it permutes the elements of ARGV so that,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   when it is done, all the options precede everything else.  Thus";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   all application programs are extended to handle flexible argument order.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "*/";
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   If the field `flag' is not NULL, it points to a variable that is set";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   to the value given in the field `val' when the option is found, but";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   left unchanged if the option is not found.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "   To have a long-named option do something other than set an `int' to";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   a compiled-in constant, such as set a value from `custom_optarg', set the";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   option's `flag' field to zero and its `val' field to a nonzero";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   value (the equivalent single-letter option character, if there is";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   one).  For long options that have a zero `flag' field, `getopt'";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   returns the contents of the `val' field.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/* Names for the values of the `has_arg' field of `struct option'.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifndef no_argument";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#define no_argument               0";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifndef required_argument";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#define required_argument 1";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifndef optional_argument";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#define optional_argument 2";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "struct custom_getopt_data {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * These have exactly the same meaning as the corresponding global variables,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * except that they are used for the reentrant versions of getopt.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int custom_opterr;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int custom_optopt;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  char *custom_optarg;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /* True if the internal members have been initialized.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int initialized;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * The next char to be scanned in the option-element in which the last option";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * character we returned was found.  This allows us to pick up the scan where";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * we left off.  If this is zero, or a null string, it means resume the scan by";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * advancing to the next ARGV-element.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  char *nextchar;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * Describe the part of ARGV that contains non-options that have been skipped.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * the index after the last of them.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int first_nonopt;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int last_nonopt;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "};";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * the variables optarg, optind, opterr and optopt are renamed with";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * the custom_ prefix so that they don't interfere with getopt ones.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Moreover they're static so they are visible only from within the";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * file where this very file will be included.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * option that takes an argument, the argument value is returned here.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static char *custom_optarg;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Index in ARGV of the next element to be scanned.  This is used for";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * communication to and from the caller and for communication between";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * successive calls to `custom_getopt'.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * On entry to `custom_getopt', 1 means this is the first call; initialize.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * When `custom_getopt' returns -1, this is the index of the first of the non-option";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * elements that the caller should itself scan.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * has been scanned so far.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * 1003.2 says this must be 1 before any call.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int custom_optind = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Callers store zero here to inhibit the error message for unrecognized";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * options.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int custom_opterr = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Set to an option character which was unrecognized.  This must be initialized";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * on some systems to avoid linking in the system's own getopt implementation.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int custom_optopt = '?';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Exchange two adjacent subsequences of ARGV.  One subsequence is elements";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * [first_nonopt,last_nonopt) which contains all the non-options that have been";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * all the options processed since those non-options were skipped.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * `first_nonopt' and `last_nonopt' are relocated so that they describe the new";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * indices of the non-options in ARGV after they are moved.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static void exchange(char **argv, struct custom_getopt_data *d)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int bottom = d->first_nonopt;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int middle = d->last_nonopt;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int top = d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  char *tem;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * Exchange the shorter segment with the far end of the longer segment.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * That puts the shorter segment into the right place.  It leaves the";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * longer segment in the right place overall, but it consists of two";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * parts that need to be swapped next.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  while (top > middle && middle > bottom) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (top - middle > middle - bottom) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* Bottom segment is the short one.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  int len = middle - bottom;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  int i;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* Swap it with the top part of the top segment.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  for (i = 0; i < len; i++) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          tem = argv[bottom + i];";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          argv[bottom + i] =";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  argv[top - (middle - bottom) + i];";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          argv[top - (middle - bottom) + i] = tem;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* Exclude the moved bottom segment from further swapping.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  top -= len;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          } else {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* Top segment is the short one.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  int len = top - middle;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  int i;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* Swap it with the bottom part of the bottom segment.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  for (i = 0; i < len; i++) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          tem = argv[bottom + i];";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          argv[bottom + i] = argv[middle + i];";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          argv[middle + i] = tem;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* Exclude the moved top segment from further swapping.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  bottom += len;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /* Update records for the slots the non-options now occupy.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->first_nonopt += (d->custom_optind - d->last_nonopt);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->last_nonopt = d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/* Initialize the internal data when the first call is made.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static void custom_getopt_initialize(struct custom_getopt_data *d)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * Start processing options with ARGV-element 1 (since ARGV-element 0";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * is the program name); the sequence of previously skipped non-option";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * ARGV-elements is empty.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->first_nonopt = d->last_nonopt = d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->nextchar = NULL;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->initialized = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\\0')";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/* return: zero: continue, nonzero: return given value to user */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct custom_getopt_data *d)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * moved back by the user (who may also have changed the arguments).";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (d->last_nonopt > d->custom_optind)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->last_nonopt = d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (d->first_nonopt > d->custom_optind)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->first_nonopt = d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * If we have just processed some options following some";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * non-options, exchange them so that the options come first.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (d->first_nonopt != d->last_nonopt &&";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  d->last_nonopt != d->custom_optind)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          exchange((char **) argv, d);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  else if (d->last_nonopt != d->custom_optind)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->first_nonopt = d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * Skip any additional non-options and extend the range of";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * non-options previously skipped.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  while (d->custom_optind < argc && NONOPTION_P)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->custom_optind++;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->last_nonopt = d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * The special ARGV-element `--' means premature end of options.  Skip";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * it like a null option, then exchange with previous non-options as if";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * it were an option, then skip everything else like a non-option.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], \"--\")) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->custom_optind++;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (d->first_nonopt != d->last_nonopt";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          && d->last_nonopt != d->custom_optind)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  exchange((char **) argv, d);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          else if (d->first_nonopt == d->last_nonopt)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  d->first_nonopt = d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->last_nonopt = argc;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->custom_optind = argc;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * If we have done all the ARGV-elements, stop the scan and back over";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * any non-options that we skipped and permuted.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (d->custom_optind == argc) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "           * Set the next-arg-index to point at the non-options that we";
+  stream << "\n";
+  stream << indent_str;
+  stream << "           * previously skipped, so the caller will digest them.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "           */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (d->first_nonopt != d->last_nonopt)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  d->custom_optind = d->first_nonopt;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          return -1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * If we have come to a non-option and did not permute it, either stop";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * the scan or describe it to the caller and pass it by.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (NONOPTION_P) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->custom_optarg = argv[d->custom_optind++];";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          return 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * We have found another option-ARGV-element. Skip the initial";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * punctuation.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Check whether the ARGV-element is a long option.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * If there's a long option \"fubar\" and the ARGV-element is \"-fu\", consider";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * that an abbreviation of the long option, just like \"--fu\", and not \"-f\" with";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * arg \"u\".";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * This distinction seems to be the most useful approach.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int check_long_opt(int argc, char *const *argv, const char *optstring,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          const struct option *longopts, int *longind,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          int print_errors, struct custom_getopt_data *d)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  char *nameend;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const struct option *p;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const struct option *pfound = NULL;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int exact = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int ambig = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int indfound = -1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int option_index;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          /* Do nothing.  */ ;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /* Test all long options for either exact match or abbreviated matches */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  for (p = longopts, option_index = 0; p->name; p++, option_index++)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  if ((unsigned int) (nameend - d->nextchar)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  == (unsigned int) strlen(p->name)) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          /* Exact match found.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          pfound = p;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          indfound = option_index;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          exact = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          break;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  } else if (pfound == NULL) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          /* First nonexact match found.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          pfound = p;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          indfound = option_index;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  } else if (pfound->has_arg != p->has_arg";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  || pfound->flag != p->flag";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  || pfound->val != p->val)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          /* Second or later nonexact match found.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          ambig = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (ambig && !exact) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (print_errors) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  fprintf(stderr,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          \"%s: option `%s' is ambiguous\\n\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          argv[0], argv[d->custom_optind]);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->nextchar += strlen(d->nextchar);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->custom_optind++;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->custom_optopt = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          return '?';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (pfound) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          option_index = indfound;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->custom_optind++;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (*nameend) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  if (pfound->has_arg != no_argument)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optarg = nameend + 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  else {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          if (print_errors) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  if (argv[d->custom_optind - 1][1] == '-') {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          /* --option */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          fprintf(stderr, \"%s: option `--%s' doesn't allow an argument\\n\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                                  argv[0], pfound->name);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  } else {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          /* +option or -option */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          fprintf(stderr, \"%s: option `%c%s' doesn't allow an argument\\n\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                                  argv[0], argv[d->custom_optind - 1][0], pfound->name);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->nextchar += strlen(d->nextchar);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optopt = pfound->val;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          return '?';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          } else if (pfound->has_arg == required_argument) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  if (d->custom_optind < argc)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optarg = argv[d->custom_optind++];";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  else {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          if (print_errors) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  fprintf(stderr,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          \"%s: option `%s' requires an argument\\n\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          argv[0],";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          argv[d->custom_optind - 1]);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->nextchar += strlen(d->nextchar);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optopt = pfound->val;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          return optstring[0] == ':' ? ':' : '?';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->nextchar += strlen(d->nextchar);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (longind != NULL)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  *longind = option_index;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (pfound->flag) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  *(pfound->flag) = pfound->val;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  return 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          return pfound->val;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * Can't find it as a long option.  If this is not getopt_long_only, or";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * the option starts with '--' or is not a valid short option, then";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * it's an error.  Otherwise interpret it as a short option.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (print_errors) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (argv[d->custom_optind][1] == '-') {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* --option */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  fprintf(stderr,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          \"%s: unrecognized option `--%s'\\n\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          argv[0], d->nextchar);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          } else {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* +option or -option */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  fprintf(stderr,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          \"%s: unrecognized option `%c%s'\\n\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          argv[0], argv[d->custom_optind][0],";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->nextchar);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->nextchar = (char *) \"\";";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->custom_optind++;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->custom_optopt = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return '?';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int check_short_opt(int argc, char *const *argv, const char *optstring,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          int print_errors, struct custom_getopt_data *d)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  char c = *d->nextchar++;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const char *temp = strchr(optstring, c);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /* Increment `custom_optind' when we start to process its last character.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (*d->nextchar == '\\0')";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          ++d->custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (!temp || c == ':') {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (print_errors)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  fprintf(stderr, \"%s: invalid option -- %c\\n\", argv[0], c);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "          d->custom_optopt = c;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          return '?';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (temp[1] == ':') {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (temp[2] == ':') {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* This is an option that accepts an argument optionally.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  if (*d->nextchar != '\\0') {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optarg = d->nextchar;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optind++;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  } else";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optarg = NULL;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  d->nextchar = NULL;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          } else {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  /* This is an option that requires an argument.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  if (*d->nextchar != '\\0') {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optarg = d->nextchar;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                           * If we end this ARGV-element by taking the";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                           * rest as an arg, we must advance to the next";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                           * element now.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                           */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optind++;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  } else if (d->custom_optind == argc) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          if (print_errors) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  fprintf(stderr,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          \"%s: option requires an argument -- %c\\n\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                          argv[0], c);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optopt = c;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          if (optstring[0] == ':')";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  c = ':';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          else";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                                  c = '?';";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  } else";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          /*";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                           * We already incremented `custom_optind' once;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                           * increment it again when taking next ARGV-elt";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                           * as argument.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                           */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                          d->custom_optarg = argv[d->custom_optind++];";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  d->nextchar = NULL;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return c;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/*";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Scan elements of ARGV for option characters given in OPTSTRING.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * If an element of ARGV starts with '-', and is not exactly \"-\" or \"--\",";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * then it is an option element.  The characters of this element";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * (aside from the initial '-') are option characters.  If `getopt'";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * is called repeatedly, it returns successively each of the option characters";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * from each of the option elements.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * If `getopt' finds another option character, it returns that character,";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * updating `custom_optind' and `nextchar' so that the next call to `getopt' can";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * resume the scan with the following option character or ARGV-element.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * If there are no more option characters, `getopt' returns -1.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Then `custom_optind' is the index in ARGV of the first ARGV-element";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * that is not an option.  (The ARGV-elements have been permuted";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * so that those that are not options now come last.)";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * OPTSTRING is a string containing the legitimate option characters.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * If an option character is seen that is not listed in OPTSTRING,";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * return '?' after printing an error message.  If you set `custom_opterr' to";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * zero, the error message is suppressed but we still return '?'.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * If a char in OPTSTRING is followed by a colon, that means it wants an arg,";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * so the following text in the same ARGV-element, or the text of the following";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * wants an optional arg; if there is text in the current ARGV-element,";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * If OPTSTRING starts with `-' or `+', it requests different methods of";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * handling the non-option ARGV-elements.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Long-named options begin with `--' instead of `-'.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Their names may be abbreviated as long as the abbreviation is unique";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * or is an exact match for some defined option.  If they have an";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * argument, it follows the option name in the same ARGV-element, separated";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * from the option name by a `=', or else the in next ARGV-element.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * When `getopt' finds a long-named option, it returns 0 if that option's";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * `flag' field is nonzero, the value of the option's `val' field";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * if the `flag' field is zero.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * The elements of ARGV aren't really const, because we permute them.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * But we pretend they're const in the prototype to be compatible";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * with other systems.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * LONGOPTS is a vector of `struct option' terminated by an";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * element containing a name which is zero.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * LONGIND returns the index in LONGOPT of the long-named option found.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * It is only valid when a long-named option has been found by the most";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * recent call.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Return the option character from OPTS just read.  Return -1 when there are";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * no more options.  For unrecognized options, or options missing arguments,";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * `custom_optopt' is set to the option letter, and '?' is returned.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * The OPTS string is a list of characters which are recognized option letters,";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * optionally followed by colons, specifying that that letter takes an";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * argument, to be placed in `custom_optarg'.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * If a letter in OPTS is followed by two colons, its argument is optional.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * This behavior is specific to the GNU `getopt'.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * The argument `--' causes premature termination of argument scanning,";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * explicitly telling `getopt' that there are no more options.  If OPTS begins";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * with `--', then non-option arguments are treated as arguments to the option";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * '\\0'.  This behavior is specific to the GNU `getopt'.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int getopt_internal_r(int argc, char *const *argv, const char *optstring,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          const struct option *longopts, int *longind,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          struct custom_getopt_data *d)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int ret, print_errors = d->custom_opterr;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (optstring[0] == ':')";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          print_errors = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (argc < 1)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          return -1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d->custom_optarg = NULL;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /* ";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * This is a big difference with GNU getopt, since optind == 0";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   * means initialization while here 1 means first call.";
+  stream << "\n";
+  stream << indent_str;
+  stream << "   */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (d->custom_optind == 0 || !d->initialized) {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (d->custom_optind == 0)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  d->custom_optind = 1;   /* Don't scan ARGV[0], the program name.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          custom_getopt_initialize(d);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (d->nextchar == NULL || *d->nextchar == '\\0') {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          ret = shuffle_argv(argc, argv, longopts, d);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          if (ret)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  return ret;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (longopts && (argv[d->custom_optind][1] == '-' ))";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          return check_long_opt(argc, argv, optstring, longopts,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "                  longind, print_errors, d);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return check_short_opt(argc, argv, optstring, print_errors, d);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const struct option *longopts, int *longind)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int result;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  /* Keep a global copy of all internal members of d */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  static struct custom_getopt_data d;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d.custom_optind = custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  d.custom_opterr = custom_opterr;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  result = getopt_internal_r(argc, argv, optstring, longopts,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          longind, &d);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  custom_optind = d.custom_optind;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  custom_optarg = d.custom_optarg;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  custom_optopt = d.custom_optopt;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return result;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "static int custom_getopt_long (int argc, char *const *argv, const char *options,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const struct option *long_options, int *opt_index)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  return custom_getopt_internal(argc, argv, options, long_options,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "          opt_index);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/custom_getopt_gen.h b/cmake/gengetopt/skels/custom_getopt_gen.h
new file mode 100644 (file)
index 0000000..0f24834
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef CUSTOM_GETOPT_GEN_GEN_CLASS_H
+#define CUSTOM_GETOPT_GEN_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class custom_getopt_gen_gen_class
+{
+ protected:
+
+ public:
+  custom_getopt_gen_gen_class()
+  {
+  }
+  
+
+  void generate_custom_getopt_gen(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // CUSTOM_GETOPT_GEN_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/dependant_option.cc b/cmake/gengetopt/skels/dependant_option.cc
new file mode 100644 (file)
index 0000000..f9396a1
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "dependant_option.h"
+
+void
+dependant_option_gen_class::generate_dependant_option(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "if (args_info->";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_given && ! args_info->";
+  generate_string (dep_option, stream, indent + indent_str.length ());
+  stream << "_given)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    fprintf (stderr, \"%s: ";
+  generate_string (option_descr, stream, indent + indent_str.length ());
+  stream << " option depends on option '";
+  generate_string (dep_option_descr, stream, indent + indent_str.length ());
+  stream << "'%s\\n\", ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << ", (additional_error ? additional_error : \"\"));";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    error = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+}
diff --git a/cmake/gengetopt/skels/dependant_option.h b/cmake/gengetopt/skels/dependant_option.h
new file mode 100644 (file)
index 0000000..4a10656
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef DEPENDANT_OPTION_GEN_CLASS_H
+#define DEPENDANT_OPTION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class dependant_option_gen_class
+{
+ protected:
+  string dep_option;
+  string dep_option_descr;
+  string option_descr;
+  string option_var_name;
+  string package_var_name;
+
+ public:
+  dependant_option_gen_class()
+  {
+  }
+  
+  dependant_option_gen_class(const string &_dep_option, const string &_dep_option_descr, const string &_option_descr, const string &_option_var_name, const string &_package_var_name) :
+    dep_option (_dep_option), dep_option_descr (_dep_option_descr), option_descr (_option_descr), option_var_name (_option_var_name), package_var_name (_package_var_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_dep_option(const string &_dep_option)
+  {
+    dep_option = _dep_option;
+  }
+
+  void set_dep_option_descr(const string &_dep_option_descr)
+  {
+    dep_option_descr = _dep_option_descr;
+  }
+
+  void set_option_descr(const string &_option_descr)
+  {
+    option_descr = _option_descr;
+  }
+
+  void set_option_var_name(const string &_option_var_name)
+  {
+    option_var_name = _option_var_name;
+  }
+
+  void set_package_var_name(const string &_package_var_name)
+  {
+    package_var_name = _package_var_name;
+  }
+
+  void generate_dependant_option(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // DEPENDANT_OPTION_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/enum_decl.cc b/cmake/gengetopt/skels/enum_decl.cc
new file mode 100644 (file)
index 0000000..00c9408
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "enum_decl.h"
+
+void
+enum_decl_gen_class::generate_enum_decl(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "enum enum_";
+  generate_string (var_arg, stream, indent + indent_str.length ());
+  stream << " { ";
+  generate_string (var_arg, stream, indent + indent_str.length ());
+  stream << "__NULL = -1";
+  generate_string (enum_values, stream, indent + indent_str.length ());
+  stream << " };";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/enum_decl.h b/cmake/gengetopt/skels/enum_decl.h
new file mode 100644 (file)
index 0000000..566f296
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef ENUM_DECL_GEN_CLASS_H
+#define ENUM_DECL_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class enum_decl_gen_class
+{
+ protected:
+  string enum_values;
+  string var_arg;
+
+ public:
+  enum_decl_gen_class()
+  {
+  }
+  
+  enum_decl_gen_class(const string &_enum_values, const string &_var_arg) :
+    enum_values (_enum_values), var_arg (_var_arg)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_enum_values(const string &_enum_values)
+  {
+    enum_values = _enum_values;
+  }
+
+  void set_var_arg(const string &_var_arg)
+  {
+    var_arg = _var_arg;
+  }
+
+  void generate_enum_decl(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // ENUM_DECL_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/exit_failure.cc b/cmake/gengetopt/skels/exit_failure.cc
new file mode 100644 (file)
index 0000000..705ea34
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "exit_failure.h"
+
+void
+exit_failure_gen_class::generate_exit_failure(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (handle_error)
+    {
+      stream << "if (result == EXIT_FAILURE)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  {";
+      stream << "\n";
+      stream << indent_str;
+      indent = 4;
+      stream << "    ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_free (args_info);";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+      stream << "    exit (EXIT_FAILURE);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "return result;";
+}
diff --git a/cmake/gengetopt/skels/exit_failure.h b/cmake/gengetopt/skels/exit_failure.h
new file mode 100644 (file)
index 0000000..42bf53c
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef EXIT_FAILURE_GEN_CLASS_H
+#define EXIT_FAILURE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class exit_failure_gen_class
+{
+ protected:
+  bool handle_error;
+  string parser_name;
+
+ public:
+  exit_failure_gen_class() :
+    handle_error (false)
+  {
+  }
+  
+  exit_failure_gen_class(bool _handle_error, const string &_parser_name) :
+    handle_error (_handle_error), parser_name (_parser_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_handle_error(bool _handle_error)
+  {
+    handle_error = _handle_error;
+  }
+
+  void set_parser_name(const string &_parser_name)
+  {
+    parser_name = _parser_name;
+  }
+
+  void generate_exit_failure(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // EXIT_FAILURE_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/file_save.cc b/cmake/gengetopt/skels/file_save.cc
new file mode 100644 (file)
index 0000000..44888e6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "file_save.h"
+
+void
+file_save_gen_class::generate_file_save(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "if (args_info->";
+  generate_string (given, stream, indent + indent_str.length ());
+  stream << ")";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  write_into_file(outfile, \"";
+  generate_string (opt_name, stream, indent + indent_str.length ());
+  stream << "\", ";
+  if (( arg == "" ))
+    {
+      stream << "0, 0 ";
+    }
+  else
+    {
+      stream << "args_info->";
+      generate_string (arg, stream, indent + indent_str.length ());
+      stream << ", ";
+      generate_string (values, stream, indent + indent_str.length ());
+    }
+  stream << ");";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/file_save.h b/cmake/gengetopt/skels/file_save.h
new file mode 100644 (file)
index 0000000..81d59e6
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FILE_SAVE_GEN_CLASS_H
+#define FILE_SAVE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class file_save_gen_class
+{
+ protected:
+  string arg;
+  string given;
+  string opt_name;
+  string values;
+
+ public:
+  file_save_gen_class()
+  {
+  }
+  
+  file_save_gen_class(const string &_arg, const string &_given, const string &_opt_name, const string &_values) :
+    arg (_arg), given (_given), opt_name (_opt_name), values (_values)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_arg(const string &_arg)
+  {
+    arg = _arg;
+  }
+
+  void set_given(const string &_given)
+  {
+    given = _given;
+  }
+
+  void set_opt_name(const string &_opt_name)
+  {
+    opt_name = _opt_name;
+  }
+
+  void set_values(const string &_values)
+  {
+    values = _values;
+  }
+
+  void generate_file_save(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // FILE_SAVE_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/file_save_multiple.cc b/cmake/gengetopt/skels/file_save_multiple.cc
new file mode 100644 (file)
index 0000000..405be31
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "file_save_multiple.h"
+
+void
+file_save_multiple_gen_class::generate_file_save_multiple(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (has_arg)
+    {
+      stream << "write_multiple_into_file(outfile, args_info->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_given, \"";
+      generate_string (opt_name, stream, indent + indent_str.length ());
+      stream << "\", args_info->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_orig, ";
+      generate_string (values, stream, indent + indent_str.length ());
+      stream << ");";
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "write_multiple_into_file(outfile, args_info->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_given, \"";
+      generate_string (opt_name, stream, indent + indent_str.length ());
+      stream << "\", 0, 0);";
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/file_save_multiple.h b/cmake/gengetopt/skels/file_save_multiple.h
new file mode 100644 (file)
index 0000000..36a8aba
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FILE_SAVE_MULTIPLE_GEN_CLASS_H
+#define FILE_SAVE_MULTIPLE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class file_save_multiple_gen_class
+{
+ protected:
+  bool has_arg;
+  string opt_name;
+  string opt_var;
+  string values;
+
+ public:
+  file_save_multiple_gen_class() :
+    has_arg (false)
+  {
+  }
+  
+  file_save_multiple_gen_class(bool _has_arg, const string &_opt_name, const string &_opt_var, const string &_values) :
+    has_arg (_has_arg), opt_name (_opt_name), opt_var (_opt_var), values (_values)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_has_arg(bool _has_arg)
+  {
+    has_arg = _has_arg;
+  }
+
+  void set_opt_name(const string &_opt_name)
+  {
+    opt_name = _opt_name;
+  }
+
+  void set_opt_var(const string &_opt_var)
+  {
+    opt_var = _opt_var;
+  }
+
+  void set_values(const string &_values)
+  {
+    values = _values;
+  }
+
+  void generate_file_save_multiple(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // FILE_SAVE_MULTIPLE_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/free_list.cc b/cmake/gengetopt/skels/free_list.cc
new file mode 100644 (file)
index 0000000..fef4555
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "free_list.h"
+
+void
+free_list_gen_class::generate_free_list(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "free_list (";
+  generate_string (list_name, stream, indent + indent_str.length ());
+  stream << "_list, ";
+  if (string_list)
+    {
+      stream << "1 ";
+    }
+  else
+    {
+      stream << "0 ";
+    }
+  stream << ");";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/free_list.h b/cmake/gengetopt/skels/free_list.h
new file mode 100644 (file)
index 0000000..82f5159
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FREE_LIST_GEN_CLASS_H
+#define FREE_LIST_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class free_list_gen_class
+{
+ protected:
+  string list_name;
+  bool string_list;
+
+ public:
+  free_list_gen_class() :
+    string_list (false)
+  {
+  }
+  
+  free_list_gen_class(const string &_list_name, bool _string_list) :
+    list_name (_list_name), string_list (_string_list)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_list_name(const string &_list_name)
+  {
+    list_name = _list_name;
+  }
+
+  void set_string_list(bool _string_list)
+  {
+    string_list = _string_list;
+  }
+
+  void generate_free_list(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // FREE_LIST_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/free_multiple.cc b/cmake/gengetopt/skels/free_multiple.cc
new file mode 100644 (file)
index 0000000..e9403b2
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "free_multiple.h"
+
+void
+free_multiple_gen_class::generate_free_multiple(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (has_string_type)
+    {
+      stream << "free_multiple_string_field (";
+      generate_string (structure, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_given, &(";
+      generate_string (structure, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_arg), &(";
+      generate_string (structure, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_orig));";
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "free_multiple_field (";
+      generate_string (structure, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_given, (void *)(";
+      generate_string (structure, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_arg), &(";
+      generate_string (structure, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_orig));";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (structure, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_arg = 0;";
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/free_multiple.h b/cmake/gengetopt/skels/free_multiple.h
new file mode 100644 (file)
index 0000000..64fe58c
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FREE_MULTIPLE_GEN_CLASS_H
+#define FREE_MULTIPLE_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class free_multiple_gen_class
+{
+ protected:
+  bool has_string_type;
+  string opt_var;
+  string structure;
+
+ public:
+  free_multiple_gen_class() :
+    has_string_type (false)
+  {
+  }
+  
+  free_multiple_gen_class(bool _has_string_type, const string &_opt_var, const string &_structure) :
+    has_string_type (_has_string_type), opt_var (_opt_var), structure (_structure)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_has_string_type(bool _has_string_type)
+  {
+    has_string_type = _has_string_type;
+  }
+
+  void set_opt_var(const string &_opt_var)
+  {
+    opt_var = _opt_var;
+  }
+
+  void set_structure(const string &_structure)
+  {
+    structure = _structure;
+  }
+
+  void generate_free_multiple(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // FREE_MULTIPLE_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/free_string.cc b/cmake/gengetopt/skels/free_string.cc
new file mode 100644 (file)
index 0000000..6946f8f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "free_string.h"
+
+void
+free_string_gen_class::generate_free_string(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (has_string_type)
+    {
+      stream << "free_string_field (&(";
+      generate_string (structure, stream, indent + indent_str.length ());
+      stream << "->";
+      generate_string (opt_var, stream, indent + indent_str.length ());
+      stream << "_arg));";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "free_string_field (&(";
+  generate_string (structure, stream, indent + indent_str.length ());
+  stream << "->";
+  generate_string (opt_var, stream, indent + indent_str.length ());
+  stream << "_orig));";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/free_string.h b/cmake/gengetopt/skels/free_string.h
new file mode 100644 (file)
index 0000000..7622617
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef FREE_STRING_GEN_CLASS_H
+#define FREE_STRING_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class free_string_gen_class
+{
+ protected:
+  bool has_string_type;
+  string opt_var;
+  string structure;
+
+ public:
+  free_string_gen_class() :
+    has_string_type (false)
+  {
+  }
+  
+  free_string_gen_class(bool _has_string_type, const string &_opt_var, const string &_structure) :
+    has_string_type (_has_string_type), opt_var (_opt_var), structure (_structure)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_has_string_type(bool _has_string_type)
+  {
+    has_string_type = _has_string_type;
+  }
+
+  void set_opt_var(const string &_opt_var)
+  {
+    opt_var = _opt_var;
+  }
+
+  void set_structure(const string &_structure)
+  {
+    structure = _structure;
+  }
+
+  void generate_free_string(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // FREE_STRING_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/generic_option.cc b/cmake/gengetopt/skels/generic_option.cc
new file mode 100644 (file)
index 0000000..36166f7
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "generic_option.h"
+
+void
+generic_option_gen_class::generate_generic_option(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (has_short_option)
+    {
+      stream << "case '";
+      generate_string (short_option, stream, indent + indent_str.length ());
+      stream << "':    /* ";
+      generate_string (option_comment, stream, indent + indent_str.length ());
+      stream << ".  */";
+      stream << "\n";
+      stream << indent_str;
+      if (( short_option == "?" ))
+        {
+          stream << "\n";
+          stream << indent_str;
+          stream << "  if (optopt) /* '?' represents an unrecognized option */";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    goto failure;";
+          stream << "\n";
+          stream << indent_str;
+        }
+    }
+  else
+    {
+      stream << "/* ";
+      generate_string (option_comment, stream, indent + indent_str.length ());
+      stream << ".  */";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (gen_else, stream, indent + indent_str.length ());
+      stream << "if (strcmp (long_options[option_index].name, \"";
+      generate_string (long_option, stream, indent + indent_str.length ());
+      stream << "\") == 0)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "{";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (option_has_mode)
+    {
+      stream << "  args_info->";
+      generate_string (group_var_name, stream, indent + indent_str.length ());
+      stream << "_mode_counter += 1;";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  if (multiple)
+    {
+      if (option_has_type)
+        {
+          stream << "  if (update_multiple_arg_temp(&";
+          generate_string (structure, stream, indent + indent_str.length ());
+          stream << ", ";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      &(local_args_info.";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_given), optarg, ";
+          generate_string (possible_values, stream, indent + indent_str.length ());
+          stream << ", ";
+          generate_string (default_value, stream, indent + indent_str.length ());
+          stream << ", ";
+          generate_string (arg_type, stream, indent + indent_str.length ());
+          stream << ",";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      \"";
+          generate_string (long_option, stream, indent + indent_str.length ());
+          stream << "\", '";
+          generate_string (short_option, stream, indent + indent_str.length ());
+          stream << "',";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      additional_error))";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    goto failure;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      else
+        {
+          stream << "  local_args_info.";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_given++;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (option_has_group)
+        {
+          stream << "  if (!args_info->";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_group)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    {";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      args_info->";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_group = 1;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      args_info->";
+          generate_string (group_var_name, stream, indent + indent_str.length ());
+          stream << "_group_counter += 1;";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    }";
+          stream << "\n";
+          stream << indent_str;
+        }
+    }
+  else
+    {
+      if (option_has_group)
+        {
+          stream << "  if (args_info->";
+          generate_string (group_var_name, stream, indent + indent_str.length ());
+          stream << "_group_counter && override)";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    reset_group_";
+          generate_string (group_var_name, stream, indent + indent_str.length ());
+          stream << " (args_info);";
+          stream << "\n";
+          stream << indent_str;
+          stream << "  args_info->";
+          generate_string (group_var_name, stream, indent + indent_str.length ());
+          stream << "_group_counter += 1;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      stream << "\n";
+      stream << indent_str;
+      if (( arg_type == "ARG_FLAG" ))
+        {
+          stream << "  if (update_arg((void *)&(args_info->";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_flag), 0, &(args_info->";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_given),";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      &(local_args_info.";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_given), optarg, 0, 0, ";
+          generate_string (arg_type, stream, indent + indent_str.length ());
+          stream << ",";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      check_ambiguity, override, 1, 0, \"";
+          generate_string (long_option, stream, indent + indent_str.length ());
+          stream << "\", '";
+          generate_string (short_option, stream, indent + indent_str.length ());
+          stream << "',";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      additional_error))";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    goto failure;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      else
+        {
+          stream << "  if (update_arg(";
+          if (( arg_type == "ARG_NO" ))
+            {
+              stream << " 0 ";
+            }
+          else
+            {
+              stream << " (void *)&(args_info->";
+              generate_string (option_var_name, stream, indent + indent_str.length ());
+              stream << "_arg)";
+            }
+          stream << ", ";
+          stream << "\n";
+          stream << indent_str;
+          indent = 6;
+          stream << "      ";
+          if (( arg_type == "ARG_NO" ))
+            {
+              stream << " 0 ";
+            }
+          else
+            {
+              stream << " &(args_info->";
+              generate_string (option_var_name, stream, indent + indent_str.length ());
+              stream << "_orig)";
+            }
+          stream << ", &(args_info->";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_given),";
+          indent = 0;
+          stream << "\n";
+          stream << indent_str;
+          stream << "      &(local_args_info.";
+          generate_string (option_var_name, stream, indent + indent_str.length ());
+          stream << "_given), optarg, ";
+          generate_string (possible_values, stream, indent + indent_str.length ());
+          stream << ", ";
+          generate_string (default_value, stream, indent + indent_str.length ());
+          stream << ", ";
+          generate_string (arg_type, stream, indent + indent_str.length ());
+          stream << ",";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      check_ambiguity, override, 0, 0,";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      \"";
+          generate_string (long_option, stream, indent + indent_str.length ());
+          stream << "\", '";
+          generate_string (short_option, stream, indent + indent_str.length ());
+          stream << "',";
+          stream << "\n";
+          stream << indent_str;
+          stream << "      additional_error))";
+          stream << "\n";
+          stream << indent_str;
+          stream << "    goto failure;";
+          stream << "\n";
+          stream << indent_str;
+        }
+      if (( final_instructions != "" ))
+        {
+          indent = 2;
+          stream << "  ";
+          generate_string (final_instructions, stream, indent + indent_str.length ());
+          indent = 0;
+          stream << "\n";
+          stream << indent_str;
+        }
+    }
+  if (has_short_option)
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "  break;";
+    }
+  else
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/generic_option.h b/cmake/gengetopt/skels/generic_option.h
new file mode 100644 (file)
index 0000000..feeed55
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GENERIC_OPTION_GEN_CLASS_H
+#define GENERIC_OPTION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class generic_option_gen_class
+{
+ protected:
+  string arg_type;
+  string default_value;
+  string final_instructions;
+  string gen_else;
+  string group_var_name;
+  bool has_short_option;
+  string long_option;
+  bool multiple;
+  string option_comment;
+  bool option_has_group;
+  bool option_has_mode;
+  bool option_has_type;
+  string option_var_name;
+  string possible_values;
+  string short_option;
+  string structure;
+
+ public:
+  generic_option_gen_class() :
+    has_short_option (false), multiple (false), option_has_group (false), option_has_mode (false), option_has_type (false)
+  {
+  }
+  
+  generic_option_gen_class(const string &_arg_type, const string &_default_value, const string &_final_instructions, const string &_gen_else, const string &_group_var_name, bool _has_short_option, const string &_long_option, bool _multiple, const string &_option_comment, bool _option_has_group, bool _option_has_mode, bool _option_has_type, const string &_option_var_name, const string &_possible_values, const string &_short_option, const string &_structure) :
+    arg_type (_arg_type), default_value (_default_value), final_instructions (_final_instructions), gen_else (_gen_else), group_var_name (_group_var_name), has_short_option (_has_short_option), long_option (_long_option), multiple (_multiple), option_comment (_option_comment), option_has_group (_option_has_group), option_has_mode (_option_has_mode), option_has_type (_option_has_type), option_var_name (_option_var_name), possible_values (_possible_values), short_option (_short_option), structure (_structure)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_arg_type(const string &_arg_type)
+  {
+    arg_type = _arg_type;
+  }
+
+  void set_default_value(const string &_default_value)
+  {
+    default_value = _default_value;
+  }
+
+  void set_final_instructions(const string &_final_instructions)
+  {
+    final_instructions = _final_instructions;
+  }
+
+  void set_gen_else(const string &_gen_else)
+  {
+    gen_else = _gen_else;
+  }
+
+  void set_group_var_name(const string &_group_var_name)
+  {
+    group_var_name = _group_var_name;
+  }
+
+  void set_has_short_option(bool _has_short_option)
+  {
+    has_short_option = _has_short_option;
+  }
+
+  void set_long_option(const string &_long_option)
+  {
+    long_option = _long_option;
+  }
+
+  void set_multiple(bool _multiple)
+  {
+    multiple = _multiple;
+  }
+
+  void set_option_comment(const string &_option_comment)
+  {
+    option_comment = _option_comment;
+  }
+
+  void set_option_has_group(bool _option_has_group)
+  {
+    option_has_group = _option_has_group;
+  }
+
+  void set_option_has_mode(bool _option_has_mode)
+  {
+    option_has_mode = _option_has_mode;
+  }
+
+  void set_option_has_type(bool _option_has_type)
+  {
+    option_has_type = _option_has_type;
+  }
+
+  void set_option_var_name(const string &_option_var_name)
+  {
+    option_var_name = _option_var_name;
+  }
+
+  void set_possible_values(const string &_possible_values)
+  {
+    possible_values = _possible_values;
+  }
+
+  void set_short_option(const string &_short_option)
+  {
+    short_option = _short_option;
+  }
+
+  void set_structure(const string &_structure)
+  {
+    structure = _structure;
+  }
+
+  void generate_generic_option(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // GENERIC_OPTION_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/given_field.cc b/cmake/gengetopt/skels/given_field.cc
new file mode 100644 (file)
index 0000000..d53b61b
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "given_field.h"
+
+void
+given_field_gen_class::generate_given_field(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "unsigned int ";
+  generate_string (arg_name, stream, indent + indent_str.length ());
+  stream << "_given ;  /**< ";
+  stream << "@";
+  stream << "brief Whether ";
+  generate_string (long_opt, stream, indent + indent_str.length ());
+  stream << " was given.  */";
+  stream << "\n";
+  stream << indent_str;
+  if (group)
+    {
+      stream << "  int ";
+      generate_string (arg_name, stream, indent + indent_str.length ());
+      stream << "_group ; /**< ";
+      stream << "@";
+      stream << "brief Whether ";
+      generate_string (long_opt, stream, indent + indent_str.length ());
+      stream << "'s was updated.  */";
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/given_field.h b/cmake/gengetopt/skels/given_field.h
new file mode 100644 (file)
index 0000000..e964db6
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GIVEN_FIELD_GEN_CLASS_H
+#define GIVEN_FIELD_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class given_field_gen_class
+{
+ protected:
+  string arg_name;
+  bool group;
+  string long_opt;
+
+ public:
+  given_field_gen_class() :
+    group (false)
+  {
+  }
+  
+  given_field_gen_class(const string &_arg_name, bool _group, const string &_long_opt) :
+    arg_name (_arg_name), group (_group), long_opt (_long_opt)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_arg_name(const string &_arg_name)
+  {
+    arg_name = _arg_name;
+  }
+
+  void set_group(bool _group)
+  {
+    group = _group;
+  }
+
+  void set_long_opt(const string &_long_opt)
+  {
+    long_opt = _long_opt;
+  }
+
+  void generate_given_field(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // GIVEN_FIELD_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/group_counter.cc b/cmake/gengetopt/skels/group_counter.cc
new file mode 100644 (file)
index 0000000..4c42adb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * File automatically generated by
+ * gengen 1.3 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "group_counter.h"
+
+void
+group_counter_gen_class::generate_group_counter(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "int ";
+  generate_string (group_name, stream, indent + indent_str.length ());
+  stream << "_";
+  generate_string (name, stream, indent + indent_str.length ());
+  stream << "_counter; /**< ";
+  stream << "@";
+  stream << "brief Counter for ";
+  generate_string (name, stream, indent + indent_str.length ());
+  stream << " ";
+  generate_string (group_name, stream, indent + indent_str.length ());
+  stream << " */";
+}
diff --git a/cmake/gengetopt/skels/group_counter.h b/cmake/gengetopt/skels/group_counter.h
new file mode 100644 (file)
index 0000000..5cd8f8c
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * File automatically generated by
+ * gengen 1.3 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GROUP_COUNTER_GEN_CLASS_H
+#define GROUP_COUNTER_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class group_counter_gen_class
+{
+ protected:
+  string group_name;
+  string name;
+
+ public:
+  group_counter_gen_class()
+  {
+  }
+  
+  group_counter_gen_class(const string &_group_name, const string &_name) :
+    group_name (_group_name), name (_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_group_name(const string &_group_name)
+  {
+    group_name = _group_name;
+  }
+
+  void set_name(const string &_name)
+  {
+    name = _name;
+  }
+
+  void generate_group_counter(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // GROUP_COUNTER_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/group_option.cc b/cmake/gengetopt/skels/group_option.cc
new file mode 100644 (file)
index 0000000..714aa01
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "group_option.h"
+
+void
+group_option_gen_class::generate_group_option(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "if (args_info->";
+  generate_string (group_var_name, stream, indent + indent_str.length ());
+  stream << "_group_counter ";
+  generate_string (Comparison_rule, stream, indent + indent_str.length ());
+  stream << ")";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    fprintf (stderr, \"%s: %d options of group ";
+  generate_string (group_name, stream, indent + indent_str.length ());
+  stream << " were given. ";
+  generate_string (number_required, stream, indent + indent_str.length ());
+  stream << " is required%s.\\n\", ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << ", args_info->";
+  generate_string (group_var_name, stream, indent + indent_str.length ());
+  stream << "_group_counter, (additional_error ? additional_error : \"\"));";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    error = 1;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  }";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/group_option.h b/cmake/gengetopt/skels/group_option.h
new file mode 100644 (file)
index 0000000..2f0bd01
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef GROUP_OPTION_GEN_CLASS_H
+#define GROUP_OPTION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class group_option_gen_class
+{
+ protected:
+  string Comparison_rule;
+  string group_name;
+  string group_var_name;
+  string number_required;
+  string package_var_name;
+
+ public:
+  group_option_gen_class()
+  {
+  }
+  
+  group_option_gen_class(const string &_Comparison_rule, const string &_group_name, const string &_group_var_name, const string &_number_required, const string &_package_var_name) :
+    Comparison_rule (_Comparison_rule), group_name (_group_name), group_var_name (_group_var_name), number_required (_number_required), package_var_name (_package_var_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_Comparison_rule(const string &_Comparison_rule)
+  {
+    Comparison_rule = _Comparison_rule;
+  }
+
+  void set_group_name(const string &_group_name)
+  {
+    group_name = _group_name;
+  }
+
+  void set_group_var_name(const string &_group_var_name)
+  {
+    group_var_name = _group_var_name;
+  }
+
+  void set_number_required(const string &_number_required)
+  {
+    number_required = _number_required;
+  }
+
+  void set_package_var_name(const string &_package_var_name)
+  {
+    package_var_name = _package_var_name;
+  }
+
+  void generate_group_option(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // GROUP_OPTION_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/handle_help.cc b/cmake/gengetopt/skels/handle_help.cc
new file mode 100644 (file)
index 0000000..0f9d2cd
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "handle_help.h"
+
+void
+handle_help_gen_class::generate_handle_help(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (detailed_help)
+    {
+      stream << "if (strcmp (long_options[option_index].name, \"detailed-help\") == 0) {";
+      stream << "\n";
+      stream << indent_str;
+      indent = 2;
+      stream << "  ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_print_detailed_help ();";
+      indent = 0;
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      if (full_help)
+        {
+          stream << "if (strcmp (long_options[option_index].name, \"full-help\") == 0) {";
+          stream << "\n";
+          stream << indent_str;
+          indent = 2;
+          stream << "  ";
+          generate_string (parser_name, stream, indent + indent_str.length ());
+          stream << "_print_full_help ();";
+          indent = 0;
+          stream << "\n";
+          stream << indent_str;
+        }
+      else
+        {
+          if (short_opt)
+            {
+              stream << "case 'h':     /* Print help and exit.  */";
+              stream << "\n";
+              stream << indent_str;
+            }
+          else
+            {
+              stream << "if (strcmp (long_options[option_index].name, \"help\") == 0) {";
+              stream << "\n";
+              stream << indent_str;
+            }
+          stream << "  ";
+          generate_string (parser_name, stream, indent + indent_str.length ());
+          stream << "_print_help ();";
+          stream << "\n";
+          stream << indent_str;
+        }
+    }
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_free (&local_args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  exit (EXIT_SUCCESS);";
+  if (( full_help || ( ! short_opt ) ))
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+    }
+}
diff --git a/cmake/gengetopt/skels/handle_help.h b/cmake/gengetopt/skels/handle_help.h
new file mode 100644 (file)
index 0000000..1759c9f
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef HANDLE_HELP_GEN_CLASS_H
+#define HANDLE_HELP_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class handle_help_gen_class
+{
+ protected:
+  bool detailed_help;
+  bool full_help;
+  string parser_name;
+  bool short_opt;
+
+ public:
+  handle_help_gen_class() :
+    detailed_help (false), full_help (false), short_opt (false)
+  {
+  }
+  
+  handle_help_gen_class(bool _detailed_help, bool _full_help, const string &_parser_name, bool _short_opt) :
+    detailed_help (_detailed_help), full_help (_full_help), parser_name (_parser_name), short_opt (_short_opt)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_detailed_help(bool _detailed_help)
+  {
+    detailed_help = _detailed_help;
+  }
+
+  void set_full_help(bool _full_help)
+  {
+    full_help = _full_help;
+  }
+
+  void set_parser_name(const string &_parser_name)
+  {
+    parser_name = _parser_name;
+  }
+
+  void set_short_opt(bool _short_opt)
+  {
+    short_opt = _short_opt;
+  }
+
+  void generate_handle_help(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // HANDLE_HELP_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/handle_version.cc b/cmake/gengetopt/skels/handle_version.cc
new file mode 100644 (file)
index 0000000..1e61456
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "handle_version.h"
+
+void
+handle_version_gen_class::generate_handle_version(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (short_opt)
+    {
+      stream << "case 'V':     /* Print version and exit.  */";
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "if (strcmp (long_options[option_index].name, \"version\") == 0) {";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_print_version ();";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_free (&local_args_info);";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  exit (EXIT_SUCCESS);";
+  if (( ! short_opt ))
+    {
+      stream << "\n";
+      stream << indent_str;
+      stream << "}";
+    }
+}
diff --git a/cmake/gengetopt/skels/handle_version.h b/cmake/gengetopt/skels/handle_version.h
new file mode 100644 (file)
index 0000000..c7b2e6d
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * File automatically generated by
+ * gengen 1.4.1 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef HANDLE_VERSION_GEN_CLASS_H
+#define HANDLE_VERSION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class handle_version_gen_class
+{
+ protected:
+  string parser_name;
+  bool short_opt;
+
+ public:
+  handle_version_gen_class() :
+    short_opt (false)
+  {
+  }
+  
+  handle_version_gen_class(const string &_parser_name, bool _short_opt) :
+    parser_name (_parser_name), short_opt (_short_opt)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_parser_name(const string &_parser_name)
+  {
+    parser_name = _parser_name;
+  }
+
+  void set_short_opt(bool _short_opt)
+  {
+    short_opt = _short_opt;
+  }
+
+  void generate_handle_version(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // HANDLE_VERSION_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/header.cc b/cmake/gengetopt/skels/header.cc
new file mode 100644 (file)
index 0000000..92c3d52
--- /dev/null
@@ -0,0 +1,1077 @@
+/*
+ * File automatically generated by
+ * gengen 1.4 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "header.h"
+
+void
+header_gen_class::generate_header(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "/** ";
+  stream << "@";
+  stream << "file ";
+  generate_string (header_file_name, stream, indent + indent_str.length ());
+  stream << ".";
+  generate_string (header_file_ext, stream, indent + indent_str.length ());
+  stream << "\n";
+  stream << indent_str;
+  stream << " *  ";
+  stream << "@";
+  stream << "brief The header file for the command line option parser";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *  generated by GNU Gengetopt ";
+  generate_string (generator_version, stream, indent + indent_str.length ());
+  stream << "\n";
+  stream << indent_str;
+  stream << " *  http://www.gnu.org/software/gengetopt.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *  DO NOT modify this file, since it can be overwritten";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *  ";
+  stream << "@";
+  stream << "author GNU Gengetopt by Lorenzo Bettini */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifndef ";
+  generate_string (ifndefname, stream, indent + indent_str.length ());
+  stream << "_H";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#define ";
+  generate_string (ifndefname, stream, indent + indent_str.length ());
+  stream << "_H";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/* If we use autoconf.  */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifdef HAVE_CONFIG_H";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#include \"config.h\"";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#include <stdio.h> /* for FILE */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifdef __cplusplus";
+  stream << "\n";
+  stream << indent_str;
+  stream << "extern \"C\" {";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif /* __cplusplus */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifndef ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << "\n";
+  stream << indent_str;
+  stream << "/** ";
+  stream << "@";
+  stream << "brief the program name (used for printing errors) */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#define ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << " ";
+  generate_string (package_var_val, stream, indent + indent_str.length ());
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifndef ";
+  generate_string (package_var_name, stream, indent + indent_str.length ());
+  stream << "_NAME";
+  stream << "\n";
+  stream << indent_str;
+  stream << "/** ";
+  stream << "@";
+  stream << "brief the complete program name (used for help and version) */";
+  stream << "\n";
+  stream << indent_str;
+  if (( package_var_val != "PACKAGE" ))
+    {
+      stream << "#define ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << "_NAME ";
+      generate_string (package_var_val, stream, indent + indent_str.length ());
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "#ifdef PACKAGE_NAME";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#define ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << "_NAME PACKAGE_NAME";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#else";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#define ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << "_NAME PACKAGE";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#endif";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifndef ";
+  generate_string (version_var_name, stream, indent + indent_str.length ());
+  stream << "\n";
+  stream << indent_str;
+  stream << "/** ";
+  stream << "@";
+  stream << "brief the program version */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#define ";
+  generate_string (version_var_name, stream, indent + indent_str.length ());
+  stream << " ";
+  generate_string (version_var_val, stream, indent + indent_str.length ());
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif";
+  stream << "\n";
+  stream << indent_str;
+  if (enum_types.size () > 0)
+    generate_string (enum_types, stream, indent + indent_str.length ());
+  else
+    generate_enum_types (stream, indent + indent_str.length ());
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/** ";
+  stream << "@";
+  stream << "brief Where the command line options are stored */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  if (option_arg.size () > 0)
+    generate_string (option_arg, stream, indent + indent_str.length ());
+  else
+    generate_option_arg (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  if (option_given.size () > 0)
+    generate_string (option_given, stream, indent + indent_str.length ());
+  else
+    generate_option_given (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  if (group_counters.size () > 0)
+    generate_string (group_counters, stream, indent + indent_str.length ());
+  else
+    generate_group_counters (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  indent = 2;
+  if (mode_counters.size () > 0)
+    generate_string (mode_counters, stream, indent + indent_str.length ());
+  else
+    generate_mode_counters (stream, indent + indent_str.length ());
+  indent = 0;
+  stream << indent_str;
+  stream << "} ;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/** ";
+  stream << "@";
+  stream << "brief The additional parameters to pass to parser functions */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int override; /**< ";
+  stream << "@";
+  stream << "brief whether to override possibly already present options (default 0) */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int initialize; /**< ";
+  stream << "@";
+  stream << "brief whether to initialize the option structure ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " (default 1) */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int check_required; /**< ";
+  stream << "@";
+  stream << "brief whether to check that all required options were provided (default 1) */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int check_ambiguity; /**< ";
+  stream << "@";
+  stream << "brief whether to check for options already specified in the option structure ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " (default 0) */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int print_errors; /**< ";
+  stream << "@";
+  stream << "brief whether getopt_long should print an error message for a bad option (default 1) */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "} ;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/** ";
+  stream << "@";
+  stream << "brief the purpose string of the program */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "extern const char *";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_purpose;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "/** ";
+  stream << "@";
+  stream << "brief the usage string of the program */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "extern const char *";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_usage;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "/** ";
+  stream << "@";
+  stream << "brief all the lines making the help output */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "extern const char *";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << "_help[];";
+  stream << "\n";
+  stream << indent_str;
+  if (has_hidden)
+    {
+      stream << "/** ";
+      stream << "@";
+      stream << "brief all the lines making the full help output (including hidden options) */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "extern const char *";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << "_full_help[];";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_details)
+    {
+      stream << "/** ";
+      stream << "@";
+      stream << "brief all the lines making the detailed help output (including hidden options and details) */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "extern const char *";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << "_detailed_help[];";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * The command line parser";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param argc the number of command line options";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param argv the command line options";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param args_info the structure where option information will be stored";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "return 0 if everything went fine, NON 0 if an error took place";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "int ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << " (int argc, char **argv,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * The command line parser (version with additional parameters - deprecated)";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param argc the number of command line options";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param argv the command line options";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param args_info the structure where option information will be stored";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param override whether to override possibly already present options";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param initialize whether to initialize the option structure my_args_info";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param check_required whether to check that all required options were provided";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "return 0 if everything went fine, NON 0 if an error took place";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "deprecated use ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_ext() instead";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "int ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "2 (int argc, char **argv,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  int override, int initialize, int check_required);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * The command line parser (version with additional parameters)";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param argc the number of command line options";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param argv the command line options";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param args_info the structure where option information will be stored";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param params additional parameters for the parser";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "return 0 if everything went fine, NON 0 if an error took place";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "int ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_ext (int argc, char **argv,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *params);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Save the contents of the option struct into an already open FILE stream.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param outfile the stream where to dump options";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param args_info the option struct to dump";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "return 0 if everything went fine, NON 0 if an error took place";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "int ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_dump(FILE *outfile,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Save the contents of the option struct into a (text) file.";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * This file can be read by the config file parser (if generated by gengetopt)";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param filename the file where to save";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param args_info the option struct to save";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "return 0 if everything went fine, NON 0 if an error took place";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "int ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_file_save(const char *filename,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Print the help";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_print_help(void);";
+  stream << "\n";
+  stream << indent_str;
+  if (has_hidden)
+    {
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * Print the full help (including hidden options)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "void ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_print_full_help(void);";
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (has_details)
+    {
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * Print the detailed help (including hidden options and details)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "void ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_print_detailed_help(void);";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Print the version";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_print_version(void);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Initializes all the fields a ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params structure ";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * to their default values";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param params the structure to initialize";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params_init(struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *params);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Allocates dynamically a ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params structure and initializes";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * all its fields to their default values";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "return the created and initialized ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params structure";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "struct ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params *";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_params_create(void);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Initializes the passed ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " structure's fields";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * (also set default values for options that have a default)";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param args_info the structure to initialize";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_init (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Deallocates the string fields of the ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " structure";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * (but does not deallocate the structure itself)";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param args_info the structure to deallocate";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "void ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_free (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (generate_config_parser)
+    {
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * The config file parser (deprecated version)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param filename the name of the config file";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param args_info the structure where option information will be stored";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param override whether to override possibly already present options";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param initialize whether to initialize the option structure my_args_info";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param check_required whether to check that all required options were provided";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "return 0 if everything went fine, NON 0 if an error took place";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "deprecated use ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_config_file() instead";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "int ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_configfile (const char *filename,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int override, int initialize, int check_required);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * The config file parser";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param filename the name of the config file";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param args_info the structure where option information will be stored";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param params additional parameters for the parser";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "return 0 if everything went fine, NON 0 if an error took place";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "int ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_config_file (const char *filename,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_params *params);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  if (generate_string_parser)
+    {
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * The string parser (interprets the passed string as a command line)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param cmdline the command line stirng";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param args_info the structure where option information will be stored";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param prog_name the name of the program that will be used to print";
+      stream << "\n";
+      stream << indent_str;
+      stream << " *   possible errors";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "return 0 if everything went fine, NON 0 if an error took place";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "int ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string (const char *cmdline, struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  const char *prog_name);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * The string parser (version with additional parameters - deprecated)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param cmdline the command line stirng";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param args_info the structure where option information will be stored";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param prog_name the name of the program that will be used to print";
+      stream << "\n";
+      stream << indent_str;
+      stream << " *   possible errors";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param override whether to override possibly already present options";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param initialize whether to initialize the option structure my_args_info";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param check_required whether to check that all required options were provided";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "return 0 if everything went fine, NON 0 if an error took place";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "deprecated use ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string_ext() instead";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "int ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string2 (const char *cmdline, struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  const char *prog_name,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  int override, int initialize, int check_required);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "/**";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * The string parser (version with additional parameters)";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param cmdline the command line stirng";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param args_info the structure where option information will be stored";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param prog_name the name of the program that will be used to print";
+      stream << "\n";
+      stream << indent_str;
+      stream << " *   possible errors";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "param params additional parameters for the parser";
+      stream << "\n";
+      stream << indent_str;
+      stream << " * ";
+      stream << "@";
+      stream << "return 0 if everything went fine, NON 0 if an error took place";
+      stream << "\n";
+      stream << indent_str;
+      stream << " */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "int ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_string_ext (const char *cmdline, struct ";
+      generate_string (args_info, stream, indent + indent_str.length ());
+      stream << " *args_info,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  const char *prog_name,";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  struct ";
+      generate_string (parser_name, stream, indent + indent_str.length ());
+      stream << "_params *params);";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "/**";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * Checks that all the required options were specified";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param args_info the structure to check";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "param prog_name the name of the program that will be used to print";
+  stream << "\n";
+  stream << indent_str;
+  stream << " *   possible errors";
+  stream << "\n";
+  stream << indent_str;
+  stream << " * ";
+  stream << "@";
+  stream << "return";
+  stream << "\n";
+  stream << indent_str;
+  stream << " */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "int ";
+  generate_string (parser_name, stream, indent + indent_str.length ());
+  stream << "_required (struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  const char *prog_name);";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  if (option_values_decl.size () > 0)
+    generate_string (option_values_decl, stream, indent + indent_str.length ());
+  else
+    generate_option_values_decl (stream, indent + indent_str.length ());
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+  stream << "#ifdef __cplusplus";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif /* __cplusplus */";
+  stream << "\n";
+  stream << indent_str;
+  stream << "#endif /* ";
+  generate_string (ifndefname, stream, indent + indent_str.length ());
+  stream << "_H */";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/header.h b/cmake/gengetopt/skels/header.h
new file mode 100644 (file)
index 0000000..19c725a
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * File automatically generated by
+ * gengen 1.4 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef HEADER_GEN_CLASS_H
+#define HEADER_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class header_gen_class
+{
+ protected:
+  string args_info;
+  string enum_types;
+  bool generate_config_parser;
+  bool generate_string_parser;
+  string generator_version;
+  string group_counters;
+  bool has_details;
+  bool has_hidden;
+  string header_file_ext;
+  string header_file_name;
+  string ifndefname;
+  string mode_counters;
+  string option_arg;
+  string option_given;
+  string option_values_decl;
+  string package_var_name;
+  string package_var_val;
+  string parser_name;
+  string version_var_name;
+  string version_var_val;
+
+ public:
+  header_gen_class() :
+    generate_config_parser (false), generate_string_parser (false), has_details (false), has_hidden (false)
+  {
+  }
+  
+  header_gen_class(const string &_args_info, const string &_enum_types, bool _generate_config_parser, bool _generate_string_parser, const string &_generator_version, const string &_group_counters, bool _has_details, bool _has_hidden, const string &_header_file_ext, const string &_header_file_name, const string &_ifndefname, const string &_mode_counters, const string &_option_arg, const string &_option_given, const string &_option_values_decl, const string &_package_var_name, const string &_package_var_val, const string &_parser_name, const string &_version_var_name, const string &_version_var_val) :
+    args_info (_args_info), enum_types (_enum_types), generate_config_parser (_generate_config_parser), generate_string_parser (_generate_string_parser), generator_version (_generator_version), group_counters (_group_counters), has_details (_has_details), has_hidden (_has_hidden), header_file_ext (_header_file_ext), header_file_name (_header_file_name), ifndefname (_ifndefname), mode_counters (_mode_counters), option_arg (_option_arg), option_given (_option_given), option_values_decl (_option_values_decl), package_var_name (_package_var_name), package_var_val (_package_var_val), parser_name (_parser_name), version_var_name (_version_var_name), version_var_val (_version_var_val)
+  {
+  }
+
+  virtual ~header_gen_class()
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_args_info(const string &_args_info)
+  {
+    args_info = _args_info;
+  }
+
+  virtual void generate_enum_types(ostream &stream, unsigned int indent) = 0;
+
+  void set_enum_types(const string &_enum_types)
+  {
+    enum_types = _enum_types;
+  }
+
+  void set_generate_config_parser(bool _generate_config_parser)
+  {
+    generate_config_parser = _generate_config_parser;
+  }
+
+  void set_generate_string_parser(bool _generate_string_parser)
+  {
+    generate_string_parser = _generate_string_parser;
+  }
+
+  void set_generator_version(const string &_generator_version)
+  {
+    generator_version = _generator_version;
+  }
+
+  virtual void generate_group_counters(ostream &stream, unsigned int indent) = 0;
+
+  void set_group_counters(const string &_group_counters)
+  {
+    group_counters = _group_counters;
+  }
+
+  void set_has_details(bool _has_details)
+  {
+    has_details = _has_details;
+  }
+
+  void set_has_hidden(bool _has_hidden)
+  {
+    has_hidden = _has_hidden;
+  }
+
+  void set_header_file_ext(const string &_header_file_ext)
+  {
+    header_file_ext = _header_file_ext;
+  }
+
+  void set_header_file_name(const string &_header_file_name)
+  {
+    header_file_name = _header_file_name;
+  }
+
+  void set_ifndefname(const string &_ifndefname)
+  {
+    ifndefname = _ifndefname;
+  }
+
+  virtual void generate_mode_counters(ostream &stream, unsigned int indent) = 0;
+
+  void set_mode_counters(const string &_mode_counters)
+  {
+    mode_counters = _mode_counters;
+  }
+
+  virtual void generate_option_arg(ostream &stream, unsigned int indent) = 0;
+
+  void set_option_arg(const string &_option_arg)
+  {
+    option_arg = _option_arg;
+  }
+
+  virtual void generate_option_given(ostream &stream, unsigned int indent) = 0;
+
+  void set_option_given(const string &_option_given)
+  {
+    option_given = _option_given;
+  }
+
+  virtual void generate_option_values_decl(ostream &stream, unsigned int indent) = 0;
+
+  void set_option_values_decl(const string &_option_values_decl)
+  {
+    option_values_decl = _option_values_decl;
+  }
+
+  void set_package_var_name(const string &_package_var_name)
+  {
+    package_var_name = _package_var_name;
+  }
+
+  void set_package_var_val(const string &_package_var_val)
+  {
+    package_var_val = _package_var_val;
+  }
+
+  void set_parser_name(const string &_parser_name)
+  {
+    parser_name = _parser_name;
+  }
+
+  void set_version_var_name(const string &_version_var_name)
+  {
+    version_var_name = _version_var_name;
+  }
+
+  void set_version_var_val(const string &_version_var_val)
+  {
+    version_var_val = _version_var_val;
+  }
+
+  void generate_header(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // HEADER_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/init_args_info.cc b/cmake/gengetopt/skels/init_args_info.cc
new file mode 100644 (file)
index 0000000..1b59bed
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "init_args_info.h"
+
+void
+init_args_info_gen_class::generate_init_args_info(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "args_info->";
+  generate_string (var_arg, stream, indent + indent_str.length ());
+  stream << "_help = ";
+  generate_string (help_strings, stream, indent + indent_str.length ());
+  stream << "[";
+  generate_string (num, stream, indent + indent_str.length ());
+  stream << "] ;";
+  stream << "\n";
+  stream << indent_str;
+  if (multiple)
+    {
+      stream << "args_info->";
+      generate_string (var_arg, stream, indent + indent_str.length ());
+      stream << "_min = ";
+      generate_string (min, stream, indent + indent_str.length ());
+      stream << ";";
+      stream << "\n";
+      stream << indent_str;
+      stream << "args_info->";
+      generate_string (var_arg, stream, indent + indent_str.length ());
+      stream << "_max = ";
+      generate_string (max, stream, indent + indent_str.length ());
+      stream << ";";
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/init_args_info.h b/cmake/gengetopt/skels/init_args_info.h
new file mode 100644 (file)
index 0000000..d4fdcce
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef INIT_ARGS_INFO_GEN_CLASS_H
+#define INIT_ARGS_INFO_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class init_args_info_gen_class
+{
+ protected:
+  string help_strings;
+  string max;
+  string min;
+  bool multiple;
+  string num;
+  string var_arg;
+
+ public:
+  init_args_info_gen_class() :
+    multiple (false)
+  {
+  }
+  
+  init_args_info_gen_class(const string &_help_strings, const string &_max, const string &_min, bool _multiple, const string &_num, const string &_var_arg) :
+    help_strings (_help_strings), max (_max), min (_min), multiple (_multiple), num (_num), var_arg (_var_arg)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_help_strings(const string &_help_strings)
+  {
+    help_strings = _help_strings;
+  }
+
+  void set_max(const string &_max)
+  {
+    max = _max;
+  }
+
+  void set_min(const string &_min)
+  {
+    min = _min;
+  }
+
+  void set_multiple(bool _multiple)
+  {
+    multiple = _multiple;
+  }
+
+  void set_num(const string &_num)
+  {
+    num = _num;
+  }
+
+  void set_var_arg(const string &_var_arg)
+  {
+    var_arg = _var_arg;
+  }
+
+  void generate_init_args_info(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // INIT_ARGS_INFO_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/multiple_fill_array.cc b/cmake/gengetopt/skels/multiple_fill_array.cc
new file mode 100644 (file)
index 0000000..ab5f06f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "multiple_fill_array.h"
+
+void
+multiple_fill_array_gen_class::generate_multiple_fill_array(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (( default_value != "0" ))
+    {
+      stream << "multiple_default_value.";
+      if (( arg_type == "ARG_STRING" ))
+        {
+          stream << "default_";
+        }
+      generate_string (type, stream, indent + indent_str.length ());
+      stream << "_arg = ";
+      generate_string (default_value, stream, indent + indent_str.length ());
+      stream << ";";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "update_multiple_arg((void *)&(args_info->";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_arg),";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  &(args_info->";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_orig), args_info->";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_given,";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  local_args_info.";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_given, ";
+  if (( default_value != "0" ))
+    {
+      stream << "&multiple_default_value";
+    }
+  else
+    {
+      stream << "0";
+    }
+  stream << ",";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (arg_type, stream, indent + indent_str.length ());
+  stream << ", ";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_list);";
+}
diff --git a/cmake/gengetopt/skels/multiple_fill_array.h b/cmake/gengetopt/skels/multiple_fill_array.h
new file mode 100644 (file)
index 0000000..9249fd5
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef MULTIPLE_FILL_ARRAY_GEN_CLASS_H
+#define MULTIPLE_FILL_ARRAY_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class multiple_fill_array_gen_class
+{
+ protected:
+  string arg_type;
+  string default_value;
+  string option_var_name;
+  string type;
+
+ public:
+  multiple_fill_array_gen_class()
+  {
+  }
+  
+  multiple_fill_array_gen_class(const string &_arg_type, const string &_default_value, const string &_option_var_name, const string &_type) :
+    arg_type (_arg_type), default_value (_default_value), option_var_name (_option_var_name), type (_type)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_arg_type(const string &_arg_type)
+  {
+    arg_type = _arg_type;
+  }
+
+  void set_default_value(const string &_default_value)
+  {
+    default_value = _default_value;
+  }
+
+  void set_option_var_name(const string &_option_var_name)
+  {
+    option_var_name = _option_var_name;
+  }
+
+  void set_type(const string &_type)
+  {
+    type = _type;
+  }
+
+  void generate_multiple_fill_array(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // MULTIPLE_FILL_ARRAY_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/multiple_opt_list.cc b/cmake/gengetopt/skels/multiple_opt_list.cc
new file mode 100644 (file)
index 0000000..f8b6acd
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "multiple_opt_list.h"
+
+void
+multiple_opt_list_gen_class::generate_multiple_opt_list(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "struct generic_list * ";
+  generate_string (arg_name, stream, indent + indent_str.length ());
+  stream << "_list = NULL;";
+}
diff --git a/cmake/gengetopt/skels/multiple_opt_list.h b/cmake/gengetopt/skels/multiple_opt_list.h
new file mode 100644 (file)
index 0000000..ee0e214
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef MULTIPLE_OPT_LIST_GEN_CLASS_H
+#define MULTIPLE_OPT_LIST_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class multiple_opt_list_gen_class
+{
+ protected:
+  string arg_name;
+
+ public:
+  multiple_opt_list_gen_class()
+  {
+  }
+  
+  multiple_opt_list_gen_class(const string &_arg_name) :
+    arg_name (_arg_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_arg_name(const string &_arg_name)
+  {
+    arg_name = _arg_name;
+  }
+
+  void generate_multiple_opt_list(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // MULTIPLE_OPT_LIST_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/option_arg.cc b/cmake/gengetopt/skels/option_arg.cc
new file mode 100644 (file)
index 0000000..5b02e04
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * File automatically generated by
+ * gengen 1.3 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "option_arg.h"
+
+void
+option_arg_gen_class::generate_option_arg(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (long_long_arg)
+    {
+      stream << "#ifdef HAVE_LONG_LONG";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (type, stream, indent + indent_str.length ());
+      stream << " ";
+      generate_string (name, stream, indent + indent_str.length ());
+      stream << "_arg; /**< ";
+      stream << "@";
+      stream << "brief ";
+      generate_string (desc, stream, indent + indent_str.length ());
+      if (has_default)
+        {
+          stream << " (default=";
+          generate_string (default_value, stream, indent + indent_str.length ());
+          stream << ")";
+        }
+      stream << ".  */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#else";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (longtype, stream, indent + indent_str.length ());
+      stream << " ";
+      generate_string (name, stream, indent + indent_str.length ());
+      stream << "_arg; /**< ";
+      stream << "@";
+      stream << "brief ";
+      generate_string (desc, stream, indent + indent_str.length ());
+      if (has_default)
+        {
+          stream << " (default=";
+          generate_string (default_value, stream, indent + indent_str.length ());
+          stream << ")";
+        }
+      stream << ".  */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "#endif";
+      stream << "\n";
+      stream << indent_str;
+      generate_string (origtype, stream, indent + indent_str.length ());
+      stream << " ";
+      generate_string (name, stream, indent + indent_str.length ());
+      stream << "_orig;        /**< ";
+      stream << "@";
+      stream << "brief ";
+      generate_string (desc, stream, indent + indent_str.length ());
+      stream << " original value given at command line.  */";
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      if (flag_arg)
+        {
+          generate_string (type, stream, indent + indent_str.length ());
+          stream << " ";
+          generate_string (name, stream, indent + indent_str.length ());
+          stream << "_flag;    /**< ";
+          stream << "@";
+          stream << "brief ";
+          generate_string (desc, stream, indent + indent_str.length ());
+          stream << " (default=";
+          if (default_on)
+            {
+              stream << "on";
+            }
+          else
+            {
+              stream << "off";
+            }
+          stream << ").  */";
+          stream << "\n";
+          stream << indent_str;
+        }
+      else
+        {
+          if (has_arg)
+            {
+              if (has_enum)
+                {
+                  stream << "enum enum_";
+                  generate_string (name, stream, indent + indent_str.length ());
+                  stream << " ";
+                  if (multiple)
+                    {
+                      stream << "*";
+                    }
+                  generate_string (name, stream, indent + indent_str.length ());
+                  stream << "_arg;     /**< ";
+                  stream << "@";
+                  stream << "brief ";
+                  generate_string (desc, stream, indent + indent_str.length ());
+                  if (has_default)
+                    {
+                      stream << " (default='";
+                      generate_string (default_value, stream, indent + indent_str.length ());
+                      stream << "')";
+                    }
+                  stream << ".  */";
+                  stream << "\n";
+                  stream << indent_str;
+                }
+              else
+                {
+                  generate_string (type, stream, indent + indent_str.length ());
+                  stream << " ";
+                  generate_string (name, stream, indent + indent_str.length ());
+                  stream << "_arg;     /**< ";
+                  stream << "@";
+                  stream << "brief ";
+                  generate_string (desc, stream, indent + indent_str.length ());
+                  if (has_default)
+                    {
+                      stream << " (default='";
+                      generate_string (default_value, stream, indent + indent_str.length ());
+                      stream << "')";
+                    }
+                  stream << ".  */";
+                  stream << "\n";
+                  stream << indent_str;
+                }
+              generate_string (origtype, stream, indent + indent_str.length ());
+              stream << " ";
+              generate_string (name, stream, indent + indent_str.length ());
+              stream << "_orig;        /**< ";
+              stream << "@";
+              stream << "brief ";
+              generate_string (desc, stream, indent + indent_str.length ());
+              stream << " original value given at command line.  */";
+              stream << "\n";
+              stream << indent_str;
+            }
+        }
+    }
+  if (multiple)
+    {
+      stream << "unsigned int ";
+      generate_string (name, stream, indent + indent_str.length ());
+      stream << "_min; /**< ";
+      stream << "@";
+      stream << "brief ";
+      generate_string (desc, stream, indent + indent_str.length ());
+      stream << "'s minimum occurreces */";
+      stream << "\n";
+      stream << indent_str;
+      stream << "unsigned int ";
+      generate_string (name, stream, indent + indent_str.length ());
+      stream << "_max; /**< ";
+      stream << "@";
+      stream << "brief ";
+      generate_string (desc, stream, indent + indent_str.length ());
+      stream << "'s maximum occurreces */";
+      stream << "\n";
+      stream << indent_str;
+    }
+  stream << "const char *";
+  generate_string (name, stream, indent + indent_str.length ());
+  stream << "_help; /**< ";
+  stream << "@";
+  stream << "brief ";
+  generate_string (desc, stream, indent + indent_str.length ());
+  stream << " help description.  */";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/option_arg.h b/cmake/gengetopt/skels/option_arg.h
new file mode 100644 (file)
index 0000000..e443b79
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * File automatically generated by
+ * gengen 1.3 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef OPTION_ARG_GEN_CLASS_H
+#define OPTION_ARG_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class option_arg_gen_class
+{
+ protected:
+  bool default_on;
+  string default_value;
+  string desc;
+  bool flag_arg;
+  bool has_arg;
+  bool has_default;
+  bool has_enum;
+  bool long_long_arg;
+  string longtype;
+  bool multiple;
+  string name;
+  string origtype;
+  string type;
+
+ public:
+  option_arg_gen_class() :
+    default_on (false), flag_arg (false), has_arg (false), has_default (false), has_enum (false), long_long_arg (false), multiple (false)
+  {
+  }
+  
+  option_arg_gen_class(bool _default_on, const string &_default_value, const string &_desc, bool _flag_arg, bool _has_arg, bool _has_default, bool _has_enum, bool _long_long_arg, const string &_longtype, bool _multiple, const string &_name, const string &_origtype, const string &_type) :
+    default_on (_default_on), default_value (_default_value), desc (_desc), flag_arg (_flag_arg), has_arg (_has_arg), has_default (_has_default), has_enum (_has_enum), long_long_arg (_long_long_arg), longtype (_longtype), multiple (_multiple), name (_name), origtype (_origtype), type (_type)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_default_on(bool _default_on)
+  {
+    default_on = _default_on;
+  }
+
+  void set_default_value(const string &_default_value)
+  {
+    default_value = _default_value;
+  }
+
+  void set_desc(const string &_desc)
+  {
+    desc = _desc;
+  }
+
+  void set_flag_arg(bool _flag_arg)
+  {
+    flag_arg = _flag_arg;
+  }
+
+  void set_has_arg(bool _has_arg)
+  {
+    has_arg = _has_arg;
+  }
+
+  void set_has_default(bool _has_default)
+  {
+    has_default = _has_default;
+  }
+
+  void set_has_enum(bool _has_enum)
+  {
+    has_enum = _has_enum;
+  }
+
+  void set_long_long_arg(bool _long_long_arg)
+  {
+    long_long_arg = _long_long_arg;
+  }
+
+  void set_longtype(const string &_longtype)
+  {
+    longtype = _longtype;
+  }
+
+  void set_multiple(bool _multiple)
+  {
+    multiple = _multiple;
+  }
+
+  void set_name(const string &_name)
+  {
+    name = _name;
+  }
+
+  void set_origtype(const string &_origtype)
+  {
+    origtype = _origtype;
+  }
+
+  void set_type(const string &_type)
+  {
+    type = _type;
+  }
+
+  void generate_option_arg(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // OPTION_ARG_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/print_help_string.cc b/cmake/gengetopt/skels/print_help_string.cc
new file mode 100644 (file)
index 0000000..9eaa514
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "print_help_string.h"
+
+void
+print_help_string_gen_class::generate_print_help_string(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (shared)
+    {
+      generate_string (target, stream, indent + indent_str.length ());
+      stream << "[";
+      generate_string (index, stream, indent + indent_str.length ());
+      stream << "] = ";
+      if (last)
+        {
+          stream << "0; ";
+        }
+      else
+        {
+          generate_string (from, stream, indent + indent_str.length ());
+          stream << "[";
+          generate_string (full_index, stream, indent + indent_str.length ());
+          stream << "];";
+        }
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "\"";
+      generate_string (helpstring, stream, indent + indent_str.length ());
+      stream << "\",";
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/print_help_string.h b/cmake/gengetopt/skels/print_help_string.h
new file mode 100644 (file)
index 0000000..5179816
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef PRINT_HELP_STRING_GEN_CLASS_H
+#define PRINT_HELP_STRING_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class print_help_string_gen_class
+{
+ protected:
+  string from;
+  string full_index;
+  string helpstring;
+  string index;
+  bool last;
+  bool shared;
+  string target;
+
+ public:
+  print_help_string_gen_class() :
+    last (false), shared (false)
+  {
+  }
+  
+  print_help_string_gen_class(const string &_from, const string &_full_index, const string &_helpstring, const string &_index, bool _last, bool _shared, const string &_target) :
+    from (_from), full_index (_full_index), helpstring (_helpstring), index (_index), last (_last), shared (_shared), target (_target)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_from(const string &_from)
+  {
+    from = _from;
+  }
+
+  void set_full_index(const string &_full_index)
+  {
+    full_index = _full_index;
+  }
+
+  void set_helpstring(const string &_helpstring)
+  {
+    helpstring = _helpstring;
+  }
+
+  void set_index(const string &_index)
+  {
+    index = _index;
+  }
+
+  void set_last(bool _last)
+  {
+    last = _last;
+  }
+
+  void set_shared(bool _shared)
+  {
+    shared = _shared;
+  }
+
+  void set_target(const string &_target)
+  {
+    target = _target;
+  }
+
+  void generate_print_help_string(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // PRINT_HELP_STRING_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/required_option.cc b/cmake/gengetopt/skels/required_option.cc
new file mode 100644 (file)
index 0000000..864a9e1
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "required_option.h"
+
+void
+required_option_gen_class::generate_required_option(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  if (checkrange)
+    {
+      stream << "if (";
+      generate_string (mode_condition, stream, indent + indent_str.length ());
+      stream << "check_multiple_option_occurrences(";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << ", args_info->";
+      generate_string (option_var_name, stream, indent + indent_str.length ());
+      stream << "_given, args_info->";
+      generate_string (option_var_name, stream, indent + indent_str.length ());
+      stream << "_min, args_info->";
+      generate_string (option_var_name, stream, indent + indent_str.length ());
+      stream << "_max, \"";
+      generate_string (option_descr, stream, indent + indent_str.length ());
+      stream << "\"))";
+      stream << "\n";
+      stream << indent_str;
+      stream << "   error = 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+  else
+    {
+      stream << "if (";
+      generate_string (mode_condition, stream, indent + indent_str.length ());
+      stream << "! args_info->";
+      generate_string (option_var_name, stream, indent + indent_str.length ());
+      stream << "_given)";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  {";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    fprintf (stderr, \"%s: ";
+      generate_string (option_descr, stream, indent + indent_str.length ());
+      stream << " option required%s\\n\", ";
+      generate_string (package_var_name, stream, indent + indent_str.length ());
+      stream << ", (additional_error ? additional_error : \"\"));";
+      stream << "\n";
+      stream << indent_str;
+      stream << "    error = 1;";
+      stream << "\n";
+      stream << indent_str;
+      stream << "  }";
+      stream << "\n";
+      stream << indent_str;
+      stream << "\n";
+      stream << indent_str;
+    }
+}
diff --git a/cmake/gengetopt/skels/required_option.h b/cmake/gengetopt/skels/required_option.h
new file mode 100644 (file)
index 0000000..9a27551
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef REQUIRED_OPTION_GEN_CLASS_H
+#define REQUIRED_OPTION_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class required_option_gen_class
+{
+ protected:
+  bool checkrange;
+  string mode_condition;
+  string option_descr;
+  string option_var_name;
+  string package_var_name;
+
+ public:
+  required_option_gen_class() :
+    checkrange (false)
+  {
+  }
+  
+  required_option_gen_class(bool _checkrange, const string &_mode_condition, const string &_option_descr, const string &_option_var_name, const string &_package_var_name) :
+    checkrange (_checkrange), mode_condition (_mode_condition), option_descr (_option_descr), option_var_name (_option_var_name), package_var_name (_package_var_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_checkrange(bool _checkrange)
+  {
+    checkrange = _checkrange;
+  }
+
+  void set_mode_condition(const string &_mode_condition)
+  {
+    mode_condition = _mode_condition;
+  }
+
+  void set_option_descr(const string &_option_descr)
+  {
+    option_descr = _option_descr;
+  }
+
+  void set_option_var_name(const string &_option_var_name)
+  {
+    option_var_name = _option_var_name;
+  }
+
+  void set_package_var_name(const string &_package_var_name)
+  {
+    package_var_name = _package_var_name;
+  }
+
+  void generate_required_option(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // REQUIRED_OPTION_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/reset_group.cc b/cmake/gengetopt/skels/reset_group.cc
new file mode 100644 (file)
index 0000000..84497d7
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "reset_group.h"
+
+void
+reset_group_gen_class::generate_reset_group(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "static void";
+  stream << "\n";
+  stream << indent_str;
+  stream << "reset_group_";
+  generate_string (name, stream, indent + indent_str.length ());
+  stream << "(struct ";
+  generate_string (args_info, stream, indent + indent_str.length ());
+  stream << " *args_info)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "{";
+  stream << "\n";
+  stream << indent_str;
+  stream << "  if (! args_info->";
+  generate_string (name, stream, indent + indent_str.length ());
+  stream << "_group_counter)";
+  stream << "\n";
+  stream << indent_str;
+  stream << "    return;";
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  indent = 2;
+  stream << "  ";
+  generate_string (body, stream, indent + indent_str.length ());
+  indent = 0;
+  stream << "\n";
+  stream << indent_str;
+  stream << "  args_info->";
+  generate_string (name, stream, indent + indent_str.length ());
+  stream << "_group_counter = 0;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "}";
+  stream << "\n";
+  stream << indent_str;
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/reset_group.h b/cmake/gengetopt/skels/reset_group.h
new file mode 100644 (file)
index 0000000..bf51661
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef RESET_GROUP_GEN_CLASS_H
+#define RESET_GROUP_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class reset_group_gen_class
+{
+ protected:
+  string args_info;
+  string body;
+  string name;
+
+ public:
+  reset_group_gen_class()
+  {
+  }
+  
+  reset_group_gen_class(const string &_args_info, const string &_body, const string &_name) :
+    args_info (_args_info), body (_body), name (_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_args_info(const string &_args_info)
+  {
+    args_info = _args_info;
+  }
+
+  void set_body(const string &_body)
+  {
+    body = _body;
+  }
+
+  void set_name(const string &_name)
+  {
+    name = _name;
+  }
+
+  void generate_reset_group(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // RESET_GROUP_GEN_CLASS_H
diff --git a/cmake/gengetopt/skels/update_given.cc b/cmake/gengetopt/skels/update_given.cc
new file mode 100644 (file)
index 0000000..ed52b43
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#include "update_given.h"
+
+void
+update_given_gen_class::generate_update_given(ostream &stream, unsigned int indent)
+{
+  string indent_str (indent, ' ');
+  indent = 0;
+
+  stream << "args_info->";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_given += local_args_info.";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_given;";
+  stream << "\n";
+  stream << indent_str;
+  stream << "local_args_info.";
+  generate_string (option_var_name, stream, indent + indent_str.length ());
+  stream << "_given = 0;";
+  stream << "\n";
+  stream << indent_str;
+}
diff --git a/cmake/gengetopt/skels/update_given.h b/cmake/gengetopt/skels/update_given.h
new file mode 100644 (file)
index 0000000..29f5c8d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * File automatically generated by
+ * gengen 1.2 by Lorenzo Bettini 
+ * http://www.gnu.org/software/gengen
+ */
+
+#ifndef UPDATE_GIVEN_GEN_CLASS_H
+#define UPDATE_GIVEN_GEN_CLASS_H
+
+#include <string>
+#include <iostream>
+
+using std::string;
+using std::ostream;
+
+class update_given_gen_class
+{
+ protected:
+  string option_var_name;
+
+ public:
+  update_given_gen_class()
+  {
+  }
+  
+  update_given_gen_class(const string &_option_var_name) :
+    option_var_name (_option_var_name)
+  {
+  }
+
+  static void
+  generate_string(const string &s, ostream &stream, unsigned int indent)
+  {
+    if (!indent || s.find('\n') == string::npos)
+      {
+        stream << s;
+        return;
+      }
+
+    string::size_type pos;
+    string::size_type start = 0;
+    string ind (indent, ' ');
+    while ( (pos=s.find('\n', start)) != string::npos)
+      {
+        stream << s.substr (start, (pos+1)-start);
+        start = pos+1;
+        if (start+1 <= s.size ())
+          stream << ind;
+      }
+    if (start+1 <= s.size ())
+      stream << s.substr (start);
+  }
+
+  void set_option_var_name(const string &_option_var_name)
+  {
+    option_var_name = _option_var_name;
+  }
+
+  void generate_update_given(ostream &stream, unsigned int indent = 0);
+  
+};
+
+#endif // UPDATE_GIVEN_GEN_CLASS_H
diff --git a/cmake/gengetopt/yyerror.cc b/cmake/gengetopt/yyerror.cc
new file mode 100644 (file)
index 0000000..ca06a2e
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+This file is licensed to you under the license specified in the included file
+`LICENSE'. Look there for further details.
+*/
+
+
+/*
+  Called by yyparse on error.
+ */
+
+#include "yyerror.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+
+extern int gengetopt_count_line;
+extern char * gengetopt_input_filename;
+
+extern int tokenpos;
+extern char linebuf[];
+extern char *yytext;
+
+using namespace std;
+
+void
+yyerror (const char *s)
+{
+  const char *source =
+    (gengetopt_input_filename ? gengetopt_input_filename : "gengetopt");
+
+  fprintf (stderr, "%s:%d: %s %s\n", source, gengetopt_count_line, s, yytext);
+
+  if (/*!linebuf || */!strlen(linebuf))
+    return;
+
+  fprintf (stderr, "%s:%d: %s\n", source, gengetopt_count_line, linebuf);
+  fprintf (stderr, "%s:%d: %*s\n", source, gengetopt_count_line,
+           tokenpos + 1, "^");
+}
+
+void
+yyerror (gengetopt_option *opt, const char *s)
+{
+  const char *source =
+    (opt->filename ? opt->filename : "gengetopt");
+
+  cerr << source << ":" << opt->linenum << ": " << s << endl;
+}
diff --git a/cmake/gengetopt/yyerror.h b/cmake/gengetopt/yyerror.h
new file mode 100644 (file)
index 0000000..a97d414
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef YYERROR_H_
+#define YYERROR_H_
+
+#include "ggos.h"
+
+void
+yyerror (const char *s);
+
+void
+yyerror (gengetopt_option *opt, const char *s);
+
+#endif /*YYERROR_H_*/
diff --git a/cmake/gengetopt/yywrap.c b/cmake/gengetopt/yywrap.c
new file mode 100644 (file)
index 0000000..9e561d3
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+This file is licensed to you under the license specified in the included file
+`LICENSE'. Look there for further details.
+*/
+
+
+/*
+  This function is called when found EOF.
+ */
+#include <stdio.h>
+
+int
+yywrap ()
+{
+  /* fprintf (stderr, "yywrap() called.\n"); */
+  return 1;
+}
+
index 589d108cbeb90013f9d73c26eb971b95027c33d1..0263f3a031cb7696d0ff821fe993f4f1b49ed64e 100644 (file)
@@ -56,3 +56,4 @@ TARGET_LINK_LIBRARIES(clitkDicomRTStruct vtkHybrid)
 
 #ADD_LIBRARY(clitkCommonShared SHARED ${clitkCommon_SRC})
 #SET_TARGET_PROPERTIES(clitkCommonShared PROPERTIES COMPILE_FLAGS -fPIC)
+
index b12f6f5d4b64eb17add326e8ae6dfd69e26d2c2d..785b0fd2c021ad087dd500a68ba0d03a60481b65 100644 (file)
@@ -41,7 +41,8 @@ void clitk::skipComment(std::istream & is)
     is >> c;
     if (is.eof()) return;
   }
-  is.unget();
+  if (!(is.fail()) && c != '\n')
+    is.unget();
 } ////
 //------------------------------------------------------------------
 
index f040914a05aa1ea53e1e4b00fb911a9257fd118f..5f99d7a9c7c27e3a83ac6e6b66999d24888e7a4d 100644 (file)
@@ -1,3 +1,21 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
 #ifndef clitk_configuration_h
 #define clitk_configuration_h
 //This file is interpreted by cmake, to define macros based on the cmake configuration options
@@ -6,4 +24,8 @@
 #cmakedefine01 CLITK_EXPERIMENTAL
 #cmakedefine01 CLITK_MEMORY_INFO
 
+// Global environment variables
+#define OS_NAME "@CMAKE_SYSTEM@"
+#define ARCHITECTURE "@CMAKE_SYSTEM_PROCESSOR@"
+
 #endif
index c5b52951b4851c48260fdcea17425df7549c8fbc..f43db9d005d9ef9d98f4b6ca4dc66bb5713b8b66 100644 (file)
 #define clitkDD_h
 
 #include <iostream>
-
+#ifdef WIN32
+# include <windows.h>
+#endif
 // David's debug
 
-#define DD(a) std::cout << #a " = [ " << a << " ]" << std::endl;std::cout.flush();
+#ifdef WIN32
+# define DD(a) { \
+    std::ostringstream ossDD; \
+    ossDD << #a " = [ " << a << " ]" << std::endl; \
+    OutputDebugString(ossDD.str().c_str()); \
+  }
+#else
+# define DD(a) std::cout << #a " = [ " << a << " ]" << std::endl;std::cout.flush();
+#endif
 #define DDV(a,n) { std::cout << #a " = [ "; for(unsigned int _i_=0; _i_<n; _i_++) { std::cout << a[_i_] << " "; }; std::cout << " ]" << std::endl;std::cout.flush();}
   template<class T>
     void _print_container(T const& a)
index 633064e18e578f7f80c72cbbf0e573e1645b34f8..0cc62b0439c74dc7a756e050792f0a8e8a2d3dd9 100644 (file)
@@ -82,7 +82,6 @@ bool clitk::DicomRT_Contour::Read(gdcm::Item const & item)
   const gdcm::DataElement & contourdata = nestedds2.GetDataElement( tcontourdata );
   at.SetFromDataElement( contourdata );
   const double* points = at.GetValues();
-  unsigned int npts = at.GetNumberOfValues() / 3;
 
   assert(at.GetNumberOfValues() == static_cast<unsigned int>(mNbOfPoints)*3);
 
index 25a2f4322548a1de065c220654352490d7368219..88bab72d80ad025c8e2dba52fe2a97d8cad0bb3f 100644 (file)
@@ -36,7 +36,6 @@ clitk::DicomRT_ROI::DicomRT_ROI()
   mMeshIsUpToDate = false;
   mBackgroundValue = 0;
   mForegroundValue = 1;
-  mZDelta = 0;
 }
 //--------------------------------------------------------------------
 
@@ -163,6 +162,8 @@ void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::Item cons
   gdcm::Tag tcsq(0x3006,0x0040);
   if( !nestedds.FindDataElement( tcsq ) )
     {
+      std::cerr << "Warning. Could not read contour for structure <" << mName << ">, number" << mNumber << " ? I ignore it" << std::endl;
+      return;
     }
   const gdcm::DataElement& csq = nestedds.GetDataElement( tcsq );
   gdcm::SmartPointer<gdcm::SequenceOfItems> sqi2 = csq.GetValueAsSQ();
@@ -171,28 +172,15 @@ void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::Item cons
     }
   unsigned int nitems = sqi2->GetNumberOfItems();
 
-  bool contour_processed=false;
-  bool delta_computed=false;
-  double last_z=0;
   for(unsigned int i = 0; i < nitems; ++i)
     {
-    const gdcm::Item & j = sqi2->GetItem(i+1); // Item start at #1
-    DicomRT_Contour::Pointer c = DicomRT_Contour::New();
-    bool b = c->Read(j);
-    if (b) {
-      mListOfContours.push_back(c);
-      if (contour_processed) {
-        double delta=c->GetZ() - last_z;
-        if (delta_computed)
-          assert(mZDelta == delta);
-        else
-          mZDelta = delta;
-      } else
-        contour_processed=true;
-      last_z=c->GetZ();
+      const gdcm::Item & j = sqi2->GetItem(i+1); // Item start at #1
+      DicomRT_Contour::Pointer c = DicomRT_Contour::New();
+      bool b = c->Read(j);
+      if (b) {
+        mListOfContours.push_back(c);
+      }
     }
-  }
-
 }
 #else
 void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem * item)
@@ -213,25 +201,20 @@ void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem *
 
   // Read contours [Contour Sequence]
   gdcm::SeqEntry * contours=item->GetSeqEntry(0x3006,0x0040);
-  bool contour_processed=false;
-  bool delta_computed=false;
-  double last_z=0;
-  for(gdcm::SQItem* j=contours->GetFirstSQItem(); j!=0; j=contours->GetNextSQItem()) {
-    DicomRT_Contour::Pointer c = DicomRT_Contour::New();
-    bool b = c->Read(j);
-    if (b) {
-      mListOfContours.push_back(c);
-      if (contour_processed) {
-        double delta=c->GetZ() - last_z;
-        if (delta_computed)
-          assert(mZDelta == delta);
-        else
-          mZDelta = delta;
-      } else
-        contour_processed=true;
-      last_z=c->GetZ();
+  if (contours) {
+    int i=0;
+    for(gdcm::SQItem* j=contours->GetFirstSQItem(); j!=0; j=contours->GetNextSQItem()) {
+      DicomRT_Contour::Pointer c = DicomRT_Contour::New();
+      bool b = c->Read(j);
+      if (b) {
+        mListOfContours.push_back(c);
+      }
+      ++i;
     }
   }
+  else {
+    std::cerr << "Warning. Could not read contour for structure <" << mName << ">, number" << mNumber << " ? I ignore it" << std::endl;
+  }
 }
 #endif
 //--------------------------------------------------------------------
@@ -277,9 +260,9 @@ void clitk::DicomRT_ROI::ComputeMesh()
 
 //--------------------------------------------------------------------
 void clitk::DicomRT_ROI::SetFromBinaryImage(vvImage * image, int n,
-                                           std::string name,
-                                           std::vector<double> color, 
-                                           std::string filename)
+                                            std::string name,
+                                            std::vector<double> color, 
+                                            std::string filename)
 {
 
   // ROI number [Referenced ROI Number]
index a22322ecbb853c0d8172444201edbcabd2fd534f..0fb30768cae840c65d79046711017bd779b5d462 100644 (file)
@@ -64,7 +64,7 @@ public:
   void SetImage(vvImage * im);
   DicomRT_Contour* GetContour(int n);
 
-  double GetContourSpacing() const {return mZDelta;}
+  // double GetContourSpacing() const {return mZDelta;}
   
 protected:
   void ComputeMesh();
@@ -79,7 +79,7 @@ protected:
   double mBackgroundValue;
   double mForegroundValue;
   ///Spacing between two contours
-  double mZDelta;
+  // double mZDelta;
 
 private:
   DicomRT_ROI();
index 07c7a956eccf327c1c8245978e7902858b4525c5..e3b34723fdc264865ee925ddac9cd549b836bd67 100644 (file)
 
 #include <iterator>
 #include <algorithm>
+
+// clitk
 #include "clitkDicomRT_ROI_ConvertToImageFilter.h"
+#include "clitkImageCommon.h"
+
+// vtk
 #include <vtkPolyDataToImageStencil.h>
 #include <vtkSmartPointer.h>
 #include <vtkImageStencil.h>
 #include <vtkLinearExtrusionFilter.h>
-#include "clitkImageCommon.h"
+#include <vtkMetaImageWriter.h>
+
 
 //--------------------------------------------------------------------
 clitk::DicomRT_ROI_ConvertToImageFilter::DicomRT_ROI_ConvertToImageFilter()
@@ -121,11 +127,9 @@ void clitk::DicomRT_ROI_ConvertToImageFilter::Update()
     std::cerr << "Error. Please provide image info (spacing/origin) with SetImageFilename" << std::endl;
     exit(0);
   }
-  // DD("Update");
 
   // Get Mesh
   vtkPolyData * mesh = mROI->GetMesh();
-  DD(mesh->GetNumberOfCells());
 
   // Get bounds
   double *bounds=mesh->GetBounds();
@@ -176,7 +180,8 @@ void clitk::DicomRT_ROI_ConvertToImageFilter::Update()
   // Extrude
   vtkSmartPointer<vtkLinearExtrusionFilter> extrude=vtkSmartPointer<vtkLinearExtrusionFilter>::New();
   extrude->SetInput(mesh);
-  extrude->SetVector(0, 0, mROI->GetContourSpacing());
+  ///We extrude in the -slice_spacing direction to respect the FOCAL convention (NEEDED !)
+  extrude->SetVector(0, 0, -mSpacing[2]);
 
   // Binarization
   vtkSmartPointer<vtkPolyDataToImageStencil> sts=vtkSmartPointer<vtkPolyDataToImageStencil>::New();
@@ -192,6 +197,14 @@ void clitk::DicomRT_ROI_ConvertToImageFilter::Update()
   stencil->SetInput(mBinaryImage);
   stencil->ReverseStencilOn();
   stencil->Update();
+
+  /*
+  vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
+  w->SetInput(stencil->GetOutput());
+  w->SetFileName("binary2.mhd");
+  w->Write();
+  */
+
   mBinaryImage->ShallowCopy(stencil->GetOutput());
 
   if (mWriteOutput) {
index f0b690f546093837870632630ee30be540a443cc..8543fb7ddfefac3bbd5392b8a0e3a1f6bbdc18b8 100644 (file)
@@ -274,7 +274,12 @@ void clitk::DicomRT_StructureSet::Read(const std::string & filename)
   mStudyTime = reader.GetValEntry(0x008,0x0020)->GetValue();
   mStudyDate = reader.GetValEntry(0x008,0x0030)->GetValue();
   mLabel     = reader.GetValEntry(0x3006,0x002)->GetValue();
-  mName      = reader.GetValEntry(0x3006,0x004)->GetValue();
+  if (!reader.GetValEntry(0x3006,0x004)) {
+    mName = "Anonymous";
+  }
+  else {
+    mName = reader.GetValEntry(0x3006,0x004)->GetValue();
+  }
   mTime      = reader.GetValEntry(0x3006,0x009)->GetValue();
 
   //----------------------------------
index 3cd8ae51520d7623bb95e0ccca692e329142684e..32bba4916c1ec25244a09655bd1a3dcdf6cd54d2 100644 (file)
@@ -1,7 +1,7 @@
 /*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
-  Authors belong to: 
+  Authors belong to:
   - University of LYON              http://www.universite-lyon.fr/
   - Léon Bérard cancer center       http://www.centreleonberard.fr
   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
 #include "itkImageSeriesReader.h"
 #include "itkImageFileWriter.h"
 
-namespace clitk {
-  
-  //--------------------------------------------------------------------
-  // New Image creation (no allocation)
-  template<class PixelType>
-  typename itk::Image<PixelType,1>::Pointer NewImage1D(int size, double spacing=1.0);
-  template<class PixelType>
-  typename itk::Image<PixelType,2>::Pointer NewImage2D(int sx, int sy, double dx=1.0, double dy=1.0);
-  template<class PixelType>
-  typename itk::Image<PixelType,3>::Pointer NewImage3D(int sx, int sy, int sz, double dx=1.0, double dy=1.0, double dz=1.0);
-  template<class PixelType>
-  typename itk::Image<PixelType,4>::Pointer NewImage4D(int sx, int sy, int sz, int st, double dx=1.0, double dy=1.0, double dz=1.0, double dt=1.0);
-
-  template<class ImageType>
-  typename ImageType::Pointer NewImageLike(const typename ImageType::Pointer input, bool allocate=true);
-
-  template<class ImageType>
-  void CopyValues(const typename ImageType::Pointer input, typename ImageType::Pointer output);
-  //--------------------------------------------------------------------
-  // New Image creation (with allocation)
-
-  //--------------------------------------------------------------------
-  // Read an Write image
-  // template<class ImageType>
-  //   typename ImageType::Pointer ReadImage(const std::string & filename, const bool verbose=false);
-  template<typename ImageType>
-  typename ImageType::Pointer readImage(const std::string & filename, const bool verbose=false);  
-  template<typename ImageType>
-  typename ImageType::Pointer readImage(const std::vector<std::string> & filenames, const bool verbose=false);
-  template<class ImageType>
-  void writeImage(const typename ImageType::Pointer image, const std::string & filename, const bool verbose=false);
-//   template<class ImageType>  
+namespace clitk
+{
+
+//--------------------------------------------------------------------
+// New Image creation (no allocation)
+template<class PixelType>
+typename itk::Image<PixelType,1>::Pointer NewImage1D(int size, double spacing=1.0);
+template<class PixelType>
+typename itk::Image<PixelType,2>::Pointer NewImage2D(int sx, int sy, double dx=1.0, double dy=1.0);
+template<class PixelType>
+typename itk::Image<PixelType,3>::Pointer NewImage3D(int sx, int sy, int sz, double dx=1.0, double dy=1.0, double dz=1.0);
+template<class PixelType>
+typename itk::Image<PixelType,4>::Pointer NewImage4D(int sx, int sy, int sz, int st, double dx=1.0, double dy=1.0, double dz=1.0, double dt=1.0);
+
+template<class ImageType>
+typename ImageType::Pointer NewImageLike(const typename ImageType::Pointer input, bool allocate=true);
+
+template<class ImageType>
+void CopyValues(const typename ImageType::Pointer input, typename ImageType::Pointer output);
+//--------------------------------------------------------------------
+// New Image creation (with allocation)
+
+//--------------------------------------------------------------------
+// Read an Write image
+// template<class ImageType>
+//   typename ImageType::Pointer ReadImage(const std::string & filename, const bool verbose=false);
+template<typename ImageType>
+typename ImageType::Pointer readImage(const std::string & filename, const bool verbose=false);
+template<typename ImageType>
+typename ImageType::Pointer readImage(const std::vector<std::string> & filenames, const bool verbose=false);
+template<class ImageType>
+void writeImage(const typename ImageType::Pointer image, const std::string & filename, const bool verbose=false, const bool compression=false);
+//   template<class ImageType>
 //   void writeConstImage(const typename ImageType::ConstPointer image, const std::string & filename, const bool verbose=false);
-  template<class ImageType>  
-  void writeImage(const ImageType* image, const std::string & filename, const bool verbose=false);
-
-  //--------------------------------------------------------------------
-  // Read/print image header
-  itk::ImageIOBase::Pointer readImageHeader(const std::string & filename,bool exit_on_error=true);
-  void printImageHeader(itk::ImageIOBase::Pointer header, std::ostream & os, const int level=0);
-
-  //--------------------------------------------------------------------
-  // Determine pixetype and dimension of an image file
-  void ReadImageDimensionAndPixelType(const std::string & filename, int & dimension, std::string & pixeType);
-
-  //--------------------------------------------------------------------
-  // Determine pixetype, dimension and number of pixel components  of an image file
-  void ReadImageDimensionAndPixelType(const std::string & filename, int & dimension, std::string & pixeType, int & components);
-
-  //--------------------------------------------------------------------
-  template<class ImageType>
-  int ComputeHowManyDifferentIntensity(const typename ImageType::Pointer & image, 
-                                      std::vector<typename ImageType::PixelType> & listOfIntensities);
-  template<class InputImageType, class MaskImageType>
-  void ComputeWeightsOfEachClasses(const typename InputImageType::Pointer & input, 
-                                  const typename MaskImageType::Pointer & mask,
-                                  const std::vector<typename MaskImageType::PixelType> & listOfIntensities, 
-                                  std::map<typename MaskImageType::PixelType, 
-                                  std::map<typename InputImageType::PixelType, double> > & mapOfLabelsAndWeights);
-
-  //--------------------------------------------------------------------
-  template<class ImageType1, class ImageType2>
-  bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A, 
-                             typename ImageType2::ConstPointer B);
-
-  template<class ImageType1, class ImageType2>
-  bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A, 
-                             typename ImageType2::Pointer B);
-
-  //--------------------------------------------------------------------
-  template<class ImageType1, class ImageType2>
-  bool HaveSameSpacing(typename ImageType1::ConstPointer A, 
-                       typename ImageType2::ConstPointer B);
-
-  template<class ImageType1, class ImageType2>
-  bool HaveSameSpacing(typename ImageType1::Pointer A, 
-                       typename ImageType2::Pointer B);
+template<class ImageType>
+void writeImage(const ImageType* image, const std::string & filename, const bool verbose=false, const bool compression=false);
+
+//--------------------------------------------------------------------
+// Read/print image header
+itk::ImageIOBase::Pointer readImageHeader(const std::string & filename,bool exit_on_error=true);
+void printImageHeader(itk::ImageIOBase::Pointer header, std::ostream & os, const int level=0);
+
+//--------------------------------------------------------------------
+// Determine pixetype and dimension of an image file
+void ReadImageDimensionAndPixelType(const std::string & filename, int & dimension, std::string & pixeType);
+
+//--------------------------------------------------------------------
+// Determine pixetype, dimension and number of pixel components  of an image file
+void ReadImageDimensionAndPixelType(const std::string & filename, int & dimension, std::string & pixeType, int & components);
+
+//--------------------------------------------------------------------
+template<class ImageType>
+int ComputeHowManyDifferentIntensity(const typename ImageType::Pointer & image,
+                                     std::vector<typename ImageType::PixelType> & listOfIntensities);
+template<class InputImageType, class MaskImageType>
+void ComputeWeightsOfEachClasses(const typename InputImageType::Pointer & input,
+                                 const typename MaskImageType::Pointer & mask,
+                                 const std::vector<typename MaskImageType::PixelType> & listOfIntensities,
+                                 std::map<typename MaskImageType::PixelType,
+                                 std::map<typename InputImageType::PixelType, double> > & mapOfLabelsAndWeights);
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSpacing(typename ImageType1::ConstPointer A,
+                     typename ImageType2::ConstPointer B);
+
+template<class ImageType1, class ImageType2>
+bool HaveSameSpacing(typename ImageType1::Pointer A,
+                     typename ImageType2::Pointer B);
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSize(typename ImageType1::ConstPointer A,
+                  typename ImageType2::ConstPointer B);
+
+template<class ImageType1, class ImageType2>
+bool HaveSameSize(typename ImageType1::Pointer A,
+                  typename ImageType2::Pointer B);
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A,
+                            typename ImageType2::ConstPointer B);
+
+template<class ImageType1, class ImageType2>
+bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A,
+                            typename ImageType2::Pointer B);
 
 #include "clitkImageCommon.txx"
 
index 9d8d6e131b62c47bdedd20b599a0b77f8ba56f46..a07c66f0459eca0743c41c460937e48a484c75a0 100644 (file)
@@ -21,7 +21,7 @@
 
 //--------------------------------------------------------------------
 template<class PixelType>
-typename itk::Image<PixelType,1>::Pointer 
+typename itk::Image<PixelType,1>::Pointer
 NewImage1D(int vsize, double vspacing)
 {
   typedef itk::Image<PixelType,1> ImageType;
@@ -40,7 +40,7 @@ NewImage1D(int vsize, double vspacing)
 
 //--------------------------------------------------------------------
 template<class PixelType>
-typename itk::Image<PixelType,2>::Pointer 
+typename itk::Image<PixelType,2>::Pointer
 NewImage2D(int sx, int sy, double dx, double dy)
 {
   typedef itk::Image<PixelType,2> ImageType;
@@ -62,7 +62,7 @@ NewImage2D(int sx, int sy, double dx, double dy)
 
 //--------------------------------------------------------------------
 template<class PixelType>
-typename itk::Image<PixelType,3>::Pointer 
+typename itk::Image<PixelType,3>::Pointer
 NewImage3D(int sx, int sy, int sz, double dx, double dy, double dz)
 {
   typedef itk::Image<PixelType,3> ImageType;
@@ -188,34 +188,22 @@ typename ImageType::Pointer readImage(const std::vector<std::string> & filenames
 
 //--------------------------------------------------------------------
 template<class ImageType>
-void writeImage(const typename ImageType::Pointer image, const std::string & filename, const bool verbose)
+void writeImage(const typename ImageType::Pointer image, const std::string & filename, const bool verbose, const bool compression)
 {
-  typedef itk::ImageFileWriter<ImageType> WriterType;
-  typename WriterType::Pointer writer = WriterType::New();
-  writer->SetFileName(filename.c_str());
-  writer->SetInput(image);
-  if (verbose) {
-    std::cout << "Writing [" << filename << "] ... " << std::endl;
-  }
-  try {
-    writer->Update();
-  } catch( itk::ExceptionObject & err ) {
-    std::cerr << "Exception while writing image [" << filename << "]" << std::endl;
-    std::cerr << err << std::endl;
-    exit(-1);
-  }
+  return writeImage(image.GetPointer(), filename, verbose, compression);
 }
 //--------------------------------------------------------------------
 
 
 //--------------------------------------------------------------------
 template<class ImageType>
-void writeImage(const ImageType* image, const std::string & filename, const bool verbose)
+void writeImage(const ImageType* image, const std::string & filename, const bool verbose, const bool compression)
 {
   typedef itk::ImageFileWriter<ImageType> WriterType;
   typename WriterType::Pointer writer = WriterType::New();
   writer->SetFileName(filename.c_str());
   writer->SetInput(image);
+  writer->SetUseCompression(compression);
   if (verbose) {
     std::cout << "Writing [" << filename << "] ... " << std::endl;
   }
@@ -323,13 +311,12 @@ void ComputeWeightsOfEachClasses(const typename InputImageType::Pointer & input,
 
 //--------------------------------------------------------------------
 template<class ImageType1, class ImageType2>
-bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A, 
-                           typename ImageType2::ConstPointer B) 
+bool HaveSameSpacing(typename ImageType1::ConstPointer A,
+                     typename ImageType2::ConstPointer B)
 {
   if (A->GetImageDimension() != B->GetImageDimension()) return false;
   for(unsigned int i=0; i<A->GetImageDimension(); i++) {
     if (A->GetSpacing()[i] != B->GetSpacing()[i]) return false;
-    if (A->GetLargestPossibleRegion().GetSize()[i] != B->GetLargestPossibleRegion().GetSize()[i]) return false;
   }
   return true;
 }
@@ -337,13 +324,12 @@ bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A,
 
 //--------------------------------------------------------------------
 template<class ImageType1, class ImageType2>
-bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A, 
-                           typename ImageType2::Pointer B) 
+bool HaveSameSpacing(typename ImageType1::Pointer A,
+                     typename ImageType2::Pointer B)
 {
   if (A->GetImageDimension() != B->GetImageDimension()) return false;
   for(unsigned int i=0; i<A->GetImageDimension(); i++) {
     if (A->GetSpacing()[i] != B->GetSpacing()[i]) return false;
-    if (A->GetLargestPossibleRegion().GetSize()[i] != B->GetLargestPossibleRegion().GetSize()[i]) return false;
   }
   return true;
 }
@@ -351,12 +337,12 @@ bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A,
 
 //--------------------------------------------------------------------
 template<class ImageType1, class ImageType2>
-bool HaveSameSpacing(typename ImageType1::ConstPointer A, 
-                     typename ImageType2::ConstPointer B) 
+bool HaveSameSize(typename ImageType1::ConstPointer A,
+                  typename ImageType2::ConstPointer B)
 {
   if (A->GetImageDimension() != B->GetImageDimension()) return false;
   for(unsigned int i=0; i<A->GetImageDimension(); i++) {
-    if (A->GetSpacing()[i] != B->GetSpacing()[i]) return false;
+    if (A->GetLargestPossibleRegion().GetSize()[i] != B->GetLargestPossibleRegion().GetSize()[i]) return false;
   }
   return true;
 }
@@ -364,16 +350,36 @@ bool HaveSameSpacing(typename ImageType1::ConstPointer A,
 
 //--------------------------------------------------------------------
 template<class ImageType1, class ImageType2>
-bool HaveSameSpacing(typename ImageType1::Pointer A, 
-                           typename ImageType2::Pointer B) 
+bool HaveSameSize(typename ImageType1::Pointer A,
+                  typename ImageType2::Pointer B)
 {
   if (A->GetImageDimension() != B->GetImageDimension()) return false;
   for(unsigned int i=0; i<A->GetImageDimension(); i++) {
-    if (A->GetSpacing()[i] != B->GetSpacing()[i]) return false;
+    if (A->GetLargestPossibleRegion().GetSize()[i] != B->GetLargestPossibleRegion().GetSize()[i]) return false;
   }
   return true;
 }
 //--------------------------------------------------------------------
 
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSizeAndSpacing(typename ImageType1::ConstPointer A,
+                            typename ImageType2::ConstPointer B)
+{
+  return ( HaveSameSize<ImageType1, ImageType2>(A, B) &&
+           HaveSameSpacing<ImageType1, ImageType2>(A, B) );
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+bool HaveSameSizeAndSpacing(typename ImageType1::Pointer A,
+                            typename ImageType2::Pointer B)
+{
+  return ( HaveSameSize<ImageType1, ImageType2>(A, B) &&
+           HaveSameSpacing<ImageType1, ImageType2>(A, B) );
+}
+//--------------------------------------------------------------------
+
 #endif /* end #define CLITKIMAGECOMMON_TXX */
 
index 8b0505d7bb2ec214db028ef0fba9a1211640a5f3..5f9cfac54d283c092418ca372ea6355577d59043 100644 (file)
@@ -36,6 +36,7 @@ clitk::ImageToImageGenericFilterBase::ImageToImageGenericFilterBase(std::string
   m_FailOnImageTypeError = true;
   m_ReadOnDisk = true;
   m_WriteOnDisk = true;
+  m_WriteCompression = false;
   // m_LastError = "";
   // StopOnErrorOn();
   SetFilterBase(NULL);
@@ -72,6 +73,14 @@ void clitk::ImageToImageGenericFilterBase::EnableWriteOnDisk(bool b)
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+void clitk::ImageToImageGenericFilterBase::EnableWriteCompression(bool b)
+{
+  m_WriteCompression = b;
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 void clitk::ImageToImageGenericFilterBase::SetInputFilename(const std::string & filename)
 {
@@ -321,7 +330,7 @@ template<class ImageType>
 void clitk::ImageToImageGenericFilterBase::SetNextOutput(typename ImageType::Pointer output)
 {
   if (m_WriteOnDisk && m_OutputFilenames.size()) {
-    clitk::writeImage<ImageType>(output, m_OutputFilenames.front(), m_IOVerbose);
+    clitk::writeImage<ImageType>(output, m_OutputFilenames.front(), m_IOVerbose, m_WriteCompression);
     m_OutputFilenames.pop_front();
   }
   if (m_InputVVImages.size()) //We assume that if a vv image is set as input, we want one as the output
index 039b850a59199ead284232b2ee13681080042c31..03b4f4acfa030d91b52e0804b521e06e6f30ed25 100644 (file)
@@ -62,6 +62,7 @@ namespace clitk {
     void SetInputFilenames(const std::vector<std::string> & filenames);
     void EnableReadOnDisk(bool b);
     void EnableWriteOnDisk(bool b);
+    void EnableWriteCompression(bool b);
     void SetOutputFilename(const std::string & filename);
     void AddOutputFilename(const std::string filename);
     void SetOutputFilenames(const std::vector<std::string> & filenames);
@@ -94,6 +95,8 @@ namespace clitk {
   protected:  
     bool m_ReadOnDisk;
     bool m_WriteOnDisk;
+    bool m_WriteCompression;
+
     /// Call this function to dispatch an output towards the correct sink
     template<class ImageType> 
     void SetNextOutput(typename ImageType::Pointer output);
index b9380a2e2ff476421d98676a2d0c592b861683d0..07384efe5cc9e965e9f07e3ed33655128a68a5c2 100644 (file)
@@ -700,11 +700,13 @@ int clitk::XdrImageIO::ReadImageInformationWithError()
         SetOrigin(i,10*p[0]);
 
         //Test if rectilinear image is actually uniform (tolerance 0.1 mm)
-        for (j=0; j<GetDimensions(i)-1; j++) {
-          if (fabs((p[j+1]-p[j])*10-GetSpacing(i))>0.1) {
-            free(points);
-            fclose(fstream);
-            return ER_NOT_HANDLED;
+        if(i<3) { // Only for first 3 dimensions because spacing is barely used in other dims
+          for (j=0; j<GetDimensions(i)-1; j++) {
+            if (fabs((p[j+1]-p[j])*10-GetSpacing(i))>0.1) {
+              free(points);
+              fclose(fstream);
+              return ER_NOT_HANDLED;
+            }
           }
         }
         p += (int)GetDimensions(i);
index c089816ad785085026eb9a594ef3ad6d476df808..30e1bfe6325c3205a6cb47dee118483ce8c120a0 100644 (file)
 /**Converts the itk image to vv, handling the 4D problem
  * The time_sequence boolean specifies that the image is to be interpreted as a time sequence,
  * even if its dim is < 4. */
-template<unsigned int Dim, class PixelType> vvImage::Pointer vvImageFromITK(typename itk::Image<PixelType,Dim>::Pointer input, bool time_sequence=false)
+
+template<unsigned int Dim, class PixelType>
+static inline void ReadTimeSequence (vvImage::Pointer& vv_image, typename itk::Image<PixelType,Dim>::Pointer input, bool time_sequence=false)
 {
-    assert(Dim < 5 && Dim > 0); // We don't handle anything higher than 4-dimensional (for the moment :-p)
-    vvImage::Pointer vv_image=vvImage::New();
-    typedef itk::Image< PixelType, Dim > InputImageType;
+  typedef itk::Image< PixelType, Dim > InputImageType;
+  typedef itk::Image< PixelType,  Dim - 1 >    ItkImageType;
+  typedef itk::ExtractImageFilter<InputImageType, ItkImageType> FilterType;
+
+  //extract the 3D slices and put them in a std::vector<vtkImageData*>
+  input->UpdateOutputInformation();
+  typename InputImageType::RegionType inputRegion = input->GetLargestPossibleRegion();
+  typename InputImageType::SizeType inputSize = inputRegion.GetSize();
+  typename InputImageType::IndexType start = inputRegion.GetIndex();
+  typename InputImageType::SizeType extractedRegionSize = inputSize;
+  typename InputImageType::RegionType extractedRegion;
+  extractedRegionSize[Dim - 1] = 0;
+  extractedRegion.SetSize(extractedRegionSize);
 
-    if (Dim == 4 || time_sequence) //The time sequence case: create a series of VTK images
-    {
-        typedef itk::Image< PixelType,  Dim - 1 >    ItkImageType;
-        typedef itk::ExtractImageFilter<InputImageType, ItkImageType> FilterType;
-
-        //extract the 3D slices and put them in a std::vector<vtkImageData*>
-        input->UpdateOutputInformation();
-        typename InputImageType::RegionType inputRegion = input->GetLargestPossibleRegion();
-        typename InputImageType::SizeType inputSize = inputRegion.GetSize();
-        typename InputImageType::IndexType start = inputRegion.GetIndex();
-        typename InputImageType::SizeType extractedRegionSize = inputSize;
-        typename InputImageType::RegionType extractedRegion;
-        extractedRegionSize[Dim - 1] = 0;
-        extractedRegion.SetSize(extractedRegionSize);
-
-        for (unsigned int i = 0; i < inputSize[Dim - 1]; i++) {
-            start[Dim - 1] = i;
-            extractedRegion.SetIndex(start);
-
-            typename FilterType::Pointer filter = FilterType::New();
+  for (unsigned int i = 0; i < inputSize[Dim - 1]; i++) {
+    start[Dim - 1] = i;
+    extractedRegion.SetIndex(start);
+
+    typename FilterType::Pointer filter = FilterType::New();
 #if ITK_VERSION_MAJOR == 4
-            filter->SetDirectionCollapseToSubmatrix();
+    filter->SetDirectionCollapseToSubmatrix();
 #endif
-            filter->SetExtractionRegion(extractedRegion);
-            filter->SetInput(input);
-            filter->ReleaseDataFlagOn();
-            vv_image->AddItkImage<ItkImageType>(filter->GetOutput());
-        }
-        vv_image->SetTimeSpacing(input->GetSpacing()[Dim-1]);
-        vv_image->SetTimeOrigin(input->GetOrigin()[Dim-1]);
-    }
+    filter->SetExtractionRegion(extractedRegion);
+    filter->SetInput(input);
+    filter->ReleaseDataFlagOn();
+    vv_image->AddItkImage<ItkImageType>(filter->GetOutput());
+  }
+  vv_image->SetTimeSpacing(input->GetSpacing()[Dim-1]);
+  vv_image->SetTimeOrigin(input->GetOrigin()[Dim-1]);
+}
+
+template<unsigned int Dim, class PixelType>
+struct vvImageFromITK_Impl
+{
+  static vvImage::Pointer Do (typename itk::Image<PixelType,Dim>::Pointer input, bool time_sequence=false)
+  {
+    vvImage::Pointer vv_image=vvImage::New();
+    typedef itk::Image< PixelType, Dim > InputImageType;
+
+    if (time_sequence) //The time sequence case: create a series of VTK images
+      ReadTimeSequence<Dim,PixelType>(vv_image, input, time_sequence);
     else //Dim == 1,2,3 and not time_sequence
-    {
-        vv_image->AddItkImage<InputImageType>(input);
-    }
+      vv_image->AddItkImage<InputImageType>(input);
+
+    return vv_image;
+  }
+};
+
+template<class PixelType>
+struct vvImageFromITK_Impl<4u, PixelType>
+{
+  static vvImage::Pointer Do (typename itk::Image<PixelType,4u>::Pointer input, bool time_sequence=false)
+  {
+    vvImage::Pointer vv_image = vvImage::New();
+    ReadTimeSequence<4u,PixelType>(vv_image, input, time_sequence);
     return vv_image;
+  }
+};
+
+template<unsigned int Dim, class PixelType> vvImage::Pointer vvImageFromITK(typename itk::Image<PixelType,Dim>::Pointer input, bool time_sequence=false)
+{
+    assert(Dim < 5 && Dim > 0); // We don't handle anything higher than 4-dimensional (for the moment :-p)
+    return vvImageFromITK_Impl<Dim, PixelType>::Do(input, time_sequence);
 }
 //------------------------------------------------------------------------------
 
index 6e8907633987e48e4fc17c0f7b97cd3eecc57eae..14da10a227f7d825cde021a143b8c2f84a74d7bb 100644 (file)
@@ -26,21 +26,30 @@ void vvImage::AddItkImage(TItkImageType *input)
   input->Update();
 
   // Convert from ITK object to VTK object
-  mImageDimension = TItkImageType::ImageDimension; 
+  mImageDimension = TItkImageType::ImageDimension;
   typedef itk::ImageToVTKImageFilter <TItkImageType> ConverterType;
   typename ConverterType::Pointer converter = ConverterType::New();
   mItkToVtkConverters.push_back(dynamic_cast< itk::ProcessObject *>(converter.GetPointer()));
   converter->SetInput(input);
   converter->Update();
   mVtkImages.push_back( converter->GetOutput() );
-  
+
   // Account for direction in transform. The offset is already accounted for
   // in the VTK image coordinates, no need to put it in the transform.
   vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
   matrix->Identity();
-  for(unsigned int j=0; j<input->GetImageDimension(); j++)
-    for(unsigned int i=0; i<input->GetImageDimension(); i++)
+  for(unsigned int i=0; i<input->GetImageDimension(); i++) {
+    for(unsigned int j=0; j<input->GetImageDimension(); j++) {
       (*matrix)[i][j] = input->GetDirection()[i][j];
+      // Direction is used around the image origin in ITK
+      (*matrix)[i][3] -= (*matrix)[i][j] * input->GetOrigin()[j];
+    }
+    (*matrix)[i][3] += input->GetOrigin()[i];
+  }
+
+  // GetDirection provides the forward transform, vtkImageReslice wants the inverse
+  matrix->Invert();
+
   mTransform->SetMatrix(matrix);
 }
 //--------------------------------------------------------------------
index 715c4c50ad1c5ff6d242f4af8ca3c6faeb422891..09853a1bbde4caf8bf870dd33bf82bd1ff5d5cfc 100644 (file)
@@ -148,13 +148,15 @@ void vvImageReader::ReadNkiImageTransform()
 //Read transformation in ASCII format
 void vvImageReader::ReadMatImageTransform()
 {
-  std::string filename(mInputFilenames[0]+".mat");
+  std::string filename(itksys::SystemTools::GetFilenameWithoutExtension(mInputFilenames[0]));
+  filename += ".mat";
+
   std::ifstream f(filename.c_str());
   if(f.is_open()) {
     f.close();
-    
+
     itk::Matrix<double, 4, 4> itkMat = clitk::ReadMatrix3D(filename);
-    
+
     vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
     matrix->Identity();
     for(int j=0; j<4; j++)
@@ -166,22 +168,26 @@ void vvImageReader::ReadMatImageTransform()
     // file is inverted wrt the transformation given in the MAT file.
     // We don't really know where the inversion takes place inside
     // VTK or ITK. For what we could see in VV, the transformation
-    // given in the MHD file seems "more correct" than that given in 
+    // given in the MHD file seems "more correct" than that given in
     // the MAT file. For this reason, we invert the matrix read from
     // the MAT file before concatenating it to the current transformation.
     // Still, it would be nice to find out what happens exactly between
     // VTK and ITK...
     //
-    vtkSmartPointer<vtkMatrix4x4> inv_matrix = vtkSmartPointer<vtkMatrix4x4>::New();
+    // SR: 23/06/2011
+    // We actually use vtkImageReslice which takes the inverse transform
+    // as input. So it seems more correct to inverse the matrix given by
+    // itk::ImageBase< VImageDimension >::GetDirection() than the matrix
+    // in .mat which is indeed the inverse optimized by a typical
+    // affine registration algorithm.
+    // Validated using clitkAffineTransform --transform_grid
     if (matrix->Determinant() == 0)
     {
       vtkGenericWarningMacro("Matrix in " << filename.c_str() << " cannot be inverted (determinant = 0)");
     }
-    else
-      matrix->Invert(*matrix, *inv_matrix);
-    
+
     mImage->GetTransform()->PostMultiply();
-    mImage->GetTransform()->Concatenate(inv_matrix);
+    mImage->GetTransform()->Concatenate(matrix);
     mImage->GetTransform()->Update();
   }
 }
index 06cf8c4bbc99c191c88e5d81b9ae18e921f69eea..2f1de53537794d937e16c4770ff8828eeddeddd5 100644 (file)
@@ -35,6 +35,7 @@ public:
   IMAGEWITHTIME,
   MERGEDWITHTIME,
   VECTORFIELD,
+  VECTORFIELDWITHTIME,
   UNDEFINEDIMAGETYPE
   } LoadedImageType;
 
@@ -42,6 +43,8 @@ public:
   typedef itk::SmartPointer<Self> Pointer;
   itkNewMacro(Self);
 
+  const std::vector<std::string>& GetInputFilenames(){return mInputFilenames;}
+
   void SetInputFilename(const std::string & filename);
   void SetInputFilenames(const std::vector<std::string> & filenames);
 
index fa111e200c06fbbc4e6ad07f682b8ecedccbc37c..2d7d5b573f3c9a2985bfef023c21f4a542c53537 100644 (file)
@@ -34,7 +34,7 @@
 template<unsigned int VImageDimension>
 void vvImageReader::UpdateWithDim(std::string InputPixelType)
 {
-  if (mType == VECTORFIELD)
+  if (mType == VECTORFIELD || mType == VECTORFIELDWITHTIME)
     UpdateWithDimAndInputPixelType<itk::Vector<float,3>,VImageDimension>();
   else if (InputPixelType == "short")
     UpdateWithDimAndInputPixelType<short,VImageDimension>();
@@ -67,7 +67,7 @@ void vvImageReader::UpdateWithDim(std::string InputPixelType)
 template<class InputPixelType, unsigned int VImageDimension>
 void vvImageReader::UpdateWithDimAndInputPixelType()
 {
-  itk::AnalyzeImageIO *analyzeImageIO;
+  itk::AnalyzeImageIO *analyzeImageIO = NULL;
 
   if (mType == MERGEDWITHTIME)   // In this case we can load the images
     // one at the time to avoid excessive
@@ -118,6 +118,9 @@ void vvImageReader::UpdateWithDimAndInputPixelType()
     filter->SetExtractionRegion(extractedRegion);
     filter->SetInput(reader->GetOutput());
     filter->ReleaseDataFlagOn();
+#if ITK_VERSION_MAJOR == 4
+    filter->SetDirectionCollapseToSubmatrix();
+#endif
     try {
       mImage->AddItkImage<SlicedImageType>(filter->GetOutput());
     } catch ( itk::ExceptionObject & err ) {
@@ -136,7 +139,12 @@ void vvImageReader::UpdateWithDimAndInputPixelType()
 
       try {
         if (mType == IMAGEWITHTIME)
-          mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput(),true);
+        {
+          std::cerr << "We should never come here:" << std::endl
+            << "  Calling vvImageReader with multiple images and IMAGEWITHTIME is undefined." << std::endl
+            << "  You are probably looking for MERGEDWITHTIME Type." << std::endl;
+          return;
+        }
         else
           mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput());
       } catch ( itk::ExceptionObject & err ) {
@@ -154,7 +162,7 @@ void vvImageReader::UpdateWithDimAndInputPixelType()
       reader->ReleaseDataFlagOn();
 
       try {
-        if (mType == IMAGEWITHTIME)
+        if (mType == IMAGEWITHTIME || mType == VECTORFIELDWITHTIME)
           mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput(),true);
         else
           mImage=vvImageFromITK<VImageDimension,InputPixelType>(reader->GetOutput());
index 93a3aa303541299be87153742d1eb0c538a03f3e..11797e78d72ed449edddafc67d1873f7b2a1a3d1 100644 (file)
@@ -80,11 +80,18 @@ namespace itk
    *   
    *   This filter is implemented using the propagation algorithm
    */
+
+#if ITK_VERSION_MAJOR == 4
+  template <class TInputImage, class TOutputImage, class TtNorm=Functor::Minimum<
+                                                     typename TOutputImage::PixelType,
+                                                     typename TOutputImage::PixelType,
+                                                     typename TOutputImage::PixelType>  >
+#else
   template <class TInputImage, class TOutputImage, class TtNorm=Function::Minimum<
                                                      typename TOutputImage::PixelType,
                                                      typename TOutputImage::PixelType,
                                                      typename TOutputImage::PixelType>  >
+#endif
   class ITK_EXPORT RelativePositionPropImageFilter :
     public ImageToImageFilter< TInputImage, TOutputImage > 
   {
index a9f8a910893efd4049270c3dbfeb8bf2b794524e..54f431109728bd8b31b4bdbd8b5d09cc9679e441 100644 (file)
 #include <itkBinaryErodeImageFilter.h>
 #include <itkBinaryBallStructuringElement.h>
 #include <itkAddImageFilter.h>
-#include <itkDivideByConstantImageFilter.h>
+#if ITK_VERSION_MAJOR >= 4
+  #include <itkDivideImageFilter.h>
+#else
+  #include <itkDivideByConstantImageFilter.h>
+#endif
 
 // itk [Bloch et al] 
 #include "RelativePositionPropImageFilter.h"
@@ -359,10 +363,16 @@ GenerateData()
 
   // Divide by the number of relpos
   if (GetNumberOfAngles() != 1) {
+#if ITK_VERSION_MAJOR >= 4
+    typedef itk::DivideImageFilter<FloatImageType, FloatImageType, FloatImageType> DivideFilter;
+    typename DivideFilter::Pointer divideFilter = DivideFilter::New();
+    divideFilter->SetConstant2(GetNumberOfAngles());
+#else
     typedef itk::DivideByConstantImageFilter<FloatImageType, float, FloatImageType> DivideFilter;
     typename DivideFilter::Pointer divideFilter = DivideFilter::New();
-    divideFilter->SetInput(m_FuzzyMap);
     divideFilter->SetConstant(GetNumberOfAngles());
+#endif
+    divideFilter->SetInput(m_FuzzyMap);
     divideFilter->Update();
     m_FuzzyMap = divideFilter->GetOutput();
   }
index 0005eb8665b2d2c2626ea34ab54a55bddff37d1e..71f9ab08b0f07e93e3c3ec3495cef208e104c563 100644 (file)
@@ -38,7 +38,7 @@ namespace clitk {
   AutoCropFilter():itk::ImageToImageFilter<ImageType, ImageType>() {
     this->SetNumberOfRequiredInputs(1);
     m_BackgroundValue  = 0;
-    UseBorderOn();
+    UseBorderOff();
   }
   //--------------------------------------------------------------------
 
@@ -97,6 +97,8 @@ namespace clitk {
     autoCropFilter->SetInput(imageToLabelFilter->GetOutput());
     //    autoCropFilter->ReleaseDataFlagOff(); 
     if (GetUseBorder()) {
+      DD("UseBorder seems buggy ?");
+      exit(0);
       typename ImageType::SizeType s;
       for(uint i=0; i<ImageType::ImageDimension; i++) s[i] = 1;
       autoCropFilter->SetCropBorder(s);
index ebaeffc49fee3ff2c3753d7d8a4d344e6b5c2cf5..7de71a116111326f2bed06060af31bc165a6ecb5 100644 (file)
@@ -148,6 +148,11 @@ namespace clitk
        }
     }
 
+    void SetPanelShift(double x, double y)
+    {
+      m_PanelShift[0] = x;
+      m_PanelShift[1] = y;
+    }
     //     itkSetMacro(IsoCenter, OutputPointType);
     //     itkGetConstReferenceMacro(IsoCenter, OutputPointType)
     //     itkSetMacro( SourceToScreen, double );
@@ -258,6 +263,7 @@ namespace clitk
     double  m_SourceToAxis;
     OutputPixelType m_EdgePaddingValue;
     double m_ProjectionAngle;
+    double m_PanelShift[2];
 
     // Output image info
     OutputSizeType                m_OutputSize;        // Size of the output image
index 65ac8017d4cb98b2009b573f3de03afb07e694db..befc8822013cb8543d7bbc0d3ece59b417f84b31 100644 (file)
@@ -20,6 +20,7 @@
 #include "clitkBackProjectImageFilter.h"
 #include "itkContinuousIndex.h"
 #include "vnl/vnl_math.h"
+#include "itkLinearInterpolateImageFunction.h"
 
 namespace clitk
 {
@@ -39,6 +40,8 @@ namespace clitk
     this->m_SourceToAxis = 1000.0;
     this->m_EdgePaddingValue = itk::NumericTraits<OutputPixelType>::Zero;//density images
     this->m_RigidTransformMatrix.SetIdentity();
+    this->m_PanelShift[0] = 0.;
+    this->m_PanelShift[1] = 0.;
 
     //Parameters for output
     this->m_OutputSpacing.Fill(1);
@@ -304,8 +307,6 @@ namespace clitk
   {
     //Projection pointer
     InputImageConstPointer inputPtr=this->GetInput();
-    InputPixelType * beginPtr=const_cast<InputPixelType *>(this->GetInput()->GetBufferPointer());
-    InputPixelType * pp;
     
     //Volume pointer
     OutputImagePointer outputPTr= this->GetOutput();
@@ -325,8 +326,6 @@ namespace clitk
     OutputIndexType oIndex;
     ContinuousInputIndexType iIndex;
     InputSizeType inputSize=inputPtr->GetLargestPossibleRegion().GetSize();
-    double dx,dy,dxm,dym;
-    int lx, ly;
 
     //Get the first output coordinate
     oIndex=iterator.GetIndex();//costly but only once a thread
@@ -337,9 +336,13 @@ namespace clitk
        
     //Compute the first input coordinate (invert Y/X)
     homInputPoint= (m_ProjectionMatrix * homOutputPoint);
-    iPoint[0]=-homInputPoint[0]/homInputPoint[2];
-    iPoint[1]=homInputPoint[1]/homInputPoint[2];
-    
+    iPoint[0]=-homInputPoint[0]/homInputPoint[2] + m_PanelShift[0];
+    iPoint[1]=homInputPoint[1]/homInputPoint[2] + m_PanelShift[1];
+
+    typedef itk::LinearInterpolateImageFunction< InputImageType, double > InterpolatorType;
+    typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
+    interpolator->SetInputImage(this->GetInput());
+
     //Run over all output voxels
     for (unsigned int i=0; i<outputSizeForThread[2]; i++)
       {
@@ -347,25 +350,15 @@ namespace clitk
          {
            for (unsigned int k=0; k<outputSizeForThread[0]; k++)
              {
-               iPoint[0]=homInputPoint[0]/homInputPoint[2];
-               iPoint[1]=homInputPoint[1]/homInputPoint[2];
+               iPoint[0]=-homInputPoint[0]/homInputPoint[2] + m_PanelShift[0];
+               iPoint[1]=homInputPoint[1]/homInputPoint[2] + m_PanelShift[1];
 
                //Check wether inside, convert to index (use modified with correct origin)
-               if( m_ModifiedInput->TransformPhysicalPointToContinuousIndex(iPoint, iIndex) )
-                 {
-                   //Own (fast bilinear) interpolation   
-                   lx = (int)floor(iIndex[0]); dx = iIndex[0]-lx; dxm = 1.-dx;
-                   ly = (int)floor(iIndex[1]); dy = iIndex[1]-ly; dym = 1.-dy;
-                   pp = beginPtr + ly*inputSize[0]+lx;
-                   value =static_cast<OutputPixelType>( ( dxm  * dym*(double)(*pp) 
-                                                          + dx * dym*(double)(*(pp+1)) 
-                                                          + dxm* dy *(double)(*(pp + inputSize[0]))
-                                                          + dx * dy *(double)(*(pp + inputSize[0]+1))) );
-           
-                 }
+               if (m_ModifiedInput->TransformPhysicalPointToContinuousIndex(iPoint, iIndex) && interpolator->IsInsideBuffer(iIndex))
+                    value = interpolator->EvaluateAtContinuousIndex(iIndex);
                //Outside: padding value
-               else value=m_EdgePaddingValue;
-               
+               else
+                  value=m_EdgePaddingValue;
                //Set it
                iterator.Set(value);
 
index b02de1bd9f3d14c068f96f263e9d72ec7fd9b5ff..e70d9c3f26dc8f74473fde3e677c584eba1b173a 100644 (file)
@@ -116,7 +116,7 @@ namespace clitk
                
                
                // get neighbor index and overlap fraction
-               for( dim = 0; dim < 3; dim++ )
+               for( dim = 0; dim < ImageDimension; dim++ )
                  {
                    if ( upper & 1 )
                      {
index 2059f9d96368eef66e0df5bc93f38b625854ba9d..f3c66d33a326ee9949cb4cf64a6f68e7dfe5cfc2 100644 (file)
@@ -277,9 +277,9 @@ namespace clitk
                    IndexType idx = tmpRegIndexIt.GetIndex() + *itIdx;
                    if( outputRegion.IsInside( idx ) )
                      { 
-                       // JV output->SetPixel( idx, static_cast<OutputPixelType> ( foregroundValue ) ); }
-                       if (input->GetPixel(idx)==backgroundValue)
-                         output->SetPixel( idx, static_cast<OutputPixelType> ( foregroundValue ) ); 
+            // JV output->SetPixel( idx, static_cast<OutputPixelType> ( foregroundValue ) ); }
+            if (input->GetPixel(idx)==backgroundValue)
+                output->SetPixel( idx, static_cast<OutputPixelType> ( foregroundValue ) ); 
                      }
                  }
  
diff --git a/itk/clitkConditionalGrayscaleDilateImageFilter.h b/itk/clitkConditionalGrayscaleDilateImageFilter.h
new file mode 100644 (file)
index 0000000..c129102
--- /dev/null
@@ -0,0 +1,148 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile: itkGrayscaleDilateImageFilter.h,v $
+  Language:  C++
+  Date:      $Date: 2009-04-28 14:36:20 $
+  Version:   $Revision: 1.19 $
+
+  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 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#ifndef __clitkGrayscaleDilateImageFilter_h
+#define __clitkGrayscaleDilateImageFilter_h
+
+// First make sure that the configuration is available.
+// This line can be removed once the optimized versions
+// gets integrated into the main directories.
+#include "itkConfigure.h"
+
+#ifdef ITK_USE_CONSOLIDATED_MORPHOLOGY
+#include "itkOptGrayscaleDilateImageFilter.h"
+#else
+
+
+#include "itkMorphologyImageFilter.h"
+
+namespace itk {
+
+/**
+ * \class ConditionalGrayscaleDilateImageFilter
+ * \brief gray scale dilation of an image
+ *
+ * Dilate an image using grayscale morphology. Dilation takes the
+ * maximum of all the pixels identified by the structuring element.
+ *
+ * The structuring element is assumed to be composed of binary
+ * values (zero or one). Only elements of the structuring element
+ * having values > 0 are candidates for affecting the center pixel.
+ * 
+ * For the each input image pixel, 
+ *   - NeighborhoodIterator gives neighbors of the pixel. 
+ *   - Evaluate() member function returns the maximum value among 
+ *     the image neighbors where the kernel has elements > 0.
+ *   - Replace the original value with the max value
+ *
+ * \sa MorphologyImageFilter, GrayscaleFunctionDilateImageFilter, BinaryDilateImageFilter
+ * \ingroup ImageEnhancement  MathematicalMorphologyImageFilters
+ */
+
+template<class TInputImage, class TOutputImage, class TKernel>
+class ITK_EXPORT ConditionalGrayscaleDilateImageFilter : 
+    public MorphologyImageFilter<TInputImage, TOutputImage, TKernel>
+{
+public:
+  /** Standard class typedefs. */
+  typedef ConditionalGrayscaleDilateImageFilter Self;
+  typedef MorphologyImageFilter<TInputImage, TOutputImage, TKernel>
+                                     Superclass;
+  typedef SmartPointer<Self>         Pointer;
+  typedef SmartPointer<const Self>   ConstPointer;
+  
+  /** Standard New method. */
+  itkNewMacro(Self);  
+
+  /** Runtime information support. */
+  itkTypeMacro(ConditionalGrayscaleDilateImageFilter, 
+               MorphologyImageFilter);
+  
+  /** Declaration of pixel type. */
+  typedef typename Superclass::PixelType PixelType;
+
+  /** Kernel (structuring element) iterator. */
+  typedef typename Superclass::KernelIteratorType  KernelIteratorType;
+
+  /** Neighborhood iterator type. */
+  typedef typename Superclass::NeighborhoodIteratorType NeighborhoodIteratorType;
+
+  /** Kernel typedef. */
+  typedef typename Superclass::KernelType KernelType;
+
+  /** Default boundary condition type */
+  typedef typename Superclass::DefaultBoundaryConditionType DefaultBoundaryConditionType;
+
+  /** ImageDimension constants */
+  itkStaticConstMacro(InputImageDimension, unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension, unsigned int,
+                      TOutputImage::ImageDimension);
+  itkStaticConstMacro(KernelDimension, unsigned int,
+                      TKernel::NeighborhoodDimension);
+
+  /** Type of the pixels in the Kernel. */
+  typedef typename TKernel::PixelType            KernelPixelType;
+
+#ifdef ITK_USE_CONCEPT_CHECKING
+  /** Begin concept checking */
+  itkConceptMacro(InputConvertibleToOutputCheck,
+    (Concept::Convertible<PixelType, typename TOutputImage::PixelType>));
+  itkConceptMacro(SameDimensionCheck1,
+     (Concept::SameDimension<InputImageDimension, OutputImageDimension>));
+  itkConceptMacro(SameDimensionCheck2,
+    (Concept::SameDimension<InputImageDimension, KernelDimension>));
+  itkConceptMacro(InputGreaterThanComparableCheck,
+    (Concept::GreaterThanComparable<PixelType>));
+  itkConceptMacro(KernelGreaterThanComparableCheck,
+    (Concept::GreaterThanComparable<KernelPixelType>));
+  /** End concept checking */
+#endif
+
+protected:
+  ConditionalGrayscaleDilateImageFilter();
+  ~ConditionalGrayscaleDilateImageFilter() {};
+
+  /** Evaluate image neighborhood with kernel to find the new value 
+   * for the center pixel value
+   *
+   * It will return the maximum value of the image pixels whose corresponding
+   * element in the structuring element is positive. This version of
+   * Evaluate is used for non-boundary pixels. */
+  PixelType Evaluate(const NeighborhoodIteratorType &nit,
+                     const KernelIteratorType kernelBegin,
+                     const KernelIteratorType kernelEnd);
+
+private:
+  ConditionalGrayscaleDilateImageFilter(const Self&); //purposely not implemented
+  void operator=(const Self&); //purposely not implemented
+
+  // Default boundary condition for dilation filter, defaults to
+  // NumericTraits<PixelType>::NonpositiveMin()
+  DefaultBoundaryConditionType m_DilateBoundaryCondition;
+
+}; // end of class
+
+} // end namespace itk
+  
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkConditionalGrayscaleDilateImageFilter.txx"
+#endif
+
+#endif
+
+#endif
diff --git a/itk/clitkConditionalGrayscaleDilateImageFilter.txx b/itk/clitkConditionalGrayscaleDilateImageFilter.txx
new file mode 100644 (file)
index 0000000..84ed968
--- /dev/null
@@ -0,0 +1,86 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile: itkConditionalGrayscaleDilateImageFilter.txx,v $
+  Language:  C++
+  Date:      $Date: 2009-04-28 14:36:20 $
+  Version:   $Revision: 1.17 $
+
+  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 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __clitkConditionalGrayscaleDilateImageFilter_txx
+#define __clitkConditionalGrayscaleDilateImageFilter_txx
+
+// First make sure that the configuration is available.
+// This line can be removed once the optimized versions
+// gets integrated into the main directories.
+#include "itkConfigure.h"
+
+#ifdef ITK_USE_CONSOLIDATED_MORPHOLOGY
+#include "itkOptGrayscaleDilateImageFilter.txx"
+#else
+
+
+#include "clitkConditionalGrayscaleDilateImageFilter.h"
+
+namespace itk {
+
+template<class TInputImage, class TOutputImage, class TKernel>
+ConditionalGrayscaleDilateImageFilter<TInputImage, TOutputImage, TKernel>
+::ConditionalGrayscaleDilateImageFilter()
+{
+  m_DilateBoundaryCondition.SetConstant( NumericTraits<PixelType>::NonpositiveMin() );
+  this->OverrideBoundaryCondition( &m_DilateBoundaryCondition );
+}
+
+template<class TInputImage, class TOutputImage, class TKernel>
+typename ConditionalGrayscaleDilateImageFilter<TInputImage, TOutputImage, TKernel>::PixelType
+ConditionalGrayscaleDilateImageFilter<TInputImage, TOutputImage, TKernel>
+::Evaluate(const NeighborhoodIteratorType &nit,
+           const KernelIteratorType kernelBegin,
+           const KernelIteratorType kernelEnd)
+{
+  unsigned int i;
+  PixelType max = NumericTraits<PixelType>::NonpositiveMin();
+  PixelType temp;
+
+  KernelIteratorType kernel_it;
+
+  PixelType center = nit.GetCenterPixel ();
+  // if (center != NumericTraits<KernelPixelType>::Zero)  {
+  //   DD((int)center);
+  // }
+
+  if (center > NumericTraits<KernelPixelType>::Zero) return center;
+  
+  for( i=0, kernel_it=kernelBegin; kernel_it<kernelEnd; ++kernel_it, ++i )
+    {
+    // if structuring element is positive, use the pixel under that element
+    // in the image
+    if( *kernel_it > NumericTraits<KernelPixelType>::Zero )
+      {
+      // note we use GetPixel() on the SmartNeighborhoodIterator to
+      // respect boundary conditions
+      temp = nit.GetPixel(i);
+
+      if( temp > max )
+        {
+        max = temp;
+        }
+      }
+    }
+  
+  return max;
+} 
+
+
+}// end namespace itk
+#endif
+
+#endif
index 0af957bb20c6e8ae57e5b560920c3a907719ceea..28772392ff7fff31a4b9b738b5a08e69909832e3 100644 (file)
@@ -136,6 +136,16 @@ GenerateOutputInformation() {
                           << ") of 'like' is " << likeSpacing[i] << ".");
     }
   }
+
+  // Check that we must crop along each dimension. If not, we use the
+  // size of the input image
+  for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
+    if (m_CropAlongThisDimension[i] == false) {
+      likeStart[i] = input->GetLargestPossibleRegion().GetIndex()[i];
+      likeSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
+    }
+  }
+
   // Define output region 
   m_OutputRegion.SetIndex(likeStart);
   m_OutputRegion.SetSize(likeSize);
index 68033a05225f698da19f0adccfac13c5f08ad8b1..3ab61cbd141b02d815a58e1476caf48df8fef1bf 100644 (file)
@@ -97,8 +97,9 @@ namespace clitk
     itkGetConstMacro( Outside, InternalPixelType);  
     itkSetMacro( ErosionPaddingValue, OutputPixelType);
     itkGetConstMacro( ErosionPaddingValue, OutputPixelType);  
-    void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
+    void SetRadius ( const SizeType& s) { m_Radius=s; this->Modified();}
     SizeType GetRadius(void){return m_Radius;}
+    void SetRadius(const int r) { for(uint i=0; i<InputImageDimension; i++) m_Radius[i] = r; SetRadius(m_Radius); }
     itkSetMacro( NumberOfNewLabels, unsigned int);
     itkGetConstMacro( NumberOfNewLabels, unsigned int);
     itkSetMacro( MinimumObjectSize, unsigned int);
index deabdfc5cd53e8bb9128159d9b3eaa606e1c535b..43874d0265f60cd70b11c5916a5b3c5bea85a74c 100644 (file)
@@ -118,6 +118,9 @@ GenerateData() {
     m_index[GetDirection()] = start + i;
     m_region.SetIndex(m_index);
     extract->SetExtractionRegion(m_region);
+#if ITK_VERSION_MAJOR == 4
+    extract->SetDirectionCollapseToSubmatrix();
+#endif
     extract->Update();
     SetNthOutput(i, extract->GetOutput());
   }
index 5e1bb132d05470e9fd3c3ab69f2ec7028b431b66..e99ef0fde6b0ca08883abe75fa48832807145a7e 100644 (file)
@@ -154,6 +154,7 @@ void HelperClass1<InputImageType, OutputImageType, DeformationFieldType>::Thread
   //define some temp variables
   signed long baseIndex[ImageDimension];
   double distance[ImageDimension];
+  for(uint i=0; i<ImageDimension; i++) distance[i] = 0.0; // to avoid warning
   unsigned int dim, counter, upper;
   double overlap, totalOverlap;
   typename OutputImageType::IndexType neighIndex;
@@ -195,7 +196,7 @@ void HelperClass1<InputImageType, OutputImageType, DeformationFieldType>::Thread
         upper = counter;  // each bit indicates upper/lower neighbour
 
         // get neighbor index and overlap fraction
-        for( dim = 0; dim < 3; dim++ ) {
+        for( dim = 0; dim < ImageDimension; dim++ ) {
           if ( upper & 1 ) {
             neighIndex[dim] = baseIndex[dim] + 1;
             overlap *= distance[dim];
index c464c08ea50b4b827dc3ef1a828c3e8cf0e2a133..32d31fe51075bf235a8256d9d8066f38d7bf509a 100644 (file)
 #include "itkConnectedComponentImageFilter.h"
 #include "itkStatisticsImageFilter.h"
 #include "itkCastImageFilter.h"
-#include "itkDifferenceImageFilter.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkTestingComparisonImageFilter.h"
+#else
+  #include "itkDifferenceImageFilter.h"
+#endif
 #include "itkThresholdImageFilter.h"
 
 namespace clitk 
@@ -84,6 +88,7 @@ namespace clitk
     itkSetMacro( Verbose, bool);
     itkGetConstReferenceMacro( Verbose, bool);
     void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
+    void SetRadius(const int r) { for(uint i=0; i<InputImageDimension; i++) m_Radius[i] = r; SetRadius(m_Radius); }
     SizeType GetRadius(void){return m_Radius;}
     itkSetMacro( ErosionPaddingValue, OutputPixelType);
     itkGetConstMacro( ErosionPaddingValue, OutputPixelType)
index 82e28e6e6c421be11de171eae8a1b7733791b30e..8e30eb39e6dbb4efeae79b8a6493d1094a4d22d0 100644 (file)
@@ -68,7 +68,11 @@ namespace clitk
     typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
     typedef itk::BinaryBallStructuringElement<InternalPixelType,InputImageDimension > KernelType;
     typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> ConditionalBinaryDilateImageFilterType;
+#if ITK_VERSION_MAJOR >= 4
+    typedef itk::Testing::ComparisonImageFilter<InternalImageType, InternalImageType> DifferenceImageFilterType;
+#else
     typedef itk::DifferenceImageFilter<InternalImageType, InternalImageType> DifferenceImageFilterType;
+#endif
     typedef itk::CastImageFilter<InternalImageType, OutputImageType> OutputCastImageFilterType;
     typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
 
diff --git a/itk/clitkReconstructWithConditionalGrayscaleDilateImageFilter.h b/itk/clitkReconstructWithConditionalGrayscaleDilateImageFilter.h
new file mode 100644 (file)
index 0000000..0b0de84
--- /dev/null
@@ -0,0 +1,108 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+
+#ifndef clitkReconstructWithConditionalGrayscaleDilateImageFilter_h
+#define clitkReconstructWithConditionalGrayscaleDilateImageFilter_h
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkConditionalGrayscaleDilateImageFilter.h"
+
+namespace clitk 
+{
+  /*
+    This filter takes as input a multilabel image (and a bg value).
+    It performs several greyscale dilatation of radius 1, but only in
+    the bg pixels. It means that when two objects (with different
+    labels) will dilate inside each other (collistion), the dilatation
+    is stopped.
+   */
+
+  template <class ImageType>
+  class ITK_EXPORT ReconstructWithConditionalGrayscaleDilateImageFilter :
+    public itk::ImageToImageFilter<ImageType, ImageType>
+  {
+  public:
+    //----------------------------------------
+    // ITK
+    //----------------------------------------
+    typedef ReconstructWithConditionalGrayscaleDilateImageFilter Self;
+    typedef itk::ImageToImageFilter<ImageType, ImageType>        Superclass;
+    typedef itk::SmartPointer<Self>                              Pointer;
+    typedef itk::SmartPointer<const Self>                        ConstPointer;
+   
+    // Method for creation through the object factory
+    itkNewMacro(Self);  
+
+    // Run-time type information (and related methods)
+    itkTypeMacro( ReconstructWithConditionalGrayscaleDilateImageFilter, ImageToImageFilter);
+
+    /** Dimension of the domain space. */
+    itkStaticConstMacro(ImageDimension, unsigned int, Superclass::InputImageDimension);
+
+    //----------------------------------------
+    // Typedefs
+    //----------------------------------------
+    typedef typename ImageType::PixelType PixelType;
+    typedef typename ImageType::SizeType SizeType;
+
+    //----------------------------------------
+    // Set & Get
+    //----------------------------------------    
+    itkBooleanMacro(Verbose);
+    itkSetMacro( Verbose, bool);
+    itkGetConstReferenceMacro( Verbose, bool);
+
+    itkSetMacro(IterationNumber, int);
+    itkGetConstMacro(IterationNumber, int);
+
+    itkSetMacro(BackgroundValue, PixelType);
+    itkGetConstMacro(BackgroundValue, PixelType);
+
+  protected:
+
+    //----------------------------------------  
+    // Constructor & Destructor
+    //----------------------------------------  
+    ReconstructWithConditionalGrayscaleDilateImageFilter();
+    ~ReconstructWithConditionalGrayscaleDilateImageFilter() {};
+
+    //----------------------------------------  
+    // Update
+    //----------------------------------------  
+    // Generate Data
+    void GenerateData(void);
+
+    //----------------------------------------  
+    // Data members
+    //----------------------------------------
+    bool m_Verbose;
+    PixelType m_BackgroundValue;
+    int m_IterationNumber;
+  };
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkReconstructWithConditionalGrayscaleDilateImageFilter.txx"
+#endif
+
+#endif // #define clitkReconstructWithConditionalGrayscaleDilateImageFilter_h
+
+
diff --git a/itk/clitkReconstructWithConditionalGrayscaleDilateImageFilter.txx b/itk/clitkReconstructWithConditionalGrayscaleDilateImageFilter.txx
new file mode 100644 (file)
index 0000000..7a68818
--- /dev/null
@@ -0,0 +1,79 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+
+#ifndef clitkReconstructWithConditionalGrayscaleDilateImageFilter_txx
+#define clitkReconstructWithConditionalGrayscaleDilateImageFilter_txx
+
+#include <itkGrayscaleDilateImageFilter.h>
+
+namespace clitk
+{
+
+  //-------------------------------------------------------------------
+  template<class ImageType>
+  ReconstructWithConditionalGrayscaleDilateImageFilter<ImageType>::ReconstructWithConditionalGrayscaleDilateImageFilter()
+  {
+   m_Verbose=false;
+   m_BackgroundValue=0;
+   m_IterationNumber = 5;
+  }
+  //-------------------------------------------------------------------
+
+  //-------------------------------------------------------------------
+  template<class ImageType> 
+  void 
+  ReconstructWithConditionalGrayscaleDilateImageFilter<ImageType>::GenerateData()
+  {
+    // Get input image 
+    typename ImageType::ConstPointer input = this->GetInput();
+
+    // Main loop
+    typename ImageType::Pointer output;
+    for(int r=0; r<GetIterationNumber(); r++) {
+      
+      // Create kernel for GrayscaleDilateImageFilter
+      typedef itk::BinaryBallStructuringElement<PixelType,ImageDimension > KernelType;
+      KernelType k;
+      k.SetRadius(1);
+      k.CreateStructuringElement();
+    
+      // Check that BG is 0, because ConditionalGrayscaleDilateImageFilter consider BG is 0
+      if (GetBackgroundValue() !=0) {
+        FATAL("FATAL -> BG is not 0, check ReconstructWithConditionalGrayscaleDilateImageFilter");
+        // TODO -> replace 0 with new label, replace BG with 0 ; reverse at the end
+      }
+      
+      // ConditionalGrayscaleDilateImageFilter -> Dilate only BG value
+      typedef itk::ConditionalGrayscaleDilateImageFilter<ImageType, ImageType, KernelType> FilterType;
+      typename FilterType::Pointer m = FilterType::New();
+      m->SetKernel(k);
+      if (r==0) {
+        m->SetInput(input); // First time
+      }
+      else m->SetInput(output);
+      m->Update();
+      output = m->GetOutput();
+    }
+
+    //---------------------------------
+    this->SetNthOutput(0, output);
+  }
+
+}//end clitk
+#endif //#define clitkReconstructWithConditionalGrayscaleDilateImageFilter_txx
index 7e5eeab4eb78e9d4745d4b9a92fd8f2e34d6430b..a3f88beb3db8443f08fa376da1480433f24e4051 100644 (file)
@@ -125,11 +125,15 @@ GenerateOutputInformation()
       // floor() is used to intentionally reduce the number of slices 
       // because, from a clinical point of view, it's better to 
       // remove data than to add data that privously didn't exist.
+      if(inputSpacing[i]*m_OutputSpacing[i]<0)
+        itkExceptionMacro( << "Input and output spacings don't have the same signs, can't cope with that" );
       m_OutputSize[i] = (int)floor(inputSize[i]*inputSpacing[i]/m_OutputSpacing[i]);
     }
   } else {
     if (m_OutputSpacing[0] != -1) { // apply spacing, compute size
       for(unsigned int i=0; i<dim; i++) {
+        if(inputSpacing[i]*m_OutputSpacing[i]<0)
+          itkExceptionMacro( << "Input and output spacings don't have the same signs, can't cope with that" );
        // see comment above for the use of floor()
        m_OutputSize[i] = (int)floor(inputSize[i]*inputSpacing[i]/m_OutputSpacing[i]);
       }
@@ -151,7 +155,7 @@ GenerateOutputInformation()
     m_OutputSize[l] = inputSize[l];
     m_OutputSpacing[l] = inputSpacing[l];
   }
-    
+
   // Set Size/Spacing
   OutputImagePointer outputImage = this->GetOutput(0);
   // OutputImageRegionType region;
index 5aa9b9aefbb92cd73b2463e44e07d98a675be2b0..6204c9c96639b78c7be26a440cbd7b9cf21ddbe8 100644 (file)
@@ -23,6 +23,7 @@
 #include "clitkCommon.h"
 #include "clitkAutoCropFilter.h"
 #include "clitkLabelizeParameters.h"
+#include "clitkExtractSliceFilter.h"
 
 // itk
 #include <itkBoundingBox.h>
@@ -192,18 +193,23 @@ namespace clitk {
                         typename ImageType::PixelType BG=0);
   template<class ImageType>
   typename ImageType::Pointer
-  CropImageAbove(const ImageType * image, 
-                 int dim, double min, bool autoCrop = false,
-                 typename ImageType::PixelType BG=0);
+  CropImageRemoveGreaterThan(const ImageType * image, 
+                             int dim, double min, bool autoCrop = false,
+                             typename ImageType::PixelType BG=0);
   template<class ImageType>
   typename ImageType::Pointer
-  CropImageBelow(const ImageType * image, 
-                 int dim, double max,bool autoCrop = false,
-                 typename ImageType::PixelType BG=0);
+  CropImageRemoveLowerThan(const ImageType * image, 
+                           int dim, double max,bool autoCrop = false,
+                           typename ImageType::PixelType BG=0);
   //--------------------------------------------------------------------
 
 
   //--------------------------------------------------------------------
+  template<class ImageType, class LabelType>
+  typename itk::LabelMap< itk::ShapeLabelObject<LabelType, ImageType::ImageDimension> >::Pointer
+  ComputeLabelMap(const ImageType * image, 
+                  typename ImageType::PixelType BG,                   
+                  bool computePerimeterFlag=false);
   template<class ImageType>
   void
   ComputeCentroids(const ImageType * image, 
@@ -220,9 +226,19 @@ namespace clitk {
   //--------------------------------------------------------------------
   template<class ImageType>
   void
-  ExtractSlices(const ImageType * image, int dim, 
-               std::vector< typename itk::Image<typename ImageType::PixelType, 
-                                                 ImageType::ImageDimension-1>::Pointer > & slices);
+  ExtractSlices(const ImageType * image, int direction,
+                std::vector<typename itk::Image<typename ImageType::PixelType,
+                                                ImageType::ImageDimension-1>::Pointer > & slices)
+  {
+    typedef ExtractSliceFilter<ImageType> ExtractSliceFilterType;
+    typedef typename ExtractSliceFilterType::SliceType SliceType;
+    typename ExtractSliceFilterType::Pointer
+      extractSliceFilter = ExtractSliceFilterType::New();
+    extractSliceFilter->SetInput(image);
+    extractSliceFilter->SetDirection(direction);
+    extractSliceFilter->Update();
+    extractSliceFilter->GetOutputSlices(slices);
+  }
   //--------------------------------------------------------------------
 
 
@@ -308,6 +324,15 @@ namespace clitk {
          bool extendSupport);
   //--------------------------------------------------------------------
 
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer 
+  Opening(const ImageType * image, typename ImageType::SizeType radius,
+          typename ImageType::PixelType BG, typename ImageType::PixelType FG);
+  //--------------------------------------------------------------------
+
+
   //--------------------------------------------------------------------
   template<class ValueType, class VectorType>
   void ConvertOption(std::string optionName, uint given, 
@@ -334,6 +359,10 @@ namespace clitk {
   void AndNot(ImageType * input, 
               const ImageType * object, 
               typename ImageType::PixelType BG=0);
+  template<class ImageType>
+  void And(ImageType * input, 
+           const ImageType * object, 
+           typename ImageType::PixelType BG=0);
   //--------------------------------------------------------------------
  
 
@@ -389,6 +418,60 @@ namespace clitk {
   //--------------------------------------------------------------------
 
 
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer
+  SliceBySliceKeepMainCCL(const ImageType * input, 
+                          typename ImageType::PixelType BG,
+                          typename ImageType::PixelType FG);
+  //--------------------------------------------------------------------
+  
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer
+  Clone(const ImageType * input);
+  //--------------------------------------------------------------------
+  
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer
+  SliceBySliceSetBackgroundFromSingleLine(const ImageType * input, 
+                                          typename ImageType::PixelType BG, 
+                                          typename ImageType::PointType & A, 
+                                          typename ImageType::PointType & B, 
+                                          int dim1, int dim2, bool removeLowerPartFlag);
+  //--------------------------------------------------------------------
+  
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer
+  SliceBySliceSetBackgroundFromPoints(const ImageType * input, 
+                                      typename ImageType::PixelType BG, 
+                                      int sliceDim,
+                                      std::vector<typename ImageType::PointType> & A, 
+                                      bool removeGreaterThanXFlag,
+                                      bool removeGreaterThanYFlag);
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  void
+  FillRegionWithValue(ImageType * input, typename ImageType::PixelType value, 
+                      typename ImageType::RegionType & region);
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  void
+  GetMinMaxBoundary(ImageType * input, typename ImageType::PointType & min, 
+                    typename ImageType::PointType & max);
+  //--------------------------------------------------------------------
+
 }
 
 #include "clitkSegmentationUtils.txx"
index 7acec2087eee0da0f898af71a47cf99caf331092..afcefcf3077701a64abeb070374ece19c45ba044 100644 (file)
@@ -32,6 +32,8 @@
 #include <itkBinaryDilateImageFilter.h>
 #include <itkConstantPadImageFilter.h>
 #include <itkImageSliceIteratorWithIndex.h>
+#include <itkBinaryMorphologicalOpeningImageFilter.h>
+#include <itkImageDuplicator.h>
 
 namespace clitk {
 
@@ -352,6 +354,7 @@ namespace clitk {
     sliceRelPosFilter->SetIntermediateSpacingFlag((spacing != -1));
     sliceRelPosFilter->SetIntermediateSpacing(spacing);
     sliceRelPosFilter->SetUniqueConnectedComponentBySlice(uniqueConnectedComponent);
+    sliceRelPosFilter->CCLSelectionFlagOff();
     sliceRelPosFilter->SetUseASingleObjectConnectedComponentBySliceFlag(singleObjectCCL);
     //    sliceRelPosFilter->SetInverseOrientationFlag(inverseflag); 
     sliceRelPosFilter->SetAutoCropFlag(autocropFlag); 
@@ -420,7 +423,7 @@ namespace clitk {
   //--------------------------------------------------------------------
   template<class ImageType>
   typename ImageType::Pointer
-  CropImageAbove(const ImageType * image, 
+  CropImageRemoveGreaterThan(const ImageType * image, 
                  int dim, double min, bool autoCrop,
                  typename ImageType::PixelType BG) 
   {
@@ -435,7 +438,7 @@ namespace clitk {
   //--------------------------------------------------------------------
   template<class ImageType>
   typename ImageType::Pointer
-  CropImageBelow(const ImageType * image, 
+  CropImageRemoveLowerThan(const ImageType * image, 
                  int dim, double max, bool autoCrop,
                  typename ImageType::PixelType BG) 
   {
@@ -464,7 +467,7 @@ namespace clitk {
     p[dim] = max;
     typename ImageType::IndexType end;
     image->TransformPhysicalPointToIndex(p, end);
-    size[dim] = fabs(end[dim]-start[dim]);
+    size[dim] = abs(end[dim]-start[dim]);
     region.SetIndex(start);
     region.SetSize(size);
   
@@ -508,14 +511,40 @@ namespace clitk {
 
     centroids.clear();
     typename ImageType::PointType dummy;
-    centroids.push_back(dummy); // label 0 -> no centroid, use dummy point
-    for(uint i=1; i<labelMap->GetNumberOfLabelObjects()+1; i++) {
-      centroids.push_back(labelMap->GetLabelObject(i)->GetCentroid());
+    centroids.push_back(dummy); // label 0 -> no centroid, use dummy point for BG 
+    //DS FIXME (not useful ! to change ..)
+    for(uint i=0; i<labelMap->GetNumberOfLabelObjects(); i++) {
+      int label = labelMap->GetLabels()[i];
+      centroids.push_back(labelMap->GetLabelObject(label)->GetCentroid());
     } 
   }
   //--------------------------------------------------------------------
 
 
+  //--------------------------------------------------------------------
+  template<class ImageType, class LabelType>
+  typename itk::LabelMap< itk::ShapeLabelObject<LabelType, ImageType::ImageDimension> >::Pointer
+  ComputeLabelMap(const ImageType * image, 
+                  typename ImageType::PixelType BG, 
+                  bool computePerimeterFlag) 
+  {
+    static const unsigned int Dim = ImageType::ImageDimension;
+    typedef itk::ShapeLabelObject< LabelType, Dim > LabelObjectType;
+    typedef itk::LabelMap< LabelObjectType > LabelMapType;
+    typedef itk::LabelImageToLabelMapFilter<ImageType, LabelMapType> ImageToMapFilterType;
+    typename ImageToMapFilterType::Pointer imageToLabelFilter = ImageToMapFilterType::New(); 
+    typedef itk::ShapeLabelMapFilter<LabelMapType, ImageType> ShapeFilterType; 
+    typename ShapeFilterType::Pointer statFilter = ShapeFilterType::New();
+    imageToLabelFilter->SetBackgroundValue(BG);
+    imageToLabelFilter->SetInput(image);
+    statFilter->SetInput(imageToLabelFilter->GetOutput());
+    statFilter->SetComputePerimeter(computePerimeterFlag);
+    statFilter->Update();
+    return statFilter->GetOutput();
+  }
+  //--------------------------------------------------------------------
+
+
   //--------------------------------------------------------------------
   template<class ImageType>
   void
@@ -557,25 +586,6 @@ namespace clitk {
   //--------------------------------------------------------------------
 
 
-  //--------------------------------------------------------------------
-  template<class ImageType>
-  void
-  ExtractSlices(const ImageType * image, int direction, 
-                std::vector<typename itk::Image<typename ImageType::PixelType, 
-                                                ImageType::ImageDimension-1>::Pointer > & slices) 
-  {
-    typedef ExtractSliceFilter<ImageType> ExtractSliceFilterType;
-    typedef typename ExtractSliceFilterType::SliceType SliceType;
-    typename ExtractSliceFilterType::Pointer 
-      extractSliceFilter = ExtractSliceFilterType::New();
-    extractSliceFilter->SetInput(image);
-    extractSliceFilter->SetDirection(direction);
-    extractSliceFilter->Update();
-    extractSliceFilter->GetOutputSlices(slices);
-  }
-  //--------------------------------------------------------------------
-
-
   //--------------------------------------------------------------------
   template<class ImageType>
   void
@@ -720,13 +730,42 @@ namespace clitk {
     dilateFilter->SetForegroundValue(FG);
     dilateFilter->SetBoundaryToForeground(false);
     dilateFilter->SetKernel(structuringElement);
-    dilateFilter->SetInput(output);
+    if (extendSupport) dilateFilter->SetInput(output);
+    else dilateFilter->SetInput(image);
     dilateFilter->Update();
     return dilateFilter->GetOutput();
   }
   //--------------------------------------------------------------------
 
 
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer 
+  Opening(const ImageType * image, typename ImageType::SizeType radius,
+         typename ImageType::PixelType BG,
+         typename ImageType::PixelType FG)
+  {
+    // Kernel 
+    typedef itk::BinaryBallStructuringElement<typename ImageType::PixelType, 
+                                              ImageType::ImageDimension> KernelType;    
+    KernelType structuringElement;
+    structuringElement.SetRadius(radius);
+    structuringElement.CreateStructuringElement();
+    
+    // Filter
+    typedef itk::BinaryMorphologicalOpeningImageFilter<ImageType, ImageType , KernelType> OpeningFilterType;
+    typename OpeningFilterType::Pointer open = OpeningFilterType::New();
+    open->SetInput(image);
+    open->SetBackgroundValue(BG);
+    open->SetForegroundValue(FG);
+    open->SetKernel(structuringElement);
+    open->Update();
+    return open->GetOutput();
+  }
+  //--------------------------------------------------------------------
+
+
+
   //--------------------------------------------------------------------
   template<class ValueType, class VectorType>
   void ConvertOption(std::string optionName, uint given, 
@@ -793,9 +832,6 @@ namespace clitk {
     while ((i<lA.size()) && (!siter.IsAtEnd())) {
       // Check that the current slice correspond to the current point
       input->TransformIndexToPhysicalPoint(siter.GetIndex(), C);
-      // DD(C);
-      // DD(i);
-      // DD(lA[i]);
       if ((fabs(C[2] - lA[i][2]))>0.01) { // is !equal with a tolerance of 0.01 mm
       }
       else {
@@ -803,9 +839,6 @@ namespace clitk {
         A = lA[i];
         B = lB[i];
         C = A;
-        // DD(A);
-        // DD(B);
-        // DD(C);
       
         // Check that the line is not a point (A=B)
         bool p = (A[0] == B[0]) && (A[1] == B[1]);
@@ -839,6 +872,7 @@ namespace clitk {
   }                                                   
   //--------------------------------------------------------------------
 
+
   //--------------------------------------------------------------------
   template<class ImageType>
   void 
@@ -867,6 +901,34 @@ namespace clitk {
   //--------------------------------------------------------------------
 
 
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  void 
+  And(ImageType * input, 
+      const ImageType * object, 
+      typename ImageType::PixelType BG)
+  {
+    typename ImageType::Pointer o;
+    bool resized=false;
+    if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(input, object)) {
+      o = clitk::ResizeImageLike<ImageType>(object, input, BG);
+      resized = true;
+    }
+
+    typedef clitk::BooleanOperatorLabelImageFilter<ImageType> BoolFilterType;
+    typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); 
+    boolFilter->InPlaceOn();
+    boolFilter->SetInput1(input);
+    if (resized) boolFilter->SetInput2(o);  
+    else boolFilter->SetInput2(object);
+    boolFilter->SetBackgroundValue1(BG);
+    boolFilter->SetBackgroundValue2(BG);
+    boolFilter->SetOperationType(BoolFilterType::And);
+    boolFilter->Update();
+  }
+  //--------------------------------------------------------------------
+
+
   //--------------------------------------------------------------------
   template<class ImageType>
   typename ImageType::Pointer
@@ -879,6 +941,7 @@ namespace clitk {
     typedef itk::BinaryThresholdImageFilter<ImageType, ImageType> BinaryThresholdFilterType;
     typename BinaryThresholdFilterType::Pointer binarizeFilter = BinaryThresholdFilterType::New();
     binarizeFilter->SetInput(input);
+    binarizeFilter->InPlaceOff();
     binarizeFilter->SetLowerThreshold(lower);
     binarizeFilter->SetUpperThreshold(upper);
     binarizeFilter->SetInsideValue(FG);
@@ -995,7 +1058,7 @@ namespace clitk {
                                                             extremaDirection, extremaOppositeFlag, p);
       if (found) {
         position2D[i] = p;
-      }    
+      }
     }
     
     // Convert 2D points in slice into 3D points
@@ -1008,13 +1071,230 @@ namespace clitk {
       p[lineDirection] += 10;
       B.push_back(p);
       // Margins ?
-      A[i][1] += margin;
-      B[i][1] += margin;
+      A[i][extremaDirection] += margin;
+      B[i][extremaDirection] += margin;
+    }
+
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer
+  SliceBySliceKeepMainCCL(const ImageType * input, 
+                          typename ImageType::PixelType BG,
+                          typename ImageType::PixelType FG)  {
+    
+    // Extract slices
+    const int d = ImageType::ImageDimension-1;
+    typedef typename itk::Image<typename ImageType::PixelType, d> SliceType;
+    std::vector<typename SliceType::Pointer> slices;
+    clitk::ExtractSlices<ImageType>(input, d, slices);
+    
+    // Labelize and keep the main one
+    std::vector<typename SliceType::Pointer> o;
+    for(uint i=0; i<slices.size(); i++) {
+      o.push_back(clitk::Labelize<SliceType>(slices[i], BG, false, 1));
+      o[i] = clitk::KeepLabels<SliceType>(o[i], BG, FG, 1, 1, true);
+    }
+    
+    // Join slices
+    typename ImageType::Pointer output;
+    output = clitk::JoinSlices<ImageType>(o, input, d);
+    return output;
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer
+  Clone(const ImageType * input) {
+    typedef itk::ImageDuplicator<ImageType> DuplicatorType;
+    typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
+    duplicator->SetInputImage(input);
+    duplicator->Update();
+    return duplicator->GetOutput();
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  /* Consider an input object, start at A, for each slice (dim1): 
+     - compute the intersection between the AB line and the current slice
+     - remove what is at lower or greater according to dim2 of this point
+     - stop at B
+  */
+  template<class ImageType>
+  typename ImageType::Pointer
+  SliceBySliceSetBackgroundFromSingleLine(const ImageType * input, 
+                                          typename ImageType::PixelType BG, 
+                                          typename ImageType::PointType & A, 
+                                          typename ImageType::PointType & B, 
+                                          int dim1, int dim2, bool removeLowerPartFlag)
+    
+  {
+    // Extract slices
+    typedef typename itk::Image<typename ImageType::PixelType, ImageType::ImageDimension-1> SliceType;
+    typedef typename SliceType::Pointer SlicePointer;
+    std::vector<SlicePointer> slices;
+    clitk::ExtractSlices<ImageType>(input, dim1, slices);
+
+    // Start at slice that contains A, and stop at B
+    typename ImageType::IndexType Ap;
+    typename ImageType::IndexType Bp;
+    input->TransformPhysicalPointToIndex(A, Ap);
+    input->TransformPhysicalPointToIndex(B, Bp);
+    
+    // Determine slice largest region
+    typename SliceType::RegionType region = slices[0]->GetLargestPossibleRegion();
+    typename SliceType::SizeType size = region.GetSize();
+    typename SliceType::IndexType index = region.GetIndex();
+
+    // Line slope
+    double a = (Bp[dim2]-Ap[dim2])/(Bp[dim1]-Ap[dim1]);
+    double b = Ap[dim2];
+
+    // Loop from slice A to slice B
+    for(uint i=0; i<(Bp[dim1]-Ap[dim1]); i++) {
+      // Compute intersection between line AB and current slice for the dim2
+      double p = a*i+b;
+      // Change region (lower than dim2)
+      if (removeLowerPartFlag) {
+        size[dim2] = p-Ap[dim2];
+      }
+      else {
+        size[dim2] = slices[0]->GetLargestPossibleRegion().GetSize()[dim2]-p;
+        index[dim2] = p;
+      }
+      region.SetSize(size);
+      region.SetIndex(index);
+      // Fill region with BG (simple region iterator)
+      FillRegionWithValue<SliceType>(slices[i+Ap[dim1]], BG, region);
+      /*
+      typedef itk::ImageRegionIterator<SliceType> IteratorType;
+      IteratorType iter(slices[i+Ap[dim1]], region);
+      iter.GoToBegin();
+      while (!iter.IsAtEnd()) {
+        iter.Set(BG);
+        ++iter;
+      }
+      */
+      // Loop
+    }
+    
+    // Merge slices
+    typename ImageType::Pointer output;
+    output = clitk::JoinSlices<ImageType>(slices, input, dim1);
+    return output;
+  }
+  //--------------------------------------------------------------------
+
+  //--------------------------------------------------------------------
+  /* Consider an input object, slice by slice, use the point A and set
+     pixel to BG according to their position relatively to A
+  */
+  template<class ImageType>
+  typename ImageType::Pointer
+  SliceBySliceSetBackgroundFromPoints(const ImageType * input, 
+                                      typename ImageType::PixelType BG, 
+                                      int sliceDim,
+                                      std::vector<typename ImageType::PointType> & A, 
+                                      bool removeGreaterThanXFlag,
+                                      bool removeGreaterThanYFlag)
+    
+  {
+    // Extract slices
+    typedef typename itk::Image<typename ImageType::PixelType, ImageType::ImageDimension-1> SliceType;
+    typedef typename SliceType::Pointer SlicePointer;
+    std::vector<SlicePointer> slices;
+    clitk::ExtractSlices<ImageType>(input, sliceDim, slices);
+
+    // Start at slice that contains A
+    typename ImageType::IndexType Ap;
+    
+    // Determine slice largest region
+    typename SliceType::RegionType region = slices[0]->GetLargestPossibleRegion();
+    typename SliceType::SizeType size = region.GetSize();
+    typename SliceType::IndexType index = region.GetIndex();
+
+    // Loop from slice A to slice B
+    for(uint i=0; i<A.size(); i++) {
+      input->TransformPhysicalPointToIndex(A[i], Ap);
+      uint sliceIndex = Ap[2] - input->GetLargestPossibleRegion().GetIndex()[2];
+      if ((sliceIndex < 0) || (sliceIndex >= slices.size())) {
+        continue; // do not consider this slice
+      }
+      
+      // Compute region for BG
+      if (removeGreaterThanXFlag) {
+        index[0] = Ap[0];
+        size[0] = region.GetSize()[0]-(index[0]-region.GetIndex()[0]);
+      }
+      else {
+        index[0] = region.GetIndex()[0];
+        size[0] = Ap[0] - index[0];
+      }
+
+      if (removeGreaterThanYFlag) {
+        index[1] = Ap[1];
+        size[1] = region.GetSize()[1]-(index[1]-region.GetIndex()[1]);
+      }
+      else {
+        index[1] = region.GetIndex()[1];
+        size[1] = Ap[1] - index[1];
+      }
+
+      // Set region
+      region.SetSize(size);
+      region.SetIndex(index);
+
+      // Fill region with BG (simple region iterator)
+      FillRegionWithValue<SliceType>(slices[sliceIndex], BG, region);
+      // Loop
     }
+    
+    // Merge slices
+    typename ImageType::Pointer output;
+    output = clitk::JoinSlices<ImageType>(slices, input, sliceDim);
+    return output;
+  }
+  //--------------------------------------------------------------------
+
 
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  void
+  FillRegionWithValue(ImageType * input, typename ImageType::PixelType value, typename ImageType::RegionType & region)
+  {
+    typedef itk::ImageRegionIterator<ImageType> IteratorType;
+    IteratorType iter(input, region);
+    iter.GoToBegin();
+    while (!iter.IsAtEnd()) {
+      iter.Set(value);
+      ++iter;
+    }    
   }
   //--------------------------------------------------------------------
 
 
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  void
+  GetMinMaxBoundary(ImageType * input, typename ImageType::PointType & min, 
+                    typename ImageType::PointType & max)
+  {
+    typedef typename ImageType::PointType PointType;
+    typedef typename ImageType::IndexType IndexType;
+    IndexType min_i, max_i;
+    min_i = input->GetLargestPossibleRegion().GetIndex();
+    for(uint i=0; i<ImageType::ImageDimension; i++)
+      max_i[i] = input->GetLargestPossibleRegion().GetSize()[i] + min_i[i];
+    input->TransformIndexToPhysicalPoint(min_i, min);
+    input->TransformIndexToPhysicalPoint(max_i, max);  
+  }
+  //--------------------------------------------------------------------
+
 } // end of namespace
 
index 76b0fec9cb35281aa8b8860a1f30313c1902013a..f2452d872ad2258528c20301f0515f606648e323 100644 (file)
@@ -37,7 +37,7 @@ SliceBySliceRelativePositionFilter():
   this->VerboseStepFlagOff();
   this->WriteStepFlagOff();
   this->SetCombineWithOrFlag(false);
-  CCLSelectionFlagOn();
+  CCLSelectionFlagOff();
   SetCCLSelectionDimension(0);
   SetCCLSelectionDirection(1);
   CCLSelectionIgnoreSingleCCLFlagOff();
@@ -222,7 +222,7 @@ GenerateOutputInformation()
                                                                    true);
           }
         }
-      }
+      } // end GetCCLSelectionFlag = true
 
       // Relative position
       typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
index 7a58c052496c9524a58490e2ec2679b8c5497f40..e89579e0f7d5500f98958542417c4871dac0249a 100644 (file)
@@ -1,4 +1,4 @@
-/*=========================================================================
+/*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
   Authors belong to:
@@ -20,7 +20,7 @@
 #include "itkRayCastInterpolateImageFunctionWithOrigin.h"
 
 #include "vnl/vnl_math.h"
-
+#include "clitkCommon.h"
 
 // Put the helper class in an anonymous namespace so that it is not
 // exposed to the user
@@ -498,6 +498,9 @@ RayCastHelper<TInputImage, TCoordRep>
 {
   double maxInterDist, interDist;
   double cornerVect[4][3];
+  for(clitk::uint i=0; i<4; i++)
+    for(clitk::uint j=0; j<3; j++)
+      cornerVect[i][j] = 0.0; // to avoid warning
   int cross[4][3], noInterFlag[6];
   int nSidesCrossed, crossFlag, c[4];
   double ax, ay, az, bx, by, bz;
index d567eacfca753909136f9e0422718210626e3234..72e4e03defe168886b506594c00e47bf86147ba4 100644 (file)
@@ -14,5 +14,4 @@
 
   - BSD        See included LICENSE.txt file
   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-
+==========================================================================*/
diff --git a/notes.org~ b/notes.org~
deleted file mode 100644 (file)
index ec58a0b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-* GIT emacs command
-C-x v d 
-.gitignore -> contains ignored files
-commit (local)
-push (repository)
-pull
-
-* Test in temp
-git clone http://www.creatis.insa-lyon.fr/~dsarrut/clitk3.pub.git clitk3
-need itk4 (git) ?
-
index 0f09596e5aa2e18c085e5507301e633b262bd696..d15b4d4199168d5b149b20bedbfdcfaee652f9c0 100644 (file)
@@ -19,59 +19,77 @@ IF(CLITK_BUILD_REGISTRATION)
     ############################## registration algorithms
     ADD_EXECUTABLE(clitkAffineRegistration clitkAffineRegistration.cxx)
     TARGET_LINK_LIBRARIES(clitkAffineRegistration  clitkAffineRegistrationLib clitkCommon ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL clitkAffineRegistration)
 
     WRAP_GGO(clitkDemonsDeformableRegistration_GGO_C clitkDemonsDeformableRegistration.ggo)
     ADD_EXECUTABLE(clitkDemonsDeformableRegistration clitkDemonsDeformableRegistration.cxx ${clitkDemonsDeformableRegistration_GGO_C} clitkDemonsDeformableRegistrationGenericFilter.cxx)
     TARGET_LINK_LIBRARIES(clitkDemonsDeformableRegistration ${ITK_LIBRARIES} clitkCommon)
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkDemonsDeformableRegistration)
 
     WRAP_GGO(clitkBLUTDIR_GGO_C clitkBLUTDIR.ggo)
     ADD_EXECUTABLE(clitkBLUTDIR  clitkBLUTDIR.cxx clitkBLUTDIRGenericFilter.cxx ${clitkBLUTDIR_GGO_C} clitkLBFGSBOptimizer.cxx )
     TARGET_LINK_LIBRARIES(clitkBLUTDIR clitkCommon ${ITK_LIBRARIES} )
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkBLUTDIR)
 
     WRAP_GGO(clitkShapedBLUTSpatioTemporalDIR_GGO_C clitkShapedBLUTSpatioTemporalDIR.ggo)
     ADD_EXECUTABLE(clitkShapedBLUTSpatioTemporalDIR  clitkShapedBLUTSpatioTemporalDIR.cxx clitkShapedBLUTSpatioTemporalDIRGenericFilter.cxx  ${clitkShapedBLUTSpatioTemporalDIR_GGO_C} clitkLBFGSBOptimizer.cxx)
     TARGET_LINK_LIBRARIES(clitkShapedBLUTSpatioTemporalDIR clitkCommon ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkShapedBLUTSpatioTemporalDIR)
 
     WRAP_GGO(clitkBSplineDeformableRegistration_GGO_C clitkBSplineDeformableRegistration.ggo)
     ADD_EXECUTABLE(clitkBSplineDeformableRegistration clitkBSplineDeformableRegistration.cxx clitkBSplineDeformableRegistrationGenericFilter.cxx  ${clitkBSplineDeformableRegistration_GGO_C} clitkLBFGSBOptimizer.cxx)
     TARGET_LINK_LIBRARIES(clitkBSplineDeformableRegistration  clitkCommon ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkBSplineDeformableRegistration)
 
 
     ############################## registration-related tools to process points, bsplines, vf and image pyramids
     WRAP_GGO(clitkConvertPointList_GGO_C clitkConvertPointList.ggo)
     ADD_EXECUTABLE(clitkConvertPointList clitkConvertPointList.cxx  ${clitkConvertPointList_GGO_C})
     TARGET_LINK_LIBRARIES(clitkConvertPointList ${ITK_LIBRARIES} clitkCommon )
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkConvertPointList)
 
     WRAP_GGO(clitkSelectPoints_GGO_C clitkSelectPoints.ggo)
     ADD_EXECUTABLE(clitkSelectPoints clitkSelectPoints.cxx clitkSelectPointsGenericFilter.cxx  ${clitkSelectPoints_GGO_C})
     TARGET_LINK_LIBRARIES(clitkSelectPoints clitkCommon ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkSelectPoints)
 
     WRAP_GGO(clitkPointTrajectory_GGO_C clitkPointTrajectory.ggo)
     ADD_EXECUTABLE(clitkPointTrajectory  clitkPointTrajectory.cxx clitkPointTrajectoryGenericFilter.cxx  ${clitkPointTrajectory_GGO_C})
     TARGET_LINK_LIBRARIES(clitkPointTrajectory clitkCommon ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkPointTrajectory)
 
     WRAP_GGO(clitkCalculateTRE_GGO_C clitkCalculateTRE.ggo)
     ADD_EXECUTABLE(clitkCalculateTRE clitkCalculateTRE.cxx clitkCalculateTREGenericFilter.cxx ${clitkCalculateTRE_GGO_C})
     TARGET_LINK_LIBRARIES(clitkCalculateTRE clitkCommon ${ITK_LIBRARIES} )
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkCalculateTRE)
 
     WRAP_GGO(clitkMatrixTransformToVF_GGO_C clitkMatrixTransformToVF.ggo)
     ADD_EXECUTABLE(clitkMatrixTransformToVF clitkMatrixTransformToVF.cxx clitkMatrixTransformToVFGenericFilter.cxx  ${clitkMatrixTransformToVF_GGO_C})
     TARGET_LINK_LIBRARIES(clitkMatrixTransformToVF ${ITK_LIBRARIES} clitkCommon)
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkMatrixTransformToVF)
 
     WRAP_GGO(clitkConvertBSplineDeformableTransformToVF_GGO_C clitkConvertBSplineDeformableTransformToVF.ggo)
     ADD_EXECUTABLE(clitkConvertBSplineDeformableTransformToVF  clitkConvertBSplineDeformableTransformToVF.cxx clitkConvertBSplineDeformableTransformToVFGenericFilter.cxx  ${clitkConvertBSplineDeformableTransformToVF_GGO_C})
     TARGET_LINK_LIBRARIES(clitkConvertBSplineDeformableTransformToVF clitkCommon  ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkConvertBSplineDeformableTransformToVF)
 
     WRAP_GGO(clitkMultiResolutionPyramid_GGO_C clitkMultiResolutionPyramid.ggo)
     ADD_EXECUTABLE(clitkMultiResolutionPyramid  clitkMultiResolutionPyramid.cxx clitkMultiResolutionPyramidGenericFilter.cxx ${clitkMultiResolutionPyramid_GGO_C})
     TARGET_LINK_LIBRARIES(clitkMultiResolutionPyramid clitkCommon  ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkMultiResolutionPyramid)
 
     WRAP_GGO(clitkBSplinePyramid_GGO_C clitkBSplinePyramid.ggo)
     ADD_EXECUTABLE(clitkBSplinePyramid  clitkBSplinePyramid.cxx clitkBSplinePyramidGenericFilter.cxx ${clitkBSplinePyramid_GGO_C})
     TARGET_LINK_LIBRARIES(clitkBSplinePyramid  clitkCommon  ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkBSplinePyramid)
 
     WRAP_GGO(clitkResampleBSplineDeformableTransform_GGO_C clitkResampleBSplineDeformableTransform.ggo)
     ADD_EXECUTABLE(clitkResampleBSplineDeformableTransform  clitkResampleBSplineDeformableTransform.cxx clitkResampleBSplineDeformableTransformGenericFilter.cxx ${clitkResampleBSplineDeformableTransform_GGO_C})
     TARGET_LINK_LIBRARIES(clitkResampleBSplineDeformableTransform clitkCommon ${ITK_LIBRARIES})
+    SET(REGISTRATION_INSTALL ${REGISTRATION_INSTALL} clitkResampleBSplineDeformableTransform)
+
+    SET_TARGET_PROPERTIES(${REGISTRATION_INSTALL} PROPERTIES INSTALL_RPATH "${VTK_DIR}:${ITK_DIR}" )  
+    INSTALL (TARGETS ${REGISTRATION_INSTALL} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
+
 ENDIF(CLITK_BUILD_REGISTRATION)
 
index 15afacf1b475b6f734bee22854a01dc6d6625ae8..0822bd9f3f0c434325d4995ed711d8e3e6133ba3 100644 (file)
@@ -747,21 +747,25 @@ namespace clitk
       // Compute the DVF (only deformable transform)
       //=======================================================
       typedef itk::Vector< float, SpaceDimension >  DisplacementType;
-      typedef itk::Image< DisplacementType, InputImageType::ImageDimension >  DeformationFieldType;
-      typedef itk::TransformToDeformationFieldSource<DeformationFieldType, double> ConvertorType;
+      typedef itk::Image< DisplacementType, InputImageType::ImageDimension >  DisplacementFieldType;
+#if ITK_VERSION_MAJOR >= 4
+      typedef itk::TransformToDisplacementFieldSource<DisplacementFieldType, double> ConvertorType;
+#else
+      typedef itk::TransformToDeformationFieldSource<DisplacementFieldType, double> ConvertorType;
+#endif
       typename ConvertorType::Pointer filter= ConvertorType::New();
       filter->SetNumberOfThreads(1);
       transform->SetBulkTransform(NULL);
       filter->SetTransform(transform);
       filter->SetOutputParametersFromImage(fixedImage);
       filter->Update();
-      typename DeformationFieldType::Pointer field = filter->GetOutput();
+      typename DisplacementFieldType::Pointer field = filter->GetOutput();
 
 
       //=======================================================
       // Write the DVF
       //=======================================================
-      typedef itk::ImageFileWriter< DeformationFieldType >  FieldWriterType;
+      typedef itk::ImageFileWriter< DisplacementFieldType >  FieldWriterType;
       typename FieldWriterType::Pointer fieldWriter = FieldWriterType::New();
       fieldWriter->SetFileName( m_ArgsInfo.vf_arg );
       fieldWriter->SetInput( field );
index d867caababdff328074dc460770638c9368fc270..eda242f5b4d7d843a91cb2809dbbe319536d06db 100644 (file)
 #include "itkLabelGeometryImageFilter.h"
 #include "itkImageDuplicator.h"
 #include "itkExtractImageFilter.h"
-#include "itkTransformToDeformationFieldSource.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkTransformToDisplacementFieldSource.h"
+#else
+  #include "itkTransformToDeformationFieldSource.h"
+#endif
 
 namespace clitk
 {
index c49a873644a4050df35e56c8406fd23e1605973b..a0f0d7a325dfeb33cbde41907cf48c57918ef6b8 100644 (file)
@@ -1,4 +1,4 @@
-/*=========================================================================
+/*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
   Authors belong to: 
@@ -354,8 +354,8 @@ namespace clitk
            for(unsigned int r=0; r<ImageDimension; r++) 
              {
                chosenSpacing[r]= m_ArgsInfo.spacing_arg[r];
-               gridSizeOnImage[r] = ceil( (double) transformRegion.GetSize()[r] / ( round(chosenSpacing[r]/fixedImageSpacing[r]) ) );
-               adaptedSpacing[r]= ( round(chosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
+               gridSizeOnImage[r] = ceil( (double) transformRegion.GetSize()[r] / ( itk::Math::Round<double>(chosenSpacing[r]/fixedImageSpacing[r]) ) );
+               adaptedSpacing[r]= ( itk::Math::Round<double>(chosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
              }
            if (m_Verbose) std::cout<<"The chosen control point spacing "<<chosenSpacing<<"..."<<std::endl;
            if (m_Verbose) std::cout<<"The control points spacing was adapted to "<<adaptedSpacing<<"..."<<std::endl; 
index 5a084c9d841c2a3ffec678936666c41d1f0d9772..bab7f8c78257206b4d060b557211235d89b2217d 100644 (file)
@@ -254,7 +254,15 @@ namespace clitk
     } 
     
     /** Compute the Jacobian Matrix of the transformation at one point */
+#if ITK_VERSION_MAJOR >= 4
+    virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const;
+    virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+    {
+      itkExceptionMacro( "ComputeJacobianWithRespectToPosition not yet implemented for " << this->GetNameOfClass() );
+    }
+#else
     virtual const JacobianType& GetJacobian(const InputPointType  &point ) const;
+#endif
 
     /** Return the number of parameters that completely define the Transfom */
     virtual unsigned int GetNumberOfParameters(void) const;
@@ -363,6 +371,9 @@ namespace clitk
 
     // VD Add MultipleBSplineDeformableTransform as friend to facilitate wrapping
     friend class MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>;
+#if ITK_VERSION_MAJOR >= 4
+    mutable JacobianType                            m_SharedDataBSplineJacobian;
+#endif
 
   }; //class BSplineDeformableTransform
 
index db47430b5a82ab339d4103558a29d923bce7d6c8..1a2dfd3ccab98b4e60deef7e064edf18de99a474 100644 (file)
@@ -32,7 +32,11 @@ namespace clitk
   // Constructor with default arguments
   template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
   BSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+  ::BSplineDeformableTransform():Superclass(0)
+#else
   ::BSplineDeformableTransform():Superclass(OutputDimension,0)
+#endif
   {
     unsigned int i;
     
@@ -576,10 +580,18 @@ namespace clitk
     m_CoefficientImage = m_WrappedImage;
     
     //JV Wrap jacobian into OutputDimension X Vectorial images
+#if ITK_VERSION_MAJOR >= 4
+    this->m_SharedDataBSplineJacobian.set_size( OutputDimension, this->GetNumberOfParameters() );
+#else
     this->m_Jacobian.set_size( OutputDimension, this->GetNumberOfParameters() );
+#endif
 
     // Use memset to set the memory
+#if ITK_VERSION_MAJOR >= 4
+    JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_SharedDataBSplineJacobian.data_block());
+#else
     JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_Jacobian.data_block());
+#endif
     memset(jacobianDataPointer, 0,  OutputDimension*numberOfPixels*sizeof(JacobianPixelType));
     m_LastJacobianIndex = m_ValidRegion.GetIndex();
     m_NeedResetJacobian = false;
@@ -904,6 +916,69 @@ namespace clitk
 
   // JV weights are identical as for transformpoint, could be done simultaneously in metric!!!!
   // Compute the Jacobian in one position 
+#if ITK_VERSION_MAJOR >= 4
+  template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
+  void
+  BSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+  ::ComputeJacobianWithRespectToParameters(const InputPointType & point, JacobianType & jacobian) const
+  {
+    if (m_NeedResetJacobian)
+      ResetJacobian();
+
+    //========================================================
+    // For each dimension, copy the weight to the support region
+    //========================================================
+
+    // Check if inside mask
+    if (m_Mask &&  !(m_Mask->IsInside(point) ) )
+      {
+       // Outside: no (deformable) displacement
+        jacobian = m_SharedDataBSplineJacobian;
+       return;
+      }
+
+    //Get index
+    this->TransformPointToContinuousIndex( point, m_Index );
+
+    // NOTE: if the support region does not lie totally within the grid
+    // we assume zero displacement and return the input point
+    if ( !this->InsideValidRegion( m_Index ) )
+      {
+        jacobian = m_SharedDataBSplineJacobian;
+       return;
+      }
+
+    //Compute interpolation weights
+    const WeightsDataType *weights = NULL;
+    m_VectorInterpolator->EvaluateWeightsAtContinuousIndex( m_Index, &weights, m_LastJacobianIndex);
+    m_SupportRegion.SetIndex( m_LastJacobianIndex );
+
+    //Reset the iterators
+    unsigned int j = 0;
+    for ( j = 0; j < OutputDimension; j++ )
+      m_Iterator[j] = IteratorType( m_JacobianImage[j], m_SupportRegion);
+
+    // For each dimension, copy the weight to the support region
+    while ( ! (m_Iterator[0]).IsAtEnd() )
+      {
+       //copy weight to jacobian image
+       for ( j = 0; j < OutputDimension; j++ )
+         {
+           m_ZeroVector[j]=*weights;
+           (m_Iterator[j]).Set( m_ZeroVector);
+           m_ZeroVector[j]=itk::NumericTraits<JacobianValueType>::Zero;
+           ++(m_Iterator[j]);
+         }
+       // go to next coefficient in the support region
+       weights++;
+      }
+    m_NeedResetJacobian = true;
+
+    // Return the result
+    jacobian = m_SharedDataBSplineJacobian;
+
+  }
+#else
   template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
   const 
   typename BSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
@@ -972,6 +1047,7 @@ namespace clitk
     return this->m_Jacobian;
 
   }
+#endif
 
 
   template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
index 340ccb915606ac88299e0e8250ff4bc2c371e717..59af63c7d211c98d4b4e8a40c29a1b5de3a91f4e 100644 (file)
@@ -1,4 +1,4 @@
-/*=========================================================================
+/*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
   Authors belong to: 
@@ -18,6 +18,7 @@
 #ifndef __clitkBSplineDeformableTransformInitializer_txx
 #define __clitkBSplineDeformableTransformInitializer_txx
 #include "clitkBSplineDeformableTransformInitializer.h"
+#include "itkMath.h"
 
 namespace clitk
 {
@@ -80,7 +81,7 @@ namespace clitk
          {
            // JV
            m_ChosenSpacing[r]= m_ControlPointSpacing[r];
-           m_ControlPointSpacing[r]= ( round(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
+           m_ControlPointSpacing[r]= ( itk::Math::Round<double>(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
            m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] );
            if (  ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
                 == ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
index 261a9d8ac092fadd8786298a6e0fea3a675138dc..169de13db8d6fffe219c18b04adb3b3be160baab 100644 (file)
@@ -80,7 +80,11 @@ namespace clitk
     // -----------------------------------------------
     // Filter
     // -----------------------------------------------
+#if ITK_VERSION_MAJOR >= 4
+    typedef itk::TransformToDisplacementFieldSource<OutputImageType, double> ConvertorType;
+#else
     typedef itk::TransformToDeformationFieldSource<OutputImageType, double> ConvertorType;
+#endif
     ConvertorType::Pointer filter= ConvertorType::New();
 
     //Output image info
index e976f642a2039635856c1af7d4ed79370515ee9a..bcdf67ba43670a1b2b3efa0ca63f264d39ceb29e 100644 (file)
 //itk include
 #include "itkLightObject.h"
 #include "itkImageMaskSpatialObject.h"
-#include "itkTransformToDeformationFieldSource.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkTransformToDisplacementFieldSource.h"
+#else
+  #include "itkTransformToDeformationFieldSource.h"
+#endif
 
 
 namespace clitk 
index e7133ca69da81d03113c216b952f4ffc6b1a829c..aac2a786560e270580faafdee5155b488b327fde 100644 (file)
@@ -266,8 +266,13 @@ CorrelationRatioImageToImageMetric<TFixedImage,TMovingImage>
     if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
       const RealType movingValue  = this->m_Interpolator->Evaluate( transformedPoint );
 
+#if ITK_VERSION_MAJOR >= 4
+      TransformJacobianType jacobian;
+      this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint , jacobian);
+#else
       const TransformJacobianType & jacobian =
         this->m_Transform->GetJacobian( inputPoint );
+#endif
 
 
       const RealType fixedValue     = ti.Value();
@@ -384,8 +389,13 @@ CorrelationRatioImageToImageMetric<TFixedImage,TMovingImage>
     if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
       const RealType movingValue  = this->m_Interpolator->Evaluate( transformedPoint );
 
+#if ITK_VERSION_MAJOR >= 4
+      TransformJacobianType jacobian;
+        this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
       const TransformJacobianType & jacobian =
         this->m_Transform->GetJacobian( inputPoint );
+#endif
 
 
       const RealType fixedValue     = ti.Value();
index dd289591fb05e62ad496776eb07f118cdcc3c72f..06c528855cdd8fb4ec09b24b8a97c164e8c9614d 100644 (file)
@@ -109,11 +109,22 @@ namespace clitk
       return OutputCovariantVectorType();
     }
 
+#if ITK_VERSION_MAJOR >= 4
+    virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const
+    {
+      itkExceptionMacro( << "DeformationFieldTransform doesn't declare ComputeJacobianWithRespectToParameters" );
+    }
+    virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+    {
+      itkExceptionMacro( << "DeformationFieldTransform doesn't declare ComputeJacobianWithRespectToPosition" );
+    }
+#else
     virtual const JacobianType& GetJacobian(const InputPointType  &point ) const
     {
       itkExceptionMacro( << "DeformationFieldTransform doesn't declare GetJacobian" );
       return this->m_Jacobian;
     }
+#endif
 
   protected:
     DeformationFieldTransform();
index e8349a6569258262e5677b924826b5fc8e663f36..049f270bd25a5ebc797646ba1135b891d04cefdf 100644 (file)
@@ -26,7 +26,11 @@ namespace clitk
   // Constructor
   template<class TScalarType, unsigned int InputDimension, unsigned int OutputDimension, unsigned int SpaceDimension>
   DeformationFieldTransform<TScalarType, InputDimension, OutputDimension, SpaceDimension>
+#if ITK_VERSION_MAJOR >= 4
+  ::DeformationFieldTransform():Superclass(1)
+#else
   ::DeformationFieldTransform():Superclass(OutputDimension,1)
+#endif
   {
      m_DeformationField=NULL;
      m_Interpolator=DefaultInterpolatorType::New();
index 90d5319717de2c7bcaf281599cf44104875a1e61..6132dc5897ae115d57fd9117e93cfd954a024307 100644 (file)
@@ -151,8 +151,12 @@ namespace clitk
     //find the multiresolution filter
     //     typedef typename  RegistrationFilterType::FixedImageType InternalImageType;
     //     typedef typename  RegistrationFilterType::MovingImageType MovingImageType;
-    typedef typename  RegistrationFilterType::DeformationFieldType DeformationFieldType;
-    typedef clitk::MultiResolutionPDEDeformableRegistration<FixedImageType, MovingImageType, DeformationFieldType> MultiResolutionRegistrationType; 
+#if ITK_VERSION_MAJOR >= 4
+    typedef typename  RegistrationFilterType::DisplacementFieldType DisplacementFieldType;
+#else
+    typedef typename  RegistrationFilterType::DeformationFieldType DisplacementFieldType;
+#endif
+    typedef clitk::MultiResolutionPDEDeformableRegistration<FixedImageType, MovingImageType, DisplacementFieldType> MultiResolutionRegistrationType;
     typedef CommandResolutionLevelUpdate<MultiResolutionRegistrationType> LevelObserver;
     
   protected:
@@ -533,7 +537,11 @@ namespace clitk
     //JV TODO
     // pdeFilter->SetMaximumError(m_ArgsInfo.maxError_arg);
     // pdeFilter->SetMaximumKernelWidth(m_ArgsInfo.maxError_arg);
+#if ITK_VERSION_MAJOR >= 4
+    pdeFilter->SetSmoothDisplacementField(!m_ArgsInfo.fluid_flag);
+#else
     pdeFilter->SetSmoothDeformationField(!m_ArgsInfo.fluid_flag);
+#endif
     pdeFilter->SetSmoothUpdateField(m_ArgsInfo.fluid_flag);
     pdeFilter->SetUseImageSpacing( m_ArgsInfo.spacing_flag );
 
@@ -599,7 +607,11 @@ namespace clitk
     typedef itk::WarpImageFilter< MovingImageType, FixedImageType, DeformationFieldType >    WarpFilterType;
     typename WarpFilterType::Pointer warp = WarpFilterType::New();
 
+#if ITK_VERSION_MAJOR >= 4
+    warp->SetDisplacementField( deformationField );
+#else
     warp->SetDeformationField( deformationField );
+#endif
     warp->SetInput( movingImageReader->GetOutput() );
     warp->SetOutputOrigin(  fixedImage->GetOrigin() );
     warp->SetOutputSpacing( fixedImage->GetSpacing() );
index 6f10e72a1ee1e04744927727c70dbfe31b800056..e73644c5dc80f496861710400c526a2228ca4579 100644 (file)
@@ -35,7 +35,7 @@ GenericMetric<args_info_type, FixedImageType, MovingImageType>::GenericMetric()
   m_Maximize=false;
   m_Verbose=false;
   m_FixedImageRegionGiven=false;
-#ifdef ITK_USE_OPTIMISED_REGISTRATION_METHODS
+#ifdef ITK_USE_OPTIMIZED_REGISTRATION_METHODS
   m_FixedImageSamplesIntensityThreshold=0;
   m_UseFixedImageSamplesIntensityThreshold=false;
 #endif
@@ -256,11 +256,15 @@ GenericMetric<args_info_type,FixedImageType, MovingImageType>::GetMetricPointer(
   }
 
 
-  //typedef itk::ImageMaskSpatialObject<itkGetStaticConstMacro(FixedImageDimension)> ImageMaskSpatialObjectType;
-  //typename ImageMaskSpatialObjectType::ConstPointer mask = dynamic_cast<const ImageMaskSpatialObjectType*>(m_FixedImageMask.GetPointer());
+  typedef itk::ImageMaskSpatialObject<itkGetStaticConstMacro(FixedImageDimension)> ImageMaskSpatialObjectType;
+  typename ImageMaskSpatialObjectType::ConstPointer mask = NULL;
+  if (m_FixedImageMask.IsNotNull())
+    mask = dynamic_cast<const ImageMaskSpatialObjectType*>(m_FixedImageMask.GetPointer());
 
-  //typedef typename ImageMaskSpatialObjectType::RegionType ImageMaskRegionType;
-  //ImageMaskRegionType mask_region = mask->GetAxisAlignedBoundingBoxRegion();
+  typedef typename ImageMaskSpatialObjectType::RegionType ImageMaskRegionType;
+  ImageMaskRegionType mask_region;
+  if (mask.IsNotNull())
+    mask_region = mask->GetAxisAlignedBoundingBoxRegion();
 
   // Common properties
   if( m_FixedImageMask.IsNotNull() )
@@ -300,7 +304,7 @@ GenericMetric<args_info_type,FixedImageType, MovingImageType>::GetMetricPointer(
 
     // Calculate the number
     const unsigned int totalNumberOfPixels = m_FixedImageRegion.GetNumberOfPixels();
-    //const unsigned int totalNumberOfPixels = mask_region.GetNumberOfPixels();
+    const unsigned int totalNumberOfMaskPixels = mask_region.GetNumberOfPixels();
     const unsigned int numberOfDemandedPixels =  static_cast< unsigned int >( (double) totalNumberOfPixels *m_ArgsInfo.samples_arg );
 
     // --------------------------------------------------
@@ -333,11 +337,13 @@ GenericMetric<args_info_type,FixedImageType, MovingImageType>::GetMetricPointer(
         }
 
         // Intensity?
+        /*
         if( m_UseFixedImageSamplesIntensityThreshold &&
             ( regionIter.Get() < m_FixedImageSamplesIntensityThreshold) ) {
           ++regionIter; // jump to next pixel
           continue;
         }
+        */
 
         // Add point to the numbers
         fiic.push_back(index);
@@ -359,7 +365,7 @@ GenericMetric<args_info_type,FixedImageType, MovingImageType>::GetMetricPointer(
       //RandomIterator randIter( m_FixedImage, mask_region );
       
       if (m_Verbose) std::cout << "Search region " << m_FixedImageRegion << std::endl;
-      //if (m_Verbose) std::cout << "Mask search region " << mask_region << std::endl;
+      if (m_Verbose) std::cout << "Mask search region " << mask_region << std::endl;
 
       // Randomly sample the image
       short att = 1;
@@ -396,13 +402,13 @@ GenericMetric<args_info_type,FixedImageType, MovingImageType>::GetMetricPointer(
           }
 
           // Intensity?
-          if( m_UseFixedImageSamplesIntensityThreshold &&
-              randIter.Get() < m_FixedImageSamplesIntensityThreshold ) {
-            ++randIter;
-              //if (m_Verbose) std::cout << "not in threshold" << std::endl;
-              count_not_thres++;
-            continue;
-          }
+//           if( m_UseFixedImageSamplesIntensityThreshold &&
+//               randIter.Get() < m_FixedImageSamplesIntensityThreshold ) {
+//             ++randIter;
+//               //if (m_Verbose) std::cout << "not in threshold" << std::endl;
+//               count_not_thres++;
+//             continue;
+//           }
 
           // Add point to the numbers
           fiic.push_back(index);
@@ -427,6 +433,7 @@ GenericMetric<args_info_type,FixedImageType, MovingImageType>::GetMetricPointer(
     if (m_Verbose) std::cout<<"A fraction of "<<m_ArgsInfo.samples_arg<<" spatial samples was requested..."<<std::endl;
     double fraction=(double)numberOfValidPixels/ (double) totalNumberOfPixels;
     if (m_Verbose) std::cout<<"Found "<<numberOfValidPixels <<" valid pixels for a total of "<<totalNumberOfPixels<<" (a fraction of "<<fraction<<")..."<<std::endl;
+    if (m_Verbose) std::cout<<"number of mask pixels "<<totalNumberOfMaskPixels<<std::endl;
 
   }
 
index 34648cb928e7035329a764b79c9f4b5ed8f67adc..717e938a4b667b86dfaebc3eea570d578789e222 100644 (file)
 
 //itk include
 #include "itkLightObject.h"
-#include "itkTransformToDeformationFieldSource.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkTransformToDisplacementFieldSource.h"
+#else
+  #include "itkTransformToDeformationFieldSource.h"
+#endif
 #include "itkAffineTransform.h"
 
 namespace clitk 
index 0540a134a12018a2935b6977435cba68fbe47596..ebc0e45c3ba6ba0beaf9d30dd05b5a954444ebad 100644 (file)
@@ -78,7 +78,11 @@ namespace clitk
     typedef itk::Image<Displacement, Dimension> OutputImageType;
     
     // Filter
+#if ITK_VERSION_MAJOR >= 4
+    typedef itk::TransformToDisplacementFieldSource<OutputImageType, double> ConvertorType;
+#else
     typedef itk::TransformToDeformationFieldSource<OutputImageType, double> ConvertorType;
+#endif
     typename   ConvertorType::Pointer filter= ConvertorType::New();
 
     // Output image info
index a10942c1db04dbc1c150d9d6ad66c4159c0b683f..5c6b0aeaf55c38e2e3361f2d683a15a4c7d1b927 100644 (file)
@@ -335,7 +335,11 @@ MultiResolutionPDEDeformableRegistration<TFixedImage,TMovingImage,TDeformationFi
       
       if( tempField.IsNull() )
        {
+#if ITK_VERSION_MAJOR >= 4
+         m_RegistrationFilter->SetInitialDisplacementField( NULL );
+#else
          m_RegistrationFilter->SetInitialDeformationField( NULL );
+#endif
        }
       else
        {
@@ -357,7 +361,11 @@ MultiResolutionPDEDeformableRegistration<TFixedImage,TMovingImage,TDeformationFi
       tempField = m_FieldExpander->GetOutput();
       tempField->DisconnectPipeline();
 
+#if ITK_VERSION_MAJOR >= 4
+      m_RegistrationFilter->SetInitialDisplacementField( tempField );
+#else
       m_RegistrationFilter->SetInitialDeformationField( tempField );
+#endif
 
       }
 
index 3e8dc3a5b0afca8b2aadcaa508ce47a0a32cab98..09f008faa65ffe3f04d560038ce87770ff74c3ce 100644 (file)
@@ -213,7 +213,15 @@ namespace clitk
     }
 
     /** Compute the Jacobian Matrix of the transformation at one point */
+#if ITK_VERSION_MAJOR >= 4
+    virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const;
+    virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+    {
+      itkExceptionMacro( "ComputeJacobianWithRespectToPosition not yet implemented for " << this->GetNameOfClass() );
+    }
+#else
     virtual const JacobianType& GetJacobian(const InputPointType  &point ) const;
+#endif
 
     /** Return the number of parameters that completely define the Transfom */
     virtual unsigned int GetNumberOfParameters(void) const;
@@ -261,6 +269,9 @@ namespace clitk
     std::vector<ParametersType>                     m_parameters;
     mutable std::vector<CoefficientImagePointer>    m_CoefficientImages;
     mutable int                                     m_LastJacobian;
+#if ITK_VERSION_MAJOR >= 4
+    mutable JacobianType                            m_SharedDataBSplineJacobian;
+#endif
 
     void InitJacobian();
     // FIXME it seems not used
index 0ec20aa2bdf29398a97a267b81cf21d6dd800f46..32ebced48447e08923ce6baefec63dbdb4253716 100644 (file)
@@ -29,7 +29,11 @@ namespace clitk
   // Constructor with default arguments
   template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
   MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+  ::MultipleBSplineDeformableTransform() : Superclass(0)
+#else
   ::MultipleBSplineDeformableTransform() : Superclass(OutputDimension, 0)
+#endif
   {
     m_nLabels = 1;
     m_labels = 0;
@@ -425,15 +429,38 @@ namespace clitk
     return m_trans[lidx]->DeformablyTransformPoint(inputPoint);
   }
 
+#if ITK_VERSION_MAJOR >= 4
+  template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
+  inline void
+  MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+  ::ComputeJacobianWithRespectToParameters (const InputPointType &point, JacobianType &jacobian) const
+  {
+    if (m_LastJacobian != -1)
+      m_trans[m_LastJacobian]->ResetJacobian();
+
+    int lidx = 0;
+    if (m_labels)
+      lidx = m_labelInterpolator->Evaluate(point) - 1;
+    if (lidx == -1)
+    {
+      m_LastJacobian = lidx;
+      jacobian = this->m_SharedDataBSplineJacobian;
+      return;
+    }
+
+    JacobianType unused;
+    m_trans[lidx]->ComputeJacobianWithRespectToParameters(point, unused);
+    m_LastJacobian = lidx;
+
+    jacobian = this->m_SharedDataBSplineJacobian;
+  }
+
+#else
   template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
   inline const typename MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>::JacobianType &
   MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
   ::GetJacobian( const InputPointType & point ) const
   {
-    /*
-    for (unsigned i = 0; i < m_nLabels; ++i)
-      m_trans[i]->ResetJacobian();
-      */
     if (m_LastJacobian != -1)
       m_trans[m_LastJacobian]->ResetJacobian();
 
@@ -451,6 +478,7 @@ namespace clitk
 
     return this->m_Jacobian;
   }
+#endif
 
   template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
   inline void
@@ -465,8 +493,13 @@ namespace clitk
   MultipleBSplineDeformableTransform<TCoordRep, NInputDimensions,NOutputDimensions>::InitJacobian()
   {
     unsigned numberOfParameters = this->GetNumberOfParameters();
+#if ITK_VERSION_MAJOR >= 4
+    this->m_SharedDataBSplineJacobian.set_size(OutputDimension, numberOfParameters);
+    JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_SharedDataBSplineJacobian.data_block());
+#else
     this->m_Jacobian.set_size(OutputDimension, numberOfParameters);
     JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_Jacobian.data_block());
+#endif
     memset(jacobianDataPointer, 0,  numberOfParameters * sizeof (JacobianPixelType));
 
     unsigned tot = 0;
index 7c9bd5a31ee67c846637308822552cf72f1c0ae5..1b75fbbdd0d813b98aa349008845119fed3c4ae9 100644 (file)
@@ -1,4 +1,4 @@
-/*=========================================================================
+/*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
   Authors belong to:
@@ -79,7 +79,7 @@ namespace clitk
          {
            // JV
            m_ChosenSpacing[r]= m_ControlPointSpacing[r];
-           m_ControlPointSpacing[r]= ( round(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
+           m_ControlPointSpacing[r]= ( itk::Math::Round<double>(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
            m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] );
            if (  ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
                 == ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
index 3708f103ed8391866c17db471e6b0dac444603ae..342549ee72ea276bc0cde8610221b6052cf2d768 100644 (file)
@@ -251,8 +251,13 @@ NormalizedCorrelationImageToImageMetric<TFixedImage,TMovingImage>
       const RealType movingValue  = this->m_Interpolator->Evaluate( transformedPoint );
       const RealType fixedValue   = ti.Get();
 
+#if ITK_VERSION_MAJOR >= 4
+      TransformJacobianType jacobian;
+      this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
       const TransformJacobianType & jacobian =
         this->m_Transform->GetJacobian( inputPoint );
+#endif
 
       // Get the gradient by NearestNeighboorInterpolation:
       // which is equivalent to round up the point components.
@@ -427,8 +432,13 @@ NormalizedCorrelationImageToImageMetric<TFixedImage,TMovingImage>
       const RealType movingValue  = this->m_Interpolator->Evaluate( transformedPoint );
       const RealType fixedValue     = ti.Get();
 
+#if ITK_VERSION_MAJOR >= 4
+      TransformJacobianType jacobian;
+      this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
       const TransformJacobianType & jacobian =
         this->m_Transform->GetJacobian( inputPoint );
+#endif
 
       // Get the gradient by NearestNeighboorInterpolation:
       // which is equivalent to round up the point components.
index 511f97392259cdda3a4927e7909bab8ee9b8a18a..7290bd49fb1fb2cd3c701e12a7db24815503573b 100644 (file)
@@ -251,8 +251,13 @@ NormalizedCorrelationImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
       const RealType movingValue  = this->m_Interpolator->Evaluate( transformedPoint );
       const RealType fixedValue   = ti.Get();
 
+#if ITK_VERSION_MAJOR >= 4
+      TransformJacobianType jacobian;
+      this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
       const TransformJacobianType & jacobian =
         this->m_Transform->GetJacobian( inputPoint );
+#endif
 
       // Get the gradient by NearestNeighboorInterpolation:
       // which is equivalent to round up the point components.
@@ -427,8 +432,13 @@ NormalizedCorrelationImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
       const RealType movingValue  = this->m_Interpolator->Evaluate( transformedPoint );
       const RealType fixedValue     = ti.Get();
 
+#if ITK_VERSION_MAJOR >= 4
+      TransformJacobianType jacobian;
+      this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
       const TransformJacobianType & jacobian =
         this->m_Transform->GetJacobian( inputPoint );
+#endif
 
       // Get the gradient by NearestNeighboorInterpolation:
       // which is equivalent to round up the point components.
index 9fbd7d21a6690cca49be5df435e88d1e13db7baa..d98c525d6abd3c114454c6e4fccba22dfeec968e 100644 (file)
@@ -117,11 +117,22 @@ namespace clitk
       return OutputCovariantVectorType();
     }
 
+#if ITK_VERSION_MAJOR >= 4
+    virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const
+    {
+      itkExceptionMacro( << "PointListTransform doesn't declare ComputeJacobianWithRespectToParameters" );
+    }
+    virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+    {
+      itkExceptionMacro( << "PointListTransform doesn't declare ComputeJacobianWithRespectToPosition" );
+    }
+#else
     virtual const JacobianType& GetJacobian(const InputPointType  &point ) const
     {
       itkExceptionMacro( << "PointListTransform doesn't declare GetJacobian" );
       return this->m_Jacobian;
     }
+#endif
 
   protected:
     PointListTransform();
index 7a7808a2c9f7051798ddef55014886cbbf7fd9b7..a93a309b589284139d8154b33e5d2c97796674d2 100644 (file)
@@ -26,7 +26,11 @@ namespace clitk
   // Constructor
   template<class TScalarType, unsigned int NDimensions, unsigned int NOutputDimensions>
   PointListTransform<TScalarType, NDimensions, NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+  ::PointListTransform():Superclass(1)
+#else
   ::PointListTransform():Superclass(NOutputDimensions,1)
+#endif
   {
     m_PointLists.resize(0);
     m_PointList.resize(1);
index 5434b228f470c0ba02ae2efe8aca47d43ce9e1f8..963fb7811cbc5f0d24d5298c6478ec01aac4d218 100644 (file)
@@ -819,7 +819,11 @@ namespace clitk
     typedef itk::WarpImageFilter< MovingImageType, FixedImageType, DeformationField4DType >    WarpFilterType;
     typename WarpFilterType::Pointer warp = WarpFilterType::New();
 
+#if ITK_VERSION_MAJOR >= 4
+    warp->SetDisplacementField( field4D );
+#else
     warp->SetDeformationField( field4D );
+#endif
     warp->SetInput( movingImageReader->GetOutput() );
     warp->SetOutputOrigin(  fixedImage->GetOrigin() );
     warp->SetOutputSpacing( fixedImage->GetSpacing() );
index 81173be3393e2727a44f65c63d671cfd0eeef1b2..f3071b136c39433e2738063a646b268eadb5bc56 100644 (file)
@@ -27,7 +27,6 @@
 #include "itkImageRegion.h"
 #include "itkSpatialObject.h"
 #include "itkPasteImageFilter.h"
-#include "itkMultiplyByConstantImageFilter.h"
 
 namespace clitk
 {
@@ -264,7 +263,15 @@ namespace clitk
     } 
     
     /** Compute the Jacobian Matrix of the transformation at one point */
+#if ITK_VERSION_MAJOR >= 4
+    virtual void ComputeJacobianWithRespectToParameters (const InputPointType &p, JacobianType &jacobian) const;
+    virtual void ComputeJacobianWithRespectToPosition (const InputPointType &p, JacobianType &jacobian) const
+    {
+      itkExceptionMacro( "ComputeJacobianWithRespectToPosition not yet implemented for " << this->GetNameOfClass() );
+    }
+#else
     virtual const JacobianType& GetJacobian(const InputPointType  &point ) const;
+#endif
 
     /** Return the number of parameters that completely define the Transfom */
     virtual unsigned int GetNumberOfParameters(void) const;
@@ -431,6 +438,9 @@ namespace clitk
     // JV Shape
     unsigned int m_TransformShape;
 
+#if ITK_VERSION_MAJOR >= 4
+    mutable JacobianType                            m_SharedDataBSplineJacobian;
+#endif
 
   }; //class ShapedBLUTSpatioTemporalDeformableTransform
 
index 5a4b9503cdf33cbba22f925e7f40bc5f20e04efe..cebdb5bae492ec753a7e0e247bf9cf52aa70777b 100644 (file)
@@ -32,7 +32,11 @@ namespace clitk
   // Constructor with default arguments
   template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
   ShapedBLUTSpatioTemporalDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+  ::ShapedBLUTSpatioTemporalDeformableTransform():Superclass(0)
+#else
   ::ShapedBLUTSpatioTemporalDeformableTransform():Superclass(OutputDimension,0)
+#endif
   {
     unsigned int i;
     
@@ -802,11 +806,19 @@ namespace clitk
     //=====================================
     //JV Wrap jacobian into OutputDimension X Vectorial images
     //=====================================
+#if ITK_VERSION_MAJOR >= 4
+    this->m_SharedDataBSplineJacobian.set_size( OutputDimension, this->GetNumberOfParameters() );
+#else
     this->m_Jacobian.set_size( OutputDimension, this->GetNumberOfParameters() );
+#endif
 
     // Use memset to set the memory
     // JV four rows of three comps of parameters
+#if ITK_VERSION_MAJOR >= 4
+    JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_SharedDataBSplineJacobian.data_block());
+#else
     JacobianPixelType * jacobianDataPointer = reinterpret_cast<JacobianPixelType *>(this->m_Jacobian.data_block());
+#endif
     memset(jacobianDataPointer, 0,  OutputDimension*numberOfPixels*sizeof(JacobianPixelType));
 
     for (unsigned int j=0; j<OutputDimension; j++)
@@ -1037,7 +1049,6 @@ namespace clitk
     typedef itk::PasteImageFilter<CoefficientImageType, CoefficientImageType, CoefficientImageType> PasteImageFilterType;
     typedef clitk::ExtractImageFilter<CoefficientImageType, CoefficientImageType> ExtractImageFilterType;
     typedef clitk::LinearCombinationImageFilter<CoefficientImageType, CoefficientImageType> LinearCombinationFilterType;
-    typedef itk::MultiplyByConstantImageFilter<CoefficientImageType, double, CoefficientImageType> MultiplicationFilterType;
 
     // Regions
     typename   CoefficientImageType::RegionType sourceRegion=m_PaddedCoefficientImage->GetLargestPossibleRegion();
@@ -2376,11 +2387,17 @@ namespace clitk
   // JV weights are identical as for transformpoint, could be done simultaneously in metric!!!!
   // Compute the Jacobian in one position 
   template<class TCoordRep, unsigned int NInputDimensions, unsigned int NOutputDimensions>
+#if ITK_VERSION_MAJOR >= 4
+  void
+  ShapedBLUTSpatioTemporalDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
+  ::ComputeJacobianWithRespectToParameters( const InputPointType & point, JacobianType & jacobian) const
+#else
   const 
   typename ShapedBLUTSpatioTemporalDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
   ::JacobianType & 
   ShapedBLUTSpatioTemporalDeformableTransform<TCoordRep, NInputDimensions, NOutputDimensions>
   ::GetJacobian( const InputPointType & point ) const
+#endif
   {
   
     //========================================================
@@ -2476,7 +2493,12 @@ namespace clitk
     if(m_Mask &&  !(m_Mask->IsInside(point) ) )
       {
        // Outside: no (deformable) displacement
+#if ITK_VERSION_MAJOR >= 4
+        jacobian = m_SharedDataBSplineJacobian;
+        return;
+#else
        return this->m_Jacobian;
+#endif
       }        
 
     // Get index   
@@ -2486,7 +2508,12 @@ namespace clitk
     // we assume zero displacement and return the input point
     if ( !this->InsideValidRegion( m_Index ) )
       {
+#if ITK_VERSION_MAJOR >= 4
+        jacobian = m_SharedDataBSplineJacobian;
+        return;
+#else
        return this->m_Jacobian;
+#endif
       }
 
     // Compute interpolation weights
@@ -2654,7 +2681,11 @@ namespace clitk
       }
 
     // Return the result
+#if ITK_VERSION_MAJOR >= 4
+    jacobian = m_SharedDataBSplineJacobian;
+#else
     return this->m_Jacobian;
+#endif
   }
 
  
index 17ff27ce51fc9865dab242e601aae21456141830..5ff25320b84bdd22151f1130ab99cc24ec36088b 100644 (file)
@@ -1,4 +1,4 @@
-/*=========================================================================
+/*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
   Authors belong to: 
@@ -85,7 +85,7 @@ namespace clitk
          {
            // JV
            m_ChosenSpacing[r]= m_ControlPointSpacing[r];
-           m_ControlPointSpacing[r]= ( round(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
+           m_ControlPointSpacing[r]= ( itk::Math::Round<double>(m_ChosenSpacing[r]/fixedImageSpacing[r]) *fixedImageSpacing[r] ) ;
            m_NumberOfControlPointsInsideTheImage[r] = ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] );
            if ( (  ( ceil( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
                 == ( (double)fixedImageSize[r]*fixedImageSpacing[r]/ m_ControlPointSpacing[r] ) )
index 091e36cb57f5eac7a56e58a381475806e97a88e2..a31fe349856f97799509af9fe6ce4e328012d5d1 100644 (file)
 #include "itkBSplineDerivativeKernelFunction.h"
 #include "itkCentralDifferenceImageFunction.h"
 #include "itkBSplineInterpolateImageFunction.h"
-#include "itkBSplineDeformableTransform.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkBSplineTransform.h"
+#else
+  #include "itkBSplineDeformableTransform.h"
+#endif
 #include "itkArray2D.h"
 
 namespace itk
@@ -471,10 +475,17 @@ private:
   /**
    * Typedefs for the BSplineDeformableTransform.
    */
+#if ITK_VERSION_MAJOR >= 4
+  typedef BSplineTransform<
+  CoordinateRepresentationType,
+  ::itk::GetImageDimension<FixedImageType>::ImageDimension,
+  DeformationSplineOrder> BSplineTransformType;
+#else
   typedef BSplineDeformableTransform<
   CoordinateRepresentationType,
   ::itk::GetImageDimension<FixedImageType>::ImageDimension,
   DeformationSplineOrder> BSplineTransformType;
+#endif
   typedef typename BSplineTransformType::WeightsType
   BSplineTransformWeightsType;
   typedef typename BSplineTransformType::ParameterIndexArrayType
index f13fe2aa81b9d950cdb80795f5f0d640d92ae947..1b38cae012c10569ca6d8add8bcf8ab490d6fb0c 100644 (file)
 #include "itkImageRegionIterator.h"
 #include "itkImageIterator.h"
 #include "vnl/vnl_math.h"
-#include "itkBSplineDeformableTransform.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkBSplineTransform.h"
+#else
+  #include "itkBSplineDeformableTransform.h"
+#endif
 
 namespace itk
 {
@@ -1441,9 +1445,13 @@ MattesMutualInformationImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
 
     // Compute the transform Jacobian.
     typedef typename TransformType::JacobianType JacobianType;
-    const JacobianType& jacobian =
-      this->m_Transform->GetJacobian(
-        m_FixedImageSamples[sampleNumber].FixedImagePointValue );
+#if ITK_VERSION_MAJOR >= 4
+      JacobianType jacobian;
+      this->m_Transform->ComputeJacobianWithRespectToParameters( m_FixedImageSamples[sampleNumber].FixedImagePointValue, jacobian );
+#else
+      const JacobianType & jacobian =
+        this->m_Transform->GetJacobian( m_FixedImageSamples[sampleNumber].FixedImagePointValue );
+#endif
 
     for ( unsigned int mu = 0; mu < m_NumberOfParameters; mu++ ) {
       double innerProduct = 0.0;
@@ -1476,8 +1484,13 @@ MattesMutualInformationImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
       weights = m_BSplineTransformWeightsArray[sampleNumber];
       indices = m_BSplineTransformIndicesArray[sampleNumber];
     } else {
+#if ITK_VERSION_MAJOR >= 4
+      m_BSplineTransform->ComputeJacobianFromBSplineWeightsWithRespectToPosition(
+        m_FixedImageSamples[sampleNumber].FixedImagePointValue, m_Weights, m_Indices );
+#else
       m_BSplineTransform->GetJacobian(
         m_FixedImageSamples[sampleNumber].FixedImagePointValue, m_Weights, m_Indices );
+#endif
     }
 
     for( unsigned int dim = 0; dim < FixedImageDimension; dim++ ) {
index 88a71c5a0060c2f82294cb64ad3ab3311d974792..ec4b7ba6ed9c738edd3c15cdb4912311e2e32a79 100644 (file)
@@ -197,9 +197,13 @@ MeanSquaresImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
     if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
       const RealType movingValue  = this->m_Interpolator->Evaluate( transformedPoint );
 
+#if ITK_VERSION_MAJOR >= 4
+      TransformJacobianType jacobian;
+      this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
       const TransformJacobianType & jacobian =
         this->m_Transform->GetJacobian( inputPoint );
-
+#endif
 
       const RealType fixedValue     = ti.Value();
       this->m_NumberOfPixelsCounted++;
@@ -311,9 +315,13 @@ MeanSquaresImageToImageMetricFor3DBLUTFFD<TFixedImage,TMovingImage>
     if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) {
       const RealType movingValue  = this->m_Interpolator->Evaluate( transformedPoint );
 
+#if ITK_VERSION_MAJOR >= 4
+      TransformJacobianType jacobian;
+      this->m_Transform->ComputeJacobianWithRespectToParameters( inputPoint, jacobian );
+#else
       const TransformJacobianType & jacobian =
         this->m_Transform->GetJacobian( inputPoint );
-
+#endif
 
       const RealType fixedValue     = ti.Value();
       this->m_NumberOfPixelsCounted++;
diff --git a/scripts/create_mhd_3D.sh b/scripts/create_mhd_3D.sh
new file mode 100755 (executable)
index 0000000..fbb9760
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+
+#################################################################################
+# create_mhd_3D        argument : {image data} raw_image nom_fichier_de_sortie #
+#################################################################################
+if [ $# -lt 1 ] 
+then
+    echo "Usage: create_mhd_3D.sh dimx dimy dimz spcx spcy spcz offx offy offz pixel_type raw_image_file output_file"
+    echo "dim*: dimensions of the image"
+    echo "spc*: pixel spacing along each dimension"
+    echo "off*: offset along each dimension"
+    echo "pixel_type: CHAR, UCHAR, SHORT, USHORT, FLOAT"
+    echo "raw_image_file: image to be referenced by the mhd file created"
+    echo "output_file: mhd to be created"
+    exit 1
+fi
+
+# can point to existing raw files
+n=`ls ${11} | wc -l`
+if [ $n -eq 0 ] 
+then
+    echo "${11} does not exist. Cannot create mhd file."
+    exit 
+fi
+
+# check if the raw file has the "raw" extension
+n=`ls ${11} | grep .raw | wc -l`
+if [ $n -eq 0 ] 
+then
+    # change extension to raw
+    raw_base=`echo ${11} | cut -d . -f 1`; 
+    raw_file=$raw_base".raw"; 
+    mv ${11} $raw_file
+else
+    raw_file=${11}
+fi
+
+# create file (with some default values...)
+echo "NDims = 3" > ${12}
+echo "TransformMatrix = 1 0 0 0 1 0 0 0 1" >> ${12}
+echo "Offset = " $7 $8 $9 >> ${12}
+echo "CenterOfRotation = 0 0 0" >> ${12}
+echo "AnatomicalOrientation = RAI" >> ${12}
+echo "ElementSpacing = " $4 $5 $6 >> ${12}
+echo "DimSize = " $1 $2 $3 >> ${12}
+echo "ElementType = MET_"${10} >> ${12}
+echo "ElementDataFile = " $raw_file >> ${12}
+
+
diff --git a/scripts/create_mhd_4D-2.0.sh b/scripts/create_mhd_4D-2.0.sh
new file mode 100755 (executable)
index 0000000..c10e098
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/sh +x
+
+
+write_mhd_4D()
+{
+  cat $orig | sed "s/NDims = .*/NDims = 4/
+                 s/TransformMatrix = .*/TransformMatrix = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1/
+                 /Offset/ s/.*/& 0/
+                 /CenterOfRotation/ s/.*/& 0/
+                 s/AnatomicalOrientation = .*/AnatomicalOrientation = ????/
+                 /ElementSpacing/ s/.*/& 1/
+                 /DimSize/ s/.*/& $nbph/
+                 s/ElementDataFile = .*/ElementDataFile = LIST/" > "$1/$file_name_4D"
+  
+  for ph in $listph
+  do
+    phase=`basename $ph`
+    echo "$phase" >> "$1/$file_name_4D"
+  done
+}
+
+#################################################
+# create_mhd_4D        argument : repertoire   #
+#################################################
+if [ $# -lt 1 ]
+then
+  echo "Usage: create_mhd_4D.sh DIRECTORY"
+  exit 1
+fi
+
+dirname=`dirname $1`
+pattern=`basename $1`
+
+list_phase_file=`ls -1 $1*[0-9].mhd`
+nb_phase_file=`ls -1 $1*[0-9].mhd | wc -l`
+if [ $nb_phase_file = 0 ]
+then
+  echo "Error: no phase found"
+  exit 1
+fi
+
+nbph=$nb_phase_file
+orig=`echo $list_phase_file | cut -f 1 -d ' '`
+listph=`echo $list_phase_file | sed 's:\.mhd:\.raw:g'`
+
+file_name_4D=`echo "${pattern}4D.mhd"`
+
+write_mhd_4D $dirname
+echo "$dirname/$file_name_4D"
similarity index 74%
rename from vv/scripts/create_mhd_4D.sh
rename to scripts/create_mhd_4D.sh
index b0503c96a31eef862de7f238bfad335710f5ec90..bc51da445d06389ab8a1347495d680b566d4c892 100755 (executable)
@@ -28,7 +28,7 @@ then
   exit 1
 fi
 
-nb_phase_file=`find $1 -iname "*[0-9].mhd" -o -iname "*[0-9]*\]*.mhd" | wc -l`
+nb_phase_file=`find $1 -maxdepth 1 -iname "*[0-9]*.mhd" -o -iname "*[0-9]*\]*.mhd" | wc -l`
 if [ $nb_phase_file = 0 ]
 then
   echo "Error: no phase found"
@@ -38,7 +38,7 @@ fi
 ########## CT #########
 
 list_pattern=""
-list_phase_file=`find $1 -iname "*[0-9].mhd"`
+list_phase_file=`find $1 -maxdepth 1 -iname "*[0-9]*.mhd"`
 for phase_file in $list_phase_file
 do
   phase_file_name=`basename $phase_file`
@@ -63,11 +63,12 @@ do
     pattern=""
   fi
 
-  nbph=`find $1 -iname "${pattern}*[0-9].mhd" | wc -l`
-  orig=`find $1 -iname "${pattern}*[0-9].mhd" | sort | head -n 1`
-  listph=`find $1 -iname "${pattern}*[0-9].raw" | sort`
+  nbph=`find $1 -maxdepth 1 -iname "${pattern}*[0-9]*.mhd" | wc -l`
+  orig=`find $1 -maxdepth 1 -iname "${pattern}*[0-9]*.mhd" | sort | head -n 1`
+  listph=`find $1 -maxdepth 1 -iname "${pattern}*[0-9]*.raw" | sort`
 
   file_name_4D="${pattern}_4D.mhd"
+  echo $file_name_4D
 
   write_mhd_4D $1
 
@@ -77,7 +78,7 @@ done
 ############ PET ###########
 
 list_pattern=""
-list_phase_file=`find $1 -iname "*[0-9]*\]*.mhd"`
+list_phase_file=`find $1 -maxdepth 1 -iname "*[0-9]*\]*.mhd"`
 for phase_file in $list_phase_file
 do
   phase_file_name=`basename $phase_file`
@@ -102,9 +103,9 @@ do
     pattern=""
   fi
 
-  nbph=`find $1 -iname "*[0-9]${pattern}\]*.mhd" | wc -l`
-  orig=`find $1 -iname "*[0-9]${pattern}\]*.mhd" | sort | head -n 1`
-  listph=`find $1 -iname "*[0-9]${pattern}\]*.raw" | sort`
+  nbph=`find $1 -maxdepth 1 -iname "*[0-9]${pattern}\]*.mhd" | wc -l`
+  orig=`find $1 -maxdepth 1 -iname "*[0-9]${pattern}\]*.mhd" | sort | head -n 1`
+  listph=`find $1 -maxdepth 1 -iname "*[0-9]${pattern}\]*.raw" | sort`
   
   file_name_4D=`basename "$orig" | sed "s/[0-9]${pattern}\]/${pattern}\]/;s/_.mhd/_4D.mhd/"`
 
diff --git a/scripts/create_mhd_4D_pattern.sh b/scripts/create_mhd_4D_pattern.sh
new file mode 100755 (executable)
index 0000000..4d64347
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/sh +x
+
+###############################################################################
+#
+# FILE: create_mhd_pattern.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Similar to create_mhd_4D.sh, but receives a pattern as input.
+# 
+# Example:
+# create_mhd_pattern.sh "<path>/all_my_phases_start_like_this_"
+#
+###############################################################################
+
+write_mhd_4D()
+{
+  cat $orig | sed "s/NDims = .*/NDims = 4/
+                 s/TransformMatrix = .*/TransformMatrix = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1/
+                 /Offset/ s/.*/& 0/
+                 /CenterOfRotation/ s/.*/& 0/
+                 s/AnatomicalOrientation = .*/AnatomicalOrientation = ????/
+                 /ElementSpacing/ s/.*/& 1/
+                 /DimSize/ s/.*/& $nbph/
+                 s/ElementDataFile = .*/ElementDataFile = LIST/" > "$1/$file_name_4D"
+  
+  for ph in $listph
+  do
+    phase=`basename $ph`
+    echo "$phase" >> "$1/$file_name_4D"
+  done
+}
+
+#################################################
+# create_mhd_4D        argument : repertoire   #
+#################################################
+if [ $# -lt 1 ]
+then
+  echo "Usage: $0 PATTERN"
+  exit 1
+fi
+
+dirname=`dirname $1`
+pattern=`basename $1`
+
+list_phase_file=`ls -1 $1*[0-9].mhd`
+nb_phase_file=`ls -1 $1*[0-9].mhd | wc -l`
+if [ $nb_phase_file = 0 ]
+then
+  echo "Error: no phase found"
+  exit 1
+fi
+
+nbph=$nb_phase_file
+orig=`echo $list_phase_file | cut -f 1 -d ' '`
+listph=`echo $list_phase_file | sed 's:\.mhd:\.raw:g'`
+
+file_name_4D=`echo "${pattern}4D.mhd"`
+
+write_mhd_4D $dirname
+echo "$dirname/$file_name_4D"
diff --git a/scripts/create_midP-2.0.sh b/scripts/create_midP-2.0.sh
new file mode 100755 (executable)
index 0000000..93290c8
--- /dev/null
@@ -0,0 +1,209 @@
+#!/bin/sh -x
+
+###############################################################################
+#
+# FILE: create_midP-2.0.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Version 2.0 of the create_midP.sh script. The most relevant changes are:
+#   * receives a .conf file as input, with variables related to the registration
+#   parameters and to paramters of the script itself (see accompanying midp_template.conf)
+#   for details.
+#   * separates execution steps: it's now possible to choose which operation to execute
+#   (mask, registration, midp, or all).
+#   * some steps are now in different modules, to facilitate re-use (see "includes" section).
+#   * minor modifications on output file names.
+#   * attempt to simplify the code a bit.
+#
+###############################################################################
+
+######################### includes
+
+source `dirname $0`/create_midP_masks-2.0.sh using-as-lib 2 nn
+source `dirname $0`/registration.sh
+source `dirname $0`/midp_common.sh
+
+registration()
+{
+  echo
+  echo "----------- Registration ------------"
+  start=`date`
+  echo "start: $start"
+  echo
+
+  mkdir -p $vf_dir
+  mkdir -p $output_dir
+
+  # banded images may be created as separate files,
+  # with the specified preffix, which is interesting for debugging. 
+  # if blank, it means that the original images (those without bands) 
+  # will be used (see create_midP_masks-2.0.sh for details).
+  banded="banded_"
+
+  # params read from conf file
+  params="$nb_iter $nb_samples $sampling_algo $nb_hist_bins $nb_levels $bspline_spacing $metric $optimizer $interpolator"
+
+  # register all phases to the reference
+  for i in $( seq 0 $((${#phase_files[@]} - 1))); do
+    phase_file=${phase_files[$i]}
+    phase_nb=${phase_nbs[$i]}
+    
+    if [ "$phase_nb" != "$ref_phase_nb" ]; then
+      # inside params
+      reference_in=$mask_dir/${banded}inside_$ref_phase_nb.mhd
+      target_in=$mask_dir/${banded}inside_$phase_nb.mhd
+      mask_ref_in=$mask_dir/mask_inside_$ref_phase_nb.mhd
+      mask_targ_in=$mask_dir/mask_inside_$phase_nb.mhd
+      vf_in=$vf_dir/vf_inside_${ref_phase_nb}_$phase_nb.mhd
+      result_in=$output_dir/result_inside_${ref_phase_nb}_$phase_nb.mhd
+      log_in=$log_dir/log_inside_${ref_phase_nb}_$phase_nb.log
+
+      # outside params
+      reference_out=$mask_dir/${banded}outside_$ref_phase_nb.mhd
+      target_out=$mask_dir/${banded}outside_$phase_nb.mhd
+      mask_ref_out=$mask_dir/mask_outside_$ref_phase_nb.mhd
+      mask_targ_out=$mask_dir/mask_outside_$phase_nb.mhd
+      vf_out=$vf_dir/vf_outside_$ref_phase_nb\_$phase_nb.mhd
+      result_out=$output_dir/result_outside_$ref_phase_nb\_$phase_nb.mhd
+      log_out=$log_dir/log_outside_${ref_phase_nb}_$phase_nb.log
+
+      # registration
+      if [ "$method" == "blutdir" ]; then
+        registration_blutdir $reference_in $target_in $mask_ref_in $mask_targ_in $vf_in $result_in $params $log_in
+        registration_blutdir $reference_out $target_out $mask_ref_out $mask_targ_out $vf_out $result_out $params $log_out
+      elif [ "$method" == "elastix" ]; then
+        registration_elastix $reference_in $target_in $mask_ref_in $mask_targ_in $vf_in $result_in $params $log_in
+        registration_elastix $reference_out $target_out $mask_ref_out $mask_targ_out $vf_out $result_out $params $log_out
+      fi
+
+      # combine in and out vf
+      motion_mask=$mask_dir/mm_$phase_nb.mhd
+      vf_result=$vf_dir/vf_${ref_phase_nb}_$phase_nb.mhd
+      clitkCombineImage -i $vf_in -j $vf_out -m $motion_mask -o $vf_result
+      clitkZeroVF -i $vf_in -o vf_zero.mhd
+      clitkCombineImage -i $vf_result -j vf_zero.mhd -m $patient_mask -o $vf_result
+      rm vf_zero.*
+
+      # save for later...
+      vf_ref=$vf_in
+    fi
+  done
+
+  # create (zero) vf from reference to reference
+  clitkZeroVF -i $vf_ref -o $vf_dir/vf_${ref_phase_nb}_${ref_phase_nb}.mhd
+
+  # create 4D vf
+  create_mhd_4D_pattern.sh $vf_dir/vf_${ref_phase_nb}_
+
+  echo
+  echo "-------- Registration done ! --------"
+  end=`date`
+  echo "start: $start"
+  echo "end: $end"
+  echo
+}
+
+midp()
+{
+  echo
+  echo "----------- Mid-position ------------"
+  start=`date`
+  echo "start: $start"
+  echo
+
+  mkdir -p $midp_dir
+
+  ########### calculate the midp wrt the reference phase
+  phase_nb=$ref_phase_nb
+  echo "Calculating midp_$phase_nb.mhd..."
+  vf_midp=$midp_dir/vf_$phase_nb\_midp.mhd
+  midp=$midp_dir/midp_$phase_nb.mhd
+  # average the vf's from reference phase to phase
+  clitkAverageTemporalDimension -i $vf_dir/vf_${ref_phase_nb}_4D.mhd -o $vf_midp
+  # invert the vf (why?)
+  clitkInvertVF -i $vf_midp -o $vf_midp
+  # create the midp by warping the reference phase with the reference vf
+  clitkWarpImage -i $ref_phase_file -o $midp --vf=$vf_midp -s 1
+
+  ref_vf_midp=$vf_midp
+  ref_midp=$midp
+  clitkImageConvert -i $ref_midp -o $ref_midp -t float
+
+  ########### calculate the midp wrt the other phases
+  for i in $( seq 0 $((${#phase_files[@]} - 1))); do
+    phase_file=${phase_files[$i]}
+    phase_nb=${phase_nbs[$i]}
+    vf_midp=$midp_dir/vf_$phase_nb\_midp.mhd
+    midp=$midp_dir/midp_$phase_nb.mhd
+
+    if [ "$phase_nb" != "$ref_phase_nb" ]; then
+      echo "Calculating midp_$phase_nb.mhd..."
+      # calculate vf from phase to midp, using the vf from reference phase to midp (-i)
+      # and the vf from reference phase to phase (-j)
+      clitkComposeVF -i $ref_vf_midp -j $vf_dir/vf_$ref_phase_nb\_$phase_nb.mhd -o $vf_midp
+      clitkWarpImage -i $phase_file -o $midp --vf=$vf_midp -s 1
+      clitkImageConvert -i $midp -o $midp -t float
+    fi
+  done
+
+  create_mhd_4D_pattern.sh $midp_dir/midp_
+  echo "Calculating midp_avg.mhd..."
+  clitkAverageTemporalDimension -i $midp_dir/midp_4D.mhd -o $midp_dir/midp_avg.mhd
+  echo "Calculating midp_med.mhd..."
+  clitkMedianTemporalDimension -i $midp_dir/midp_4D.mhd -o $midp_dir/midp_med.mhd
+
+  # clean-up
+  rm $midp_dir/vf_*
+      
+  echo
+  echo "-------- Mid-position done ! --------"
+  end=`date`
+  echo "start: $start"
+  echo "end: $end"
+  echo
+}
+
+
+
+######################### main
+
+if [ $# != 3 ]; then
+  echo "Usage: create_midP-2.0.sh CT_4D REF_PHASE CONF_FILE"
+  exit -1
+fi
+
+echo
+echo "--------------- START ---------------"
+begining=`date --rfc-3339=seconds`
+# echo "beginning: $begining"
+echo
+
+# variable declarations
+mhd4d=$1
+ref_phase=$2
+conf=$3
+source $conf
+
+mkdir -p $log_dir
+mask_dir="MASK-${mask_interpolation_spacing}mm-$mask_interpolation_algorithm"
+
+extract_4d_phases_ref $mhd4d $ref_phase
+
+if [ "$step" == "mask" -o "$step" == "all" ]; then
+  motion_mask $mhd4d $mask_interpolation_spacing $mask_interpolation_algorithm 
+fi 
+
+if [ "$step" == "registration" -o "$step" == "all" ]; then
+  registration
+fi 
+
+if [ "$step" == "midp" -o "$step" == "all" ]; then
+  midp
+fi 
+
+echo
+echo "---------------- END ----------------"
+terminating=`date --rfc-3339=seconds`
+echo "beginning: $begining"
+echo "terminating: $terminating"
+echo
diff --git a/scripts/create_midP.sh b/scripts/create_midP.sh
new file mode 100755 (executable)
index 0000000..7591efb
--- /dev/null
@@ -0,0 +1,535 @@
+#!/bin/sh -x
+
+#################################################################
+# create_MidP  arguments : CT_4D.mhd ref_phase spacing         #
+#################################################################
+source `dirname $0`/midp_common.sh
+
+extract_patient()
+{
+  echo "$image_name -> Extracting patient..."
+  $CLITK/clitkExtractPatient -i $image_name -o MASK/patient_$image_name --noAutoCrop
+  $CLITK/clitkBinarizeImage -i MASK/patient_$image_name -o MASK/patient_$image_name -l 1 -u 1 --mode=BG
+  $CLITK/clitkSetBackground -i $image_name -o MASK/patient_only_$image_name --mask MASK/patient_$image_name --outsideValue -1000
+}
+
+extract_bones()
+{
+  echo "$image_name -> Extracting bones..."
+  $CLITK/clitkImageConvert -i $image_name -o MASK/float_$image_name -t float
+  $CLITK/clitkExtractBones -i MASK/float_$image_name -o MASK/bones_$image_name --lower1 120 --upper1 2000 --lower2 70 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
+  $CLITK/clitkMorphoMath -i MASK/bones_$image_name -o MASK/bones_$image_name --type 2 --radius 4,4,2
+}
+
+resample()
+{
+  echo "$image_name -> Resampling..."
+  $CLITK/clitkResampleImage -i MASK/patient_$image_name -o MASK/patient_$image_name --spacing $spacing
+  $CLITK/clitkResampleImage -i MASK/patient_only_$image_name -o MASK/patient_only_$image_name --spacing $spacing
+  #$CLITK/clitkResampleImage -i MASK/bones_$image_name -o MASK/bones_$image_name --like MASK/patient_only_$image_name
+}
+
+compute_motion_mask()
+{
+#   $CLITK/clitkMotionMask -i MASK/patient_only_$image_name -o MASK/mm_$image_name --featureBones=MASK/bones_$image_name --upperThresholdLungs -400 --fillingLevel 94 --offsetDetect 0,-5,0 --pad --writeFeature=MASK/feature_$image_name --writeEllips=MASK/inital_ellipse_$image_name --writeGrownEllips=MASK/growing_ellipse_$image_name;
+$CLITK/clitkMotionMask -i MASK/patient_only_$image_name -o MASK/mm_$image_name --upperThresholdLungs -400 --fillingLevel 94 --offsetDetect 0,-5,0 --pad --writeFeature=MASK/feature_$image_name --writeEllips=MASK/inital_ellipse_$image_name --writeGrownEllips=MASK/growing_ellipse_$image_name;
+}
+
+set_background()
+{
+  echo "$image_name -> Setting Background..."
+  $CLITK/clitkSetBackground -i MASK/patient_only_$image_name -o MASK/inside_$image_name --mask MASK/mm_$image_name --outsideValue -1200
+  $CLITK/clitkSetBackground -i MASK/patient_only_$image_name -o MASK/outside_$image_name --mask MASK/mm_$image_name --outsideValue -1200 --fg
+}
+
+create_registration_masks()
+{
+  echo "$image_name -> Creating registration masks..."
+  $CLITK/clitkMorphoMath -i MASK/mm_$image_name -o MASK/regmask_in_$image_name --type 1 --radius 8
+  $CLITK/clitkExtractPatient -i MASK/outside_$image_name -o MASK/regmask_out_$image_name --noAutoCrop
+  $CLITK/clitkMorphoMath -i MASK/regmask_out_$image_name -o MASK/regmask_out_$image_name --type 1 --radius 8
+}
+
+remove_files()
+{
+  echo "Removing temporary files..."
+  image_name_base=`echo $image_name | sed 's/mhd//'`
+  case $1 in
+    1)
+      rm MASK/float_$image_name_base*;;
+    2)
+      rm MASK/bones_$image_name_base*;;
+    3)
+      rm MASK/patient_only_$image_name_base*;;
+    4)
+      #rm MASK/patient_$image_name_base*
+      #rm MASK/mm_$image_name_base*
+      rm -f $vf_dir/vf_tmp_in_${ref}_${phase}.*
+      rm -f $vf_dir/vf_tmp_out_${ref}_${phase}.*
+      #rm MASK/regmask_in_$image_name_base*
+      #rm MASK/regmask_out_$image_name_base*
+      ;;
+    5)
+#       rm -f coeff_*
+      #rm $vf_dir/vf_in_*
+      #rm $vf_dir/vf_out_*
+#       rm MASK/regmask_*
+#       rm MASK/mm_*
+      ;;
+    6)
+      ;;
+      #rm -f $vf_dir/_4D.*
+      #rm -f $vf_dir/vf_MIDP_${ref}.*
+      #rm -f $vf_dir/vf_${ref}_MIDP.*;;
+    7)
+      ;; #rm $vf_dir/vf_MIDP_${phase}.*;;
+    8)
+      rm $vf_dir/*.txt
+      rm $vf_dir/*.log
+  esac
+}
+
+mm_preprocessing()
+{
+  extract_patient
+  #extract_bones
+  remove_files 1
+  resample
+}
+
+mm_postprocessing()
+{
+  remove_files 2
+  set_background
+  remove_files 3
+  create_registration_masks
+}
+
+# mm_workflow()
+# {
+#   extract_patient
+#   extract_bones
+#   remove_files 1
+#   resample
+#   echo "$image_name -> Computing motion mask..."
+#   compute_motion_mask >> LOG/motion_mask_$image_name.log
+#   remove_files 2
+#   set_background
+#   remove_files 3
+#   create_registration_masks
+# }
+
+motion_mask()
+{
+  echo
+  echo "------------ Motion mask ------------"
+  start=`date`
+  echo "start: $start"
+  echo
+  mkdir -p "MASK"
+  rm -f "LOG/motion_mask*.log"
+  regmask_in_list=""
+  regmask_out_list=""
+  reg_in_list=""
+  reg_out_list=""
+
+  # multi-threaded pre-processing for motion mask calcs
+  for phase in $phase_list
+  do
+    image_name=`echo $phase | sed 's/raw/mhd/'`
+    check_threads $MAX_THREADS
+    #mm_preprocessing &
+  done
+
+  # single-threaded motion mask calc
+  check_threads 1
+  for phase in $phase_list
+  do
+    image_name=`echo $phase | sed 's/raw/mhd/'`
+
+    echo "$image_name -> Computing motion mask..."
+    #compute_motion_mask >> LOG/motion_mask_$image_name.log
+  done
+
+  # multi-threaded post-processing of motion mask calcs
+  for phase in $phase_list
+  do
+    image_name=`echo $phase | sed 's/raw/mhd/'`
+    check_threads $MAX_THREADS 
+    #mm_postprocessing &
+    regmask_in_list="$regmask_in_list regmask_in_$image_name"
+    regmask_out_list="$regmask_out_list regmask_out_$image_name"
+    reg_in_list="$reg_in_list inside_$image_name"
+    reg_out_list="$reg_out_list outside_$image_name"
+  done
+
+  wait
+  echo
+  echo "-------- Motion mask done ! ---------"
+  end=`date`
+  echo "start: $start"
+  echo "end: $end"
+  echo
+}
+
+compute_BLUTDIR()
+{
+  ########## register in ##########
+  for reg_in in $reg_in_list
+  do
+    if [ ! -z `echo $reg_in | grep "$phase"` ]
+    then
+      target_in=$reg_in
+    fi
+  done
+  echo "Computing BLUTDIR $reference_in -> $target_in ..."
+  #$CLITK/clitkBLUTDIR --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --referenceMask="MASK/$reference_mask_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" $coeff_in_ini --coeff="$coeff_dir/coeff_in_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log
+  $CLITK/clitkBLUTDIR --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --referenceMask="MASK/$reference_mask_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" --coeff="$coeff_dir/coeff_in_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log
+  coeff_in_ini="--initCoeff=$coeff_dir/coeff_in_${ref}_${phase}.mhd"
+  ########## register out ##########
+  for reg_out in $reg_out_list
+  do
+    if [ ! -z `echo $reg_out | grep "$phase"` ]
+    then
+      target_out=$reg_out
+    fi
+  done
+  echo "Computing BLUTDIR $reference_out -> $target_out ..."
+  #$CLITK/clitkBLUTDIR --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --referenceMask="MASK/$reference_mask_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" $coeff_out_ini --coeff="$coeff_dir/coeff_out_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log
+  $CLITK/clitkBLUTDIR --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --referenceMask="MASK/$reference_mask_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" --coeff="$coeff_dir/coeff_out_${ref}_${phase}.mhd" $registration_parameters_BLUTDIR >> LOG/registration_${ref}_${phase}.log
+  coeff_out_ini="--initCoeff=$coeff_dir/coeff_out_${ref}_${phase}.mhd"
+  ##################################
+  $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+  $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd
+  $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+  remove_files 4
+}
+
+compute_DEMONSDIR()
+{
+  ########## register in ##########
+  for reg_in in $reg_in_list
+  do
+    if [ ! -z `echo $reg_in | grep "_$phase"` ]
+    then
+      target_in=$reg_in
+    fi
+  done
+  echo "Computing DEMONSDIR $reference_in -> $target_in ..."
+  $CLITK/clitkDemonsDeformableRegistration --reference="MASK/$reference_in" --target="MASK/$target_in" --output="MASK/reg_$target_in" --vf="$vf_dir/vf_in_${ref}_${phase}.mhd" $vf_in_ini $registration_parameters_DEMONSDIR #&>> LOG/registration_${ref}_${phase}.log
+  vf_in_ini="--init=$vf_dir/vf_in_${ref}_${phase}.mhd"
+  ########## register out ##########
+  for reg_out in $reg_out_list
+  do
+    if [ ! -z `echo $reg_out | grep "_$phase"` ]
+    then
+      target_out=$reg_out
+    fi
+  done
+  echo "Computing DEMONSDIR $reference_out -> $target_out ..."
+  $CLITK/clitkDemonsDeformableRegistration --reference="MASK/$reference_out" --target="MASK/$target_out" --output="MASK/reg_$target_out" --vf="$vf_dir/vf_out_${ref}_${phase}.mhd" $vf_out_ini $registration_parameters_DEMONSDIR #&>> LOG/registration_${ref}_${phase}.log
+  vf_out_ini="--init=$vf_dir/vf_out_${ref}_${phase}.mhd"
+  ##################################
+  $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+  $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd
+  $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+  remove_files 4
+}
+
+compute_ELASTIX()
+{
+  ########## register in ##########
+  for reg_in in $reg_in_list
+  do
+    if [ ! -z `echo $reg_in | grep "_$phase"` ]
+    then
+      target_in=$reg_in
+    fi
+  done
+  echo "Computing ELASTIX $reference_in -> $target_in ..."
+  exec_dir=`which elastix`
+  exec_dir=`dirname $exec_dir`
+  cat $exec_dir/params_BSpline.txt | sed -e "s+<NbIterations>+500+" \
+                              -e "s+<LabelsFile>++" \
+                              -e "s+<HistBins>+25+" \
+                              -e "s+<Levels>+3+" \
+                              -e "s+<NbSamples>+2000+" \
+                              -e "s+<SamplerType>+Random+" \
+                              -e "s+<Spacing>+32+" > params_BSpline.txt 
+  elastix -f "MASK/$reference_in" -m "MASK/$target_in" -fMask "MASK/$reference_mask_in" -out $vf_dir -p params_BSpline.txt > /dev/null
+  transformix -tp $vf_dir/TransformParameters.0.txt -out $vf_dir -def all > /dev/null  
+  mv $vf_dir/deformationField.mhd $vf_dir/vf_in_${ref}_${phase}.mhd
+  mv $vf_dir/deformationField.raw $vf_dir/vf_in_${ref}_${phase}.raw
+  sed -i "s:deformationField:vf_in_${ref}_${phase}:" $vf_dir/vf_in_${ref}_${phase}.mhd
+  mv $vf_dir/result.0.mhd MASK/reg_$target_in
+  targetraw=`echo reg_$target_in | sed 's:mhd:raw:'`
+  sed -i "s:result.0.mhd:$targetraw" MASK/reg_$target_in
+  mv $vf_dir/result.0.raw MASK/$targetraw
+  remove_files 8
+
+  ########## register out ##########
+  for reg_out in $reg_out_list
+  do
+    if [ ! -z `echo $reg_out | grep "_$phase"` ]
+    then
+      target_out=$reg_out
+    fi
+  done
+  echo "Computing ELASTIX $reference_out -> $target_out ..."
+  elastix -f "MASK/$reference_out" -m "MASK/$target_out" -fMask "MASK/$reference_mask_out" -out $vf_dir -p params_BSpline.txt > /dev/null
+  transformix -tp $vf_dir/TransformParameters.0.txt -out $vf_dir -def all > /dev/null  
+  mv $vf_dir/deformationField.mhd $vf_dir/vf_out_${ref}_${phase}.mhd
+  mv $vf_dir/deformationField.raw $vf_dir/vf_out_${ref}_${phase}.raw
+  sed -i "s:deformationField:vf_out_${ref}_${phase}:" $vf_dir/vf_out_${ref}_${phase}.mhd
+  mv $vf_dir/result.0.mhd MASK/reg_$target_out
+  targetraw=`echo reg_$target_out | sed 's:mhd:raw:'`
+  sed -i "s:result.0.mhd:$targetraw" MASK/reg_$target_out
+  mv $vf_dir/result.0.raw MASK/$targetraw
+  remove_files 8
+
+  ##################################
+  $CLITK/clitkCombineImage -i $vf_dir/vf_in_${ref}_${phase}.mhd -j $vf_dir/vf_out_${ref}_${phase}.mhd -m MASK/mm_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+  $CLITK/clitkZeroVF -i $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_${ref}_${ref}.mhd
+  $CLITK/clitkCombineImage -i $vf_dir/vf_${ref}_${phase}.mhd -j $vf_dir/vf_${ref}_${ref}.mhd -m MASK/patient_$image_name -o $vf_dir/vf_${ref}_${phase}.mhd
+  remove_files 4
+}
+
+registration()
+{
+  echo
+  echo "----------- Registration ------------"
+  start=`date`
+  echo "start: $start"
+  echo
+
+  rm -f "LOG/registration*.log"
+
+  # wait any unfinished threads
+  check_threads 1
+
+  for reg_in in $reg_in_list
+  do
+    if [ ! -z `echo $reg_in | grep "$ref"` ]
+    then
+      reference_in=$reg_in
+    fi
+  done
+  for reg_out in $reg_out_list
+  do
+    if [ ! -z `echo $reg_out | grep "$ref"` ]
+    then
+      reference_out=$reg_out
+    fi
+  done
+  for regmask_in in $regmask_in_list
+  do
+    if [ ! -z `echo $regmask_in | grep "$ref"` ]
+    then
+      reference_mask_in=$regmask_in
+    fi
+  done
+  for regmask_out in $regmask_out_list
+  do
+    if [ ! -z `echo $regmask_out | grep "$ref"` ]
+    then
+      reference_mask_out=$regmask_out
+    fi
+  done
+
+  registration_parameters_BLUTDIR="--spacing=32,32,32 --interp=2 --metric=11 --bins=25 --samples=1 --levels=3 --verbose " #--coeffEveryN 5"
+  registration_parameters_DEMONSDIR="--demons=3 --levels=1"
+  registration_parameters_ELASTIX="--demons=3 --levels=1"
+
+  coeff_in_ini=""
+  coeff_out_ini=""
+  vf_in_ini=""
+  vf_out_ini=""
+  
+  for phase in $list_phases
+  do
+    for img in $phase_list
+    do
+      if [ ! -z `echo $img | grep "$phase" | grep -v "[0-9]$phase"` ]
+      then
+       image_name=`echo $img | sed 's/raw/mhd/'`
+      fi
+    done
+    if [ $method = 1 ]
+    then
+      compute_BLUTDIR
+    elif [ $method = 2 ]
+    then
+      compute_DEMONSDIR
+    elif [ $method = 3 ]
+    then
+      compute_ELASTIX
+    fi
+  done
+  remove_files 5
+
+  echo
+  echo "-------- Registration done ! --------"
+  end=`date`
+  echo "start: $start"
+  echo "end: $end"
+  echo
+}
+
+calculate_vf_MIDP_REF()
+{
+  echo "Calculating vf_REF_MIDP.mhd..."
+  remove_files 6
+  create_mhd_4D.sh $vf_dir #"vf_4D.mhd"
+  $CLITK/clitkAverageTemporalDimension -i $vf_dir/_4D.mhd -o $vf_dir/vf_${ref}_MIDP.mhd
+  $CLITK/clitkInvertVF -i $vf_dir/vf_${ref}_MIDP.mhd -o $vf_dir/vf_MIDP_${ref}.mhd
+}
+
+calculate_CT_MIDP_REF()
+{
+  reference=`ls *.mhd | grep $ref #| grep -v "[0-9]$ref.mhd"`
+  echo "Calculating CT_MIDP_REF.mhd '$reference'..."
+  $CLITK/clitkWarpImage -i $reference -o CT_MIDP_REF.mhd --vf=$vf_dir/vf_MIDP_${ref}.mhd -s 1
+}
+
+calculate_CT_MIDP_PHASE()
+{
+  echo "Calculating CT_MIDP_${phase}.mhd..."
+  $CLITK/clitkComposeVF -i $vf_dir/vf_MIDP_${ref}.mhd -j $vf_dir/vf_${ref}_${phase}.mhd -o $vf_dir/vf_MIDP_${phase}.mhd
+  phase_img=`ls *.mhd | grep "${phase}" # | grep -v "[0-9]$ref.mhd"`
+  $CLITK/clitkWarpImage -i $phase_img -o MIDP/CT_MIDP_${phase}.mhd --vf=$vf_dir/vf_MIDP_${phase}.mhd -s 1
+  $CLITK/clitkImageConvert -i MIDP/CT_MIDP_${phase}.mhd -o MIDP/CT_MIDP_${phase}.mhd -t float
+  remove_files 7
+}
+
+prepare_MIDP_images()
+{
+  echo "Preparing MIDP images..."
+  cp CT_MIDP_REF.mhd MIDP/CT_MIDP_${ref}.mhd
+  cp CT_MIDP_REF.raw MIDP/CT_MIDP_${ref}.raw
+  cat MIDP/CT_MIDP_${ref}.mhd | sed "s/ElementDataFile = .*/ElementDataFile = CT\_MIDP\_${ref}\.raw/" > MIDP/CT_MIDP_${ref}_tmp.mhd
+  rm MIDP/CT_MIDP_${ref}.mhd
+  mv MIDP/CT_MIDP_${ref}_tmp.mhd MIDP/CT_MIDP_${ref}.mhd
+  $CLITK/clitkImageConvert -i MIDP/CT_MIDP_${ref}.mhd -o MIDP/CT_MIDP_${ref}.mhd -t float
+  create_mhd_4D.sh MIDP #"CT_MIDP_4D.mhd"
+}
+
+calculate_CT_MIDP_MOY()
+{
+  echo "Calculating CT_MIDP_MOY.mhd..."
+  $CLITK/clitkAverageTemporalDimension -i MIDP/_4D.mhd -o CT_MIDP_MOY.mhd
+}
+
+calculate_CT_MIDP_MED()
+{
+  echo "Calculating CT_MIDP_MED.mhd..."
+  $CLITK/clitkMedianTemporalDimension -i MIDP/_4D.mhd -o CT_MIDP_MED.mhd
+}
+
+calculate_CT_MIDP_MIP()
+{
+  echo "Calculating CT_MIDP_MIP.mhd..."
+  $CLITK/clitkMIP -i MIDP/_4D.mhd -o CT_MIDP_MIP.mhd -d 3
+}
+
+mid_position()
+{
+  echo
+  echo "----------- Mid-position ------------"
+  start=`date`
+  echo "start: $start"
+  echo
+  
+  mkdir -p "MIDP"
+
+  calculate_vf_MIDP_REF
+  calculate_CT_MIDP_REF
+  for phase in $list_phases
+  do  
+    check_threads $MAX_THREADS
+    calculate_CT_MIDP_PHASE &
+  done
+  wait
+  prepare_MIDP_images
+  calculate_CT_MIDP_MED &
+  calculate_CT_MIDP_MIP &
+  calculate_CT_MIDP_MOY &
+  wait
+      
+  echo
+  echo "-------- Mid-position done ! --------"
+  end=`date`
+  echo "start: $start"
+  echo "end: $end"
+  echo
+}
+
+#################
+#      main    #
+#################
+
+if [ $# -lt 1 ]
+then
+    echo "Usage: create_midP.sh CT_4D.mhd ref_phase computation_spacing(mm) method(1:BSPLINE, 2:DEMONS)"
+    exit 1
+fi
+CLITK=~/creatis/clitk3/build/bin
+CT_4D_path=$1
+CT_4D=`basename $CT_4D_path`
+work_dir=`dirname $CT_4D_path`
+cd $work_dir
+ref=$2
+spacing=$3
+method=$4
+
+vf_dir="VF"
+coeff_dir="$vf_dir/coeff"
+
+mkdir -p $vf_dir
+mkdir -p $coeff_dir
+
+echo
+echo "--------------- START ---------------"
+begining=`date`
+echo "start: $begining"
+echo
+
+mkdir -p "LOG"
+phase_list=`grep ".raw" $CT_4D`
+echo "phases -> " $phase_list
+nb_phases=`grep ".raw" $CT_4D | wc -l`
+gt_ref=""
+lt_ref=""
+
+phase_files=( `cat $CT_4D | grep ".raw" | sed 's:.raw:.mhd:'` )
+echo "Phase files are ${phase_files[@]}"
+
+phase_nbs=( `echo ${phase_files[@]} | grep -o '[[:alpha:][:punct:]][0-9]\{1,2\}[[:punct:]]' | grep -o '[0-9]\{1,2\}'` )
+#phase_nbs=( `echo ${phase_files[@]} | grep -o '[0-9]\{1,2\}'` )  
+echo "Phase numbers are ${phase_nbs[@]}"
+
+
+for ph in $phase_list
+do
+  #ph_nb=`echo $ph | grep -o "[0-9][0-9]*\.raw" | sed -e 's/\.raw//'`
+  ph_nb=`echo $ph | grep -o "[0-9][0-9]"`  
+  if [ $ph_nb -gt $ref ]
+  then
+    gt_ref="$gt_ref $ph_nb"
+  elif [ $ph_nb -lt $ref ]
+  then
+    lt_ref="$lt_ref $ph_nb"
+  fi
+done
+list_phases="$gt_ref $lt_ref"
+echo list_phases $list_phases
+
+motion_mask
+registration
+mid_position
+
+echo
+echo "---------------- END ----------------"
+terminating=`date`
+echo "start: $begining"
+echo "end: $terminating"
+echo
diff --git a/scripts/create_midP_masks-2.0.sh b/scripts/create_midP_masks-2.0.sh
new file mode 100755 (executable)
index 0000000..8a8babf
--- /dev/null
@@ -0,0 +1,258 @@
+#! /bin/bash -x
+
+###############################################################################
+#
+# FILE: create_midP-2.0.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Version 2.0 of the create_midP_masks.sh script. The most relevant changes are:
+#   * creation of bands around input and output image regions to try to improve 
+#   the registration along lung boundaries (naturally, it depends on the quality
+#   of motion mask generation).
+#   * some steps are now in different modules, to facilitate re-use (see "includes" section).
+#   * minor modifications on output file names.
+#   * attempt to simplify the code a bit.
+#
+###############################################################################
+
+source `dirname $0`/midp_common.sh
+
+extract_patient()
+{
+  echo "$phase_file -> Extracting patient..."
+  clitkExtractPatient -i $phase_file -o $mask_dir_tmp/patient_mask_$phase_nb.mhd --noAutoCrop -a $afdb_file $ExtractPatientExtra
+  clitkSetBackground -i $phase_file -o $mask_dir_tmp/patient_$phase_nb.mhd --mask $mask_dir_tmp/patient_mask_$phase_nb.mhd --outsideValue -1000
+}
+
+extract_bones()
+{
+  if [ x = x$ExtractBonesLower1 ]; then
+    ExtractBonesLower1=120
+  fi
+  if [ x = x$ExtractBonesLower2 ]; then
+    ExtractBonesLower2=80
+  fi
+  echo "$phase_file -> Extracting bones..."
+  clitkImageConvert -i $phase_file -o $mask_dir_tmp/float_$phase_nb.mhd -t float
+  clitkExtractBones -i $mask_dir_tmp/float_$phase_nb.mhd -o $mask_dir_tmp/bones_$phase_nb.mhd -a $afdb_file --lower1 $ExtractBonesLower1 --upper1 2000 --lower2 $ExtractBonesLower2 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
+}
+
+extract_lungs()
+{
+  echo "$phase_file -> Extracting lungs..."
+  clitkExtractLung -i $phase_file -o $mask_dir_tmp/lungs_$phase_nb.mhd -a $afdb_file --noAutoCrop
+}
+
+resample()
+{
+  echo "$phase_file -> Resampling..."
+  clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
+
+  clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
+}
+
+compute_motion_mask()
+{
+  if [ x = x$MotionMaskOffsetDetect ]; then
+    MotionMaskOffsetDetect="0,-5,0"
+  fi
+  if [ x = x$FillingLevel ]; then
+    FillingLevel=94
+  fi
+
+  clitkMotionMask -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/mm_$phase_nb.mhd --featureLungs $mask_dir_tmp/lungs_$phase_nb.mhd --upperThresholdLungs -400 --fillingLevel $FillingLevel --offsetDetect $MotionMaskOffsetDetect --pad --writeFeature=$mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra 
+  #--monitor=$mask_dir_tmp/monitor_$phase_nb.mhd
+}
+
+create_banded_mask()
+{
+  input=$1
+  input_mask=$2
+  output=$3
+  output_mask=$4
+  radius=$5
+
+  input_dir=`dirname $input`
+  input_base=`basename $input`
+
+  # first band
+  clitkMorphoMath -i $input_mask -o $input_dir/extra1_$input_base --type 1 --radius $radius
+  clitkImageArithm -i $input_dir/extra1_$input_base -j $input_mask -o $input_dir/band1_$input_base -t 7
+  clitkBinarizeImage -i $input_dir/band1_$input_base -o $input_dir/band1_$input_base -l 1 -u 1 --fg 100 --mode both
+  clitkImageConvert -i $input_dir/band1_$input_base -o $input_dir/short_band1_$input_base -t short
+  
+  # second band
+  clitkMorphoMath -i $input_dir/extra1_$input_base -o $input_dir/extra2_$input_base --type 1 --radius $radius
+  clitkImageArithm -i $input_dir/extra2_$input_base -j $input_dir/extra1_$input_base -o $input_dir/band2_$input_base -t 7
+  clitkBinarizeImage -i $input_dir/band2_$input_base -o $input_dir/band2_$input_base -l 1 -u 1 --fg 200 --mode both
+  clitkImageConvert -i $input_dir/band2_$input_base -o $input_dir/short_band2_$input_base -t short
+  
+  # combine bands with masks
+  clitkImageArithm -i $input_mask -j $input_dir/band1_$input_base -o $output_mask -t 0
+  clitkImageArithm -i $output_mask -j $input_dir/band2_$input_base -o $output_mask -t 0
+  # combine bands with image
+  clitkCombineImage -i $input_dir/short_band1_$input_base -j $input -m $input_dir/band1_$input_base -o $output
+  clitkCombineImage -i $input_dir/short_band2_$input_base -j $output -m $input_dir/band2_$input_base -o $output
+
+  # clean-up
+  rm `echo $input_dir/extra?_$input_base | sed 's:.mhd:.*:g'`
+  rm `echo $input_dir/band?_$input_base | sed 's:.mhd:.*:g'`
+  rm `echo $input_dir/short_band?_$input_base | sed 's:.mhd:.*:g'`
+}
+
+create_registration_masks()
+{
+  # extract inside and outside lung regions from the patient image, 
+  # using the motion mask computed previously
+  echo "$phase_file -> Setting Background..."
+  clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/inside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200
+  clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/outside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200 --fg
+
+  # the registration masks for inside (and outside) region correspond
+  # to the motion mask (and its complement) plus extra grey value bands,
+  # obtained with morphological dilations.
+  # 
+  echo "$phase_file -> Creating registration masks..."
+  # inside
+  create_banded_mask $mask_dir_tmp/inside_$phase_nb.mhd $mask_dir_tmp/mm_$phase_nb.mhd $mask_dir_tmp/banded_inside_$phase_nb.mhd $mask_dir_tmp/mask_inside_$phase_nb.mhd 4
+  # outside 
+  clitkExtractPatient -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/mm_outside_$phase_nb.mhd --noAutoCrop
+  create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/mm_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/mask_outside_$phase_nb.mhd 4
+}
+
+mm_preprocessing()
+{
+  extract_patient
+  # extract_bones
+  extract_lungs
+  # remove_tmp_masks 1
+  resample
+}
+
+mm_postprocessing()
+{
+  # remove_tmp_masks 2
+  # remove_tmp_masks 3
+  create_registration_masks
+}
+
+motion_mask()
+{
+  #set cmd line variables
+  mhd4d=$1
+  resample_spacing=$2
+  resample_algo=$3
+
+  dir=`dirname $1`
+  cd $dir
+    
+  # import variables specific to each patient
+  source ./variables
+
+  #set other global variables
+  mask_dir="MASK-${resample_spacing}mm-$resample_algo"
+  mask_dir_tmp="tmp.$mask_dir"
+  extract_4d_phases $mhd4d
+
+  echo
+  echo "------------ Motion mask from create_midP_masks.sh ------------"
+  start=`date`
+  echo "start: $start"
+  echo
+
+  # the motion masks are first created in a tmp directory. this directory is 
+  # later going to be renamed to the final motion mask directory. concurrent
+  # executions trying to create the same set of masks will be blocked until
+  # the first execution finishes. naturally, these other executions will not
+  # recreate the masks. so first we try to create the tmp directory. 
+  # if the creation fails, it means that another execution is
+  # already creating the masks, so this execution will be blocked. the
+  # execution is unblocked only when the creation of masks is finished and
+  # the mask directory is renamed.
+  #
+  # ATTENTION: RP - 08/02/2011
+  # robustness issue: tmp directory may exist but may be empty or 
+  # incomplete. the solution is to check per file, but I'll leave it like 
+  # this for the moment.
+  do_mm=0
+  if [ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]; then
+    mkdir $mask_dir_tmp 2> /dev/null
+    return_mkdir=$?
+    if [ $return_mkdir == 0 ]; then
+      do_mm=1 
+    else
+      while [[ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]]; do
+        echo "waiting creation of motion masks..."
+        sleep 2
+      done
+      echo "finished waiting"
+    fi  
+  fi
+  
+#   do_mm=1
+#   mask_dir_tmp=$mask_dir
+  if [ $do_mm == 1 ]; then
+    mask_log_dir=$mask_dir_tmp/LOG
+    mkdir -p $mask_log_dir
+
+    # multi-threaded pre-processing for motion mask calcs
+    for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
+      phase_nb=${phase_nbs[$i]}
+      phase_file=${phase_files[$i]}
+      afdb_file=`echo $phase_file | sed 's/mhd/afdb/'`
+
+      check_threads $MAX_THREADS
+      mm_preprocessing &
+    done
+
+    # single-threaded motion mask calc
+    for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
+      phase_nb=${phase_nbs[$i]}
+      phase_file=${phase_files[$i]}
+
+      check_threads 1
+      echo "$phase_file -> Computing motion mask..."
+      compute_motion_mask > $mask_log_dir/motion_mask_$phase_file.log
+    done
+
+    # multi-threaded post-processing of motion mask calcs
+    for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
+      phase_nb=${phase_nbs[$i]}
+      phase_file=${phase_files[$i]}
+
+      check_threads $MAX_THREADS 
+      mm_postprocessing &
+    done
+
+    # rename tmp mask directory after mask creation
+    check_threads 1
+    mv -f $mask_dir_tmp $mask_dir
+  fi
+
+  echo
+  echo "-------- Motion mask done ! ---------"
+  end=`date`
+  echo "start: $start"
+  echo "end: $end"
+  echo
+}
+
+
+#################
+# main  #
+#################
+
+if [ $# != 3 ]; then
+  echo "Usage: $0 CT_4D RESAMPLE_SPACING RESAMPLE_ALGORITHM"
+  exit -1
+fi
+
+#
+# variables exported in this scope
+#
+# mask_dir: directory where all masks are kept
+#
+
+if [ $1 != "using-as-lib" ]; then
+  motion_mask $1 $2 $3
+fi
diff --git a/scripts/create_midP_masks.sh b/scripts/create_midP_masks.sh
new file mode 100755 (executable)
index 0000000..845237d
--- /dev/null
@@ -0,0 +1,253 @@
+#! /bin/bash -x
+
+source `dirname $0`/midp_common.sh
+
+extract_patient()
+{
+  echo "$image_name -> Extracting patient..."
+  clitkExtractPatient -i $image_name -o $mask_dir_tmp/patient_$image_name --noAutoCrop -a $afdb_name $ExtractPatientExtra
+  clitkBinarizeImage -i $mask_dir_tmp/patient_$image_name -o $mask_dir_tmp/patient_$image_name -l 1 -u 1 --mode=BG
+  clitkSetBackground -i $image_name -o $mask_dir_tmp/patient_only_$image_name --mask $mask_dir_tmp/patient_$image_name --outsideValue -1000
+}
+
+extract_bones()
+{
+  if [ x = x$ExtractBonesLower1 ]; then
+    ExtractBonesLower1=120
+  fi
+  if [ x = x$ExtractBonesLower2 ]; then
+    ExtractBonesLower2=80
+  fi
+  echo "$image_name -> Extracting bones..."
+  clitkImageConvert -i $image_name -o $mask_dir_tmp/float_$image_name -t float
+  #clitkExtractBones -i $mask_dir_tmp/float_$image_name -o $mask_dir_tmp/bones_$image_name --lower1 120 --upper1 2000 --lower2 70 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
+  clitkExtractBones -i $mask_dir_tmp/float_$image_name -o $mask_dir_tmp/bones_$image_name -a $afdb_name --lower1 $ExtractBonesLower1 --upper1 2000 --lower2 $ExtractBonesLower2 --upper2 2000 --smooth --time 0.0625 --noAutoCrop
+  #clitkMorphoMath -i $mask_dir_tmp/bones_$image_name -o $mask_dir_tmp/bones_$image_name --type 2 --radius 4,4,2
+}
+
+extract_lungs()
+{
+  echo "$image_name -> Extracting lungs..."
+  clitkExtractLung -i $image_name -o $mask_dir_tmp/lungs_$image_name -a $afdb_name --noAutoCrop
+}
+
+resample()
+{
+  echo "$image_name -> Resampling..."
+  clitkResampleImage -i $mask_dir_tmp/patient_$image_name -o $mask_dir_tmp/patient_$image_name --spacing $resample_spacing --interp $resample_algo
+  clitkResampleImage -i $mask_dir_tmp/patient_only_$image_name -o $mask_dir_tmp/patient_only_$image_name --spacing $resample_spacing --interp $resample_algo
+  clitkResampleImage -i $mask_dir_tmp/bones_$image_name -o $mask_dir_tmp/bones_$image_name --like $mask_dir_tmp/patient_only_$image_name --interp $resample_algo
+  clitkResampleImage -i $mask_dir_tmp/lungs_$image_name -o $mask_dir_tmp/lungs_$image_name --like $mask_dir_tmp/patient_only_$image_name
+}
+
+compute_motion_mask()
+{
+  if [ x = x$MotionMaskOffsetDetect ]; then
+    MotionMaskOffsetDetect="0,-5,0"
+  fi
+  if [ x = x$FillingLevel ]; then
+    FillingLevel=94
+  fi
+  clitkMotionMask -i $mask_dir_tmp/patient_only_$image_name -o $mask_dir_tmp/mm_$image_name --featureBones=$mask_dir_tmp/bones_$image_name --featureLungs=$mask_dir_tmp/lungs_$image_name --upperThresholdLungs -400 --fillingLevel $FillingLevel --offsetDetect 0,-5,0 --pad --writeFeature=$mask_dir_tmp/feature_$image_name $MotionMaskExtra --monitor=$mask_dir_tmp/monitor_$image_name
+}
+
+set_background()
+{
+  echo "$image_name -> Setting Background..."
+  clitkSetBackground -i $mask_dir_tmp/patient_only_$image_name -o $mask_dir_tmp/inside_$image_name --mask $mask_dir_tmp/mm_$image_name --outsideValue -1200
+  clitkSetBackground -i $mask_dir_tmp/patient_only_$image_name -o $mask_dir_tmp/outside_$image_name --mask $mask_dir_tmp/mm_$image_name --outsideValue -1200 --fg
+}
+
+create_registration_masks()
+{
+  echo "$image_name -> Creating registration masks..."
+  clitkMorphoMath -i $mask_dir_tmp/mm_$image_name -o $mask_dir_tmp/regmask_in_$image_name --type 1 --radius 8
+  clitkExtractPatient -i $mask_dir_tmp/outside_$image_name -o $mask_dir_tmp/regmask_out_$image_name --noAutoCrop
+  clitkMorphoMath -i $mask_dir_tmp/regmask_out_$image_name -o $mask_dir_tmp/regmask_out_$image_name --type 1 --radius 8
+}
+
+remove_tmp_masks()
+{
+  echo "Removing temporary files..."
+  image_name_base=`echo $image_name | sed 's/mhd//'`
+  case $1 in
+  1)
+    #rm $mask_dir_tmp/float_$image_name_base*
+    ;;
+  2)
+    #rm $mask_dir_tmp/bones_$image_name_base*
+    ;;
+  3)
+    #rm $mask_dir_tmp/patient_only_$image_name_base*
+    ;;
+  esac
+}
+
+mm_preprocessing()
+{
+  extract_patient
+  extract_bones
+  extract_lungs
+  remove_tmp_masks 1
+  resample
+}
+
+mm_postprocessing()
+{
+  remove_tmp_masks 2
+  set_background
+  remove_tmp_masks 3
+  create_registration_masks
+}
+
+mm_workflow()
+{
+  extract_patient
+  extract_bones
+  remove_tmp_masks 1
+  resample
+  echo "$image_name -> Computing motion mask..."
+  compute_motion_mask >> $mask_log_dir/motion_mask_$image_name.log
+  remove_tmp_masks 2
+  set_background
+  remove_tmp_masks 3
+  create_registration_masks
+}
+
+motion_mask()
+{
+  #set cmd line variables
+  echo "4D CT -> "$1
+  phases=`grep ".raw" $1`
+  echo "mask phases -> " $phases
+
+  dir=`dirname $1`
+  cd $dir
+
+  # import variables specific to each patient
+  source variables
+
+  resample_spacing=$2
+  resample_algo=$3
+
+    
+  #set other global variables
+  mask_dir="MASK-$resample_spacing""mm""-$resample_algo"
+  mask_dir_tmp="tmp."$mask_dir
+
+  echo
+  echo "------------ Motion mask from create_midP_masks.sh ------------"
+  start=`date`
+  echo "start: $start"
+  echo
+
+  # the motion masks are first created in a tmp directory. this directory is 
+  # later going to be renamed to the final motion mask directory. concurrent
+  # executions trying to create the same set of masks will be blocked until
+  # the first execution finishes. naturally, these other executions will not
+  # recreate the masks. so first we try to create the tmp directory. 
+  # if the creation fails, it means that another execution is
+  # already creating the masks, so this execution will be blocked. the
+  # execution is unblocked only when the creation of masks is finished and
+  # the mask directory is renamed.
+  #
+  # ATTENTION: RP - 08/02/2011
+  # robustness issue: tmp directory may exist but may be empty or 
+  # incomplete. the solution is to check per file, but I'll leave it like 
+  # this for the moment.
+  do_mm=0
+  if [ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]; then
+    mkdir $mask_dir_tmp 2> /dev/null
+    return_mkdir=$?
+    if [ $return_mkdir == 0 ]; then
+      do_mm=1 
+    else
+      while [[ $(ls -d $mask_dir 2> /dev/null | wc -l) -eq 0 ]]; do
+        echo "waiting creation of motion masks..."
+        sleep 2
+      done
+      echo "finished waiting"
+    fi  
+  fi
+
+  regmask_in_list=""
+  regmask_out_list=""
+  reg_in_list=""
+  reg_out_list=""
+
+  # multi-threaded pre-processing for motion mask calcs
+  if [ $do_mm == 1 ]; then
+    mask_log_dir=$mask_dir_tmp/LOG
+    mkdir -p $mask_log_dir
+
+    for phase in $phases
+    do
+      image_name=`echo $phase | sed 's/raw/mhd/'`
+      afdb_name=`echo $phase | sed 's/raw/afdb/'`
+      check_threads $MAX_THREADS
+      mm_preprocessing &
+    done
+
+    # single-threaded motion mask calc
+    for phase in $phases
+    do
+      image_name=`echo $phase | sed 's/raw/mhd/'`
+
+      check_threads 1
+      echo "$image_name -> Computing motion mask..."
+      compute_motion_mask >> $mask_log_dir/motion_mask_$image_name.log
+    done
+  fi
+
+  # multi-threaded post-processing of motion mask calcs
+  for phase in $phases
+  do
+    image_name=`echo $phase | sed 's/raw/mhd/'`
+    if [ $do_mm = 1 ]; then
+      check_threads $MAX_THREADS 
+      mm_postprocessing &
+    fi
+
+    regmask_in_list="$regmask_in_list regmask_in_$image_name"
+    regmask_out_list="$regmask_out_list regmask_out_$image_name"
+    reg_in_list="$reg_in_list inside_$image_name"
+    reg_out_list="$reg_out_list outside_$image_name"
+  done
+
+  # rename tmp mask directory after mask creation
+  check_threads 1
+  mv $mask_dir_tmp $mask_dir
+
+  wait
+
+  echo
+  echo "-------- Motion mask done ! ---------"
+  end=`date`
+  echo "start: $start"
+  echo "end: $end"
+  echo
+}
+
+
+#################
+# main  #
+#################
+
+if [ $# != 3 ]; then
+  echo "Usage: create_midP_masks.sh 4D_CT.mhd resample_spacing resample_algorithm"
+  exit -1
+fi
+
+#
+# variables exported in this scope
+#
+# mask_dir: directory where all masks are kept
+# regmask_in_list: list of registration mask files (inside lungs)
+# regmask_out_list: list of registration mask files (outised lungs)
+# reg_in_list: list of registration image files (inside lungs)
+# reg_out_list: list of registration image files (outside lungs)
+#
+
+if [ $1 != "using-as-lib" ]; then
+  motion_mask $1 $2 $3
+fi
similarity index 91%
rename from vv/scripts/create_sequence.sh
rename to scripts/create_sequence.sh
index 73ff9a6aacdd21cd1815080422c59e25a0fdd526..339d3519612da79883bcab6b9e20b4d713a9f856 100755 (executable)
@@ -12,4 +12,4 @@ do
     find "$i" -iname "*.dcm" | clitkDicom2Image --focal_origin -o "$filename" --std_input
 done
 
-create_mhd_4D.sh . "CT_4D.mhd"
+create_mhd_4D.sh .
diff --git a/scripts/midp_common.sh b/scripts/midp_common.sh
new file mode 100755 (executable)
index 0000000..0f76707
--- /dev/null
@@ -0,0 +1,110 @@
+#! /bin/sh +x
+
+###############################################################################
+#
+# FILE: midp_common.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Helper file with many functions used in the midP scripts.
+#
+###############################################################################
+
+
+# block execution untill the number of threads (jobs) launched by the
+# current process is below the given number of threads. 
+MAX_THREADS=2
+check_threads()
+{
+  nbth=$1
+  while [[ $(jobs -p | wc -l) -ge $nbth ]]; do
+      jobs
+      sleep 10
+  done
+}
+
+#
+# receive a 4D file and and extract the corresponding phase numbers
+# export the variables containing each of the extracted data
+#
+extract_4d_phase_numbers()
+{
+  mhd4d=$1
+
+  nb_phases=${#phase_files[@]}
+
+  # get everything except numbers and punctuation
+  cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[^0-9[:punct:]]*" | sort -u > /tmp/patterns.txt
+
+  # find which patterns have the phases connected to it
+  patterns=`cat /tmp/patterns.txt`
+  if [ -z "$patterns" ]; then
+    phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep "[0-9]\+"` )
+  else
+    for i in $patterns; do 
+
+      # check if the pattern appears before the phase number
+      nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | sort -u | wc -l`
+      if [ $nb_phases_found == $nb_phases ]; then
+        # keep only what identifies the phase number
+        phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` ) 
+        break
+      fi
+    
+      # check if the pattern appears after the phase number
+      nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | sort -u | wc -l`
+      if [ $nb_phases_found == $nb_phases ]; then
+        # keep only what identifies the phase number
+        phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` ) 
+        break
+      fi
+
+    done
+  fi
+
+  echo "Phase numbers are ${phase_nbs[@]}"
+  rm /tmp/patterns.txt
+}
+
+#
+# receive a 4D file and extract the corresponding phase files, 
+# and phase numbers.
+# export the variables containing each of the extracted data
+#
+extract_4d_phases()
+{
+  mhd4d=$1
+
+  echo "4D file is $mhd4d"
+
+  # array of phase files
+  phase_files=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:'` )
+  echo "Phase files are ${phase_files[@]}"
+
+  extract_4d_phase_numbers $mhd4d 
+}
+
+
+#
+# receive a 4D file and the reference phase number as input 
+# and extract the corresponding phase files, phase numbers, 
+# and reference phase file. 
+#
+# export the variables containing each of the extracted data
+#
+extract_4d_phases_ref()
+{
+  extract_4d_phases $1
+
+  # reference phase file
+  ref_phase_file=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | grep $2`
+  echo "Reference phase is $ref_phase_file"
+
+  # reference phase number
+  for i in $( seq 0 $((${#phase_nbs[@]} - 1))); do
+    ref_phase_nb=`echo ${phase_nbs[$i]} | grep $2`
+    if [ -n "$ref_phase_nb" ]; then
+      echo "Reference phase number is $ref_phase_nb"
+      break
+    fi
+  done
+}
diff --git a/scripts/midp_template.conf b/scripts/midp_template.conf
new file mode 100644 (file)
index 0000000..8fde2c8
--- /dev/null
@@ -0,0 +1,67 @@
+###############################################################################
+#
+# FILE: midp_template.conf
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Template configuration file for create_midP-2.0.sh. Values between <> must be
+# changed according to the methods.
+#
+###############################################################################
+
+# output directories
+vf_dir="<VFDIR>"
+midp_dir="<MIDPDIR>"
+output_dir="<OUTDIR>"
+log_dir="<LOGDIR>"
+
+# script step to be executed (mask, registration, midp, all)
+# midp depends on registration, which depends on mask
+step="all"
+
+# mask parameters
+#
+# interpolation algorithm for resampling (see clitkResampleImage)
+mask_interpolation_algorithm="<MASK_INTERPOLATION_ALGORITHM>"
+# interpolation spacing (in mm)
+mask_interpolation_spacing=<MASK_INTERPOLATION_SPACING>
+
+# registration method (blut, elastix)
+method="<METHOD>"
+
+# registration parameters (depend on registration method - see descriptions)
+#
+
+# b-spline spacing (blut, elastix)
+bspline_spacing=<BSPLINE_SPACING>
+
+# multi-resolution levels
+nb_levels=<NB_LEVELS>
+
+# number of histogram bins (blut, elastix)
+nb_hist_bins=<NB_HIST_BINS>
+
+# number of points (samples) to calculate metric
+# (blut: percentage of image size; elastix: absolute number)
+nb_samples=<NBSAMPLES>
+
+# algorithm used to sample points for the metric
+# (elastix: see docs)
+sampling_algo="<SAMPLING_ALGO>"
+
+# number of iterations (blut, elastix)
+nb_iter=<NB_ITER>
+
+# tolerance (stop condition for the metric) (blut)
+tolerance=<TOLERANCE>
+
+# metric used in the registration
+# (blut: see clitkBLUTDIR; elastix: see docs)
+metric="<METRIC>"
+
+# interpolation type
+# (blut: see clitkBLUTDIR; elastix: see docs)
+interpolator="<INTERPOLATOR>"
+
+# optmizer
+# (blut: see clitkBLUTDIR; elastix: see docs)
+optimizer="<OPTIMIZER>"
diff --git a/scripts/pts_to_landmarks.sh b/scripts/pts_to_landmarks.sh
new file mode 100755 (executable)
index 0000000..87bc9ee
--- /dev/null
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+###############################################################################
+#
+# FILE: pts_to_landmarks
+# AUTHOR: Vivien Delmon
+#
+# Conversion from landmarks in the format used in clitkCalculateTRE (.pts) 
+# to the format used in VV (.txt).
+#
+###############################################################################
+
+if [ $# -ne 2 ]; then
+  echo "Usage: $0 input.pts output.txt" 1>&2
+fi
+
+to_append=/tmp/$RANDOM
+to_prepend=/tmp/$RANDOM
+
+for i in $(seq 0 $((`cat $1 | wc -l` - 1)));
+do
+  echo 0' '0 >> $to_append
+  echo $i >> $to_prepend
+done
+
+echo "LANDMARKS1" > $2
+paste -d ' ' $to_prepend $1 $to_append >> $2
diff --git a/scripts/registration.sh b/scripts/registration.sh
new file mode 100755 (executable)
index 0000000..40d5fbe
--- /dev/null
@@ -0,0 +1,124 @@
+#! /bin/sh
+
+###############################################################################
+#
+# FILE: registration.sh
+# AUTHOR: Rômulo Pinho 05/08/2011
+#
+# Helper file with registration functions using different methods.
+# Each function receives a set of parameters that overall apply to any
+# registration algorithm, as follows:
+# 
+# reference=$1 : reference (fixed) image
+# target=$2 : target (moving) image
+# mask_ref=$3 : mask for the reference image
+# mask_targ=$4 : mask for the moving image
+# vf=$5 : output vector field representing the registration
+# result=$6 : result image after applying the vector field
+# nb_iter=$7 : maximum number of iterations
+# nb_samples=$8 : number of image samples used in the metric calulcation
+# sampling_algo=$9 : algorithm used in the selection of image samples
+# hist_bins=${10} : number of histogram bins used in the metric calculation
+# nb_levels=${11} : number of image resolutions
+# spacing=${12} : spacing of the b-spline grid of the fines resolution
+# metric=${13} : metric algorithm
+# optimizer=${14} : optimizer
+# interpolator=${15} : image interpolator 
+# log=${16} : log file
+#
+# New registration functions may be added to this file at any moment, 
+# respecting the interface defined above.
+#
+###############################################################################
+
+
+################# BLUTDIR #####################
+registration_blutdir()
+{
+  reference=$1
+  target=$2
+  mask_ref=$3
+  mask_targ=$4
+  vf=$5
+  result=$6
+  nb_iter=$7
+  nb_samples=$8
+  sampling_algo=$9
+  hist_bins=${10}
+  nb_levels=${11}
+  spacing=${12}
+  metric=${13}
+  optimizer=${14}
+  interpolator=${15}
+  log=${16}
+
+  echo "Computing BLUTDIR $reference -> $target ..."
+  blutdir_params="--levels $nb_levels  --metric $metric --optimizer $optimizer --samples $nb_samples --spacing $spacing,$spacing,$spacing --bins $hist_bins --maxIt $nb_iter --interp $interpolator --verbose"
+  cmd="clitkBLUTDIR -r $reference -t $target -m $mask_ref --targetMask $mask_targ --vf $vf -o $result $blutdir_params"
+  $cmd > $log
+}
+
+################# ELASTIX #####################
+registration_elastix()
+{
+  reference=$1
+  target=$2
+  mask_ref=$3
+  mask_targ=$4
+  vf=$5
+  result=$6
+  nb_iter=$7
+  nb_samples=$8
+  sampling_algo=$9
+  hist_bins=${10}
+  nb_levels=${11}
+  spacing=${12}
+  metric=${13}
+  optimizer=${14}
+  interpolator=${15}
+  
+  ########## register in ##########
+  for reg_in in $reg_in_list
+  do
+    if [ ! -z `echo $reg_in | grep "_$phase"` ]
+    then
+      target_in=$reg_in
+    fi
+  done
+  echo "Computing ELASTIX $reference -> $target ..."
+  exec_dir=`which elastix`
+  exec_dir=`dirname $exec_dir`
+  suffix=${nb_samples}_${nb_iter}_${nb_levels}
+  cat $exec_dir/params_BSpline.txt | sed -e "s+<NbIterations>+$nb_iter+" \
+                              -e "s+<LabelsFile>++" \
+                              -e "s+<HistBins>+$hist_bins+" \
+                              -e "s+<Levels>+$nb_levels+" \
+                              -e "s+<NbSamples>+$nb_samples+" \
+                              -e "s+<SamplerType>+$sampling_algo+" \
+                              -e "s+<Spacing>+$spacing+" > params_BSpline_${suffix}.txt 
+
+  vf_dir=`dirname $vf`
+  vf_base=`basename $vf .mhd`
+  result_dir=`dirname $result`
+  result_base=`basename $result .mhd`
+
+  # image registration
+  cmd="elastix -f $reference -m $target -fMask $mask_ref -mMask $mask_targ -out $result_dir -p params_BSpline_${suffix}.txt"
+  $cmd  > /dev/null
+
+  # generate vector field
+  cmd="transformix -tp $result_dir/TransformParameters.0.txt -out $vf_dir -def all"
+  $cmd  > /dev/null
+
+  # post-processing
+  mv $vf_dir/deformationField.mhd $vf
+  mv $vf_dir/deformationField.raw `echo $vf | sed 's/mhd/raw/'`
+  sed -i "s+deformationField+$vf_base+" $vf
+
+  mv $result_dir/result.0.mhd $result
+  mv $result_dir/result.0.raw `echo $result | sed 's/mhd/raw/'`
+  sed -i "s+result.0+$result_base+" $result
+
+  mv $result_dir/elasitx.log $log
+  mv $result_dir/TransformParameters.0.txt $result_dir/${result_base}_TransformParameters.0.txt
+}
\ No newline at end of file
diff --git a/segmentation/.gitignore b/segmentation/.gitignore
deleted file mode 100644 (file)
index 294da9e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/clitkTestFilter.cxx
index ad4e11e85840f370578734729cc63ee37aa0df7b..0275336dea4a760edb663513ff8bef732858cd46 100644 (file)
@@ -20,72 +20,103 @@ IF(CLITK_BUILD_SEGMENTATION)
     WRAP_GGO(clitkConnectedComponentLabeling_GGO_C clitkConnectedComponentLabeling.ggo)
     ADD_EXECUTABLE(clitkConnectedComponentLabeling clitkConnectedComponentLabeling.cxx ${clitkConnectedComponentLabeling_GGO_C})
     TARGET_LINK_LIBRARIES(clitkConnectedComponentLabeling clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL clitkConnectedComponentLabeling)
 
     WRAP_GGO(clitkFillMask_GGO_C clitkFillMask.ggo)
     ADD_EXECUTABLE(clitkFillMask clitkFillMask.cxx ${clitkFillMask_GGO_C})
     TARGET_LINK_LIBRARIES(clitkFillMask clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkFillMask)
 
     ADD_EXECUTABLE(clitkExtractPatient clitkExtractPatient.cxx ${clitkExtractPatient_GGO_C})
     TARGET_LINK_LIBRARIES(clitkExtractPatient clitkCommon ${ITK_LIBRARIES} clitkSegmentationGgoLib)
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractPatient)
 
     ADD_EXECUTABLE(clitkExtractLung clitkExtractLung.cxx  ${clitkExtractLung_GGO_C})
     TARGET_LINK_LIBRARIES(clitkExtractLung clitkSegmentationGgoLib clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractLung)
 
     # WRAP_GGO(clitkExtractAirwaysTreeInfo_GGO_C clitkExtractAirwaysTreeInfo.ggo)
     # ADD_EXECUTABLE(clitkExtractAirwaysTreeInfo clitkExtractAirwaysTreeInfo.cxx ${clitkExtractAirwaysTreeInfo_GGO_C})
     # TARGET_LINK_LIBRARIES(clitkExtractAirwaysTreeInfo clitkSegmentationGgoLib clitkCommon ${ITK_LIBRARIES})
+    # SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractAirwaysTreeInfo)
 
     WRAP_GGO(clitkExtractBones_GGO_C clitkExtractBones.ggo)
     ADD_EXECUTABLE(clitkExtractBones clitkExtractBones.cxx ${clitkExtractBones_GGO_C})
     TARGET_LINK_LIBRARIES(clitkExtractBones clitkCommon ${ITK_LIBRARIES} clitkSegmentationGgoLib)
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractBones)
+
+    WRAP_GGO(clitkBool_GGO_C clitkBool.ggo)
+    ADD_EXECUTABLE(clitkBool clitkBool.cxx ${clitkBool_GGO_C})
+    TARGET_LINK_LIBRARIES(clitkBool clitkCommon ${ITK_LIBRARIES} clitkSegmentationGgoLib)
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkBool)
 
     WRAP_GGO(clitkExtractMediastinum_GGO_C clitkExtractMediastinum.ggo)
     ADD_EXECUTABLE(clitkExtractMediastinum clitkExtractMediastinum.cxx ${clitkExtractMediastinum_GGO_C})
     TARGET_LINK_LIBRARIES(clitkExtractMediastinum clitkCommon clitkSegmentationGgoLib ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractMediastinum)
+
+    WRAP_GGO(clitkExtractLymphStations_GGO_C clitkExtractLymphStations.ggo)
+    ADD_EXECUTABLE(clitkExtractLymphStations clitkExtractLymphStations.cxx clitkFilterWithAnatomicalFeatureDatabaseManagement.cxx ${clitkExtractLymphStations_GGO_C})
+    TARGET_LINK_LIBRARIES(clitkExtractLymphStations clitkSegmentationGgoLib clitkCommon vtkHybrid)
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractLymphStations)
 
-    # WRAP_GGO(clitkExtractLymphStations_GGO_C clitkExtractLymphStations.ggo)
-    # ADD_EXECUTABLE(clitkExtractLymphStations clitkExtractLymphStations.cxx clitkFilterWithAnatomicalFeatureDatabaseManagement.cxx ${clitkExtractLymphStations_GGO_C})
-    # TARGET_LINK_LIBRARIES(clitkExtractLymphStations clitkSegmentationGgoLib clitkCommon ITKIO ITKStatistics vtkHybrid)
+    WRAP_GGO(clitkExtractMediastinalVessels_GGO_C clitkExtractMediastinalVessels.ggo)
+    ADD_EXECUTABLE(clitkExtractMediastinalVessels clitkExtractMediastinalVessels.cxx clitkFilterWithAnatomicalFeatureDatabaseManagement.cxx ${clitkExtractMediastinalVessels_GGO_C})
+    TARGET_LINK_LIBRARIES(clitkExtractMediastinalVessels clitkSegmentationGgoLib clitkCommon vtkHybrid)
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkExtractMediastinalVessels)
 
     WRAP_GGO(clitkMorphoMath_GGO_C clitkMorphoMath.ggo)
     ADD_EXECUTABLE(clitkMorphoMath clitkMorphoMath.cxx ${clitkMorphoMath_GGO_C})
     TARGET_LINK_LIBRARIES(clitkMorphoMath clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkMorphoMath)
 
     WRAP_GGO(clitkMorphoReconstruction_GGO_C clitkMorphoReconstruction.ggo)
     ADD_EXECUTABLE(clitkMorphoReconstruction clitkMorphoReconstruction.cxx clitkMorphoReconstructionGenericFilter.cxx ${clitkMorphoReconstruction_GGO_C})
     TARGET_LINK_LIBRARIES(clitkMorphoReconstruction clitkSegmentationGgoLib clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkMorphoReconstruction)
 
     WRAP_GGO(clitkCalculateDistanceMap_GGO_C clitkCalculateDistanceMap.ggo)
     ADD_EXECUTABLE(clitkCalculateDistanceMap clitkCalculateDistanceMap.cxx clitkCalculateDistanceMapGenericFilter.cxx ${clitkCalculateDistanceMap_GGO_C})
     TARGET_LINK_LIBRARIES(clitkCalculateDistanceMap clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkCalculateDistanceMap)
 
     WRAP_GGO(clitkLevelSetSegmentation_GGO_C clitkLevelSetSegmentation.ggo)
     ADD_EXECUTABLE(clitkLevelSetSegmentation clitkLevelSetSegmentation.cxx clitkLevelSetSegmentationGenericFilter.cxx ${clitkLevelSetSegmentation_GGO_C})
     TARGET_LINK_LIBRARIES(clitkLevelSetSegmentation clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkLevelSetSegmentation)
 
     WRAP_GGO(clitkAnd_GGO_C clitkAnd.ggo)
     ADD_EXECUTABLE(clitkAnd clitkAnd.cxx clitkAndGenericFilter.cxx ${clitkAnd_GGO_C})
     TARGET_LINK_LIBRARIES(clitkAnd clitkCommon ${ITK_LIBRARIES} )
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkAnd)
 
     WRAP_GGO(clitkRegionGrowing_GGO_C clitkRegionGrowing.ggo)
     ADD_EXECUTABLE(clitkRegionGrowing clitkRegionGrowing.cxx clitkRegionGrowingGenericFilter.cxx ${clitkRegionGrowing_GGO_C})
     TARGET_LINK_LIBRARIES(clitkRegionGrowing clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkRegionGrowing)
 
     WRAP_GGO(clitkDecomposeAndReconstruct_GGO_C clitkDecomposeAndReconstruct.ggo)
     ADD_EXECUTABLE(clitkDecomposeAndReconstruct clitkDecomposeAndReconstruct.cxx clitkDecomposeAndReconstructGenericFilter.cxx ${clitkDecomposeAndReconstruct_GGO_C})
     TARGET_LINK_LIBRARIES(clitkDecomposeAndReconstruct clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkDecomposeAndReconstruct)
 
     WRAP_GGO(clitkMotionMask_GGO_C clitkMotionMask.ggo)
     ADD_EXECUTABLE(clitkMotionMask clitkMotionMask.cxx clitkMotionMaskGenericFilter.cxx ${clitkMotionMask_GGO_C})
     TARGET_LINK_LIBRARIES(clitkMotionMask clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkMotionMask)
 
     WRAP_GGO(clitkFillImageRegion_GGO_C clitkFillImageRegion.ggo)
     ADD_EXECUTABLE(clitkFillImageRegion clitkFillImageRegion.cxx clitkFillImageRegionGenericFilter.cxx ${clitkFillImageRegion_GGO_C})
     TARGET_LINK_LIBRARIES(clitkFillImageRegion clitkCommon ${ITK_LIBRARIES})
+    SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkFillImageRegion)
 
     # WRAP_GGO(clitkTestFilter_GGO_C clitkTestFilter.ggo)
     # ADD_EXECUTABLE(clitkTestFilter clitkTestFilter.cxx ${clitkTestFilter_GGO_C})
-    # TARGET_LINK_LIBRARIES(clitkTestFilter clitkSegmentationGgoLib clitkCommon vtkHybrid ITKIO)
+    # TARGET_LINK_LIBRARIES(clitkTestFilter clitkSegmentationGgoLib clitkCommon vtkHybrid)
+    # SET(SEGMENTATION_INSTALL ${TOOLS_INSTALL} clitkTestFilter)
+    
+    SET_TARGET_PROPERTIES(${SEGMENTATION_INSTALL} PROPERTIES INSTALL_RPATH "${VTK_DIR}:${ITK_DIR}" )  
+    INSTALL (TARGETS ${SEGMENTATION_INSTALL} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
 
 ENDIF(CLITK_BUILD_SEGMENTATION)
 
index 2537622a428588ad27aeba399c11b82e0de8444b..c86b2df07f7e4d056463861196589b9c7364ece0 100644 (file)
@@ -161,6 +161,7 @@ bool clitk::AnatomicalFeatureDatabase::TagExist(std::string tag)
 }
 //--------------------------------------------------------------------
 
+
 //-------------------------------------------------------------------- 
 void clitk::AnatomicalFeatureDatabase::SetDouble(std::string tag, double value)
 {
@@ -168,6 +169,7 @@ void clitk::AnatomicalFeatureDatabase::SetDouble(std::string tag, double value)
 }
 //-------------------------------------------------------------------- 
 
+
 //-------------------------------------------------------------------- 
 double clitk::AnatomicalFeatureDatabase::GetDouble(std::string tag)
 {
@@ -184,3 +186,13 @@ double clitk::AnatomicalFeatureDatabase::GetDouble(std::string tag)
   return a;  
 }
 //-------------------------------------------------------------------- 
+
+
+//-------------------------------------------------------------------- 
+void clitk::AnatomicalFeatureDatabase::RemoveTag(TagType tag)
+{
+  if (TagExist(tag)) {
+    m_MapOfTag.erase(m_MapOfTag.find(tag));
+  }
+}
+//-------------------------------------------------------------------- 
index 574bf682ff34d93e4640b12e54cb070d7966bd67..bd574d384fa3107f7bc5aea8628c65bc893574fd 100644 (file)
@@ -65,6 +65,9 @@ namespace clitk {
     // Set Get Double
     void SetDouble(TagType tag, double d);
     double GetDouble(TagType tag);
+    
+    // Remove Tag
+    void RemoveTag(TagType tag);
 
   protected:
     std::string m_Filename;
diff --git a/segmentation/clitkBool.cxx b/segmentation/clitkBool.cxx
new file mode 100644 (file)
index 0000000..dbb313c
--- /dev/null
@@ -0,0 +1,45 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+// clitk
+#include "clitkBool_ggo.h"
+#include "clitkBooleanOperatorLabelImageGenericFilter.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+
+  // Init command line
+  GGO(clitkBool, args_info);
+  CLITK_INIT;
+
+  // Filter
+  typedef clitk::BooleanOperatorLabelImageGenericFilter<args_info_clitkBool> FilterType;
+  FilterType::Pointer filter = FilterType::New();
+
+  filter->SetArgsInfo(args_info);
+  
+  try {
+    filter->Update();
+  } catch(std::runtime_error e) {
+    std::cout << e.what() << std::endl;
+  }
+
+  return EXIT_SUCCESS;
+} // This is the end, my friend
+//--------------------------------------------------------------------
diff --git a/segmentation/clitkBool.ggo b/segmentation/clitkBool.ggo
new file mode 100644 (file)
index 0000000..ede9646
--- /dev/null
@@ -0,0 +1,14 @@
+#File clitkExtractMediastinalVessels.ggo
+package "clitkExtractMediastinalVessels"
+version "1.0"
+purpose "Extract MediastinalVessels"
+
+option "config"                -  "Config file"                  string        no
+option "imagetypes"     -  "Display allowed image types"  flag          off
+option "verbose"        v  "Verbose"                     flag          off
+
+option "input"         i       "Input mask 1"               string     yes
+option "input2"        j       "Input mask 2"               string     yes
+option "output"        o       "Output filename"            string     yes
+
+option "type"          t       "Bool type : "               int default="1" no
diff --git a/segmentation/clitkBooleanOperatorLabelImageGenericFilter.h b/segmentation/clitkBooleanOperatorLabelImageGenericFilter.h
new file mode 100644 (file)
index 0000000..acd69ff
--- /dev/null
@@ -0,0 +1,80 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+#ifndef CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_H
+#define CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_H
+
+#include "clitkIO.h"
+#include "clitkImageToImageGenericFilter.h"
+#include "clitkBooleanOperatorLabelImageFilter.h"
+
+//--------------------------------------------------------------------
+namespace clitk 
+{
+  
+  template<class ArgsInfoType>
+  class ITK_EXPORT BooleanOperatorLabelImageGenericFilter: 
+    public ImageToImageGenericFilter<BooleanOperatorLabelImageGenericFilter<ArgsInfoType> >
+  {
+    
+  public:
+    //--------------------------------------------------------------------
+    BooleanOperatorLabelImageGenericFilter();
+
+    //--------------------------------------------------------------------
+    typedef ImageToImageGenericFilter<BooleanOperatorLabelImageGenericFilter<ArgsInfoType> > Superclass;
+    typedef BooleanOperatorLabelImageGenericFilter Self;
+    typedef itk::SmartPointer<Self>           Pointer;
+    typedef itk::SmartPointer<const Self>     ConstPointer;
+
+    //--------------------------------------------------------------------
+    itkNewMacro(Self);  
+    itkTypeMacro(BooleanOperatorLabelImageGenericFilter, LightObject);
+
+    //--------------------------------------------------------------------
+    // Options for the GenericFilter
+    void SetArgsInfo(const ArgsInfoType & a);
+
+    //--------------------------------------------------------------------
+    // Options for the Filter
+    template<class FilterType> 
+    void SetOptionsFromArgsInfoToFilter(FilterType * f) ;
+
+    //--------------------------------------------------------------------
+    // Main function called each time the filter is updated
+    template<class ImageType>  
+    void UpdateWithInputImageType();
+
+  protected:
+    template<unsigned int Dim> void InitializeImageType();
+    ArgsInfoType mArgsInfo;
+    
+  private:
+    BooleanOperatorLabelImageGenericFilter(const Self&); //purposely not implemented
+    void operator=(const Self&); //purposely not implemented
+    
+  }; // end class
+  //--------------------------------------------------------------------
+    
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkBooleanOperatorLabelImageGenericFilter.txx"
+#endif
+
+#endif // #define CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_H
diff --git a/segmentation/clitkBooleanOperatorLabelImageGenericFilter.txx b/segmentation/clitkBooleanOperatorLabelImageGenericFilter.txx
new file mode 100644 (file)
index 0000000..0c07b67
--- /dev/null
@@ -0,0 +1,104 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+#ifndef CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_TXX
+#define CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_TXX
+
+#include "clitkImageCommon.h"
+  
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::BooleanOperatorLabelImageGenericFilter():
+  ImageToImageGenericFilter<Self>("BooleanOperatorLabelImage") 
+{
+  // Default values
+  cmdline_parser_clitkBool_init(&mArgsInfo);
+  InitializeImageType<3>(); // Only for 3D images
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<unsigned int Dim>
+void clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::InitializeImageType() 
+{  
+  ADD_IMAGE_TYPE(Dim, uchar); // Can add float later
+}
+//--------------------------------------------------------------------
+  
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+void clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoType & a) 
+{
+  mArgsInfo=a;
+  SetIOVerbose(mArgsInfo.verbose_flag);
+  if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
+  if (mArgsInfo.input_given) AddInputFilename(mArgsInfo.input_arg);
+  if (mArgsInfo.input2_given) AddInputFilename(mArgsInfo.input2_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void 
+clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f)
+{
+  // Operation type
+  f->SetOperationType(typename FilterType::OperationTypeEnumeration(mArgsInfo.type_arg));
+  // Output filename
+  this->AddOutputFilename(mArgsInfo.output_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class ImageType>
+void clitk::BooleanOperatorLabelImageGenericFilter<ArgsInfoType>::UpdateWithInputImageType() 
+{ 
+  // Reading input
+  typename ImageType::Pointer input1 = this->template GetInput<ImageType>(0);
+  typename ImageType::Pointer input2 = this->template GetInput<ImageType>(1);
+
+  // Create filter
+  typedef clitk::BooleanOperatorLabelImageFilter<ImageType> FilterType;
+  typename FilterType::Pointer filter = FilterType::New();
+    
+  // Set global Options 
+  filter->SetInput1(input1);
+  filter->SetInput2(input2);
+  SetOptionsFromArgsInfoToFilter<FilterType>(filter);
+
+  // Go !
+  filter->Update();
+
+  // Write/Save results
+  typename ImageType::Pointer output = filter->GetOutput();
+  this->template SetNextOutput<ImageType>(output); 
+}
+//--------------------------------------------------------------------
+
+#endif //#define CLITKBOOLEANOPERATORLABELIMAGEGENERICFILTER_TXX
diff --git a/segmentation/clitkDecomposeAndReconstructImageFilter.h b/segmentation/clitkDecomposeAndReconstructImageFilter.h
deleted file mode 100644 (file)
index 3cc9ee0..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to: 
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkDecomposeAndReconstructImageFilter_h
-#define clitkDecomposeAndReconstructImageFilter_h
-
-/* =================================================
- * @file   clitkDecomposeAndReconstructImageFilter.h
- * @author 
- * @date   
- * 
- * @brief 
- * 
- ===================================================*/
-
-
-// clitk include
-#include "clitkIO.h"
-#include "clitkCommon.h"
-#include "clitkDecomposeThroughErosionImageFilter.h"
-#include "clitkReconstructThroughDilationImageFilter.h"
-
-//itk include
-#include "itkImageToImageFilter.h"
-#include "itkRelabelComponentImageFilter.h"
-
-
-namespace clitk 
-{
-
-  template <class InputImageType, class OutputImageType>
-  class ITK_EXPORT DecomposeAndReconstructImageFilter :
-    public itk::ImageToImageFilter<InputImageType, OutputImageType>
-  {
-  public:
-    //----------------------------------------
-    // ITK
-    //----------------------------------------
-    typedef DecomposeAndReconstructImageFilter                                                 Self;
-    typedef itk::ImageToImageFilter<InputImageType, OutputImageType>  Superclass;
-    typedef itk::SmartPointer<Self>                                   Pointer;
-    typedef itk::SmartPointer<const Self>                             ConstPointer;
-   
-    // Method for creation through the object factory
-    itkNewMacro(Self);  
-
-    // Run-time type information (and related methods)
-    itkTypeMacro( DecomposeAndReconstructImageFilter, ImageToImageFilter );
-
-    /** Dimension of the domain space. */
-    itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
-    itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
-
-    //----------------------------------------
-    // Typedefs
-    //----------------------------------------
-    typedef typename OutputImageType::RegionType OutputImageRegionType;
-    typedef int InternalPixelType;
-    typedef typename InputImageType::PixelType InputPixelType;
-    typedef typename OutputImageType::PixelType OutputPixelType;
-    typedef typename InputImageType::SizeType SizeType;
-
-
-    //----------------------------------------
-    // Set & Get
-    //----------------------------------------    
-    itkBooleanMacro(Verbose);
-    itkSetMacro( Verbose, bool);
-    itkGetConstReferenceMacro( Verbose, bool);
-    itkBooleanMacro(FullyConnected);
-    itkSetMacro( FullyConnected, bool);
-    itkGetConstReferenceMacro( FullyConnected, bool);
-    void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
-    SizeType GetRadius(void){return m_Radius;}
-    itkSetMacro( MaximumNumberOfLabels, unsigned int);
-    itkGetConstMacro( MaximumNumberOfLabels, unsigned int);
-    itkSetMacro( BackgroundValue, InternalPixelType);
-    itkGetConstMacro( BackgroundValue, InternalPixelType);
-    itkSetMacro( ForegroundValue, InternalPixelType);
-    itkGetConstMacro( ForegroundValue, InternalPixelType);
-    itkSetMacro( NumberOfNewLabels, unsigned int);
-    itkGetConstMacro( NumberOfNewLabels, unsigned int);
-    itkSetMacro( MinimumObjectSize, unsigned int);
-    itkGetConstMacro( MinimumObjectSize, unsigned int);
-    itkSetMacro( MinimumNumberOfIterations, unsigned int);
-    itkGetConstMacro( MinimumNumberOfIterations, unsigned int);
-    //     // Convenience macro's: Built-in
-    //     itkBooleanMacro (flag); //FlagOn FlagOff
-    //     itkGetMacro(name, type);
-    //     itkSetMacro(name, type);
-    //     itkSetConstMacro( name, type);
-    //     itkGetConstMacro( name, type);
-    //     itkSetConstReferenceMacro(name, type);
-    //     itkGetConstReferenceMacro(name, type);
-    //     // Convenience macro's: Smartpointers
-    //     itkSetObjectMacro(name, type); 
-    //     itkGetObjectMacro(name, type); 
-    //     itkSetConstObjectMacro(name, type); 
-    //     itkGetConstObjectMacro(name, type); 
-    //     itkSetConstReferenceObjectMacro(name, type); 
-    //     itkSetConstReference(name, type);
-    
-
-  protected:
-
-    //----------------------------------------  
-    // Constructor & Destructor
-    //----------------------------------------  
-    DecomposeAndReconstructImageFilter();
-    ~DecomposeAndReconstructImageFilter() {};
-
-    //----------------------------------------  
-    // Update
-    //----------------------------------------  
-    // Generate Data
-    void GenerateData(void);
-
-    //     // Threaded Generate Data
-    //     void BeforeThreadedGenerateData(void );
-    //     void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
-    //     void AfterThreadedGenerateData(void );
-    //     // Override defaults
-    //     virtual void GenerateInputRequestedRegion();
-    //     virtual void GenerateOutputInformation (void);
-    //     virtual void EnlargeOutputRequestedRegion(DataObject *data);
-    void AllocateOutputs(){;}
-    //----------------------------------------  
-    // Data members
-    //----------------------------------------
-    bool m_Verbose;
-    SizeType m_Radius;
-    unsigned int m_NumberOfNewLabels;
-    bool m_FullyConnected;
-    InputPixelType m_BackgroundValue;
-    InputPixelType m_ForegroundValue;
-    unsigned int  m_MaximumNumberOfLabels;
-    unsigned int m_MinimumObjectSize;
-    unsigned int m_MinimumNumberOfIterations;
-  };
-
-
-} // end namespace clitk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkDecomposeAndReconstructImageFilter.txx"
-#endif
-
-#endif // #define clitkDecomposeAndReconstructImageFilter_h
-
-
diff --git a/segmentation/clitkDecomposeAndReconstructImageFilter.txx b/segmentation/clitkDecomposeAndReconstructImageFilter.txx
deleted file mode 100644 (file)
index f21b56d..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to: 
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkDecomposeAndReconstructImageFilter_txx
-#define clitkDecomposeAndReconstructImageFilter_txx
-
-namespace clitk
-{
-
-  //-------------------------------------------------------------------
-  // Update with the number of dimensions
-  //-------------------------------------------------------------------
-  template<class InputImageType, class OutputImageType>
-  DecomposeAndReconstructImageFilter<InputImageType, OutputImageType>::DecomposeAndReconstructImageFilter()
-  {
-   m_Verbose=false;
-   for (unsigned int i=0; i<InputImageDimension; i++)
-     m_Radius[i]=1;
-   m_NumberOfNewLabels=1;
-   m_FullyConnected=true;
-   m_BackgroundValue=0;
-   m_ForegroundValue=1;
-   m_MaximumNumberOfLabels=10;
-   m_MinimumObjectSize=10;
-   m_MinimumNumberOfIterations=1;
-
-  }
-
-
-  //-------------------------------------------------------------------
-  // Update with the number of dimensions and the pixeltype
-  //-------------------------------------------------------------------
-  template <class InputImageType, class  OutputImageType> 
-  void 
-  DecomposeAndReconstructImageFilter<InputImageType, OutputImageType>::GenerateData()
-  {
-
-
-    // Internal type
-    typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
-
-    // Filters used
-    typedef clitk::DecomposeThroughErosionImageFilter<InputImageType, InternalImageType> DecomposeThroughErosionImageFilterType;
-    typedef clitk::ReconstructThroughDilationImageFilter<InternalImageType, InputImageType> ReconstructThroughDilationImageFilterType;
-
-    // Erode 
-    typename DecomposeThroughErosionImageFilterType::Pointer erosionFilter=DecomposeThroughErosionImageFilterType::New();
-    erosionFilter->SetInput(this->GetInput());
-    erosionFilter->SetVerbose(m_Verbose);
-    erosionFilter->SetFullyConnected(m_FullyConnected);
-    erosionFilter->SetRadius(m_Radius);
-    erosionFilter->SetNumberOfNewLabels(m_NumberOfNewLabels);
-    erosionFilter->SetMinimumObjectSize(m_MinimumObjectSize);
-    erosionFilter->SetMinimumNumberOfIterations(m_MinimumNumberOfIterations);
-    erosionFilter->Update();
-
-    // Reconstruct
-    typename ReconstructThroughDilationImageFilterType::Pointer reconstructionFilter =ReconstructThroughDilationImageFilterType::New();
-    reconstructionFilter->SetInput(erosionFilter->GetOutput());
-    reconstructionFilter->SetVerbose(m_Verbose);
-    reconstructionFilter->SetRadius(m_Radius);
-    reconstructionFilter->SetMaximumNumberOfLabels(m_MaximumNumberOfLabels);
-    reconstructionFilter->SetBackgroundValue(m_BackgroundValue);
-    reconstructionFilter->SetForegroundValue(m_ForegroundValue);
-    reconstructionFilter->Update();
-    
-    // Output
-    this->SetNthOutput(0,reconstructionFilter->GetOutput());
-  }
-
-
-}//end clitk
-#endif //#define clitkDecomposeAndReconstructImageFilter_txx
diff --git a/segmentation/clitkDecomposeThroughErosionImageFilter.h b/segmentation/clitkDecomposeThroughErosionImageFilter.h
deleted file mode 100644 (file)
index 032a6c2..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to: 
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkDecomposeThroughErosionImageFilter_h
-#define clitkDecomposeThroughErosionImageFilter_h
-
-/* =================================================
- * @file   clitkDecomposeThroughErosionImageFilter.h
- * @author 
- * @date   
- * 
- * @brief 
- * 
- ===================================================*/
-
-
-// clitk include
-#include "clitkIO.h"
-#include "clitkCommon.h"
-#include "clitkSetBackgroundImageFilter.h"
-
-//itk include
-#include "itkImageToImageFilter.h"
-#include "itkBinaryThresholdImageFilter.h"
-#include "itkBinaryErodeImageFilter.h"
-#include "itkStatisticsImageFilter.h"
-#include "itkConnectedComponentImageFilter.h"
-#include "itkCastImageFilter.h"
-#include "itkBinaryBallStructuringElement.h"
-#include "itkRelabelComponentImageFilter.h"
-
-namespace clitk 
-{
-
-  template <class InputImageType, class OutputImageType>
-  class ITK_EXPORT DecomposeThroughErosionImageFilter :
-    public itk::ImageToImageFilter<InputImageType, OutputImageType>
-  {
-  public:
-    //----------------------------------------
-    // ITK
-    //----------------------------------------
-    typedef DecomposeThroughErosionImageFilter                                                 Self;
-    typedef itk::ImageToImageFilter<InputImageType, OutputImageType>  Superclass;
-    typedef itk::SmartPointer<Self>                                   Pointer;
-    typedef itk::SmartPointer<const Self>                             ConstPointer;
-   
-    // Method for creation through the object factory
-    itkNewMacro(Self);  
-
-    // Run-time type information (and related methods)
-    itkTypeMacro( DecomposeThroughErosionImageFilter, ImageToImageFilter );
-
-    /** Dimension of the domain space. */
-    itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
-    itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
-
-    //----------------------------------------
-    // Typedefs
-    //----------------------------------------
-    typedef typename OutputImageType::RegionType OutputImageRegionType;
-    typedef int InternalPixelType;
-    typedef typename InputImageType::PixelType InputPixelType;
-    typedef typename OutputImageType::PixelType OutputPixelType;
-    typedef typename InputImageType::SizeType SizeType;
-
-    //----------------------------------------
-    // Set & Get
-    //----------------------------------------    
-    itkBooleanMacro(Verbose);
-    itkSetMacro( Verbose, bool);
-    itkGetConstReferenceMacro( Verbose, bool);
-    itkBooleanMacro(FullyConnected);
-    itkSetMacro( FullyConnected, bool);
-    itkGetConstReferenceMacro( FullyConnected, bool);
-    itkSetMacro( Lower, InputPixelType);
-    itkGetConstMacro( Lower, InputPixelType);
-    itkSetMacro( Upper, InputPixelType);
-    itkGetConstMacro( Upper, InputPixelType);
-    itkSetMacro( Inside, InternalPixelType);
-    itkGetConstMacro( Inside, InternalPixelType);  
-    itkSetMacro( Outside, InternalPixelType);
-    itkGetConstMacro( Outside, InternalPixelType);  
-    itkSetMacro( ErosionPaddingValue, OutputPixelType);
-    itkGetConstMacro( ErosionPaddingValue, OutputPixelType);  
-    void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
-    SizeType GetRadius(void){return m_Radius;}
-    itkSetMacro( NumberOfNewLabels, unsigned int);
-    itkGetConstMacro( NumberOfNewLabels, unsigned int);
-    itkSetMacro( MinimumObjectSize, unsigned int);
-    itkGetConstMacro( MinimumObjectSize, unsigned int);
-    itkSetMacro( MinimumNumberOfIterations, unsigned int);
-    itkGetConstMacro( MinimumNumberOfIterations, unsigned int);
-
-  protected:
-
-    //----------------------------------------  
-    // Constructor & Destructor
-    //----------------------------------------  
-    DecomposeThroughErosionImageFilter();
-    ~DecomposeThroughErosionImageFilter() {};
-
-    //----------------------------------------  
-    // Update
-    //----------------------------------------  
-    // Generate Data
-    void GenerateData(void);
-    void AllocateOutput(){;}
-
-    //     // Threaded Generate Data
-    //     void BeforeThreadedGenerateData(void );
-    //     void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
-    //     void AfterThreadedGenerateData(void );
-    //     // Override defaults
-    //     virtual void GenerateInputRequestedRegion();
-    //     virtual void GenerateOutputInformation (void);
-    //     virtual void EnlargeOutputRequestedRegion(DataObject *data);
-    //     void AllocateOutputs();
-    //----------------------------------------  
-    // Data members
-    //----------------------------------------
-    bool m_Verbose;
-    bool m_FullyConnected;
-    InputPixelType m_Lower;
-    InputPixelType m_Upper;
-    OutputPixelType m_ErosionPaddingValue;
-    InputPixelType m_Inside;
-    InputPixelType m_Outside;
-    SizeType m_Radius;
-    unsigned int m_NumberOfNewLabels;
-    unsigned int m_MinimumObjectSize;
-    unsigned int m_MinimumNumberOfIterations;
-
-  };
-
-
-} // end namespace clitk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkDecomposeThroughErosionImageFilter.txx"
-#endif
-
-#endif // #define clitkDecomposeThroughErosionImageFilter_h
-
-
diff --git a/segmentation/clitkDecomposeThroughErosionImageFilter.txx b/segmentation/clitkDecomposeThroughErosionImageFilter.txx
deleted file mode 100644 (file)
index 6a7ffbc..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to: 
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkDecomposeThroughErosionImageFilter_txx
-#define clitkDecomposeThroughErosionImageFilter_txx
-
-/* =================================================
- * @file   clitkDecomposeThroughErosionImageFilter.txx
- * @author 
- * @date   
- * 
- * @brief 
- * 
- ===================================================*/
-
-
-namespace clitk
-{
-
-  //-------------------------------------------------------------------
-  // Update with the number of dimensions
-  //-------------------------------------------------------------------
-  template<class InputImageType, class OutputImageType>
-  DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::DecomposeThroughErosionImageFilter()
-  {
-   m_Verbose=false;
-   m_Lower =1;
-   m_Upper=1;
-   m_Inside=1;
-   m_Outside=0;
-   m_ErosionPaddingValue=static_cast<OutputPixelType>(-1);
-   for (unsigned int i=0; i<InputImageDimension; i++)
-     m_Radius[i]=1;
-   m_NumberOfNewLabels=1;
-   m_FullyConnected=true;
-   m_MinimumObjectSize=10;
-   m_MinimumNumberOfIterations=1;
-  }
-
-
-  //-------------------------------------------------------------------
-  // Update with the number of dimensions and the pixeltype
-  //-------------------------------------------------------------------
-  template<class InputImageType, class  OutputImageType> 
-  void 
-  DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::GenerateData()
-  {
-
-    //---------------------------------
-    // Typedefs 
-    //--------------------------------- 
-
-    // Internal type
-    typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
-
-    // Filters used
-    typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinaryThresholdImageFilter;
-    typedef itk::BinaryBallStructuringElement<InputPixelType,InputImageDimension > KernelType;
-    typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> BinaryErodeImageFilterType;
-    typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> BinaryThresholdImageFilterType;
-    typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
-    typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
-    typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelImageFilterType;
-    typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
-  
-    //---------------------------------
-    // Binarize input
-    //--------------------------------- 
-    typename  InputBinaryThresholdImageFilter::Pointer inputBinarizer=InputBinaryThresholdImageFilter::New();
-    inputBinarizer->SetInput(this->GetInput());
-    inputBinarizer->SetLowerThreshold(m_Lower);
-    inputBinarizer->SetUpperThreshold(m_Upper);
-    inputBinarizer ->SetInsideValue(m_Inside);
-    inputBinarizer ->SetOutsideValue(m_Outside);
-    if(m_Verbose) std::cout<<"Binarizing the input..."<<std::endl;
-    inputBinarizer->Update();
-    //---------------------------------
-    // Label the input
-    //---------------------------------
-    typename ConnectFilterType::Pointer inputConnectFilter=ConnectFilterType::New();
-    inputConnectFilter->SetInput(inputBinarizer->GetOutput());
-    inputConnectFilter->SetBackgroundValue(0);
-    inputConnectFilter->SetFullyConnected(m_FullyConnected);
-    if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
-    //   inputConnectFilter->Update();
-    //---------------------------------
-    // Count the initial labels
-    //---------------------------------
-    typename StatisticsImageFilterType::Pointer inputStatisticsImageFilter=StatisticsImageFilterType::New();
-    inputStatisticsImageFilter->SetInput(inputConnectFilter->GetOutput());
-    if(m_Verbose) std::cout<<"Counting the initial labels..."<<std::endl;
-    inputStatisticsImageFilter->Update();
-    unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum();
-    if(m_Verbose) std::cout<<"The input contained "<<initialNumberOfLabels<<" disctictive label(s)..."<<std::endl;
-    if(m_Verbose) std::cout<<"Performing erosions till at least "<<initialNumberOfLabels+m_NumberOfNewLabels<<" distinctive labels are counted..."<<std::endl;
-    //---------------------------------
-    // Structuring element
-    //---------------------------------
-    KernelType structuringElement;
-    structuringElement.SetRadius(m_Radius);
-    structuringElement.CreateStructuringElement();
-
-    //---------------------------------
-    // Repeat while not decomposed
-    //---------------------------------
-    typename InternalImageType::Pointer current=inputBinarizer->GetOutput();
-    typename InternalImageType::Pointer output=inputBinarizer->GetOutput();
-    unsigned int iteration=0;
-    unsigned int max =initialNumberOfLabels;
-
-    while (  (iteration < m_MinimumNumberOfIterations) || ( (max< initialNumberOfLabels + m_NumberOfNewLabels ) && (iteration<100 ) ) )
-      {
-
-
-       if(m_Verbose) std::cout<<"Eroding image (iteration "<<iteration<<")..."<<std::endl;
-       
-       //---------------------------------
-       // Erode
-       //---------------------------------
-       typename BinaryErodeImageFilterType::Pointer erosionFilter=BinaryErodeImageFilterType::New();
-       erosionFilter->SetInput (current);
-       erosionFilter->SetForegroundValue (1);
-       erosionFilter->SetBackgroundValue (-1);
-       erosionFilter->SetBoundaryToForeground(false);
-       erosionFilter->SetKernel(structuringElement);
-       erosionFilter->Update();
-       current=erosionFilter->GetOutput();
-       
-       //---------------------------------
-       // Binarize (remove -1)
-       //--------------------------------- 
-       typename  BinaryThresholdImageFilterType::Pointer binarizer=BinaryThresholdImageFilterType::New();
-       binarizer->SetInput(erosionFilter->GetOutput());
-       binarizer->SetLowerThreshold(1);
-       binarizer->SetUpperThreshold(1);
-       binarizer ->SetInsideValue(1);
-       binarizer ->SetOutsideValue(0);
-       if(m_Verbose) std::cout<<"Binarizing the eroded image..."<<std::endl;
-       //binarizer->Update();
-
-       
-       //---------------------------------
-       // ReLabel the connected components
-       //---------------------------------
-       typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
-       connectFilter->SetInput(binarizer->GetOutput());
-       connectFilter->SetBackgroundValue(0);
-       connectFilter->SetFullyConnected(m_FullyConnected);
-       if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
-       //connectFilter->Update();
-               
-       //---------------------------------
-       // Sort
-       //---------------------------------
-       typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
-       relabelFilter->SetInput(connectFilter->GetOutput());
-       relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize);
-       //relabelFilter->Update();   
-       
-       
-       //---------------------------------
-       // Count the labels
-       //---------------------------------
-       typename StatisticsImageFilterType::Pointer statisticsImageFilter=StatisticsImageFilterType::New();
-       statisticsImageFilter->SetInput(relabelFilter->GetOutput());
-       statisticsImageFilter->Update();
-       max= statisticsImageFilter->GetMaximum();
-       if(m_Verbose) std::cout<<"Counted "<<max<<" label (s) larger then "<<m_MinimumObjectSize<<" voxels..."<<std::endl;
-       output=statisticsImageFilter->GetOutput();
-       
-       // Next iteration
-       iteration++;
-      }
-
-
-    //---------------------------------
-    // Binarize current (remove -1)
-    //--------------------------------- 
-    typename  BinaryThresholdImageFilterType::Pointer binarizer=BinaryThresholdImageFilterType::New();
-    binarizer->SetInput(current);
-    binarizer->SetLowerThreshold(1);
-    binarizer->SetUpperThreshold(1);
-    binarizer ->SetInsideValue(1);
-    binarizer ->SetOutsideValue(0);
-    if(m_Verbose) std::cout<<"Binarizing the eroded image..."<<std::endl;
-    //binarizer->Update();
-    
-    //---------------------------------
-    // ReLabel the connected components
-    //---------------------------------
-    typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
-    connectFilter->SetInput(binarizer->GetOutput());
-    connectFilter->SetBackgroundValue(0);
-    connectFilter->SetFullyConnected(m_FullyConnected);
-    if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
-    connectFilter->Update();
-    
-    //---------------------------------
-    // Sort
-    //---------------------------------
-    typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
-    relabelFilter->SetInput(connectFilter->GetOutput());
-    //relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize); // Preserve all intensities
-    //relabelFilter->Update();   
-
-    //---------------------------------
-    // Set -1 to padding value
-    //---------------------------------
-    typename SetBackgroundImageFilterType::Pointer setBackgroundFilter =SetBackgroundImageFilterType::New();
-    setBackgroundFilter->SetInput(relabelFilter->GetOutput());
-    setBackgroundFilter->SetInput2(current);
-    setBackgroundFilter->SetMaskValue(-1);
-    setBackgroundFilter->SetOutsideValue(m_ErosionPaddingValue);
-    if(m_Verbose) std::cout<<"Setting the eroded region to "<<m_ErosionPaddingValue<<"..."<<std::endl;
-        
-    //---------------------------------
-    // Cast
-    //---------------------------------
-    typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
-    typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
-    caster->SetInput(setBackgroundFilter->GetOutput());
-    caster->Update();
-    
-    //---------------------------------
-    // SetOutput
-    //---------------------------------
-    this->SetNthOutput(0, caster->GetOutput());
-  }
-
-
-}//end clitk
-#endif //#define clitkDecomposeThroughErosionImageFilter_txx
diff --git a/segmentation/clitkExtractImageFilter.h b/segmentation/clitkExtractImageFilter.h
deleted file mode 100644 (file)
index 0db736b..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to:
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-
-#ifndef __clitkExtractImageFilter_h
-#define __clitkExtractImageFilter_h
-
-#include "itkImageToImageFilter.h"
-#include "itkSmartPointer.h"
-#include "itkExtractImageFilterRegionCopier.h"
-
-namespace clitk
-{
-
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ExtractImageFilter:
-    public itk::ImageToImageFilter<TInputImage,TOutputImage>
-{
-public:
-  /** Standard class typedefs. */
-  typedef ExtractImageFilter         Self;
-  typedef itk::ImageToImageFilter<TInputImage,TOutputImage>  Superclass;
-  typedef itk::SmartPointer<Self>  Pointer;
-  typedef itk::SmartPointer<const Self>  ConstPointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);  
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(ExtractImageFilter, ImageToImageFilter);
-
-  /** Image type information. */
-  typedef TInputImage  InputImageType;
-  typedef TOutputImage OutputImageType;
-
-  /** Typedef to describe the output and input image region types. */
-  typedef typename TOutputImage::RegionType OutputImageRegionType;
-  typedef typename TInputImage::RegionType InputImageRegionType;
-
-  /** Typedef to describe the type of pixel. */
-  typedef typename TOutputImage::PixelType OutputImagePixelType;
-  typedef typename TInputImage::PixelType InputImagePixelType;
-
-  /** Typedef to describe the output and input image index and size types. */
-  typedef typename TOutputImage::IndexType OutputImageIndexType;
-  typedef typename TInputImage::IndexType InputImageIndexType;
-  typedef typename TOutputImage::SizeType OutputImageSizeType;
-  typedef typename TInputImage::SizeType InputImageSizeType;
-
-  /** ImageDimension enumeration */
-  itkStaticConstMacro(InputImageDimension, unsigned int,
-                      TInputImage::ImageDimension);
-  itkStaticConstMacro(OutputImageDimension, unsigned int,
-                      TOutputImage::ImageDimension);
-
-  typedef itk::ImageToImageFilterDetail::ExtractImageFilterRegionCopier<
-    itkGetStaticConstMacro(InputImageDimension), 
-    itkGetStaticConstMacro(OutputImageDimension)> ExtractImageFilterRegionCopierType;
-
-  void SetExtractionRegion(InputImageRegionType extractRegion);
-  itkGetMacro(ExtractionRegion, InputImageRegionType);
-
-#ifdef ITK_USE_CONCEPT_CHECKING
-  /** Begin concept checking */
-  itkConceptMacro(InputCovertibleToOutputCheck,
-                 (itk::Concept::Convertible<InputImagePixelType, OutputImagePixelType>));
-  /** End concept checking */
-#endif
-
-protected:
-  ExtractImageFilter();
-  ~ExtractImageFilter() {};
-  void PrintSelf(std::ostream& os, itk::Indent indent) const;
-
-
-  virtual void GenerateOutputInformation();
-
-
-  virtual void CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
-                                                 const OutputImageRegionType &srcRegion);
-
-
-  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                            int threadId );
-  InputImageRegionType m_ExtractionRegion;
-  OutputImageRegionType m_OutputImageRegion;
-
-private:
-  ExtractImageFilter(const Self&); //purposely not implemented
-  void operator=(const Self&); //purposely not implemented
-  
-};
-
-  
-} // end namespace itk
-  
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkExtractImageFilter.txx"
-#endif
-  
-#endif
diff --git a/segmentation/clitkExtractImageFilter.txx b/segmentation/clitkExtractImageFilter.txx
deleted file mode 100644 (file)
index ed7574f..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to:
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-
-#ifndef _clitkExtractImageFilter_txx
-#define _clitkExtractImageFilter_txx
-
-#include "clitkExtractImageFilter.h"
-#include "itkImageRegionIterator.h"
-#include "itkImageRegionConstIterator.h"
-#include "itkObjectFactory.h"
-#include "itkExtractImageFilterRegionCopier.h"
-#include "itkProgressReporter.h"
-
-
-namespace clitk
-{
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-ExtractImageFilter<TInputImage,TOutputImage>
-::ExtractImageFilter() 
-{
-}
-
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os,indent);
-
-  os << indent << "ExtractionRegion: " << m_ExtractionRegion << std::endl;
-  os << indent << "OutputImageRegion: " << m_OutputImageRegion << std::endl;
-}
-
-
-template<class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
-                                    const OutputImageRegionType &srcRegion)
-{
-  ExtractImageFilterRegionCopierType extractImageRegionCopier;
-  extractImageRegionCopier(destRegion, srcRegion, m_ExtractionRegion);
-}
-
-
-template <class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::SetExtractionRegion(InputImageRegionType extractRegion)
-{
-  m_ExtractionRegion = extractRegion;
-
-  unsigned int nonzeroSizeCount = 0;
-  InputImageSizeType inputSize = extractRegion.GetSize();
-  OutputImageSizeType outputSize;
-  OutputImageIndexType outputIndex;
-
-  /**
-   * check to see if the number of non-zero entries in the extraction region
-   * matches the number of dimensions in the output image.  
-   **/
-  for (unsigned int i = 0; i < InputImageDimension; ++i)
-    {
-    if (inputSize[i])
-      { 
-      outputSize[nonzeroSizeCount] = inputSize[i];    
-      outputIndex[nonzeroSizeCount] = extractRegion.GetIndex()[i];
-      nonzeroSizeCount++;
-      }
-    }
-    
-  if (nonzeroSizeCount != OutputImageDimension)
-    {
-    itkExceptionMacro("Extraction Region not consistent with output image");
-    }
-
-  m_OutputImageRegion.SetSize(outputSize);
-  m_OutputImageRegion.SetIndex(outputIndex);
-  this->Modified();
-}
-
-
-
-/** 
- * ExtractImageFilter can produce an image which is a different resolution
- * than its input image.  As such, ExtractImageFilter needs to provide an
- * implementation for GenerateOutputInformation() in order to inform
- * the pipeline execution model.  The original documentation of this
- * method is below.
- *
- * \sa ProcessObject::GenerateOutputInformaton() 
- */
-template <class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::GenerateOutputInformation()
-{
-  // do not call the superclass' implementation of this method since
-  // this filter allows the input and the output to be of different dimensions
-  // get pointers to the input and output
-  typename Superclass::OutputImagePointer      outputPtr = this->GetOutput();
-  typename Superclass::InputImageConstPointer  inputPtr  = this->GetInput();
-
-  if ( !outputPtr || !inputPtr)
-    {
-    return;
-    }
-
-  // Set the output image size to the same value as the extraction region.
-  outputPtr->SetLargestPossibleRegion( m_OutputImageRegion );
-
-  // Set the output spacing and origin
-  const itk::ImageBase<InputImageDimension> *phyData;
-
-  phyData
-    = dynamic_cast<const itk::ImageBase<InputImageDimension>*>(this->GetInput());
-
-  if (phyData)
-    {
-    // Copy what we can from the image from spacing and origin of the input
-    // This logic needs to be augmented with logic that select which
-    // dimensions to copy
-
-    unsigned int i;
-    const typename InputImageType::SpacingType& 
-      inputSpacing = inputPtr->GetSpacing();
-    const typename InputImageType::DirectionType&
-      inputDirection = inputPtr->GetDirection();
-    const typename InputImageType::PointType&
-      inputOrigin = inputPtr->GetOrigin();
-
-    typename OutputImageType::SpacingType outputSpacing;
-    typename OutputImageType::DirectionType outputDirection;
-    typename OutputImageType::PointType outputOrigin;
-
-    if ( static_cast<unsigned int>(OutputImageDimension) > 
-         static_cast<unsigned int>(InputImageDimension )    )
-      {
-      // copy the input to the output and fill the rest of the
-      // output with zeros.
-      for (i=0; i < InputImageDimension; ++i)
-        {
-        outputSpacing[i] = inputSpacing[i];
-        outputOrigin[i] = inputOrigin[i];
-        for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
-          {
-          outputDirection[i][dim] = inputDirection[i][dim];
-          }
-        }
-      for (; i < OutputImageDimension; ++i)
-        {
-        outputSpacing[i] = 1.0;
-        outputOrigin[i] = 0.0;
-        for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
-          {
-          outputDirection[i][dim] = 0.0;
-          }
-        outputDirection[i][i] = 1.0;
-        }
-      }
-    else
-      {
-      // copy the non-collapsed part of the input spacing and origing to the output
-      int nonZeroCount = 0;
-      for (i=0; i < InputImageDimension; ++i)
-        {
-        if (m_ExtractionRegion.GetSize()[i])
-          {
-          outputSpacing[nonZeroCount] = inputSpacing[i];
-          outputOrigin[nonZeroCount] = inputOrigin[i];
-          int nonZeroCount2 = 0;
-          for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
-            {
-            if (m_ExtractionRegion.GetSize()[dim])
-              {
-              outputDirection[nonZeroCount][nonZeroCount2] =
-                inputDirection[i][dim];
-              ++nonZeroCount2;
-              }
-            }
-          nonZeroCount++;
-          }
-        }
-      }
-
-    // set the spacing and origin
-    outputPtr->SetSpacing( outputSpacing );
-    outputPtr->SetDirection( outputDirection );
-    outputPtr->SetOrigin( outputOrigin );
-    outputPtr->SetNumberOfComponentsPerPixel(inputPtr->GetNumberOfComponentsPerPixel() );
-    }
-  else
-    {
-    // pointer could not be cast back down
-    itkExceptionMacro(<< "itk::ExtractImageFilter::GenerateOutputInformation "
-                      << "cannot cast input to "
-                      << typeid(itk::ImageBase<InputImageDimension>*).name() );
-    }
-}
-
-/** 
-   * ExtractImageFilter can be implemented as a multithreaded filter.
-   * Therefore, this implementation provides a ThreadedGenerateData()
-   * routine which is called for each processing thread. The output
-   * image data is allocated automatically by the superclass prior to
-   * calling ThreadedGenerateData().  ThreadedGenerateData can only
-   * write to the portion of the output image specified by the
-   * parameter "outputRegionForThread"
-   *
-   * \sa ImageToImageFilter::ThreadedGenerateData(),
-   *     ImageToImageFilter::GenerateData() 
-   */
-template <class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                       int threadId)
-{
-  itkDebugMacro(<<"Actually executing");
-
-  // Get the input and output pointers
-  typename Superclass::InputImageConstPointer  inputPtr = this->GetInput();
-  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
-
-  // support progress methods/callbacks
- itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
-  
-  // Define the portion of the input to walk for this thread
-  InputImageRegionType inputRegionForThread;
-  this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
-  
-  // Define the iterators.
-  typedef itk::ImageRegionIterator<TOutputImage> OutputIterator;
-  typedef itk::ImageRegionConstIterator<TInputImage> InputIterator;
-
-  OutputIterator outIt(outputPtr, outputRegionForThread);
-  InputIterator inIt(inputPtr, inputRegionForThread);
-
-  // walk the output region, and sample the input image
-  while( !outIt.IsAtEnd() )
-    {
-    // copy the input pixel to the output
-    outIt.Set( static_cast<OutputImagePixelType>(inIt.Get()));
-    ++outIt; 
-    ++inIt; 
-    progress.CompletedPixel();
-    }
-}
-
-} // end namespace clitk
-
-#endif
index 5f53b4d1926312ed855300abe6404180dda82b5c..12dd3e7040823c00e0676c005d95ec63d7522c94 100644 (file)
@@ -61,3 +61,4 @@ section "Step 6 : fill holes"
 option "doNotFillHoles"                -  "Do not fill holes if set"                 flag on
 option "dir"                   d  "Directions (axes) to perform filling (defaults to 2,1,0)"   int multiple no
 
+option "noAutoCrop"    -       "If set : do no crop final mask to BoundingBox"                         flag    off
index 50d553ae41ce9c130d9ba7acfde941354f3d1fd6..fa472ba711db3bff2c7ed8094380fc6b3505936c 100644 (file)
@@ -191,6 +191,11 @@ namespace clitk {
     itkGetConstMacro(FillHolesFlag, bool);
     itkBooleanMacro(FillHolesFlag);
 
+    // Step Auto Crop
+    itkSetMacro(AutoCrop, bool);
+    itkGetConstMacro(AutoCrop, bool);
+    itkBooleanMacro(AutoCrop);
+
   protected:
     ExtractLungFilter();
     virtual ~ExtractLungFilter() {}
@@ -212,6 +217,7 @@ namespace clitk {
     MaskImagePixelType m_BackgroundValue;
     MaskImagePixelType m_ForegroundValue;
     int m_MinimalComponentSize;
+    bool m_AutoCrop;
 
     // Step 1
     InputImagePixelType m_UpperThreshold;
index 67d3f5e641c08bb357a57c0b51fc17805287de45..0954c2a3de46a11249c21237b9644e9a4a123404 100644 (file)
@@ -37,6 +37,7 @@
 #include "itkImageIteratorWithIndex.h"
 #include "itkBinaryMorphologicalOpeningImageFilter.h"
 #include "itkBinaryMorphologicalClosingImageFilter.h"
+#include "itkConstantPadImageFilter.h"
 
 //--------------------------------------------------------------------
 template <class ImageType>
@@ -96,6 +97,7 @@ ExtractLungFilter():
   
   // Step 6
   FillHolesFlagOn();
+  AutoCropOn();
 }
 //--------------------------------------------------------------------
 
@@ -160,6 +162,22 @@ GenerateOutputInformation()
   StartNewStep("Set background to initial image");
   working_input = SetBackground<ImageType, MaskImageType>
     (working_input, patient, GetPatientMaskBackgroundValue(), -1000, true);
+
+  // Pad images with air to prevent patient touching the image border
+  static const unsigned int Dim = ImageType::ImageDimension;
+  typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType;
+  typename PadFilterType::Pointer padFilter = PadFilterType::New();
+  padFilter->SetInput(working_input);
+  padFilter->SetConstant(-1000);
+  typename ImageType::SizeType bounds;
+  for (unsigned i = 0; i < Dim - 1; ++i)
+    bounds[i] = 1;
+  bounds[Dim - 1] = 0;
+  padFilter->SetPadLowerBound(bounds);
+  padFilter->SetPadUpperBound(bounds);
+  padFilter->Update();
+  working_input = padFilter->GetOutput();
+
   StopCurrentStep<ImageType>(working_input);
   PrintMemory(GetVerboseMemoryFlag(), "After set bg"); // OK, additional mem = 0
 
@@ -311,7 +329,19 @@ GenerateOutputInformation()
   //--------------------------------------------------------------------
   PrintMemory(GetVerboseMemoryFlag(), "before autocropfilter");
   if (m_Seeds.size() != 0) { // if ==0 ->no trachea found
-    trachea = clitk::AutoCrop<MaskImageType>(trachea, GetBackgroundValue());
+    if (GetAutoCrop())
+      trachea = clitk::AutoCrop<MaskImageType>(trachea, GetBackgroundValue());
+    else
+    {
+      // Remove Padding region
+      typedef itk::CropImageFilter<MaskImageType, MaskImageType> CropFilterType;
+      typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+      cropFilter->SetInput(trachea);
+      cropFilter->SetLowerBoundaryCropSize(bounds);
+      cropFilter->SetUpperBoundaryCropSize(bounds);
+      cropFilter->Update();
+      trachea = cropFilter->GetOutput();
+    }
     StopCurrentStep<MaskImageType>(trachea);  
     PrintMemory(GetVerboseMemoryFlag(), "after delete trachea");
   }
@@ -321,7 +351,19 @@ GenerateOutputInformation()
   //--------------------------------------------------------------------
   StartNewStep("Cropping lung");
   PrintMemory(GetVerboseMemoryFlag(), "Before Autocropfilter");
-  working_mask = clitk::AutoCrop<MaskImageType>(working_mask, GetBackgroundValue());
+  if (GetAutoCrop())
+    working_mask = clitk::AutoCrop<MaskImageType>(working_mask, GetBackgroundValue());
+  else
+  {
+    // Remove Padding region
+    typedef itk::CropImageFilter<MaskImageType, MaskImageType> CropFilterType;
+    typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+    cropFilter->SetInput(working_mask);
+    cropFilter->SetLowerBoundaryCropSize(bounds);
+    cropFilter->SetUpperBoundaryCropSize(bounds);
+    cropFilter->Update();
+    working_mask = cropFilter->GetOutput();
+  }
   StopCurrentStep<MaskImageType>(working_mask);
 
   //--------------------------------------------------------------------
@@ -395,7 +437,6 @@ GenerateOutputInformation()
   PrintMemory(GetVerboseMemoryFlag(), "After count label");
  
   // Decompose the first label
-  static const unsigned int Dim = ImageType::ImageDimension;
   if (initialNumberOfLabels<2) {
     // Structuring element radius
     typename ImageType::SizeType radius;
@@ -588,7 +629,7 @@ ComputeTracheaVolume()
 
 //--------------------------------------------------------------------
 template <class ImageType>
-void 
+void
 clitk::ExtractLungFilter<ImageType>::
 SearchForTrachea()
 {
@@ -603,8 +644,8 @@ SearchForTrachea()
   double volume = 0.0;
   int skip = GetNumberOfSlicesToSkipBeforeSearchingSeed();
   while (!stop) {
-    stop = SearchForTracheaSeed(skip);
-    if (stop) {
+    stop = true;
+    if (SearchForTracheaSeed(skip)) {
       TracheaRegionGrowing();
       volume = ComputeTracheaVolume()/1000; // assume mm3, so divide by 1000 to get cc
       if (GetWriteStepFlag()) {
@@ -616,7 +657,6 @@ SearchForTrachea()
           if (GetVerboseStepFlag()) {
             std::cout << "\t Found trachea with volume " << volume << " cc." << std::endl;
           }
-          stop = true; 
         }
         else {
           if (GetVerboseStepFlag()) {
@@ -629,6 +669,11 @@ SearchForTrachea()
           // empty the list of seed
           m_Seeds.clear();
         }
+        if (skip > 0.5 * working_input->GetLargestPossibleRegion().GetSize()[2]) {
+          // we want to skip more than a half of the image, it is probably a bug
+          std::cerr << "2 : Number of slices to skip to find trachea too high = " << skip << std::endl;
+          stop = true;
+        }
       }
       else {
         stop = true;
index e103310e1efe7d89c455bc28003386afd88a1dc5..2dd396fb3a2498fb0a5ff15e3dc01a2bf6af6db8 100644 (file)
@@ -102,6 +102,7 @@ SetOptionsFromArgsInfoToFilter(FilterType * f)
   
   f->SetOpenCloseFlag(mArgsInfo.openclose_flag);
   f->SetOpenCloseRadius(mArgsInfo.opencloseRadius_arg);
+  f->SetAutoCrop(!mArgsInfo.noAutoCrop_flag);
   
   if (mArgsInfo.doNotFillHoles_given)
     f->SetFillHolesFlag(false);
index baa5730a0e184f71f63b21612719b8bbfd51e633..71298eb5397dfa605888f7b7b7a578757bfeae2c 100644 (file)
@@ -35,7 +35,7 @@ void HypercubeCorners(std::vector<itk::Point<double, Dim> > & out) {
   std::vector<itk::Point<double, Dim-1> > previous;
   HypercubeCorners<Dim-1>(previous);
   out.resize(previous.size()*2);
-  for(uint i=0; i<out.size(); i++) {
+  for(unsigned int i=0; i<out.size(); i++) {
     itk::Point<double, Dim> p;
     if (i<previous.size()) p[0] = 0; 
     else p[0] = 1;
@@ -65,20 +65,21 @@ void ComputeImageBoundariesCoordinates(typename ImageType::Pointer image,
                                        std::vector<typename ImageType::PointType> & bounds) 
 {
   // Get image max/min coordinates
-  const uint dim=ImageType::ImageDimension;
+  const unsigned int dim=ImageType::ImageDimension;
   typedef typename ImageType::PointType PointType;
   typedef typename ImageType::IndexType IndexType;
   PointType min_c, max_c;
   IndexType min_i, max_i;
   min_i = image->GetLargestPossibleRegion().GetIndex();
-  for(uint i=0; i<dim; i++) max_i[i] = image->GetLargestPossibleRegion().GetSize()[i] + min_i[i];
+  for(unsigned int i=0; i<dim; i++)
+    max_i[i] = image->GetLargestPossibleRegion().GetSize()[i] + min_i[i];
   image->TransformIndexToPhysicalPoint(min_i, min_c);
   image->TransformIndexToPhysicalPoint(max_i, max_c);
   
   // Get corners coordinates
   HypercubeCorners<ImageType::ImageDimension>(bounds);
-  for(uint i=0; i<bounds.size(); i++) {
-    for(uint j=0; j<dim; j++) {
+  for(unsigned int i=0; i<bounds.size(); i++) {
+    for(unsigned int j=0; j<dim; j++) {
       if (bounds[i][j] == 0) bounds[i][j] = min_c[j];
       if (bounds[i][j] == 1) bounds[i][j] = max_c[j];
     }
@@ -94,7 +95,7 @@ clitk::ExtractLymphStationsFilter<ImageType>::
 ExtractStation_2RL_SetDefaultValues()
 {
   SetFuzzyThreshold("2RL", "CommonCarotidArtery", 0.7);
-  SetFuzzyThreshold("2RL", "BrachioCephalicTrunk", 0.7);
+  SetFuzzyThreshold("2RL", "BrachioCephalicArtery", 0.7);
   SetFuzzyThreshold("2RL", "BrachioCephalicVein", 0.3);
   SetFuzzyThreshold("2RL", "Aorta", 0.7);
   SetFuzzyThreshold("2RL", "SubclavianArteryRight", 0.5);
@@ -208,17 +209,17 @@ ExtractStation_2RL_Ant_Limits()
   // -----------------------------------------------------
   // Remove Ant to H line from the Ant most part of the
   // CommonCarotidArtery until we reach the first slice of
-  // BrachioCephalicTrunk
+  // BrachioCephalicArtery
   StartNewStep("[Station 2RL] Ant limits with CommonCarotidArtery, H line");
 
-  // First, find the first slice of BrachioCephalicTrunk
-  MaskImagePointer BrachioCephalicTrunk = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicTrunk");
-  MaskImagePointType p = BrachioCephalicTrunk->GetOrigin(); // initialise to avoid warning 
-  clitk::FindExtremaPointInAGivenDirection<MaskImageType>(BrachioCephalicTrunk, GetBackgroundValue(), 2, false, p);
-  double TopOfBrachioCephalicTrunkZ=p[2] + BrachioCephalicTrunk->GetSpacing()[2]; // Add one slice
+  // First, find the first slice of BrachioCephalicArtery
+  MaskImagePointer BrachioCephalicArtery = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicArtery");
+  MaskImagePointType p = BrachioCephalicArtery->GetOrigin(); // initialise to avoid warning 
+  clitk::FindExtremaPointInAGivenDirection<MaskImageType>(BrachioCephalicArtery, GetBackgroundValue(), 2, false, p);
+  double TopOfBrachioCephalicArteryZ=p[2] + BrachioCephalicArtery->GetSpacing()[2]; // Add one slice
 
   // Remove CommonCarotidArtery below this point
-  CommonCarotidArtery = clitk::CropImageBelow<MaskImageType>(CommonCarotidArtery, 2, TopOfBrachioCephalicTrunkZ, true, GetBackgroundValue());  
+  CommonCarotidArtery = clitk::CropImageRemoveLowerThan<MaskImageType>(CommonCarotidArtery, 2, TopOfBrachioCephalicArteryZ, true, GetBackgroundValue());  
 
   // Find most Ant points
   std::vector<MaskImagePointType> ccaAntPositionA;
@@ -242,26 +243,26 @@ ExtractStation_2RL_Ant_Limits()
   m_ListOfStations["2L"] = m_Working_Support;
 
   // -----------------------------------------------------
-  // Ant limit with the BrachioCephalicTrunk
-  StartNewStep("[Station 2RL] Ant limits with BrachioCephalicTrunk line");
+  // Ant limit with the BrachioCephalicArtery
+  StartNewStep("[Station 2RL] Ant limits with BrachioCephalicArtery line");
 
-  // Remove Ant to BrachioCephalicTrunk
+  // Remove Ant to BrachioCephalicArtery
   m_Working_Support = 
-    clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, BrachioCephalicTrunk, 2, 
-                                                       GetFuzzyThreshold("2RL", "BrachioCephalicTrunk"), "NotAntTo", false, 2, true, false);
+    clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, BrachioCephalicArtery, 2, 
+                                                       GetFuzzyThreshold("2RL", "BrachioCephalicArtery"), "NotAntTo", false, 2, true, false);
   // End
   StopCurrentStep<MaskImageType>(m_Working_Support);
   m_ListOfStations["2R"] = m_Working_Support;
   m_ListOfStations["2L"] = m_Working_Support;
 
   // -----------------------------------------------------
-  // Ant limit with the BrachioCephalicTrunk H line
-  StartNewStep("[Station 2RL] Ant limits with BrachioCephalicTrunk, Horizontal line");
+  // Ant limit with the BrachioCephalicArtery H line
+  StartNewStep("[Station 2RL] Ant limits with BrachioCephalicArtery, Horizontal line");
   
   // Find most Ant points
   std::vector<MaskImagePointType> bctAntPositionA;
   std::vector<MaskImagePointType> bctAntPositionB;
-  clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(BrachioCephalicTrunk
+  clitk::SliceBySliceBuildLineSegmentAccordingToExtremaPosition<MaskImageType>(BrachioCephalicArtery
                                                                                GetBackgroundValue(), 2,
                                                                                1, true, // Ant
                                                                                0, // Horizontal line
@@ -317,7 +318,7 @@ ExtractStation_2RL_Ant_Limits2()
   /* Here, we consider the vessels form a kind of anterior barrier. We
      link all vessels centroids and remove what is post to it.
     - select the list of structure
-            vessel1 = BrachioCephalicTrunk
+            vessel1 = BrachioCephalicArtery
             vessel2 = BrachioCephalicVein (warning several CCL, keep most at Right)
             vessel3 = CommonCarotidArtery
             vessel4 = SubclavianArtery
@@ -332,7 +333,7 @@ ExtractStation_2RL_Ant_Limits2()
   */
 
   // Read structures
-  MaskImagePointer BrachioCephalicTrunk = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicTrunk");
+  MaskImagePointer BrachioCephalicArtery = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicArtery");
   MaskImagePointer BrachioCephalicVein = GetAFDB()->template GetImage<MaskImageType>("BrachioCephalicVein");
   MaskImagePointer CommonCarotidArtery = GetAFDB()->template GetImage<MaskImageType>("CommonCarotidArtery");
   MaskImagePointer SubclavianArtery = GetAFDB()->template GetImage<MaskImageType>("SubclavianArtery");
@@ -341,8 +342,8 @@ ExtractStation_2RL_Ant_Limits2()
   MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
   
   // Resize all structures like support
-  BrachioCephalicTrunk = 
-    clitk::ResizeImageLike<MaskImageType>(BrachioCephalicTrunk, m_Working_Support, GetBackgroundValue());
+  BrachioCephalicArtery = 
+    clitk::ResizeImageLike<MaskImageType>(BrachioCephalicArtery, m_Working_Support, GetBackgroundValue());
   CommonCarotidArtery = 
     clitk::ResizeImageLike<MaskImageType>(CommonCarotidArtery, m_Working_Support, GetBackgroundValue());
   SubclavianArtery = 
@@ -357,8 +358,8 @@ ExtractStation_2RL_Ant_Limits2()
     clitk::ResizeImageLike<MaskImageType>(Trachea, m_Working_Support, GetBackgroundValue());
 
   // Extract slices
-  std::vector<MaskSlicePointer> slices_BrachioCephalicTrunk;
-  clitk::ExtractSlices<MaskImageType>(BrachioCephalicTrunk, 2, slices_BrachioCephalicTrunk);
+  std::vector<MaskSlicePointer> slices_BrachioCephalicArtery;
+  clitk::ExtractSlices<MaskImageType>(BrachioCephalicArtery, 2, slices_BrachioCephalicArtery);
   std::vector<MaskSlicePointer> slices_BrachioCephalicVein;
   clitk::ExtractSlices<MaskImageType>(BrachioCephalicVein, 2, slices_BrachioCephalicVein);
   std::vector<MaskSlicePointer> slices_CommonCarotidArtery;
@@ -371,24 +372,24 @@ ExtractStation_2RL_Ant_Limits2()
   clitk::ExtractSlices<MaskImageType>(Aorta, 2, slices_Aorta);
   std::vector<MaskSlicePointer> slices_Trachea;
   clitk::ExtractSlices<MaskImageType>(Trachea, 2, slices_Trachea);
-  uint n= slices_BrachioCephalicTrunk.size();
+  unsigned int n= slices_BrachioCephalicArtery.size();
   
   // Get the boundaries of one slice
   std::vector<MaskSlicePointType> bounds;
-  ComputeImageBoundariesCoordinates<MaskSliceType>(slices_BrachioCephalicTrunk[0], bounds);
+  ComputeImageBoundariesCoordinates<MaskSliceType>(slices_BrachioCephalicArtery[0], bounds);
 
   // For all slices, for all structures, find the centroid and build the contour
   // List of 3D points (for debug)
   std::vector<MaskImagePointType> p3D;
 
   vtkSmartPointer<vtkAppendPolyData> append = vtkSmartPointer<vtkAppendPolyData>::New();
-  for(uint i=0; i<n; i++) {
+  for(unsigned int i=0; i<n; i++) {
     // Labelize the slices
     slices_CommonCarotidArtery[i] = Labelize<MaskSliceType>(slices_CommonCarotidArtery[i], 
                                                             GetBackgroundValue(), true, 1);
     slices_SubclavianArtery[i] = Labelize<MaskSliceType>(slices_SubclavianArtery[i], 
                                                          GetBackgroundValue(), true, 1);
-    slices_BrachioCephalicTrunk[i] = Labelize<MaskSliceType>(slices_BrachioCephalicTrunk[i], 
+    slices_BrachioCephalicArtery[i] = Labelize<MaskSliceType>(slices_BrachioCephalicArtery[i], 
                                                              GetBackgroundValue(), true, 1);
     slices_BrachioCephalicVein[i] = Labelize<MaskSliceType>(slices_BrachioCephalicVein[i], 
                                                             GetBackgroundValue(), true, 1);
@@ -407,7 +408,7 @@ ExtractStation_2RL_Ant_Limits2()
     std::vector<MaskSlicePointType> centroids6;
     ComputeCentroids<MaskSliceType>(slices_CommonCarotidArtery[i], GetBackgroundValue(), centroids1);
     ComputeCentroids<MaskSliceType>(slices_SubclavianArtery[i], GetBackgroundValue(), centroids2);
-    ComputeCentroids<MaskSliceType>(slices_BrachioCephalicTrunk[i], GetBackgroundValue(), centroids3);
+    ComputeCentroids<MaskSliceType>(slices_BrachioCephalicArtery[i], GetBackgroundValue(), centroids3);
     ComputeCentroids<MaskSliceType>(slices_Thyroid[i], GetBackgroundValue(), centroids4);
     ComputeCentroids<MaskSliceType>(slices_Aorta[i], GetBackgroundValue(), centroids5);
     ComputeCentroids<MaskSliceType>(slices_BrachioCephalicVein[i], GetBackgroundValue(), centroids6);
@@ -420,17 +421,17 @@ ExtractStation_2RL_Ant_Limits2()
     }
     
     // BrachioCephalicVein -> when SubclavianArtery has 2 CCL
-    // (BrachioCephalicTrunk is divided) -> forget BrachioCephalicVein
+    // (BrachioCephalicArtery is divided) -> forget BrachioCephalicVein
     if ((centroids3.size() ==1) && (centroids2.size() > 2)) {
       centroids6.clear();
     }
 
-    for(uint j=1; j<centroids1.size(); j++) points2D.push_back(centroids1[j]);
-    for(uint j=1; j<centroids2.size(); j++) points2D.push_back(centroids2[j]);
-    for(uint j=1; j<centroids3.size(); j++) points2D.push_back(centroids3[j]);
-    for(uint j=1; j<centroids4.size(); j++) points2D.push_back(centroids4[j]);
-    for(uint j=1; j<centroids5.size(); j++) points2D.push_back(centroids5[j]);
-    for(uint j=1; j<centroids6.size(); j++) points2D.push_back(centroids6[j]);
+    for(unsigned int j=1; j<centroids1.size(); j++) points2D.push_back(centroids1[j]);
+    for(unsigned int j=1; j<centroids2.size(); j++) points2D.push_back(centroids2[j]);
+    for(unsigned int j=1; j<centroids3.size(); j++) points2D.push_back(centroids3[j]);
+    for(unsigned int j=1; j<centroids4.size(); j++) points2D.push_back(centroids4[j]);
+    for(unsigned int j=1; j<centroids5.size(); j++) points2D.push_back(centroids5[j]);
+    for(unsigned int j=1; j<centroids6.size(); j++) points2D.push_back(centroids6[j]);
     
     // Sort by angle according to trachea centroid and vertical line,
     // in polar coordinates :
@@ -439,7 +440,7 @@ ExtractStation_2RL_Ant_Limits2()
     ComputeCentroids<MaskSliceType>(slices_Trachea[i], GetBackgroundValue(), centroids_trachea);
     typedef std::pair<MaskSlicePointType, double> PointAngleType;
     std::vector<PointAngleType> angles;
-    for(uint j=0; j<points2D.size(); j++) {
+    for(unsigned int j=0; j<points2D.size(); j++) {
       //double r = centroids_trachea[1].EuclideanDistanceTo(points2D[j]);
       double x = (points2D[j][0]-centroids_trachea[1][0]); // X : Right to Left
       double y = (centroids_trachea[1][1]-points2D[j][1]); // Y : Post to Ant
@@ -475,7 +476,7 @@ ExtractStation_2RL_Ant_Limits2()
 
     // Sort points2D according to polar angles
     std::sort(angles.begin(), angles.end(), comparePointsWithAngle<PointAngleType>());
-    for(uint j=0; j<angles.size(); j++) {
+    for(unsigned int j=0; j<angles.size(); j++) {
       points2D[j] = angles[j].first;
     }
     //    DDV(points2D, points2D.size());
@@ -496,7 +497,7 @@ ExtractStation_2RL_Ant_Limits2()
        low, add one point
     */
     std::vector<MaskSlicePointType> toadd;
-    uint index = 0;
+    unsigned int index = 0;
     double dmax = 5;
     while (index<points2D.size()-1) {
       MaskSlicePointType a = points2D[index];
@@ -555,7 +556,7 @@ ExtractStation_2RL_Ant_Limits2()
     // Build 3D points from the 2D points
     std::vector<ImagePointType> points3D;
     clitk::PointsUtils<MaskImageType>::Convert2DListTo3DList(points2D, i, m_Working_Support, points3D);
-    for(uint x=0; x<points3D.size(); x++) p3D.push_back(points3D[x]);
+    for(unsigned int x=0; x<points3D.size(); x++) p3D.push_back(points3D[x]);
 
     // Build the mesh from the contour's points
     vtkSmartPointer<vtkPolyData> mesh = Build3DMeshFrom2DContour(points3D);
index 7bb4643cfcae9fcd6dd11ddc1060cdfee07db359..b12fa521b4b9dfa4e22f56d4876f470efb04cb47 100644 (file)
@@ -11,6 +11,28 @@ ExtractStation_7_SetDefaultValues()
   SetFuzzyThreshold("7", "RightPulmonaryArtery", 0.3);
   SetFuzzyThreshold("7", "LeftPulmonaryArtery", 0.5);
   SetFuzzyThreshold("7", "SVC", 0.2);
+  SetS7_UseMostInferiorPartOnlyFlag(false);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_7() {
+  if (CheckForStation("7")) {
+  ExtractStation_7_SI_Limits();
+  ExtractStation_7_RL_Interior_Limits();
+
+  //  ExtractStation_7_Posterior_Limits();
+  ExtractStation_8_Single_CCL_Limits();  
+  ExtractStation_7_Remove_Structures();
+  // Store image filenames into AFDB 
+  writeImage<MaskImageType>(m_ListOfStations["7"], "seg/Station7.mhd");
+  GetAFDB()->SetImageFilename("Station7", "seg/Station7.mhd");  
+  WriteAFDB();
+  }
 }
 //--------------------------------------------------------------------
 
@@ -21,44 +43,212 @@ void
 clitk::ExtractLymphStationsFilter<TImageType>::
 ExtractStation_7_SI_Limits() 
 {
-  StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLLBronchus");
+  StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/LLL-RMLBronchus");
   // Get Inputs
   MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");  
+  // Create line from A to B with
+  // A = upper border of LLL at left
+  // B = lower border of bronchus intermedius (BI) or RightMiddleLobeBronchus
+  ImagePointType A;
+  ImagePointType B;
+  FindLineForS7S8Separation(A, B);    
+
+  // // if option -> replace A[0] with B[0]
+  // if (GetS7_UseMostInferiorPartOnlyFlag()) {
+  //   A[0] = B[0];
+  // }
+
+  // Use line to remove the inferior part
+  m_Working_Support =
+    SliceBySliceSetBackgroundFromSingleLine<MaskImageType>(m_Working_Support, GetBackgroundValue(), 
+                                                           A, B, 2, 0, false);
+
+  // Get the CarinaZ position
+  m_CarinaZ = FindCarinaSlicePosition();
   
-  // We suppoe that CarinaZ was already computed (S8)
-  double m_CarinaZ = GetAFDB()->GetDouble("CarinaZ");
+  // Crop support
+  m_Working_Support = 
+    clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2, 
+                                                A[2], m_CarinaZ, true,
+                                                GetBackgroundValue());
+  // Crop trachea 
+  m_Working_Trachea = 
+    clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2, 
+                                                A[2], m_CarinaZ, true,
+                                                GetBackgroundValue()); 
   
-  //  double m_OriginOfRightMiddleLobeBronchusZ = GetAFDB()->GetPoint3D("OriginOfRightMiddleLobeBronchus", 2);
-  // DD(m_OriginOfRightMiddleLobeBronchusZ);
-  MaskImagePointer UpperBorderOfLLLBronchus = GetAFDB()->template GetImage<MaskImageType>("UpperBorderOfLLLBronchus");
+  StopCurrentStep<MaskImageType>(m_Working_Support);
+  m_ListOfStations["7"] = m_Working_Support;
+}
+//--------------------------------------------------------------------
 
-  // Search most inf point (WHY ? IS IT THE RIGHT STRUCTURE ??)
-  MaskImagePointType ps = UpperBorderOfLLLBronchus->GetOrigin(); // initialise to avoid warning 
-  clitk::FindExtremaPointInAGivenDirection<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), 2, true, ps);
-  double m_UpperBorderOfLLLBronchusZ = ps[2];
 
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_7_RL_Interior_Limits() 
+{
+  // ----------------------------------------------------------------
+  StartNewStep("[Station7] RL limits with bronchi");  
+  
   /*
-  std::vector<MaskImagePointType> centroids;
-  clitk::ComputeCentroids<MaskImageType>(UpperBorderOfLLLBronchus, GetBackgroundValue(), centroids);
-  double m_UpperBorderOfLLLBronchusZ = centroids[1][2];
-  DD(m_UpperBorderOfLLLBronchusZ)
+    Slice by Slice, consider most Left point of the Right
+    bronchus. Remove the Ant/Right corner
   */
 
-  /* Crop support */
+  // First consider bronchi
+  FindLeftAndRightBronchi();
+  m_RightBronchus = GetAFDB()->template GetImage <MaskImageType>("RightBronchus");
+  m_LeftBronchus = GetAFDB()->template GetImage <MaskImageType>("LeftBronchus");
+
+  // Resize like m_Working_Support
+  m_LeftBronchus = 
+    clitk::ResizeImageLike<MaskImageType>(m_LeftBronchus, m_Working_Support, GetBackgroundValue());
+  m_RightBronchus = 
+    clitk::ResizeImageLike<MaskImageType>(m_RightBronchus, m_Working_Support, GetBackgroundValue());
+
+  // Extract slices, Label, compute centroid, keep most central connected component
+  std::vector<MaskSlicePointer> slices_leftbronchus;
+  std::vector<MaskSlicePointer> slices_rightbronchus;
+  std::vector<MaskSlicePointer> slices_support;
+  clitk::ExtractSlices<MaskImageType>(m_LeftBronchus, 2, slices_leftbronchus);
+  clitk::ExtractSlices<MaskImageType>(m_RightBronchus, 2, slices_rightbronchus);
+  clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices_support);
+
+  // Keep only the CCL of the bronchus with the closest to the center
+  // Loop on slices for left bronchus
+  for(uint i=0; i<slices_leftbronchus.size(); i++) {
+    slices_leftbronchus[i] = Labelize<MaskSliceType>(slices_leftbronchus[i], 0, false, 10);
+    std::vector<typename MaskSliceType::PointType> c;
+    clitk::ComputeCentroids<MaskSliceType>(slices_leftbronchus[i], GetBackgroundValue(), c);
+    if (c.size() > 1) {
+      double most_at_left = c[1][0];
+      int most_at_left_index=1;
+      for(uint j=1; j<c.size(); j++) {
+        if (c[j][0] < most_at_left) {
+          most_at_left = c[j][0];
+          most_at_left_index = j;
+        }
+      }
+      // Put all other CCL to Background
+      slices_leftbronchus[i] = 
+        clitk::Binarize<MaskSliceType>(slices_leftbronchus[i], most_at_left_index, 
+                                       most_at_left_index, GetBackgroundValue(), GetForegroundValue());
+    } // end c.size
+  }
+  
+  // Loop on slices for right bronchus
+  for(uint i=0; i<slices_rightbronchus.size(); i++) {
+    slices_rightbronchus[i] = Labelize<MaskSliceType>(slices_rightbronchus[i], 0, false, 10);
+    std::vector<typename MaskSliceType::PointType> c;
+    clitk::ComputeCentroids<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), c);
+    if (c.size() > 1) {
+      double most_at_right = c[1][0];
+      int most_at_right_index=1;
+      for(uint j=1; j<c.size(); j++) {
+        if (c[j][0] > most_at_right) {
+          most_at_right = c[j][0];
+          most_at_right_index = j;
+        }
+      }
+      // Put all other CCL to Background
+      slices_rightbronchus[i] = 
+        clitk::Binarize<MaskSliceType>(slices_rightbronchus[i], most_at_right_index, 
+                                       most_at_right_index, GetBackgroundValue(), GetForegroundValue());
+    } // end c.size
+  }
+  
+  // Joint slices
+  m_LeftBronchus = clitk::JoinSlices<MaskImageType>(slices_leftbronchus, m_LeftBronchus, 2);
+  m_RightBronchus = clitk::JoinSlices<MaskImageType>(slices_rightbronchus, m_RightBronchus, 2);
+
+  // For Right bronchus, Find most Left point. Remove corner Ant/Right corner
+  for(uint i=0; i<slices_rightbronchus.size(); i++) {
+    // Find most point most at left
+    MaskSlicePointType p_left;
+    MaskSlicePointType p_post;
+    bool b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), 0, false, p_left);
+    if (b) {
+      b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), 1, false, p_post);
+    }
+    if (b) {
+      MaskSlicePointType p = p_left;
+      p[1] = p_post[1];
+      MaskSliceIndexType pi;
+      slices_rightbronchus[i]->TransformPhysicalPointToIndex(p, pi);
+      
+      // Build region to remove
+      MaskSliceRegionType region = slices_rightbronchus[i]->GetLargestPossibleRegion();
+      MaskSliceIndexType index = region.GetIndex();
+      MaskSliceSizeType size = region.GetSize();
+      size[0] = pi[0] - index[0];
+      size[1] = pi[1] - index[1];
+      region.SetSize(size);
+      
+      // Fill region with Background value
+      clitk::FillRegionWithValue<MaskSliceType>(slices_support[i], GetBackgroundValue(), region);
+    }
+  }
+
+  // For Left bronchus, Find most Right point. Remove corner Ant/Left corner
+  for(uint i=0; i<slices_leftbronchus.size(); i++) {
+    // Find most point most at right
+    MaskSlicePointType p_right;
+    MaskSlicePointType p_post;
+    bool b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_leftbronchus[i], GetBackgroundValue(), 0, true, p_right);
+    if (b) {
+      b = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices_rightbronchus[i], GetBackgroundValue(), 1, false, p_post);
+    }
+    if (b) {
+      MaskSlicePointType p = p_right;
+      p[1] = p_post[1];
+      MaskSliceIndexType pi;
+      slices_leftbronchus[i]->TransformPhysicalPointToIndex(p, pi);
+      
+      /*      typedef itk::ImageRegionIterator<ImageType> IteratorType;
+      IteratorType iter(input, region);
+      iter.GoToBegin();
+      while (!iter.IsAtEnd()) {
+        MaskSliceIndexType index = iter.GetIndex();
+        if (index[0] > pi[0]) && (index[1] > pi[1]) iter.Set(GetBackgroundValue());
+
+        ++iter;
+      } 
+      */  
+      
+
+      // Build region to remove
+      MaskSliceRegionType region = slices_leftbronchus[i]->GetLargestPossibleRegion();
+      MaskSliceIndexType index = region.GetIndex();
+      MaskSliceSizeType size = region.GetSize();
+      index[0] = pi[0];
+      size[0] = slices_leftbronchus[i]->GetLargestPossibleRegion().GetSize()[0] - pi[0];
+      size[1] = pi[1] - index[1];
+      region.SetSize(size);
+      region.SetIndex(index);
+      
+      // Fill region with Background value
+      clitk::FillRegionWithValue<MaskSliceType>(slices_support[i], GetBackgroundValue(), region);
+    }
+  }
+
+  m_Working_Support = clitk::JoinSlices<MaskImageType>(slices_support, m_Working_Support, 2);
+
+  // Also remove what is at right of the Right bronchus (left respectively)
   m_Working_Support = 
-    clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2, 
-                                                m_UpperBorderOfLLLBronchusZ, 
-                                                m_CarinaZ, true,
-                                                GetBackgroundValue());
-  /* Crop trachea */
-  m_Working_Trachea = 
-    clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2, 
-                                                m_UpperBorderOfLLLBronchusZ, 
-                                                m_CarinaZ, true,
-                                                GetBackgroundValue());
+    clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_LeftBronchus, 2, 
+                                                       GetFuzzyThreshold("7", "Bronchi"), "NotLeftTo", 
+                                                       false, 3, false);
+  m_Working_Support = 
+    clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, m_RightBronchus, 2, 
+                                                       GetFuzzyThreshold("7", "Bronchi"), "NotRightTo", 
+                                                       false, 3, false);
+
+  // SECOND PART 
 
   StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["7"] = m_Working_Support;
 }
 //--------------------------------------------------------------------
 
@@ -67,7 +257,7 @@ ExtractStation_7_SI_Limits()
 template <class TImageType>
 void 
 clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_7_RL_Limits() 
+ExtractStation_7_RL_Limits_OLD() 
 {
   // ----------------------------------------------------------------
   StartNewStep("[Station7] Limits with bronchus : RightTo the left bronchus");  
@@ -82,6 +272,10 @@ ExtractStation_7_RL_Limits()
   clitk::ExtractSlices<MaskImageType>(m_LeftBronchus, 2, slices_leftbronchus);
   clitk::ExtractSlices<MaskImageType>(m_RightBronchus, 2, slices_rightbronchus);
   
+  // Version #1 with limit = centroid of the bronchus (OUTDATED)
+  // Step1 = keep only the CCL of the bronchus with the closest to the center
+  // Step2 = SliceBySlice Rel pos to both bronchi
+
   // Loop on slices
   for(uint i=0; i<slices_leftbronchus.size(); i++) {
     slices_leftbronchus[i] = Labelize<MaskSliceType>(slices_leftbronchus[i], 0, false, 10);
@@ -345,13 +539,22 @@ ExtractStation_7_Remove_Structures()
 
   Remove_Structures("7", "AzygousVein");
   Remove_Structures("7", "Aorta");
-  Remove_Structures("7", "Esophagus");
   Remove_Structures("7", "RightPulmonaryArtery");
   Remove_Structures("7", "LeftPulmonaryArtery");
   Remove_Structures("7", "LeftSuperiorPulmonaryVein");
   Remove_Structures("7", "PulmonaryTrunk");
   Remove_Structures("7", "VertebralBody");
 
+  // Keep only one CCL by slice (before removing Esophagus)
+  //  DD("SliceBySliceKeepMainCCL");
+
+  // TODO -> replace by keep the one that contains point at the middle of the line between the bronchus
+  //      -> new function "keep/select" the ccl that contains this point (2D)
+
+  //m_Working_Support = clitk::SliceBySliceKeepMainCCL<MaskImageType>(m_Working_Support, GetBackgroundValue(), GetForegroundValue());
+
+  Remove_Structures("7", "Esophagus");
+
   // END
   StopCurrentStep<MaskImageType>(m_Working_Support);
   m_ListOfStations["7"] = m_Working_Support;
index bb1ce79044a209e1c125d6b705383484c87c2f0c..7402a626bebd7e86bd06c92c43f843b5291f930e 100644 (file)
@@ -8,7 +8,6 @@ void
 clitk::ExtractLymphStationsFilter<ImageType>::
 ExtractStation_8_SetDefaultValues()
 {
-  SetDistanceMaxToAnteriorPartOfTheSpine(10);
   MaskImagePointType p;
   p[0] = 15; p[1] = 2; p[2] = 1;
   SetEsophagusDiltationForAnt(p);
@@ -19,6 +18,29 @@ ExtractStation_8_SetDefaultValues()
 }
 //--------------------------------------------------------------------
 
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_8() 
+{
+  if (CheckForStation("8")) {
+    ExtractStation_8_SI_Limits();         // OK, validated
+    ExtractStation_8_Ant_Limits();        // OK, validated
+    ExtractStation_8_Left_Sup_Limits();   // OK, validated
+    ExtractStation_8_Left_Inf_Limits();   // OK, validated
+    ExtractStation_8_Single_CCL_Limits(); // OK, validated
+    ExtractStation_8_Remove_Structures(); // OK, validated
+
+    // Store image filenames into AFDB 
+    writeImage<MaskImageType>(m_ListOfStations["8"], "seg/Station8.mhd");
+    GetAFDB()->SetImageFilename("Station8", "seg/Station8.mhd");  
+    WriteAFDB();
+  }
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 template <class ImageType>
 void 
@@ -42,63 +64,42 @@ ExtractStation_8_SI_Limits()
     left; the lower border of the bronchus intermedius on the right"
 
   */
-  StartNewStep("[Station8] Inf/Sup mediastinum limits with carina/diaphragm junction");
-
-  // Get Carina Z position
-  MaskImagePointer Carina = GetAFDB()->template GetImage<MaskImageType>("Carina");
+  StartNewStep("[Station8] Sup/Inf limits with LeftLower/RightMiddle Lobe and diaphragm");
 
-  std::vector<MaskImagePointType> centroids;
-  clitk::ComputeCentroids<MaskImageType>(Carina, GetBackgroundValue(), centroids);
-  m_CarinaZ = centroids[1][2];
-  // DD(m_CarinaZ);
-  // add one slice to include carina ?
-  m_CarinaZ += m_Mediastinum->GetSpacing()[2];
-  // We dont need Carina structure from now
-  Carina->Delete();
-  GetAFDB()->SetDouble("CarinaZ", m_CarinaZ);
+  /* -----------------------------------------------
+     NEW SUPERIOR LIMIT = LeftLowerLobeBronchus /
+     RightMiddleLobeBronchus See FindLineForS7S8Separation
+     -----------------------------------------------
+  */
+  ImagePointType A;
+  ImagePointType B;
+  FindLineForS7S8Separation(A, B);
+
+  // add one slice to be adjacent to Station7
+  B[2] += m_Working_Support->GetSpacing()[2];
+  A[2] += m_Working_Support->GetSpacing()[2];
+
+  // Use the line to remove the inferior part
+  m_Working_Support =
+    SliceBySliceSetBackgroundFromSingleLine<MaskImageType>(m_Working_Support, 
+                                                           GetBackgroundValue(), A, B, 2, 0, true);
   
+  /* -----------------------------------------------
+     INFERIOR LIMIT = Diaphragm
+     -----------------------------------------------
+  */  
+
   // Found most inferior part of the lung
   MaskImagePointer Lungs = GetAFDB()->template GetImage<MaskImageType>("Lungs");
   // It should be already croped, so I took the origin and add 10mm above 
   m_DiaphragmInferiorLimit = Lungs->GetOrigin()[2]+10;
-  //  Lungs->Delete(); // we don't need it, release memory -> it we want to release, also free in AFDB
-  clitk::PrintMemory(GetVerboseMemoryFlag(), "after reading lungs");
   GetAFDB()->template ReleaseImage<MaskImageType>("Lungs");
-  clitk::PrintMemory(GetVerboseMemoryFlag(), "after release lungs");
 
-  /* Crop support :
-     Superior limit = carina
-     Inferior limit = DiaphragmInferiorLimit (old=Gastroesphogeal junction) */
   m_Working_Support = 
     clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2, 
-                                                m_DiaphragmInferiorLimit, //GOjunctionZ, 
-                                                m_CarinaZ, true,
+                                                m_DiaphragmInferiorLimit,
+                                                B[2], true,
                                                 GetBackgroundValue());
-  
-  // Remove some structures that we know are excluded 
-  MaskImagePointer VertebralBody = 
-    GetAFDB()->template GetImage <MaskImageType>("VertebralBody");  
-  MaskImagePointer Aorta = 
-    GetAFDB()->template GetImage <MaskImageType>("Aorta");  
-
-  typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
-  typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); 
-  boolFilter->InPlaceOn();
-  boolFilter->SetInput1(m_Working_Support);
-  boolFilter->SetInput2(VertebralBody);    
-  boolFilter->SetOperationType(BoolFilterType::AndNot);
-  boolFilter->Update(); 
-  /*
-    
-    DO NOT REMOVE AORTA YET (LATER)
-
-    boolFilter->SetInput1(boolFilter->GetOutput());
-    boolFilter->SetInput2(Aorta);    
-    boolFilter->SetOperationType(BoolFilterType::AndNot);
-    boolFilter->Update();    
-  */ 
-  m_Working_Support = boolFilter->GetOutput();
-
   // Done.
   StopCurrentStep<MaskImageType>(m_Working_Support);
   m_ListOfStations["8"] = m_Working_Support;
@@ -110,290 +111,8 @@ ExtractStation_8_SI_Limits()
 template <class ImageType>
 void 
 clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_Post_Limits() 
-{
-  /*
-    Station 8: paraeosphageal nodes
-
-    Anteriorly, it is in contact with Station 7 and the
-    left main stem bronchus in its superior aspect (Fig. 3C–H) and
-    with the heart more inferiorly. Posteriorly, Station 8 abuts the
-    descending aorta and the anterior aspect of the vertebral body
-    until an imaginary horizontal line running 1 cm posterior to the
-    anterior border of the vertebral body (Fig. 3C). 
-
-    New classification IASCL 2009 :
-
-    "Nodes lying adjacent to the wall of the esophagus and to the
-    right or left of the midline, excluding subcarinal nodes (S7)
-    Upper"
-
-  */
-
-  StartNewStep("[Station8] Post limits with vertebral body");
-  MaskImagePointer VertebralBody = 
-    GetAFDB()->template GetImage <MaskImageType>("VertebralBody");  
-
-  // Consider vertebral body slice by slice
-  typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
-  typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
-  typedef typename ExtractSliceFilterType::SliceType SliceType;
-  std::vector<typename SliceType::Pointer> vertebralSlices;
-  extractSliceFilter->SetInput(VertebralBody);
-  extractSliceFilter->SetDirection(2);
-  extractSliceFilter->Update();
-  extractSliceFilter->GetOutputSlices(vertebralSlices);
-
-  // For each slice, compute the most anterior point
-  std::map<int, typename SliceType::PointType> vertebralAntPositionBySlice;
-  for(uint i=0; i<vertebralSlices.size(); i++) {
-    typename SliceType::PointType p;
-    bool found = clitk::FindExtremaPointInAGivenDirection<SliceType>(vertebralSlices[i], 
-                                                                     GetBackgroundValue(), 
-                                                                     1, true, p);
-    if (found) {
-      vertebralAntPositionBySlice[i] = p;
-    }
-    else { 
-      // no Foreground in this slice (it appends generally at the
-      // beginning and the end of the volume). Do nothing in this
-      // case.
-    }
-  }
-
-  // Convert 2D points in slice into 3D points
-  std::vector<MaskImagePointType> vertebralAntPositions;
-  clitk::PointsUtils<MaskImageType>::Convert2DMapTo3DList(vertebralAntPositionBySlice, 
-                                                          VertebralBody, 
-                                                          vertebralAntPositions);
-
-  // DEBUG : write list of points
-  clitk::WriteListOfLandmarks<MaskImageType>(vertebralAntPositions, 
-                                             "S8-vertebralMostAntPositions-points.txt");
-
-  // Cut support posteriorly 1cm the most anterior point of the
-  // VertebralBody. Do nothing below and above the VertebralBody. To
-  // do that compute several region, slice by slice and fill. 
-  MaskImageRegionType region;
-  MaskImageSizeType size;
-  MaskImageIndexType start;
-  size[2] = 1; // a single slice
-  start[0] = m_Working_Support->GetLargestPossibleRegion().GetIndex()[0];
-  size[0] = m_Working_Support->GetLargestPossibleRegion().GetSize()[0];
-  for(uint i=0; i<vertebralAntPositions.size(); i++) {
-    typedef typename itk::ImageRegionIterator<MaskImageType> IteratorType;
-    IteratorType iter = 
-      IteratorType(m_Working_Support, m_Working_Support->GetLargestPossibleRegion());
-    MaskImageIndexType index;
-    // Consider some cm posterior to most anterior positions (usually
-    // 1 cm).
-    vertebralAntPositions[i][1] += GetDistanceMaxToAnteriorPartOfTheSpine();
-    // Get index of this point
-    m_Working_Support->TransformPhysicalPointToIndex(vertebralAntPositions[i], index);
-    // Compute region (a single slice)
-    start[2] = index[2];
-    start[1] = m_Working_Support->GetLargestPossibleRegion().GetIndex()[1]+index[1];
-    size[1] = m_Working_Support->GetLargestPossibleRegion().GetSize()[1]-start[1];
-    region.SetSize(size);
-    region.SetIndex(start);
-    // Fill region
-    if (m_Working_Support->GetLargestPossibleRegion().IsInside(start))  {
-      itk::ImageRegionIterator<MaskImageType> it(m_Working_Support, region);
-      it.GoToBegin();
-      while (!it.IsAtEnd()) {
-        it.Set(GetBackgroundValue());
-        ++it;
-      }
-    }
-  }
-
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["8"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_Ant_Sup_Limits() 
+ExtractStation_8_Ant_Limits() 
 {
-  //--------------------------------------------------------------------
-  StartNewStep("[Station8] Ant limits with S7 above Carina");
-  /*
-    Anteriorly, it is in contact with Station 7 and the
-    left main stem bronchus in its superior aspect (Fig. 3C–H) and
-    with the heart more inferiorly. 
-
-    1) line post wall bronchi (S7), till originRMLB
-    - LUL bronchus : to detect in trachea. But not needed here ??
-    2) heart ! -> not delineated.
-    ==> below S7, crop CT not to far away (ant), then try with threshold
-    
-    1) ==> how to share with S7 ? Prepare both support at the same time !
-    NEED vector of initial support for each station ? No -> map if it exist before, take it !!
-
-  */
-
-  // Ant limit from carina (start) to end of S7 = originRMLB
-  // Get Trachea
-  MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
-  MaskImagePointer m_Working_Trachea = 
-    clitk::CropImageAbove<MaskImageType>(Trachea, 2, m_CarinaZ, true, // AutoCrop
-                                         GetBackgroundValue());
-
-  // Seprate into two main bronchi
-  MaskImagePointer RightBronchus;
-  MaskImagePointer LeftBronchus;
-
-  // Labelize and consider the two first (main) labels
-  m_Working_Trachea = Labelize<MaskImageType>(m_Working_Trachea, 0, true, 1);
-
-  // Carina position must at the first slice that separate the two
-  // main bronchus (not superiorly). We thus first check that the
-  // upper slice is composed of at least two labels
-  typedef itk::ImageSliceIteratorWithIndex<MaskImageType> SliceIteratorType;
-  SliceIteratorType iter(m_Working_Trachea, m_Working_Trachea->GetLargestPossibleRegion());
-  iter.SetFirstDirection(0);
-  iter.SetSecondDirection(1);
-  iter.GoToReverseBegin(); // Start from the end (because image is IS not SI)
-  int maxLabel=0;
-  while (!iter.IsAtReverseEndOfSlice()) {
-    while (!iter.IsAtReverseEndOfLine()) {    
-      if (iter.Get() > maxLabel) maxLabel = iter.Get();
-      --iter;
-    }
-    iter.PreviousLine();
-  }
-  if (maxLabel < 2) {
-    clitkExceptionMacro("First slice form Carina does not seems to seperate the two main bronchus. Abort");
-  }
-
-  // Compute 3D centroids of both parts to identify the left from the
-  // right bronchus
-  std::vector<ImagePointType> c;
-  clitk::ComputeCentroids<MaskImageType>(m_Working_Trachea, GetBackgroundValue(), c);
-  ImagePointType C1 = c[1];
-  ImagePointType C2 = c[2];
-
-  ImagePixelType rightLabel;
-  ImagePixelType leftLabel;  
-  if (C1[0] < C2[0]) { rightLabel = 1; leftLabel = 2; }
-  else { rightLabel = 2; leftLabel = 1; }
-
-  // Select LeftLabel (set one label to Backgroundvalue)
-  RightBronchus = 
-    clitk::Binarize<MaskImageType>(m_Working_Trachea, rightLabel, rightLabel, 
-                                   GetBackgroundValue(), GetForegroundValue());
-  /*
-    SetBackground<MaskImageType, MaskImageType>(m_Working_Trachea, m_Working_Trachea, 
-    leftLabel, GetBackgroundValue(), false);
-  */
-  LeftBronchus = clitk::Binarize<MaskImageType>(m_Working_Trachea, leftLabel, leftLabel, 
-                                                GetBackgroundValue(), GetForegroundValue());
-  /*
-    SetBackground<MaskImageType, MaskImageType>(m_Working_Trachea, m_Working_Trachea, 
-    rightLabel, GetBackgroundValue(), false);
-  */
-
-  // Crop images
-  RightBronchus = clitk::AutoCrop<MaskImageType>(RightBronchus, GetBackgroundValue()); 
-  LeftBronchus = clitk::AutoCrop<MaskImageType>(LeftBronchus, GetBackgroundValue()); 
-
-  // Insert int AFDB if need after 
-  GetAFDB()->template SetImage <MaskImageType>("RightBronchus", "seg/rightBronchus.mhd", 
-                                               RightBronchus, true);
-  GetAFDB()->template SetImage <MaskImageType>("LeftBronchus", "seg/leftBronchus.mhd", 
-                                               LeftBronchus, true);
-
-  // Now crop below OriginOfRightMiddleLobeBronchusZ
-  // It is not done before to keep entire bronchi.
-  
-  MaskImagePointer OriginOfRightMiddleLobeBronchus = 
-    GetAFDB()->template GetImage<MaskImageType>("OriginOfRightMiddleLobeBronchus");
-  std::vector<MaskImagePointType> centroids;
-  clitk::ComputeCentroids<MaskImageType>(OriginOfRightMiddleLobeBronchus, GetBackgroundValue(), centroids);
-  m_OriginOfRightMiddleLobeBronchusZ = centroids[1][2];
-  // add one slice to include carina ?
-  m_OriginOfRightMiddleLobeBronchusZ += RightBronchus->GetSpacing()[2];
-  // We dont need Carina structure from now
-  OriginOfRightMiddleLobeBronchus->Delete();
-
-  RightBronchus = 
-    clitk::CropImageBelow<MaskImageType>(RightBronchus, 2, 
-                                         m_OriginOfRightMiddleLobeBronchusZ, 
-                                         true, // AutoCrop
-                                         GetBackgroundValue());
-  LeftBronchus = 
-    clitk::CropImageBelow<MaskImageType>(LeftBronchus, 2, 
-                                         m_OriginOfRightMiddleLobeBronchusZ, 
-                                         true, // AutoCrop
-                                         GetBackgroundValue());
-
-  // Search for points that are the most left/post/ant and most
-  // right/post/ant of the left and right bronchus
-  // 15  = not 15 mm more distance than the middle point.
-  FindExtremaPointsInBronchus(RightBronchus, 0, 10, m_LeftMostInRightBronchus, 
-                             m_AntMostInRightBronchus, m_PostMostInRightBronchus);
-
-  FindExtremaPointsInBronchus(LeftBronchus, 1, 10, m_RightMostInLeftBronchus, 
-                             m_AntMostInLeftBronchus, m_PostMostInLeftBronchus);
-
-  // DEBUG : write the list of points
-  ListOfPointsType v;
-  v.reserve(m_LeftMostInRightBronchus.size()+m_AntMostInRightBronchus.size()+
-            m_PostMostInRightBronchus.size());
-  v.insert(v.end(), m_LeftMostInRightBronchus.begin(), m_LeftMostInRightBronchus.end() );
-  v.insert(v.end(), m_AntMostInRightBronchus.begin(), m_AntMostInRightBronchus.end() );
-  v.insert(v.end(), m_PostMostInRightBronchus.begin(), m_PostMostInRightBronchus.end() );
-  clitk::WriteListOfLandmarks<MaskImageType>(v, "S8-RightBronchus-points.txt");
-
-  v.clear();
-  v.reserve(m_RightMostInLeftBronchus.size()+m_AntMostInLeftBronchus.size()+
-            m_PostMostInLeftBronchus.size());
-  v.insert(v.end(), m_RightMostInLeftBronchus.begin(), m_RightMostInLeftBronchus.end() );
-  v.insert(v.end(), m_AntMostInLeftBronchus.begin(), m_AntMostInLeftBronchus.end() );
-  v.insert(v.end(), m_PostMostInLeftBronchus.begin(), m_PostMostInLeftBronchus.end() );
-  clitk::WriteListOfLandmarks<MaskImageType>(v, "S8-LeftBronchus-points.txt");
-
-  v.clear();
-  v.reserve(m_PostMostInLeftBronchus.size()+m_PostMostInRightBronchus.size());
-  v.insert(v.end(), m_PostMostInLeftBronchus.begin(), m_PostMostInLeftBronchus.end() );
-  v.insert(v.end(), m_PostMostInRightBronchus.begin(), m_PostMostInRightBronchus.end() );
-  clitk::WriteListOfLandmarks<MaskImageType>(v, "S8-RightLeftBronchus-points.txt");
-
-
-  // Now uses these points to limit, slice by slice 
-  // line is mainly horizontal, so mainDirection=1
-  clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
-                                                                    m_PostMostInRightBronchus,
-                                                                    m_PostMostInLeftBronchus,
-                                                                    GetBackgroundValue(), 1, 10); 
-
-  // Keep main 3D CCL :
-  m_Working_Support = Labelize<MaskImageType>(m_Working_Support, 0, false, 10);
-  m_Working_Support = KeepLabels<MaskImageType>(m_Working_Support, 
-                                                GetBackgroundValue(), 
-                                                GetForegroundValue(), 1, 1, true);
-  
-  // Autocrop
-  m_Working_Support = clitk::AutoCrop<MaskImageType>(m_Working_Support, GetBackgroundValue()); 
-
-  // End of step
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-  //  m_ListOfStations["8"] = m_Working_Support;
-
-}
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_Ant_Inf_Limits() 
-{
-
   //--------------------------------------------------------------------
   StartNewStep("[Station8] Ant part: not post to Esophagus");
   /*
@@ -404,7 +123,6 @@ ExtractStation_8_Ant_Inf_Limits()
   
   // Get Esophagus
   m_Esophagus = GetAFDB()->template GetImage<MaskImageType>("Esophagus");
-  clitk::PrintMemory(GetVerboseMemoryFlag(), "after read Esophagus");
 
   // In images from the original article, Atlas – UM, the oesophagus
   //was included in nodal stations 3p and 8.  Having said that, in the
@@ -416,46 +134,17 @@ ExtractStation_8_Ant_Inf_Limits()
   //prospective, the oesophagus should be excluded from these nodal
   //stations.
 
-  /* NOT YET !! DO IT LATER
-
-     typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
-     typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); 
-     boolFilter->InPlaceOn();
-     boolFilter->SetInput1(m_Working_Support);
-     boolFilter->SetInput2(m_Esophagus);    
-     boolFilter->SetOperationType(BoolFilterType::AndNot);
-     boolFilter->Update();    
-     m_Working_Support = boolFilter->GetOutput();
-
-  */
-
-  // Crop Esophagus : keep only below the OriginOfRightMiddleLobeBronchusZ
+  // Resize Esophagus like current support
   m_Esophagus = 
-    clitk::CropImageAbove<MaskImageType>(m_Esophagus, 2, 
-                                         m_OriginOfRightMiddleLobeBronchusZ, 
-                                         true, // AutoCrop
-                                         GetBackgroundValue());
+    clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue()); // Needed ?
 
   // Dilate to keep only not Anterior positions
   MaskImagePointType radiusInMM = GetEsophagusDiltationForAnt();
-
-  //  m_Esophagus = EnlargeEsophagusDilatationRadiusInferiorly(m_Esophagus);
-
   m_Esophagus = clitk::Dilate<MaskImageType>(m_Esophagus, 
                                              radiusInMM, 
                                              GetBackgroundValue(), 
                                              GetForegroundValue(), true);
-
-  // Remove Anterior part according to this dilatated esophagus. Note:
-  // because we crop Esophagus with ORML, the support will also be
-  // croped in the same way. Here it is a desired feature. If we dont
-  // want, use SetIgnoreEmptySliceObject(true)
-
-  // In the new IASCL definition, it is not clear if sup limits is
-  //  around carina or On the right, it is “the lower border of the
-  //  bronchus intermedius”, indicated on the image set as a point
-  //  (“lower border of the bronchus intermedius”)
-
+  // Keep what is Posterior to Esophagus
   typedef clitk::SliceBySliceRelativePositionFilter<MaskImageType> RelPosFilterType;
   typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
   relPosFilter->VerboseStepFlagOff();
@@ -488,88 +177,10 @@ ExtractStation_8_Ant_Inf_Limits()
 template <class ImageType>
 void 
 clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_Ant_Injected_Limits() 
+ExtractStation_8_Left_Sup_Limits() 
 {
-
   //--------------------------------------------------------------------
-  StartNewStep("[Station8] Ant part (remove high density, injected part)");
-
-  // Consider initial image, crop to current support
-  ImagePointer working_input = 
-    clitk::ResizeImageLike<ImageType>(m_Input, 
-                                      m_Working_Support, 
-                                      (short)GetBackgroundValue());
-  
-  // Threshold
-  typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> BinarizeFilterType; 
-  typename BinarizeFilterType::Pointer binarizeFilter = BinarizeFilterType::New();
-  binarizeFilter->SetInput(working_input);
-  binarizeFilter->SetLowerThreshold(GetInjectedThresholdForS8());
-  binarizeFilter->SetInsideValue(GetForegroundValue());
-  binarizeFilter->SetOutsideValue(GetBackgroundValue());
-  binarizeFilter->Update();
-  MaskImagePointer injected = binarizeFilter->GetOutput();
-  
-  // Combine with current support
-  clitk::AndNot<MaskImageType>(m_Working_Support, injected, GetBackgroundValue());
-
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["8"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_1_Limits() 
-{
-  //--------------------------------------------------------------------
-  StartNewStep("[Station8] Left and Right (from Carina to PulmonaryTrunk): Right to LeftPulmonaryArtery");
-  
-  /*
-    We remove LeftPulmonaryArtery structure and what is at Left to
-    this structure.
-  */
-  MaskImagePointer LeftPulmonaryArtery = GetAFDB()->template GetImage<MaskImageType>("LeftPulmonaryArtery");
-
-  // Relative Position : not at Left
-  typedef clitk::AddRelativePositionConstraintToLabelImageFilter<MaskImageType> RelPosFilterType;
-  typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
-  relPosFilter->VerboseStepFlagOff();
-  relPosFilter->WriteStepFlagOff();
-  relPosFilter->SetBackgroundValue(GetBackgroundValue());
-  relPosFilter->SetInput(m_Working_Support); 
-  relPosFilter->SetInputObject(LeftPulmonaryArtery); 
-  relPosFilter->RemoveObjectFlagOn(); // remove the object too
-  relPosFilter->AddOrientationTypeString("L");
-  relPosFilter->InverseOrientationFlagOn(); // Not at Left
-  relPosFilter->SetIntermediateSpacing(3);
-  relPosFilter->IntermediateSpacingFlagOn();
-  relPosFilter->SetFuzzyThreshold(0.7);
-  relPosFilter->AutoCropFlagOn();
-  relPosFilter->Update();   
-  m_Working_Support = relPosFilter->GetOutput();
-
-  // Release LeftPulmonaryArtery
-  GetAFDB()->template ReleaseImage<MaskImageType>("LeftPulmonaryArtery");
-
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["8"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_2_Limits() 
-{
-  //--------------------------------------------------------------------
-  StartNewStep("[Station8] Left and Right (from PulmTrunk to OriginMiddleLobeBronchus) Right to line from Aorta to PulmonaryTrunk");
+  StartNewStep("[Station8] Left limits: remove Left to line from Aorta to PulmonaryTrunk");
 
   /*
     We consider a line from Left part of Aorta to left part of
@@ -682,280 +293,14 @@ ExtractStation_8_Single_CCL_Limits()
 template <class ImageType>
 void 
 clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_Limits_old2() 
-{
-
-  //--------------------------------------------------------------------
-  StartNewStep("[Station8] Left and Right limits arround esophagus (below Carina)");
-
-  // Estract slices for current support for slice by slice processing
-  std::vector<typename MaskSliceType::Pointer> slices;
-  clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices);
-  
-  // Dilate the Esophagus to consider a margins around
-  MaskImagePointType radiusInMM = GetEsophagusDiltationForAnt();
-  m_Esophagus = clitk::Dilate<MaskImageType>(m_Esophagus, 
-                                             radiusInMM, 
-                                             GetBackgroundValue(), 
-                                             GetForegroundValue(), true);
-
-  // Remove what is outside the mediastinum in this enlarged Esophagus -> it allows to select
-  // 'better' extrema points (not too post).
-  MaskImagePointer Lungs = GetAFDB()->template GetImage<MaskImageType>("Lungs");
-  clitk::AndNot<MaskImageType>(m_Esophagus, Lungs, GetBackgroundValue());
-  GetAFDB()->template ReleaseImage<MaskImageType>("Lungs");
-
-  // Estract slices of Esophagus (resize like support before to have the same set of slices)
-  MaskImagePointer EsophagusForSlice = clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue());
-
-  std::vector<typename MaskSliceType::Pointer> eso_slices;
-  clitk::ExtractSlices<MaskImageType>(EsophagusForSlice, 2, eso_slices);
-
-  // Estract slices of Vertebral (resize like support before to have the same set of slices)
-  MaskImagePointer VertebralBody = GetAFDB()->template GetImage<MaskImageType>("VertebralBody");
-  VertebralBody = clitk::ResizeImageLike<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
-  std::vector<typename MaskSliceType::Pointer> vert_slices;
-  clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, vert_slices);
-
-  // Estract slices of Aorta (resize like support before to have the same set of slices)
-  MaskImagePointer Aorta = GetAFDB()->template GetImage<MaskImageType>("Aorta");
-  Aorta = clitk::ResizeImageLike<MaskImageType>(Aorta, m_Working_Support, GetBackgroundValue());
-  std::vector<typename MaskSliceType::Pointer> aorta_slices;
-  clitk::ExtractSlices<MaskImageType>(Aorta, 2, aorta_slices);
-
-  // Extract slices of Mediastinum (resize like support before to have the same set of slices)
-  m_Mediastinum = GetAFDB()->template GetImage<MaskImageType>("Mediastinum");
-  m_Mediastinum = clitk::ResizeImageLike<MaskImageType>(m_Mediastinum, m_Working_Support, GetBackgroundValue());
-  std::vector<typename MaskSliceType::Pointer> mediast_slices;
-  clitk::ExtractSlices<MaskImageType>(m_Mediastinum, 2, mediast_slices);
-
-  // List of points
-  std::vector<MaskImagePointType> p_RightMostAnt;
-  std::vector<MaskImagePointType> p_RightMostPost;
-  std::vector<MaskImagePointType> p_LeftMostAnt;
-  std::vector<MaskImagePointType> p_LeftMostPost;
-  std::vector<MaskImagePointType> p_AllPoints;
-  std::vector<MaskImagePointType> p_LeftAorta;
-  std::vector<MaskImagePointType> p_LeftEso;
-
-  /*
-    In the following, we search for the LeftRight limits.  We search
-    for the most Right points in Esophagus and in VertebralBody and
-    consider a line between those to most right points. All points in
-    the support which are most right to this line are discarded. Same
-    for the left part. The underlying assumption is that the support
-    is concave between Eso/VertebralBody. Esophagus is a bit
-    dilatated. On VertebralBody we go right (or left) until we reach
-    the lung (but no more 20 mm).
-  */
-
-  // Loop slices
-  MaskImagePointType p;
-  MaskImagePointType pp;
-  for(uint i=0; i<slices.size() ; i++) {
-    // Declare all needed points (sp = slice point)
-    typename MaskSliceType::PointType sp_maxRight_Eso;    
-    typename MaskSliceType::PointType sp_maxRight_Aorta;    
-    typename MaskSliceType::PointType sp_maxRight_Vertebra;
-    typename MaskSliceType::PointType sp_maxLeft_Eso; 
-    typename MaskSliceType::PointType sp_maxLeft_Aorta;   
-    typename MaskSliceType::PointType sp_maxLeft_Vertebra;
-    
-    // Right is at left on screen, coordinate decrease
-    // Left is at right on screen, coordinate increase
-    
-    // Find limit of Vertebral -> only at most Post part of current
-    // slice support.  First found most ant point in VertebralBody
-    typedef MaskSliceType SliceType;
-    typename SliceType::PointType p_slice_ant;
-    bool found = clitk::FindExtremaPointInAGivenDirection<SliceType>(vert_slices[i], GetBackgroundValue(), 1, true, p_slice_ant);
-    if (!found) {
-      // It should not happen ! But sometimes, a contour is missing or
-      // the VertebralBody is not delineated enough inferiorly ... in
-      // those cases, we consider the first found slice.
-      std::cerr << "No foreground pixels in this VertebralBody slices !?? I try with the previous/next slice" << std::endl;
-      int j=i++;
-      bool found = false;
-      while (!found) {
-        found = clitk::FindExtremaPointInAGivenDirection<SliceType>(vert_slices[j], GetBackgroundValue(), 1, true, p_slice_ant);
-        //clitkExceptionMacro("No foreground pixels in this VertebralBody slices ??");
-        j++;
-      }
-    }
-    p_slice_ant[1] += GetDistanceMaxToAnteriorPartOfTheSpine(); // Consider offset
-    
-    // The, find most Right and Left points on that AP position
-    typename SliceType::IndexType indexR;
-    typename SliceType::IndexType indexL;
-    vert_slices[i]->TransformPhysicalPointToIndex(p_slice_ant, indexR);
-    indexL = indexR;
-    // Check that is inside the mask
-    indexR[1] = std::min(indexR[1], (long)vert_slices[i]->GetLargestPossibleRegion().GetSize()[1]-1);
-    indexL[1] = indexR[1];
-    while (vert_slices[i]->GetPixel(indexR) != GetBackgroundValue()) {
-      indexR[0] --; // Go to the right
-    }
-    while (vert_slices[i]->GetPixel(indexL) != GetBackgroundValue()) {
-      indexL[0] ++; // Go to the left
-    }
-    vert_slices[i]->TransformIndexToPhysicalPoint(indexR, sp_maxRight_Vertebra);
-    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, VertebralBody, i, p);
-    p_AllPoints.push_back(p);
-    vert_slices[i]->TransformIndexToPhysicalPoint(indexL, sp_maxLeft_Vertebra);
-    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, VertebralBody, i, p);
-    p_AllPoints.push_back(p);
-    
-    // Find last point out of the mediastinum on this line, Right :
-    mediast_slices[i]->TransformPhysicalPointToIndex(sp_maxRight_Vertebra, indexR);
-    double distance = 0.0;
-    while (mediast_slices[i]->GetPixel(indexR) != GetBackgroundValue()) {
-      indexR[0] --;
-      distance += mediast_slices[i]->GetSpacing()[0];
-    }
-    if (distance < 30) { // Ok in this case, we found limit with lung
-      mediast_slices[i]->TransformIndexToPhysicalPoint(indexR, sp_maxRight_Vertebra);
-      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, m_Mediastinum, i, p);
-    }
-    else { // in that case, we are probably below the diaphragm, so we
-           // add aribtrarly few mm
-      sp_maxRight_Vertebra[0] -= 2; // Leave 2 mm around the VertebralBody 
-      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Vertebra, m_Mediastinum, i, p);
-    }
-    p_RightMostPost.push_back(p);
-    p_AllPoints.push_back(p);
-
-    // Find last point out of the mediastinum on this line, Left :
-    mediast_slices[i]->TransformPhysicalPointToIndex(sp_maxLeft_Vertebra, indexL);
-    distance = 0.0;
-    while (mediast_slices[i]->GetPixel(indexL) != GetBackgroundValue()) {
-      indexL[0] ++;
-      distance += mediast_slices[i]->GetSpacing()[0];
-    }
-    if (distance < 30) { // Ok in this case, we found limit with lung
-      mediast_slices[i]->TransformIndexToPhysicalPoint(indexL, sp_maxLeft_Vertebra);
-      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, m_Mediastinum, i, p);
-    }
-    else { // in that case, we are probably below the diaphragm, so we
-           // add aribtrarly few mm
-      sp_maxLeft_Vertebra[0] += 2; // Leave 2 mm around the VertebralBody 
-      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Vertebra, m_Mediastinum, i, p);
-    }
-    p_LeftMostPost.push_back(p);
-    p_AllPoints.push_back(p);
-
-    // Find Eso slice centroid and do not consider what is post to
-    // this centroid.
-    std::vector<typename MaskSliceType::PointType> c;
-    clitk::ComputeCentroids<MaskSliceType>(eso_slices[i], GetBackgroundValue(), c);
-    if (c.size() >1) {
-      eso_slices[i] = 
-        clitk::CropImageAbove<MaskSliceType>(eso_slices[i], 1, c[1][1], false, GetBackgroundValue());
-      eso_slices[i] = 
-        clitk::ResizeImageLike<MaskSliceType>(eso_slices[i], aorta_slices[i], GetBackgroundValue());
-      // writeImage<MaskSliceType>(eso_slices[i], "eso-slice-"+toString(i)+".mhd");
-    }
-
-    // Find right limit of Esophagus and Aorta
-    bool f = 
-      clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(), 
-                                                              0, true, sp_maxRight_Eso);
-    f = f && 
-      clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(aorta_slices[i], GetBackgroundValue(), 
-                                                              0, true, sp_maxRight_Aorta);
-    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Eso, EsophagusForSlice, i, p);
-    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxRight_Aorta, Aorta, i, pp);
-    pp[0] -= 2; // Add a margin of 2 mm to include the Aorta 'wall'
-    p_AllPoints.push_back(p);
-    if (f) {
-      p_AllPoints.push_back(pp);
-      MaskImagePointType A = p_RightMostPost.back();
-      MaskImagePointType B = p;
-      MaskImagePointType C = pp;
-      double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
-      if (s>0) p_RightMostAnt.push_back(p);
-      else p_RightMostAnt.push_back(pp);
-    }
-    else { // No more Esophagus in this slice : do nothing
-      //      p_RightMostAnt.push_back(p); 
-      p_RightMostPost.pop_back();
-    }
-
-    // --------------------------------------------------------------------------
-    // Find the limit on the Left: most left point between Eso and
-    // Eso. (Left is left on screen, coordinate increase)
-    
-    // Find left limit of Esophagus
-    clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(), 0, false, sp_maxLeft_Eso);
-    f = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(aorta_slices[i], GetBackgroundValue(), 0, false, sp_maxLeft_Aorta);
-    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Eso, EsophagusForSlice, i, p);
-    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_maxLeft_Aorta, Aorta, i, pp);
-    p_AllPoints.push_back(p);
-    pp[0] += 2; // Add a margin of 2 mm to include the 'wall'
-    if (f) { // not below Aorta
-      p_AllPoints.push_back(pp);
-      MaskImagePointType A = p_LeftMostPost.back();
-      MaskImagePointType B = p;
-      MaskImagePointType C = pp;
-      double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
-      if (s<0) {
-        p_LeftMostAnt.push_back(p); // Insert point most at Left, Eso
-      }
-      else {
-        // in this case -> two lines !
-        p_LeftMostAnt.push_back(pp);  // Insert point most at Left, Aorta (Vert to Aorta)
-        // but also consider Aorta to Eso
-        p_LeftAorta.push_back(pp);
-        p_LeftEso.push_back(p);
-      }
-    }
-    else { // No more Esophagus in this slice : do nothing
-      p_LeftMostPost.pop_back();
-      //p_LeftMostAnt.push_back(p);
-    }
-  } // End of slice loop
-  
-  clitk::WriteListOfLandmarks<MaskImageType>(p_AllPoints, "S8-LR-Eso-Vert.txt");
-  clitk::WriteListOfLandmarks<MaskImageType>(p_LeftEso, "S8-Left-Eso.txt");
-  clitk::WriteListOfLandmarks<MaskImageType>(p_LeftAorta, "S8-Left-Aorta.txt");
-
-  // Now uses these points to limit, slice by slice 
-  // Line is mainly vertical, so mainDirection=0
-  clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
-                                                                    p_RightMostAnt, p_RightMostPost,
-                                                                    GetBackgroundValue(), 0, 10);
-  clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
-                                                                    p_LeftMostAnt, p_LeftMostPost,
-                                                                    GetBackgroundValue(), 0, -10);
-  clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
-                                                                    p_LeftEso,p_LeftAorta, 
-                                                                    GetBackgroundValue(), 0, -10);
-  // END
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["8"] = m_Working_Support;
-  return;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_Limits() 
+ExtractStation_8_Left_Inf_Limits() 
 {
-
   //--------------------------------------------------------------------
-  StartNewStep("[Station8] Left and Right limits arround esophagus with lines from VertebralBody-Aorta-Esophagus");
+  StartNewStep("[Station8] Left limits around esophagus with lines from VertebralBody-Aorta-Esophagus");
 
   // Estract slices for current support for slice by slice processing
   std::vector<typename MaskSliceType::Pointer> slices;
   clitk::ExtractSlices<MaskImageType>(m_Working_Support, 2, slices);
-  
-  // Dilate the Esophagus to consider a margins around
-  MaskImagePointType radiusInMM = GetEsophagusDiltationForAnt();
-  m_Esophagus = clitk::Dilate<MaskImageType>(m_Esophagus, radiusInMM, 
-                                             GetBackgroundValue(), GetForegroundValue(), true);
-  //  m_Esophagus = EnlargeEsophagusDilatationRadiusInferiorly(m_Esophagus);
 
   // Remove what is outside the mediastinum in this enlarged Esophagus -> it allows to select
   // 'better' extrema points (not too post).
@@ -964,13 +309,18 @@ ExtractStation_8_LR_Limits()
   GetAFDB()->template ReleaseImage<MaskImageType>("Lungs");
 
   // Estract slices of Esophagus (resize like support before to have the same set of slices)
-  MaskImagePointer EsophagusForSlice = clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue());
+  MaskImagePointer EsophagusForSlice = 
+    clitk::ResizeImageLike<MaskImageType>(m_Esophagus, m_Working_Support, GetBackgroundValue());
   std::vector<typename MaskSliceType::Pointer> eso_slices;
   clitk::ExtractSlices<MaskImageType>(EsophagusForSlice, 2, eso_slices);
 
   // Estract slices of Vertebral (resize like support before to have the same set of slices)
   MaskImagePointer VertebralBody = GetAFDB()->template GetImage<MaskImageType>("VertebralBody");
   VertebralBody = clitk::ResizeImageLike<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
+  // Remove what is outside the support to not consider what is to
+  // posterior in the VertebralBody (post the horizontal line)
+  clitk::And<MaskImageType>(VertebralBody, m_Working_Support, GetBackgroundValue());
+  // writeImage<MaskImageType>(VertebralBody, "vb.mhd");
   std::vector<typename MaskSliceType::Pointer> vert_slices;
   clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, vert_slices);
 
@@ -1006,80 +356,67 @@ ExtractStation_8_LR_Limits()
   // Temporary 3D point
   MaskImagePointType p;
 
+  typename MaskSliceType::PointType minSlicePoint;
+  typename MaskSliceType::PointType maxSlicePoint;
+  clitk::GetMinMaxPointPosition<MaskSliceType>(vert_slices[0], minSlicePoint, maxSlicePoint);
+
   // Loop slices
   for(uint i=0; i<slices.size() ; i++) {
     // Declare all needed 2D points (sp = slice point)
-    typename MaskSliceType::PointType sp_MostRightVertebralBody;
+    //    typename MaskSliceType::PointType sp_MostRightVertebralBody;
     typename MaskSliceType::PointType sp_MostLeftVertebralBody;
     typename MaskSliceType::PointType sp_MostLeftAorta;
     typename MaskSliceType::PointType sp_temp;
     typename MaskSliceType::PointType sp_MostLeftEsophagus;
-    
-    // Right is at left on screen, coordinate decrease
-    // Left is at right on screen, coordinate increase
-    
+
     /* -------------------------------------------------------------------------------------
-       Find most Left point in VertebralBody. Consider only the
-       horizontal line which is 'DistanceMaxToAnteriorPartOfTheSpine'
-       away from the most ant point.
-     */
-    typename MaskSliceType::PointType sp_MostAntVertebralBody;
-    bool found = false;
-    int j=i;
-    while (!found) {
-      found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[j], GetBackgroundValue(), 1, true, sp_MostAntVertebralBody);
-      if (!found) {
-        // It should not happen ! But sometimes, a contour is missing or
-        // the VertebralBody is not delineated enough inferiorly ... in
-        // those cases, we consider the first found slice.
-        std::cerr << "No foreground pixels in this VertebralBody slices !?? I try with the previous/next slice" << std::endl;
-        j++;
-      }
-    }
-    sp_MostAntVertebralBody[1] += GetDistanceMaxToAnteriorPartOfTheSpine(); // Consider offset
+        Find first point not in mediastinum at LEFT
+    */
+    clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[i], GetBackgroundValue(), 
+                                                            0, false, sp_MostLeftVertebralBody);
+    // clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftVertebralBody, VertebralBody, i, p);
+    // DD(p);
 
-    // Crop the vertebralbody below this most post line
-    vert_slices[j] = 
-      clitk::CropImageAbove<MaskSliceType>(vert_slices[j], 1, sp_MostAntVertebralBody[1], false, GetBackgroundValue());
-    vert_slices[j] = 
-      clitk::ResizeImageLike<MaskSliceType>(vert_slices[j], aorta_slices[i], GetBackgroundValue());
-    //    writeImage<MaskSliceType>(vert_slices[i], "vert-slice-"+toString(i)+".mhd");
+    sp_MostLeftVertebralBody = 
+      clitk::FindExtremaPointInAGivenLine<MaskSliceType>(mediast_slices[i], 0, false, 
+                                                         sp_MostLeftVertebralBody, GetBackgroundValue(), 30);
+    // clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftVertebralBody, VertebralBody, i, p);
+    // DD(p);
 
-    // Find first point not in mediastinum
-    clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[j], GetBackgroundValue(), 0, false, sp_MostLeftVertebralBody);
-    sp_MostLeftVertebralBody = clitk::FindExtremaPointInAGivenLine<MaskSliceType>(mediast_slices[i], 0, false, sp_MostLeftVertebralBody, GetBackgroundValue(), 30);
     sp_MostLeftVertebralBody[0] += 2; // 2mm margin
-    clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[j], GetBackgroundValue(), 0, true, sp_MostRightVertebralBody);
-    sp_MostRightVertebralBody = clitk::FindExtremaPointInAGivenLine<MaskSliceType>(mediast_slices[i], 0, true, sp_MostRightVertebralBody, GetBackgroundValue(),30);
-    sp_MostRightVertebralBody[0] -= 2; // 2 mm margin
+    // clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftVertebralBody, VertebralBody, i, p);
+    // DD(p);
 
     // Convert 2D points into 3D
-    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostRightVertebralBody, VertebralBody, i, p);
-    p_MostRightVertebralBody.push_back(p);
     clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftVertebralBody, VertebralBody, i, p);
     p_MostLeftVertebralBody.push_back(p);
 
+    /* -------------------------------------------------------------------------------------
+       Find first point not in mediastinum at RIGHT. Not used yet.
+    clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vert_slices[i], GetBackgroundValue(), 
+                                                            0, true, sp_MostRightVertebralBody);
+    sp_MostRightVertebralBody = 
+      clitk::FindExtremaPointInAGivenLine<MaskSliceType>(mediast_slices[i], 0, true, 
+                                                         sp_MostRightVertebralBody, GetBackgroundValue(),30);
+    sp_MostRightVertebralBody[0] -= 2; // 2 mm margin
+    
+    // Convert 2D points into 3D
+    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostRightVertebralBody, VertebralBody, i, p);
+    p_MostRightVertebralBody.push_back(p);
+    */
+
+
     /* -------------------------------------------------------------------------------------
        Find most Left point in Esophagus
      */
-    found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(), 0, false, sp_MostLeftEsophagus);
+    bool found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(eso_slices[i], GetBackgroundValue(), 0, false, sp_MostLeftEsophagus);
     if (!found) { // No more Esophagus, I remove the previous point
-
-      // if (p_MostLeftEsophagus.size() < 1)  {
-      p_MostLeftVertebralBody.pop_back();      
-      // }
-      // else {
-      //   // Consider the previous point
-      //   p = p_MostLeftEsophagus.back();
-      //   p_MostLeftEsophagus.push_back(p);
-      //   sp_MostLeftEsophagus = sp_temp; // Retrieve previous 2D position
-      //   found = true;
-      // }
+      //DD("no eso pop back");
+      p_MostLeftVertebralBody.pop_back();
     }
     else {
       clitk::PointsUtils<MaskImageType>::Convert2DTo3D(sp_MostLeftEsophagus, EsophagusForSlice, i, p);
       p_MostLeftEsophagus.push_back(p);
-      // sp_temp = sp_MostLeftEsophagus; // Store previous 2D position
     }
       
     /* -------------------------------------------------------------------------------------
@@ -1101,7 +438,7 @@ ExtractStation_8_LR_Limits()
   } // End of slice loop
   
   clitk::WriteListOfLandmarks<MaskImageType>(p_MostLeftVertebralBody, "S8-MostLeft-VB-points.txt");
-  clitk::WriteListOfLandmarks<MaskImageType>(p_MostRightVertebralBody, "S8-MostRight-VB-points.txt");
+  //  clitk::WriteListOfLandmarks<MaskImageType>(p_MostRightVertebralBody, "S8-MostRight-VB-points.txt");
   clitk::WriteListOfLandmarks<MaskImageType>(p_MostLeftAorta, "S8-MostLeft-Aorta-points.txt");
   clitk::WriteListOfLandmarks<MaskImageType>(p_MostLeftEsophagus, "S8-MostLeft-eso-points.txt");
 
@@ -1112,7 +449,6 @@ ExtractStation_8_LR_Limits()
   clitk::SliceBySliceSetBackgroundFromLineSeparation<MaskImageType>(m_Working_Support, 
                                                                     p_MostLeftAorta, p_MostLeftEsophagus,
                                                                     GetBackgroundValue(), 0, -10);
-
   // END
   StopCurrentStep<MaskImageType>(m_Working_Support);
   m_ListOfStations["8"] = m_Working_Support;
@@ -1127,12 +463,10 @@ void
 clitk::ExtractLymphStationsFilter<ImageType>::
 ExtractStation_8_Remove_Structures()
 {
-
   //--------------------------------------------------------------------
-  StartNewStep("[Station8] remove some structures");
-
   Remove_Structures("8", "Aorta");
   Remove_Structures("8", "Esophagus");
+  Remove_Structures("8", "VertebralBody");  
 
   // END
   StopCurrentStep<MaskImageType>(m_Working_Support);
@@ -1142,143 +476,6 @@ ExtractStation_8_Remove_Structures()
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class ImageType>
-typename clitk::ExtractLymphStationsFilter<ImageType>::MaskImagePointer
-clitk::ExtractLymphStationsFilter<ImageType>::
-EnlargeEsophagusDilatationRadiusInferiorly(MaskImagePointer & Esophagus)
-{
-  // Check if Esophagus is delineated at least until Diaphragm. Now,
-  // because we use AutoCrop, Origin[2] gives this max inferior
-  // position.
-
-  DD("BUGGY DONT USE");
-  exit(0);
-
-  if (Esophagus->GetOrigin()[2] > m_DiaphragmInferiorLimit) {
-    // crop first slice without mask
-    MaskImagePointType pt;
-    clitk::FindExtremaPointInAGivenDirection<MaskImageType>(Esophagus, GetBackgroundValue(), 2, true, pt);
-    DD(pt);
-    Esophagus = 
-      clitk::CropImageBelow<MaskImageType>(Esophagus, 2, 
-                                           pt[2], 
-                                           false, // AutoCrop
-                                           GetBackgroundValue());
-    writeImage<MaskImageType>(Esophagus, "crop-eso.mhd");
-
-    std::cout << "Warning Esophagus is not delineated until Diaphragm. I mirror-pad it." 
-              << std::endl;
-    double extraSize = Esophagus->GetOrigin()[2]-m_DiaphragmInferiorLimit; 
-    
-    // Pad with few more slices
-    typedef itk::MirrorPadImageFilter<MaskImageType, MaskImageType> PadFilterType;
-    typename PadFilterType::Pointer padFilter = PadFilterType::New();
-    padFilter->SetInput(Esophagus);
-    MaskImageSizeType b;
-    b[0] = 0; b[1] = 0; b[2] = (uint)ceil(extraSize/Esophagus->GetSpacing()[2])+1;
-    padFilter->SetPadLowerBound(b);
-    padFilter->Update();
-    Esophagus = padFilter->GetOutput();
-  }
-  return Esophagus;
-}
-//--------------------------------------------------------------------
-
-
-//--------------------------------------------------------------------
-template <class ImageType>
-void 
-clitk::ExtractLymphStationsFilter<ImageType>::
-ExtractStation_8_LR_Limits_old() 
-{
-  /*
-    Station 8: paraeosphageal nodes
-
-    Laterally, it is within the pleural envelope and again abuts the
-    descending aorta on the left. Reasonably, the delineation of
-    Station 8 is limited to the soft tissue surrounding the esophagus
-    (Fig.  3C–H). 
-  */
-
-  StartNewStep("[Station8] Right limits (around esophagus)");
-  // Get Esophagus
-  MaskImagePointer Esophagus = GetAFDB()->template GetImage<MaskImageType>("Esophagus");
-
-  // Autocrop to get first slice with starting Esophagus
-  Esophagus = clitk::AutoCrop<MaskImageType>(Esophagus, GetBackgroundValue()); 
-
-  // Dilate 
-  // LR dilatation -> large to keep point inside
-  // AP dilatation -> few mm 
-  // SI dilatation -> enough to cover Diaphragm (old=GOjunctionZ)
-  MaskImagePointType radiusInMM = GetEsophagusDiltationForRight();
-  Esophagus = EnlargeEsophagusDilatationRadiusInferiorly(Esophagus);
-  Esophagus = clitk::Dilate<MaskImageType>(Esophagus, 
-                                           radiusInMM, 
-                                           GetBackgroundValue(), 
-                                           GetForegroundValue(), true);
-  writeImage<MaskImageType>(Esophagus, "dilateEso2.mhd");
-
-  writeImage<MaskImageType>(m_Working_Support, "before-relpos2.mhd");
-
-  // Remove Right (Left on the screen) part according to this
-  // dilatated esophagus
-  typedef clitk::SliceBySliceRelativePositionFilter<MaskImageType> RelPosFilterType;
-  typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
-  relPosFilter->VerboseStepFlagOff();
-  relPosFilter->WriteStepFlagOff();
-  relPosFilter->SetInput(m_Working_Support);
-  relPosFilter->SetInputObject(Esophagus);
-  relPosFilter->AddOrientationTypeString("NotLeftTo");
-  //  relPosFilter->InverseOrientationFlagOn(); // Not Left to
-  relPosFilter->SetDirection(2); // Z axis
-  relPosFilter->UniqueConnectedComponentBySliceOff(); // important
-  relPosFilter->SetIntermediateSpacing(4);
-  relPosFilter->IntermediateSpacingFlagOn();
-  relPosFilter->SetFuzzyThreshold(0.9); // remove few part only
-  relPosFilter->RemoveObjectFlagOff();
-  relPosFilter->Update();
-  m_Working_Support = relPosFilter->GetOutput();
-
-  // Get a single 3D CCL
-  m_Working_Support = Labelize<MaskImageType>(m_Working_Support, 0, false, 10);
-  m_Working_Support = KeepLabels<MaskImageType>(m_Working_Support, 
-                                                GetBackgroundValue(), 
-                                                GetForegroundValue(), 1, 1, true);
-
-
-  /*
-  // Re-Add post to Esophagus -> sometimes previous relpos remove some
-  // correct part below esophagus.
-  MaskImagePointer Esophagus = GetAFDB()->template GetImage<MaskImageType>("Esophagus");
-  EnlargeEsophagusDilatationRadiusInferiorly(Esophagus);
-  writeImage<MaskImageType>(Esophagus, "e-again.mhd");
-  typedef clitk::SliceBySliceRelativePositionFilter<MaskImageType> RelPosFilterType;
-  typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
-  relPosFilter->VerboseStepOff();
-  relPosFilter->WriteStepOff();
-  relPosFilter->SetInput(m_Working_Support);
-  relPosFilter->SetInputObject(Esophagus);
-  relPosFilter->SetOrientationTypeString("P");
-  relPosFilter->InverseOrientationFlagOff(); 
-  relPosFilter->SetDirection(2); // Z axis
-  relPosFilter->UniqueConnectedComponentBySliceOff(); // important
-  relPosFilter->SetIntermediateSpacing(4);
-  relPosFilter->IntermediateSpacingFlagOn();
-  relPosFilter->CombineWithOrFlagOn();
-  relPosFilter->SetFuzzyThreshold(0.9); // remove few part only
-  relPosFilter->RemoveObjectFlagOff();
-  relPosFilter->Update();
-  m_Working_Support = relPosFilter->GetOutput();
-  */
-
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-  m_ListOfStations["8"] = m_Working_Support;
-}
-//--------------------------------------------------------------------
-
-
 //--------------------------------------------------------------------
 template <class TImageType>
 void 
diff --git a/segmentation/clitkExtractLymphStation_Supports.txx b/segmentation/clitkExtractLymphStation_Supports.txx
new file mode 100644 (file)
index 0000000..903948d
--- /dev/null
@@ -0,0 +1,74 @@
+
+#include <itkBinaryDilateImageFilter.h>
+#include <itkMirrorPadImageFilter.h>
+
+//--------------------------------------------------------------------
+template <class ImageType>
+void 
+clitk::ExtractLymphStationsFilter<ImageType>::
+ExtractStationSupports()
+{
+  DD("ExtractStationSupports");
+
+  // Get initial Mediastinum
+  m_Working_Support = m_Mediastinum = GetAFDB()->template GetImage<MaskImageType>("Mediastinum", true);
+
+  // Superior limits: CricoidCartilag
+  // Inferior limits: lung
+  //  (the Mediastinum support already stop at this limit)
+
+  // Consider above Carina
+  m_CarinaZ = FindCarinaSlicePosition();
+  MaskImagePointer m_Support_Superior_to_Carina = 
+    clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
+                                                   m_CarinaZ, true, GetBackgroundValue());
+  MaskImagePointer m_Support_Inferior_to_Carina = 
+    clitk::CropImageRemoveGreaterThan<MaskImageType>(m_Working_Support, 2, 
+                                                     m_CarinaZ, true, GetBackgroundValue());
+
+  // Consider only Superior to Carina
+  m_Working_Support = m_Support_Superior_to_Carina;
+
+  // Step : S1RL
+  StartNewStep("[Support] sup-inf S1RL");
+  /*
+    Lower border: clavicles bilaterally and, in the midline, the upper
+    border of the manubrium, 1R designates right-sided nodes, 1L,
+    left-sided nodes in this region
+    
+    2R: Upper border: apex of the right lung and pleural space, and in
+    the midline, the upper border of the manubrium
+    
+    2L: Upper border: apex of the left lung and pleural space, and in the
+    midline, the upper border of the manubrium
+  */
+
+
+
+
+
+
+
+
+
+  // //  LeftRight cut along trachea
+  // MaskImagePointer Trachea = GetAFDB()->GetImage("Trachea");
+  // // build a ant-post line for each slice
+
+  // MaskImagePointer m_Support_SupRight = 
+  //   clitk::CropImageRemoveLowerThan<MaskImageType>(m_Working_Support, 2, 
+  //                                                  m_CarinaZ, true, GetBackgroundValue());
+
+
+
+
+
+  // Store image filenames into AFDB 
+  m_ListOfSupports["S1R"] = m_Working_Support;
+  writeImage<MaskImageType>(m_ListOfSupports["S1R"], "seg/Support_S1R.mhd");
+  GetAFDB()->SetImageFilename("Support_S1R", "seg/Support_S1R.mhd");
+  WriteAFDB();
+}
+//--------------------------------------------------------------------
+
+
index d789824756ce33ad9d6fb37e9adf725d44b6a0db..96ac9940799a7ed377e47cdced452bca33e571b4 100644 (file)
@@ -20,28 +20,27 @@ option "output"        o    "Output lungs mask filename"      string        no
 option "station"       -       "Force to compute station even if already exist in the DB"      string  no multiple
 
 section "Options for Station 8"
-option "maxAntSpine"                 - "Distance max to anterior part of the spine in mm"  double no default="10"
-option "esophagusDilatationForAnt"   - "Dilatation of esophagus, in mm, for 'anterior' limits (default=15,2,1)" double no multiple
-option "esophagusDilatationForRight" - "Dilatation of esophagus, in mm, for 'right' limits (default=5,10,1)" double no multiple
-option "tS8_Esophagus"               - "Threshold for 'Post' to dilated Esophagus" double default="0.5" no 
-option "injectedThresholdForS8"      - "Threshold injected areas in the ct" double default="150" no 
+option "S8_esophagusDilatationForAnt"   - "Dilatation of esophagus, in mm, for 'anterior' limits (default=15,2,1)" double no multiple
+option "S8_esophagusDilatationForRight" - "Dilatation of esophagus, in mm, for 'right' limits (default=5,10,1)" double no multiple
+option "S8_ft_Esophagus"                - "Fuzzy Threshold for 'Post' to dilated Esophagus" double default="0.5" no 
 
 section "Options for Station 7"
-option "tS7_Bronchi"                    - "Threshold for Left/Right bronchi" double default="0.1" no 
-option "tS7_LeftSuperiorPulmonaryVein"  - "Threshold for LeftSuperiorPulmonaryVein" double default="0.3" no 
-option "tS7_RightSuperiorPulmonaryVein" - "Threshold for RightSuperiorPulmonaryVein" double default="0.2" no 
-option "tS7_RightPulmonaryArtery"       - "Threshold for RightPulmonaryArtery" double default="0.3" no 
-option "tS7_LeftPulmonaryArtery"        - "Threshold for LeftPulmonaryArtery (NOT USEFUL YET)" double default="0.5" no 
-option "tS7_SVC"                        - "Threshold for SVC" double default="0.2" no 
+option "S7_ft_Bronchi"                    - "Fuzzy Threshold for Left/Right bronchi" double default="0.1" no 
+option "S7_ft_LeftSuperiorPulmonaryVein"  - "Fuzzy Threshold for LeftSuperiorPulmonaryVein" double default="0.3" no 
+option "S7_ft_RightSuperiorPulmonaryVein" - "Fuzzy Threshold for RightSuperiorPulmonaryVein" double default="0.2" no 
+option "S7_ft_RightPulmonaryArtery"       - "Fuzzy Threshold for RightPulmonaryArtery" double default="0.3" no 
+option "S7_ft_LeftPulmonaryArtery"        - "Fuzzy Threshold for LeftPulmonaryArtery (NOT USEFUL YET)" double default="0.5" no 
+option "S7_ft_SVC"                        - "Fuzzy Threshold for SVC" double default="0.2" no 
+option "S7_UseMostInferiorPartOnly"    - "Inferior separation with S8."  flag off
 
 section "Options for Station 3A"
-option "tS3A_Sternum"          - "Threshold for Post to Sternum" double default="0.5" no 
-option "tS3A_SubclavianArtery" - "Threshold for Ant to SubclavianArtery" double default="0.2" no 
+option "S3A_ft_Sternum"          - "Fuzzy Threshold for Post to Sternum" double default="0.5" no 
+option "S3A_ft_SubclavianArtery" - "Fuzzy Threshold for Ant to SubclavianArtery" double default="0.2" no 
 
 section "Options for Station 2RL"
-option "tS2RL_CommonCarotidArtery"   - "Threshold for NotAntTo to CommonCarotidArtery"   double default="0.7" no 
-option "tS2RL_BrachioCephalicTrunk"  - "Threshold for NotAntTo to BrachioCephalicTrunk"  double default="0.7" no 
-option "tS2RL_BrachioCephalicVein"   - "Threshold for NotAntTo to BrachioCephalicVein"   double default="0.3" no 
-option "tS2RL_Aorta"                 - "Threshold for RightTo  to Aorta"                 double default="0.7" no 
-option "tS2RL_SubclavianArteryRight" - "Threshold for NotLeft  to SubclavianArteryRight" double default="0.5" no 
-option "tS2RL_SubclavianArteryLeft"  - "Threshold for NotRight to SubclavianArteryLeft"  double default="0.8" no 
+option "S2RL_ft_CommonCarotidArtery"   - "Threshold for NotAntTo to CommonCarotidArtery"   double default="0.7" no 
+option "S2RL_ft_BrachioCephalicTrunk"  - "Threshold for NotAntTo to BrachioCephalicTrunk"  double default="0.7" no 
+option "S2RL_ft_BrachioCephalicVein"   - "Threshold for NotAntTo to BrachioCephalicVein"   double default="0.3" no 
+option "S2RL_ft_Aorta"                 - "Threshold for RightTo  to Aorta"                 double default="0.7" no 
+option "S2RL_ft_SubclavianArteryRight" - "Threshold for NotLeft  to SubclavianArteryRight" double default="0.5" no 
+option "S2RL_ft_SubclavianArteryLeft"  - "Threshold for NotRight to SubclavianArteryLeft"  double default="0.8" no 
index 8d160b1aad557945d3b13be3f54b7435b991f0b0..dd99c5fd4f8eced90f38eef544e1929417ddd802 100644 (file)
@@ -76,6 +76,9 @@ namespace clitk {
     typedef itk::Image<MaskImagePixelType, 2>    MaskSliceType;
     typedef typename MaskSliceType::Pointer      MaskSlicePointer;
     typedef typename MaskSliceType::PointType    MaskSlicePointType;
+    typedef typename MaskSliceType::RegionType   MaskSliceRegionType; 
+    typedef typename MaskSliceType::SizeType     MaskSliceSizeType; 
+    typedef typename MaskSliceType::IndexType    MaskSliceIndexType; 
 
     /** ImageDimension constants */
     itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
@@ -87,8 +90,8 @@ namespace clitk {
     itkSetMacro(ForegroundValue, MaskImagePixelType);
 
     // Station 8
-    itkSetMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
-    itkGetConstMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
+    // itkSetMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
+    //itkGetConstMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
     itkSetMacro(EsophagusDiltationForAnt, MaskImagePointType);
     itkGetConstMacro(EsophagusDiltationForAnt, MaskImagePointType);
     itkSetMacro(EsophagusDiltationForRight, MaskImagePointType);
@@ -97,6 +100,9 @@ namespace clitk {
     itkGetConstMacro(InjectedThresholdForS8, double);
 
     // Station 7
+    itkGetConstMacro(S7_UseMostInferiorPartOnlyFlag, bool);
+    itkSetMacro(S7_UseMostInferiorPartOnlyFlag, bool);
+    itkBooleanMacro(S7_UseMostInferiorPartOnlyFlag);
 
     // All stations
     bool GetComputeStation(std::string s);
@@ -116,6 +122,7 @@ namespace clitk {
     MaskImagePointer   m_Mediastinum;
     MaskImagePointer   m_Working_Support;
     std::map<std::string, MaskImagePointer> m_ListOfStations;
+    std::map<std::string, MaskImagePointer> m_ListOfSupports;
     MaskImagePixelType m_BackgroundValue;
     MaskImagePixelType m_ForegroundValue;
     std::map<std::string, bool> m_ComputeStationMap;
@@ -123,12 +130,20 @@ namespace clitk {
     bool CheckForStation(std::string station);
     void Remove_Structures(std::string station, std::string s);
 
+    // Functions common to several stations
+    void FindLineForS7S8Separation(MaskImagePointType & A, MaskImagePointType & B);
+    double FindCarinaSlicePosition();
+    void FindLeftAndRightBronchi();
+
     // Global parameters
     typedef std::map<std::string, double> FuzzyThresholdByStructureType;
     std::map<std::string, FuzzyThresholdByStructureType> m_FuzzyThreshold;    
 
+    // Station's supports
+    void ExtractStationSupports();
+
     // Station 8
-    double m_DistanceMaxToAnteriorPartOfTheSpine;
+    // double m_DistanceMaxToAnteriorPartOfTheSpine;
     double m_DiaphragmInferiorLimit;
     double m_CarinaZ;
     double m_OriginOfRightMiddleLobeBronchusZ;
@@ -136,22 +151,16 @@ namespace clitk {
     MaskImagePointer m_Esophagus;
     MaskImagePointType m_EsophagusDiltationForAnt;
     MaskImagePointType m_EsophagusDiltationForRight;
-    MaskImagePointer EnlargeEsophagusDilatationRadiusInferiorly(MaskImagePointer & eso);
+
     void ExtractStation_8();
     void ExtractStation_8_SetDefaultValues();
     void ExtractStation_8_SI_Limits();
-    void ExtractStation_8_Post_Limits();
-    void ExtractStation_8_Ant_Sup_Limits();
-    void ExtractStation_8_Ant_Inf_Limits();
-    void ExtractStation_8_Ant_Injected_Limits();
-    void ExtractStation_8_LR_1_Limits();
-    void ExtractStation_8_LR_2_Limits();
+    void ExtractStation_8_Ant_Limits();
+    void ExtractStation_8_Left_Sup_Limits();
+    void ExtractStation_8_Left_Inf_Limits();
     void ExtractStation_8_Single_CCL_Limits();
-    void ExtractStation_8_LR_Limits();
     void ExtractStation_8_Remove_Structures();
-    void ExtractStation_8_LR_Limits_old();
-    void ExtractStation_8_LR_Limits_old2();
-    
+
     // Station 3P
     void ExtractStation_3P();
     void ExtractStation_3P_SetDefaultValues();
@@ -186,9 +195,13 @@ namespace clitk {
     void ExtractStation_7();
     void ExtractStation_7_SetDefaultValues();
     void ExtractStation_7_SI_Limits();
-    void ExtractStation_7_RL_Limits();
+    void ExtractStation_7_RL_Interior_Limits();
+
+
+    void ExtractStation_7_RL_Limits_OLD();
     void ExtractStation_7_Posterior_Limits();   
     void ExtractStation_7_Remove_Structures();
+    bool m_S7_UseMostInferiorPartOnlyFlag;
     MaskImagePointer m_Working_Trachea;
     MaskImagePointer m_LeftBronchus;
     MaskImagePointer m_RightBronchus;
@@ -226,6 +239,7 @@ namespace clitk {
 
 #ifndef ITK_MANUAL_INSTANTIATION
 #include "clitkExtractLymphStationsFilter.txx"
+#include "clitkExtractLymphStation_Supports.txx"
 #include "clitkExtractLymphStation_8.txx"
 #include "clitkExtractLymphStation_3P.txx"
 #include "clitkExtractLymphStation_2RL.txx"
index 1823e998c40cf228444cb29439c5adc760d5cd0e..58f2991d348426b184c92a37c6c7baf93848399a 100644 (file)
@@ -72,6 +72,12 @@ GenerateOutputInformation() {
   m_Input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
   m_Mediastinum = GetAFDB()->template GetImage <MaskImageType>("Mediastinum");
 
+  // Global supports for stations
+  StartNewStep("Supports for stations");
+  StartSubStep(); 
+  ExtractStationSupports();
+  StopSubStep();  
+
   // Extract Station8
   StartNewStep("Station 8");
   StartSubStep(); 
@@ -85,10 +91,12 @@ GenerateOutputInformation() {
   StopSubStep();
 
   // Extract Station2RL
-  StartNewStep("Station 2RL");
-  StartSubStep(); 
-  ExtractStation_2RL();
-  StopSubStep();
+  /*
+    StartNewStep("Station 2RL");
+    StartSubStep(); 
+    ExtractStation_2RL();
+    StopSubStep();
+  */
 
   // Extract Station3A
   StartNewStep("Station 3A");
@@ -189,32 +197,6 @@ AddComputeStation(std::string station)
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class TImageType>
-void 
-clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_8() 
-{
-  if (CheckForStation("8")) {
-    ExtractStation_8_SI_Limits();
-    ExtractStation_8_Post_Limits();
-    ExtractStation_8_Ant_Sup_Limits();
-    ExtractStation_8_Ant_Inf_Limits();
-    ExtractStation_8_LR_1_Limits();
-    ExtractStation_8_LR_2_Limits();
-    ExtractStation_8_LR_Limits();
-    ExtractStation_8_Ant_Injected_Limits();
-    ExtractStation_8_Single_CCL_Limits();
-    ExtractStation_8_Remove_Structures();
-    // Store image filenames into AFDB 
-    writeImage<MaskImageType>(m_ListOfStations["8"], "seg/Station8.mhd");
-    GetAFDB()->SetImageFilename("Station8", "seg/Station8.mhd");  
-    WriteAFDB();
-  }
-}
-//--------------------------------------------------------------------
-
-
 //--------------------------------------------------------------------
 template <class TImageType>
 void 
@@ -239,26 +221,6 @@ ExtractStation_3P()
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class TImageType>
-void 
-clitk::ExtractLymphStationsFilter<TImageType>::
-ExtractStation_7() {
-  if (CheckForStation("7")) {
-  ExtractStation_7_SI_Limits();
-  ExtractStation_7_RL_Limits();
-  ExtractStation_7_Posterior_Limits();
-  //  ExtractStation_8_Single_CCL_Limits(); // Yes the same than 8
-  ExtractStation_7_Remove_Structures();
-  // Store image filenames into AFDB 
-  writeImage<MaskImageType>(m_ListOfStations["7"], "seg/Station7.mhd");
-  GetAFDB()->SetImageFilename("Station7", "seg/Station7.mhd");  
-  WriteAFDB();
-  }
-}
-//--------------------------------------------------------------------
-
-
 //--------------------------------------------------------------------
 template <class TImageType>
 void 
@@ -371,6 +333,171 @@ GetFuzzyThreshold(std::string station, std::string tag)
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractLymphStationsFilter<TImageType>::
+FindLineForS7S8Separation(MaskImagePointType & A, MaskImagePointType & B)
+{
+  // Create line from A to B with
+  // A = upper border of LLL at left
+  // B = lower border of bronchus intermedius (BI) or RightMiddleLobeBronchus
+  
+  try {
+    GetAFDB()->GetPoint3D("LineForS7S8Separation_Begin", A); 
+    GetAFDB()->GetPoint3D("LineForS7S8Separation_End", B);
+  }
+  catch(clitk::ExceptionObject & o) {
+    
+    DD("FindLineForS7S8Separation");
+    // Load LeftLowerLobeBronchus and get centroid point
+    MaskImagePointer LeftLowerLobeBronchus = 
+      GetAFDB()->template GetImage <MaskImageType>("LeftLowerLobeBronchus");
+    std::vector<MaskImagePointType> c;
+    clitk::ComputeCentroids<MaskImageType>(LeftLowerLobeBronchus, GetBackgroundValue(), c);
+    A = c[1];
+    
+    // Load RightMiddleLobeBronchus and get superior point (not centroid here)
+    MaskImagePointer RightMiddleLobeBronchus = 
+      GetAFDB()->template GetImage <MaskImageType>("RightMiddleLobeBronchus");
+    bool b = FindExtremaPointInAGivenDirection<MaskImageType>(RightMiddleLobeBronchus, 
+                                                              GetBackgroundValue(), 
+                                                              2, false, B);
+    if (!b) {
+      clitkExceptionMacro("Error while searching most superior point in RightMiddleLobeBronchus. Abort");
+    }
+    
+    // Insert into the DB
+    GetAFDB()->SetPoint3D("LineForS7S8Separation_Begin", A);
+    GetAFDB()->SetPoint3D("LineForS7S8Separation_End", B);
+  }
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+double 
+clitk::ExtractLymphStationsFilter<TImageType>::
+FindCarinaSlicePosition()
+{
+  double z;
+  try {
+    z = GetAFDB()->GetDouble("CarinaZ");
+  }
+  catch(clitk::ExceptionObject e) {
+    DD("FindCarinaSlicePosition");
+    // Get Carina
+    MaskImagePointer Carina = GetAFDB()->template GetImage<MaskImageType>("Carina");
+    
+    // Get Centroid and Z value
+    std::vector<MaskImagePointType> centroids;
+    clitk::ComputeCentroids<MaskImageType>(Carina, GetBackgroundValue(), centroids);
 
+    // We dont need Carina structure from now
+    Carina->Delete();
+    
+    // Put inside the AFDB
+    GetAFDB()->SetPoint3D("CarinaPoint", centroids[1]);
+    GetAFDB()->SetDouble("CarinaZ", centroids[1][2]);
+    WriteAFDB();
+    z = centroids[1][2];
+  }
+  return z;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::ExtractLymphStationsFilter<TImageType>::
+FindLeftAndRightBronchi()
+{
+  try {
+    m_RightBronchus = GetAFDB()->template GetImage <MaskImageType>("RightBronchus");
+    m_LeftBronchus = GetAFDB()->template GetImage <MaskImageType>("LeftBronchus");
+  }
+  catch(clitk::ExceptionObject & o) {
+
+    DD("FindLeftAndRightBronchi");
+    // The goal is to separate the trachea inferiorly to the carina into
+    // a Left and Right bronchus.
+  
+    // Get the trachea
+    MaskImagePointer Trachea = GetAFDB()->template GetImage<MaskImageType>("Trachea");
+
+    // Get the Carina position
+    m_CarinaZ = FindCarinaSlicePosition();
+
+    // Consider only inferiorly to the Carina
+    MaskImagePointer m_Working_Trachea = 
+      clitk::CropImageRemoveGreaterThan<MaskImageType>(Trachea, 2, m_CarinaZ, true, // AutoCrop
+                                                       GetBackgroundValue());
+
+    // Labelize the trachea
+    m_Working_Trachea = Labelize<MaskImageType>(m_Working_Trachea, 0, true, 1);
+
+    // Carina position must at the first slice that separate the two
+    // main bronchus (not superiorly). We thus first check that the
+    // upper slice is composed of at least two labels
+    MaskImagePointer RightBronchus;
+    MaskImagePointer LeftBronchus;
+    typedef itk::ImageSliceIteratorWithIndex<MaskImageType> SliceIteratorType;
+    SliceIteratorType iter(m_Working_Trachea, m_Working_Trachea->GetLargestPossibleRegion());
+    iter.SetFirstDirection(0);
+    iter.SetSecondDirection(1);
+    iter.GoToReverseBegin(); // Start from the end (because image is IS not SI)
+    int maxLabel=0;
+    while (!iter.IsAtReverseEndOfSlice()) {
+      while (!iter.IsAtReverseEndOfLine()) {    
+        if (iter.Get() > maxLabel) maxLabel = iter.Get();
+        --iter;
+      }
+      iter.PreviousLine();
+    }
+    if (maxLabel < 2) {
+      clitkExceptionMacro("First slice from Carina does not seems to seperate the two main bronchus. Abort");
+    }
+
+    // Compute 3D centroids of both parts to identify the left from the
+    // right bronchus
+    std::vector<ImagePointType> c;
+    clitk::ComputeCentroids<MaskImageType>(m_Working_Trachea, GetBackgroundValue(), c);
+    ImagePointType C1 = c[1];
+    ImagePointType C2 = c[2];
+
+    ImagePixelType rightLabel;
+    ImagePixelType leftLabel;  
+    if (C1[0] < C2[0]) { rightLabel = 1; leftLabel = 2; }
+    else { rightLabel = 2; leftLabel = 1; }
+
+    // Select LeftLabel (set one label to Backgroundvalue)
+    RightBronchus = 
+      clitk::Binarize<MaskImageType>(m_Working_Trachea, rightLabel, rightLabel, 
+                                     GetBackgroundValue(), GetForegroundValue());
+    /*
+      SetBackground<MaskImageType, MaskImageType>(m_Working_Trachea, m_Working_Trachea, 
+      leftLabel, GetBackgroundValue(), false);
+    */
+    LeftBronchus = clitk::Binarize<MaskImageType>(m_Working_Trachea, leftLabel, leftLabel, 
+                                                  GetBackgroundValue(), GetForegroundValue());
+    /*
+      SetBackground<MaskImageType, MaskImageType>(m_Working_Trachea, m_Working_Trachea, 
+      rightLabel, GetBackgroundValue(), false);
+    */
+
+    // Crop images
+    RightBronchus = clitk::AutoCrop<MaskImageType>(RightBronchus, GetBackgroundValue()); 
+    LeftBronchus = clitk::AutoCrop<MaskImageType>(LeftBronchus, GetBackgroundValue()); 
+
+    // Insert int AFDB if need after 
+    GetAFDB()->template SetImage <MaskImageType>("RightBronchus", "seg/rightBronchus.mhd", 
+                                                 RightBronchus, true);
+    GetAFDB()->template SetImage <MaskImageType>("LeftBronchus", "seg/leftBronchus.mhd", 
+                                                 LeftBronchus, true);
+  }
+}
+//--------------------------------------------------------------------
 
 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
index ffa6c3c87e6a668373182b87b629a3a47040fd75..8b6167ec9090ca4fc1d17dcad7f33dd0b4a21767 100644 (file)
@@ -70,9 +70,9 @@ SetOptionsFromArgsInfoToFilter(FilterType * f)
   f->SetAFDBFilename(mArgsInfo.afdb_arg);  
 
   // Station 8
-  f->SetDistanceMaxToAnteriorPartOfTheSpine(mArgsInfo.maxAntSpine_arg);
-  f->SetFuzzyThreshold("8", "Esophagus", mArgsInfo.tS8_Esophagus_arg);
-  f->SetInjectedThresholdForS8(mArgsInfo.injectedThresholdForS8_arg);
+  //f->SetDistanceMaxToAnteriorPartOfTheSpine(mArgsInfo.S8_maxAntSpine_arg);
+  f->SetFuzzyThreshold("8", "Esophagus", mArgsInfo.S8_ft_Esophagus_arg);
+  //  f->SetInjectedThresholdForS8(mArgsInfo.tS8_injectedThreshold_arg);
 
   // Check multiple options for radius dilatation
   /*
@@ -83,27 +83,27 @@ SetOptionsFromArgsInfoToFilter(FilterType * f)
    */
   typename FilterType::MaskImagePointType p;
   p[0] = 7; p[1] = 5; p[2] = 0; // default value
-  if (mArgsInfo.esophagusDilatationForAnt_given == 3) {
+  if (mArgsInfo.S8_esophagusDilatationForAnt_given == 3) {
     for(uint i=0; i<3; i++)
-      p[i] = mArgsInfo.esophagusDilatationForAnt_arg[i];
+      p[i] = mArgsInfo.S8_esophagusDilatationForAnt_arg[i];
   }
   else {
-    if (mArgsInfo.esophagusDilatationForAnt_given == 1) {
+    if (mArgsInfo.S8_esophagusDilatationForAnt_given == 1) {
       for(uint i=0; i<3; i++)
-        p[i] = mArgsInfo.esophagusDilatationForAnt_arg[0];
+        p[i] = mArgsInfo.S8_esophagusDilatationForAnt_arg[0];
     }
   }
   f->SetEsophagusDiltationForAnt(p);
   
   p[0] = 5; p[1] = 10; p[2] = 1; // default value
-  if (mArgsInfo.esophagusDilatationForRight_given == 3) {
+  if (mArgsInfo.S8_esophagusDilatationForRight_given == 3) {
     for(uint i=0; i<3; i++)
-      p[i] = mArgsInfo.esophagusDilatationForRight_arg[i];
+      p[i] = mArgsInfo.S8_esophagusDilatationForRight_arg[i];
   }
   else {
-    if (mArgsInfo.esophagusDilatationForRight_given == 1) {
+    if (mArgsInfo.S8_esophagusDilatationForRight_given == 1) {
       for(uint i=0; i<3; i++)
-        p[i] = mArgsInfo.esophagusDilatationForRight_arg[0];
+        p[i] = mArgsInfo.S8_esophagusDilatationForRight_arg[0];
     }
   }
   f->SetEsophagusDiltationForRight(p);  
@@ -112,24 +112,25 @@ SetOptionsFromArgsInfoToFilter(FilterType * f)
     f->AddComputeStation(mArgsInfo.station_arg[i]);
 
   // Station 7
-  f->SetFuzzyThreshold("7", "Bronchi", mArgsInfo.tS7_Bronchi_arg);
-  f->SetFuzzyThreshold("7", "LeftSuperiorPulmonaryVein", mArgsInfo.tS7_LeftSuperiorPulmonaryVein_arg);
-  f->SetFuzzyThreshold("7", "RightSuperiorPulmonaryVein", mArgsInfo.tS7_RightSuperiorPulmonaryVein_arg);
-  f->SetFuzzyThreshold("7", "RightPulmonaryArtery", mArgsInfo.tS7_RightPulmonaryArtery_arg);
-  f->SetFuzzyThreshold("7", "LeftPulmonaryArtery", mArgsInfo.tS7_LeftPulmonaryArtery_arg);
-  f->SetFuzzyThreshold("7", "SVC", mArgsInfo.tS7_SVC_arg);
+  f->SetFuzzyThreshold("7", "Bronchi", mArgsInfo.S7_ft_Bronchi_arg);
+  f->SetFuzzyThreshold("7", "LeftSuperiorPulmonaryVein", mArgsInfo.S7_ft_LeftSuperiorPulmonaryVein_arg);
+  f->SetFuzzyThreshold("7", "RightSuperiorPulmonaryVein", mArgsInfo.S7_ft_RightSuperiorPulmonaryVein_arg);
+  f->SetFuzzyThreshold("7", "RightPulmonaryArtery", mArgsInfo.S7_ft_RightPulmonaryArtery_arg);
+  f->SetFuzzyThreshold("7", "LeftPulmonaryArtery", mArgsInfo.S7_ft_LeftPulmonaryArtery_arg);
+  f->SetFuzzyThreshold("7", "SVC", mArgsInfo.S7_ft_SVC_arg);
+  f->SetS7_UseMostInferiorPartOnlyFlag(mArgsInfo.S7_UseMostInferiorPartOnly_flag);
 
   // Station 3A
-  f->SetFuzzyThreshold("3A", "Sternum", mArgsInfo.tS3A_Sternum_arg);
-  f->SetFuzzyThreshold("3A", "SubclavianArtery", mArgsInfo.tS3A_SubclavianArtery_arg);
+  f->SetFuzzyThreshold("3A", "Sternum", mArgsInfo.S3A_ft_Sternum_arg);
+  f->SetFuzzyThreshold("3A", "SubclavianArtery", mArgsInfo.S3A_ft_SubclavianArtery_arg);
   
   // Station 2RL
-  f->SetFuzzyThreshold("2RL", "CommonCarotidArtery", mArgsInfo.tS2RL_CommonCarotidArtery_arg);
-  f->SetFuzzyThreshold("2RL", "BrachioCephalicTrunk", mArgsInfo.tS2RL_BrachioCephalicTrunk_arg);
-  f->SetFuzzyThreshold("2RL", "BrachioCephalicVein", mArgsInfo.tS2RL_BrachioCephalicVein_arg);
-  f->SetFuzzyThreshold("2RL", "Aorta", mArgsInfo.tS2RL_Aorta_arg);
-  f->SetFuzzyThreshold("2RL", "SubclavianArteryLeft", mArgsInfo.tS2RL_SubclavianArteryLeft_arg);
-  f->SetFuzzyThreshold("2RL", "SubclavianArteryRight", mArgsInfo.tS2RL_SubclavianArteryRight_arg);
+  f->SetFuzzyThreshold("2RL", "CommonCarotidArtery", mArgsInfo.S2RL_ft_CommonCarotidArtery_arg);
+  f->SetFuzzyThreshold("2RL", "BrachioCephalicTrunk", mArgsInfo.S2RL_ft_BrachioCephalicTrunk_arg);
+  f->SetFuzzyThreshold("2RL", "BrachioCephalicVein", mArgsInfo.S2RL_ft_BrachioCephalicVein_arg);
+  f->SetFuzzyThreshold("2RL", "Aorta", mArgsInfo.S2RL_ft_Aorta_arg);
+  f->SetFuzzyThreshold("2RL", "SubclavianArteryLeft", mArgsInfo.S2RL_ft_SubclavianArteryLeft_arg);
+  f->SetFuzzyThreshold("2RL", "SubclavianArteryRight", mArgsInfo.S2RL_ft_SubclavianArteryRight_arg);
 }
 //--------------------------------------------------------------------
 
diff --git a/segmentation/clitkExtractMediastinalVessels.cxx b/segmentation/clitkExtractMediastinalVessels.cxx
new file mode 100644 (file)
index 0000000..4171f05
--- /dev/null
@@ -0,0 +1,45 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+// clitk
+#include "clitkExtractMediastinalVessels_ggo.h"
+#include "clitkExtractMediastinalVesselsGenericFilter.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+
+  // Init command line
+  GGO(clitkExtractMediastinalVessels, args_info);
+  CLITK_INIT;
+
+  // Filter
+  typedef clitk::ExtractMediastinalVesselsGenericFilter<args_info_clitkExtractMediastinalVessels> FilterType;
+  FilterType::Pointer filter = FilterType::New();
+
+  filter->SetArgsInfo(args_info);
+  
+  try {
+    filter->Update();
+  } catch(std::runtime_error e) {
+    std::cout << e.what() << std::endl;
+  }
+
+  return EXIT_SUCCESS;
+} // This is the end, my friend
+//--------------------------------------------------------------------
diff --git a/segmentation/clitkExtractMediastinalVessels.ggo b/segmentation/clitkExtractMediastinalVessels.ggo
new file mode 100644 (file)
index 0000000..77bd309
--- /dev/null
@@ -0,0 +1,32 @@
+#File clitkExtractMediastinalVessels.ggo
+package "clitkExtractMediastinalVessels"
+version "1.0"
+purpose "Extract MediastinalVessels"
+
+option "config"                -  "Config file"                  string        no
+option "imagetypes"     -  "Display allowed image types"  flag          off
+option "verbose"        v  "Verbose"                     flag          off
+option "verboseStep"    -  "Verbose each step"           flag          off
+option "writeStep"      w  "Write image at each step"    flag          off
+option "verboseOption"  -  "Display options values"       flag          off
+option "verboseWarningOff" -  "Do not display warning"    flag          off
+option "verboseMemory"  -  "Display memory usage"         flag          off
+
+section "I/O"
+
+option "afdb"          a       "Input Anatomical Feature DB"     string        yes
+option "input"         i       "Input CT filename"               string        yes
+option "output"        o       "Output filename"                 string        yes
+option "seed"          s        "Seed point name in AFDB"         string       yes
+option "name"          n        "Name of the vessels to sought"   string       yes
+
+option "thresholdHigh" t       "Initial high threshold"          double default="140" no
+option "thresholdLow"  l       "Initial low threshold"           double default="55" no
+option "erode"         e       "Erosion radius in pixel"         int default="2" no
+option "dilate"        d       "Dilatation radius in pixel"      int default="9" no
+option "maxPost"       -       "Max distance post to Carina"     double default="10" no
+option "maxAnt"        -       "Max distance ant to Carina"      double default="40" no
+option "maxLeft"       -       "Max distance left to Carina"     double default="35" no
+option "maxRight"      -       "Max distance right to Carina"    double default="35" no
+option "bif"           -       "Max number of bifurcation during traking"    int default="0" no
+option "open"          -       "Final opening radius"            int default="1" no
\ No newline at end of file
diff --git a/segmentation/clitkExtractMediastinalVesselsFilter.h b/segmentation/clitkExtractMediastinalVesselsFilter.h
new file mode 100644 (file)
index 0000000..44bb53a
--- /dev/null
@@ -0,0 +1,195 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+#ifndef CLITKEXTRACTLYMPHSTATIONSFILTER_H
+#define CLITKEXTRACTLYMPHSTATIONSFILTER_H
+
+// clitk
+#include "clitkFilterBase.h"
+#include "clitkFilterWithAnatomicalFeatureDatabaseManagement.h"
+
+namespace clitk {
+  
+  //--------------------------------------------------------------------
+  /*
+    Try to extract the some Mediastinal Vessels in a thorax CT.
+    Need a set of Anatomical Features (AFDB)
+  */
+  //--------------------------------------------------------------------
+  
+  template <class TImageType>
+  class ITK_EXPORT ExtractMediastinalVesselsFilter: 
+    public virtual clitk::FilterBase, 
+    public clitk::FilterWithAnatomicalFeatureDatabaseManagement,
+    public itk::ImageToImageFilter<TImageType, itk::Image<uchar, 3> >
+  {
+
+  public:
+    /** Standard class typedefs. */
+    typedef itk::ImageToImageFilter<TImageType, itk::Image<uchar, 3> > Superclass;
+    typedef ExtractMediastinalVesselsFilter          Self;
+    typedef itk::SmartPointer<Self>             Pointer;
+    typedef itk::SmartPointer<const Self>       ConstPointer;
+    
+    /** Method for creation through the object factory. */
+    itkNewMacro(Self);
+    
+    /** Run-time type information (and related methods). */
+    itkTypeMacro(ExtractMediastinalVesselsFilter, ImageToImageFilter);
+
+    /** Some convenient typedefs. */
+    typedef TImageType                       ImageType;
+    typedef typename ImageType::ConstPointer ImageConstPointer;
+    typedef typename ImageType::Pointer      ImagePointer;
+    typedef typename ImageType::RegionType   ImageRegionType; 
+    typedef typename ImageType::PixelType    ImagePixelType; 
+    typedef typename ImageType::SizeType     ImageSizeType; 
+    typedef typename ImageType::IndexType    ImageIndexType; 
+    typedef typename ImageType::PointType    ImagePointType; 
+        
+    typedef uchar MaskImagePixelType;
+    typedef itk::Image<MaskImagePixelType, 3>    MaskImageType;  
+    typedef typename MaskImageType::Pointer      MaskImagePointer;
+    typedef typename MaskImageType::RegionType   MaskImageRegionType; 
+    typedef typename MaskImageType::SizeType     MaskImageSizeType; 
+    typedef typename MaskImageType::IndexType    MaskImageIndexType; 
+    typedef typename MaskImageType::PointType    MaskImagePointType; 
+
+    typedef itk::Image<MaskImagePixelType, 2>    MaskSliceType;
+    typedef typename MaskSliceType::Pointer      MaskSlicePointer;
+    typedef typename MaskSliceType::PointType    MaskSlicePointType;
+
+    typedef long LabelType;
+    /** ImageDimension constants */
+    itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
+    FILTERBASE_INIT;
+   
+    itkGetConstMacro(BackgroundValue, MaskImagePixelType);
+    itkSetMacro(BackgroundValue, MaskImagePixelType);
+
+    itkGetConstMacro(ForegroundValue, MaskImagePixelType);
+    itkSetMacro(ForegroundValue, MaskImagePixelType);
+
+    itkGetConstMacro(TemporaryForegroundValue, MaskImagePixelType);
+    itkSetMacro(TemporaryForegroundValue, MaskImagePixelType);
+
+    itkGetConstMacro(ThresholdHigh, ImagePixelType);
+    itkSetMacro(ThresholdHigh, ImagePixelType);
+
+    itkGetConstMacro(ThresholdLow, ImagePixelType);
+    itkSetMacro(ThresholdLow, ImagePixelType);
+
+    itkGetConstMacro(ErosionRadius, int);
+    itkSetMacro(ErosionRadius, int);
+
+    itkGetConstMacro(DilatationRadius, int);
+    itkSetMacro(DilatationRadius, int);
+
+    itkGetConstMacro(MaxDistancePostToCarina, double);
+    itkSetMacro(MaxDistancePostToCarina, double);
+    itkGetConstMacro(MaxDistanceAntToCarina, double);
+    itkSetMacro(MaxDistanceAntToCarina, double);
+    itkGetConstMacro(MaxDistanceLeftToCarina, double);
+    itkSetMacro(MaxDistanceLeftToCarina, double);
+    itkGetConstMacro(MaxDistanceRightToCarina, double);
+    itkSetMacro(MaxDistanceRightToCarina, double);
+
+    itkSetMacro(DebugFlag, bool);
+    itkGetConstMacro(DebugFlag, bool);
+    itkBooleanMacro(DebugFlag);
+
+    itkSetMacro(SoughtVesselSeedName, std::string);
+    itkGetConstMacro(SoughtVesselSeedName, std::string);
+
+    itkSetMacro(SoughtVesselName, std::string);
+    itkGetConstMacro(SoughtVesselName, std::string);
+
+    itkSetMacro(OutputFilename, std::string);
+    itkGetConstMacro(OutputFilename, std::string);
+
+    itkSetMacro(MaxNumberOfFoundBifurcation, int);
+    itkGetConstMacro(MaxNumberOfFoundBifurcation, int);
+
+    itkSetMacro(FinalOpeningRadius, int);
+    itkGetConstMacro(FinalOpeningRadius, int);
+
+  protected:
+    ExtractMediastinalVesselsFilter();
+    virtual ~ExtractMediastinalVesselsFilter() {}
+    
+    virtual void GenerateOutputInformation();
+    virtual void GenerateInputRequestedRegion();
+    virtual void GenerateData();
+    
+    bool               m_DebugFlag;
+    ImagePointer       m_Input;
+    MaskImagePointer   m_Working_Support;
+    MaskImagePointer   m_Mediastinum;
+    MaskImagePointer   m_Mask;
+    MaskImagePixelType m_BackgroundValue;
+    MaskImagePixelType m_ForegroundValue;
+    MaskImagePixelType m_TemporaryForegroundValue;
+    ImagePixelType     m_ThresholdHigh;
+    ImagePixelType     m_ThresholdLow;
+    int                m_ErosionRadius;
+    int                m_DilatationRadius;
+    double             m_MaxDistancePostToCarina;
+    double             m_MaxDistanceAntToCarina;
+    double             m_MaxDistanceLeftToCarina;
+    double             m_MaxDistanceRightToCarina;
+    int                m_MaxNumberOfFoundBifurcation;
+    int                m_FinalOpeningRadius;
+
+    std::vector<MaskSlicePointer> m_slice_recon;
+    std::vector<MaskSlicePointer> m_slice_recon2;
+    
+    // Resulting structures
+    MaskImageType::Pointer m_SoughtVessel;
+    std::string m_SoughtVesselSeedName;
+    std::string m_SoughtVesselName;
+    std::string m_OutputFilename;
+    
+    void CropInputImage();
+    void TrackBifurcationFromPoint(MaskImagePointer & recon, 
+                                   std::vector<MaskSlicePointer> & slices_recon, 
+                                   MaskImagePointType point3D,
+                                   MaskImagePointType pointMaxSlice,
+                                   LabelType newLabel, 
+                                   std::vector<MaskImagePointType> & bif);
+
+    void TrackVesselsFromPoint(MaskImagePointer & recon, 
+                               std::vector<MaskSlicePointer> & slices_recon, 
+                               MaskImagePointType point3D,
+                               MaskImagePointType pointMaxSlice,
+                               LabelType newLabel);
+    
+  private:
+    ExtractMediastinalVesselsFilter(const Self&); //purposely not implemented
+    void operator=(const Self&); //purposely not implemented
+    
+  }; // end class
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+//--------------------------------------------------------------------
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkExtractMediastinalVesselsFilter.txx"
+#endif
+
+#endif
diff --git a/segmentation/clitkExtractMediastinalVesselsFilter.txx b/segmentation/clitkExtractMediastinalVesselsFilter.txx
new file mode 100644 (file)
index 0000000..29709f4
--- /dev/null
@@ -0,0 +1,994 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+#ifndef CLITKEXTRACTLYMPHSTATIONSFILTER_TXX
+#define CLITKEXTRACTLYMPHSTATIONSFILTER_TXX
+
+// clitk
+#include "clitkCommon.h"
+#include "clitkExtractMediastinalVesselsFilter.h"
+#include "clitkSegmentationUtils.h"
+#include "clitkReconstructWithConditionalGrayscaleDilateImageFilter.h"
+
+// itk
+#include <itkBinaryThresholdImageFilter.h>
+#include <itkMinimumMaximumImageCalculator.h>
+
+template<class T> struct index_cmp {
+  index_cmp(const T varr) : arr(varr) {}
+  bool operator()(const size_t a, const size_t b) const
+  { return arr[a] < arr[b]; }
+  const T arr;
+};
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+ExtractMediastinalVesselsFilter():
+  clitk::FilterBase(),
+  clitk::FilterWithAnatomicalFeatureDatabaseManagement(),
+  itk::ImageToImageFilter<TImageType, MaskImageType>()
+{
+  this->SetNumberOfRequiredInputs(1);
+  SetBackgroundValue(0);
+  SetForegroundValue(1);
+  SetThresholdHigh(140);
+  SetThresholdLow(55);
+  SetErosionRadius(2);
+  SetDilatationRadius(9);
+  SetMaxDistancePostToCarina(10);
+  SetMaxDistanceAntToCarina(40);
+  SetMaxDistanceLeftToCarina(35);
+  SetMaxDistanceRightToCarina(35);
+  SetSoughtVesselSeedName("NoSeedNameGiven");
+  SetFinalOpeningRadius(1);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+GenerateOutputInformation() { 
+  // Get inputs
+  LoadAFDB();
+  m_Input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
+  
+  // ------------------------------------------------------------------
+  // Crop the initial image superiorly and inferiorly. 
+  // TODO : add options for x cm above/below
+  CropInputImage();  
+
+  // ------------------------------------------------------------------
+  // Binarize the image. Need two thresholds, one high to select
+  // structures (CCL) that are almost not connected (after erosion),
+  // and one low thresholds to select the real contours. Will be
+  // reconstructed later. 
+  StartNewStep("Binarize with high threshold = "+toString(GetThresholdHigh()));
+  typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> BinarizeFilterType; 
+  typename BinarizeFilterType::Pointer binarizeFilter = BinarizeFilterType::New();
+  binarizeFilter->SetInput(m_Input);
+  binarizeFilter->SetLowerThreshold(GetThresholdHigh());
+  binarizeFilter->SetInsideValue(GetForegroundValue());
+  binarizeFilter->SetOutsideValue(GetBackgroundValue());
+  binarizeFilter->Update();
+  m_Mask = binarizeFilter->GetOutput();
+  StopCurrentStep<MaskImageType>(m_Mask);
+
+  // ------------------------------------------------------------------
+  StartNewStep("Binarize with low threshold = "+toString(GetThresholdLow()));
+  binarizeFilter = BinarizeFilterType::New();
+  binarizeFilter->SetInput(m_Input);
+  binarizeFilter->SetLowerThreshold(GetThresholdLow());
+  binarizeFilter->SetInsideValue(GetForegroundValue());
+  binarizeFilter->SetOutsideValue(GetBackgroundValue());
+  binarizeFilter->Update();
+  MaskImagePointer m_Mask2 = binarizeFilter->GetOutput();
+  StopCurrentStep<MaskImageType>(m_Mask2);
+
+  // ------------------------------------------------------------------
+  // Extract slices
+  StartNewStep("Detect objects : erosion, then slice by slice reconstruction");
+  std::vector<MaskSlicePointer> slices_mask;
+  clitk::ExtractSlices<MaskImageType>(m_Mask, 2, slices_mask);
+  std::vector<MaskSlicePointer> slices_mask2;
+  clitk::ExtractSlices<MaskImageType>(m_Mask2, 2, slices_mask2);
+  int radius = GetErosionRadius();
+
+  // List of working slices (debug only)
+  std::vector<MaskSlicePointer> debug_eroded;
+  // std::vector<MaskSlicePointer> debug_labeled;
+  
+  // ------------------------------------------------------------------
+  // Loop Slice by Slice in order to break connectivity between
+  // CCL. Erode and reconstruct all labels at the same time without
+  // merging them.
+  for(uint i=0; i<slices_mask.size(); i++) {
+
+    /*// Erosion kernel
+      typedef itk::BinaryBallStructuringElement<MaskSliceType::PixelType,2> KernelType;
+      KernelType structuringElement;
+      structuringElement.SetRadius(radius);
+      structuringElement.CreateStructuringElement();
+    */
+    
+    // Erosion -> we break the connectivity between structure
+    MaskSliceType::SizeType r;
+    r[0] = r[1] = radius;
+    MaskSlicePointer eroded = clitk::Opening<MaskSliceType>(slices_mask[i], 
+                                                            r,
+                                                            GetBackgroundValue(), 
+                                                            GetForegroundValue());
+    /*
+    //typedef itk::BinaryErodeImageFilter<MaskSliceType, MaskSliceType, KernelType> ErodeFilterType;
+    typedef itk::BinaryMorphologicalOpeningImageFilter<MaskSliceType, MaskSliceType, KernelType> ErodeFilterType;
+    typename ErodeFilterType::Pointer eroder = ErodeFilterType::New();
+    eroder->SetInput(slices_mask[i]);
+    eroder->SetBackgroundValue(GetBackgroundValue());
+    eroder->SetForegroundValue(GetForegroundValue());
+    //eroder->SetBoundaryToForeground(true); // ?? for BinaryErodeImageFilter
+    eroder->SetKernel(structuringElement);
+    eroder->Update();
+    MaskSlicePointer eroded = eroder->GetOutput();
+    */
+
+    // Keep slice for debug
+    debug_eroded.push_back(eroded);
+
+    // Labelize (CCL)
+    MaskSlicePointer labeled = 
+      clitk::Labelize<MaskSliceType>(eroded, GetBackgroundValue(), true, 1); // Fully connected !
+    // debug_labeled.push_back(labeled);
+
+    // Make Reconstruction filter : dilation all labels at the same
+    // time, prevent to merge them.
+    typedef clitk::ReconstructWithConditionalGrayscaleDilateImageFilter<MaskSliceType> ReconstructFilterType;
+    typename ReconstructFilterType::Pointer reconstructor = ReconstructFilterType::New();
+    reconstructor->SetInput(labeled);
+    reconstructor->SetIterationNumber(radius+GetDilatationRadius());
+    reconstructor->Update();
+    MaskSlicePointer s = reconstructor->GetOutput();
+
+    // Remove Initial BG of the second tresholded image
+    s = clitk::SetBackground<MaskSliceType, MaskSliceType>(s, slices_mask2[i], 
+                                                           GetBackgroundValue(), GetBackgroundValue(), true);
+    m_slice_recon.push_back(s);
+
+  } // end loop
+  
+  // Build 3D images from the slice by slice processing
+  MaskImageType::Pointer eroded = clitk::JoinSlices<MaskImageType>(debug_eroded, m_Mask, 2);
+  writeImage<MaskImageType>(eroded, "erode.mhd");
+  //MaskImageType::Pointer l = clitk::JoinSlices<MaskImageType>(debug_labeled, m_Mask, 2);  
+  MaskImageType::Pointer r = clitk::JoinSlices<MaskImageType>(m_slice_recon, m_Mask, 2);
+  writeImage<MaskImageType>(r, "recon1.mhd");
+  
+  // ------------------------------------------------------------------
+  // Track the SoughtVessel from the given first point
+  // superiorly. This is done by TrackBifurcationFromPoint
+  MaskImagePointType SoughtVesselSeedPoint;
+  GetAFDB()->GetPoint3D(m_SoughtVesselSeedName, SoughtVesselSeedPoint);
+  MaskImagePointType MaxSlicePoint;
+  if (GetAFDB()->TagExist(m_SoughtVesselSeedName+"Max")) {
+    GetAFDB()->GetPoint3D(m_SoughtVesselSeedName+"Max", MaxSlicePoint);
+  }
+  else {
+    MaxSlicePoint = SoughtVesselSeedPoint;
+    MaxSlicePoint[2] += 1000;
+  }
+
+  // Find the label with the maximum value to set the result
+  typedef itk::MinimumMaximumImageCalculator<MaskImageType> MinMaxFilterType;
+  MinMaxFilterType::Pointer ff = MinMaxFilterType::New();
+  ff->SetImage(r);
+  ff->ComputeMaximum();
+  LabelType newLabel = ff->GetMaximum()+1; 
+
+  // the following bifurcations point will the centroids of the
+  // components obtain when (hopefully!) the SoughtVessel
+  // split into CommonArtery and SubclavianArtery.
+  std::vector<MaskImagePointType> bifurcations;
+  //  TrackBifurcationFromPoint(r, m_slice_recon, SoughtVesselSeedPoint, 
+  //                         MaxSlicePoint, newLabel, bifurcations);
+
+  TrackVesselsFromPoint(r, m_slice_recon, SoughtVesselSeedPoint, 
+                        MaxSlicePoint, newLabel);
+
+  // Build the final 3D image from the previous slice by slice processing
+  m_SoughtVessel = clitk::JoinSlices<MaskImageType>(m_slice_recon, m_Mask, 2);
+  writeImage<MaskImageType>(m_SoughtVessel, "recon2.mhd");
+  
+  // Set binary image, (remove other labels).  
+  m_SoughtVessel = 
+    clitk::Binarize<MaskImageType>(m_SoughtVessel, newLabel, newLabel, 
+                                   GetBackgroundValue(), GetForegroundValue());
+
+  //  writeImage<MaskImageType>(m_SoughtVessel, "afterbinarize.mhd");
+  m_SoughtVessel = clitk::AutoCrop<MaskImageType>(m_SoughtVessel, GetBackgroundValue());
+
+  //  writeImage<MaskImageType>(m_SoughtVessel, "afterautocrop.mhd");
+
+  // Clean the image : Opening (not in Z direction)
+  typename MaskImageType::SizeType rad;
+  rad[0] = rad[1] = GetFinalOpeningRadius(); 
+  rad[2] = 0;
+  m_SoughtVessel = clitk::Opening<MaskImageType>(m_SoughtVessel, rad, 
+                                                 GetBackgroundValue(), GetForegroundValue());
+
+  //  writeImage<MaskImageType>(m_SoughtVessel, "afteropen.mhd");
+
+  // Clean the image : keep main CCL slice by slice
+  m_SoughtVessel = clitk::SliceBySliceKeepMainCCL<MaskImageType>(m_SoughtVessel, 
+                                                                 GetBackgroundValue(), 
+                                                                 GetForegroundValue());  
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+GenerateInputRequestedRegion() {
+  //DD("GenerateInputRequestedRegion (nothing?)");
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+GenerateData() {
+  // Save in the AFDB (not write on the disk here)
+  GetAFDB()->SetImageFilename(GetSoughtVesselName(), GetOutputFilename());  
+  WriteAFDB();
+  // Final Step -> graft output
+  this->GraftNthOutput(0, m_SoughtVessel);
+}
+//--------------------------------------------------------------------
+  
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+CropInputImage() { 
+  StartNewStep("Crop the input image: SI,AP limits with carina and crop with mediastinum");
+  /*
+    Need : Trachea, Carina (roi not point), 
+  */
+  // Get Trachea and Carina
+  MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");  
+  
+  // Compute Carina position
+  double m_CarinaZ;
+  MaskImagePointer Carina = GetAFDB()->template GetImage<MaskImageType>("Carina");
+  std::vector<MaskImagePointType> centroids;
+  clitk::ComputeCentroids<MaskImageType>(Carina, GetBackgroundValue(), centroids);
+  m_CarinaZ = centroids[1][2];
+  // add one slice to include carina 
+  m_CarinaZ += Carina->GetSpacing()[2];
+  // We dont need Carina structure from now
+  Carina->Delete();
+  GetAFDB()->SetPoint3D("CarinaPoint", centroids[1]);
+  
+  // Crop Inf, remove below Carina
+  m_Input = 
+    clitk::CropImageRemoveLowerThan<ImageType>(m_Input, 2, m_CarinaZ, false, GetBackgroundValue());  
+
+  // Crop post
+  double m_CarinaY = centroids[1][1];
+  m_Input = clitk::CropImageRemoveGreaterThan<ImageType>(m_Input, 1,
+                                                         m_CarinaY+GetMaxDistancePostToCarina(), 
+                                                         false, GetBackgroundValue());  
+  // Crop ant 
+  m_Input = clitk::CropImageRemoveLowerThan<ImageType>(m_Input, 1, 
+                                                       m_CarinaY-GetMaxDistanceAntToCarina(), 
+                                                       false, GetBackgroundValue());  
+  // Crop Right
+  double m_CarinaX = centroids[1][0];
+  m_Input = clitk::CropImageRemoveLowerThan<ImageType>(m_Input, 0, 
+                                                       m_CarinaX-GetMaxDistanceRightToCarina(), 
+                                                       false, GetBackgroundValue());  
+  // Crop Left
+  m_Input = clitk::CropImageRemoveGreaterThan<ImageType>(m_Input, 0, 
+                                                         m_CarinaX+GetMaxDistanceLeftToCarina(), 
+                                                         false, GetBackgroundValue());  
+
+  /*
+  // AutoCrop with Mediastinum, generaly only allow to remove few slices (superiorly)
+  m_Mediastinum  = GetAFDB()->template GetImage<MaskImageType>("Mediastinum");
+  // Resize like input (sup to carina)
+  m_Mediastinum = clitk::ResizeImageLike<MaskImageType>(m_Mediastinum, m_Input, GetBackgroundValue());
+  // Auto crop
+  m_Mediastinum = clitk::AutoCrop<MaskImageType>(m_Mediastinum, GetBackgroundValue());
+  // Resize input
+  m_Input = clitk::ResizeImageLike<ImageType>(m_Input, m_Mediastinum, GetBackgroundValue());
+  */
+
+  //  writeImage<ImageType>(m_Input, "crop.mhd");
+  // End
+  StopCurrentStep<ImageType>(m_Input);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+TrackBifurcationFromPoint(MaskImagePointer & recon, 
+                          std::vector<MaskSlicePointer> & slices_recon, 
+                          MaskImagePointType point3D, 
+                          MaskImagePointType pointMaxSlice,
+                          LabelType newLabel,
+                          std::vector<MaskImagePointType> & bifurcations) {
+  StartNewStep("Track the SoughtVessel from the seed point");
+
+  // Find first slice index
+  MaskImageIndexType index;
+  recon->TransformPhysicalPointToIndex(point3D, index);
+  int numberOfBifurcation = 0;
+  typedef typename MaskSliceType::PointType SlicePointType;
+  SlicePointType previousCenter;
+  
+  // Max slice
+  MaskImageIndexType indexMaxSlice;
+  recon->TransformPhysicalPointToIndex(pointMaxSlice, indexMaxSlice);  
+  uint maxSlice = indexMaxSlice[2];
+
+  // Get current label at the point3D of interest
+  uint currentSlice=index[2]; 
+  bool found = false;
+  LabelType previous_slice_label=recon->GetPixel(index);
+  //  DD(slices_recon.size());
+  do {
+    //    DD(currentSlice);
+    // Consider current reconstructed slice
+    MaskSlicePointer s = slices_recon[currentSlice];
+    MaskSlicePointer previous;
+    if (currentSlice == index[2]) previous = s;
+    else {
+      previous = slices_recon[currentSlice-1];
+    }
+    
+    // Get centroids of the labels in the current slice
+    static const unsigned int Dim = MaskSliceType::ImageDimension;
+    typedef itk::ShapeLabelObject< LabelType, Dim > LabelObjectType;
+    typedef itk::LabelMap< LabelObjectType > LabelMapType;
+    typedef itk::LabelImageToLabelMapFilter<MaskSliceType, LabelMapType> ImageToMapFilterType;
+    typename ImageToMapFilterType::Pointer imageToLabelFilter = ImageToMapFilterType::New(); 
+    typedef itk::ShapeLabelMapFilter<LabelMapType, MaskSliceType> ShapeFilterType; 
+    typename ShapeFilterType::Pointer statFilter = ShapeFilterType::New();
+    imageToLabelFilter->SetBackgroundValue(GetBackgroundValue());
+    imageToLabelFilter->SetInput(s);
+    statFilter->SetInput(imageToLabelFilter->GetOutput()); 
+    // statFilter->SetComputeFeretDiameter( true );
+    statFilter->ComputePerimeterOn(); // To be able to get proper Roundness value
+    statFilter->Update();
+    typename LabelMapType::Pointer labelMap = statFilter->GetOutput();
+
+    // Look what centroid inside the previous largest one
+    std::vector<SlicePointType> centroids;
+    std::vector<LabelType> centroids_label;
+    std::vector<double> labels_size;
+    for(uint c=0; c<labelMap->GetNumberOfLabelObjects(); c++) {
+      int label = labelMap->GetLabels()[c];
+      //      DD(label);
+      SlicePointType center = labelMap->GetLabelObject(label)->GetCentroid();
+      //      DD(center);
+      // Get label into previous slice
+      typename MaskSliceType::IndexType centerIndex;
+      previous->TransformPhysicalPointToIndex(center, centerIndex);
+      LabelType labelInPreviousSlice = previous->GetPixel(centerIndex);
+      // if this current centroid was in the current label, add it to bifurcations
+      if (labelInPreviousSlice == previous_slice_label) {
+        centroids.push_back(center);
+        centroids_label.push_back(label);
+        labels_size.push_back(labelMap->GetLabelObject(label)->GetPhysicalSize());
+        //DD(labels_size.back());
+        //DD(labelMap->GetLabelObject(label)->GetRoundness());
+        // previousCenter = centroids.back();
+      }
+    }
+
+    // -------------------------
+    // If no centroid were found
+    if (centroids.size() == 0) {
+      // Last attempt to find -> check if previous centroid is inside a CCL
+      //      if in s -> get value, getcentroid add.
+      //      DD(currentSlice);
+      //DD("Last change to find");
+      //DD(previous_slice_label);
+      //DD(newLabel);
+      typename MaskSliceType::IndexType previousCenterIndex;
+      s->TransformPhysicalPointToIndex(previousCenter, previousCenterIndex);
+      //DD(previousCenter);
+      LabelType labelInSlice = s->GetPixel(previousCenterIndex);
+      //DD(labelInSlice);
+      if (labelInSlice != GetBackgroundValue()) {
+        centroids.push_back(labelMap->GetLabelObject(labelInSlice)->GetCentroid());
+        centroids_label.push_back(labelInSlice);
+        labels_size.push_back(labelMap->GetLabelObject(labelInSlice)->GetPhysicalSize());
+      }
+    }
+
+    // Some centroid were found
+    // If several centroids, we found a bifurcation
+    if (centroids.size() > 1) {
+      //      int n = centroids.size();
+      // Debug point
+      std::vector<ImagePointType> d;
+      clitk::PointsUtils<MaskImageType>::Convert2DListTo3DList(centroids, currentSlice, m_Mask, d);
+      //      DDV(d, d.size());
+
+      /*
+      // try one or all centroids
+      std::vector<
+      for(uint a<=0; a<nb++; a++) {
+      DD(a);
+      // Create the list of candidates
+      std::vector<int> c;
+      if (a==nb) { for(uint x=0; x<nb; x++) c.push_back(x); }
+      else c.push_back(a);
+      DD(a.size());
+
+      // Test size
+      double size=0.0;
+      for(uint x=0; x<c.size(); c++) { size += labels_size[c[x]]; }
+      DD(size);
+      */        
+
+
+      // new potential bifurcation found
+      numberOfBifurcation++;
+      // If the number of bifurcation is greater than the required one, we stop
+      if (numberOfBifurcation > GetMaxNumberOfFoundBifurcation()) {
+        found = true;
+        //DD("max bif reach");
+        for(uint c=0; c<centroids.size(); c++) {
+          ImagePointType bif;
+          clitk::PointsUtils<MaskImageType>::Convert2DTo3D(centroids[c], m_Mask, currentSlice, bif);
+          bifurcations.push_back(bif);
+        }
+      }
+      // Else we continue along the main (largest) connected component
+      else {
+        int indexOfLargest = 0;
+        for(uint b=0; b<centroids.size(); b++) {
+          if (labels_size[b] > labels_size[indexOfLargest]) {
+            indexOfLargest = b;
+          }
+        }
+        //DD(indexOfLargest);
+        //DD(labels_size[indexOfLargest]);
+        SlicePointType c = centroids[indexOfLargest];
+        LabelType l = centroids_label[indexOfLargest];
+        //DD(l);
+        //DD(c);
+        centroids.clear();
+        centroids.push_back(c);
+        centroids_label.clear();
+        centroids_label.push_back(l);
+      }
+    }
+
+
+    /*    ==> here all centroid are considered as ok.*/
+    
+    // REMOVE IF CENTROID=1, REPLACE BY >0
+    
+    // if only one centroids, we change the current image with the current label 
+    if (centroids.size() == 1) {
+      //DD(centroids_label[0]);
+      s = clitk::SetBackground<MaskSliceType, MaskSliceType>(s, s, centroids_label[0], newLabel, true);
+      slices_recon[currentSlice] = s;
+      previous_slice_label = newLabel;
+      // It can happend that several CCL share this same label. To
+      // prevent this case, we only consider the one that contains
+      // the centroid. 
+      MaskSlicePointer temp = clitk::Binarize<MaskSliceType>(s, newLabel, newLabel, GetBackgroundValue(), GetForegroundValue());
+      //      writeImage<MaskSliceType>(temp, "bin-"+toString(currentSlice)+".mhd");
+      temp = clitk::Labelize<MaskSliceType>(temp, GetBackgroundValue(), true, 1);
+      //writeImage<MaskSliceType>(temp, "label-"+toString(currentSlice)+".mhd");
+      typename MaskSliceType::IndexType centroids_index;
+      temp->TransformPhysicalPointToIndex(centroids[0], centroids_index);
+      typename MaskSliceType::PixelType v = temp->GetPixel(centroids_index); 
+
+      // It can happend that the centroid is inside the BG, so we keep
+      // the largest CCL (the first);
+      if (v == GetBackgroundValue()) {
+        //        DD(currentSlice);
+        //        DD("inside BG");
+        //        DD(centroids[0]);
+        v = 1; // largest one
+      }
+
+      //DD(v);
+      temp = clitk::Binarize<MaskSliceType>(temp, v, v, GetBackgroundValue(), newLabel);      
+      //writeImage<MaskSliceType>(temp, "relabel-"+toString(currentSlice)+".mhd");      
+      s = temp;
+      slices_recon[currentSlice] = s;
+
+      // I need to recompute the centroid if we have removed some
+      // connected component.
+      clitk::ComputeCentroids<MaskSliceType>(s, GetBackgroundValue(), centroids);
+      previousCenter = centroids[1];
+    }
+
+    if (centroids.size() == 0) {
+      //      DD("ZERO");
+      found = true;
+    }
+
+    if (currentSlice == slices_recon.size()-1) {
+      //      DD("end of slices");
+      found = true;
+    }
+    
+    if (currentSlice == maxSlice) {
+      //      DD("end max slice");
+      found = true;
+    }
+
+    // iterate
+    ++currentSlice;
+  } while (!found);
+
+  // End
+  StopCurrentStep();
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractMediastinalVesselsFilter<TImageType>::
+TrackVesselsFromPoint(MaskImagePointer & recon, 
+                      std::vector<MaskSlicePointer> & slices, 
+                      MaskImagePointType seedPoint, 
+                      MaskImagePointType pointMaxSlice,
+                      LabelType newLabel) {
+  StartNewStep("Track the SoughtVessel from the seed point");
+
+  // Find first slice index
+  MaskImageIndexType seedIndex;
+  recon->TransformPhysicalPointToIndex(seedPoint, seedIndex);
+  //  int numberOfBifurcation = 0;
+  typedef typename MaskSliceType::PointType SlicePointType;
+  SlicePointType previousCentroid;
+  previousCentroid[0] = seedPoint[0];
+  previousCentroid[1] = seedPoint[1];
+  
+  // Max slice
+  MaskImageIndexType indexMaxSlice;
+  recon->TransformPhysicalPointToIndex(pointMaxSlice, indexMaxSlice);  
+  uint maxSlice = std::min((uint)indexMaxSlice[2], (uint)slices.size());
+  //  DD(maxSlice);
+
+  // Get current label at the seedPoint of interest
+  uint currentSlice=seedIndex[2]; 
+  bool found = false;
+  // LabelType previous_slice_label=recon->GetPixel(seedIndex);
+  
+  // Currrent label map variable
+  typedef itk::ShapeLabelObject< LabelType, 2> LabelObjectType;
+  typedef itk::LabelMap< LabelObjectType > LabelMapType;
+  typename LabelMapType::Pointer labelMap;
+  std::vector<typename LabelObjectType::Pointer> shapeObjectsList;
+  std::vector<MaskSlicePointer> shapeObjectsSliceList; // keep slice, useful for 'union'
+  typename LabelObjectType::Pointer previousShapeObject;
+
+  do {
+    // Debug
+    std::cout << std::endl;
+    //DD(currentSlice);
+    ImagePointType c;
+    clitk::PointsUtils<MaskImageType>::Convert2DTo3D(previousCentroid, m_Mask, currentSlice-1, c);
+    //DD(c);
+
+    // Consider current reconstructed slice
+    MaskSlicePointer s = slices[currentSlice];
+    MaskSlicePointer previous;
+    shapeObjectsList.clear();
+    shapeObjectsSliceList.clear();
+
+    // Get shape of all labels in the current slice (it is already labelized)
+
+    // Normal -> same CCL with different label
+    // PB -> sometimes same label in different CCL ! car growing
+    //ADD les deux l+s ? mais avec max entre chaque ccl number  (bof)
+    /*
+      for each label in s -> map avec label in l; if different -> change
+     */
+    MaskSlicePointer ll = clitk::Labelize<MaskSliceType>(s, GetBackgroundValue(), true, 1);
+    //    writeImage<MaskSliceType>(s, "slice-"+toString(currentSlice)+".mhd");
+    //writeImage<MaskSliceType>(ll, "slice-label-"+toString(currentSlice)+".mhd");
+    typedef itk::ImageRegionIteratorWithIndex<MaskSliceType> IteratorType;
+    IteratorType its(s, s->GetLargestPossibleRegion());
+    IteratorType itl(ll, ll->GetLargestPossibleRegion());
+    std::map<LabelType, LabelType> labelInL;
+    std::map<LabelType, std::map<LabelType, LabelType> > labelToChange;
+    its.GoToBegin();
+    itl.GoToBegin();
+    int currentLabel = newLabel+10;
+    while (!its.IsAtEnd()) {
+      LabelType labs = its.Get();
+      if (labs != GetBackgroundValue()) {
+        LabelType labl = itl.Get();
+        if (labelInL.find(labs) == labelInL.end()) { // Not found in map, first time
+          //          DD("first");
+          labelInL[labs] = labl;
+          //DD(labs);
+          //DD(labl);
+        }
+        else {
+          if (labelInL[labs] != labl) { // I found a labs with a different labl. Store it.
+            if (labelToChange[labs].find(labl) == labelToChange[labs].end()) { // if not already found
+              //DD("found");
+              //DD(labs);
+              //DD(labl);
+              //DD(labelInL[labs]);
+              //DD(currentLabel);
+              labelToChange[labs][labl] = currentLabel;
+              ++currentLabel;
+            }
+          }
+        }
+      }
+      ++its;
+      ++itl;
+    }
+
+    its.GoToBegin();
+    itl.GoToBegin();
+    while (!its.IsAtEnd()) {
+      LabelType labs = its.Get();
+      if (labs != GetBackgroundValue()) { // if not BG
+        LabelType labl = itl.Get();
+        if (labelToChange[labs].find(labl) != labelToChange[labs].end()) { // if some labs can change their label
+          its.Set(labelToChange[labs][labl]); // change with the label for <labs-labl> 
+        }
+      }
+      ++its;
+      ++itl;
+    } // end while 
+    
+    //    writeImage<MaskSliceType>(s, "slice-final"+toString(currentSlice)+".mhd");
+
+
+    labelMap = clitk::ComputeLabelMap<MaskSliceType, LabelType>(s, GetBackgroundValue(), true);
+    //    DD(labelMap->GetNumberOfLabelObjects());
+
+    // If this is the first slice, get the object that contains the seed
+    if (currentSlice == seedIndex[2]) {
+      // DD("First slice");
+      LabelType l = recon->GetPixel(seedIndex);
+      // DD(l);
+      shapeObjectsList.push_back(labelMap->GetLabelObject(l));
+      shapeObjectsSliceList.push_back(s);
+      previous = s;
+      previousCentroid = shapeObjectsList[0]->GetCentroid();
+      previousShapeObject = shapeObjectsList[0];
+    }
+    else {
+      previous = slices[currentSlice-1];
+      // Loop on labels to check if centroid is on the previous contour
+      for(uint c=0; c<labelMap->GetNumberOfLabelObjects(); c++) {
+        // Get the current label number
+        int label = labelMap->GetLabels()[c];
+        //DD(label);
+        // Get the centroids
+        SlicePointType centroid = labelMap->GetLabelObject(label)->GetCentroid();
+        // Convert centroid into index in previous slice (same coordinate)
+        typename MaskSliceType::IndexType centroidIndex;
+        previous->TransformPhysicalPointToIndex(centroid, centroidIndex);
+        LabelType labelInPreviousSlice = previous->GetPixel(centroidIndex);
+        // if this current centroid was in the current label, we keep it
+        //DD(labelInPreviousSlice);
+        if (labelInPreviousSlice == newLabel) {
+          shapeObjectsList.push_back(labelMap->GetLabelObject(label));
+          shapeObjectsSliceList.push_back(s);
+        }
+      }
+    }
+    
+    
+    // Potentially the previous centroid could be inside another
+    // labels, we consider i
+    typename MaskSliceType::IndexType previousCentroidIndex;
+    s->TransformPhysicalPointToIndex(previousCentroid, previousCentroidIndex);
+    LabelType l = s->GetPixel(previousCentroidIndex);
+    //DD(l);
+    if (l != 0) { // if is not the background label
+      int index = -1;
+      for(uint c=0; c<shapeObjectsList.size(); c++) {
+        if (shapeObjectsList[c]->GetLabel() == l) {
+          index = c;
+        }
+      }
+      if (index == -1) {
+        //DD("not inside");
+        shapeObjectsList.push_back(labelMap->GetLabelObject(l));
+        shapeObjectsSliceList.push_back(s);
+      }
+      else {
+        // DD("already inside");
+      }
+    }
+
+    // for(uint c=0; c<shapeObjectsList.size(); c++) {
+    //   std::cout << c << " " << shapeObjectsList[c]->GetLabel() << " " 
+    //             << shapeObjectsList[c]->GetCentroid() << std::endl;
+    // }
+
+
+    // If several candidates, add one more with the union of all candidates
+    MaskSlicePointer temp;
+    if (shapeObjectsList.size() > 1) {
+      //DD("add union");
+      // Copy the slice
+      temp = clitk::Clone<MaskSliceType>(s);
+      // change label to a single label
+      LabelType l = newLabel+1;
+      for(uint c=0; c<shapeObjectsList.size(); c++) {
+        LabelType ll = shapeObjectsList[c]->GetLabel();
+        temp = clitk::SetBackground<MaskSliceType, MaskSliceType>(temp, temp, ll, l, true);
+      }
+      // Compute Label object properties
+      labelMap = clitk::ComputeLabelMap<MaskSliceType, LabelType>(temp, GetBackgroundValue(), true);
+      shapeObjectsList.push_back(labelMap->GetLabelObject(l));
+      shapeObjectsSliceList.push_back(temp);
+    }
+    
+    /*
+    for(uint c=0; c<shapeObjectsList.size(); c++) {
+      std::cout << c << " " << shapeObjectsList[c]->GetLabel() << " " 
+                << shapeObjectsList[c]->GetCentroid() << std::endl;
+    }
+    */
+    
+
+    for(uint c=0; c<shapeObjectsList.size(); c++) {
+      ImagePointType cc;
+      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(shapeObjectsList[c]->GetCentroid(), m_Mask, currentSlice, cc);
+      // std::cout << c << " " << shapeObjectsList[c]->GetLabel() << " " 
+      //   //                << shapeObjectsList[c]->GetCentroid() << " " 
+      //           << cc << " " 
+      //           << shapeObjectsList[c]->GetPhysicalSize() << " " 
+      //           << shapeObjectsList[c]->GetRoundness() << std::endl;
+    }
+
+
+    if (shapeObjectsList.size() == 0) {
+      found = true;
+    }
+    else {
+      // Heuristic to select the good one. For each candidate, we consider the size
+      std::vector<double> sizes;
+      std::vector<double> roundness;
+      std::vector<size_t> index_sizes;
+      std::vector<size_t> index_roundness;    
+      double previousSize = previousShapeObject->GetPhysicalSize();
+      //DD(previousSize);
+      for(uint c=0; c<shapeObjectsList.size(); c++) {
+        double s = shapeObjectsList[c]->GetPhysicalSize();
+        sizes.push_back(fabs(previousSize-s)/previousSize);
+        roundness.push_back(fabs(1.0-shapeObjectsList[c]->GetRoundness()));
+        index_sizes.push_back(c);
+        index_roundness.push_back(c);
+      }
+      //DDV(sizes, sizes.size());
+      //DDV(roundness, roundness.size());
+      // DDV(index_sizes, index_sizes.size());
+      // DDV(index_roundness, index_roundness.size());
+      sort(index_sizes.begin(), index_sizes.end(), index_cmp<std::vector<double>&>(sizes));
+      sort(index_roundness.begin(), index_roundness.end(), index_cmp<std::vector<double>&>(roundness));
+      //DDV(index_sizes, index_sizes.size());
+      // DDV(index_roundness, index_roundness.size());
+
+      // TEMPORARY GET THE FIRST
+      int best = index_sizes[0];
+      // if (currentSlice == seedIndex[2]) { // first contour => idiot, first = single contour
+      //   best = index_roundness[0]; // best is more round
+      // }
+      LabelType label = shapeObjectsList[best]->GetLabel();
+      //      DD(label);
+      s = shapeObjectsSliceList[best];
+      s = clitk::SetBackground<MaskSliceType, MaskSliceType>(s, s, label, newLabel, true);
+
+      // HERE
+
+      // It can happend that several CCL share this same label. To
+      // prevent this case, we only consider the one that contains
+      // the centroid. 
+
+      // TODO -> PREVIOUS CENTROID ???
+
+      MaskSlicePointer temp = clitk::Binarize<MaskSliceType>(s, newLabel, newLabel, GetBackgroundValue(), GetForegroundValue());
+      temp = clitk::Labelize<MaskSliceType>(temp, GetBackgroundValue(), true, 1);
+      typename MaskSliceType::IndexType centroids_index;
+      temp->TransformPhysicalPointToIndex(shapeObjectsList[best]->GetCentroid(), centroids_index);
+      typename MaskSliceType::PixelType v = temp->GetPixel(centroids_index); 
+        if (v == GetBackgroundValue()) {
+          // DD(currentSlice);
+          // DD("inside BG");
+          //DD(centroids[0]);
+          v = 1; // largest one
+        }
+        
+        //DD(v);
+        temp = clitk::Binarize<MaskSliceType>(temp, v, v, GetBackgroundValue(), newLabel);      
+        //writeImage<MaskSliceType>(temp, "relabel-"+toString(currentSlice)+".mhd");      
+        s = temp;
+
+      
+      // end 
+      slices[currentSlice] = s;
+      previousCentroid = shapeObjectsList[best]->GetCentroid();
+      previousShapeObject = shapeObjectsList[best];
+    }
+
+    ++currentSlice;
+    
+    if (currentSlice == maxSlice) {
+      // DD("end max slice");
+      found = true;
+    }
+
+  } while (!found);
+  
+  /*
+  // -------------------------
+  // If no centroid were found
+  if (shapeObjectsList.size() == 0) {
+  // Last attempt to find -> check if previous centroid is inside a CCL
+  //      if in s -> get value, getcentroid add.
+  DD(currentSlice);
+  DD("Last change to find");
+  DD(previous_slice_label);
+  DD(newLabel);
+  typename MaskSliceType::IndexType previousCentroidIndex;
+  s->TransformPhysicalPointToIndex(previousCentroid, previousCentroidIndex);
+  DD(previousCentroid);
+  LabelType labelInSlice = s->GetPixel(previousCentroidIndex);
+  DD(labelInSlice);
+  if (labelInSlice != GetBackgroundValue()) {
+  centroids.push_back(labelMap->GetLabelObject(labelInSlice)->GetCentroid());
+  centroids_label.push_back(labelInSlice);
+  labels_size.push_back(labelMap->GetLabelObject(labelInSlice)->GetPhysicalSize());
+  }
+  }
+
+  // Some centroid were found
+  // If several centroids, we found a bifurcation
+  if (centroids.size() > 1) {
+  //      int n = centroids.size();
+  // Debug point
+  std::vector<ImagePointType> d;
+  clitk::PointsUtils<MaskImageType>::Convert2DListTo3DList(centroids, currentSlice, m_Mask, d);
+  DDV(d, d.size());
+
+  // new potential bifurcation found
+  numberOfBifurcation++;
+  // If the number of bifurcation is greater than the required one, we stop
+  if (numberOfBifurcation > GetMaxNumberOfFoundBifurcation()) {
+  found = true;
+  DD("max bif reach");
+  for(uint c=0; c<centroids.size(); c++) {
+  ImagePointType bif;
+  clitk::PointsUtils<MaskImageType>::Convert2DTo3D(centroids[c], m_Mask, currentSlice, bif);
+  bifurcations.push_back(bif);
+  }
+  }
+  // Else we continue along the main (largest) connected component
+  else {
+  int indexOfLargest = 0;
+  for(uint b=0; b<centroids.size(); b++) {
+  if (labels_size[b] > labels_size[indexOfLargest]) {
+  indexOfLargest = b;
+  }
+  }
+  DD(indexOfLargest);
+  DD(labels_size[indexOfLargest]);
+  SlicePointType c = centroids[indexOfLargest];
+  LabelType l = centroids_label[indexOfLargest];
+  DD(l);
+  DD(c);
+  centroids.clear();
+  centroids.push_back(c);
+  centroids_label.clear();
+  centroids_label.push_back(l);
+  }
+  }
+  */
+
+  /*    ==> here all centroid are considered as ok.*/
+    
+  /*
+  // REMOVE IF CENTROID=1, REPLACE BY >0
+    
+  // if only one centroids, we change the current image with the current label 
+  if (centroids.size() == 1) {
+  DD(centroids_label[0]);
+  s = clitk::SetBackground<MaskSliceType, MaskSliceType>(s, s, centroids_label[0], newLabel, true);
+  slices[currentSlice] = s;
+  previous_slice_label = newLabel;
+  // It can happend that several CCL share this same label. To
+  // prevent this case, we only consider the one that contains
+  // the centroid. 
+  MaskSlicePointer temp = clitk::Binarize<MaskSliceType>(s, newLabel, newLabel, GetBackgroundValue(), GetForegroundValue());
+  //      writeImage<MaskSliceType>(temp, "bin-"+toString(currentSlice)+".mhd");
+  temp = clitk::Labelize<MaskSliceType>(temp, GetBackgroundValue(), true, 1);
+  //writeImage<MaskSliceType>(temp, "label-"+toString(currentSlice)+".mhd");
+  typename MaskSliceType::IndexType centroids_index;
+  temp->TransformPhysicalPointToIndex(centroids[0], centroids_index);
+  typename MaskSliceType::PixelType v = temp->GetPixel(centroids_index); 
+
+  // It can happend that the centroid is inside the BG, so we keep
+  // the largest CCL (the first);
+  if (v == GetBackgroundValue()) {
+  DD(currentSlice);
+  DD("inside BG");
+  DD(centroids[0]);
+  v = 1; // largest one
+  }
+
+  //DD(v);
+  temp = clitk::Binarize<MaskSliceType>(temp, v, v, GetBackgroundValue(), newLabel);      
+  //writeImage<MaskSliceType>(temp, "relabel-"+toString(currentSlice)+".mhd");      
+  s = temp;
+  slices[currentSlice] = s;
+
+  // I need to recompute the centroid if we have removed some
+  // connected component.
+  clitk::ComputeCentroids<MaskSliceType>(s, GetBackgroundValue(), centroids);
+  previousCentroid = centroids[1];
+  }
+
+  if (centroids.size() == 0) {
+  DD("ZERO");
+  found = true;
+  }
+
+  if (currentSlice == slices.size()-1) {
+  DD("end of slices");
+  found = true;
+  }
+    
+  if (currentSlice == maxSlice) {
+  DD("end max slice");
+  found = true;
+  }
+
+  // iterate
+  ++currentSlice;
+  } while (!found);
+  */
+
+  // End
+  StopCurrentStep();
+}
+//--------------------------------------------------------------------
+
+
+#endif //#define CLITKEXTRACTMEDIASTINALVESSELSFILTER_TXX
diff --git a/segmentation/clitkExtractMediastinalVesselsGenericFilter.h b/segmentation/clitkExtractMediastinalVesselsGenericFilter.h
new file mode 100644 (file)
index 0000000..9e53d7a
--- /dev/null
@@ -0,0 +1,80 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+#ifndef CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_H
+#define CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_H
+
+#include "clitkIO.h"
+#include "clitkImageToImageGenericFilter.h"
+#include "clitkExtractMediastinalVesselsFilter.h"
+
+//--------------------------------------------------------------------
+namespace clitk 
+{
+  
+  template<class ArgsInfoType>
+  class ITK_EXPORT ExtractMediastinalVesselsGenericFilter: 
+    public ImageToImageGenericFilter<ExtractMediastinalVesselsGenericFilter<ArgsInfoType> >
+  {
+    
+  public:
+    //--------------------------------------------------------------------
+    ExtractMediastinalVesselsGenericFilter();
+
+    //--------------------------------------------------------------------
+    typedef ImageToImageGenericFilter<ExtractMediastinalVesselsGenericFilter<ArgsInfoType> > Superclass;
+    typedef ExtractMediastinalVesselsGenericFilter Self;
+    typedef itk::SmartPointer<Self>           Pointer;
+    typedef itk::SmartPointer<const Self>     ConstPointer;
+
+    //--------------------------------------------------------------------
+    itkNewMacro(Self);  
+    itkTypeMacro(ExtractMediastinalVesselsGenericFilter, LightObject);
+
+    //--------------------------------------------------------------------
+    // Options for the GenericFilter
+    void SetArgsInfo(const ArgsInfoType & a);
+
+    //--------------------------------------------------------------------
+    // Options for the Filter
+    template<class FilterType> 
+    void SetOptionsFromArgsInfoToFilter(FilterType * f) ;
+
+    //--------------------------------------------------------------------
+    // Main function called each time the filter is updated
+    template<class ImageType>  
+    void UpdateWithInputImageType();
+
+  protected:
+    template<unsigned int Dim> void InitializeImageType();
+    ArgsInfoType mArgsInfo;
+    
+  private:
+    ExtractMediastinalVesselsGenericFilter(const Self&); //purposely not implemented
+    void operator=(const Self&); //purposely not implemented
+    
+  }; // end class
+  //--------------------------------------------------------------------
+    
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkExtractMediastinalVesselsGenericFilter.txx"
+#endif
+
+#endif // #define CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_H
diff --git a/segmentation/clitkExtractMediastinalVesselsGenericFilter.txx b/segmentation/clitkExtractMediastinalVesselsGenericFilter.txx
new file mode 100644 (file)
index 0000000..71f8c6b
--- /dev/null
@@ -0,0 +1,125 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+#ifndef CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_TXX
+#define CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_TXX
+
+#include "clitkImageCommon.h"
+  
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::ExtractMediastinalVesselsGenericFilter():
+  ImageToImageGenericFilter<Self>("ExtractMediastinalVessels") 
+{
+  // Default values
+  cmdline_parser_clitkExtractMediastinalVessels_init(&mArgsInfo);
+  InitializeImageType<3>(); // Only for 3D images
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<unsigned int Dim>
+void clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::InitializeImageType() 
+{  
+  ADD_IMAGE_TYPE(Dim, short); // Can add float later
+}
+//--------------------------------------------------------------------
+  
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+void clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoType & a) 
+{
+  mArgsInfo=a;
+  SetIOVerbose(mArgsInfo.verbose_flag);
+  if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
+  if (mArgsInfo.input_given) AddInputFilename(mArgsInfo.input_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void 
+clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f)
+{
+  f->SetVerboseOptionFlag(mArgsInfo.verbose_flag);
+  f->SetVerboseStepFlag(mArgsInfo.verboseStep_flag);
+  f->SetWriteStepFlag(mArgsInfo.writeStep_flag);
+  f->SetVerboseMemoryFlag(mArgsInfo.verboseMemory_flag);
+  f->SetAFDBFilename(mArgsInfo.afdb_arg);  
+
+  f->SetThresholdHigh(mArgsInfo.thresholdHigh_arg);
+  f->SetThresholdLow(mArgsInfo.thresholdLow_arg);
+  f->SetErosionRadius(mArgsInfo.erode_arg);
+  f->SetDilatationRadius(mArgsInfo.dilate_arg);
+  
+  f->SetMaxDistancePostToCarina(mArgsInfo.maxPost_arg);
+  f->SetMaxDistanceAntToCarina(mArgsInfo.maxAnt_arg);
+  f->SetMaxDistanceLeftToCarina(mArgsInfo.maxLeft_arg);
+  f->SetMaxDistanceRightToCarina(mArgsInfo.maxRight_arg);
+  
+  f->SetSoughtVesselSeedName(mArgsInfo.seed_arg);
+  f->SetSoughtVesselName(mArgsInfo.name_arg);
+  f->SetMaxNumberOfFoundBifurcation(mArgsInfo.bif_arg);
+
+  f->SetFinalOpeningRadius(mArgsInfo.open_arg);
+  
+  // Output filename
+  this->AddOutputFilename(mArgsInfo.output_arg);
+  f->SetOutputFilename(mArgsInfo.output_arg);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class ImageType>
+void clitk::ExtractMediastinalVesselsGenericFilter<ArgsInfoType>::UpdateWithInputImageType() 
+{ 
+  // Reading input
+  typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
+
+  // Create filter
+  typedef clitk::ExtractMediastinalVesselsFilter<ImageType> FilterType;
+  typename FilterType::Pointer filter = FilterType::New();
+    
+  // Set global Options 
+  filter->SetInput(input);
+  SetOptionsFromArgsInfoToFilter<FilterType>(filter);
+
+  // Go !
+  filter->Update();
+
+  // Write/Save results
+  for(uint i=0; i<filter->GetNumberOfOutputs(); i++) {
+    typedef uchar MaskImagePixelType;
+    typedef itk::Image<MaskImagePixelType, 3> OutputImageType;
+    typename OutputImageType::Pointer output = filter->GetOutput(i);
+    this->template SetNextOutput<OutputImageType>(output); 
+  }
+}
+//--------------------------------------------------------------------
+
+#endif //#define CLITKEXTRACTLYMPHSTATIONSSGENERICFILTER_TXX
index f5f740b93e4e7d7842cc55eef0251be4e1aee9e1..bbb473dae195f85c2893ffd5ef71cab2530bf522 100644 (file)
@@ -15,22 +15,24 @@ option "verboseMemory"  -  "Display memory usage"         flag          off
 section "I/O"
 
 option "input"     i   "Input CT filename"               string        yes
-option "afdb"      a   "Input Anatomical Feature DB"     string        no
+option "output"    o   "Output lungs mask filename"      string        yes
+option "afdb"      a   "Input Anatomical Feature DB (needs Patient, Lungs, Trachea, VertebralBody)"     string         no
 option "useBones"  -    "If set : do use bones mask (when image is not injected)"  flag        off
+option "maxAntSpine"  - "Distance max to anterior part of the VertebralBody (spine) in mm"  double no default="10"
 
-option "output"        o       "Output lungs mask filename"      string        yes
-
-section "Step 1 : Left/Right limits with lungs"
 option "spacing"     - "Intermediate resampling spacing"         double no default="6"
-option "fuzzy1"             -  "Fuzzy relative position threshold"       double no default="0.5"
+option "ft_LR_lungs"        -  "RelPos LR limits lungs"          double no default="0.3"
+option "ft_bones"           -  "RelPos AP limits bones"          double no default="0.6"
+option "ft_inf_lungs"       -  "RelPos inf limits bones"         double no default="0.05"
+option "ft_ant_sternum"             -  "RelPos ant limits sternum"       double no default="0.5"
+
+#section "Step 1 : Left/Right limits with lungs"
 
 section "Step 2 : Ant/Post limits with bones"
-option "fuzzy2"             -  "Fuzzy relative position threshold"       double no default="0.6"
-option "antSpine"     -        "Distance max to anterior part of the spine in mm"  double no default="10"
+#option "antSpine"     -       "Distance max to anterior part of the spine in mm"  double no default="10"
 
-section "Step 3 : Inf limits with Lung"
-option "fuzzy3"             -  "Fuzzy relative position threshold"       double no default="0.05"
+#section "Step 3 : Inf limits with Lung"
 
-section "Step x : threshold for removing bones and injected parts"
-option "upper"  - "Upper threshold" double no default="150"
-option "lower"  - "Lower threshold" double no default="-200"
\ No newline at end of file
+section "Step x : threshold for removing bones and injected parts"
+option "upper"  - "Upper threshold" double no default="150"
+option "lower"  - "Lower threshold" double no default="-200"
\ No newline at end of file
index ea7f86aace0697dcf793cf246d3aec0d97e52b53..61abdee1707a5e7ce533741d6908995ade1020d7 100644 (file)
@@ -27,11 +27,12 @@ namespace clitk {
   //--------------------------------------------------------------------
   /*
     Try to extract the mediastinum part of a thorax CT.
-    Inputs : 
-    - Patient label image
-    - Lungs label image
-    - Bones label image
-    - Trachea label image
+    Input masks needed : 
+    - Patient
+    - Lungs 
+    - Bones [Optional]
+    - Trachea
+    - VertebralBody 
   */
   //--------------------------------------------------------------------
   
@@ -63,6 +64,10 @@ namespace clitk {
     typedef typename MaskImageType::IndexType    MaskImageIndexType; 
     typedef typename MaskImageType::PointType    MaskImagePointType; 
         
+    typedef itk::Image<MaskImagePixelType, 2>    MaskSliceType;
+    typedef typename MaskSliceType::Pointer      MaskSlicePointer;
+    typedef typename MaskSliceType::PointType    MaskSlicePointType;
+
     /** Standard class typedefs. */
     typedef itk::ImageToImageFilter<TImageType, MaskImageType> Superclass;
     typedef ExtractMediastinumFilter            Self;
@@ -116,24 +121,15 @@ namespace clitk {
     itkSetMacro(IntermediateSpacing, double);
     itkGetConstMacro(IntermediateSpacing, double);
 
-    itkSetMacro(FuzzyThreshold1, double);
-    itkGetConstMacro(FuzzyThreshold1, double);
-
-    itkSetMacro(FuzzyThreshold2, double);
-    itkGetConstMacro(FuzzyThreshold2, double);
-
-    itkSetMacro(FuzzyThreshold3, double);
-    itkGetConstMacro(FuzzyThreshold3, double);
-
     itkBooleanMacro(UseBones);
     itkSetMacro(UseBones, bool);
     itkGetConstMacro(UseBones, bool);
 
-    itkSetMacro(UpperThreshold, double);
-    itkGetConstMacro(UpperThreshold, double);
+    itkSetMacro(DistanceMaxToAnteriorPartOfTheVertebralBody, double);
+    itkGetConstMacro(DistanceMaxToAnteriorPartOfTheVertebralBody, double);
 
-    itkSetMacro(LowerThreshold, double);
-    itkGetConstMacro(LowerThreshold, double);
+    void SetFuzzyThreshold(std::string tag, double value);
+    double GetFuzzyThreshold(std::string tag);
 
   protected:
     ExtractMediastinumFilter();
@@ -156,15 +152,18 @@ namespace clitk {
     MaskImagePixelType m_BackgroundValue;
     MaskImagePixelType m_ForegroundValue;
 
-    typename MaskImageType::Pointer output;
+    MaskImagePointer output;
+    MaskImagePointer patient;
+    MaskImagePointer lung;
+    MaskImagePointer bones;
+    MaskImagePointer trachea;
 
+    std::map<std::string, double> m_FuzzyThreshold;
     double m_IntermediateSpacing;
-    double m_FuzzyThreshold1;
-    double m_FuzzyThreshold2;
-    double m_FuzzyThreshold3;
     bool   m_UseBones;
-    double m_UpperThreshold;
-    double m_LowerThreshold;
+    double m_DistanceMaxToAnteriorPartOfTheVertebralBody;
+
+    void RemovePostPartOfVertebralBody();
     
     std::string m_OutputMediastinumFilename;
     
index d3ba557b97d863cb7a486aab5c59c742a4f371b0..67bc305d2ae0bf73f5808727fa3750d22c19deff 100644 (file)
@@ -50,7 +50,6 @@ ExtractMediastinumFilter():
   itk::ImageToImageFilter<ImageType, MaskImageType>()
 {
   this->SetNumberOfRequiredInputs(1);
-
   SetBackgroundValuePatient(0);
   SetBackgroundValueLung(0);
   SetBackgroundValueBones(0);
@@ -58,14 +57,12 @@ ExtractMediastinumFilter():
   SetForegroundValueRightLung(2);
   SetBackgroundValue(0);
   SetForegroundValue(1);
-
   SetIntermediateSpacing(6);
-  SetFuzzyThreshold1(0.5);
-  SetFuzzyThreshold2(0.6);
-  SetFuzzyThreshold3(0.05);
-  
-  SetOutputMediastinumFilename("mediastinum.mhd");
-  
+  SetFuzzyThreshold("LR_lungs", 0.3);
+  SetFuzzyThreshold("bones", 0.6);
+  SetFuzzyThreshold("inf_lungs", 0.05);
+  SetDistanceMaxToAnteriorPartOfTheVertebralBody(10);  
+  SetOutputMediastinumFilename("mediastinum.mhd");  
   UseBonesOff();
 }
 //--------------------------------------------------------------------
@@ -121,6 +118,32 @@ SetInputTracheaLabelImage(const MaskImageType * image, MaskImagePixelType bg)
 }
 //--------------------------------------------------------------------
 
+//--------------------------------------------------------------------
+template <class ImageType>
+void 
+clitk::ExtractMediastinumFilter<ImageType>::
+SetFuzzyThreshold(std::string tag, double value)
+{
+  m_FuzzyThreshold[tag] = value;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class ImageType>
+double 
+clitk::ExtractMediastinumFilter<ImageType>::
+GetFuzzyThreshold(std::string tag)
+{
+  if (m_FuzzyThreshold.find(tag) == m_FuzzyThreshold.end()) {
+    clitkExceptionMacro("Could not find options "+tag+" in the list of FuzzyThresholds.");
+    return 0.0;
+  }
+  
+  return m_FuzzyThreshold[tag]; 
+}
+//--------------------------------------------------------------------
+
 
 //--------------------------------------------------------------------
 template <class ImageType>
@@ -158,21 +181,18 @@ GenerateOutputInformation() {
 
   //--------------------------------------------------------------------
   // Get input pointers
-  clitk::PrintMemory(GetVerboseMemoryFlag(), "Initial memory"); // OK
   LoadAFDB();
   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
-  MaskImagePointer patient = GetAFDB()->template GetImage <MaskImageType>("Patient");  
-  MaskImagePointer lung = GetAFDB()->template GetImage <MaskImageType>("Lungs");
-  MaskImagePointer bones;
+  MaskImagePointer patient, lung, bones, trachea;
+  patient = GetAFDB()->template GetImage <MaskImageType>("Patient");
+  lung = GetAFDB()->template GetImage <MaskImageType>("Lungs");
   if (GetUseBones()) {
     bones = GetAFDB()->template GetImage <MaskImageType>("Bones");  
   }
-  MaskImagePointer trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");  
-    
-  clitk::PrintMemory(GetVerboseMemoryFlag(), "After read patient, lung"); 
+  trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");  
   
   //--------------------------------------------------------------------
-  // Step 1: Crop support (patient) to lung extend in RL
+  // Step : Crop support (patient) to lung extend in RL
   StartNewStep("Crop support like lungs along LR");
   typedef clitk::CropLikeImageFilter<MaskImageType> CropFilterType;
   typename CropFilterType::Pointer cropFilter = CropFilterType::New();
@@ -181,9 +201,9 @@ GenerateOutputInformation() {
   cropFilter->Update();
   output = cropFilter->GetOutput();
   this->template StopCurrentStep<MaskImageType>(output);
+
   //--------------------------------------------------------------------
-  // Step 2: Crop support (previous) to bones extend in AP
+  // Step : Crop support (previous) to bones extend in AP
   if (GetUseBones()) {
     StartNewStep("Crop support like bones along AP");
     cropFilter = CropFilterType::New();
@@ -195,7 +215,7 @@ GenerateOutputInformation() {
   }
 
   //--------------------------------------------------------------------
-  // Step 3: patient minus lungs, minus bones, minus trachea
+  // Step : patient minus lungs, minus bones, minus trachea
   StartNewStep("Patient contours minus lungs, trachea [and bones]");
   typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
   typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); 
@@ -221,7 +241,7 @@ GenerateOutputInformation() {
   this->template StopCurrentStep<MaskImageType>(output);
 
   //--------------------------------------------------------------------
-  // Step 4: LR limits from lung (need separate lung ?)
+  // Step : LR limits from lung (need separate lung ?)
   // Get separate lung images to get only the right and left lung
   // (because RelativePositionPropImageFilter only consider fg=1);
   // (label must be '1' because right is greater than left).  (WE DO
@@ -245,13 +265,11 @@ GenerateOutputInformation() {
   relPosFilter->WriteStepFlagOff();
   relPosFilter->SetInput(output); 
   relPosFilter->SetInputObject(left_lung); 
-  //  relPosFilter->SetInputObject(lung); 
   relPosFilter->AddOrientationType(RelPosFilterType::AtRightTo); // warning left lung is at right ;)
   relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
-  relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1());
+  relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("LR_lungs"));
   relPosFilter->Update();
   output = relPosFilter->GetOutput();
-  //writeImage<MaskImageType>(right_lung, "step4-left.mhd");
 
   relPosFilter = RelPosFilterType::New();
   relPosFilter->SetInput(output); 
@@ -260,16 +278,26 @@ GenerateOutputInformation() {
   relPosFilter->WriteStepFlagOff();
   relPosFilter->SetInput(output); 
   relPosFilter->SetInputObject(right_lung);
-  //relPosFilter->SetInputObject(lung); 
   relPosFilter->AddOrientationType(RelPosFilterType::AtLeftTo);
   relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
-  relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1());
+  relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("LR_lungs"));
   relPosFilter->Update();   
   output = relPosFilter->GetOutput();
   this->template StopCurrentStep<MaskImageType>(output);
 
   //--------------------------------------------------------------------
-  // Step 5: AP limits from bones
+  // Step : superior limits
+  StartNewStep("Keep inferior to CricoidCartilag");
+  // load Cricoid, get centroid, cut above (or below), lower bound
+  MaskImagePointer CricoidCartilag = GetAFDB()->template GetImage <MaskImageType>("CricoidCartilag");
+  MaskImagePointType p;
+  p[0] = p[1] = p[2] =  0.0; // to avoid warning
+  clitk::FindExtremaPointInAGivenDirection<MaskImageType>(CricoidCartilag, GetBackgroundValue(), 2, true, p);
+  output = clitk::CropImageRemoveGreaterThan<MaskImageType>(output, 2, p[2], true, GetBackgroundValue());
+  this->template StopCurrentStep<MaskImageType>(output);
+
+  //--------------------------------------------------------------------
+  // Step : AP limits from bones
   // Separate the bones in the ant-post middle
   MaskImageConstPointer bones_ant;
   MaskImageConstPointer bones_post;
@@ -326,7 +354,7 @@ GenerateOutputInformation() {
     relPosFilter->SetInputObject(bones_post); 
     relPosFilter->AddOrientationType(RelPosFilterType::AntTo);
     relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
-    relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold2());
+    relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("bones"));
     relPosFilter->Update();
     output = relPosFilter->GetOutput();
     //    writeImage<MaskImageType>(output, "post.mhd");
@@ -339,14 +367,14 @@ GenerateOutputInformation() {
     relPosFilter->SetInputObject(bones_ant); 
     relPosFilter->AddOrientationType(RelPosFilterType::PostTo);
     relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
-    relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold2());
+    relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold("bones"));
     relPosFilter->Update();   
     output = relPosFilter->GetOutput();
     this->template StopCurrentStep<MaskImageType>(output);
   }
 
   //--------------------------------------------------------------------
-  // Step 6: Get CCL
+  // Step: Get CCL
   StartNewStep("Keep main connected component");
   output = clitk::Labelize<MaskImageType>(output, GetBackgroundValue(), false, 500);
   // output = RemoveLabels<MaskImageType>(output, BG, param->GetLabelsToRemove());
@@ -354,113 +382,23 @@ GenerateOutputInformation() {
                                             GetForegroundValue(), 1, 1, 0);
   this->template StopCurrentStep<MaskImageType>(output);
 
-
-  //--------------------------------------------------------------------
-  // Step 8: Trial segmentation KMeans
-  if (0) {
-    StartNewStep("K means");
-    // Take input, crop like current mask
-    typedef CropLikeImageFilter<ImageType> CropLikeFilterType;
-    typename CropLikeFilterType::Pointer cropLikeFilter = CropLikeFilterType::New();
-    cropLikeFilter->SetInput(input);
-    cropLikeFilter->SetCropLikeImage(output);
-    cropLikeFilter->Update();
-    ImagePointer working_input = cropLikeFilter->GetOutput();
-    writeImage<ImageType>(working_input, "crop-input.mhd");
-    // Set bG at -1000
-    working_input = clitk::SetBackground<ImageType, MaskImageType>(working_input, output, GetBackgroundValue(), -1000, true);
-    writeImage<ImageType>(working_input, "crop-input2.mhd");
-    // Kmeans
-    typedef itk::ScalarImageKmeansImageFilter<ImageType> KMeansFilterType;
-    typename KMeansFilterType::Pointer kmeansFilter = KMeansFilterType::New();
-    kmeansFilter->SetInput(working_input);
-    //  const unsigned int numberOfInitialClasses = 3;
-    // const unsigned int useNonContiguousLabels = 0;
-    kmeansFilter->AddClassWithInitialMean(-1000);
-    kmeansFilter->AddClassWithInitialMean(30);
-    kmeansFilter->AddClassWithInitialMean(-40);  // ==> I want this one
-    DD("Go!");
-    kmeansFilter->Update();
-    DD("End");
-    typename KMeansFilterType::ParametersType estimatedMeans = kmeansFilter->GetFinalMeans();
-    const unsigned int numberOfClasses = estimatedMeans.Size();
-    for ( unsigned int i = 0 ; i < numberOfClasses ; ++i ) {
-      std::cout << "cluster[" << i << "] ";
-      std::cout << "    estimated mean : " << estimatedMeans[i] << std::endl;
-    }
-    MaskImageType::Pointer kmeans = kmeansFilter->GetOutput();
-    kmeans = clitk::SetBackground<MaskImageType, MaskImageType>(kmeans, kmeans, 
-                                                                1, GetBackgroundValue(), true);
-    writeImage<MaskImageType>(kmeans, "kmeans.mhd");
-    // Get final results, and remove from current mask
-    boolFilter = BoolFilterType::New(); 
-    boolFilter->InPlaceOn();
-    boolFilter->SetInput1(output);
-    boolFilter->SetInput2(kmeans);    
-    boolFilter->SetOperationType(BoolFilterType::And);
-    boolFilter->Update();    
-    output = boolFilter->GetOutput();
-    writeImage<MaskImageType>(output, "out-kmean.mhd");
-    this->template StopCurrentStep<MaskImageType>(output);
-
-    // TODO -> FillMASK ?
-    // comment speed ? mask ? 2 class ?
-
-
-    //TODO 
-    // Confidence connected ?
-
-  }
-
   //--------------------------------------------------------------------
-  // Step 8: Lower limits from lung (need separate lung ?)
-  if (0) {
-    // StartNewStep("Trial : minus segmented struct");
-    // MaskImagePointer heart = GetAFDB()->template GetImage <MaskImageType>("heart");  
-    // boolFilter = BoolFilterType::New(); 
-    // boolFilter->InPlaceOn();
-    // boolFilter->SetInput1(output);
-    // boolFilter->SetInput2(heart);
-    // boolFilter->SetOperationType(BoolFilterType::AndNot);
-    // boolFilter->Update();  
-    //  output = boolFilter->GetOutput(); // not needed because InPlace
-    
-    // Not below the heart
-    // relPosFilter = RelPosFilterType::New();
-    // relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-    // relPosFilter->VerboseStepFlagOff();
-    // relPosFilter->WriteStepFlagOff();
-    // relPosFilter->SetInput(output); 
-    // relPosFilter->SetInputObject(heart);
-    // relPosFilter->SetOrientationType(RelPosFilterType::SupTo);
-    // relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
-    // relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold3());
-    // relPosFilter->Update();
-    // output = relPosFilter->GetOutput();
-  }
+  // Step: Remove post part from VertebralBody
+  StartNewStep("Remove post part according to VertebralBody");
+  RemovePostPartOfVertebralBody();
+  this->template StopCurrentStep<MaskImageType>(output);
 
   //--------------------------------------------------------------------
-  // Step 8: Lower limits from lung (need separate lung ?)
-  if (0) {
-    StartNewStep("Lower limits with lungs");
-    // TODO BOFFF ????
-    relPosFilter = RelPosFilterType::New();
-    relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-    relPosFilter->VerboseStepFlagOff();
-    relPosFilter->WriteStepFlagOff();
-    relPosFilter->SetInput(output); 
-    //  relPosFilter->SetInputObject(left_lung); 
-    relPosFilter->SetInputObject(lung); 
-    relPosFilter->AddOrientationType(RelPosFilterType::SupTo);
-    relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
-    relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold3());
-    relPosFilter->Update();
-    output = relPosFilter->GetOutput();
-    this->template StopCurrentStep<MaskImageType>(output);
-  }
+  // Step: Remove ant part according to Sternum
+  StartNewStep("Remove ant part according to Sternum");
+  MaskImagePointer Sternum = GetAFDB()->template GetImage <MaskImageType>("Sternum");
+  output = clitk::SliceBySliceRelativePosition<MaskImageType>(output, Sternum, 2, 
+                                                              GetFuzzyThreshold("ant_sternum"),
+                                                              "PostTo", false, 3, true, false);  
+  this->template StopCurrentStep<MaskImageType>(output);
 
   //--------------------------------------------------------------------
-  // Step 10: Slice by Slice CCL
+  // Step: Slice by Slice CCL
   StartNewStep("Slice by Slice keep only one component");
   typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
   //  typename ExtractSliceFilterType::Pointer 
@@ -486,59 +424,12 @@ GenerateOutputInformation() {
   output = joinFilter->GetOutput();
   this->template StopCurrentStep<MaskImageType>(output);
 
-  //--------------------------------------------------------------------
-  // Step 9: Binarize to remove too high HU
-  // --> warning CCL slice by slice must be done before
-  if (0) {
-    StartNewStep("Remove hypersignal (bones and injected part");
-    // Crop initial ct like current support
-    typedef CropLikeImageFilter<ImageType> CropLikeFilterType;
-    typename CropLikeFilterType::Pointer cropLikeFilter = CropLikeFilterType::New();
-    cropLikeFilter->SetInput(input);
-    cropLikeFilter->SetCropLikeImage(output);
-    cropLikeFilter->Update();
-    ImagePointer working_input = cropLikeFilter->GetOutput();
-    //  writeImage<ImageType>(working_input, "crop-ct.mhd");
-    // Binarize
-    typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> InputBinarizeFilterType; 
-    typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
-    binarizeFilter->SetInput(working_input);
-    binarizeFilter->SetLowerThreshold(GetLowerThreshold());
-    binarizeFilter->SetUpperThreshold(GetUpperThreshold());
-    binarizeFilter->SetInsideValue(this->GetBackgroundValue());  // opposite
-    binarizeFilter->SetOutsideValue(this->GetForegroundValue()); // opposite
-    binarizeFilter->Update();
-    MaskImagePointer working_bin = binarizeFilter->GetOutput();
-    // writeImage<MaskImageType>(working_bin, "bin.mhd");
-    // Remove from support
-    boolFilter = BoolFilterType::New(); 
-    boolFilter->InPlaceOn();
-    boolFilter->SetInput1(output);
-    boolFilter->SetInput2(working_bin);    
-    boolFilter->SetOperationType(BoolFilterType::AndNot);
-    boolFilter->Update();
-    output = boolFilter->GetOutput();
-    StopCurrentStep<MaskImageType>(output);
-  }
-
   //--------------------------------------------------------------------
   // Step 10 : AutoCrop
   StartNewStep("AutoCrop");
   output = clitk::AutoCrop<MaskImageType>(output, GetBackgroundValue()); 
   this->template StopCurrentStep<MaskImageType>(output);
 
-  // Bones ? pb with RAM ? FillHoles ?
-
-  // how to do with post part ? spine /lung ?
-  // POST the spine (should be separated from the rest) 
-  /// DO THAT ---->>
-  // histo Y on the whole bones_post (3D) -> result is the Y center on the spine (?)
-  // by slice on bones_post
-  //       find the most ant point in the center
-  //       from this point go to post until out of bones.
-  //       
-
-
   // End, set the real size
   this->GetOutput(0)->SetRegions(output->GetLargestPossibleRegion());
   this->GetOutput(0)->SetLargestPossibleRegion(output->GetLargestPossibleRegion());
@@ -560,6 +451,102 @@ GenerateData()
   WriteAFDB();
 }
 //--------------------------------------------------------------------
+
   
+//--------------------------------------------------------------------
+template <class ImageType>
+void 
+clitk::ExtractMediastinumFilter<ImageType>::
+RemovePostPartOfVertebralBody()
+{
+  
+  /*
+    Posteriorly, Station 8 abuts the descending aorta and the anterior
+    aspect of the vertebral body until an imaginary horizontal line
+    running 1 cm posterior to the anterior border of the vertebral
+    body (Fig. 3C).
+    
+    => We use this definition for all the mediastinum
+
+   Find most Ant point in VertebralBody. Consider the horizontal line
+   which is 'DistanceMaxToAnteriorPartOfTheVertebralBody' away from
+   the most ant point.
+  */
+
+  // Get VertebralBody mask image
+  MaskImagePointer VertebralBody = 
+    GetAFDB()->template GetImage <MaskImageType>("VertebralBody");  
+
+  // Consider vertebral body slice by slice
+  std::vector<MaskSlicePointer> vertebralSlices;
+  clitk::ExtractSlices<MaskImageType>(VertebralBody, 2, vertebralSlices);
+
+  // For each slice, compute the most anterior point
+  std::map<int, MaskSlicePointType> vertebralAntPositionBySlice;
+  for(uint i=0; i<vertebralSlices.size(); i++) {
+    MaskSlicePointType p;
+    bool found = clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(vertebralSlices[i], 
+                                                                     GetBackgroundValue(), 
+                                                                     1, true, p);
+    if (found) {
+      vertebralAntPositionBySlice[i] = p;
+    }
+    else { 
+      // It should not happen ! But sometimes, a contour is missing or
+      // the VertebralBody is not delineated enough inferiorly ... in
+      // those cases, we consider the first found slice.
+      //        std::cerr << "No foreground pixels in this VertebralBody slices !?? I try with the previous/next slice" << std::endl;
+      // [ Possible alternative -> consider previous limit ]
+    }
+  }
+
+  // Convert 2D points in slice into 3D points
+  std::vector<MaskImagePointType> vertebralAntPositions;
+  clitk::PointsUtils<MaskImageType>::Convert2DMapTo3DList(vertebralAntPositionBySlice, 
+                                                          VertebralBody, 
+                                                          vertebralAntPositions);
+
+  // DEBUG : write list of points
+  clitk::WriteListOfLandmarks<MaskImageType>(vertebralAntPositions, 
+                                             "VertebralBodyMostAnteriorPoints.txt");
+
+  // Cut support posteriorly 1cm the most anterior point of the
+  // VertebralBody. Do nothing below and above the VertebralBody. To
+  // do that compute several region, slice by slice and fill. 
+  MaskImageRegionType region;
+  MaskImageSizeType size;
+  MaskImageIndexType start;
+  size[2] = 1; // a single slice
+  start[0] = output->GetLargestPossibleRegion().GetIndex()[0];
+  size[0] = output->GetLargestPossibleRegion().GetSize()[0];
+  for(uint i=0; i<vertebralAntPositions.size(); i++) {
+    typedef typename itk::ImageRegionIterator<MaskImageType> IteratorType;
+    IteratorType iter = 
+      IteratorType(output, output->GetLargestPossibleRegion());
+    MaskImageIndexType index;
+    // Consider some cm posterior to most anterior positions (usually
+    // 1 cm).
+    vertebralAntPositions[i][1] += GetDistanceMaxToAnteriorPartOfTheVertebralBody();
+    // Get index of this point
+    output->TransformPhysicalPointToIndex(vertebralAntPositions[i], index);
+    // Compute region (a single slice)
+    start[2] = index[2];
+    start[1] = output->GetLargestPossibleRegion().GetIndex()[1]+index[1];
+    size[1] = output->GetLargestPossibleRegion().GetSize()[1]-start[1];
+    region.SetSize(size);
+    region.SetIndex(start);
+    // Fill region
+    if (output->GetLargestPossibleRegion().IsInside(start))  {
+      itk::ImageRegionIterator<MaskImageType> it(output, region);
+      it.GoToBegin();
+      while (!it.IsAtEnd()) {
+        it.Set(GetBackgroundValue());
+        ++it;
+      }
+    }
+  }  
+}
+//--------------------------------------------------------------------
+
 
 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
index 54abc2f98df921637c2304e89e5833f2f5cf3a05..0670ed7830571b1bac02c460553f054d5c84ba23 100644 (file)
@@ -75,13 +75,14 @@ SetOptionsFromArgsInfoToFilter(FilterType * f)
   f->SetOutputMediastinumFilename(mArgsInfo.output_arg);
   f->SetVerboseMemoryFlag(mArgsInfo.verboseMemory_flag);
 
+  f->SetDistanceMaxToAnteriorPartOfTheVertebralBody(mArgsInfo.maxAntSpine_arg);
   f->SetUseBones(mArgsInfo.useBones_flag);
+
   f->SetIntermediateSpacing(mArgsInfo.spacing_arg);
-  f->SetFuzzyThreshold1(mArgsInfo.fuzzy1_arg);
-  f->SetFuzzyThreshold2(mArgsInfo.fuzzy2_arg);
-  f->SetFuzzyThreshold3(mArgsInfo.fuzzy3_arg);
-  f->SetUpperThreshold(mArgsInfo.upper_arg);
-  f->SetLowerThreshold(mArgsInfo.lower_arg);
+  f->SetFuzzyThreshold("LR_lungs", mArgsInfo.ft_LR_lungs_arg);
+  f->SetFuzzyThreshold("bones", mArgsInfo.ft_bones_arg);
+  f->SetFuzzyThreshold("inf_lungs", mArgsInfo.ft_inf_lungs_arg);
+  f->SetFuzzyThreshold("ant_sternum", mArgsInfo.ft_ant_sternum_arg);
 }
 //--------------------------------------------------------------------
 
index 5c2861dfbae5a4550487ac9b8311ea872f324d11..f4944409a1b10e6286a9930b1046b659a2301ece 100644 (file)
@@ -22,6 +22,7 @@ section "Binarize"
 
 option "lower"         -       "Initial lower threshold"       double          no      
 option "upper"         -       "Initial upper threshold"       double          no      default="-300"
+option "openingRadius"    - "Radius for opening after threshold"  int no  default="0"
 
 section "First Label Image (air=1)"
 
index b612fd3f7eba02ba344e2e814bdafbcf944dcfa1..fe290cc2302603808682cf1c49887494ca0c72a5 100644 (file)
@@ -98,7 +98,9 @@ namespace clitk {
 
     itkSetMacro(LowerThreshold, InputImagePixelType);
     itkGetMacro(LowerThreshold, InputImagePixelType);
-    itkSetMacro(UseLowerThreshold, bool);    
+    itkSetMacro(UseLowerThreshold, bool);   
+    itkGetMacro(PrimaryOpeningRadius, unsigned int);
+    itkSetMacro(PrimaryOpeningRadius, unsigned int);
     itkGetConstMacro(UseLowerThreshold, bool);    
     itkBooleanMacro(UseLowerThreshold);
 
@@ -165,6 +167,7 @@ namespace clitk {
     bool m_DecomposeAndReconstructDuringFirstStep;
     bool m_DecomposeAndReconstructDuringSecondStep;
     bool m_FinalOpenClose;
+    unsigned  m_PrimaryOpeningRadius;
     InternalImageSizeType m_Radius1;
     InternalImageSizeType m_Radius2;
     int m_MaximumNumberOfLabels1;
index a04232b9d3a72119f973fa784cc9f2011aee6a52..fedf853c82590918849ddc8df2e9e58ec06a7f9e 100644 (file)
@@ -1,7 +1,7 @@
 /*=========================================================================
   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
 
-  Authors belong to: 
+  Authors belong to:
   - University of LYON              http://www.universite-lyon.fr/
   - Léon Bérard cancer center       http://www.centreleonberard.fr
   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
@@ -35,6 +35,7 @@
 #include "itkBinaryMorphologicalOpeningImageFilter.h"
 #include "itkBinaryBallStructuringElement.h"
 #include "itkCastImageFilter.h"
+#include "itkConstantPadImageFilter.h"
 
 //--------------------------------------------------------------------
 template <class TInputImageType>
@@ -47,6 +48,7 @@ ExtractPatientFilter():
   this->SetNumberOfRequiredInputs(1);
   SetBackgroundValue(0); // Must be zero
   SetForegroundValue(1);
+  SetPrimaryOpeningRadius(0);
 
   // Step 1: Threshold + CC + sort (Find low density areas)
   SetUpperThreshold(-300);
@@ -68,11 +70,11 @@ ExtractPatientFilter():
   SetRadius2(r);
   SetMaximumNumberOfLabels2(2);
   SetNumberOfNewLabels2(1);
-  
+
   // Step 5: Only keep label corresponding (Keep patient's labels)
   SetFirstKeep(1);
   SetLastKeep(1);
-  
+
   // Step 4: OpenClose (option)
   FinalOpenCloseOff();
   AutoCropOn();
@@ -82,9 +84,9 @@ ExtractPatientFilter():
 
 //--------------------------------------------------------------------
 template <class TInputImageType>
-void 
+void
 clitk::ExtractPatientFilter<TInputImageType>::
-SetInput(const TInputImageType * image) 
+SetInput(const TInputImageType * image)
 {
   this->SetNthInput(0, const_cast<TInputImageType *>(image));
 }
@@ -93,9 +95,9 @@ SetInput(const TInputImageType * image)
 
 //--------------------------------------------------------------------
 template <class TInputImageType>
-void 
+void
 clitk::ExtractPatientFilter<TInputImageType>::
-GenerateOutputInformation() { 
+GenerateOutputInformation() {
 
   clitk::PrintMemory(GetVerboseMemoryFlag(), "Initial memory"); // OK
 
@@ -108,40 +110,81 @@ GenerateOutputInformation() {
   // Get input pointers
   static const unsigned int Dim = InputImageType::ImageDimension;
   //input = dynamic_cast<const TInputImageType*>(itk::ProcessObject::GetInput(0));
-    
+
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
-  // Step 1: 
+  // Step 1:
   StartNewStep("Find low densities areas");
-  typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> BinarizeFilterType;  
+
+  // Pad images with air to prevent patient touching the image border
+  typedef itk::ConstantPadImageFilter<InputImageType, InputImageType> PadFilterType;
+  typename PadFilterType::Pointer padFilter = PadFilterType::New();
+  padFilter->SetInput(input);
+  padFilter->SetConstant(GetUpperThreshold() - 1);
+  typename InputImageType::SizeType bounds;
+  for (unsigned i = 0; i < Dim - 1; ++i)
+    bounds[i] = 1;
+  bounds[Dim - 1] = 0;
+  padFilter->SetPadLowerBound(bounds);
+  padFilter->SetPadUpperBound(bounds);
+  padFilter->Update();
+  
+  typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> BinarizeFilterType;
   typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New();
-  binarizeFilter->SetInput(input);
+  binarizeFilter->SetInput(padFilter->GetOutput());
   if (m_UseLowerThreshold) binarizeFilter->SetLowerThreshold(GetLowerThreshold());
   binarizeFilter->SetUpperThreshold(GetUpperThreshold());
   binarizeFilter ->SetInsideValue(this->GetForegroundValue());
   binarizeFilter ->SetOutsideValue(this->GetBackgroundValue());
+  padFilter->GetOutput()->ReleaseData();
+  working_image = binarizeFilter->GetOutput();
+
+  typedef itk::BinaryBallStructuringElement<InternalPixelType,Dim> KernelType;
+  unsigned int radius = this->GetPrimaryOpeningRadius();
+  if (radius > 0)
+  {
+    if (this->GetVerboseOptionFlag()) std::cout << ("Opening after threshold; R = ") << radius << std::endl;
+    KernelType kernel;
+    kernel.SetRadius(radius);
+    
+    typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> OpenFilterType2;
+    typename OpenFilterType2::Pointer openFilter2 = OpenFilterType2::New();
+    openFilter2->SetInput(working_image);
+    openFilter2->SetBackgroundValue(0);
+    openFilter2->SetForegroundValue(1);
+    openFilter2->SetKernel(kernel);
+    openFilter2->Update();
+    working_image->ReleaseData();
+    working_image = openFilter2->GetOutput();
+  }
 
+  if (this->GetVerboseOptionFlag()) std::cout << ("Labelling") << std::endl;
   // Connected component labeling
   typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
   typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
-  connectFilter->SetInput(binarizeFilter->GetOutput());
+  connectFilter->SetInput(working_image);
   connectFilter->SetBackgroundValue(this->GetBackgroundValue());
   connectFilter->SetFullyConnected(false);
-  
+  connectFilter->Update();
+  working_image->ReleaseData();
+  working_image = connectFilter->GetOutput();
+
+  if (this->GetVerboseOptionFlag()) std::cout << ("RelabelComponentImageFilter") << std::endl;
   // Sort labels according to size
   typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
   typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
   relabelFilter->InPlaceOn();
   relabelFilter->SetInput(connectFilter->GetOutput());
   relabelFilter->Update();
+  working_image->ReleaseData();
   working_image = relabelFilter->GetOutput();
-  
+
   // End
   StopCurrentStep<InternalImageType>(working_image);
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
-  // [Optional] 
+  // [Optional]
   if (GetDecomposeAndReconstructDuringFirstStep()) {
     StartNewStep("First Decompose & Reconstruct step");
     typedef clitk::DecomposeAndReconstructImageFilter<InternalImageType,InternalImageType> FilterType;
@@ -155,40 +198,48 @@ GenerateOutputInformation() {
     f->SetFullyConnected(true);
     f->SetNumberOfNewLabels(GetNumberOfNewLabels1());
     f->Update();
+    working_image->ReleaseData();
     working_image = f->GetOutput();
     StopCurrentStep<InternalImageType>(working_image);
   }
-  
+
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
+  if (this->GetVerboseOptionFlag()) std::cout << ("Remove the air (largest area)") << std::endl;
   StartNewStep("Remove the air (largest area)");
-  typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> iBinarizeFilterType;  
+  typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> iBinarizeFilterType;
   typename iBinarizeFilterType::Pointer binarizeFilter2 = iBinarizeFilterType::New();
   binarizeFilter2->SetInput(working_image);
   binarizeFilter2->SetLowerThreshold(GetFirstKeep());
   binarizeFilter2->SetUpperThreshold(GetLastKeep());
   binarizeFilter2 ->SetInsideValue(0);
   binarizeFilter2 ->SetOutsideValue(1);
-  //  binarizeFilter2 ->Update(); // NEEDED ?
+  binarizeFilter2 ->Update();
+  working_image->ReleaseData();
+  working_image = binarizeFilter2->GetOutput();
 
   typename ConnectFilterType::Pointer connectFilter2 = ConnectFilterType::New();
-  connectFilter2->SetInput(binarizeFilter2->GetOutput());
+  connectFilter2->SetInput(working_image);
   connectFilter2->SetBackgroundValue(this->GetBackgroundValue());
   connectFilter2->SetFullyConnected(false);
+  connectFilter2->Update();
+  working_image->ReleaseData();
+  working_image = connectFilter2->GetOutput();
 
   typename RelabelFilterType::Pointer relabelFilter2 = RelabelFilterType::New();
-  relabelFilter2->SetInput(connectFilter2->GetOutput());
+  relabelFilter2->SetInput(working_image);
   relabelFilter2->Update();
+  working_image->ReleaseData();
   working_image = relabelFilter2->GetOutput();
-  
+
   // Keep main label
   working_image = KeepLabels<InternalImageType>
-    (working_image, GetBackgroundValue(), GetForegroundValue(), 1, 1, true);  
+    (working_image, GetBackgroundValue(), GetForegroundValue(), 1, 1, true);
   StopCurrentStep<InternalImageType>(working_image);
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
-  // [Optional] 
+  // [Optional]
   if (GetDecomposeAndReconstructDuringSecondStep()) {
     StartNewStep("Second Decompose & Reconstruct step");
     typedef clitk::DecomposeAndReconstructImageFilter<InternalImageType,InternalImageType> FilterType;
@@ -202,6 +253,7 @@ GenerateOutputInformation() {
     f->SetFullyConnected(true);
     f->SetNumberOfNewLabels(GetNumberOfNewLabels2());
     f->Update();
+    working_image->ReleaseData();
     working_image = f->GetOutput();
     StopCurrentStep<InternalImageType>(working_image);
   }
@@ -212,7 +264,6 @@ GenerateOutputInformation() {
   if (GetFinalOpenClose()) {
     StartNewStep("Final OpenClose");
     // Open
-    typedef itk::BinaryBallStructuringElement<InternalPixelType,Dim> KernelType;
     KernelType structuringElement;
     structuringElement.SetRadius(1);
     structuringElement.CreateStructuringElement();
@@ -221,7 +272,7 @@ GenerateOutputInformation() {
     openFilter->SetInput(working_image);
     openFilter->SetBackgroundValue(this->GetBackgroundValue());
     openFilter->SetForegroundValue(this->GetForegroundValue());
-    openFilter->SetKernel(structuringElement);  
+    openFilter->SetKernel(structuringElement);
     // Close
     typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> CloseFilterType;
     typename CloseFilterType::Pointer closeFilter = CloseFilterType::New();
@@ -230,18 +281,20 @@ GenerateOutputInformation() {
     closeFilter->SetForegroundValue(this->GetForegroundValue());
     //  closeFilter->SetBackgroundValue(SetBackgroundValue());
     closeFilter->SetKernel(structuringElement);
-    closeFilter->Update();  
+    closeFilter->Update();
+    working_image->ReleaseData();
     working_image = closeFilter->GetOutput();
     StopCurrentStep<InternalImageType>(working_image);
   }
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
-  // Final Cast 
+  // Final Cast
   typedef itk::CastImageFilter<InternalImageType, MaskImageType> CastImageFilterType;
   typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
   caster->SetInput(working_image);
   caster->Update();
+  working_image->ReleaseData();
   output = caster->GetOutput();
 
   //--------------------------------------------------------------------
@@ -253,26 +306,39 @@ GenerateOutputInformation() {
     typename CropFilterType::Pointer cropFilter = CropFilterType::New();
     cropFilter->SetInput(output);
     cropFilter->SetBackgroundValue(GetBackgroundValue());
-    cropFilter->Update();   
+    cropFilter->Update();
+    output->ReleaseData();
     output = cropFilter->GetOutput();
     StopCurrentStep<MaskImageType>(output);
   }
+  else
+  {
+    // Remove Padding region
+    typedef itk::CropImageFilter<MaskImageType, MaskImageType> CropFilterType;
+    typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+    cropFilter->SetInput(output);
+    cropFilter->SetLowerBoundaryCropSize(bounds);
+    cropFilter->SetUpperBoundaryCropSize(bounds);
+    cropFilter->Update();
+    output->ReleaseData();
+    output = cropFilter->GetOutput();
+  }
 }
 //--------------------------------------------------------------------
 
 
 //--------------------------------------------------------------------
 template <class TInputImageType>
-void 
+void
 clitk::ExtractPatientFilter<TInputImageType>::
 GenerateData() {
   // Final Graft
   this->GraftOutput(output);
   // Store image filename into AFDB
-  GetAFDB()->SetImageFilename("Patient", this->GetOutputPatientFilename());  
+  GetAFDB()->SetImageFilename("Patient", this->GetOutputPatientFilename());
   WriteAFDB();
 }
 //--------------------------------------------------------------------
-  
+
 
 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
index a8fbad81e227e2360e1b34b74e71233c85cebdac..e7d4ebee74565d7dca39e2cd2bef982bb9a161fd 100644 (file)
@@ -75,6 +75,7 @@ SetOptionsFromArgsInfoToFilter(FilterType * f)
 
   f->SetUpperThreshold(mArgsInfo.upper_arg);
   f->SetLowerThreshold(mArgsInfo.lower_arg);
+  f->SetPrimaryOpeningRadius(mArgsInfo.openingRadius_arg);
 
   f->SetDecomposeAndReconstructDuringFirstStep(mArgsInfo.erode1_flag);
 
index 03f50eab37a63571749fb0193990737e69fff21f..2eb3a0261c280da9193d39e270d1746f6a478944 100644 (file)
@@ -30,6 +30,7 @@ clitk::MorphoMathFilter<ImageType>::MorphoMathFilter():
   p.Fill(1);
   SetRadius(p);
   SetBoundaryToForegroundFlag(false);
+  VerboseFlagOff();
 }
 //--------------------------------------------------------------------
 
@@ -84,15 +85,9 @@ template<class ImageType>
 void clitk::MorphoMathFilter<ImageType>::
 SetOperationType(int type)
 {
-  switch (type) {
-  case 0: m_OperationType = Erode; return;
-  case 1: m_OperationType = Dilate; return;
-  case 2: m_OperationType = Open; return;
-  case 3: m_OperationType = Close; return;
-  case 4: m_OperationType = CondErode; return;
-  case 5: m_OperationType = CondDilate; return;
-  default: clitkExceptionMacro("Operation type must be between 0-5 (0=Erode, 1=Dilate, 2=Close (erode(dilate(x))), 3=Open (dilate(erode(x))), 4=CondErode, 5=CondDilate)");
-  }    
+  if(type<0 || type>5)
+    clitkExceptionMacro("Operation type must be between 0-5 (0=Erode, 1=Dilate, 2=Close (erode(dilate(x))), 3=Open (dilate(erode(x))), 4=CondErode, 5=CondDilate)");
+  m_OperationType = OperationTypeEnumeration(type);
 }
 //--------------------------------------------------------------------
 
@@ -288,7 +283,9 @@ GenerateData()
   typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
   oCaster->SetInput(filter->GetOutput());
   oCaster->Update();
+
   this->SetNthOutput(0, oCaster->GetOutput());
+  //this->GraftOutput(oCaster->GetOutput()); // NO
 }
 //--------------------------------------------------------------------
 
index d094baf733e270a3bcaffa9559d9045f3b424302..543bcdb830f61de6537c5537e7204a59023f3433 100644 (file)
@@ -377,6 +377,8 @@ MotionMaskGenericFilter::GetLungsImage(typename itk::Image<PixelType, Dimension>
     connectFilter->SetBackgroundValue(0);
     connectFilter->SetFullyConnected(true);
     if (m_Verbose) std::cout<<"Labeling the connected components..."<<std::endl;
+    connectFilter->Update();
+    if (m_Verbose) std::cout<<"found "<< connectFilter->GetObjectCount() << std::endl;
 
     //---------------------------------
     // Sort the labels according to size
diff --git a/segmentation/clitkReconstructThroughDilationImageFilter.h b/segmentation/clitkReconstructThroughDilationImageFilter.h
deleted file mode 100644 (file)
index 3f0b88a..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to: 
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef clitkReconstructThroughDilationImageFilter_h
-#define clitkReconstructThroughDilationImageFilter_h
-
-/* =================================================
- * @file   clitkReconstructThroughDilationImageFilter.h
- * @author 
- * @date   
- * 
- * @brief 
- * 
- ===================================================*/
-
-
-// clitk include
-#include "clitkIO.h"
-#include "clitkCommon.h"
-#include "clitkConditionalBinaryDilateImageFilter.h"
-
-//itk include
-#include "itkImageToImageFilter.h"
-#include "itkBinaryBallStructuringElement.h"
-#include "itkConnectedComponentImageFilter.h"
-#include "itkStatisticsImageFilter.h"
-#include "itkCastImageFilter.h"
-#include "itkDifferenceImageFilter.h"
-#include "itkThresholdImageFilter.h"
-
-namespace clitk 
-{
-
-  template <class InputImageType, class OutputImageType>
-  class ITK_EXPORT ReconstructThroughDilationImageFilter :
-    public itk::ImageToImageFilter<InputImageType, OutputImageType>
-  {
-  public:
-    //----------------------------------------
-    // ITK
-    //----------------------------------------
-    typedef ReconstructThroughDilationImageFilter                                                 Self;
-    typedef itk::ImageToImageFilter<InputImageType, OutputImageType>  Superclass;
-    typedef itk::SmartPointer<Self>                                   Pointer;
-    typedef itk::SmartPointer<const Self>                             ConstPointer;
-   
-    // Method for creation through the object factory
-    itkNewMacro(Self);  
-
-    // Run-time type information (and related methods)
-    itkTypeMacro( ReconstructThroughDilationImageFilter, ImageToImageFilter );
-
-    /** Dimension of the domain space. */
-    itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
-    itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
-
-    //----------------------------------------
-    // Typedefs
-    //----------------------------------------
-    typedef typename OutputImageType::RegionType OutputImageRegionType;
-    typedef int InternalPixelType;
-    typedef typename InputImageType::PixelType InputPixelType;
-    typedef typename OutputImageType::PixelType OutputPixelType;
-    typedef typename InputImageType::SizeType SizeType;
-
-    //----------------------------------------
-    // Set & Get
-    //----------------------------------------    
-    itkBooleanMacro(Verbose);
-    itkSetMacro( Verbose, bool);
-    itkGetConstReferenceMacro( Verbose, bool);
-    void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
-    SizeType GetRadius(void){return m_Radius;}
-    itkSetMacro( ErosionPaddingValue, OutputPixelType);
-    itkGetConstMacro( ErosionPaddingValue, OutputPixelType)
-    itkSetMacro( MaximumNumberOfLabels, unsigned int);
-    itkGetConstMacro( MaximumNumberOfLabels, unsigned int);
-    itkSetMacro( BackgroundValue, InternalPixelType);
-    itkGetConstMacro( BackgroundValue, InternalPixelType);
-    itkSetMacro( ForegroundValue, InternalPixelType);
-    itkGetConstMacro( ForegroundValue, InternalPixelType);
-
-  protected:
-
-    //----------------------------------------  
-    // Constructor & Destructor
-    //----------------------------------------  
-    ReconstructThroughDilationImageFilter();
-    ~ReconstructThroughDilationImageFilter() {};
-
-    //----------------------------------------  
-    // Update
-    //----------------------------------------  
-    // Generate Data
-    void GenerateData(void);
-
-    //     // Threaded Generate Data
-    //     void BeforeThreadedGenerateData(void );
-    //     void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
-    //     void AfterThreadedGenerateData(void );
-    //     // Override defaults
-    //     virtual void GenerateInputRequestedRegion();
-    //     virtual void GenerateOutputInformation (void);
-    //     virtual void EnlargeOutputRequestedRegion(DataObject *data);
-    //     void AllocateOutputs();
-    //----------------------------------------  
-    // Data members
-    //----------------------------------------
-    bool m_Verbose;
-    InternalPixelType m_BackgroundValue;
-    InternalPixelType m_ForegroundValue;
-    unsigned int m_MaximumNumberOfLabels;
-    OutputPixelType m_ErosionPaddingValue;
-    SizeType m_Radius;
-
-  };
-
-
-} // end namespace clitk
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkReconstructThroughDilationImageFilter.txx"
-#endif
-
-#endif // #define clitkReconstructThroughDilationImageFilter_h
-
-
diff --git a/segmentation/clitkReconstructThroughDilationImageFilter.txx b/segmentation/clitkReconstructThroughDilationImageFilter.txx
deleted file mode 100644 (file)
index 613f10b..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to: 
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-======================================================================-====*/
-#ifndef clitkReconstructThroughDilationImageFilter_txx
-#define clitkReconstructThroughDilationImageFilter_txx
-
-namespace clitk
-{
-
-  //-------------------------------------------------------------------
-  // Update with the number of dimensions
-  //-------------------------------------------------------------------
-  template<class InputImageType, class OutputImageType>
-  ReconstructThroughDilationImageFilter<InputImageType, OutputImageType>::ReconstructThroughDilationImageFilter()
-  {
-   m_Verbose=false;
-   m_BackgroundValue=0;
-   m_ForegroundValue=1;
-   m_ErosionPaddingValue=static_cast<InputPixelType>(-1);
-   for (unsigned int i=0; i<InputImageDimension; i++)
-     m_Radius[i]=1;
-   m_MaximumNumberOfLabels=10;
-  }
-
-
-  //-------------------------------------------------------------------
-  // Update with the number of dimensions and the pixeltype
-  //-------------------------------------------------------------------
-  template<class InputImageType, class  OutputImageType> 
-  void 
-  ReconstructThroughDilationImageFilter<InputImageType, OutputImageType>::GenerateData()
-  {
-
-    //---------------------------------
-    // Typedefs 
-    //--------------------------------- 
-    
-    // Internal type
-    typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
-
-    // Filters used
-    typedef itk::CastImageFilter<InputImageType, InternalImageType> InputCastImageFilterType;   
-    typedef itk::ThresholdImageFilter<InternalImageType> InputThresholdImageFilterType;
-    typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
-    typedef itk::BinaryBallStructuringElement<InternalPixelType,InputImageDimension > KernelType;
-    typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> ConditionalBinaryDilateImageFilterType;
-    typedef itk::DifferenceImageFilter<InternalImageType, InternalImageType> DifferenceImageFilterType;
-    typedef itk::CastImageFilter<InternalImageType, OutputImageType> OutputCastImageFilterType;
-    typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
-
-    //---------------------------------
-    // Cast
-    //---------------------------------
-    typename InputCastImageFilterType::Pointer castImageFilter=InputCastImageFilterType::New();
-    castImageFilter->SetInput(this->GetInput());
-    castImageFilter->Update();
-
-    //---------------------------------
-    // Threshold
-    //---------------------------------
-    typename InputThresholdImageFilterType::Pointer thresholdImageFilter=InputThresholdImageFilterType::New();
-    thresholdImageFilter->SetInput(castImageFilter->GetOutput());
-    thresholdImageFilter->ThresholdAbove(m_MaximumNumberOfLabels);
-    thresholdImageFilter->SetOutsideValue(m_ForegroundValue);
-    if(m_Verbose) std::cout<<"Thresholding the input to "<<m_MaximumNumberOfLabels<<" labels ..."<<std::endl;
-    thresholdImageFilter->Update();
-
-    //---------------------------------
-    // Set -1 to padding value
-    //---------------------------------
-    typename SetBackgroundImageFilterType::Pointer setBackgroundFilter =SetBackgroundImageFilterType::New();
-    setBackgroundFilter->SetInput(thresholdImageFilter->GetOutput());
-    setBackgroundFilter->SetInput2(castImageFilter->GetOutput());
-    setBackgroundFilter->SetMaskValue(m_ErosionPaddingValue);
-    setBackgroundFilter->SetOutsideValue(-1);
-    if(m_Verbose) std::cout<<"Setting the eroded region from "<<m_ErosionPaddingValue<<" to -1..."<<std::endl;
-
-    
-    //---------------------------------
-    // Count the initial labels
-    //---------------------------------
-    typename StatisticsImageFilterType::Pointer inputStatisticsImageFilter=StatisticsImageFilterType::New();
-    inputStatisticsImageFilter->SetInput(setBackgroundFilter->GetOutput());
-    if(m_Verbose) std::cout<<"Counting the initial labels..."<<std::endl;
-    inputStatisticsImageFilter->Update();
-    unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum();
-    if(m_Verbose) std::cout<<"The input contained "<<initialNumberOfLabels<<" disctictive label(s)..."<<std::endl;
-    unsigned int numberOfConsideredLabels=std::min(initialNumberOfLabels, m_MaximumNumberOfLabels);
-    if(m_Verbose) std::cout<<"Performing dilation the first "<<numberOfConsideredLabels<<" disctictive labels..."<<std::endl;
-
-    //---------------------------------
-    // Dilate while change
-    //---------------------------------
-    typename itk::NumericTraits<InputPixelType>::AccumulateType difference=1;
-    typename InternalImageType::Pointer labelImage=inputStatisticsImageFilter->GetOutput();
-    typename InternalImageType::Pointer oldLabelImage=inputStatisticsImageFilter->GetOutput();
-
-    // element
-    KernelType structuringElement;
-    structuringElement.SetRadius(m_Radius);
-    structuringElement.CreateStructuringElement();
-
-    while( difference)
-      {
-       // Dilate all labels once
-       for ( int label=0; label<(int)numberOfConsideredLabels+1;label++)  
-         if ( m_BackgroundValue != label)
-           {
-             typename ConditionalBinaryDilateImageFilterType::Pointer dilateFilter=ConditionalBinaryDilateImageFilterType::New();
-             dilateFilter->SetBoundaryToForeground(false);
-             dilateFilter->SetKernel(structuringElement);
-             dilateFilter->SetBackgroundValue (-1);
-             dilateFilter->SetInput (labelImage);
-             dilateFilter->SetForegroundValue (label);
-             if(m_Verbose) std::cout<<"Dilating the label "<<label<<"..."<<std::endl;
-             dilateFilter->Update();
-             labelImage=dilateFilter->GetOutput();
-           }
-  
-       // Difference with previous labelImage
-       typename DifferenceImageFilterType::Pointer differenceFilter=DifferenceImageFilterType::New();
-       differenceFilter->SetValidInput(oldLabelImage);
-       differenceFilter->SetTestInput(labelImage);
-       differenceFilter->Update();
-       difference =differenceFilter->GetTotalDifference();
-       if(m_Verbose) std::cout<<"The change in this iteration was "<<difference<<"..."<<std::endl;     
-       oldLabelImage=labelImage;
-      }
-      
-    //---------------------------------
-    // Set -1 to padding value
-    //---------------------------------
-    typename SetBackgroundImageFilterType::Pointer setBackgroundFilter2 =SetBackgroundImageFilterType::New();
-    setBackgroundFilter2->SetInput(labelImage);
-    setBackgroundFilter2->SetInput2(labelImage);
-    setBackgroundFilter2->SetMaskValue(-1);
-    setBackgroundFilter2->SetOutsideValue(m_ErosionPaddingValue);
-    if(m_Verbose) std::cout<<"Setting the eroded region to "<<m_ErosionPaddingValue<<"..."<<std::endl;
-
-    //---------------------------------
-    // Cast
-    //---------------------------------
-    typename OutputCastImageFilterType::Pointer outputCastImageFilter=OutputCastImageFilterType::New();
-    outputCastImageFilter->SetInput(setBackgroundFilter2->GetOutput());
-    if(m_Verbose) std::cout<<"Casting the output..."<<std::endl;
-    outputCastImageFilter->Update();
-
-    //---------------------------------
-    // SetOutput
-    //---------------------------------
-    this->SetNthOutput(0, outputCastImageFilter->GetOutput());
-
-
-  }
-
-
-}//end clitk
-#endif //#define clitkReconstructThroughDilationImageFilter_txx
index 1e5595b07cc56f4bea60ade0954faa05d3781c27..30beaaaeb2d97781361eae18e0be9181ddfcd7c5 100644 (file)
@@ -1,22 +1,32 @@
-# Tests are organized to mirror the clitk directory tree. 
-# Eacho subdirectory has its own CMakeLists.txt with the compiling directives
-
-IF (BUILD_TESTING)
-
-  set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/tests/bin)
-
-  # default data path is searched in the project source tree
-  FIND_PATH(CLITK_DATA_PATH data PATHS ${PROJECT_SOURCE_DIR})
-  IF (CLITK_DATA_PATH STREQUAL "CLITK_DATA_PATH-NOTFOUND")
-    MESSAGE(FATAL_ERROR "Data path must be given when tests are enabled.")
-  ENDIF (CLITK_DATA_PATH STREQUAL "CLITK_DATA_PATH-NOTFOUND")
-
-  set(CLITK_DATA_PATH ${CLITK_DATA_PATH}/data)
-  ADD_DEFINITIONS(-DCLITK_DATA_PATH='"${CLITK_DATA_PATH}"')
-
+cmake_policy(SET CMP0005 NEW)
+#=========================================================
+#=========================================================
+# Data tests path
+FIND_PATH(CLITK_TEST_DATA_PATH Lung3D.mhd)
+IF(NOT ${CLITK_TEST_DATA_PATH} MATCHES "NOTFOUND$")
+ SET(CLITK_TEST_DATA_PATH "${CLITK_TEST_DATA_PATH}/")
+ENDIF()
+ADD_DEFINITIONS(-DCLITK_TEST_DATA_PATH="${CLITK_TEST_DATA_PATH}")
+#=========================================================
+#=========================================================
+SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/tests/bin)
+SET(BUILDNAME ${CMAKE_SYSTEM_NAME}${CMAKE_OSX_ARCHITECTURES} CACHE INTERNAL DOCSTRING)
+#=========================================================
+#=========================================================
+# Enabled options to test
+IF(CLITK_BUILD_TOOLS)
   ADD_SUBDIRECTORY(tools)
-  #ADD_SUBDIRECTORY(segmentation)
-  #ADD_SUBDIRECTORY(registration)
-  #ADD_SUBDIRECTORY(common)
+ENDIF()
+#IF(CLITK_BUILD_VV)
+#  ADD_SUBDIRECTORY(vv)
+#ENDIF()
+# IF(CLITK_BUILD_SEGMENTATION)
+#   ADD_SUBDIRECTORY(segmentation)
+# ENDIF()
+# 
+# IF(CLITK_BUILD_REGISTATION)
+#   ADD_SUBDIRECTORY(registration)
+# ENDIF()
+#ADD_SUBDIRECTORY(common)
+#=========================================================
 
-ENDIF(BUILD_TESTING)
index f915a5bbd177f9ac52a77fe724be2b51385b9e02..3d5e87f63900a6220e18e2f8eaa380113fada321 100644 (file)
@@ -1,17 +1,50 @@
-# Add test apps and test executions to this part
-# Test apps are compiled as any other app in the
-# project. Test executions are run using "make test"
-#
-IF(BUILD_TESTING)
+include_directories(
+  ${PROJECT_SOURCE_DIR}/common
+  ${PROJECT_SOURCE_DIR}/tools
+  ${GTEST_DIR}/include
+)
 
-  # clitkImageInfo
-  ADD_EXECUTABLE(clitkImageInfoTest clitkImageInfoTest.cxx)
-  TARGET_LINK_LIBRARIES(clitkImageInfoTest ITKIO)
-  ADD_TEST(NAME clitkImageInfoTest COMMAND clitkImageInfoTest)
+SET (CUSTOM_TEST_SRC
+  clitkImageInfoTest.cxx
+  vvMainTest.cxx
+)
 
-  # clitkWriteDicomSeries
-  ADD_EXECUTABLE(clitkWriteDicomSeriesTest clitkWriteDicomSeriesTest.cxx)
-  TARGET_LINK_LIBRARIES(clitkWriteDicomSeriesTest ITKIO)
-  ADD_TEST(NAME clitkWriteDicomSeriesTest COMMAND clitkWriteDicomSeriesTest)
+SET(BUILDNAME ${BUILDNAME}_tools CACHE INTERNAL DOCSTRING)
+ADD_DEFINITIONS(-DCLITK_TEST_TOOLS_PATH=\"${PROJECT_BINARY_DIR}/bin/\")
+SET (srcs
+  toolTestRunner.cxx
+)
 
-ENDIF(BUILD_TESTING)
+ADD_EXECUTABLE(toolTestRunner ${srcs})
+TARGET_LINK_LIBRARIES(toolTestRunner vvLib ${vvExternalLibs})
+SET(exe ${EXECUTABLE_OUTPUT_PATH}/toolTestRunner) 
+SET(p ${CLITK_TEST_DATA_PATH})
+SET(tmpFile "feve51zd")
+#=========================================================
+# clitkImageInfo
+ADD_TEST(clitkImageInfo_4d    ${exe} clitkImageInfo ${p}Deformation4D.mhd ${p}Deformation4D_ref.info)
+ADD_TEST(clitkImageInfo_3d    ${exe} clitkImageInfo ${p}Lung3D.mhd      ${p}Lung3D_ref.info)
+#=========================================================
+# clitkGetSpacing
+ADD_TEST(clitkGetSpacing_4d   ${exe} clitkGetSpacing -i ${p}Deformation4D.mhd ${p}Deformation4D_ref.spacing)
+ADD_TEST(clitkGetSpacing_3d   ${exe} clitkGetSpacing -i ${p}Lung3D.mhd              ${p}Lung3D_ref.spacing)
+#=========================================================
+# clitkGetOrigin
+ADD_TEST(clitkGetOrigin_4d    ${exe} clitkGetOrigin -i ${p}Deformation4D.mhd ${p}Deformation4D_ref.origin)
+ADD_TEST(clitkGetOrigin_3d    ${exe} clitkGetOrigin -i ${p}Lung3D.mhd      ${p}Lung3D_ref.origin)
+#=========================================================
+# clitkGetSize
+ADD_TEST(clitkGetSize_4d      ${exe} clitkGetSize -i ${p}Deformation4D.mhd   ${p}Deformation4D_ref.size)
+ADD_TEST(clitkGetSize_3d     ${exe} clitkGetSize -i ${p}Lung3D.mhd         ${p}Lung3D_ref.size)
+#=========================================================
+# clitkGetDirection
+ADD_TEST(clitkGetDirection_4d ${exe} clitkGetDirection -i ${p}Deformation4D.mhd  ${p}Deformation4D_ref.direction)
+ADD_TEST(clitkGetDirection_3d ${exe} clitkGetDirection -i ${p}Lung3D.mhd       ${p}Lung3D_ref.direction)
+#=========================================================
+# clitkBinarize
+ADD_TEST(clitkBinarizeBGl0.1356_4d ${exe} clitkBinarizeImage -i ${p}Deformation4D.mhd --mode BG -l 0.1356 -o Deformation4D_ref.binarizeBGl0.1356.mhd ${p}Deformation4D_ref.binarizeBGl0.1356)
+ADD_TEST(clitkBinarizeFGl0.1556_3d ${exe} clitkBinarizeImage -i ${p}Lung3D.mhd        --mode FG -l 0.1556 -o Lung3D_ref.binarizeFGl0.1556.mhd ${p}Lung3D_ref.binarizeFGl0.1556)
+
+UNSET(tmpFile)
+UNSET(exe)
+UNSET(p)
\ No newline at end of file
diff --git a/tests/tools/clitkImageInfoTest.cxx b/tests/tools/clitkImageInfoTest.cxx
deleted file mode 100644 (file)
index e7cc921..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to:
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-#include <cstdlib>
-#include <cstdio>
-
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include <itksys/SystemTools.hxx>
-
-
-const size_t NUMTESTS=2;
-
-// test files
-const char mhd_files[NUMTESTS][128] = {
-  CLITK_DATA_PATH"/4d/mhd/00.mhd",
-  CLITK_DATA_PATH"/4d/mhd/bh.mhd"
-};
-
-// pre-written validation files. the idea
-// is that the output generated from the test
-// files match the verification files
-const char validation_files[NUMTESTS][128] = {
-  CLITK_DATA_PATH"/tools/clitkImageInfoTestValidate3D.out",
-  CLITK_DATA_PATH"/tools/clitkImageInfoTestValidate4D.out"
-};
-
-int main(int argc, char** argv)
-{
-  system("pwd");
-  
-  bool failed = false;
-  for (size_t i = 0; i < NUMTESTS; i++) {
-    std::ostringstream cmd_line;
-    cmd_line << "clitkImageInfo " << mhd_files[i] << " > clitkImageInfoTest.out";
-
-    std::cout << "Executing " << cmd_line.str() << std::endl;
-    system(cmd_line.str().c_str());
-    
-    // compare output with validation file
-    std::cout << "Validating output against " << validation_files[i] << std::endl;
-    bool differ = itksys::SystemTools::FilesDiffer("clitkImageInfoTest.out", validation_files[i]);
-    if (differ)
-    {
-      failed = true;
-      std::cout << "FAILED: Program output and reference do not match." << std::endl;
-    }
-    else
-    {
-      itksys::SystemTools::RemoveFile("clitkImageInfoTest.out");
-      std::cout << "PASSED" << std::endl;
-    }
-  }
-  return failed ? -1 : 0;
-}
\ No newline at end of file
diff --git a/tests/tools/clitkWriteDicomSeriesTest.cxx b/tests/tools/clitkWriteDicomSeriesTest.cxx
deleted file mode 100644 (file)
index 6f53ef5..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to:
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================*/
-#include <cstdlib>
-#include <cstdio>
-
-#include <iostream>
-#include <sstream>
-#include <cassert>
-
-#include <itksys/SystemTools.hxx>
-
-const size_t NUMTESTS=1;
-
-const char mhd_files[NUMTESTS][128] = {
-  CLITK_DATA_PATH"/3d/mhd/00.mhd"
-};
-
-const char dcm_dirs[NUMTESTS][128] = {
-  CLITK_DATA_PATH"/3d/dcm/1.2.840.113704.1.111.536.1248695032.26"
-};
-
-int main(int argc, char** argv)
-{
-  bool failed = false;
-  for (size_t i = 0; i < NUMTESTS; i++) {
-    std::ostringstream cmd_line;
-    cmd_line << "clitkWriteDicomSeries -i " << mhd_files[i] << " -d " << dcm_dirs[i] << " -o dcm --verbose";
-
-    std::cout << "Executing " << cmd_line.str() << std::endl;
-    int err = system(cmd_line.str().c_str());
-    if (err != 0)
-    {
-      failed = true;
-      std::cout << "FAILED (errno = " << err << ")" << std::endl;
-    }
-    else
-    {
-      itksys::SystemTools::RemoveADirectory("dcm");
-      std::cout << "PASSED" << std::endl;
-    }
-  }
-  return failed ? -1 : 0;
-}
\ No newline at end of file
diff --git a/tests/tools/toolTestRunner.cxx b/tests/tools/toolTestRunner.cxx
new file mode 100644 (file)
index 0000000..42226b7
--- /dev/null
@@ -0,0 +1,119 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <fstream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <itksys/SystemTools.hxx>
+const int NO_OUTPUT_OPTION=-1;
+const int TEST_EXITED=1;
+int getOutputOptionIndex(int argc, char** argv){
+  for(int i=1; i<argc; i++){
+      std::string s = argv[i];
+      if(s=="-o"){
+        return i+1;
+      }
+  }
+  return NO_OUTPUT_OPTION;
+}
+
+std::string getTmpFileName(){
+#ifdef _WIN32
+  char fileName[L_tmpnam_s];
+  errno_t err = tmpnam_s(fileName);
+#else
+  char fileName[] = "/tmp/vvTempXXXXXX";
+  int err=0;
+  int fd = mkstemp(fileName);
+  if(fd==-1) err=1;
+#endif
+  if(err){
+   std::cout<<"couldnot create file. Exiting"<<std::endl;
+   exit(TEST_EXITED);
+  }
+  return std::string(fileName);
+}
+
+void assertFalse(int fail, const std::string &message=""){
+  if(fail){
+    std::cout<<message<<std::endl; 
+    exit(1);
+  }
+}
+/**
+ * argv
+ * [1] executable
+ * [2] random options
+ * [2.x] -o
+ * [3] reference file
+ * 
+ * [2.x] is optional. If set a temporary file will be generated. So NO need to pass a random outputFileName
+ */
+int main(int argc, char** argv){
+  //reference file must exist or we fail
+  char* refFile = argv[argc-1];
+  assertFalse(!(itksys::SystemTools::FileExists(refFile, true)), "refFile "+std::string(refFile)+" doesn't exist");
+  
+  std::ostringstream cmd_line;
+  cmd_line<<CLITK_TEST_TOOLS_PATH;
+  for(int i=1; i<argc-1; i++){
+      //we should ensure the file exists, find an -i index or a long file name maybe?
+      cmd_line<<argv[i]<<" ";
+  }
+
+  //look for the need of generating an output file
+  int outputOptionIndex = getOutputOptionIndex(argc, argv);
+  std::string outFile;
+  if(NO_OUTPUT_OPTION==outputOptionIndex){
+     outFile = getTmpFileName();
+     cmd_line<<">"<<outFile;
+  }else{
+     outFile = argv[argc-2];
+  }
+  std::cout<<cmd_line.str()<<std::endl;;
+  //run the command line
+  system(cmd_line.str().c_str());
+  
+  //compare source files
+  assertFalse((itksys::SystemTools::FilesDiffer(outFile.c_str(), refFile)), "Source Files are different");
+  
+  //eventually raw files associated
+  //should be passed as a boolean to check also for raw or not
+  
+  std::string refRawFile = std::string(refFile)+".raw";
+  
+  
+  int found=outFile.find_last_of(".");
+  std::string rawFile = outFile.substr(0, found)+".raw";
+  if((itksys::SystemTools::FileExists(refRawFile.c_str(), true))){
+    //compare the raw stuff
+    if((itksys::SystemTools::FileExists(rawFile.c_str(), true))){
+       std::cout<<"Checking raws"<<std::endl;
+       assertFalse(itksys::SystemTools::FilesDiffer(refRawFile.c_str(), rawFile.c_str()), "Raws are different");
+    }
+    //file is not removed if there is a fail
+    remove(rawFile.c_str());
+  }
+  //neither the mhd is
+  remove(outFile.c_str());
+  
+  //success
+  return 0;
+}
diff --git a/tools/.cvsignore b/tools/.cvsignore
deleted file mode 100644 (file)
index 59659d6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-*_ggo.*
index c46ba3a0ec806a420f0819ad9c94bcfbc7c781e3..45a06acd30c6367b0e0843f75df310179d9ae7b9 100644 (file)
@@ -25,236 +25,325 @@ WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo)
 ADD_LIBRARY(clitkMedianImageFilterLib clitkMedianImageGenericFilter.cxx ${clitkMedianImageFilter_GGO_C})
 
 IF (CLITK_BUILD_TOOLS)
-    WRAP_GGO(clitkDicomInfo_GGO_C clitkDicomInfo.ggo)
-    ADD_EXECUTABLE(clitkDicomInfo clitkDicomInfo.cxx ${clitkDicomInfo_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkDicom2Image_GGO_C clitkDicom2Image.ggo)
-    ADD_EXECUTABLE(clitkDicom2Image clitkDicom2Image.cxx ${clitkDicom2Image_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkDicom2Image clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkImageInfo_GGO_C clitkImageInfo.ggo)
-    ADD_EXECUTABLE(clitkImageInfo clitkImageInfo.cxx ${clitkImageInfo_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkImageInfo clitkCommon ${ITK_LIBRARIES})
-
-    ADD_EXECUTABLE(clitkImageConvert clitkImageConvert.cxx)
-    TARGET_LINK_LIBRARIES(clitkImageConvert clitkImageConvertLib clitkCommon ${ITK_LIBRARIES})
-
-    ADD_EXECUTABLE(clitkBinarizeImage clitkBinarizeImage.cxx)
-    TARGET_LINK_LIBRARIES(clitkBinarizeImage clitkBinarizeImageLib clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkVFResample_GGO_C clitkVFResample.ggo)
-    ADD_EXECUTABLE(clitkVFResample clitkVFResample.cxx clitkVFResampleGenericFilter.cxx ${clitkVFResample_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkVFResample clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkImageCreate_GGO_C clitkImageCreate.ggo)
-    ADD_EXECUTABLE(clitkImageCreate clitkImageCreate.cxx ${clitkImageCreate_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkImageCreate clitkCommon  ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkZeroVF_GGO_C clitkZeroVF.ggo)
-    ADD_EXECUTABLE(clitkZeroVF clitkZeroVF.cxx ${clitkZeroVF_GGO_C} clitkZeroVFGenericFilter.cxx)
-    TARGET_LINK_LIBRARIES(clitkZeroVF clitkCommon  ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkImageExtractLine_GGO_C clitkImageExtractLine.ggo)
-    ADD_EXECUTABLE(clitkImageExtractLine clitkImageExtractLine.cxx ${clitkImageExtractLine_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkImageExtractLine clitkCommon  ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkSplitImage_GGO_C clitkSplitImage.ggo)
-    ADD_EXECUTABLE(clitkSplitImage clitkSplitImage.cxx clitkSplitImageGenericFilter.cxx ${clitkSplitImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkSplitImage clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkVFMerge_GGO_C clitkVFMerge.ggo)
-    ADD_EXECUTABLE(clitkVFMerge clitkVFMerge.cxx ${clitkVFMerge_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkVFMerge clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkWriteDicomSeries_GGO_C clitkWriteDicomSeries.ggo)
-    ADD_EXECUTABLE(clitkWriteDicomSeries clitkWriteDicomSeries.cxx ${clitkWriteDicomSeries_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkWriteDicomSeries clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkAverageTemporalDimension_GGO_C clitkAverageTemporalDimension.ggo)
-    ADD_EXECUTABLE(clitkAverageTemporalDimension clitkAverageTemporalDimension.cxx ${clitkAverageTemporalDimension_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkAverageTemporalDimension clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkMedianTemporalDimension_GGO_C clitkMedianTemporalDimension.ggo)
-    ADD_EXECUTABLE(clitkMedianTemporalDimension clitkMedianTemporalDimension.cxx
-        ${clitkMedianTemporalDimension_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkMedianTemporalDimension clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkWarpImage_GGO_C clitkWarpImage.ggo)
-    ADD_EXECUTABLE(clitkWarpImage clitkWarpImage.cxx ${clitkWarpImage_GGO_C} clitkWarpImageGenericFilter.cxx)
-    TARGET_LINK_LIBRARIES(clitkWarpImage clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkInvertVF_GGO_C clitkInvertVF.ggo)
-    ADD_EXECUTABLE(clitkInvertVF clitkInvertVF.cxx ${clitkInvertVF_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkInvertVF clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkAffineTransform_GGO_C clitkAffineTransform.ggo)
-    ADD_EXECUTABLE(clitkAffineTransform clitkAffineTransform.cxx ${clitkAffineTransform_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkAffineTransform clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkSetBackground_GGO_C clitkSetBackground.ggo)
-    ADD_EXECUTABLE(clitkSetBackground clitkSetBackground.cxx clitkSetBackgroundGenericFilter.cxx ${clitkSetBackground_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkSetBackground clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkGuerreroVentilation_GGO_C clitkGuerreroVentilation.ggo)
-    ADD_EXECUTABLE(clitkGuerreroVentilation clitkGuerreroVentilation.cxx clitkGuerreroVentilationGenericFilter.cxx ${clitkGuerreroVentilation_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkGuerreroVentilation clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkGammaIndex_GGO_C clitkGammaIndex.ggo)
-    ADD_EXECUTABLE(clitkGammaIndex clitkGammaIndex.cxx ${clitkGammaIndex_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkGammaIndex vtkCommon vtkFiltering vtkGraphics vtkIO vtkImaging)
-
-    ADD_EXECUTABLE(clitkImageArithm clitkImageArithm.cxx)
-    TARGET_LINK_LIBRARIES(clitkImageArithm clitkImageArithmImageLib clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkUnsharpMask_GGO_C clitkUnsharpMask.ggo)
-    ADD_EXECUTABLE(clitkUnsharpMask clitkUnsharpMask.cxx ${clitkUnsharpMask_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon ${ITK_LIBRARIES} ) 
-
-    WRAP_GGO(clitkFooImage_GGO_C clitkFooImage.ggo)
-    ADD_EXECUTABLE(clitkFooImage clitkFooImage.cxx ${clitkFooImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkFooImage clitkCommon ${ITK_LIBRARIES} ) 
-
-    WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo)
-    ADD_EXECUTABLE(clitkMedianImageFilter clitkMedianImageFilter.cxx ${clitkMedianImageFilter_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkMedianImageFilter clitkCommon ${ITK_LIBRARIES})
-
-    ADD_EXECUTABLE(clitkResampleImage clitkResampleImage.cxx)
-    TARGET_LINK_LIBRARIES(clitkResampleImage clitkResampleImageLib clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkMinMaxMask_GGO_C clitkMinMaxMask.ggo)
-    ADD_EXECUTABLE(clitkMinMaxMask clitkMinMaxMask.cxx ${clitkMinMaxMask_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkMinMaxMask clitkCommon ${ITK_LIBRARIES}  )
-
-    # WRAP_GGO(clitkAutoCrop_GGO_C clitkAutoCrop.ggo)
-    # ADD_EXECUTABLE(clitkAutoCrop clitkAutoCrop.cxx ${clitkAutoCrop_GGO_C})
-    # TARGET_LINK_LIBRARIES(clitkAutoCrop clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkDicomRTStruct2BinaryImage_GGO_C clitkDicomRTStruct2BinaryImage.ggo)
-    ADD_EXECUTABLE(clitkDicomRTStruct2BinaryImage clitkDicomRTStruct2BinaryImage.cxx ${clitkDicomRTStruct2BinaryImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkDicomRTStruct2BinaryImage clitkDicomRTStruct clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkImageLog_GGO_C clitkImageLog.ggo)
-    ADD_EXECUTABLE(clitkImageLog clitkImageLog.cxx ${clitkImageLog_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkImageLog  ${ITK_LIBRARIES} clitkCommon)
-
-    WRAP_GGO(clitkFilter_GGO_C clitkFilter.ggo)
-    ADD_EXECUTABLE(clitkFilter clitkFilter.cxx clitkFilterGenericFilter.cxx ${clitkFilter_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkFilter ${ITK_LIBRARIES} clitkCommon)
-
-    WRAP_GGO(clitkConeBeamProjectImage_GGO_C clitkConeBeamProjectImage.ggo)
-    ADD_EXECUTABLE(clitkConeBeamProjectImage clitkConeBeamProjectImage.cxx clitkConeBeamProjectImageGenericFilter.cxx ${clitkConeBeamProjectImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkConeBeamProjectImage  ${ITK_LIBRARIES} clitkCommon )
-
-    WRAP_GGO(clitkComposeVF_GGO_C clitkComposeVF.ggo)
-    ADD_EXECUTABLE(clitkComposeVF clitkComposeVFGenericFilter.cxx clitkComposeVF.cxx ${clitkComposeVF_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkComposeVF ${ITK_LIBRARIES} clitkCommon)
-
-    WRAP_GGO(clitkMergeSequence_GGO_C clitkMergeSequence.ggo)
-    ADD_EXECUTABLE(clitkMergeSequence clitkMergeSequence.cxx clitkMergeSequenceGenericFilter.cxx ${clitkMergeSequence_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkMergeSequence ${ITK_LIBRARIES} clitkCommon)
-
-    WRAP_GGO(clitkBackProjectImage_GGO_C clitkBackProjectImage.ggo)
-    ADD_EXECUTABLE(clitkBackProjectImage clitkBackProjectImage.cxx clitkBackProjectImageGenericFilter.cxx ${clitkBackProjectImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkBackProjectImage ${ITK_LIBRARIES} clitkCommon )
-
-    ADD_EXECUTABLE(clitkCropImage clitkCropImage.cxx ${clitkCropImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkCropImage clitkCropImageLib clitkCommon ${ITK_LIBRARIES})
-
-    # WRAP_GGO(clitkExtractSlice_GGO_C clitkExtractSlice.ggo)
-    # ADD_EXECUTABLE(clitkExtractSlice clitkExtractSlice.cxx clitkExtractSliceGenericFilter.cxx ${clitkExtractSlice_GGO_C})
-    # TARGET_LINK_LIBRARIES(clitkExtractSlice clitkCommon ${ITK_LIBRARIES})
+  WRAP_GGO(clitkDicomInfo_GGO_C clitkDicomInfo.ggo)
+  ADD_EXECUTABLE(clitkDicomInfo clitkDicomInfo.cxx ${clitkDicomInfo_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkDicomInfo clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL clitkDicomInfo)
+
+  WRAP_GGO(clitkDicom2Image_GGO_C clitkDicom2Image.ggo)
+  ADD_EXECUTABLE(clitkDicom2Image clitkDicom2Image.cxx ${clitkDicom2Image_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkDicom2Image clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicom2Image)
+
+  WRAP_GGO(clitkImageInfo_GGO_C clitkImageInfo.ggo)
+  ADD_EXECUTABLE(clitkImageInfo clitkImageInfo.cxx ${clitkImageInfo_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkImageInfo clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageInfo)
+
+  ADD_EXECUTABLE(clitkImageConvert clitkImageConvert.cxx)
+  TARGET_LINK_LIBRARIES(clitkImageConvert clitkImageConvertLib clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageConvert)
+
+  ADD_EXECUTABLE(clitkBinarizeImage clitkBinarizeImage.cxx)
+  TARGET_LINK_LIBRARIES(clitkBinarizeImage clitkBinarizeImageLib clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBinarizeImage)
+
+  WRAP_GGO(clitkVFResample_GGO_C clitkVFResample.ggo)
+  ADD_EXECUTABLE(clitkVFResample clitkVFResample.cxx clitkVFResampleGenericFilter.cxx ${clitkVFResample_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkVFResample clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVFResample)
+
+  WRAP_GGO(clitkImageCreate_GGO_C clitkImageCreate.ggo)
+  ADD_EXECUTABLE(clitkImageCreate clitkImageCreate.cxx ${clitkImageCreate_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkImageCreate clitkCommon  ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageCreate)
+
+  WRAP_GGO(clitkZeroVF_GGO_C clitkZeroVF.ggo)
+  ADD_EXECUTABLE(clitkZeroVF clitkZeroVF.cxx ${clitkZeroVF_GGO_C} clitkZeroVFGenericFilter.cxx)
+  TARGET_LINK_LIBRARIES(clitkZeroVF clitkCommon  ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkZeroVF)
+
+  WRAP_GGO(clitkImageExtractLine_GGO_C clitkImageExtractLine.ggo)
+  ADD_EXECUTABLE(clitkImageExtractLine clitkImageExtractLine.cxx ${clitkImageExtractLine_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkImageExtractLine clitkCommon  ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageExtractLine)
+
+  WRAP_GGO(clitkSplitImage_GGO_C clitkSplitImage.ggo)
+  ADD_EXECUTABLE(clitkSplitImage clitkSplitImage.cxx clitkSplitImageGenericFilter.cxx ${clitkSplitImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkSplitImage clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSplitImage)
+
+  WRAP_GGO(clitkVFMerge_GGO_C clitkVFMerge.ggo)
+  ADD_EXECUTABLE(clitkVFMerge clitkVFMerge.cxx ${clitkVFMerge_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkVFMerge clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVFMerge)
+
+  WRAP_GGO(clitkWriteDicomSeries_GGO_C clitkWriteDicomSeries.ggo)
+  ADD_EXECUTABLE(clitkWriteDicomSeries clitkWriteDicomSeries.cxx ${clitkWriteDicomSeries_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkWriteDicomSeries clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkWriteDicomSeries)
+
+  WRAP_GGO(clitkAverageTemporalDimension_GGO_C clitkAverageTemporalDimension.ggo)
+  ADD_EXECUTABLE(clitkAverageTemporalDimension clitkAverageTemporalDimension.cxx ${clitkAverageTemporalDimension_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkAverageTemporalDimension clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkAverageTemporalDimension)
+
+  WRAP_GGO(clitkMedianTemporalDimension_GGO_C clitkMedianTemporalDimension.ggo)
+  ADD_EXECUTABLE(clitkMedianTemporalDimension clitkMedianTemporalDimension.cxx
+      ${clitkMedianTemporalDimension_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMedianTemporalDimension clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMedianTemporalDimension)
+
+  WRAP_GGO(clitkWarpImage_GGO_C clitkWarpImage.ggo)
+  ADD_EXECUTABLE(clitkWarpImage clitkWarpImage.cxx ${clitkWarpImage_GGO_C} clitkWarpImageGenericFilter.cxx)
+  TARGET_LINK_LIBRARIES(clitkWarpImage clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkWarpImage)
+
+  WRAP_GGO(clitkInvertVF_GGO_C clitkInvertVF.ggo)
+  ADD_EXECUTABLE(clitkInvertVF clitkInvertVF.cxx ${clitkInvertVF_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkInvertVF clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkInvertVF)
+
+  WRAP_GGO(clitkAffineTransform_GGO_C clitkAffineTransform.ggo)
+  ADD_EXECUTABLE(clitkAffineTransform clitkAffineTransform.cxx ${clitkAffineTransform_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkAffineTransform clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicom2Image)
+
+  WRAP_GGO(clitkSetBackground_GGO_C clitkSetBackground.ggo)
+  ADD_EXECUTABLE(clitkSetBackground clitkSetBackground.cxx clitkSetBackgroundGenericFilter.cxx ${clitkSetBackground_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkSetBackground clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSetBackground)
+
+  WRAP_GGO(clitkGuerreroVentilation_GGO_C clitkGuerreroVentilation.ggo)
+  ADD_EXECUTABLE(clitkGuerreroVentilation clitkGuerreroVentilation.cxx clitkGuerreroVentilationGenericFilter.cxx ${clitkGuerreroVentilation_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkGuerreroVentilation clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGuerreroVentilation)
+
+  WRAP_GGO(clitkGammaIndex_GGO_C clitkGammaIndex.ggo)
+  ADD_EXECUTABLE(clitkGammaIndex clitkGammaIndex.cxx ${clitkGammaIndex_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkGammaIndex vtkCommon vtkFiltering vtkGraphics vtkIO vtkImaging)
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGammaIndex)
+
+  ADD_EXECUTABLE(clitkImageArithm clitkImageArithm.cxx)
+  TARGET_LINK_LIBRARIES(clitkImageArithm clitkImageArithmImageLib clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageArithm)
+
+  WRAP_GGO(clitkUnsharpMask_GGO_C clitkUnsharpMask.ggo)
+  ADD_EXECUTABLE(clitkUnsharpMask clitkUnsharpMask.cxx ${clitkUnsharpMask_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon ${ITK_LIBRARIES} ) 
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkUnsharpMask)
+
+  WRAP_GGO(clitkFooImage_GGO_C clitkFooImage.ggo)
+  ADD_EXECUTABLE(clitkFooImage clitkFooImage.cxx ${clitkFooImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkFooImage clitkCommon ${ITK_LIBRARIES} ) 
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkFooImage)
+
+  #WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo)
+  #ADD_EXECUTABLE(clitkMedianImageFilter clitkMedianImageFilter.cxx ${clitkMedianImageFilter_GGO_C})
+  #TARGET_LINK_LIBRARIES(clitkMedianImageFilter clitkMedianImageFilterLib clitkCommon ${ITK_LIBRARIES})
+  #SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMedianImageFilter)
+
+  ADD_EXECUTABLE(clitkResampleImage clitkResampleImage.cxx)
+  TARGET_LINK_LIBRARIES(clitkResampleImage clitkResampleImageLib clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkResampleImage)
+
+  WRAP_GGO(clitkMinMaxMask_GGO_C clitkMinMaxMask.ggo)
+  ADD_EXECUTABLE(clitkMinMaxMask clitkMinMaxMask.cxx ${clitkMinMaxMask_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMinMaxMask clitkCommon ${ITK_LIBRARIES}  )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMinMaxMask)
+
+  WRAP_GGO(clitkAutoCrop_GGO_C clitkAutoCrop.ggo)
+  ADD_EXECUTABLE(clitkAutoCrop clitkAutoCrop.cxx ${clitkAutoCrop_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkAutoCrop clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkAutoCrop)
+
+  WRAP_GGO(clitkDicomRTStruct2BinaryImage_GGO_C clitkDicomRTStruct2BinaryImage.ggo)
+  ADD_EXECUTABLE(clitkDicomRTStruct2BinaryImage clitkDicomRTStruct2BinaryImage.cxx ${clitkDicomRTStruct2BinaryImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkDicomRTStruct2BinaryImage clitkDicomRTStruct clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicomRTStruct2BinaryImage)
+
+  WRAP_GGO(clitkImageLog_GGO_C clitkImageLog.ggo)
+  ADD_EXECUTABLE(clitkImageLog clitkImageLog.cxx ${clitkImageLog_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkImageLog  ${ITK_LIBRARIES} clitkCommon)
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageLog)
+
+  WRAP_GGO(clitkFilter_GGO_C clitkFilter.ggo)
+  ADD_EXECUTABLE(clitkFilter clitkFilter.cxx clitkFilterGenericFilter.cxx ${clitkFilter_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkFilter ${ITK_LIBRARIES} clitkCommon)
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkFilter)
+
+  WRAP_GGO(clitkConeBeamProjectImage_GGO_C clitkConeBeamProjectImage.ggo)
+  ADD_EXECUTABLE(clitkConeBeamProjectImage clitkConeBeamProjectImage.cxx clitkConeBeamProjectImageGenericFilter.cxx ${clitkConeBeamProjectImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkConeBeamProjectImage  ${ITK_LIBRARIES} clitkCommon )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkConeBeamProjectImage)
+
+  WRAP_GGO(clitkComposeVF_GGO_C clitkComposeVF.ggo)
+  ADD_EXECUTABLE(clitkComposeVF clitkComposeVFGenericFilter.cxx clitkComposeVF.cxx ${clitkComposeVF_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkComposeVF ${ITK_LIBRARIES} clitkCommon)
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkComposeVF)
+
+  WRAP_GGO(clitkMergeSequence_GGO_C clitkMergeSequence.ggo)
+  ADD_EXECUTABLE(clitkMergeSequence clitkMergeSequence.cxx clitkMergeSequenceGenericFilter.cxx ${clitkMergeSequence_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMergeSequence ${ITK_LIBRARIES} clitkCommon)
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMergeSequence)
+
+  WRAP_GGO(clitkBackProjectImage_GGO_C clitkBackProjectImage.ggo)
+  ADD_EXECUTABLE(clitkBackProjectImage clitkBackProjectImage.cxx clitkBackProjectImageGenericFilter.cxx ${clitkBackProjectImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkBackProjectImage ${ITK_LIBRARIES} clitkCommon )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBackProjectImage)
+
+  ADD_EXECUTABLE(clitkCropImage clitkCropImage.cxx ${clitkCropImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkCropImage clitkCropImageLib clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkCropImage)
+
+  # WRAP_GGO(clitkExtractSlice_GGO_C clitkExtractSlice.ggo)
+  # ADD_EXECUTABLE(clitkExtractSlice clitkExtractSlice.cxx clitkExtractSliceGenericFilter.cxx ${clitkExtractSlice_GGO_C})
+  # TARGET_LINK_LIBRARIES(clitkExtractSlice clitkCommon ${ITK_LIBRARIES})
+  #SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkExtractSlice)
+  
+  WRAP_GGO(clitkFlipImage_GGO_C clitkFlipImage.ggo)
+  ADD_EXECUTABLE(clitkFlipImage clitkFlipImage.cxx clitkFlipImageGenericFilter.cxx ${clitkFlipImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkFlipImage clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkFlipImage)
+
+  WRAP_GGO(clitkMirrorPadImage_GGO_C clitkMirrorPadImage.ggo)
+  ADD_EXECUTABLE(clitkMirrorPadImage clitkMirrorPadImage.cxx clitkMirrorPadImageGenericFilter.cxx ${clitkMirrorPadImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMirrorPadImage clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMirrorPadImage)
+
+  WRAP_GGO(clitkImageMoment_GGO_C clitkImageMoment.ggo)
+  ADD_EXECUTABLE(clitkImageMoment clitkImageMoment.cxx clitkImageMomentGenericFilter.cxx ${clitkImageMoment_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkImageMoment clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicom2Image)
+
+  WRAP_GGO(clitkImageStatistics_GGO_C clitkImageStatistics.ggo)
+  ADD_EXECUTABLE(clitkImageStatistics clitkImageStatistics.cxx clitkImageStatisticsGenericFilter.cxx ${clitkImageStatistics_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkImageStatistics clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageStatistics)
+
+  WRAP_GGO(clitkSetOrigin_GGO_C clitkSetOrigin.ggo)
+  ADD_EXECUTABLE(clitkSetOrigin clitkSetOrigin.cxx clitkSetOriginGenericFilter.cxx ${clitkSetOrigin_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkSetOrigin clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSetOrigin)
     
-    WRAP_GGO(clitkFlipImage_GGO_C clitkFlipImage.ggo)
-    ADD_EXECUTABLE(clitkFlipImage clitkFlipImage.cxx clitkFlipImageGenericFilter.cxx ${clitkFlipImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkFlipImage clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkMirrorPadImage_GGO_C clitkMirrorPadImage.ggo)
-    ADD_EXECUTABLE(clitkMirrorPadImage clitkMirrorPadImage.cxx clitkMirrorPadImageGenericFilter.cxx ${clitkMirrorPadImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkMirrorPadImage clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkImageMoment_GGO_C clitkImageMoment.ggo)
-    ADD_EXECUTABLE(clitkImageMoment clitkImageMoment.cxx clitkImageMomentGenericFilter.cxx ${clitkImageMoment_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkImageMoment clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkImageStatistics_GGO_C clitkImageStatistics.ggo)
-    ADD_EXECUTABLE(clitkImageStatistics clitkImageStatistics.cxx clitkImageStatisticsGenericFilter.cxx ${clitkImageStatistics_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkImageStatistics clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkSetOrigin_GGO_C clitkSetOrigin.ggo)
-    ADD_EXECUTABLE(clitkSetOrigin clitkSetOrigin.cxx clitkSetOriginGenericFilter.cxx ${clitkSetOrigin_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkSetOrigin clitkCommon ${ITK_LIBRARIES} )
-     
-    WRAP_GGO(clitkGetOrigin_GGO_C clitkGetOrigin.ggo)
-    ADD_EXECUTABLE(clitkGetOrigin clitkGetOrigin.cxx clitkGetOriginGenericFilter.cxx ${clitkGetOrigin_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkGetOrigin clitkCommon ${ITK_LIBRARIES} )
-
-    WRAP_GGO(clitkGetDirection_GGO_C clitkGetDirection.ggo)
-    ADD_EXECUTABLE(clitkGetDirection clitkGetDirection.cxx clitkGetDirectionGenericFilter.cxx ${clitkGetDirection_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkGetDirection clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkSetDirection_GGO_C clitkSetDirection.ggo)
-    ADD_EXECUTABLE(clitkSetDirection clitkSetDirection.cxx clitkSetDirectionGenericFilter.cxx ${clitkSetDirection_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkSetDirection clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkGetSize_GGO_C clitkGetSize.ggo)
-    ADD_EXECUTABLE(clitkGetSize  clitkGetSize.cxx clitkGetSizeGenericFilter.cxx ${clitkGetSize_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkGetSize  clitkCommon   ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkGetSpacing_GGO_C clitkGetSpacing.ggo)
-    ADD_EXECUTABLE(clitkGetSpacing  clitkGetSpacing.cxx clitkGetSpacingGenericFilter.cxx ${clitkGetSpacing_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkGetSpacing  clitkCommon   ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkSetSpacing_GGO_C clitkSetSpacing.ggo)
-    ADD_EXECUTABLE(clitkSetSpacing  clitkSetSpacing.cxx clitkSetSpacingGenericFilter.cxx ${clitkSetSpacing_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkSetSpacing  clitkCommon   ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkCombineImage_GGO_C clitkCombineImage.ggo)
-    ADD_EXECUTABLE(clitkCombineImage clitkCombineImage.cxx clitkCombineImageGenericFilter.cxx ${clitkCombineImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkCombineImage clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkPermuteAxes_GGO_C clitkPermuteAxes.ggo)
-    ADD_EXECUTABLE(clitkPermuteAxes clitkPermuteAxes.cxx clitkPermuteAxesGenericFilter.cxx ${clitkPermuteAxes_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkPermuteAxes clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkChangeImageOrientation_GGO_C clitkChangeImageOrientation.ggo)
-    ADD_EXECUTABLE(clitkChangeImageOrientation clitkChangeImageOrientation.cxx clitkChangeImageOrientationGenericFilter.cxx ${clitkChangeImageOrientation_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkChangeImageOrientation clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkVFConvert_GGO_C clitkVFConvert.ggo)
-    ADD_EXECUTABLE(clitkVFConvert clitkVFConvert.cxx clitkVFConvertGenericFilter.cxx ${clitkVFConvert_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkVFConvert ${ITK_LIBRARIES} clitkCommon )
-
-    WRAP_GGO(clitkImageToVectorImage_GGO_C clitkImageToVectorImage.ggo)
-    ADD_EXECUTABLE(clitkImageToVectorImage  clitkImageToVectorImage.cxx clitkImageToVectorImageGenericFilter.cxx ${clitkImageToVectorImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkImageToVectorImage  clitkCommon   ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkVectorImageToImage_GGO_C clitkVectorImageToImage.ggo)
-    ADD_EXECUTABLE(clitkVectorImageToImage  clitkVectorImageToImage.cxx clitkVectorImageToImageGenericFilter.cxx ${clitkVectorImageToImage_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkVectorImageToImage  clitkCommon   ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkBSplineCoefficientsToValues_GGO_C clitkBSplineCoefficientsToValues.ggo)
-    ADD_EXECUTABLE(clitkBSplineCoefficientsToValues  clitkBSplineCoefficientsToValues.cxx clitkBSplineCoefficientsToValuesGenericFilter.cxx ${clitkBSplineCoefficientsToValues_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkBSplineCoefficientsToValues clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkValuesToBSplineCoefficients_GGO_C clitkValuesToBSplineCoefficients.ggo)
-    ADD_EXECUTABLE(clitkValuesToBSplineCoefficients  clitkValuesToBSplineCoefficients.cxx clitkValuesToBSplineCoefficientsGenericFilter.cxx ${clitkValuesToBSplineCoefficients_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkValuesToBSplineCoefficients clitkCommon ${ITK_LIBRARIES})
-
-    ADD_EXECUTABLE(clitkMIP clitkMIP.cxx clitkMIPGenericFilter.cxx)
-    TARGET_LINK_LIBRARIES(clitkMIP clitkMIPLib clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkRelativePosition_GGO_C clitkRelativePosition.ggo)
-    ADD_EXECUTABLE(clitkRelativePosition  clitkRelativePosition.cxx ${clitkRelativePosition_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkRelativePosition clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkTransformLandmarks_GGO_C clitkTransformLandmarks.ggo)
-    ADD_EXECUTABLE(clitkTransformLandmarks clitkTransformLandmarks.cxx ${clitkTransformLandmarks_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkTransformLandmarks clitkCommon ${ITK_LIBRARIES})
-
-    WRAP_GGO(clitkLineProfile_GGO_C clitkLineProfile.ggo)
-    ADD_EXECUTABLE(clitkLineProfile clitkLineProfile.cxx clitkLineProfileGenericFilter.cxx ${clitkLineProfile_GGO_C})
-    TARGET_LINK_LIBRARIES(clitkLineProfile clitkCommon ${ITK_LIBRARIES})
+  WRAP_GGO(clitkGetOrigin_GGO_C clitkGetOrigin.ggo)
+  ADD_EXECUTABLE(clitkGetOrigin clitkGetOrigin.cxx clitkGetOriginGenericFilter.cxx ${clitkGetOrigin_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkGetOrigin clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGetOrigin)
+
+  WRAP_GGO(clitkGetDirection_GGO_C clitkGetDirection.ggo)
+  ADD_EXECUTABLE(clitkGetDirection clitkGetDirection.cxx clitkGetDirectionGenericFilter.cxx ${clitkGetDirection_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkGetDirection clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGetDirection)
+
+  WRAP_GGO(clitkSetDirection_GGO_C clitkSetDirection.ggo)
+  ADD_EXECUTABLE(clitkSetDirection clitkSetDirection.cxx clitkSetDirectionGenericFilter.cxx ${clitkSetDirection_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkSetDirection clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkSetDirection)
+
+  WRAP_GGO(clitkGetSize_GGO_C clitkGetSize.ggo)
+  ADD_EXECUTABLE(clitkGetSize  clitkGetSize.cxx clitkGetSizeGenericFilter.cxx ${clitkGetSize_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkGetSize  clitkCommon   ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGetSize)
+
+  WRAP_GGO(clitkGetSpacing_GGO_C clitkGetSpacing.ggo)
+  ADD_EXECUTABLE(clitkGetSpacing  clitkGetSpacing.cxx clitkGetSpacingGenericFilter.cxx ${clitkGetSpacing_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkGetSpacing  clitkCommon   ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkGetSpacing)
+
+  WRAP_GGO(clitkSetSpacing_GGO_C clitkSetSpacing.ggo)
+  ADD_EXECUTABLE(clitkSetSpacing  clitkSetSpacing.cxx clitkSetSpacingGenericFilter.cxx ${clitkSetSpacing_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkSetSpacing  clitkCommon   ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDicom2Image)
+
+  WRAP_GGO(clitkCombineImage_GGO_C clitkCombineImage.ggo)
+  ADD_EXECUTABLE(clitkCombineImage clitkCombineImage.cxx clitkCombineImageGenericFilter.cxx ${clitkCombineImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkCombineImage clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkCombineImage)
+
+  WRAP_GGO(clitkPermuteAxes_GGO_C clitkPermuteAxes.ggo)
+  ADD_EXECUTABLE(clitkPermuteAxes clitkPermuteAxes.cxx clitkPermuteAxesGenericFilter.cxx ${clitkPermuteAxes_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkPermuteAxes clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkPermuteAxes)
+
+  WRAP_GGO(clitkChangeImageOrientation_GGO_C clitkChangeImageOrientation.ggo)
+  ADD_EXECUTABLE(clitkChangeImageOrientation clitkChangeImageOrientation.cxx clitkChangeImageOrientationGenericFilter.cxx ${clitkChangeImageOrientation_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkChangeImageOrientation clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkChangeImageOrientation)
+
+  WRAP_GGO(clitkVFConvert_GGO_C clitkVFConvert.ggo)
+  ADD_EXECUTABLE(clitkVFConvert clitkVFConvert.cxx clitkVFConvertGenericFilter.cxx ${clitkVFConvert_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkVFConvert ${ITK_LIBRARIES} clitkCommon )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVFConvert)
+
+  WRAP_GGO(clitkImageToVectorImage_GGO_C clitkImageToVectorImage.ggo)
+  ADD_EXECUTABLE(clitkImageToVectorImage  clitkImageToVectorImage.cxx clitkImageToVectorImageGenericFilter.cxx ${clitkImageToVectorImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkImageToVectorImage  clitkCommon   ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageToVectorImage)
+
+  WRAP_GGO(clitkVectorImageToImage_GGO_C clitkVectorImageToImage.ggo)
+  ADD_EXECUTABLE(clitkVectorImageToImage  clitkVectorImageToImage.cxx clitkVectorImageToImageGenericFilter.cxx ${clitkVectorImageToImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkVectorImageToImage  clitkCommon   ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVectorImageToImage)
+
+  WRAP_GGO(clitkBSplineCoefficientsToValues_GGO_C clitkBSplineCoefficientsToValues.ggo)
+  ADD_EXECUTABLE(clitkBSplineCoefficientsToValues  clitkBSplineCoefficientsToValues.cxx clitkBSplineCoefficientsToValuesGenericFilter.cxx ${clitkBSplineCoefficientsToValues_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkBSplineCoefficientsToValues clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBSplineCoefficientsToValues)
+
+  WRAP_GGO(clitkValuesToBSplineCoefficients_GGO_C clitkValuesToBSplineCoefficients.ggo)
+  ADD_EXECUTABLE(clitkValuesToBSplineCoefficients  clitkValuesToBSplineCoefficients.cxx clitkValuesToBSplineCoefficientsGenericFilter.cxx ${clitkValuesToBSplineCoefficients_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkValuesToBSplineCoefficients clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkValuesToBSplineCoefficients)
+
+  ADD_EXECUTABLE(clitkMIP clitkMIP.cxx clitkMIPGenericFilter.cxx)
+  TARGET_LINK_LIBRARIES(clitkMIP clitkMIPLib clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMIP)
+
+  WRAP_GGO(clitkRelativePosition_GGO_C clitkRelativePosition.ggo)
+  ADD_EXECUTABLE(clitkRelativePosition  clitkRelativePosition.cxx ${clitkRelativePosition_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkRelativePosition clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkRelativePosition)
+
+  WRAP_GGO(clitkTransformLandmarks_GGO_C clitkTransformLandmarks.ggo)
+  ADD_EXECUTABLE(clitkTransformLandmarks clitkTransformLandmarks.cxx ${clitkTransformLandmarks_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkTransformLandmarks clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkTransformLandmarks)
+
+  WRAP_GGO(clitkLineProfile_GGO_C clitkLineProfile.ggo)
+  ADD_EXECUTABLE(clitkLineProfile clitkLineProfile.cxx clitkLineProfileGenericFilter.cxx ${clitkLineProfile_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkLineProfile clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkLineProfile)
+
+  ADD_EXECUTABLE(clitkMakeSphereImage clitkMakeSphereImage.cxx) # clitkLineProfileGenericFilter.cxx ${clitkLineProfile_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMakeSphereImage clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMakeSphereImage)
+
+  WRAP_GGO(clitkJacobianImage_GGO_C clitkJacobianImage.ggo)
+  ADD_EXECUTABLE(clitkJacobianImage clitkJacobianImage.cxx clitkJacobianImageGenericFilter.cxx ${clitkJacobianImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkJacobianImage clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkJacobianImage)
+  
+  WRAP_GGO(clitkPadImage_GGO_C clitkPadImage.ggo)
+  ADD_EXECUTABLE(clitkPadImage clitkPadImage.cxx ${clitkPadImage_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkPadImage clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkPadImage)
+
+  IF(CLITK_EXPERIMENTAL)
+
+    WRAP_GGO(clitkBinaryImageToMesh_GGO_C clitkBinaryImageToMesh.ggo)
+    ADD_EXECUTABLE(clitkBinaryImageToMesh clitkBinaryImageToMesh.cxx ${clitkBinaryImageToMesh_GGO_C})
+    TARGET_LINK_LIBRARIES(clitkBinaryImageToMesh ${ITK_LIBRARIES} vtkCommon vtkRendering)
+    SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkBinaryImageToMesh)
+
+    WRAP_GGO(clitkMeshViewer_GGO_C clitkMeshViewer.ggo)
+    ADD_EXECUTABLE(clitkMeshViewer clitkMeshViewer.cxx ${clitkMeshViewer_GGO_C})
+    TARGET_LINK_LIBRARIES(clitkMeshViewer vtkCommon vtkRendering)
+    SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMeshViewer)
+  ENDIF(CLITK_EXPERIMENTAL)
+
+  SET_TARGET_PROPERTIES(${TOOLS_INSTALL} PROPERTIES INSTALL_RPATH "${VTK_DIR}:${ITK_DIR}" )  
+  INSTALL (TARGETS ${TOOLS_INSTALL} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
 
 ENDIF(CLITK_BUILD_TOOLS)
 
index ba035367e9424b5ed1779b10c3ce4326ba774cd7..8eeb3fc3b8b6365fb1bf348905d2514b241e33e4 100644 (file)
@@ -10,6 +10,7 @@ section "I/O"
 option "input"         i       "Input image filename"            string        yes
 option "output"        o       "Output image filename"           string        yes
 option "like"          l       "Resample output this image (size, spacing,origin)"     string  no
+option "transform_grid" -       "Apply affine transform to input grid for output's"     flag    off
 
 section "Options"
 option "size"          -       "New output size if different from input"       int     no      multiple
index 5a8cfa964e144132560fbc080da28ae903c67937..ef81fe2d464bc7082ed42a8f2d9ae1d5856ea3dc 100644 (file)
@@ -163,6 +163,46 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
     likeReader->SetFileName(m_ArgsInfo.like_arg);
     likeReader->Update();
     resampler->SetOutputParametersFromImage(likeReader->GetOutput());
+  } else if(m_ArgsInfo.transform_grid_flag) {
+    typename itk::Matrix<double, Dimension+1, Dimension+1> invMatrix( matrix.GetInverse() );
+    typename itk::Matrix<double, Dimension, Dimension> invRotMatrix( clitk::GetRotationalPartMatrix(invMatrix) );
+    typename itk::Vector<double,Dimension> invTrans =  clitk::GetTranslationPartMatrix(invMatrix);
+
+    // Spacing is influenced by affine transform matrix and input direction
+    typename InputImageType::SpacingType outputSpacing;
+    outputSpacing = invRotMatrix *
+                    input->GetDirection() *
+                    input->GetSpacing();
+
+    // Origin is influenced by translation but not by input direction
+    typename InputImageType::PointType outputOrigin;
+    outputOrigin = invRotMatrix *
+                   input->GetOrigin() +
+                   invTrans;
+
+    // Size is influenced by affine transform matrix and input direction
+    // Size is converted to double, transformed and converted back to size type.
+    vnl_vector<double> vnlOutputSize(Dimension);
+    for(unsigned int i=0; i< Dimension; i++) {
+      vnlOutputSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
+    }
+    vnlOutputSize = invRotMatrix *
+                    input->GetDirection().GetVnlMatrix() *
+                    vnlOutputSize;
+    typename OutputImageType::SizeType outputSize;
+    for(unsigned int i=0; i< Dimension; i++) {
+      // If the size is negative, we have a flip and we must modify
+      // the origin and the spacing accordingly.
+      if(vnlOutputSize[i]<0.) {
+        vnlOutputSize[i] *= -1.;
+        outputOrigin[i] = outputOrigin[i] + outputSpacing[i] * (vnlOutputSize[i]-1);
+        outputSpacing[i] *= -1.;
+      }
+      outputSize[i] = lrint(vnlOutputSize[i]);
+    }
+    resampler->SetSize( outputSize );
+    resampler->SetOutputSpacing( outputSpacing );
+    resampler->SetOutputOrigin( outputOrigin );
   } else {
     //Size
     typename OutputImageType::SizeType outputSize;
@@ -170,7 +210,6 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
       for(unsigned int i=0; i< Dimension; i++)
         outputSize[i]=m_ArgsInfo.size_arg[i];
     } else outputSize=input->GetLargestPossibleRegion().GetSize();
-    std::cout<<"Setting the size to "<<outputSize<<"..."<<std::endl;
 
     //Spacing
     typename OutputImageType::SpacingType outputSpacing;
@@ -178,7 +217,6 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
       for(unsigned int i=0; i< Dimension; i++)
         outputSpacing[i]=m_ArgsInfo.spacing_arg[i];
     } else outputSpacing=input->GetSpacing();
-    std::cout<<"Setting the spacing to "<<outputSpacing<<"..."<<std::endl;
 
     //Origin
     typename OutputImageType::PointType outputOrigin;
@@ -186,7 +224,6 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
       for(unsigned int i=0; i< Dimension; i++)
         outputOrigin[i]=m_ArgsInfo.origin_arg[i];
     } else outputOrigin=input->GetOrigin();
-    std::cout<<"Setting the origin to "<<outputOrigin<<"..."<<std::endl;
 
     // Set
     resampler->SetSize( outputSize );
@@ -195,6 +232,12 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
 
   }
 
+  if (m_ArgsInfo.verbose_flag) {
+    std::cout << "Setting the output size to " << resampler->GetSize() << "..." << std::endl;
+    std::cout << "Setting the output spacing to " << resampler->GetOutputSpacing() << "..." << std::endl;
+    std::cout << "Setting the output origin to " << resampler->GetOutputOrigin() << "..." << std::endl;
+  }
+
   resampler->SetInput( input );
   resampler->SetTransform( affineTransform );
   resampler->SetInterpolator( genericInterpolator->GetInterpolatorPointer());
index ff102320daf38582f1a15afe40881b4a65bfbd4c..184cc4f4374bfb51f68bfad91b12da166b3433ca 100644 (file)
 #include "itkBSplineResampleImageFunction.h"
 #include "clitkVectorBSplineResampleImageFunction.h"
 #include "itkAddImageFilter.h"
-#include "itkTransformToDeformationFieldSource.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkTransformToDisplacementFieldSource.h"
+#else
+  #include "itkTransformToDeformationFieldSource.h"
+#endif
 
 namespace clitk 
 {
index a2156499773160bd62d6b430ac762688361ca22c..0111db24da506afa39a3bec1286af876104002df 100644 (file)
@@ -284,7 +284,11 @@ namespace clitk
     // Matrix Transform
     if(m_ArgsInfo.matrix_given)
       {
+#if ITK_VERSION_MAJOR >= 4
+       typedef itk::TransformToDisplacementFieldSource<OutputImageType, double> ConvertorType;
+#else
        typedef itk::TransformToDeformationFieldSource<OutputImageType, double> ConvertorType;
+#endif
        typename   ConvertorType::Pointer filter= ConvertorType::New();
        filter->SetOutputParametersFromImage(output);
        
diff --git a/tools/clitkBinaryImageToMesh.cxx b/tools/clitkBinaryImageToMesh.cxx
new file mode 100644 (file)
index 0000000..463fa45
--- /dev/null
@@ -0,0 +1,122 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+#include "clitkBinaryImageToMesh_ggo.h"
+#include "clitkImageToImageGenericFilter.h"
+
+#include "vtkMetaImageReader.h"
+#include "vtkContourFilter.h"
+#include "vtkDecimatePro.h"
+#include "vtkPolyDataMapper.h"
+#include "vtkRenderer.h"
+#include "vtkRenderWindow.h"
+#include "vtkActor.h"
+#include "vtkCamera.h"
+#include "vtkOBJExporter.h"
+#include "vtkRenderWindowInteractor.h"
+#include "vtkSmartPointer.h"
+
+#include "itksys/SystemTools.hxx"
+
+void run(const args_info_clitkBinaryImageToMesh& argsInfo);
+
+int main(int argc, char** argv)
+{
+  GGO(clitkBinaryImageToMesh, args_info);
+
+  run(args_info);
+  
+  return EXIT_SUCCESS;
+}
+
+void run(const args_info_clitkBinaryImageToMesh& argsInfo)
+{
+    std::string file = argsInfo.input_arg;
+   
+    vtkSmartPointer<vtkMetaImageReader> pbmp_reader = vtkMetaImageReader::New();
+    pbmp_reader->SetFileName(file.c_str());
+    pbmp_reader->Update();
+
+    printf("Filtering...\n");
+    vtkSmartPointer<vtkContourFilter> pcontour = vtkContourFilter::New();
+    pcontour->SetValue(0, 0.5);
+    pcontour->SetInputConnection(pbmp_reader->GetOutputPort());
+    
+    vtkSmartPointer<vtkDecimatePro> psurface = vtkDecimatePro::New();
+    psurface->SetInputConnection(pcontour->GetOutputPort());
+
+    vtkSmartPointer<vtkPolyDataMapper> skinMapper = vtkPolyDataMapper::New();
+      skinMapper->SetInputConnection(psurface->GetOutputPort());
+      skinMapper->ScalarVisibilityOff();
+    
+    vtkSmartPointer<vtkActor> skin = vtkActor::New();
+      skin->SetMapper(skinMapper);
+    
+    vtkSmartPointer<vtkCamera> aCamera = vtkCamera::New();
+      aCamera->SetViewUp (0, 0, -1);
+      aCamera->SetPosition (0, 1, 0);
+      aCamera->SetFocalPoint (0, 0, 0);
+      aCamera->ComputeViewPlaneNormal();
+    aCamera->Dolly(1.5);
+
+    vtkSmartPointer<vtkRenderer> aRenderer = vtkRenderer::New();
+    aRenderer->AddActor(skin);
+    aRenderer->SetActiveCamera(aCamera);
+    aRenderer->ResetCamera ();
+    aRenderer->SetBackground(0,0,0);
+    aRenderer->ResetCameraClippingRange ();
+
+    vtkSmartPointer<vtkRenderWindow> renWin = vtkRenderWindow::New();
+      renWin->AddRenderer(aRenderer);
+    renWin->SetSize(640, 480);
+    
+    vtkSmartPointer<vtkOBJExporter> pwriter2 = vtkOBJExporter::New();
+    pwriter2->SetRenderWindow(renWin);
+
+    std::string output;
+    if (argsInfo.output_given) {
+      output = argsInfo.output_arg;
+      if (itksys::SystemTools::FileIsDirectory(output.c_str())) {
+        file = itksys::SystemTools::GetFilenameName(file.c_str());
+        file = itksys::SystemTools::GetFilenameWithoutExtension(file.c_str());
+        file = itksys::SystemTools::CollapseFullPath(file.c_str(), output.c_str());
+      }
+      else {
+        file = output;
+      }
+    }
+    else { 
+      file = itksys::SystemTools::GetFilenameWithoutExtension(file);
+    }
+    pwriter2->SetFilePrefix(file.c_str());
+    pwriter2->Write();
+
+    vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkRenderWindowInteractor::New();
+      iren->SetRenderWindow(renWin);
+
+    skinMapper->Update();
+    bool interact = argsInfo.view_flag;
+    if (interact)
+    {
+      iren->Initialize();
+      iren->Start(); 
+    }
+    else
+      renWin->Render();
+}
+
+
diff --git a/tools/clitkBinaryImageToMesh.ggo b/tools/clitkBinaryImageToMesh.ggo
new file mode 100644 (file)
index 0000000..d04462d
--- /dev/null
@@ -0,0 +1,11 @@
+#File clitkBinaryImageToMesh.ggo
+package "clitkBinaryImageToMesh"
+version "1.0"
+purpose "Get the HU profile along the given line. Output to stdout."
+
+option "config"   - "Config file"   string  no
+option "verbose"  v     "Verbose"   flag  off
+
+option "input"    i "Input image"   string  yes
+option "output"    o "Output mesh file prefix (if empty, use input file's base name as prefix; if a directoy, output to it using input file's base name as prefix; otherwise, use given name as prefix"  string  no
+option "view"   - "View result"        flag    off
index 1c77551e0500be7c8b9601d67d1610b4c9a99fa1..4e80707a030803ce6c948b65206f792938c462fa 100644 (file)
@@ -35,4 +35,4 @@ option "size"                 -       "Size for the output image"                     int             multiple no     default="512"
 option "spacing"               -       "Spacing for the output image"                  double          multiple no     default="0.8"       
 
 option "panel_position"         -       "Approximate position of the panel: small, medium or large"     string          no              default="small"
-option "panel_shift"            -       "Precise position of the panel in mm"           double          no
+option "panel_shift"            -       "Precise position of the panel in mm"           double          multiple        no
index fcf8610c5798ab471583a69aa751316ce1e3682f..2363a5f1a3882567f5eaa926adf7d19c7b34abce 100644 (file)
@@ -188,11 +188,16 @@ namespace clitk
     }
 
     /** Set the panelshift. */
-    void SetPanelShift(double shift)
+    void SetPanelShift(double x, double y)
     {
-      if (m_PanelShift!=shift)
+      if (m_PanelShift[0] != x)
        {
-         m_PanelShift=shift;
+         m_PanelShift[0] = x;
+         m_IsInitialized=false;
+       }
+      if (m_PanelShift[1] != y)
+       {
+         m_PanelShift[1] = y;
          m_IsInitialized=false;
        }
     }
@@ -229,7 +234,7 @@ namespace clitk
     double m_SourceToScreen;
     double m_SourceToAxis;
     double m_ProjectionAngle;
-    double m_PanelShift;
+    double m_PanelShift[2];
     MatrixType m_RigidTransformMatrix;
     OutputPixelType m_EdgePaddingValue;
 
index dfc889827dfab2865ec6914910f0dad0763047b2..798fbd1c5bd10b83e5d5b8994ef8da36bf62e7e3 100644 (file)
@@ -36,6 +36,8 @@ namespace clitk
     m_IsoCenter.Fill(0.0);
     m_SourceToScreen=1536.;
     m_SourceToAxis=1000.;
+    m_PanelShift[0] = 0.;
+    m_PanelShift[1] = 0.;
     m_ProjectionAngle=0.;
     m_RigidTransformMatrix.SetIdentity();
     m_EdgePaddingValue=itk::NumericTraits<OutputPixelType>::Zero;//density images
@@ -163,15 +165,15 @@ namespace clitk
     spacingOutput[1] = m_OutputSpacing[0];  // pixel spacing along Y of the 2D DRR image [mm]
     spacingOutput[2] = m_OutputSpacing[1];  // pixel spacing along Y of the 2D DRR image [mm]
     m_Resampler->SetOutputSpacing( spacingOutput );
-    if (m_Verbose)std::cout<<"The output size is "<< m_OutputSpacing <<"..."<< std::endl;
+    if (m_Verbose)std::cout<<"The output spacing is "<< m_OutputSpacing <<"..."<< std::endl;
 
     // The position of the DRR is specified, we presume that for an angle of 0° the flatpanel is located at the negative x-axis
     // JV -1 seems to correspond better with shearwarp of Simon Rit
     typename  InterpolatorType::InputPointType originOutput;
     originOutput[0] = m_IsoCenter[0]- (m_SourceToScreen - m_SourceToAxis);
     DD(m_PanelShift);
-    originOutput[1] = m_IsoCenter[1]-static_cast<double>(sizeOuput[1]-1)*spacingOutput[1]/2.0 - m_PanelShift;
-    originOutput[2] = m_IsoCenter[2]-static_cast<double>(sizeOuput[2]-1)*spacingOutput[2]/2.0
+    originOutput[1] = m_IsoCenter[1]-static_cast<double>(sizeOuput[1]-1)*spacingOutput[1]/2.0 - m_PanelShift[0];
+    originOutput[2] = m_IsoCenter[2]-static_cast<double>(sizeOuput[2]-1)*spacingOutput[2]/2.0 - m_PanelShift[1];
     m_Resampler->SetOutputOrigin( originOutput );
     if (m_Verbose)std::cout<<"The origin of the flat panel is at "<< originOutput <<",..."<< std::endl;
 
index d659b969f8e2f48a75eb30ed8724eb1dc72d1ec2..e36b7d1b1febafabe4843a7a627516292d5ba2ea 100644 (file)
@@ -133,14 +133,14 @@ namespace clitk
 
     DD(m_ArgsInfo.panel_position_arg);
     if (m_ArgsInfo.panel_shift_given) // one should read the specific values for each angle in Frame.dbf
-      filter->SetPanelShift(m_ArgsInfo.panel_shift_arg);
+      filter->SetPanelShift(m_ArgsInfo.panel_shift_arg[0], m_ArgsInfo.panel_shift_arg[1]);
     else { // approximate panel positions hard coded values for the elekta synergy
       if (strcmp(m_ArgsInfo.panel_position_arg,"small") ==0)
-        filter->SetPanelShift(0.);
+        filter->SetPanelShift(0., 0.);
       else if (strcmp(m_ArgsInfo.panel_position_arg,"medium") ==0)
-        filter->SetPanelShift(114.84);
+        filter->SetPanelShift(114.84, 0.); // VD : 120 , 0 ?
       else if (strcmp(m_ArgsInfo.panel_position_arg,"large") ==0)
-        filter->SetPanelShift(190.);
+        filter->SetPanelShift(190., 0.);
       else assert(false); //Unsupported panel position
     }
     // Output image info
index 8e557139501b3ba72393231faecfd1221a1881ff..3c6725cdccd056c1c501f373e1d2d84716db0634 100644 (file)
@@ -34,7 +34,7 @@ int main(int argc, char * argv[])
 
   filter->SetArgsInfo(args_info);
 
-  try {
+  try { 
     filter->Update();
   } catch(std::runtime_error e) {
     std::cout << e.what() << std::endl;
index e8650de42447336cd1b09755ac4cabdc99313f33..a674f8bbef5b5450493a3c0eae14ccde4acb0579 100644 (file)
@@ -15,7 +15,7 @@ option "input"                i       "Input image filename"            string        yes
 option "output"        o       "Output image filename"           string        yes
 
 section "Used determined crop"
-option "boundingBox"           b       "Bounding box of the crop region (in 2D: =x1,y2, x2,y2)"  int   no  multiple
+option "boundingBox"           b       "Bounding box of the crop region (in 3D: =x1,x2,y1,y2,z1,z2)"  int      no  multiple
 option "lower"         l       "Size of the lower crop region (multiple values)"         int   no  multiple
 option "upper"         u       "Size of the upper crop region (multiple values)"         int   no  multiple
 option "origin"        -       "Set new origin to zero"          flag  off  
index b062976b678b4dac3abe72804dd6dbda572c81aa..aeae1f988806c100c6198f407f59baefc5134222 100644 (file)
@@ -79,6 +79,7 @@ namespace clitk
   { 
     // Reading input
     typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
+    typename ImageType::RegionType input_region = input->GetLargestPossibleRegion();
 
     // Check options
     if (mArgsInfo.BG_given && mArgsInfo.like_given)
@@ -123,10 +124,11 @@ namespace clitk
         // ------------------------------------------------
         typename ImageType::SizeType lSize;
         typename ImageType::SizeType uSize;
+        if (mArgsInfo.verbose_flag) std::cout << "input region " << input_region << std::endl;
         if (mArgsInfo.boundingBox_given) {
           for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
             lSize[i] = mArgsInfo.boundingBox_arg[2*i];
-            uSize[i] = input->GetLargestPossibleRegion().GetSize()[i]-mArgsInfo.boundingBox_arg[2*i+1]-1;
+            uSize[i] = input_region.GetSize()[i]-mArgsInfo.boundingBox_arg[2*i+1]-1;
           }
         }
         else {
@@ -141,6 +143,11 @@ namespace clitk
           }
           else uSize.Fill(0);
         }
+        
+        if (mArgsInfo.verbose_flag) {
+          std::cout << "lower " << lSize << " upper " << uSize << std::endl;
+        }
+        
         typedef  itk::CropImageFilter<ImageType, ImageType> CropImageFilterType;
         typename CropImageFilterType::Pointer filter=CropImageFilterType::New();
         filter->SetInput(input);
@@ -157,7 +164,22 @@ namespace clitk
       origin.Fill(itk::NumericTraits<double>::Zero);
       output->SetOrigin(origin);
     }
-
+    
+    // adjust image origin and force index to zero 
+    typename ImageType::RegionType region = output->GetLargestPossibleRegion();
+    typename ImageType::IndexType index = region.GetIndex();
+    typename ImageType::PointType origin = output->GetOrigin();
+    typename ImageType::SpacingType spacing = output->GetSpacing();
+    if (mArgsInfo.verbose_flag) std::cout << "origin before crop " << origin << std::endl;
+    for (unsigned int i = 0; i < output->GetImageDimension(); i++)
+      origin[i] += index[i]*spacing[i];
+    if (mArgsInfo.verbose_flag) std::cout << "origin after crop " << origin << std::endl;
+    output->SetOrigin(origin);
+
+    index.Fill(itk::NumericTraits<double>::Zero);
+    region.SetIndex(index);
+    output->SetRegions(region);
+    
     // Write/Save results
     this->template SetNextOutput<ImageType>(output); 
   }
index d54c47e408d75d068a0a9089a1f5fe9961d48a8c..97eff971d4fb4b26f923d1a56357cc1424cbceb4 100644 (file)
@@ -30,7 +30,9 @@ int main(int argc, char * argv[]) {
   // Read and display information
   clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
   s->Read(args_info.input_arg);
-  // s->Print(std::cout);
+  if (args_info.verboseFile_flag) {
+    s->Print(std::cout);
+  }
   
   // New filter to convert to binary image
   clitk::DicomRT_ROI_ConvertToImageFilter filter;
index 5fdd7414c5f16dfa81e58bf925bfec6711dc2b06..d403f069524b7b112ceb67d19bb7b3eaad718f0a 100644 (file)
@@ -4,6 +4,7 @@ version "Convert DICOM RT Structure Set (contours) to binary image"
 
 option "config"                 - "Config file"                     string     no
 option "verbose"         v "Verbose"                        flag       off
+option "verboseFile"     - "Verbose file content"            flag      off
 option "input"          i "Input Dicom file"                string     yes
 option "image"          j "Used to read image info (spacing, origin)"    string        yes
 option "roi"            r "ROI to binarize (if -1 = all roi)"            int    no default="-1"
index 6f4b932c5a6f24f1ddf8f56f43e90d43f660d5ce..ca7e91607876aa9d33c608f907177a58513aa453 100644 (file)
@@ -13,7 +13,7 @@ option "input2"          j    "Input second image filename"     string   no
 option "output"    o   "Output image filename"           string   yes
 
 option "scalar"           s    "Scalar value"            double   no
-option "operation" t   "Type of operation : \n With another image : 0=add, 1=multiply, 2=divide,\n 3=max, 4=min, 5=absdiff, 6=squareddiff,  7=difference, 8=relativ diff\n For 'scalar' : 0=add, 1=multiply, 2=inverse,\n 3=max, 4=min 5=absval 6=squareval\n 7=log 8=exp 9=sqrt 10=EPID"      int default="0" no 
+option "operation" t   "Type of operation : \n With another image : 0=add, 1=multiply, 2=divide,\n 3=max, 4=min, 5=absdiff, 6=squareddiff,  7=difference, 8=relativ diff\n For 'scalar' : 0=add, 1=multiply, 2=inverse,\n 3=max, 4=min 5=absval 6=squareval\n 7=log 8=exp 9=sqrt 10=EPID 11=divide 12=normalize (divide by max)"       int default="0" no 
 option "pixelValue" -  "Default value for NaN/Inf"     double   default="0.0"  no
 
 option "setFloatOutput" f "Set output to float pixel type" flag off
index f3b1d449718abdc68b8c1333d0d9ef85ee56d535..24ebbbdac8d2d472ec6ddca3eebbdcfdd5f33f6f 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "clitkImageCommon.h"
 
+#include "itkMinimumMaximumImageCalculator.h"
+
 namespace clitk
 {
 
@@ -110,6 +112,15 @@ void ImageArithmGenericFilter<args_info_type>::UpdateWithInputImageType()
   typename ImageType::Pointer input2 = NULL;
   IteratorType it2;
 
+  // Special case for normalisation
+  if (mTypeOfOperation == 12) {
+    typedef itk::MinimumMaximumImageCalculator<ImageType> MinMaxFilterType;
+    typename MinMaxFilterType::Pointer ff = MinMaxFilterType::New();
+    ff->SetImage(input1);
+    ff->ComputeMaximum();
+    mScalar = ff->GetMaximum();
+    mTypeOfOperation = 11; // divide
+  }
 
   if (mIsOperationUseASecondImage) {
       // Read input2
@@ -117,9 +128,12 @@ void ImageArithmGenericFilter<args_info_type>::UpdateWithInputImageType()
       // Set input image iterator
       it2 = IteratorType(input2, input2->GetLargestPossibleRegion());
       // Check dimension
-      if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(input1, input2)) {
-          std::cerr << "* ERROR * the images (input and input2) must have the same size & spacing";
-          return;
+      if (!clitk::HaveSameSize<ImageType, ImageType>(input1, input2)) {
+        itkExceptionMacro(<< "The images (input and input2) must have the same size");
+      }
+      if(!clitk::HaveSameSpacing<ImageType, ImageType>(input1, input2)) {
+        itkWarningMacro(<< "The images (input and input2) do not have the same spacing. "
+                        << "Using first input's information.");
       }
   }
 
@@ -370,6 +384,13 @@ void clitk::ImageArithmGenericFilter<args_info_type>::ComputeImage(Iter1 it, Ite
       ++ito;
     }
     break;
+  case 11: // divide
+    while (!it.IsAtEnd()) {
+      ito.Set(PixelTypeDownCast<double, PixelType>((double)it.Get() / mScalar) );
+      ++it;
+      ++ito;
+    }
+    break;
   default: // error ?
     std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
     exit(-1);
index 7b14021ab28d9b13abd6159c17715172b9ecb33a..297b63711f6c107f389ea487b9049221582a4b44 100644 (file)
@@ -56,6 +56,7 @@ int main(int argc, char * argv[])
   filter->SetInputFilenames(l);
   filter->SetIOVerbose(args_info.verbose_flag);
   filter->SetOutputFilename(args_info.output_arg);
+  filter->EnableWriteCompression(args_info.compression_flag);
   if (args_info.type_given) filter->SetOutputPixelType(args_info.type_arg);
 
   // Go !
index 22e32916e4f76736b312cea8f00461c62cb2ae7f..395b43542655cbaf7bd5535bd9e4811750d77e46 100644 (file)
@@ -8,3 +8,4 @@ option "input"          i  "Input image filename"                       string  no multiple
 option "output"        o  "Output image filename"                      string  yes
 option "type"          t  "Output type (float, ushort ...)"            string  no
 option "verbose"       v  "Verbose"                                    flag    off
+option "compression"    c  "Compress output"                                   flag    off
index b4ef60340ce2c2752999c28b2d2390de9df26874..3d59bf57882f0f502a0d05fe3a065c12d789fe29 100644 (file)
@@ -137,7 +137,7 @@ int main(int argc, char * argv[])
       DD(direction);
       
       std::vector<double> val(dim[b]);
-       for (int i=0; i<dim[b]; i++)
+       for (size_t i=0; i<dim[b]; i++)
          val[i]=0;
        
       int k;
index a3207984487684a769fcab7696af7ee5e7885b1d..012524c8fc266d817b9cda408cde4259def6d5d9 100644 (file)
 
 //itk include
 #include "itkLightObject.h"
-#include "itkInverseDeformationFieldImageFilter.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkInverseDisplacementFieldImageFilter.h"
+#else
+  #include "itkInverseDeformationFieldImageFilter.h"
+#endif
 
 namespace clitk 
 {
index b9641fad1f376cf85d7b046f36f95e01958b734b..9835c2e739f64d3edd1af378e7955efc43059ba7 100644 (file)
@@ -148,7 +148,11 @@ InvertVFGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
 
   case 1: {
     // Create the InverseDeformationFieldFilter
+#if ITK_VERSION_MAJOR >= 4
+    typedef itk::InverseDisplacementFieldImageFilter<InputImageType,OutputImageType> FilterType;
+#else
     typedef itk::InverseDeformationFieldImageFilter<InputImageType,OutputImageType> FilterType;
+#endif
     typename FilterType::Pointer filter =FilterType::New();
     filter->SetInput(input);
     filter->SetOutputOrigin(input->GetOrigin());
diff --git a/tools/clitkJacobianImage.cxx b/tools/clitkJacobianImage.cxx
new file mode 100644 (file)
index 0000000..af36184
--- /dev/null
@@ -0,0 +1,16 @@
+#include "clitkJacobianImage_ggo.h"
+#include "clitkJacobianImageGenericFilter.h"
+
+int main(int argc, char** argv) {
+  // Init command line
+  GGO(clitkJacobianImage, args_info);
+
+  // Filter
+  typedef clitk::JacobianImageGenericFilter<args_info_clitkJacobianImage> FilterType;
+  FilterType::Pointer genericFilter = FilterType::New();
+
+  genericFilter->SetArgsInfo(args_info);
+  genericFilter->Update();
+
+  return EXIT_SUCCESS;
+}
\ No newline at end of file
diff --git a/tools/clitkJacobianImage.ggo b/tools/clitkJacobianImage.ggo
new file mode 100644 (file)
index 0000000..26a71ff
--- /dev/null
@@ -0,0 +1,12 @@
+#File clitkJacobianImage.ggo
+#Author: Rômulo Pinho <pinho@lyon.fnclcc.fr>
+#Date : Tue 21 June 16.10 
+
+package "clitk"
+version "Read a DVF and calculate the corresponding jacobian image."
+
+option "config"       - "Config file"               string    no
+option "verbose"      v     "Verbose"               flag    off
+
+option "input"        i     "Input VF filename"             string    yes
+option "output"       o     "Output VF filename"              string    yes
similarity index 90%
rename from vv/vvMainWindow.txx
rename to tools/clitkJacobianImageGenericFilter.cxx
index 7cdb61355cb66b275acb34200f98041a4fa396fa..b5f7cd41543d783d6e33f8fef06ba6fc5cf916d4 100644 (file)
 
   - BSD        See included LICENSE.txt file
   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-// }
+===========================================================================*/
+#include "clitkJacobianImageGenericFilter.h"
+
+namespace clitk
+{
+
+}
\ No newline at end of file
diff --git a/tools/clitkJacobianImageGenericFilter.h b/tools/clitkJacobianImageGenericFilter.h
new file mode 100644 (file)
index 0000000..73e9b64
--- /dev/null
@@ -0,0 +1,119 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef clitkJacobianImageGenericFilter_h
+#define clitkJacobianImageGenericFilter_h
+
+/* =================================================
+ * @file   clitkJacobianImageGenericFilter.h
+ * @author 
+ * @date   
+ * 
+ * @brief 
+ * 
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkJacobianImage_ggo.h"
+
+//itk include
+#include "itkLightObject.h"
+#if ITK_VERSION_MAJOR >= 4
+  #include "itkInverseDisplacementFieldImageFilter.h"
+#else
+  #include "itkInverseDeformationFieldImageFilter.h"
+#endif
+
+namespace clitk 
+{
+
+  template<class args_info_type>
+  class ITK_EXPORT JacobianImageGenericFilter : public itk::LightObject
+  {
+  public:
+    //----------------------------------------
+    // ITK
+    //----------------------------------------
+    typedef JacobianImageGenericFilter                   Self;
+    typedef itk::LightObject                   Superclass;
+    typedef itk::SmartPointer<Self>            Pointer;
+    typedef itk::SmartPointer<const Self>      ConstPointer;
+   
+    // Method for creation through the object factory
+    itkNewMacro(Self);  
+
+    // Run-time type information (and related methods)
+    itkTypeMacro( JacobianImageGenericFilter, LightObject );
+
+
+    //----------------------------------------
+    // Typedefs
+    //----------------------------------------
+
+
+    //----------------------------------------
+    // Set & Get
+    //----------------------------------------    
+    void SetArgsInfo(const args_info_type & a)
+    {
+      m_ArgsInfo=a;
+      m_Verbose=m_ArgsInfo.verbose_flag;
+      m_InputFileName=m_ArgsInfo.input_arg;
+    }
+    
+    
+    //----------------------------------------  
+    // Update
+    //----------------------------------------  
+    void Update();
+
+  protected:
+
+    //----------------------------------------  
+    // Constructor & Destructor
+    //----------------------------------------  
+    JacobianImageGenericFilter();
+    ~JacobianImageGenericFilter() {};
+
+    
+    //----------------------------------------  
+    // Templated members
+    //----------------------------------------  
+    template <unsigned int Dimension>  void UpdateWithDim(std::string PixelType);
+    template <unsigned int Dimension, class PixelType>  void UpdateWithDimAndPixelType();
+
+
+    //----------------------------------------  
+    // Data members
+    //----------------------------------------
+    args_info_type m_ArgsInfo;
+    bool m_Verbose;
+    std::string m_InputFileName;
+
+  };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkJacobianImageGenericFilter.txx"
+#endif
+
+#endif // #define clitkJacobianImageGenericFilter_h
diff --git a/tools/clitkJacobianImageGenericFilter.txx b/tools/clitkJacobianImageGenericFilter.txx
new file mode 100644 (file)
index 0000000..2189411
--- /dev/null
@@ -0,0 +1,155 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef clitkJacobianImageGenericFilter_txx
+#define clitkJacobianImageGenericFilter_txx
+
+/* =================================================
+ * @file   clitkJacobianImageGenericFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkImageCommon.h"
+#include "itkDeformationFieldJacobianDeterminantFilter.h"
+#include "itkImage.h"
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+#include "itkVector.h"
+#include "itkNormalizeImageFilter.h"
+
+namespace clitk
+{
+
+//-----------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------
+template<class args_info_type>
+JacobianImageGenericFilter<args_info_type>::JacobianImageGenericFilter()
+{
+  m_Verbose=false;
+  m_InputFileName="";
+}
+
+
+//-----------------------------------------------------------
+// Update
+//-----------------------------------------------------------
+template<class args_info_type>
+void JacobianImageGenericFilter<args_info_type>::Update()
+{
+  // Read the Dimension and PixelType
+  int Dimension;
+  std::string PixelType;
+  ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+  // Call UpdateWithDim
+  if(Dimension==2) UpdateWithDim<2>(PixelType);
+  else if(Dimension==3) UpdateWithDim<3>(PixelType);
+  // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+  else {
+    std::cout<<"Error, Only for 2 or 3  Dimensions!!!"<<std::endl ;
+    return;
+  }
+}
+
+//-------------------------------------------------------------------
+// Update with the number of dimensions
+//-------------------------------------------------------------------
+template<class args_info_type>
+template<unsigned int Dimension>
+void
+JacobianImageGenericFilter<args_info_type>::UpdateWithDim(std::string PixelType)
+{
+  if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+  //    if(PixelType == "short"){
+  //       if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+  //       UpdateWithDimAndPixelType<Dimension, signed short>();
+  //     }
+  //    else if(PixelType == "unsigned_short"){
+  //       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+  //       UpdateWithDimAndPixelType<Dimension, unsigned short>();
+  //     }
+
+  //     else if (PixelType == "unsigned_char"){
+  //       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+  //       UpdateWithDimAndPixelType<Dimension, unsigned char>();
+  //     }
+
+  //     else if (PixelType == "char"){
+  //       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+  //       UpdateWithDimAndPixelType<Dimension, signed char>();
+  //     }
+  //  else {
+  if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+  UpdateWithDimAndPixelType<Dimension, itk::Vector<float, Dimension> >();
+  // }
+}
+
+
+//-------------------------------------------------------------------
+// Update with the number of dimensions and the pixeltype
+//-------------------------------------------------------------------
+template<class args_info_type>
+template <unsigned int Dimension, class  PixelType>
+void
+JacobianImageGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
+{
+  std::string vfield_file = m_ArgsInfo.input_arg;
+  
+  const unsigned int dim = Dimension;
+  typedef itk::Vector<double, dim> VectorType;
+  typedef itk::Image<VectorType, dim> VectorFieldType;
+  typedef itk::ImageFileReader<VectorFieldType> VectorFieldReaderType;
+  
+  typename VectorFieldReaderType::Pointer vfield_reader = VectorFieldReaderType::New();
+  vfield_reader->SetFileName(vfield_file.c_str());
+  
+  typedef double OutputPixelType;
+  typedef itk::Image<OutputPixelType, dim> ImageType;
+  //typedef itk::DeformationFieldJacobianDeterminantFilter<VectorFieldType, PixelType, ImageType> JacobianFilterType;
+  typedef itk::DisplacementFieldJacobianDeterminantFilter<VectorFieldType, OutputPixelType, ImageType> JacobianFilterType;
+
+  typename VectorFieldType::Pointer vfield = vfield_reader->GetOutput();
+  typename JacobianFilterType::Pointer jac = JacobianFilterType::New();
+  jac->SetInput(vfield);
+  jac->Update();
+  
+  typedef itk::NormalizeImageFilter<ImageType, ImageType> NormalizeFilterType;
+  typename NormalizeFilterType::Pointer normalize = NormalizeFilterType::New();
+  normalize->SetInput(jac->GetOutput());
+  normalize->Update();
+
+  typedef itk::ImageFileWriter<ImageType> ImageFileWriterType;
+  typename ImageFileWriterType::Pointer image_writer = ImageFileWriterType::New();
+  
+  std::string image_file = m_ArgsInfo.output_arg;
+  image_writer->SetFileName(image_file.c_str());
+  image_writer->SetInput(jac->GetOutput());
+  image_writer->Update();
+  
+}
+
+
+}//end clitk
+
+#endif //#define clitkJacobianImageGenericFilter_txx
diff --git a/tools/clitkMakeSphereImage.cxx b/tools/clitkMakeSphereImage.cxx
new file mode 100644 (file)
index 0000000..7f29dfe
--- /dev/null
@@ -0,0 +1,63 @@
+#include "itkImage.h"
+#include "itkSphereSpatialFunction.h"
+#include <itkImageRegionIterator.h>
+#include "itkImageFileWriter.h"
+
+int main(int argc, char** argv) {
+  
+  const unsigned int dim = 3;
+  typedef char PixelType;
+  typedef itk::Image<PixelType, dim> ImageType;
+  typedef ImageType::IndexType IndexType;
+  typedef ImageType::PointType PointType;
+  typedef ImageType::SizeType SizeType;
+  typedef ImageType::RegionType RegionType;
+
+  IndexType index;
+  index.Fill(0);
+
+  SizeType size;
+  size[0] = atoi(argv[2]);
+  size[1] = atoi(argv[3]);
+  size[2] = atoi(argv[4]);
+  
+  PointType origin;
+  origin[0] = atoi(argv[5]);
+  origin[1] = atoi(argv[6]);
+  origin[2] = atoi(argv[7]);
+  
+  RegionType region;
+  region.SetIndex(index);
+  region.SetSize(size);
+
+  ImageType::Pointer image = ImageType::New();
+  image->SetRegions(region);
+  image->Allocate();
+  
+  typedef itk::SphereSpatialFunction<dim, PointType> ShpereFunctionType;
+  ShpereFunctionType::Pointer sphere = ShpereFunctionType::New();
+  
+  double radius = atof(argv[8])/2;
+  sphere->SetCenter(origin);
+  sphere->SetRadius(radius);
+  
+  PixelType max = itk::NumericTraits<PixelType>::max();
+  typedef itk::ImageRegionIterator<ImageType> ImageIteratorType;
+  ImageIteratorType it(image, region);
+  PointType point;
+  for (it.GoToBegin(); !it.IsAtEnd(); ++it) {
+    image->TransformIndexToPhysicalPoint(it.GetIndex(), point);
+    if (sphere->Evaluate(point)) {
+      PixelType value = static_cast<PixelType>(max*(point - origin).GetNorm()/radius); 
+      it.Set(value);
+    }
+    else
+      it.Set(0);
+  }
+  
+  typedef itk::ImageFileWriter<ImageType> ImageWriterType;
+  ImageWriterType::Pointer writer = ImageWriterType::New();
+  writer->SetInput(image);
+  writer->SetFileName(argv[1]);
+  writer->Update();
+}
\ No newline at end of file
index 253b49315a0e546850f8bd6b679f7029fed259b7..f23e2771ff5fe2d4821f63aafee59b6c747dcc01 100644 (file)
@@ -184,22 +184,23 @@ namespace clitk
 
       // Take the median
       double value;
+      typename InputImageType::IndexValueType temporal_dimension = size4D[Dimension-1];
+      std::vector<PixelType> temp(temporal_dimension);
       while (!(iterators[0]).IsAtEnd()) {
         value=0.;
-        std::vector<PixelType> temp;
-        for (unsigned int i=0; i<size4D[Dimension-1]; i++) {
-          temp.push_back(iterators[i].Get());
+        for (unsigned int i=0; i<temporal_dimension; i++) {
+          temp[i] = iterators[i].Get();
           ++(iterators[i]);
         }
-        if (temp.size() % 2) {
-          nth_element(temp.begin(),temp.begin()+((temp.size()-1)/2+1),temp.end());
-          value=temp[(temp.size()-1)/2];
+        if (temporal_dimension & 1) {
+          nth_element(temp.begin(), temp.begin() + temporal_dimension/2,temp.end());
+          value = temp[temporal_dimension/2];
         } else {
-          nth_element(temp.begin(),temp.begin()+(temp.size())/2,temp.end());
-          value=temp[temp.size()/2];
-          nth_element(temp.begin(),temp.begin()+ (temp.size()/2+1),temp.end());
-          value+=temp[temp.size()/2+1];
-          value/=2;
+          nth_element(temp.begin(), temp.begin() + temporal_dimension/2 - 1, temp.end());
+          value = temp[temporal_dimension/2 - 1];
+          nth_element(temp.begin(), temp.begin() + temporal_dimension/2, temp.end());
+          value += temp[temporal_dimension/2];
+          value /= 2;
         }
         avIt.Set(value);
         ++avIt;
diff --git a/tools/clitkMeshViewer.cxx b/tools/clitkMeshViewer.cxx
new file mode 100644 (file)
index 0000000..c21bc4e
--- /dev/null
@@ -0,0 +1,318 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================*/
+
+#include "vtkOBJReader.h"
+#include "vtkPolyDataMapper.h"
+#include "vtkRenderer.h"
+#include "vtkRenderWindow.h"
+#include "vtkActor.h"
+#include "vtkCamera.h"
+#include "vtkRenderWindowInteractor.h"
+#include "vtkSmartPointer.h"
+#include "vtkCommand.h"
+#include "vtkAnimationCue.h"
+#include "vtkAnimationScene.h"
+#include "vtkProperty.h"
+#include "vtkInteractorStyle.h"
+
+#include "clitkCommon.h"
+#include "clitkMeshViewer_ggo.h"
+
+#include <string>
+#include <iostream>
+#include <vector>
+
+typedef vtkSmartPointer<vtkOBJReader> ObjReaderType;
+typedef vtkSmartPointer<vtkPolyDataMapper> MapperType;
+typedef vtkSmartPointer<vtkActor> ActorType;
+
+
+long run(const args_info_clitkMeshViewer& argsInfo);
+
+// Adapted from vtkAnimationCue example...
+class CueAnimator
+{
+public:
+  CueAnimator(std::vector<ActorType>& rActors) : m_Fps(1), m_CurrentActor(0), m_rActors(rActors) {
+    m_rActors[0]->SetVisibility(1);
+    for (unsigned int i = 1; i < m_rActors.size(); i++) {
+      m_rActors[i]->SetVisibility(0);
+    }
+  }
+  
+  ~CueAnimator() {
+   }
+  
+  void SetFps(double fps) {
+    m_Fps = fps;
+  }
+  
+  void StartCue(vtkAnimationCue::AnimationCueInfo *vtkNotUsed(info),
+                vtkRenderer *ren)
+    {
+      //std::cout << "StartCue" << std::endl;
+    }
+  
+  void Tick(vtkAnimationCue::AnimationCueInfo *info,
+            vtkRenderer *ren)
+    {
+      //std::cout << "Tick AT:" << info->AnimationTime << " DT:" << info->DeltaTime << " CT:" << info->ClockTime << std::endl;
+      
+      m_rActors[m_CurrentActor]->SetVisibility(0);
+      
+      int step = lrint(m_Fps * info->AnimationTime);
+      int actor = step % m_rActors.size();
+      
+      //if (actor != m_CurrentActor) std::cout << "Showing frame: " << m_CurrentActor << std::endl;
+      m_CurrentActor = actor;
+      m_rActors[m_CurrentActor]->SetVisibility(1);
+      
+      ren->Render();
+    }
+  
+  void EndCue(vtkAnimationCue::AnimationCueInfo *info,
+              vtkRenderer *ren)
+    {
+      //std::cout << "EndCue" << std::endl;
+    }
+  
+protected:
+  
+  double m_Fps;
+  clock_t m_LastTick;
+  double m_TotalTicks;
+  int m_CurrentActor;
+  std::vector<ActorType>& m_rActors;
+};
+
+class vtkAnimationCueObserver : public vtkCommand
+{
+public:
+  static vtkAnimationCueObserver *New()
+    {
+      return new vtkAnimationCueObserver;
+    }
+  
+  virtual void Execute(vtkObject *vtkNotUsed(caller),
+                       unsigned long event,
+                       void *calldata)
+    {
+      if(this->Animator!=0 && this->Renderer!=0)
+        {
+        vtkAnimationCue::AnimationCueInfo *info=
+          static_cast<vtkAnimationCue::AnimationCueInfo *>(calldata);
+        switch(event)
+          {
+          case vtkCommand::StartAnimationCueEvent:
+            this->Animator->StartCue(info,this->Renderer);
+            break;
+          case vtkCommand::EndAnimationCueEvent:
+            this->Animator->EndCue(info,this->Renderer);
+            break;
+          case vtkCommand::AnimationCueTickEvent:
+            this->Animator->Tick(info,this->Renderer);
+            break;
+          }
+        }
+      if(this->RenWin!=0)
+        {
+        this->RenWin->Render();
+        }
+    }
+  
+  vtkRenderer *Renderer;
+  vtkRenderWindow *RenWin;
+  CueAnimator *Animator;
+  
+protected:
+  vtkAnimationCueObserver()
+    {
+      this->Renderer=0;
+      this->Animator=0;
+      this->RenWin=0;
+    }
+};
+
+class vtkWindowObserver : public vtkCommand
+{
+public:
+  static vtkWindowObserver *New()
+    {
+      return new vtkWindowObserver;
+    }
+
+  virtual void Execute(vtkObject *caller,
+                       unsigned long event,
+                       void *calldata)
+    {
+      vtkRenderWindowInteractor *isi = dynamic_cast<vtkRenderWindowInteractor *>(caller);
+      //std::cout << "Execute" << std::endl;
+      switch (event)
+      {
+        case vtkCommand::KeyPressEvent:
+        {
+          std::string key = isi->GetKeySym();
+          //std::cout << key[0] << std::endl;
+          switch (key[0])
+          {
+            case 'P':
+            case 'p':
+              if (this->m_Scene)
+                this->m_Scene->Play();
+              break;
+          
+            case 'M':
+            case 'm':
+              if (this->m_Scene)
+                this->m_Scene->Stop();
+              break;
+          
+            default:
+              break;
+          }
+        }
+          
+        default:
+          break;
+          
+      }
+      
+    }
+    
+    vtkAnimationScene* m_Scene;
+    
+  protected:
+    
+    vtkWindowObserver() : m_Scene(0) {}
+};
+
+int main(int argc, char** argv)
+{
+  GGO(clitkMeshViewer, args_info);
+
+  return run(args_info);
+}
+
+long run(const args_info_clitkMeshViewer& argsInfo)
+{
+  std::vector<ObjReaderType> objs;
+  std::vector<MapperType> mappers;
+  std::vector<ActorType> actors;
+  
+  bool verbose = argsInfo.verbose_flag;
+
+  int nfiles = argsInfo.inputs_num;
+  if (nfiles == 0)
+  {
+    std::cout << "At leas one mesh (.OBJ) file must be given. See clitkMeshViewer -h." << std::endl;
+    return -1;
+  }
+  
+  if (verbose) 
+    std::cout << nfiles << " file(s) to be loaded..." << std::endl;
+  
+  vtkSmartPointer<vtkRenderer> aRenderer = vtkRenderer::New();
+  for (int i = 0; i < nfiles; i++) {    
+    std::string file = argsInfo.inputs[i];
+    if (verbose)
+      std::cout << "Reading " << file << std::endl;
+    
+    vtkSmartPointer<vtkOBJReader> preader = vtkOBJReader::New();
+    preader->SetFileName(file.c_str());
+    preader->Update();
+    objs.push_back(preader);
+    
+    vtkSmartPointer<vtkPolyDataMapper> skinMapper = vtkPolyDataMapper::New();
+    skinMapper->SetInputConnection(preader->GetOutputPort());
+    skinMapper->ScalarVisibilityOff();
+    mappers.push_back(skinMapper);
+
+    vtkSmartPointer<vtkActor> skin = vtkActor::New();
+    skin->SetMapper(skinMapper);
+    actors.push_back(skin);
+
+    aRenderer->AddActor(skin);
+  }
+
+  vtkSmartPointer<vtkCamera> aCamera = vtkCamera::New();
+  aCamera->SetViewUp (0, 0, -1);
+  aCamera->SetPosition (0, 1, 0);
+  aCamera->SetFocalPoint (0, 0, 0);
+  aCamera->ComputeViewPlaneNormal();
+  aCamera->Dolly(1.5);
+
+  aRenderer->SetActiveCamera(aCamera);
+  aRenderer->ResetCamera ();
+  aRenderer->SetBackground(0,0,0);
+  aRenderer->ResetCameraClippingRange ();
+
+  vtkSmartPointer<vtkRenderWindow> renWin = vtkRenderWindow::New();
+  renWin->AddRenderer(aRenderer);
+  renWin->SetSize(640, 480);
+  
+  vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkRenderWindowInteractor::New();
+  iren->SetRenderWindow(renWin);
+  iren->Initialize();
+  
+  vtkSmartPointer<vtkAnimationScene> scene;
+  vtkSmartPointer<vtkAnimationCue> cue1;
+  vtkSmartPointer<vtkAnimationCueObserver> anim_observer;
+  vtkSmartPointer<vtkWindowObserver> window_observer;
+  CueAnimator animator(actors);
+  
+  bool animate = argsInfo.animate_flag;
+  if (animate) {
+    double fps = argsInfo.fps_arg;
+    animator.SetFps(fps);
+
+    // Create an Animation Scene
+    scene=vtkAnimationScene::New();
+    scene->SetModeToRealTime();
+
+    scene->SetLoop(1);
+    scene->SetTimeModeToRelative();
+    scene->SetStartTime(0);
+    scene->SetEndTime(actors.size()/fps);
+    
+    // Create an Animation Cue.
+    cue1=vtkAnimationCue::New();
+    cue1->SetTimeModeToRelative();
+    cue1->SetStartTime(0);
+    cue1->SetEndTime(actors.size()/fps);
+    scene->AddCue(cue1);
+    
+    // Create Cue anim_observer.
+    anim_observer=vtkAnimationCueObserver::New();
+    anim_observer->Renderer=aRenderer;
+    anim_observer->Animator=&animator;
+    anim_observer->RenWin=renWin;
+    cue1->AddObserver(vtkCommand::StartAnimationCueEvent,anim_observer);
+    cue1->AddObserver(vtkCommand::EndAnimationCueEvent,anim_observer);
+    cue1->AddObserver(vtkCommand::AnimationCueTickEvent,anim_observer);
+
+    window_observer = vtkWindowObserver::New();
+    window_observer->m_Scene = scene;
+    iren->AddObserver(vtkCommand::KeyPressEvent, window_observer);
+    
+  }
+
+  iren->Start(); 
+  return 0;
+}
+
+
diff --git a/tools/clitkMeshViewer.ggo b/tools/clitkMeshViewer.ggo
new file mode 100644 (file)
index 0000000..b990d7a
--- /dev/null
@@ -0,0 +1,11 @@
+#File clitkMeshViewer.ggo
+package "clitkMeshViewer"
+version "1.0"
+purpose "Visualize a set of meshes"
+usage "clitkMeshViewer FILE1 FILE2 ... [OPTIONS]"
+
+option "config"   - "Config file"   string  no
+option "verbose"  v     "Verbose"   flag  off
+
+option "animate"    - "Enable animation mode (type p/m to start/stop animation)"  flag  off
+option "fps"    - "Set the animation's frame rate (in fps)"    double  default="4.0"   no
diff --git a/tools/clitkPadImage.cxx b/tools/clitkPadImage.cxx
new file mode 100644 (file)
index 0000000..ad93eaa
--- /dev/null
@@ -0,0 +1,116 @@
+#include "itkImage.h"
+#include "itkImageFileReader.h"
+#include "itkImageFileWriter.h"
+#include "itkConstantPadImageFilter.h"
+#include "clitkCommon.h"
+#include "clitkPadImage_ggo.h"
+#include <string>
+#include "itkMath.h"
+
+enum
+{
+  ERR_SUCCESS = 0,
+  ERR_NOT_SAME_SPACING = -1,
+  ERR_NOT_LIKE_LARGER = -2
+};
+
+typedef unsigned int DimType;
+
+template <class ImageType, class PadBoundType, DimType dim>
+int pad_like(typename ImageType::Pointer input, const std::string& likeFile, PadBoundType* padLower, PadBoundType* padUpper)
+{
+  typedef typename ImageType::SpacingType SpacingType;
+  typedef typename ImageType::RegionType RegionType;
+  typedef typename ImageType::SizeType SizeType;
+  typedef typename ImageType::IndexType IndexType;
+  typedef typename ImageType::PointType PointType;
+  typedef typename ImageType::PointValueType PointValueType;
+
+  typedef itk::ImageFileReader<ImageType> ImageReaderType;
+  typename ImageReaderType::Pointer reader = ImageReaderType::New();
+  reader->SetFileName(likeFile);
+  reader->Update();
+  
+  typename ImageType::Pointer like_image = reader->GetOutput();
+
+  SpacingType spacing = input->GetSpacing(), like_spacing = like_image->GetSpacing(); 
+  if (spacing != like_spacing) {
+    std::cerr << "Like-image must have same spacing as input: " << spacing << " " << like_spacing << std::endl;
+    return ERR_NOT_SAME_SPACING;
+  }
+  
+  SizeType size = input->GetLargestPossibleRegion().GetSize(), like_size = like_image->GetLargestPossibleRegion().GetSize();
+  PointType origin = input->GetOrigin(), like_origin = like_image->GetOrigin();
+  
+  PointType lower_bound, like_lower_bound;
+  PointType upper_bound, like_upper_bound;
+  PointValueType auxl = 0, auxu = 0;
+  for (DimType i = 0; i < dim; i++) {
+    lower_bound[i] = origin[i];
+    like_lower_bound[i] = like_origin[i];
+    auxl = itk::Math::Round<PointValueType>(((lower_bound[i] - like_lower_bound[i])/spacing[i]));
+    
+    upper_bound[i] = (lower_bound[i] + size[i]*spacing[i]);
+    like_upper_bound[i] = (like_lower_bound[i] + like_size[i]*spacing[i]);
+    auxu = itk::Math::Round<PointValueType>(((like_upper_bound[i] - upper_bound[i])/spacing[i]));
+
+    if (auxl < 0 || auxu < 0) {
+      std::cerr << "Like-image's bounding box must be larger than input's" << std::endl;
+      return ERR_NOT_LIKE_LARGER;
+    }
+
+    padLower[i] = (PadBoundType)auxl;
+    padUpper[i] = (PadBoundType)auxu;
+  }
+  
+  return ERR_SUCCESS;
+}
+
+int main(int argc, char** argv)
+{
+  const DimType dim = 3;
+  typedef short PixelType;
+  typedef itk::Image<PixelType, dim> ImageType;
+  typedef itk::ImageFileReader<ImageType> ImageReaderType;
+  typedef itk::ImageFileWriter<ImageType> ImageWriterType;
+  typedef itk::ConstantPadImageFilter<ImageType, ImageType> PadFilterType;
+  typedef PadFilterType::SizeValueType PadBoundType;
+  
+  GGO(clitkPadImage, args_info);
+  
+  ImageReaderType::Pointer reader = ImageReaderType::New();
+  reader->SetFileName(args_info.input_arg);
+  reader->Update();
+  
+  PadBoundType pad_lower[dim], pad_upper[dim];
+  ImageType::Pointer input = reader->GetOutput();
+  if (args_info.like_given) {
+    int err = pad_like<ImageType, PadBoundType, dim>(input, args_info.like_arg, pad_lower, pad_upper);
+    if (err) {
+      std::cerr << "Error processing like image." << std::endl;
+      return err;
+    }
+  }
+  else {
+    for (DimType i = 0; i < dim; i++) {
+      pad_lower[i] = args_info.lower_arg[i];
+      pad_upper[i] = args_info.upper_arg[i];
+    }
+  }
+  
+  PadFilterType::Pointer filter = PadFilterType::New();
+  filter->SetPadLowerBound(pad_lower);
+  filter->SetPadUpperBound(pad_upper);
+  filter->SetInput(input);
+  filter->SetConstant(args_info.value_arg);
+  filter->Update();
+  
+  ImageType::Pointer output = filter->GetOutput();
+  ImageWriterType::Pointer writer = ImageWriterType::New();
+  writer->SetInput(output);
+  writer->SetFileName(args_info.output_arg);
+  writer->Update();
+  
+  return ERR_SUCCESS;
+}
+
diff --git a/tools/clitkPadImage.ggo b/tools/clitkPadImage.ggo
new file mode 100644 (file)
index 0000000..6f21563
--- /dev/null
@@ -0,0 +1,26 @@
+#File clitkCropImage.ggo
+package "clitkCropImage"
+version "1.0"
+purpose "Pad an image according to a given extends or like another image"
+
+option "config"                   -  "Config file"                 string  no
+option "verbose"           v  "Verbose"                            flag    off
+
+section "I/O"
+
+option "input"         i       "Input image filename"            string        yes
+option "output"        o       "Output image filename"           string        yes
+
+section "Used determined padding"
+option "lower"         l       "Size of the lower crop region (multiple values)"         int   no  multiple
+option "upper"         u       "Size of the upper crop region (multiple values)"         int   no  multiple
+
+section "Pad like another image"
+option "like"          -       "Pad like this image (must have the same spacing and bounding box must be larger)"   string no
+
+section "Extra parameters"
+option "value"    - "Value to be set in padded area" float default="0" no  
+
+
+
+
index 6585d892d7a7dcd94520af0d1a8c834c04d5ac5e..5a5e246e8c6eb81d11bf3d872c1cf3ba64ff94cb 100644 (file)
@@ -63,6 +63,9 @@ void clitk::SplitImageGenericFilter::UpdateWithInputImageType()
   size[mSplitDimension]=0;
   typename ImageType::RegionType extracted_region;
   extracted_region.SetSize(size);
+#if ITK_VERSION_MAJOR >= 4
+  filter->SetDirectionCollapseToSubmatrix();
+#endif
   filter->SetExtractionRegion(extracted_region);
   filter->Update();
 
index ea84d18674c8712845468accfffb6707d6a28913..86745a419363ad9d97194b0e9ccdf921c39ee39e 100644 (file)
@@ -36,6 +36,7 @@ void write_points_txt(const std::string& fileName, const PointArrayType& points,
 void read_points_pts(const std::string& fileName, PointArrayType& points);
 void write_points_pts(const std::string& fileName, const PointArrayType& points);
 
+void apply_spacing(const PointArrayType& input, const double* spacing, PointArrayType& output);
 void transform_points(const PointArrayType& input, const MatrixType& matrix, PointArrayType& output);
 
 
@@ -46,8 +47,6 @@ int main(int argc, char** argv)
   GGO(clitkTransformLandmarks, args_info);
   verbose = args_info.verbose_flag;
 
-  MatrixType matrix = clitk::ReadMatrix3D(args_info.matrix_arg);
-
   TxtDataArrayType data;
   PointArrayType inputPoints;
   if (strcmp(args_info.type_arg, "txt") == 0) {
@@ -58,13 +57,29 @@ int main(int argc, char** argv)
   }
   
   PointArrayType outputPoints;
-  transform_points(inputPoints, matrix, outputPoints);
+  PointArrayType spacingPoints;
+  PointArrayType* workingInputPoints = &inputPoints;
+  PointArrayType* workingOutputPoints = &outputPoints;
+  if (args_info.spacing_given) {
+    if (verbose) std::cout << "Processing spacing..." << std::endl;
+    
+    apply_spacing(*workingInputPoints, args_info.spacing_arg, spacingPoints);
+    workingInputPoints = &spacingPoints;
+    workingOutputPoints = &spacingPoints;
+  }
+
+  MatrixType matrix;
+  if (args_info.matrix_given) {
+    matrix = clitk::ReadMatrix3D(args_info.matrix_arg);
+    transform_points(*workingInputPoints, matrix, outputPoints);
+    workingOutputPoints = &outputPoints;
+  }
 
   if (strcmp(args_info.type_arg, "txt") == 0) {
-    write_points_txt(args_info.output_arg, outputPoints, data);
+    write_points_txt(args_info.output_arg, *workingOutputPoints, data);
   }
   else {
-    write_points_pts(args_info.output_arg, outputPoints);
+    write_points_pts(args_info.output_arg, *workingOutputPoints);
   }
   
   return 0;
@@ -74,14 +89,14 @@ void read_points_txt(const std::string& fileName, PointArrayType& points, TxtDat
 {
   std::ifstream landmarksFile(fileName.c_str());
   if (landmarksFile.fail()) {
-    std::cout << "ERROR: could not open '" << fileName << "'" << std::endl;
+    std::cerr << "ERROR: could not open '" << fileName << "'" << std::endl;
     exit(-2);
   }
   
   std::string line;
   std::getline(landmarksFile, line);
   if (line.find("LANDMARKS") == std::string::npos) {
-    std::cout << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
+    std::cerr << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
     exit(-3);
   }
   
@@ -119,14 +134,14 @@ void read_points_pts(const std::string& fileName, PointArrayType& points)
 {
   std::ifstream landmarksFile(fileName.c_str());
   if (landmarksFile.fail()) {
-    std::cout << "ERROR: could not open '" << fileName << "'" << std::endl;
+    std::cerr << "ERROR: could not open '" << fileName << "'" << std::endl;
     exit(-2);
   }
   
   std::string line;
   std::getline(landmarksFile, line);
   if (line.find("#X") != 0) {
-    std::cout << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
+    std::cerr << "ERROR: invalid landmarks file '" << fileName << "'" << std::endl;
     exit(-3);
   }
   
@@ -156,6 +171,22 @@ void write_points_pts(const std::string& fileName, const PointArrayType& points)
     landmarksFile << points[i][0] << "\t" << points[i][1] << "\t" << points[i][2] << "\t" << std::endl;
 }
 
+void apply_spacing(const PointArrayType& input, const double* spacing, PointArrayType& output)
+{
+  PointType out;
+  out.Fill(1);
+  
+  for (size_t i = 0; i < input.size(); i++) {
+    out[0] = input[i][0] * spacing[0];
+    out[1] = input[i][1] * spacing[1];
+    out[2] = input[i][2] * spacing[2];
+    if (verbose){
+      std::cout << "output " << out << std::endl;
+    }
+    output.push_back(out);
+  }
+}
+
 void transform_points(const PointArrayType& input, const MatrixType& matrix, PointArrayType& output)
 {
   for (size_t i = 0; i < input.size(); i++) {
index 71186ef19eec14c84b3a8f35af5e5a55a1d4f6f4..c731c23086539cfdecd138621afd6b8a6c0606a9 100644 (file)
@@ -7,7 +7,8 @@ option "config"     - "Config file"       string    no
 option "verbose"    v     "Verbose"       flag    off
 
 option "input"    i "Input landmarks filename"      string    yes
-option "matrix"   m "Input 4x4 matrix filename ('.mat' file)"      string    yes
+option "matrix"   m "Input 4x4 matrix filename ('.mat' file)"      string    no
+option "spacing"   s "If given, applies the given spacing (x,y,z) to the input points."      double    no multiple  default="1"
 option "output"                o       "Output landmarks filename"                     string          yes
 option "type"          t       "Landmarks type ('pts' for Jef; 'txt' for VV)"          string          no              default="txt" 
 
index 2ecc5d5dc0eabf20fc3a23c9f99974e1099fbf95..8544df2ba33bf859c827513c4219ac8e6301a42b 100644 (file)
@@ -192,7 +192,11 @@ WarpImageGenericFilter::UpdateWithDimAndPixelType()
     //Backward mapping
     typedef itk::WarpImageFilter<InputImageType, InputImageType, DeformationFieldType> BackwardWarpFilterType;
     typename BackwardWarpFilterType::Pointer backwardWarpFilter= BackwardWarpFilterType::New();
+#if ITK_VERSION_MAJOR >= 4
+    backwardWarpFilter->SetDisplacementField( deformationField );
+#else
     backwardWarpFilter->SetDeformationField( deformationField );
+#endif
     backwardWarpFilter->SetEdgePaddingValue( static_cast<PixelType>(m_ArgsInfo.pad_arg) );
     backwardWarpFilter->SetOutputSpacing( deformationField->GetSpacing() );
     backwardWarpFilter->SetOutputOrigin( input->GetOrigin() );
diff --git a/vv/.gitignore b/vv/.gitignore
deleted file mode 100644 (file)
index e1993c8..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-build/*
-Louise
-tests_jef
-mctools
-*.swp
-Makefile
-tags
-doc
-CVS
-CMakeFiles
-CMakeCache.txt
-.vimrc
-*_ggo.*
-*.directory
index eca10624f70f6b0655a268f9dd774f46089fe28a..70c9ccd8a9a3590bf80bec970f59f9795888b6f3 100644 (file)
@@ -7,6 +7,7 @@ if(COMMAND cmake_policy)
 endif(COMMAND cmake_policy)
 #=========================================================
 
+
 #=========================================================
 #List of vv tools to compile
 SET(vv_TOOLS
@@ -18,6 +19,7 @@ SET(vv_TOOLS
   vvToolResample
 #   vvToolExtractPatient
 #  vvToolExtractLung
+  vvToolStructureSetManager
   vvToolMIP
   vvToolConvert ## with dummy vvToolConvert.ui
   
@@ -61,7 +63,7 @@ SET(vv_COMMON_WITH_UI
   vvToolWidgetBase  
   vvToolSimpleInputSelectorWidget
   vvToolInputSelectorWidget
-  vvToolStructureSetManager
+  vvRegisterForm
 )
 
 # All others sources
@@ -124,14 +126,23 @@ QT4_WRAP_UI(vv_UI_CXX
 
 QT4_ADD_RESOURCES(vv_SRCS vvIcons.qrc)
 
-#Add the autotools and the common files ui
+# Add the autotools in the header vvToolsList.h for initialization of the dummy
+# variables in vv.cxx for the tools contained in vvLib
+file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/vvToolsList.h)
+foreach(tool ${vv_TOOLS})
+    FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/vvToolsList.h "#include \"${tool}.h\"\n")
+    FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/vvToolsList.h "extern const vvToolCreator<${tool}> *dummy${tool};\n")
+    FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/vvToolsList.h "const vvToolCreator<${tool}> *dummy${tool}2 = dummy${tool};\n\n")
+endforeach(tool)
+
+# Add the autotools and the common files ui
 foreach(tool ${vv_TOOLS} ${vv_COMMON_WITH_UI})
     SET(vv_SRCS ${vv_SRCS} ${tool}.cxx)
     QT4_WRAP_CPP(vv_SRCS ${tool}.h)
     QT4_WRAP_UI(vv_UI_CXX qt_ui/${tool}.ui)
 endforeach(tool)
 
-#Add the common source files
+# Add the common source files
 foreach(tool ${vv_COMMON})
     SET(vv_SRCS ${vv_SRCS} ${tool}.cxx)
     QT4_WRAP_CPP(vv_SRCS ${tool}.h)
@@ -179,26 +190,34 @@ INCLUDE_DIRECTORIES(
   ../segmentation
   )
 
-IF(WIN32)
-  SET(EXE_ICON vvIcon.rc)
-ENDIF(WIN32)
-
 LINK_DIRECTORIES(${QT_LIBRARY_DIR})
-ADD_EXECUTABLE(vv ${vv_SRCS} vv.cxx ${vv_UI_CXX} ${EXE_ICON})
-ADD_DEPENDENCIES(vv clitkSegmentationGgoLib)
-TARGET_LINK_LIBRARIES(vv clitkDicomRTStruct)
-
 #=========================================================
 #Add each tool's dependencies
 foreach(tool ${vv_TOOLS})
-    target_link_libraries(vv ${${tool}_LIBS})
+  SET(toolLibs ${toolLibs} ${${tool}_LIBS})
 endforeach(tool)
-
 #=========================================================
 #Add Foundation Libraries (this should be after our libraries, since we depend
 #on them)
-TARGET_LINK_LIBRARIES(vv
-clitkCommon ${ITK_LIBRARIES} QVTK vtkHybrid)
+SET(foundationLibraries clitkCommon ${ITK_LIBRARIES} QVTK vtkHybrid)
+
+#=========================================================
+#Create binary and libs for tests
+SET(vvExternalLibs ${QT_QTNETWORK_LIBRARY} clitkSegmentationGgoLib clitkDicomRTStruct ${toolLibs} ${foundationLibraries})
+# QtNetwork is required by vvRegisterForm
+
+ADD_LIBRARY(vvLib ${vv_SRCS} ${vv_UI_CXX})
+TARGET_LINK_LIBRARIES(vvLib ${vvExternalLibs})
+
+IF(WIN32)
+  ADD_EXECUTABLE(vv WIN32 vv.cxx vvIcon.rc)
+ELSE(WIN32)
+  ADD_EXECUTABLE(vv vv.cxx)
+ENDIF(WIN32)
+
+#TARGET_LINK_LIBRARIES(vv vvLib)
+TARGET_LINK_LIBRARIES(vv vvLib)
+
 
 #=========================================================
 # Install options (also used by CPack)
@@ -232,9 +251,10 @@ SET(CPACK_PACKAGE_VENDOR "Creatis-CLB")
 SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/ReadMe.txt")
 SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
 SET(CPACK_PACKAGE_VERSION_MAJOR "1")
-SET(CPACK_PACKAGE_VERSION_MINOR "1")
-SET(CPACK_PACKAGE_VERSION_PATCH "0")
+SET(CPACK_PACKAGE_VERSION_MINOR "2")
+SET(CPACK_PACKAGE_VERSION_PATCH "2")
 SET(CPACK_PACKAGE_INSTALL_DIRECTORY "vv")
+SET(CPACK_STRIP_FILES TRUE)
 
 IF(WIN32)
   # There is a bug in NSI that does not handle full unix paths properly. Make
@@ -255,3 +275,6 @@ ELSE(WIN32)
 ENDIF(WIN32)
 INCLUDE(CPack)
 #=========================================================
+#=========================================================
+configure_file(vvConfiguration.h.in vvConfiguration.h)
+#=========================================================
index 8eabad242e50fdbafa9f5823cff6f31ee8f3babd..5beaac5a90b6fc4d79c9c01f79ded7fe5f21a730 100644 (file)
@@ -3,7 +3,7 @@
 
   Authors belong to:
   - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
 
   This software is distributed WITHOUT ANY WARRANTY; without even
@@ -25,7 +25,7 @@ copyright is shown below.
  
 Copyright (c) 2008 CLB / CREATIS-LRMN
 
-CLB = Léon Bérard cancer center http://www.centreleonberard.fr
+CLB = Léon Bérard cancer center http://www.centreleonberard.fr
 CREATIS-LMRN = Centre de Recherche et d'Applications en Traitement de l'Image http://www.creatis.insa-lyon.fr
 
 All rights reserved.
diff --git a/vv/icons/identity.png b/vv/icons/identity.png
new file mode 100644 (file)
index 0000000..dbce16d
Binary files /dev/null and b/vv/icons/identity.png differ
diff --git a/vv/icons/weNeedYou.png b/vv/icons/weNeedYou.png
new file mode 100644 (file)
index 0000000..a363a57
Binary files /dev/null and b/vv/icons/weNeedYou.png differ
index 303a665961753183f141624ae79af50d27d487bf..29623b35426578c50b7bfa2165c34e9f785990f7 100644 (file)
@@ -22,9 +22,9 @@
         <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
 &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
 p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;F1: &lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Help (this window)&lt;/span&gt;&lt;/p&gt;
-&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;&quot;&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Slice Selection&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt; font-weight:600;&quot;&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;F2:&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt; Sagital&lt;/span&gt;&lt;/p&gt;
@@ -38,6 +38,10 @@ p, li { white-space: pre-wrap; }
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;0,1,2,3,4,5&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt; : Windowing Preset Selection&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;6,7,8,9&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: Colormap Selection&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;w&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: Local &lt;/span&gt;&lt;span style=&quot; font-size:12pt; text-decoration: underline;&quot;&gt;w&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;indowing around mouse cursor&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Ctrl+w&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: Idem for fusion or overlay&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Miscellaneous&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;&quot;&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: Toggle &lt;/span&gt;&lt;span style=&quot; font-size:12pt; text-decoration: underline;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;inear interpolation&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: Toggle &lt;/span&gt;&lt;span style=&quot; font-size:12pt; text-decoration: underline;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;ontour superposition mode&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
@@ -65,7 +69,7 @@ p, li { white-space: pre-wrap; }
         <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
 &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
 p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;space&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: Landmark&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;&quot;&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; text-decoration: underline;&quot;&gt;Navigation&lt;/span&gt;&lt;/p&gt;
@@ -74,6 +78,7 @@ p, li { white-space: pre-wrap; }
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;u&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot; font-size:12pt; text-decoration: underline;&quot;&gt;U&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;pdate Image&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot; font-size:12pt; text-decoration: underline;&quot;&gt;F&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;ly To Mouse Position&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;g&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot; font-size:12pt; text-decoration: underline;&quot;&gt;G&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;o to Crosshair Position&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Ctrl+g&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot; font-size:12pt; text-decoration: underline;&quot;&gt;G&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;o to Coordinate System Origin&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;h&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot; font-size:12pt; text-decoration: underline;&quot;&gt;H&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;ide Crosshair and corner annotations&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt;&quot;&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Up,Down&lt;/span&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;: Change Slice&lt;/span&gt;&lt;/p&gt;
index 5560a9e063b1f7b32fb1c9c31f7a89485961e586..a6801c2ca363b92615db55f7665894b1f14ef309 100644 (file)
@@ -27,7 +27,7 @@
     <normaloff>:/common/icons/ducky.png</normaloff>:/common/icons/ducky.png</iconset>
   </property>
   <property name="statusTip">
-   <string>Type 'h' on image to display help on navigation</string>
+   <string>Type 'F1' on image to display help on navigation</string>
   </property>
   <widget class="QWidget" name="centralwidget">
    <property name="sizePolicy">
@@ -37,7 +37,7 @@
     </sizepolicy>
    </property>
    <property name="statusTip">
-    <string>Type 'h' on image to display help on navigation</string>
+    <string>Type 'F1' on image to display help on navigation</string>
    </property>
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
            <string>Cold</string>
           </property>
          </item>
+         <item>
+          <property name="text">
+           <string>Dosimetry</string>
+          </property>
+         </item>
          <item>
           <property name="text">
            <string>Full Color</string>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="NOViewWidget" native="true">
+           <widget class="QVTKWidget" name="NOViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="SOViewWidget" native="true">
+           <widget class="QVTKWidget" name="SOViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="NEViewWidget" native="true">
+           <widget class="QVTKWidget" name="NEViewWidget">
             <property name="mouseTracking">
              <bool>true</bool>
             </property>
            <number>2</number>
           </property>
           <item row="0" column="0">
-           <widget class="QVTKWidget" name="SEViewWidget" native="true">
+           <widget class="QVTKWidget" name="SEViewWidget">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
               <horstretch>0</horstretch>
     </property>
     <addaction name="actionNavigation_Help"/>
     <addaction name="actionDocumentation"/>
+    <addaction name="actionRegister_vv"/>
    </widget>
    <widget class="QMenu" name="menuOverlay">
     <property name="title">
      <normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
    </property>
    <property name="text">
-    <string>Merge several xD images into a single (x+1)D image</string>
+    <string>Merge several nD images into a single (n+1)D image</string>
    </property>
   </action>
   <action name="actionSlice_Image_As_Multiple_Images">
      <normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
    </property>
    <property name="text">
-    <string>Slice a xD image into several (x-1)D images</string>
+    <string>Slice a nD image into several (n-1)D images</string>
    </property>
   </action>
   <action name="actionOpen_one_Image_as_Multiple">
      <normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
    </property>
    <property name="text">
-    <string>Open xD image(s) as (x-1)D + t</string>
+    <string>Open a nD image as a (n-1)D + t image</string>
    </property>
   </action>
   <action name="actionMerge_images_as_n_dim_t">
      <normaloff>:/common/icons/open.png</normaloff>:/common/icons/open.png</iconset>
    </property>
    <property name="text">
-    <string>Open several xD images into a single xD+t images</string>
+    <string>Open several nD images into a single nD+t image</string>
    </property>
   </action>
   <action name="actionAdd_fusion_image">
     <string>Experimental...</string>
    </property>
   </action>
+  <action name="actionRegister_vv">
+   <property name="text">
+    <string>Register vv</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
index 60a6803859eb98011b98a10c9cd2961e5c7ac997..eab2f23388823d0fc8e12a961cedc9d01dd2d8f8 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>323</width>
-    <height>447</height>
+    <width>342</width>
+    <height>480</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -171,12 +171,12 @@ p, li { white-space: pre-wrap; }
         </item>
         <item>
          <widget class="QToolButton" name="vfColorButton">
-           <property name="styleSheet">
-            <string>
+          <property name="styleSheet">
+           <string>
               background-color: rgb(0, 255, 0);
               border: 0px;
             </string>
-           </property>
+          </property>
          </widget>
         </item>
        </layout>
@@ -221,7 +221,7 @@ p, li { white-space: pre-wrap; }
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
-     <layout class="QGridLayout">
+     <layout class="QGridLayout" name="compareGridLayout">
       <property name="margin">
        <number>2</number>
       </property>
@@ -267,7 +267,7 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="1" column="2">
+      <item row="1" column="1" colspan="5">
        <widget class="QSlider" name="colorHorizontalSlider">
         <property name="maximum">
          <number>359</number>
@@ -277,7 +277,7 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="2" column="0" colspan="3">
+      <item row="2" column="0" colspan="5">
        <widget class="QLabel" name="refValueLabel">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -290,7 +290,7 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="3" column="0" colspan="3">
+      <item row="3" column="0" colspan="5">
        <widget class="QLabel" name="valueLabel">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -303,7 +303,7 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="3">
+      <item row="4" column="0" colspan="5">
        <widget class="QLabel" name="diffValueLabel">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -316,6 +316,81 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
+      <item row="5" column="0">
+       <widget class="QLabel" name="label_10">
+        <property name="text">
+         <string>Window :</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="1">
+       <widget class="QDoubleSpinBox" name="overlayWindowSpinBox">
+        <property name="decimals">
+         <number>4</number>
+        </property>
+        <property name="minimum">
+         <double>-999999.000000000000000</double>
+        </property>
+        <property name="maximum">
+         <double>999999.000000000000000</double>
+        </property>
+        <property name="singleStep">
+         <double>10.000000000000000</double>
+        </property>
+        <property name="value">
+         <double>100.000000000000000</double>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="2">
+       <widget class="QLabel" name="label_11">
+        <property name="text">
+         <string>Level :</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="3">
+       <widget class="QDoubleSpinBox" name="overlayLevelSpinBox">
+        <property name="decimals">
+         <number>4</number>
+        </property>
+        <property name="minimum">
+         <double>-999999.000000000000000</double>
+        </property>
+        <property name="maximum">
+         <double>999999.000000000000000</double>
+        </property>
+        <property name="singleStep">
+         <double>10.000000000000000</double>
+        </property>
+        <property name="value">
+         <double>1000.000000000000000</double>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="4">
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="5" column="5">
+       <widget class="QCheckBox" name="overlayLinkCheckBox">
+        <property name="text">
+         <string>Link</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
@@ -330,13 +405,7 @@ p, li { white-space: pre-wrap; }
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
-     <layout class="QGridLayout">
-      <property name="margin">
-       <number>2</number>
-      </property>
-      <property name="spacing">
-       <number>2</number>
-      </property>
+     <layout class="QGridLayout" name="fusionGridLayout">
       <item row="0" column="0">
        <widget class="QLabel" name="label_5">
         <property name="maximumSize">
@@ -353,7 +422,7 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="0" column="1" colspan="4">
+      <item row="0" column="1" colspan="2">
        <widget class="QLabel" name="dataFusionnedLabel">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -366,14 +435,14 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="1" column="0" colspan="2">
+      <item row="1" column="0" colspan="3">
        <widget class="QLabel" name="opacityLabel">
         <property name="text">
-         <string>Opacity :</string>
+         <string>Global Opacity :</string>
         </property>
        </widget>
       </item>
-      <item row="1" column="2" colspan="3">
+      <item row="1" column="3" colspan="3">
        <widget class="QSlider" name="opacityHorizontalSlider">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -386,7 +455,36 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="2" column="0" colspan="2">
+      <item row="2" column="0" colspan="3">
+       <widget class="QLabel" name="thresOpacityLabel">
+        <property name="toolTip">
+         <string>All colors below the threshold will be made transparent.</string>
+        </property>
+        <property name="statusTip">
+         <string/>
+        </property>
+        <property name="whatsThis">
+         <string/>
+        </property>
+        <property name="text">
+         <string>Transparency Threshold :</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="3" colspan="3">
+       <widget class="QSlider" name="thresOpacityHorizontalSlider">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0" colspan="2">
        <widget class="QLabel" name="label_6">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
@@ -399,10 +497,10 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="2" column="2" colspan="2">
+      <item row="3" column="2" colspan="2">
        <widget class="QComboBox" name="fusionColorMapComboBox">
         <property name="currentIndex">
-         <number>3</number>
+         <number>0</number>
         </property>
         <item>
          <property name="text">
@@ -419,6 +517,11 @@ p, li { white-space: pre-wrap; }
           <string>Cold</string>
          </property>
         </item>
+        <item>
+         <property name="text">
+          <string>Dosimetry</string>
+         </property>
+        </item>
         <item>
          <property name="text">
           <string>Full Color Range</string>
@@ -426,15 +529,15 @@ p, li { white-space: pre-wrap; }
         </item>
        </widget>
       </item>
-      <item row="3" column="0" colspan="2">
+      <item row="4" column="0" colspan="2">
        <widget class="QLabel" name="label_7">
         <property name="text">
          <string>Window :</string>
         </property>
        </widget>
       </item>
-      <item row="3" column="2">
-       <widget class="QDoubleSpinBox" name="windowSpinBox">
+      <item row="4" column="2" colspan="2">
+       <widget class="QDoubleSpinBox" name="fusionWindowSpinBox">
         <property name="decimals">
          <number>4</number>
         </property>
@@ -452,15 +555,15 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="3" column="3">
+      <item row="4" column="4">
        <widget class="QLabel" name="label_8">
         <property name="text">
          <string>Level :</string>
         </property>
        </widget>
       </item>
-      <item row="3" column="4">
-       <widget class="QDoubleSpinBox" name="levelSpinBox">
+      <item row="4" column="5">
+       <widget class="QDoubleSpinBox" name="fusionLevelSpinBox">
         <property name="decimals">
          <number>4</number>
         </property>
@@ -478,7 +581,7 @@ p, li { white-space: pre-wrap; }
         </property>
        </widget>
       </item>
-      <item row="4" column="0" colspan="5">
+      <item row="5" column="0" colspan="3">
        <widget class="QLabel" name="valueFusionnedLabel">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -510,7 +613,6 @@ p, li { white-space: pre-wrap; }
   </layout>
  </widget>
  <resources>
-  <include location="../vvIcons.qrc"/>
   <include location="../vvIcons.qrc"/>
   <include location="vvIcons.qrc"/>
  </resources>
diff --git a/vv/qt_ui/vvRegisterForm.ui b/vv/qt_ui/vvRegisterForm.ui
new file mode 100644 (file)
index 0000000..9458ca5
--- /dev/null
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>vvRegisterForm</class>
+ <widget class="QDialog" name="vvRegisterForm">
+  <property name="windowModality">
+   <enum>Qt::ApplicationModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>350</width>
+    <height>396</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>VV registration</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_2">
+   <item row="0" column="0">
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <item>
+      <widget class="QTextBrowser" name="textBrowser">
+       <property name="contextMenuPolicy">
+        <enum>Qt::DefaultContextMenu</enum>
+       </property>
+       <property name="autoFillBackground">
+        <bool>false</bool>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::NoFrame</enum>
+       </property>
+       <property name="frameShadow">
+        <enum>QFrame::Plain</enum>
+       </property>
+       <property name="html">
+        <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p align=&quot;justify&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;img src=&quot;:/common/icons/weNeedYou.png&quot; style=&quot;float: left;&quot; /&gt;&lt;span style=&quot; font-size:11pt; font-weight:600; color:#0000c0;&quot;&gt;Welcome to VV !&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We wish to keep an estimate of the number of persons using VV. This is really important for us to justify the ressources spent in developing this software.&lt;/p&gt;
+&lt;p align=&quot;justify&quot; style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p align=&quot;justify&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Please, take a few seconds to fill in the following fields and send us the information by clicking OK. If you still prefer to remain anonymous, simply click &amp;quot;Cancel&amp;quot; (you can still register afterwards using the help menu).&lt;/p&gt;
+&lt;p align=&quot;justify&quot; style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p align=&quot;justify&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:10px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Privacy: the collected information is for internal and non-commercial use only. We will only use your email for vv release announcements.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="0" column="0">
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>First name</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1">
+        <widget class="QLineEdit" name="firstName"/>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="label_2">
+         <property name="text">
+          <string>Last name</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLineEdit" name="lastName"/>
+       </item>
+       <item row="2" column="0">
+        <widget class="QLabel" name="label_3">
+         <property name="text">
+          <string>Email</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLineEdit" name="email"/>
+       </item>
+       <item row="3" column="0">
+        <widget class="QLabel" name="label_4">
+         <property name="text">
+          <string>Institute</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1">
+        <widget class="QLineEdit" name="group"/>
+       </item>
+       <item row="4" column="0">
+        <widget class="QLabel" name="label_5">
+         <property name="text">
+          <string>OS name</string>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="1">
+        <widget class="QLabel" name="osName">
+         <property name="text">
+          <string>OS name</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="../vvIcons.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>vvRegisterForm</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>vvRegisterForm</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/vv/scripts/transfer_patients.sh b/vv/scripts/transfer_patients.sh
deleted file mode 100755 (executable)
index e683f7d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-cd current
-echo -n "Patients before: "
-find . -type l | wc -l
-for i in /home/gauthier/Base_de_donnees_stereo_poumon/*; do [ -e "$i" ] || ln -s "$i" .; done
-echo -n "Patients after: "
-find . -type l | wc -l
-for i in $(find . -type l); do date; echo $i; irsync -rv "$i" "i:/rhone-alpes/home/clb/patients/$i" >> "$i"_$(date "+%H:%m-%d_%b%Y").log; done
index 2a68f3384e3e330c39fcc7dd4b171addb9d9478f..981105095d68a80934280b6e332895cc1d42fa9a 100644 (file)
--- a/vv/vv.cxx
+++ b/vv/vv.cxx
@@ -30,6 +30,7 @@
 
 #include "clitkIO.h"
 #include "vvMainWindow.h"
+#include "vvToolsList.h"
 #include <vtkFileOutputWindow.h>
 #include <vtkSmartPointer.h>
 #include <itkFileOutputWindow.h>
@@ -38,7 +39,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include  <errno.h>
+#include <errno.h>
 
 void load_image_first_error()
 {
@@ -61,19 +62,37 @@ std::string create_timed_string()
 }
 
 //------------------------------------------------------------------------------
+#ifdef _WIN32
+int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd)
+{
+  int argc = __argc;
+  char **argv = __argv;
+#else
 int main( int argc, char** argv )
 {
+#endif
+
   CLITK_INIT;
 
   QApplication app( argc, argv );
   Q_INIT_RESOURCE(vvIcons);
-  //QPixmap pixmap(":/splashscreen.PNG");
-  QSplashScreen *splash = new QSplashScreen(QPixmap(QString::fromUtf8(":/new/prefix1/splashscreen.PNG")));
-  /*splash->showMessage("VV 1.0 developped by Léon Bérard c`ancer center http://www.centreleonberard.fr and CREATIS-LRMN http://www.creatis.insa-lyon.fr",(Qt::AlignRight | Qt::AlignBottom));*/
-  //  splash->show();
-  QTimer::singleShot(2000, splash, SLOT(close()));
-  while (!splash->isHidden())
-    app.processEvents();
+  
+  // 
+  // ATTENTION: Rômulo Pinho - 05/08/2011
+  // Forcing the locale of the application is necessary
+  // because QT initialization changes it to the locale
+  // of the language of the system. This can cause 
+  // inconsistencies when, e.g., reading float values
+  // from DICOM fields with gdcm, since the decimal
+  // point may be changed for a comma (as in French).
+  // In practice, functions such as scanf and its
+  // variations are directly affected.
+  // https://bugreports.qt.nokia.com//browse/QTBUG-15247?page=com.atlassian.jira.plugin.system.issuetabpanels%253Achangehistory-tabpanel
+  //
+#ifndef _WIN32
+  std::string old_locale = setlocale(LC_NUMERIC, NULL);
+  setlocale(LC_NUMERIC, "POSIX");
+#endif
 
   vvMainWindow window;
 
@@ -129,9 +148,11 @@ int main( int argc, char** argv )
 
           if(itksys::SystemTools::FileExists(log_dir.c_str()) &&
               !itksys::SystemTools::FileIsDirectory(log_dir.c_str())) {
-            itkGenericExceptionMacro(<< "Error creating log directory, file exists and is not a directory.");
+            std::cerr << "Error creating log directory, file exists and is not a directory." << std::endl;
+            exit(1);
           } else if(!itksys::SystemTools::MakeDirectory(log_dir.c_str())) {
-            itkGenericExceptionMacro(<< "Error creating log directory.");
+            std::cerr << "Error creating log directory." << std::endl;
+            exit(1);
           }
 
           std::string log_file = log_dir + "/" + create_timed_string() + ".log";
@@ -171,9 +192,14 @@ int main( int argc, char** argv )
   }
 
   if(win!="" && lev!="") {
-    window.WindowLevelChanged(atof(win.c_str()), atof(lev.c_str()), 6, 0);
+    window.SetWindowLevel(atof(win.c_str()), atof(lev.c_str()));
     window.ApplyWindowLevelToAllImages();
   }
 
+#ifndef _WIN32
+  // restoring the locale, just to be clean...
+  setlocale(LC_NUMERIC, old_locale.c_str());
+#endif
+
   return app.exec();
 }
diff --git a/vv/vvConfiguration.h.in b/vv/vvConfiguration.h.in
new file mode 100644 (file)
index 0000000..36d3258
--- /dev/null
@@ -0,0 +1,24 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+
+#ifndef vv_configuration_h
+#define vv_configuration_h
+
+#define VV_VERSION "v@CPACK_PACKAGE_VERSION_MAJOR@.@CPACK_PACKAGE_VERSION_MINOR@.@CPACK_PACKAGE_VERSION_PATCH@"
+
+#endif
index 462b0ea1198f417ec836cbde5db8aa58231773c8..15a864843ba26c5767d6a665b72bd65063f245ca 100644 (file)
@@ -1,6 +1,7 @@
 <RCC>
   <qresource prefix="common">
     <file>icons/mip.png</file>
+    <file>icons/weNeedYou.png</file>
     <file>icons/tool-roi.png</file>
     <file>icons/plastimatch.png</file>
     <file>icons/lung-overlay.png</file>
@@ -38,5 +39,6 @@
     <file>icons/adjustsize.png</file>
     <file>icons/standardbutton-apply-16.png</file>
     <file>icons/standardbutton-cancel-16.png</file>
+    <file>icons/identity.png</file>
   </qresource>
 </RCC>
index 99bc6e495858a5156cc6951600e555edb7a31be7..94129031759648c7808a40f6216b12b95ef74d1d 100644 (file)
@@ -35,6 +35,7 @@ vvImageContour::vvImageContour()
   mHiddenImageIsUsed = false;
   mDisplayModeIsPreserveMemory = true;
   SetPreserveMemoryModeEnabled(true);
+  mPreviousOrientation = -1;
 }
 //------------------------------------------------------------------------------
 
@@ -138,7 +139,9 @@ void vvImageContour::Update(double value) {
   if (mPreviousValue == value) {
     if (mPreviousSlice == mSlicer->GetSlice()) {
       if (mPreviousTSlice == mSlicer->GetTSlice()) {
-        return; // Nothing to do
+        if (mPreviousOrientation == ComputeCurrentOrientation()) {
+          return; // Nothing to do
+        }
       }
     }
   }
@@ -156,11 +159,12 @@ void vvImageContour::Update(double value) {
     UpdateWithFastCacheMode();
   }
 
-  //  mSlicer->Render(); //DS ---> REMOVE ??
+  //mSlicer->Render(); //DS ---> REMOVE ??
 
   mPreviousTSlice = mSlicer->GetTSlice();
   mPreviousSlice  = mSlicer->GetSlice();
   mPreviousValue  = value;
+  mPreviousOrientation = ComputeCurrentOrientation();
 }
 //------------------------------------------------------------------------------
 
@@ -168,20 +172,22 @@ void vvImageContour::Update(double value) {
 //------------------------------------------------------------------------------
 void vvImageContour::UpdateWithPreserveMemoryMode() {
   // Only change actor visibility if tslice change
-  int mPreviousTslice = mTSlice;
+  mPreviousTslice = mTSlice;
   mTSlice = mSlicer->GetTSlice();
 
   vtkMarchingSquares * mSquares = mSquaresList[mTSlice];
+  vtkPolyDataMapper* mapper = mSquaresMapperList[mTSlice];
   vtkImageClip * mClipper = mClipperList[mTSlice];
   vtkActor * mSquaresActor = mSquaresActorList[mTSlice];
   int orientation = ComputeCurrentOrientation();
 
-  UpdateActor(mSquaresActor, mSquares, mClipper, mValue, orientation, mSlice);
-  //mSquaresActorList[mTSlice]->VisibilityOn();
+  UpdateActor(mSquaresActor, mapper, mSquares, mClipper, mValue, orientation, mSlice);
 
   if (mPreviousTslice != mTSlice) {
     if (mPreviousTslice != -1) mSquaresActorList[mPreviousTslice]->VisibilityOff();
   }
+  
+  mSlicer->Render();
 }
 //------------------------------------------------------------------------------
 
@@ -261,6 +267,7 @@ void vvImageContour::CreateNewActor(int numImage) {
     clipper->SetInput(mHiddenImage->GetVTKImages()[0]);
   else
     clipper->SetInput(mSlicer->GetImage()->GetVTKImages()[numImage]);
+  
   squares->SetInput(clipper->GetOutput());
   squaresMapper->SetInput(squares->GetOutput());
   squaresMapper->ScalarVisibilityOff();
@@ -280,9 +287,11 @@ void vvImageContour::CreateNewActor(int numImage) {
 
 //------------------------------------------------------------------------------
 void vvImageContour::UpdateActor(vtkActor * actor, 
+                                 vtkPolyDataMapper * mapper, 
                                  vtkMarchingSquares * squares, 
                                  vtkImageClip * clipper, 
                                  double threshold, int orientation, int slice) {
+  
    // Set parameter for the MarchigSquare
   squares->SetValue(0, threshold);
 
@@ -319,6 +328,7 @@ void vvImageContour::UpdateActor(vtkActor * actor,
 
   } else {
     extent2 = extent;
+    actor->VisibilityOn();
   }
  
   clipper->SetOutputWholeExtent(extent2[0],extent2[1],extent2[2],
@@ -327,44 +337,11 @@ void vvImageContour::UpdateActor(vtkActor * actor,
   if (mHiddenImageIsUsed) delete extent2;
 
   // Move the actor to be visible
-  switch (orientation)  {
-  case 0:
-    actor->SetPosition(-1,0,0);
-    /*
-    // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0]);
-    if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[0] > slice) {
-    actor->SetPosition(1,0,0);
-    } else {
-      actor->SetPosition(-1,0,0);
-      }*/
-    break;
-  case 1:
-    actor->SetPosition(0,-1,0);
-    /*
-    // DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1]);
-    if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[1] > slice) {
-      actor->SetPosition(0,1,0);
-    } else {
-      actor->SetPosition(0,-1,0);
-    }
-    */
-    break;
-  case 2:
-    actor->SetPosition(0,0,-1);
-    /*
-    DD(mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2]);
-    if (mSlicer->GetRenderer()->GetActiveCamera()->GetPosition()[2] > slice) {
-      DD("1");
-      actor->SetPosition(0,0,1);
-    } else {
-     DD("-1");
-      actor->SetPosition(0,0,-1);
-    }
-    */
-    break;
-  }
-
-  squares->Update();
+  double position[3] = {0, 0, 0};
+  position[orientation] = -1;
+  actor->SetPosition(position);
+  
+  mapper->Update();
 }
 //------------------------------------------------------------------------------
 
index 1cf2e569b9df57def7a2312176f0b107cac369f7..d2be5129a6e00d6bb1d7c63dbe7f5b1ff1815b56 100644 (file)
@@ -71,7 +71,7 @@ protected:
   void UpdateWithPreserveMemoryMode();
   void UpdateWithFastCacheMode();
   void CreateNewActor(int numImage);
-  void UpdateActor(vtkActor * actor, vtkMarchingSquares * squares, vtkImageClip * clipper,
+  void UpdateActor(vtkActor * actor, vtkPolyDataMapper * mapper, vtkMarchingSquares * squares, vtkImageClip * clipper,
                    double threshold, int orientation, int slice);
   void CreateActor(int orientation, int slice);
   int ComputeCurrentOrientation();
@@ -79,6 +79,7 @@ protected:
 private:
   vvImageContour();
   ~vvImageContour();
+    int mPreviousTslice;
 }; // end class vvImageContour
 //------------------------------------------------------------------------------
 
index 1cfde1612b0ce77dacaf911b0d52dc9e584f4a8f..ff6580387a3c93aaef6c0af3a17c023f57a413d6 100644 (file)
@@ -101,7 +101,11 @@ void vvImageWarp::Update_WithDimAndPixelType()
     jacobian_filter->SetUseImageSpacingOn();
     vf_connector->SetInput(mVF->GetVTKImages()[num]);
     warp_filter->SetInput(input[num]);
+#if ITK_VERSION_MAJOR >= 4
+    warp_filter->SetDisplacementField(vf_connector->GetOutput());
+#else
     warp_filter->SetDeformationField(vf_connector->GetOutput());
+#endif
     jacobian_filter->SetInput(vf_connector->GetOutput());
     warp_filter->SetOutputSpacing(input[num]->GetSpacing());
     warp_filter->SetOutputOrigin(input[num]->GetOrigin());
index 44290450473d56957a6d439a1751385748ebc689..e8d3ba8187718616c917a166ae14e7e5476f4654 100644 (file)
 
 #include "vvInfoPanel.h"
 #include "clitkMemoryUsage.h"
+#include "clitkConfiguration.h"
+
+//------------------------------------------------------------------------------
+vvInfoPanel::vvInfoPanel(QWidget * parent):QWidget(parent)
+{
+  setupUi(this);
+#if CLITK_MEMORY_INFO==0
+  memoryUsageLabel->hide();
+#endif
+}
+//------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
 void vvInfoPanel::setTransformation(QString text)
@@ -111,55 +122,6 @@ void vvInfoPanel::setCurrentInfo(int visibility, double x, double y, double z, d
 //------------------------------------------------------------------------------
 
 
-//------------------------------------------------------------------------------
-void vvInfoPanel::setViews(int window, int view, int slice)
-{/*
-  QString viewString;
-  switch (view) {
-  case 0: {
-    viewString = "Sagital,  ";
-    break;
-  }
-  case 1: {
-    viewString = "Coronal, ";
-    break;
-  }
-  case 2: {
-    viewString = "Axial,   ";
-    break;
-  }
-  }
-
-  QString text = viewString;
-  if (view != -1) {
-    text += "current slice : ";
-    text += QString::number(slice);
-  } else {
-    text = "Disable";
-  }
-
-  switch (window) {
-  case 0: {
-    ULLabel->setText(text);
-    break;
-  }
-  case 1: {
-    URLabel->setText(text);
-    break;
-  }
-  case 2: {
-    DLLabel->setText(text);
-    break;
-  }
-  case 3: {
-    DRLabel->setText(text);
-    break;
-  }
-  }*/
-}
-//------------------------------------------------------------------------------
-
-
 //------------------------------------------------------------------------------
 void vvInfoPanel::setMemoryInMb(QString text)
 {
index c064b3ae4b4d318162d3bdb674ee463cd5edad20..4a665e1aaa34ba09029fa843a5130cf5feabc43c 100644 (file)
@@ -27,9 +27,7 @@ class vvInfoPanel : public QWidget, private Ui::vvInfoPanel
   Q_OBJECT
 
 public:
-    vvInfoPanel(QWidget * parent=0):QWidget(parent) {
-        setupUi(this);
-    }
+    vvInfoPanel(QWidget * parent=0);
     ~vvInfoPanel() {}
 
     void setTransformation(QString text);
@@ -41,7 +39,6 @@ public:
     void setDimension(QString text);
     void setSizePixel(QString text);
     void setCurrentInfo(int visibility, double x, double y, double z, double X, double Y, double Z, double value);
-    void setViews(int window, int view, int slice);
     void setMemoryInMb(QString text);
 
 public slots:
index e53841950d599b2b1b1f8d1d29db7a2658c8f2af..1c2230f57160a8aa43e904f4e40734ed6233211a 100644 (file)
 #include <QInputDialog>
 #include <QTimer>
 #include "QTreePushButton.h"
+#include <QUrl>
+#include <QSettings>
 
 // VV include
 #include "vvMainWindow.h"
 #include "vvHelpDialog.h"
+#include "vvRegisterForm.h"
 #include "vvDocumentation.h"
 #include "vvProgressDialog.h"
 #include "vvQDicomSeriesSelector.h"
 #include <vtkPNMWriter.h>
 #include <vtkPNGWriter.h>
 #include <vtkJPEGWriter.h>
-#include <vtkFFMPEGWriter.h>
+#ifdef VTK_USE_FFMPEG_ENCODER
+#  include <vtkFFMPEGWriter.h>
+#endif
 #ifdef VTK_USE_MPEG2_ENCODER
-  #include <vtkMPEG2Writer.h>
+#  include <vtkMPEG2Writer.h>
 #endif
 #include <vtkMatrix4x4.h>
 #include <vtkTransform.h>
@@ -86,7 +91,7 @@
 #define COLUMN_RELOAD_IMAGE 6
 #define COLUMN_IMAGE_NAME 7
 
-#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.hdr *.vox *.his *.xdr *.SCAN )"
+#define EXTENSIONS "Images ( *.bmp *.png *.jpeg *.jpg *.tif *.mhd *.mha *.hdr *.vox *.his *.xdr *.SCAN )"
 
 /*Data Tree values
   0,Qt::UserRole full filename
@@ -155,6 +160,11 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionAdd_fusion_image,SIGNAL(triggered()),this,SLOT(SelectFusionImage()));
   contextActions.push_back(actionAdd_fusion_image);
 
+  contextMenu.addSeparator();
+  QAction* actionResetMatrix = contextMenu.addAction(QIcon(QString::fromUtf8(":/common/icons/identity.png")),
+                                                      tr("Reset transformation to identity"));
+  connect(actionResetMatrix, SIGNAL(triggered()), this,SLOT(ResetTransformationToIdentity()));
+
   // TRIAL DS
   /*
   QMenu * m = new QMenu(menubar);
@@ -249,6 +259,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionAdd_VF_to_current_Image,SIGNAL(triggered()),this,SLOT(OpenField()));
   connect(actionNavigation_Help,SIGNAL(triggered()),this,SLOT(ShowHelpDialog()));
   connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation()));
+  connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm()));
 
   ///////////////////////////////////////////////
   connect(actionSegmentation,SIGNAL(triggered()),this,SLOT(SegmentationOnCurrentImage()));
@@ -283,9 +294,10 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(linkPanel,SIGNAL(addLink(QString,QString)),this,SLOT(AddLink(QString,QString)));
   connect(linkPanel,SIGNAL(removeLink(QString,QString)),this,SLOT(RemoveLink(QString,QString)));
   connect(overlayPanel,SIGNAL(VFPropertyUpdated(int,int,int,int,double,double,double)),this,SLOT(SetVFProperty(int,int,int,int,double,double,double)));
-  connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int)),this,SLOT(SetOverlayProperty(int)));
-  connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,double,double)),
-          this,SLOT(SetFusionProperty(int,int,double,double)));
+  connect(overlayPanel,SIGNAL(OverlayPropertyUpdated(int,int,double,double)),
+          this,SLOT(SetOverlayProperty(int,int,double,double)));
+  connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,int,double,double)),
+          this,SLOT(SetFusionProperty(int,int,int,double,double)));
   connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows()));
 
   playMode = 0;//pause
@@ -306,21 +318,15 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
 
   //Recently opened files
   std::list<std::string> recent_files = GetRecentlyOpenedImages();
+  recentlyOpenedFilesMenu=NULL;
   if ( !recent_files.empty() ) {
-    QMenu * rmenu = new QMenu("Recently opened files...");
-    rmenu->setIcon(QIcon(QString::fromUtf8(":/common/icons/open.png")));
-    menuFile->insertMenu(actionOpen_Image_With_Time,rmenu);
-    menuFile->insertSeparator(actionOpen_Image_With_Time);
-    for (std::list<std::string>::iterator i = recent_files.begin(); i!=recent_files.end(); i++) {
-      QAction* current=new QAction(QIcon(QString::fromUtf8(":/common/icons/open.png")),
-                                   (*i).c_str(),this);
-      rmenu->addAction(current);
-      connect(current,SIGNAL(triggered()),this,SLOT(OpenRecentImage()));
-    }
+    createRecentlyOpenedFilesMenu();
+    updateRecentlyOpenedFilesMenu(recent_files);
   }
 
   // Adding all new tools (insertion in the menu)
   vvToolManager::GetInstance()->InsertToolsInMenu(this);
+  vvToolManager::GetInstance()->EnableToolsInMenu(this, false);
 
   if (!CLITK_EXPERIMENTAL)
     menuExperimental->menuAction()->setVisible(false);
@@ -330,11 +336,13 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   //timerMemory->setInterval(5);
   connect(timerMemory, SIGNAL(timeout()), this, SLOT(UpdateMemoryUsage()));
   timerMemory->start(2000);
-  
 }
 //------------------------------------------------------------------------------
-
-
+void vvMainWindow::show()
+{
+  vvMainWindowBase::show();
+  PopupRegisterForm(true);
+}
 //------------------------------------------------------------------------------
 void vvMainWindow::UpdateMemoryUsage()
 {
@@ -345,6 +353,35 @@ void vvMainWindow::UpdateMemoryUsage()
 //------------------------------------------------------------------------------
 
 
+//------------------------------------------------------------------------------
+void vvMainWindow::createRecentlyOpenedFilesMenu()
+{
+  recentlyOpenedFilesMenu = new QMenu("Recently opened files...");
+  recentlyOpenedFilesMenu->setIcon(QIcon(QString::fromUtf8(":/common/icons/open.png")));
+  menuFile->insertMenu(actionOpen_Image_With_Time,recentlyOpenedFilesMenu);
+  menuFile->insertSeparator(actionOpen_Image_With_Time);
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+
+void vvMainWindow::updateRecentlyOpenedFilesMenu(const std::list<std::string> &recent_files)
+{
+  if(recentlyOpenedFilesMenu==NULL) {
+    createRecentlyOpenedFilesMenu();
+  } else {
+    recentlyOpenedFilesMenu->clear();
+  }
+  for (std::list<std::string>::const_iterator i = recent_files.begin(); i!=recent_files.end(); i++) {
+    QAction* current=new QAction(QIcon(QString::fromUtf8(":/common/icons/open.png")), i->c_str(),this);
+    recentlyOpenedFilesMenu->addAction(current);
+    connect(current,SIGNAL(triggered()),this,SLOT(OpenRecentImage()));
+  }
+}
+//------------------------------------------------------------------------------
+
+
 //------------------------------------------------------------------------------
 void vvMainWindow::ComputeMidPosition()
 {
@@ -790,6 +827,7 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
   if (files.size() == 1) {
     QFileInfo finfo=tr(files[0].c_str());
     AddToRecentlyOpenedImages(finfo.absoluteFilePath().toStdString());
+    updateRecentlyOpenedFilesMenu(GetRecentlyOpenedImages());
   }
   //init the progress events
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
@@ -833,7 +871,8 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
         item->setData(0,Qt::UserRole,files[i].c_str());
         QFileInfo fileinfo(imageManager->GetFileName().c_str()); //Do not show the path
         item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
-        item->setToolTip(COLUMN_IMAGE_NAME,fileinfo.absoluteFilePath());
+        item->setData(1,Qt::UserRole,tr("image"));
+        item->setToolTip(COLUMN_IMAGE_NAME, imageManager->GetListOfAbsoluteFilePathInOneString("image").c_str());
         qApp->processEvents();
 
         //Create the buttons for reload and close
@@ -867,8 +906,8 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
 
         connect(mSlicerManagers.back(), SIGNAL(currentImageChanged(std::string)),
                 this,SLOT(CurrentImageChanged(std::string)));
-       connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)),
-               this, SLOT(CurrentPickedImageChanged(std::string)));
+        connect(mSlicerManagers.back(), SIGNAL(currentPickedImageChanged(std::string)),
+                this, SLOT(CurrentPickedImageChanged(std::string)));
         connect(mSlicerManagers.back(), SIGNAL(UpdatePosition(int, double, double, double, double, double, double, double)),
                 this,SLOT(MousePositionChanged(int,double, double, double, double, double, double, double)));
         connect(mSlicerManagers.back(), SIGNAL(UpdateVector(int, double, double, double, double)),
@@ -877,10 +916,8 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
                 this, SLOT(OverlayChanged(int,double,double)));
         connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
                 this, SLOT(FusionChanged(int,double)));
-        connect(mSlicerManagers.back(), SIGNAL(UpdateWindows(int, int, int)),
-                this,SLOT(WindowsChanged(int, int, int)));
-        connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged(double, double,int, int)),
-                this,SLOT(WindowLevelChanged(double, double, int, int)));
+        connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
+                this,SLOT(WindowLevelChanged()));
         connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
                 this,SLOT(UpdateSlice(int,int)));
         connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
@@ -989,6 +1026,7 @@ void vvMainWindow::ImageInfoChanged()
   actionNorth_West_Window->setEnabled(1);
   actionSouth_East_Window->setEnabled(1);
   actionSouth_West_Window->setEnabled(1);
+  vvToolManager::GetInstance()->EnableToolsInMenu(this, true);
   inverseButton->setEnabled(1);
 
   goToCursorPushButton->setEnabled(1);
@@ -1031,70 +1069,35 @@ void vvMainWindow::ImageInfoChanged()
     vvImage::Pointer imageSelected;
     if (DataTree->topLevelItem(index) == DataTree->selectedItems()[0]) {
       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
-      dimension = imageSelected->GetNumberOfDimensions();
-      origin.resize(dimension);
-      inputSpacing.resize(dimension);
-      inputSize.resize(dimension);
-      sizeMM.resize(dimension);
-      pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
-      for (int i = 0; i < dimension; i++) {
-        origin[i] = imageSelected->GetOrigin()[i];
-        inputSpacing[i] = imageSelected->GetSpacing()[i];
-        inputSize[i] = imageSelected->GetSize()[i];
-        sizeMM[i] = inputSize[i]*inputSpacing[i];
-        NPixel *= inputSize[i];
-      }
-      inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "vector") {
       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetVF();
-      dimension = imageSelected->GetNumberOfDimensions();
-      origin.resize(dimension);
-      inputSpacing.resize(dimension);
-      inputSize.resize(dimension);
-      sizeMM.resize(dimension);
-      pixelType = mSlicerManagers[index]->GetVF()->GetScalarTypeAsITKString().c_str();
-      for (int i = 0; i < dimension; i++) {
-        origin[i] = imageSelected->GetOrigin()[i];
-        inputSpacing[i] = imageSelected->GetSpacing()[i];
-        inputSize[i] = imageSelected->GetSize()[i];
-        sizeMM[i] = inputSize[i]*inputSpacing[i];
-        NPixel *= inputSize[i];
-      }
-      inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "overlay") {
       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetOverlay();
-      dimension = imageSelected->GetNumberOfDimensions();
-      origin.resize(dimension);
-      inputSpacing.resize(dimension);
-      inputSize.resize(dimension);
-      sizeMM.resize(dimension);
-      pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
-      for (int i = 0; i < dimension; i++) {
-        origin[i] = imageSelected->GetOrigin()[i];
-        inputSpacing[i] = imageSelected->GetSpacing()[i];
-        inputSize[i] = imageSelected->GetSize()[i];
-        sizeMM[i] = inputSize[i]*inputSpacing[i];
-        NPixel *= inputSize[i];
-      }
-      inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
     } else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "fusion") {
       imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetFusion();
-      dimension = imageSelected->GetNumberOfDimensions();
-      origin.resize(dimension);
-      inputSpacing.resize(dimension);
-      inputSize.resize(dimension);
-      sizeMM.resize(dimension);
-      pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
-      for (int i = 0; i < dimension; i++) {
-        origin[i] = imageSelected->GetOrigin()[i];
-        inputSpacing[i] = imageSelected->GetSpacing()[i];
-        inputSize[i] = imageSelected->GetSize()[i];
-        sizeMM[i] = inputSize[i]*inputSpacing[i];
-        NPixel *= inputSize[i];
-      }
-      inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
+    }
+    else if (DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString() == "contour") {
+      imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
+    }
+    else {
+      imageSelected = mSlicerManagers[index]->GetSlicer(0)->GetImage();
     }
 
+    dimension = imageSelected->GetNumberOfDimensions();
+    origin.resize(dimension);
+    inputSpacing.resize(dimension);
+    inputSize.resize(dimension);
+    sizeMM.resize(dimension);
+    pixelType = mSlicerManagers[index]->GetImage()->GetScalarTypeAsITKString().c_str();
+    for (int i = 0; i < dimension; i++) {
+      origin[i] = imageSelected->GetOrigin()[i];
+      inputSpacing[i] = imageSelected->GetSpacing()[i];
+      inputSize[i] = imageSelected->GetSize()[i];
+      sizeMM[i] = inputSize[i]*inputSpacing[i];
+      NPixel *= inputSize[i];
+    }
+    inputSizeInBytes = GetSizeInBytes(imageSelected->GetActualMemorySize()*1000);
+    
     QString dim = QString::number(dimension) + " (";
     dim += pixelType + ")";
 
@@ -1120,10 +1123,6 @@ void vvMainWindow::ImageInfoChanged()
         break;
       }
     }
-    windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
-    levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
-    presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
-    colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
 
     infoPanel->setFileName(image);
     infoPanel->setDimension(dim);
@@ -1145,10 +1144,7 @@ void vvMainWindow::ImageInfoChanged()
         break;
       }
     }
-    windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
-    levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
-    presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
-    colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
+    WindowLevelChanged();
 
     if (mSlicerManagers[index]->GetSlicer(0)->GetVF()) {
       overlayPanel->getVFName(mSlicerManagers[index]->GetVFName().c_str());
@@ -1161,20 +1157,14 @@ void vvMainWindow::ImageInfoChanged()
     }
     if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) {
       overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
-      overlayPanel->getOverlayProperty(mSlicerManagers[index]->GetOverlayColor());
     } else {
       overlayPanel->getOverlayName(mSlicerManagers[index]->GetOverlayName().c_str());
-      overlayPanel->getOverlayProperty(-1);
     }
+    
     if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
       overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
-      overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
-                                      mSlicerManagers[index]->GetFusionColorMap(),
-                                      mSlicerManagers[index]->GetFusionWindow(),
-                                      mSlicerManagers[index]->GetFusionLevel());
     } else {
       overlayPanel->getFusionName(mSlicerManagers[index]->GetFusionName().c_str());
-      overlayPanel->getFusionProperty(-1, -1,-1,-1);
     }
   }
 }
@@ -1185,6 +1175,23 @@ void vvMainWindow::ShowDocumentation()
 {
   documentation->show();
 }
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvMainWindow::PopupRegisterForm(bool checkCanPush)
+{
+  vvRegisterForm* registerForm = new vvRegisterForm(QUrl("http://www.creatis.insa-lyon.fr/~dsarrut/vvregister/write.php"), getVVSettingsPath(), getSettingsOptionFormat());
+  if(!checkCanPush) {
+    registerForm->show();
+  } else {
+    if(registerForm->canPush()) {
+      registerForm->show();
+      registerForm->acquitPushed();//too bad if there is not internet connection anymore.
+    }
+  }
+}
+//------------------------------------------------------------------------------
+
 //------------------------------------------------------------------------------
 void vvMainWindow::ShowHelpDialog()
 {
@@ -1195,41 +1202,37 @@ void vvMainWindow::ShowHelpDialog()
 //------------------------------------------------------------------------------
 void vvMainWindow::ChangeViewMode()
 {
-  QListIterator<int> it0(splitter_3->sizes());
-  QListIterator<int> it1(splitter_3->sizes());
-  int max0 = 0;
-  int max1 = 1;
-  while (it0.hasNext()) {
-    max0 += it0.next();
-  }
-  while (it1.hasNext()) {
-    max1 += it1.next();
-  }
-  QList<int> size0;
-  QList<int> size1;
+  QList<int> size;
   if (viewMode == 1) {
     viewMode = 0;
-    size0.push_back(max0);
-    size0.push_back(0);
-    size1.push_back(max1);
-    size1.push_back(0);
-    splitter_3->setSizes(size0);
-    OSplitter->setSizes(size1);
+    size.push_back(1);
+    size.push_back(0);
+    splitter_3->setSizes(size);
+    OSplitter->setSizes(size);
     DataTree->setColumnHidden(2,1);
     DataTree->setColumnHidden(3,1);
     DataTree->setColumnHidden(4,1);
   } else {
     viewMode = 1;
-    size0.push_back(int(max0/2));
-    size0.push_back(int(max0/2));
-    size1.push_back(int(max1/2));
-    size1.push_back(int(max1/2));
-    splitter_3->setSizes(size0);
-    OSplitter->setSizes(size1);
+    size.push_back(1);
+    size.push_back(1);
+    splitter_3->setSizes(size);
+    OSplitter->setSizes(size);
     DataTree->setColumnHidden(2,0);
     DataTree->setColumnHidden(3,0);
     DataTree->setColumnHidden(4,0);
   }
+  UpdateRenderWindows();
+  /*
+  ** I don't know why but for both resized QVTKWidget we also need to render
+  ** the associated Slicer to redraw crosses.
+  */
+  for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
+    if (DataTree->topLevelItem(i)->data(COLUMN_UL_VIEW,Qt::CheckStateRole).toInt() > 1)
+      mSlicerManagers[i]->GetSlicer(0)->Render();
+    if (DataTree->topLevelItem(i)->data(COLUMN_DL_VIEW,Qt::CheckStateRole).toInt() > 1)
+      mSlicerManagers[i]->GetSlicer(2)->Render();
+  }
 }
 //------------------------------------------------------------------------------
 
@@ -1329,74 +1332,71 @@ QTreeWidgetItem* vvMainWindow::GetItemFromSlicerManager(vvSlicerManager* sm)
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::DisplayChanged(QTreeWidgetItem *clicked_item, int column)
+void vvMainWindow::DisplayChanged(QTreeWidgetItem *clickedItem, int column)
 {
-  int index = GetSlicerIndexFromItem(clicked_item);
   if ( column >= COLUMN_CLOSE_IMAGE || column <= 0)
     return;
+
+  // Get parent information (might be the same item)
+  int slicerManagerIndex = GetSlicerIndexFromItem(clickedItem);
+  QTreeWidgetItem* clickedParentItem = DataTree->topLevelItem(slicerManagerIndex);
+  vvSlicer* clickedSlicer = mSlicerManagers[slicerManagerIndex]->GetSlicer(column-1);
+
+  // Go over the complete item tree (only 2 levels, parents and children)
   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
-    //Trick to avoid redoing twice the job for a key (sr)
-    mSlicerManagers[i]->GetSlicer(column-1)->GetRenderWindow()-> GetInteractor()->SetKeySym("Crap");
-
-    QTreeWidgetItem* current_row=DataTree->topLevelItem(i);
-    if (DataTree->topLevelItem(index) == current_row) {
-      vvSlicer* clicked_slicer=mSlicerManagers[i]->GetSlicer(column-1);
-      if (current_row == clicked_item) {
-        //If we just activated a slicer
-        if (current_row->data(column,Qt::CheckStateRole).toInt() > 0) {
-          mSlicerManagers[i]->UpdateSlicer(column-1,clicked_item->data(column,Qt::CheckStateRole).toInt());
-          mSlicerManagers[i]->UpdateInfoOnCursorPosition(column-1);
-          DisplaySliders(i,column-1);
-          std::map<std::string,int> overlay_counts;
-          for (int child = 0; child < current_row->childCount(); child++) {
-            std::string overlay_type =
-              current_row->child(child)->data(1,Qt::UserRole).toString().toStdString();
-            overlay_counts[overlay_type]++;
-            current_row->child(child)->setData(column,Qt::CheckStateRole,
-                                               current_row->data(column,Qt::CheckStateRole));
-            clicked_slicer->SetActorVisibility(overlay_type,overlay_counts[overlay_type]-1,true);
-          }
-        } else { //We don't allow simply desactivating a slicer
-          clicked_item->setData(column,Qt::CheckStateRole,2);
-          return;
-        }
+    // Trick to avoid redoing twice the job for a key (sr)
+    mSlicerManagers[i]->GetSlicer(column-1)->GetRenderWindow()->GetInteractor()->SetKeySym("Crap");
+
+    QTreeWidgetItem* currentParentItem = DataTree->topLevelItem(i);
+    if(currentParentItem != clickedParentItem) {
+      // Not the branch of the clicked item, uncheck all
+
+      // Parent
+      currentParentItem->setData(column,Qt::CheckStateRole, 0);
+      mSlicerManagers[i]->UpdateSlicer(column-1, false);
+
+      // Children
+      for (int iChild = 0; iChild < currentParentItem->childCount(); iChild++) {
+        currentParentItem->child(iChild)->setData(column,Qt::CheckStateRole, 0);
       }
-      //if we clicked on the vector(or overlay) and not the image
-      else {
-        if (clicked_item->data(column,Qt::CheckStateRole).toInt()) {
-          current_row->setData(column,Qt::CheckStateRole,2);
-          mSlicerManagers[i]->UpdateSlicer(column-1,2);
-          mSlicerManagers[i]->UpdateInfoOnCursorPosition(column-1);
-          DisplaySliders(i,column-1);
-        }
-        int vis = clicked_item->data(column,Qt::CheckStateRole).toInt();
-        std::string overlay_type = clicked_item->data(1,Qt::UserRole).toString().toStdString();
-        int overlay_index=0;
-        for (int child = 0; child < current_row->childCount(); child++) {
-          if (current_row->child(child)->data(1,Qt::UserRole).toString().toStdString() == overlay_type)
-            overlay_index++;
-          if (current_row->child(child) == clicked_item) break;
-        }
-        clicked_slicer->SetActorVisibility(
-          clicked_item->data(1,Qt::UserRole).toString().toStdString(), overlay_index-1,vis);
+    }
+    else {
+      // Branch of the clicked one: get check status from actor visibility in slicer
+      // and toggle the clicked one
+
+      // Parent
+      bool vis = clickedSlicer->GetActorVisibility("image", 0);
+      bool draw = clickedSlicer->GetRenderer()->GetDraw();
+
+      // Update slicer (after getting visibility)
+      mSlicerManagers[slicerManagerIndex]->UpdateSlicer(column-1, true);
+      mSlicerManagers[slicerManagerIndex]->UpdateInfoOnCursorPosition(column-1);
+      DisplaySliders(slicerManagerIndex, column-1);
+      if(clickedParentItem == clickedItem) {
+        // Toggle
+        vis = !draw || !vis;
       }
-    } else if (current_row->data(column,Qt::CheckStateRole).toInt() > 0) {
-      current_row->setData(column,Qt::CheckStateRole,0);
-      mSlicerManagers[i]->UpdateSlicer(column-1,0);
-      std::map<std::string,int> overlay_counts;
-      for (int child = 0; child < current_row->childCount(); child++) {
-        std::string overlay_type =
-          current_row->child(child)->data(1,Qt::UserRole).toString().toStdString();
-        overlay_counts[overlay_type]++;
-        current_row->child(child)->setData(column,Qt::CheckStateRole,0);
-        vvSlicer * current_slicer=mSlicerManagers[i]->GetSlicer(column-1);
-        current_slicer->SetActorVisibility(overlay_type,overlay_counts[overlay_type]-1,false);
+      clickedSlicer->SetActorVisibility("image", 0, vis);
+      clickedParentItem->setData(column, Qt::CheckStateRole, vis?2:0);
+
+      // Children
+      std::map<std::string, int> actorTypeCounts;      
+      for (int iChild = 0; iChild < clickedParentItem->childCount(); iChild++) {
+        QTreeWidgetItem* currentChildItem = clickedParentItem->child(iChild);
+        std::string actorType = currentChildItem->data(1,Qt::UserRole).toString().toStdString();
+        vis = clickedSlicer->GetActorVisibility(actorType, actorTypeCounts[actorType]);
+        if(currentChildItem == clickedItem) {
+          // Toggle or force visibility if it was not on this branch so far
+          vis = !draw || !vis;
+          clickedSlicer->SetActorVisibility(actorType, actorTypeCounts[actorType], vis);
+        }
+        currentChildItem->setData(column, Qt::CheckStateRole, vis?2:0);
+        actorTypeCounts[actorType]++;
       }
     }
-    //mSlicerManagers[i]->SetColorMap(-1);
-    mSlicerManagers[i]->SetColorMap();
   }
-  mSlicerManagers[index]->GetSlicer(column-1)->Render();
+
+  clickedSlicer->Render();
 }
 //------------------------------------------------------------------------------
 
@@ -1567,15 +1567,18 @@ void vvMainWindow::ReloadImage(QTreeWidgetItem* item, int column)
   int index = GetSlicerIndexFromItem(item);
   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
   QString role=item->data(1,Qt::UserRole).toString();
-  if ( role == "vector")
+  if ( role == "vector"){
     mSlicerManagers[index]->ReloadVF();
-  else if (role == "overlay")
+  }
+  else if (role == "overlay"){
     mSlicerManagers[index]->ReloadOverlay();
-  else if (role == "fusion")
+  }
+  else if (role == "fusion"){
     mSlicerManagers[index]->ReloadFusion();
-  else
+  }
+  else{
     mSlicerManagers[index]->Reload();
-
+  }
   // Update view and info
   ImageInfoChanged();
   mSlicerManagers[index]->Render();
@@ -1612,26 +1615,52 @@ void vvMainWindow::FusionChanged(int visibility, double value)
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::WindowsChanged(int window, int view, int slice)
+void vvMainWindow::WindowLevelChanged()
 {
-  infoPanel->setViews(window, view, slice);
+  // Base image
+  int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+  if(index==-1) return;
+  windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
+  levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
+  colorMapComboBox->setCurrentIndex(mSlicerManagers[index]->GetColorMap());
+  presetComboBox->setCurrentIndex(mSlicerManagers[index]->GetPreset());
+
+  // Overlay image
+  if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay())
+    overlayPanel->getOverlayProperty(mSlicerManagers[index]->GetOverlayColor(),
+                                     mSlicerManagers[index]->GetLinkOverlayWindowLevel(),
+                                     mSlicerManagers[index]->GetOverlayColorWindow(),
+                                     mSlicerManagers[index]->GetOverlayColorLevel());
+  else
+    overlayPanel->getOverlayProperty(-1,0,0.,0.);
+
+  // Fusion image
+  if (mSlicerManagers[index]->GetSlicer(0)->GetFusion())
+    overlayPanel->getFusionProperty(mSlicerManagers[index]->GetFusionOpacity(),
+                                    mSlicerManagers[index]->GetFusionThresholdOpacity(),
+                                    mSlicerManagers[index]->GetFusionColorMap(),
+                                    mSlicerManagers[index]->GetFusionWindow(),
+                                    mSlicerManagers[index]->GetFusionLevel());
+  else
+    overlayPanel->getFusionProperty(-1, -1, -1, -1, -1);
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::WindowLevelChanged(double window, double level,int preset,int colormap)
+void vvMainWindow::WindowLevelEdited()
 {
-  windowSpinBox->setValue(window);
-  levelSpinBox->setValue(level);
-  colorMapComboBox->setCurrentIndex(colormap);
-  presetComboBox->setCurrentIndex(preset);
+  presetComboBox->setCurrentIndex(6);
+  UpdateWindowLevel();
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::WindowLevelEdited()
+void vvMainWindow::SetWindowLevel(double w, double l)
 {
+  windowSpinBox->setValue(w);
+  levelSpinBox->setValue(l);
   presetComboBox->setCurrentIndex(6);
+  colorMapComboBox->setCurrentIndex(0);
   UpdateWindowLevel();
 }
 //------------------------------------------------------------------------------
@@ -1647,8 +1676,7 @@ void vvMainWindow::UpdateWindowLevel()
     mSlicerManagers[index]->SetColorLevel(levelSpinBox->value());
     mSlicerManagers[index]->SetPreset(presetComboBox->currentIndex());
     mSlicerManagers[index]->Render();
-    windowSpinBox->setValue(mSlicerManagers[index]->GetColorWindow());
-    levelSpinBox->setValue(mSlicerManagers[index]->GetColorLevel());
+    WindowLevelChanged();
   }
 }
 //------------------------------------------------------------------------------
@@ -1801,13 +1829,11 @@ void vvMainWindow::AddOverlayImage(int index, QString file)
     item->setData(1,Qt::UserRole,tr("overlay"));
     QFileInfo fileinfo(file); //Do not show the path
     item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
-    item->setToolTip(COLUMN_IMAGE_NAME,fileinfo.absoluteFilePath());
+    item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("overlay").c_str());
     qApp->processEvents();
 
     for (int j = 1; j <= 4; j++) {
       item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
-      mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("overlay",0,
-          DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
     }
 
     //Create the buttons for reload and close
@@ -1846,6 +1872,7 @@ void vvMainWindow::AddOverlayImage(int index, QString file)
     error += mSlicerManagers[index]->GetLastError().c_str();
     QMessageBox::information(this,tr("Problem reading image !"),error);
   }
+  WindowLevelChanged();
 }
 //------------------------------------------------------------------------------
 
@@ -1900,6 +1927,16 @@ void vvMainWindow::SelectFusionImage()
 }
 //------------------------------------------------------------------------------
 
+//------------------------------------------------------------------------------
+void vvMainWindow::ResetTransformationToIdentity()
+{
+  std::string actorType = DataTree->selectedItems()[0]->data(1,Qt::UserRole).toString().toStdString();
+  int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+  mSlicerManagers[index]->ResetTransformationToIdentity(actorType);
+  ImageInfoChanged();
+}
+//------------------------------------------------------------------------------
+
 //------------------------------------------------------------------------------
 void vvMainWindow::AddFusionImage(int index, QString file)
 {
@@ -1923,13 +1960,11 @@ void vvMainWindow::AddFusionImage(int index, QString file)
       item->setData(1,Qt::UserRole,tr("fusion"));
       QFileInfo fileinfo(filename.c_str()); //Do not show the path
       item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
-      item->setToolTip(COLUMN_IMAGE_NAME,fileinfo.absoluteFilePath());
+      item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("fusion").c_str());
       qApp->processEvents();
 
       for (int j = 1; j <= 4; j++) {
         item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
-        mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("fusion",0,
-            DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
       }
 
       //Create the buttons for reload and close
@@ -1991,6 +2026,7 @@ void vvMainWindow::OpenField()
     }
 
   QString Extensions = "Images ( *.mhd)";
+  Extensions += ";;Images ( *.mha)";
   Extensions += ";;Images ( *.vf)";
   QString file = QFileDialog::getOpenFileName(this,tr("Load deformation field"),mInputPathName,Extensions);
   if (!file.isEmpty())
@@ -2008,13 +2044,11 @@ void vvMainWindow::AddFieldEntry(QString filename,int index,bool from_disk)
   item->setData(1,Qt::UserRole,tr("vector"));
   QFileInfo fileinfo(filename); //Do not show the path
   item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,fileinfo.fileName());
-  item->setToolTip(COLUMN_IMAGE_NAME,fileinfo.absoluteFilePath());
+  item->setToolTip(COLUMN_IMAGE_NAME, mSlicerManagers[index]->GetListOfAbsoluteFilePathInOneString("vector").c_str());
   qApp->processEvents();
 
   for (int j = 1; j <= 4; j++) {
     item->setData(j,Qt::CheckStateRole,DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole));
-    mSlicerManagers[index]->GetSlicer(j-1)->SetActorVisibility("vector",0,
-        DataTree->topLevelItem(index)->data(j,Qt::CheckStateRole).toInt());
   }
 
   //Create the buttons for reload and close
@@ -2122,24 +2156,28 @@ void vvMainWindow::SetVFProperty(int subsampling, int scale, int log, int width,
 
 
 //------------------------------------------------------------------------------
-void vvMainWindow::SetOverlayProperty(int color)
+void vvMainWindow::SetOverlayProperty(int color, int linked, double window, double level)
 {
   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
   if (mSlicerManagers[index]->GetSlicer(0)->GetOverlay()) {
     mSlicerManagers[index]->SetOverlayColor(color);
     mSlicerManagers[index]->SetColorMap(0);
+    mSlicerManagers[index]->SetLinkOverlayWindowLevel(linked);
+    mSlicerManagers[index]->SetOverlayColorWindow(window);
+    mSlicerManagers[index]->SetOverlayColorLevel(level);
     mSlicerManagers[index]->Render();
   }
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
-void vvMainWindow::SetFusionProperty(int opacity, int colormap,double window, double level)
+void vvMainWindow::SetFusionProperty(int opacity, int thresOpacity, int colormap,double window, double level)
 {
   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
   if (mSlicerManagers[index]->GetSlicer(0)->GetFusion()) {
-    mSlicerManagers[index]->SetFusionOpacity(opacity);
     mSlicerManagers[index]->SetFusionColorMap(colormap);
+    mSlicerManagers[index]->SetFusionOpacity(opacity);
+    mSlicerManagers[index]->SetFusionThresholdOpacity(thresOpacity);
     mSlicerManagers[index]->SetFusionWindow(window);
     mSlicerManagers[index]->SetFusionLevel(level);
     mSlicerManagers[index]->SetColorMap(0);
@@ -2169,14 +2207,17 @@ void vvMainWindow::SaveAs()
     OutputListeFormat.push_back(".jpeg");
     OutputListeFormat.push_back(".tif");
     OutputListeFormat.push_back(".mhd");
+    OutputListeFormat.push_back(".mha");
     OutputListeFormat.push_back(".hdr");
     OutputListeFormat.push_back(".vox");
   } else if (dimension == 3) {
     OutputListeFormat.push_back(".mhd");
+    OutputListeFormat.push_back(".mha");
     OutputListeFormat.push_back(".hdr");
     OutputListeFormat.push_back(".vox");
   } else if (dimension == 4) {
     OutputListeFormat.push_back(".mhd");
+    OutputListeFormat.push_back(".mha");
   }
   QString Extensions = "AllFiles(*.*)";
   for (int i = 0; i < OutputListeFormat.count(); i++) {
@@ -2226,7 +2267,7 @@ void vvMainWindow::AddLink(QString image1,QString image2)
 {
   unsigned int sm1 = 0;
   unsigned int sm2 = 0;
-  
+
   for (unsigned int i = 0; i < mSlicerManagers.size(); i++) {
     if (image1.toStdString() == mSlicerManagers[i]->GetId()) {
       mSlicerManagers[i]->AddLink(image2.toStdString());
@@ -2241,8 +2282,7 @@ void vvMainWindow::AddLink(QString image1,QString image2)
   if (linkPanel->isLinkAll())  {
     emit UpdateLinkedNavigation(mSlicerManagers[sm1]->GetId(), mSlicerManagers[mCurrentPickedImageIndex], mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(0));
     emit UpdateLinkedNavigation(mSlicerManagers[sm2]->GetId(), mSlicerManagers[mCurrentPickedImageIndex], mSlicerManagers[mCurrentPickedImageIndex]->GetSlicer(0));
-  }
-  else {
+  } else {
     emit UpdateLinkedNavigation(mSlicerManagers[sm2]->GetId(), mSlicerManagers[sm1], mSlicerManagers[sm1]->GetSlicer(0));
   }
 }
@@ -2273,8 +2313,8 @@ void vvMainWindow::ChangeImageWithIndexOffset(vvSlicerManager *sm, int slicer, i
   index = (index+offset) % mSlicerManagers.size();
 
   QTreeWidgetItem* item = GetItemFromSlicerManager(mSlicerManagers[index]);
-  //CurrentImageChanged(mSlicerManagers[index]->GetId()); //select new image
   item->setData(slicer+1,Qt::CheckStateRole,2);         //change checkbox
+  CurrentImageChanged(mSlicerManagers[index]->GetId()); //select new image
   DisplayChanged(item,slicer+1);
 }
 //------------------------------------------------------------------------------
@@ -2479,27 +2519,22 @@ void vvMainWindow::UpdateTSlice(int slicer, int slice)
 void vvMainWindow::UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax)
 {
   int position = int((min+max)/2);
-  int tPosition = int((tmin+tmax)/2);
   if (slicer == 0) {
     NOVerticalSlider->setValue(position);
     NOVerticalSlider->setRange(min,max);
     NOHorizontalSlider->setRange(tmin,tmax);
-    NOHorizontalSlider->setValue(tPosition);
   } else if (slicer == 1) {
     NEVerticalSlider->setValue(position);
     NEVerticalSlider->setRange(min,max);
     NEHorizontalSlider->setRange(tmin,tmax);
-    NEHorizontalSlider->setValue(tPosition);
   } else if (slicer == 2) {
     SOVerticalSlider->setValue(position);
     SOVerticalSlider->setRange(min,max);
     SOHorizontalSlider->setRange(tmin,tmax);
-    SOHorizontalSlider->setValue(tPosition);
   } else if (slicer == 3) {
     SEVerticalSlider->setValue(position);
     SEVerticalSlider->setRange(min,max);
     SEHorizontalSlider->setRange(tmin,tmax);
-    SEHorizontalSlider->setValue(tPosition);
   }
 }
 //------------------------------------------------------------------------------
@@ -2606,8 +2641,7 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget)
 
       vvImage * vvImg = mSlicerManagers[smIndex]->GetImage();
       int nSlice = vvImg->GetVTKImages().size();
-      for(int i=0; i<nSlice; i++)
-      {
+      for(int i=0; i<nSlice; i++) {
         mSlicerManagers[smIndex]->SetNextTSlice(0);
         vtkSmartPointer<vtkWindowToImageFilter> w2i = vtkSmartPointer<vtkWindowToImageFilter>::New();
         w2i->SetInput(widget->GetRenderWindow());
@@ -2627,8 +2661,7 @@ void vvMainWindow::SaveScreenshot(QVTKWidget *widget)
 
       vvImage * vvImg = mSlicerManagers[smIndex]->GetImage();
       int nSlice = vvImg->GetVTKImages().size();
-      for(int i=0; i<nSlice; i++)
-      {
+      for(int i=0; i<nSlice; i++) {
         mSlicerManagers[smIndex]->SetNextTSlice(0);
         vtkSmartPointer<vtkWindowToImageFilter> w2i = vtkSmartPointer<vtkWindowToImageFilter>::New();
         w2i->SetInput(widget->GetRenderWindow());
@@ -2778,6 +2811,7 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen
   //create an item in the tree with good settings
   QTreeWidgetItem *item = new QTreeWidgetItem();
   item->setData(0,Qt::UserRole,slicer_manager->GetFileName().c_str());//files[i].c_str());
+  item->setData(1,Qt::UserRole,tr("image"));
   item->setData(COLUMN_IMAGE_NAME,Qt::DisplayRole,slicer_manager->GetFileName().c_str());//filename.c_str());
   qApp->processEvents();
 
@@ -2824,10 +2858,8 @@ vvSlicerManager* vvMainWindow::AddImage(vvImage::Pointer image,std::string filen
           this, SLOT(OverlayChanged(int,double,double)));
   connect(mSlicerManagers.back(), SIGNAL(UpdateFusion(int, double)),
           this, SLOT(FusionChanged(int,double)));
-  connect(mSlicerManagers.back(), SIGNAL(UpdateWindows(int, int, int)),
-          this,SLOT(WindowsChanged(int, int, int)));
-  connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged(double, double,int, int)),
-          this,SLOT(WindowLevelChanged(double, double, int, int)));
+  connect(mSlicerManagers.back(), SIGNAL(WindowLevelChanged()),
+          this,SLOT(WindowLevelChanged()));
   connect(mSlicerManagers.back(), SIGNAL(UpdateSlice(int,int)),
           this,SLOT(UpdateSlice(int,int)));
   connect(mSlicerManagers.back(), SIGNAL(UpdateTSlice(int, int)),
index d95e7fa166e0468f68e12ee24b8f910e205293fb..8ee5ab26178adf4d421514e1c9a8a147c79765b9 100644 (file)
@@ -87,6 +87,7 @@ public slots:
   void ImageInfoChanged();
   void ShowHelpDialog();
   void ShowDocumentation();
+  void PopupRegisterForm(bool checkCanPush=false);
   void ComputeDeformableRegistration();
   void WarpImage();
   void ChangeViewMode();
@@ -100,12 +101,12 @@ public slots:
   void SegmentationOnCurrentImage();
   void SurfaceViewerLaunch();
 
-  void WindowsChanged(int window, int view, int slice);
-  void WindowLevelChanged(double window, double level,int preset, int colormap);
+  void WindowLevelChanged();
   void UpdateSlice(int slicer, int slice);
   void UpdateTSlice(int slicer, int slice);
   void UpdateSliceRange(int slicer, int min, int max, int tmin, int tmax);
   void WindowLevelEdited();
+  void SetWindowLevel(double w, double l);
   void UpdateColorMap();
   void UpdateWindowLevel();
   void SwitchWindowLevel();
@@ -139,10 +140,11 @@ public slots:
   void OpenField();
   void SelectOverlayImage();
   void SelectFusionImage();
+  void ResetTransformationToIdentity();
 
   void SetVFProperty(int subsampling,int scale,int lut, int width, double r, double g, double b);
-  void SetOverlayProperty(int color);
-  void SetFusionProperty(int opacity,int colormap,double window,double level);
+  void SetOverlayProperty(int color, int linked, double window, double level);
+  void SetFusionProperty(int opacity, int tresOpacity, int colormap,double window,double level);
 
   void GoToCursor();
   void PlayPause();
@@ -152,7 +154,13 @@ public slots:
   }
   void UpdateRenderWindows();
   void UpdateMemoryUsage();
-
+  void show();
+  
+protected:
+  
+  void createRecentlyOpenedFilesMenu();
+  void updateRecentlyOpenedFilesMenu(const std::list<std::string> &files);
+  
 private:
 
   //variables
@@ -184,6 +192,7 @@ private:
   int GetImageDuplicateFilenameNumber(std::string filename);
 
   QMenu contextMenu;
+  QMenu* recentlyOpenedFilesMenu;
   //QMenu *AddSubImageMenu;
   std::vector<QAction*> contextActions;
   std::vector<QSlider*> horizontalSliders;
@@ -203,6 +212,4 @@ private:
   
 };
 
-#include "vvMainWindow.txx"
-
 #endif
index 72ed60da872019c2021457befad5b9aa216b335f..5b11d48e2d65e1a0bc8a9edb52384127a7e4c55d 100644 (file)
@@ -141,6 +141,7 @@ void vvMesh::ComputeMasks(vtkImageData* sample,bool extrude)
     double * samp_origin=sample->GetOrigin();
     double * spacing=sample->GetSpacing();
     binary_image->SetSpacing(spacing);
+
     /// Put the origin on a voxel to avoid small skips
     binary_image->SetOrigin(floor((bounds[0]-samp_origin[0])/spacing[0]-2)*spacing[0]+samp_origin[0],
                             floor((bounds[2]-samp_origin[1])/spacing[1]-2)*spacing[1]+samp_origin[1],
@@ -173,10 +174,13 @@ void vvMesh::ComputeMasks(vtkImageData* sample,bool extrude)
     stencil->SetInput(binary_image);
     stencil->Update();
     this->AddMask(stencil->GetOutput());
-    //vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
-    //w->SetInput(stencil->GetOutput());
-    //w->SetFileName("binary.mhd");
-    //w->Write();
+
+    /*
+      vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
+      w->SetInput(stencil->GetOutput());
+      w->SetFileName("binary.mhd");
+      w->Write();
+    */
   }
 }
 
index fb0baf47a10c0edd5cd9ef7edb01dbab36db1bf6..1da14a15b4e6eabd5f9eed4e1d307917b9b05273 100644 (file)
@@ -137,6 +137,90 @@ std::vector<vvMesh::Pointer> vvMeshReader::readSelectedContours()
 {
   std::vector<vvMesh::Pointer> result;
 #if GDCM_MAJOR_VERSION == 2
+  gdcm::Reader reader;
+  reader.SetFileName(filename.c_str());
+  reader.Read();
+
+  const gdcm::DataSet &ds = reader.GetFile().GetDataSet();
+
+  gdcm::SmartPointer<gdcm::SequenceOfItems> rois = ds.GetDataElement(gdcm::Tag(0x3006,0x39)).GetValueAsSQ();
+  gdcm::SmartPointer<gdcm::SequenceOfItems> roi_info = ds.GetDataElement(gdcm::Tag(0x3006,0x20)).GetValueAsSQ();
+  assert(rois); // TODO error message
+  assert(roi_info); // TODO error message
+  assert(rois->GetNumberOfItems() == roi_info->GetNumberOfItems());
+
+  for (unsigned ridx = 0; ridx < rois->GetNumberOfItems(); ++ridx)
+  {
+    vtkSmartPointer<vtkAppendPolyData> append=vtkSmartPointer<vtkAppendPolyData>::New();
+    const gdcm::DataSet& ds_rois = rois->GetItem( ridx + 1).GetNestedDataSet();
+    const gdcm::DataSet& ds_roi_info = roi_info->GetItem( ridx + 1).GetNestedDataSet();
+
+    gdcm::Attribute<0x3006,0x84> roinumber;
+    roinumber.SetFromDataSet(ds_rois);
+    if (std::find(selected_contours.begin(), selected_contours.end(), roinumber.GetValue()) != selected_contours.end()) //Only read selected ROIs
+    {
+      gdcm::Attribute<0x3006,0x2a> trgb;
+      trgb.SetFromDataSet(ds_rois);
+      vvMesh::Pointer current_roi=vvMesh::New();
+      current_roi->r = trgb[0] / 255;
+      current_roi->g = trgb[1] / 255;
+      current_roi->b = trgb[2] / 255;
+
+      gdcm::Attribute<0x3006,0x26> tstructure_name;
+      tstructure_name.SetFromDataSet(ds_roi_info);
+      current_roi->structure_name = tstructure_name.GetValue();
+
+      gdcm::SmartPointer<gdcm::SequenceOfItems> roi_seq = ds_rois.GetDataElement(gdcm::Tag(0x3006,0x40)).GetValueAsSQ();
+      double z0=-1; //Used to determine spacing between slices, assumed to be constant
+      for (unsigned j = 0; j < roi_seq->GetNumberOfItems(); ++j)
+      {
+        gdcm::Item & item_roi_seq = roi_seq->GetItem(j + 1); // Item starts at 1
+        const gdcm::DataSet& ds_roi_seq = item_roi_seq.GetNestedDataSet();
+        gdcm::Attribute<0x3006,0x42> tcontour_type;
+        tcontour_type.SetFromDataSet(ds_roi_seq);
+        std::string contour_type = tcontour_type.GetValue();
+        if (contour_type=="CLOSED_PLANAR ")
+        {
+          gdcm::Attribute<0x3006,0x46> tpoint_number;
+          tpoint_number.SetFromDataSet(ds_roi_seq);
+          const gdcm::DataElement & points_data = ds_roi_seq.GetDataElement(gdcm::Tag(0x3006,0x50));
+          gdcm::Attribute<0x3006,0x50> tpoints;
+          tpoints.SetFromDataElement(points_data);
+          assert(tpoints.GetNumberOfValues() == static_cast<unsigned int>(tpoint_number.GetValue()) * 3);
+          const double* points = tpoints.GetValues();
+          if (z0 == -1) //First contour
+            z0=points[2];
+          else
+            if (current_roi->GetSpacing()==-1 && points[2] != z0 )
+              current_roi->SetSpacing(points[2]-z0);
+          vtkPolyData * contour=vtkPolyData::New();
+          contour->Allocate(); //for cell structures
+          contour->SetPoints(vtkPoints::New());
+          vtkIdType ids[2];
+          for (unsigned idx = 0; idx < tpoints.GetNumberOfValues(); idx += 3)
+          {
+            contour->GetPoints()->InsertNextPoint(points[idx], points[idx+1], points[idx+2]);
+            ids[0] = idx / 3;
+            ids[1] = (ids[0] + 1) % tpoint_number.GetValue(); //0-1,1-2,...,n-1-0
+            contour->GetLines()->InsertNextCell(2, ids);
+          }
+          append->AddInput(contour);
+        }
+        else
+          if (contour_type == "POINT ")
+          ; // silently ignore POINT type since we don't need them at the moment
+          else
+            std::cerr << "Warning: contour type " << contour_type << " not handled!" << std::endl;
+      }
+      append->Update();
+      current_roi->AddMesh(append->GetOutput());
+      result.push_back(current_roi);
+    }
+    else
+    {
+    //std::cerr << "Warning: ignoring ROI #" << roi_number << std::endl;
+    }
+  }
 #else
   gdcm::File reader;
   reader.SetFileName(filename.c_str());
index 88b176d360194d3406b462629225fde3be1f48f8..b4582e2275cb52ae8a59375329b537eda3fcfb11 100644 (file)
@@ -108,7 +108,11 @@ vvImage::Pointer WarpRefImage(OutputVFType::Pointer vf,vvImage::Pointer image,in
 
   typename FilterType::Pointer warp_filter = FilterType::New();
   warp_filter->SetInput(input);
+#if ITK_VERSION_MAJOR >= 4
+  warp_filter->SetDisplacementField(resampler->GetOutput());
+#else
   warp_filter->SetDeformationField(resampler->GetOutput());
+#endif
   warp_filter->SetOutputSpacing(input->GetSpacing());
   warp_filter->SetOutputOrigin(input->GetOrigin());
   warp_filter->SetOutputSize(input->GetLargestPossibleRegion().GetSize());
index 843e46d97598b54f108b0f1bfdd6dcae10c02315..eb2eaa1c7b2d27950d27551ea8943884fb366f8d 100644 (file)
@@ -45,9 +45,15 @@ vvOverlayPanel::vvOverlayPanel(QWidget * parent):QWidget(parent)
   connect(vfColorButton,SIGNAL(clicked()),this,SLOT(VFColorChangeRequest()));
   connect(colorHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(setOverlayProperty()));
   connect(opacityHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(setFusionProperty()));
+  connect(thresOpacityHorizontalSlider,SIGNAL(valueChanged(int)),this,SLOT(setFusionProperty()));
   connect(fusionColorMapComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(setFusionProperty()));
-  connect(windowSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setFusionProperty()));
-  connect(levelSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setFusionProperty()));
+  connect(fusionWindowSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setFusionProperty()));
+  connect(fusionLevelSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setFusionProperty()));
+  connect(overlayWindowSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setOverlayProperty()));
+  connect(overlayLevelSpinBox,SIGNAL(valueChanged(double)),this,SLOT(setOverlayProperty()));
+  connect(overlayLinkCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setOverlayProperty()));
+
+  disableFusionSignals = false;
 }
 
 void vvOverlayPanel::getCurrentImageName(QString name)
@@ -122,13 +128,16 @@ void vvOverlayPanel::getOverlayName(QString name)
   imageComparedLabel->setText(filename.toStdString().c_str());
 }
 
-void vvOverlayPanel::getOverlayProperty(int value)
+void vvOverlayPanel::getOverlayProperty(int color, int linked, double window, double level)
 {
-  if (value > -1) {
+  if (color > -1) {
     compareFrame->show();
     compareFrame->setEnabled(1);
     colorHorizontalSlider->setEnabled(1);
-    colorHorizontalSlider->setValue(value);
+    colorHorizontalSlider->setValue(color);
+    overlayLinkCheckBox->setCheckState( (linked)?Qt::Checked:Qt::Unchecked );
+    overlayWindowSpinBox->setValue(window);
+    overlayLevelSpinBox->setValue(level);
   } else {
     compareFrame->hide();
     compareFrame->setEnabled(0);
@@ -139,7 +148,12 @@ void vvOverlayPanel::getOverlayProperty(int value)
 
 void vvOverlayPanel::setOverlayProperty()
 {
-  emit OverlayPropertyUpdated(colorHorizontalSlider->value());
+  overlayWindowSpinBox->setEnabled(!overlayLinkCheckBox->checkState());
+  overlayLevelSpinBox->setEnabled(!overlayLinkCheckBox->checkState());
+  emit OverlayPropertyUpdated(colorHorizontalSlider->value(),
+                              overlayLinkCheckBox->checkState(),
+                              overlayWindowSpinBox->value(),
+                              overlayLevelSpinBox->value());
 }
 
 void vvOverlayPanel::getCurrentOverlayInfo(int visibility,double valueOver, double valueRef)
@@ -163,35 +177,48 @@ void vvOverlayPanel::getFusionName(QString name)
   dataFusionnedLabel->setText(filename.toStdString().c_str());
 }
 
-void vvOverlayPanel::getFusionProperty(int opacity, int colormap, double window, double level)
+void vvOverlayPanel::getFusionProperty(int opacity, int thresOpacity, int colormap, double window, double level)
 {
   if (opacity > -1) {
+    //first disable signals generated by each setValue() call
+    disableFusionSignals = true;
     fusionFrame->show();
     fusionFrame->setEnabled(1);
-    opacityHorizontalSlider->setEnabled(1);
-    opacityHorizontalSlider->setValue(opacity);
     fusionColorMapComboBox->setEnabled(1);
     fusionColorMapComboBox->setCurrentIndex(colormap);
-    windowSpinBox->setEnabled(1);
-    levelSpinBox->setEnabled(1);
-    windowSpinBox->setValue(window);
-    levelSpinBox->setValue(level);
+    opacityHorizontalSlider->setEnabled(1);
+    opacityHorizontalSlider->setValue(opacity);
+    thresOpacityHorizontalSlider->setEnabled(1);
+    thresOpacityHorizontalSlider->setValue(thresOpacity);
+    fusionWindowSpinBox->setEnabled(1);
+    fusionLevelSpinBox->setEnabled(1);
+    fusionWindowSpinBox->setValue(window);
+    fusionLevelSpinBox->setValue(level);
+    
+    // re-enable signals and trigger slot function
+    disableFusionSignals = false;
+    setFusionProperty();
   } else {
     fusionFrame->hide();
     fusionFrame->setEnabled(0);
     opacityHorizontalSlider->setEnabled(0);
     opacityHorizontalSlider->setValue(0);
+    thresOpacityHorizontalSlider->setEnabled(0);
+    thresOpacityHorizontalSlider->setValue(0);
     fusionColorMapComboBox->setEnabled(0);
     fusionColorMapComboBox->setCurrentIndex(-1);
-    windowSpinBox->setEnabled(0);
-    levelSpinBox->setEnabled(0);
+    fusionWindowSpinBox->setEnabled(0);
+    fusionLevelSpinBox->setEnabled(0);
   }
 }
 
 void vvOverlayPanel::setFusionProperty()
 {
-  emit FusionPropertyUpdated(opacityHorizontalSlider->value(), fusionColorMapComboBox->currentIndex(),
-                             windowSpinBox->value(), levelSpinBox->value());
+  if (disableFusionSignals)
+    return;
+  
+  emit FusionPropertyUpdated(opacityHorizontalSlider->value(), thresOpacityHorizontalSlider->value(), fusionColorMapComboBox->currentIndex(),
+                             fusionWindowSpinBox->value(), fusionLevelSpinBox->value());
 }
 
 void vvOverlayPanel::getCurrentFusionInfo(int visibility,double value)
index 0b867bc27a2458d5d3fb060a07663609a4d201ee..63bad7bc633c3461ad19d39e1b3b5f51ab2342b5 100644 (file)
@@ -38,10 +38,10 @@ public:
     void getVFProperty(int subsampling, int scale, int log);
     void getVFName(QString name);
 
-    void getOverlayProperty(int color);
+    void getOverlayProperty(int color, int linked, double window, double level);
     void getOverlayName(QString name);
 
-    void getFusionProperty(int opacity, int colormap, double window, double level);
+    void getFusionProperty(int opacity, int thresOpacity, int colormap, double window, double level);
     void getFusionName(QString name);
 
     void getCurrentVectorInfo(int visibility, double x, double y, double z, double value);
@@ -56,8 +56,13 @@ public slots:
 
 signals:
     void VFPropertyUpdated(int subsampling, int scale, int log, int width, double r, double g, double b);
-    void OverlayPropertyUpdated(int color);
-    void FusionPropertyUpdated(int opacity, int colormap, double window, double level);
+    void OverlayPropertyUpdated(int color, int linked, double window, double level);
+    void FusionPropertyUpdated(int opacity, int thresOpacity, int colormap, double window, double level);
+
+    
+private:
+    bool disableFusionSignals;
+    
 }; // end class vvOverlayPanel
 //====================================================================
 
diff --git a/vv/vvRegisterForm.cxx b/vv/vvRegisterForm.cxx
new file mode 100644 (file)
index 0000000..112330a
--- /dev/null
@@ -0,0 +1,73 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to:
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#include <QApplication>
+
+#include "vvRegisterForm.h"
+#include <QNetworkRequest>
+#include <QDir>
+#include <QPalette>
+#include "clitkConfiguration.h"
+#include "vvConfiguration.h"
+#include "vvUtils.h"
+
+vvRegisterForm::vvRegisterForm(QUrl url, QString path, QSettings::Format format):url(url), settings(path, format){ 
+  manager = new QNetworkAccessManager(this);
+  setupUi(this);
+  textBrowser->viewport()->setAutoFillBackground(false);
+}
+
+void vvRegisterForm::sendData(){
+  QUrl url2(url);
+  url2.addQueryItem("name", firstName->text().toUtf8());
+  url2.addQueryItem("lastName", lastName->text().toUtf8());
+  url2.addQueryItem("email", email->text().toUtf8());
+  url2.addQueryItem("group", group->text().toUtf8());
+  url2.addQueryItem("os", OS_NAME);
+  url2.addQueryItem("vvVersion", VV_VERSION);
+  url2.addQueryItem("architecture", ARCHITECTURE);
+  url2.addQueryItem("adressing", QString::number(sizeof(char*)*8)+"-bit");
+  url2.addQueryItem("compilationDate", QString(__DATE__) + ", " + QString(__TIME__) );
+
+  manager->get(QNetworkRequest(url2));
+}
+void vvRegisterForm::accept(){
+  sendData();
+  settings.setValue("name", firstName->text().toUtf8());
+  settings.setValue("lastName", lastName->text().toUtf8());
+  settings.setValue("email", email->text().toUtf8());
+  settings.setValue("group", group->text().toUtf8());
+  settings.setValue("os", osName->text().toUtf8());
+  QDialog::accept();
+}
+bool vvRegisterForm::canPush(){
+  ///maybe we show this dialog only for new major release, not for any patches?
+  return settings.value("vvVersion").toString().toStdString()<VV_VERSION;
+}
+void vvRegisterForm::acquitPushed(){
+  settings.setValue("vvVersion", VV_VERSION);
+}
+void vvRegisterForm::show(){
+ firstName->setText(settings.value("name").toString());
+ lastName->setText(settings.value("lastName").toString()); 
+ email->setText(settings.value("email").toString()); 
+ group->setText(settings.value("group").toString()); 
+ osName->setText(QString::fromStdString(OS_NAME) + ", " +
+                 ARCHITECTURE + ", " +
+                 QString::number(sizeof(char*)*8)+"-bit");
+ QDialog::show();
+}
diff --git a/vv/vvRegisterForm.h b/vv/vvRegisterForm.h
new file mode 100644 (file)
index 0000000..ab41f39
--- /dev/null
@@ -0,0 +1,44 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+===========================================================================**/
+#ifndef vvRegisterForm_h
+#define vvRegisterForm_h
+
+#include "ui_vvRegisterForm.h"
+#include <QUrl>
+#include <QSettings>
+#include <QNetworkAccessManager>
+class vvRegisterForm : public QDialog, private Ui::vvRegisterForm
+{
+    Q_OBJECT
+
+public:
+    vvRegisterForm(QUrl url, QString path, QSettings::Format format);
+    void sendData();
+    ~vvRegisterForm() {}
+    virtual bool canPush();
+    virtual void acquitPushed();
+public slots:
+  virtual void accept();
+  virtual void show();
+protected:
+  QUrl url;
+  QSettings settings;
+  QNetworkAccessManager* manager;
+};
+
+#endif
index 9809b06ddc771b574d4de2923c2a750ad11e1f67..2473c87e27c3ca8dd84b33c047d199bea685f7b3 100644 (file)
 #include <vtkImageAccumulate.h>
 #include <vtkImageReslice.h>
 
-// template <class T, unsigned int dim>
-// void print_vector(const char* pmsg, T* pvec)
-// {
-//   std::cout << pmsg << ": ";
-//   for (unsigned int i = 0; i < dim; i++)
-//     std::cout << pvec[i] << " ";
-//   std::cout << std::endl;
-// }
-
-
 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
 vtkStandardNewMacro(vvSlicer);
-
+static void copyExtent(int* in, int* to){
+ for(int i=0; i<6; ++i) to[i]=in[i]; 
+}
 //------------------------------------------------------------------------------
 vvSlicer::vvSlicer()
 {
   this->UnInstallPipeline();
   mImage = NULL;
+  mReducedExtent = new int[6];
   mCurrentTSlice = 0;
   mUseReducedExtent = false;
 
@@ -105,22 +98,6 @@ vvSlicer::vvSlicer()
   mVFColor[1] = 1;
   mVFColor[2] = 0;
 
-  std::string text = "F1 = sagital; F2 = coronal; F3 = axial\n";
-  text += "F5 = horizontal flip; F6 = vertical flip\n\n";
-  text += "0,1,2,3,4,5 : preset windowing\n";
-  text += "6,7,8,9 : preset colormap\n";
-  text += "z : local windowing\n";
-  text += "r : reset view\n";
-  text += "l : reload image\n";
-  text += "f : fly to mouse position\n";
-  text += "g : go to cross hair position\n\n";
-  text += "Up,down : change slice\n";
-  text += "Left,right : change tenporal slice\n\n";
-  text += "Scrollbar (or w/x) : zoom in/out\n";
-  text += "left button : synchronize all views\n";
-  text += "middle button : grab image\n";
-  text += "right button : change windowing\n";
-
   crossCursor = vtkSmartPointer<vtkCursor2D>::New();
   crossCursor->AllOff();
   crossCursor->AxesOn();
@@ -158,6 +135,8 @@ vvSlicer::vvSlicer()
   this->WindowLevel = vvImageMapToWLColors::New();
 
   this->InstallPipeline();
+
+  mLinkOverlayWindowLevel = true;
 }
 //------------------------------------------------------------------------------
 
@@ -179,7 +158,7 @@ vvBlendImageActor* vvSlicer::GetOverlayActor()
 
 
 //------------------------------------------------------------------------------
-vtkImageMapToWindowLevelColors* vvSlicer::GetFusionMapper()
+vtkImageMapToColors* vvSlicer::GetFusionMapper()
 {
   return mFusionMapper.GetPointer();
 }
@@ -221,7 +200,7 @@ void vvSlicer::EnableReducedExtent(bool b)
 //------------------------------------------------------------------------------
 void vvSlicer::SetReducedExtent(int * ext)
 {
-  mReducedExtent = ext;
+  copyExtent(ext, mReducedExtent);
 }
 //------------------------------------------------------------------------------
 
@@ -299,6 +278,7 @@ vvSlicer::~vvSlicer()
   for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
        i!=mSurfaceCutActors.end(); i++)
     delete (*i);
+  delete [] mReducedExtent;
 }
 //------------------------------------------------------------------------------
 
@@ -337,7 +317,7 @@ void vvSlicer::SetImage(vvImage::Pointer image)
 
     // Prevent crash when reload -> change slice if outside extent
     if (Slice < extent[SliceOrientation*2] || Slice>=extent[SliceOrientation*2+1]) {
-      Slice = (extent[SliceOrientation*2+1]-extent[SliceOrientation*2])/2.0;
+      Slice = (extent[SliceOrientation*2+1]+extent[SliceOrientation*2])/2.0;
     }
 
     // Make sure that the required part image has been computed
@@ -378,7 +358,7 @@ void vvSlicer::SetOverlay(vvImage::Pointer overlay)
       mOverlayActor = vtkSmartPointer<vvBlendImageActor>::New();
       mOverlayActor->SetInput(mOverlayMapper->GetOutput());
       mOverlayActor->SetPickable(0);
-      mOverlayActor->SetVisibility(false);
+      mOverlayActor->SetVisibility(true);
       mOverlayActor->SetOpacity(0.5);
     }
 
@@ -391,7 +371,8 @@ void vvSlicer::SetOverlay(vvImage::Pointer overlay)
       this->GetRenderer()->AddActor(mOverlayActor);
 
     //Synchronize orientation and slice
-    this->SetSliceOrientation(this->SliceOrientation);
+    AdjustResliceToSliceOrientation(mOverlayReslice);
+    this->UpdateDisplayExtent();
     this->SetTSlice(mCurrentTSlice);
   }
 }
@@ -414,45 +395,78 @@ void vvSlicer::SetFusion(vvImage::Pointer fusion)
     mFusionReslice->SetInput(0, mFusion->GetFirstVTKImageData());
 
     if (!mFusionMapper)
-      mFusionMapper = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
+      mFusionMapper = vtkSmartPointer<vtkImageMapToColors>::New();
+    
+    vtkSmartPointer<vtkLookupTable> lut = vtkLookupTable::New();
+    lut->SetRange(0, 1);
+    lut->SetValueRange(0, 1);
+    lut->SetSaturationRange(0, 0);
+    lut->Build();
+    mFusionMapper->SetLookupTable(lut);
     mFusionMapper->SetInput(mFusionReslice->GetOutput());
 
     if (!mFusionActor) {
       mFusionActor = vtkSmartPointer<vtkImageActor>::New();
       mFusionActor->SetInput(mFusionMapper->GetOutput());
       mFusionActor->SetPickable(0);
-      mFusionActor->SetVisibility(false);
+      mFusionActor->SetVisibility(true);
       mFusionActor->SetOpacity(0.7);
       this->GetRenderer()->AddActor(mFusionActor);
     }
 
     //Synchronize orientation and slice
-    this->SetSliceOrientation(this->SliceOrientation);
+    AdjustResliceToSliceOrientation(mFusionReslice);
+    this->UpdateDisplayExtent();
     this->SetTSlice(mCurrentTSlice);
   }
 }
 //------------------------------------------------------------------------------
 
 
+//------------------------------------------------------------------------------
+bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_index)
+{
+  bool vis = false;
+  if (actor_type == "image") {
+    vis = this->ImageActor->GetVisibility();
+  }
+  else if (actor_type == "vector") {
+    vis = this->mVFActor->GetVisibility();
+  }
+  else if (actor_type == "overlay") {
+    vis = this->mOverlayActor->GetVisibility();
+  }
+  else if (actor_type == "fusion") {
+    vis = this->mFusionActor->GetVisibility();
+  }
+  else if (actor_type == "contour")
+    vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility();
+
+  return vis;
+}
+//------------------------------------------------------------------------------
+
 //------------------------------------------------------------------------------
 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
 {
-  if (actor_type == "vector") {
+  if (actor_type == "image") {
+    this->ImageActor->SetVisibility(vis);
+  }
+  else if (actor_type == "vector") {
     this->mVFActor->SetVisibility(vis);
   }
-  if (actor_type == "overlay") {
+  else if (actor_type == "overlay") {
     this->mOverlayActor->SetVisibility(vis);
   }
-  if (actor_type == "fusion") {
+  else if (actor_type == "fusion") {
     this->mFusionActor->SetVisibility(vis);
   }
-  if (actor_type == "contour")
+  else if (actor_type == "contour")
     this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
   UpdateDisplayExtent();
 }
 //------------------------------------------------------------------------------
 
-
 //------------------------------------------------------------------------------
 void vvSlicer::SetVF(vvImage::Pointer vf)
 {
@@ -767,12 +781,12 @@ void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice)
   reslice->SetOutputOrigin(origin);
   reslice->SetOutputSpacing(spacing);
   reslice->UpdateInformation();
+  reslice->GetOutput()->UpdateInformation();
 }
 //------------------------------------------------------------------------------
 
 //----------------------------------------------------------------------------
-int * vvSlicer::GetExtent()
-{
+int * vvSlicer::GetExtent(){
   int *w_ext;
   if (mUseReducedExtent) {
     w_ext = mReducedExtent;
@@ -801,13 +815,7 @@ void vvSlicer::UpdateDisplayExtent()
 
   // Local copy of extent
   int w_ext[6];
-  for(unsigned int i=0; i<6; i++){
-    if (mUseReducedExtent)
-      w_ext[i] = mReducedExtent[i];
-    else  
-      w_ext[i] = input->GetWholeExtent()[i];
-  }
-
+  copyExtent(GetExtent(), w_ext);
   // Set slice value
   w_ext[ this->SliceOrientation*2   ] = this->Slice;
   w_ext[ this->SliceOrientation*2+1 ] = this->Slice;
@@ -817,8 +825,8 @@ void vvSlicer::UpdateDisplayExtent()
   
   // Overlay image actor
   if (mOverlay && mOverlayActor->GetVisibility()) {
+    AdjustResliceToSliceOrientation(mOverlayReslice);
     int overExtent[6];
-    mOverlayReslice->GetOutput()->UpdateInformation();
     this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent);
     ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
     mOverlayActor->SetDisplayExtent( overExtent );
@@ -826,8 +834,8 @@ void vvSlicer::UpdateDisplayExtent()
 
   // Fusion image actor
   if (mFusion && mFusionActor->GetVisibility()) {
+    AdjustResliceToSliceOrientation(mFusionReslice);
     int fusExtent[6];
-    mFusionReslice->GetOutput()->UpdateInformation();
     this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent);
     ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
     mFusionActor->SetDisplayExtent(fusExtent);
@@ -1040,12 +1048,7 @@ void vvSlicer::ResetCamera()
 //----------------------------------------------------------------------------
 void vvSlicer::SetDisplayMode(bool i)
 {
-  this->GetImageActor()->SetVisibility(i);
-  this->GetAnnotation()->SetVisibility(i);
   this->GetRenderer()->SetDraw(i);
-  if (mLandActor)
-    mLandActor->SetVisibility(i);
-  pdmA->SetVisibility(i);
   if (i)
     UpdateDisplayExtent();
 }
@@ -1058,7 +1061,11 @@ void vvSlicer::FlipHorizontalView()
   vtkCamera *cam = this->Renderer ? this->Renderer->GetActiveCamera() : NULL;
   if (cam) {
     double *position = cam->GetPosition();
-    switch (this->SliceOrientation) {
+    double factor[3] = {1, 1, 1};
+    factor[this->SliceOrientation] = -1;
+    cam->SetPosition(factor[0]*position[0],factor[1]*position[1],factor[2]*position[2]);
+    
+/*    switch (this->SliceOrientation) {
     case vtkImageViewer2::SLICE_ORIENTATION_XY:
       cam->SetPosition(position[0],position[1],-position[2]);
       break;
@@ -1070,7 +1077,8 @@ void vvSlicer::FlipHorizontalView()
     case vtkImageViewer2::SLICE_ORIENTATION_YZ:
       cam->SetPosition(-position[0],position[1],position[2]);
       break;
-    }
+    }*/
+
     this->Renderer->ResetCameraClippingRange();
     this->UpdateDisplayExtent();
   }
@@ -1105,7 +1113,6 @@ void vvSlicer::SetColorWindow(double window)
 }
 //----------------------------------------------------------------------------
 
-
 //----------------------------------------------------------------------------
 void vvSlicer::SetColorLevel(double level)
 {
@@ -1119,9 +1126,43 @@ void vvSlicer::SetColorLevel(double level)
 }
 //----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
+double vvSlicer::GetOverlayColorWindow()
+{
+  if(mOverlayMapper)
+    return mOverlayMapper->GetWindow();
+  else
+    return 0.;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+double vvSlicer::GetOverlayColorLevel()
+{
+  if(mOverlayMapper)
+    return mOverlayMapper->GetLevel();
+  else
+    return 0.;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicer::SetOverlayColorWindow(double window)
+{
+  mOverlayMapper->SetWindow(window);
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicer::SetOverlayColorLevel(double level)
+{
+  mOverlayMapper->SetLevel(level);
+}
+//----------------------------------------------------------------------------
+
 //----------------------------------------------------------------------------
 // Returns the min an the max value in a 41x41 region around the mouse pointer
-void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
+void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image)
 {
   //Get mouse pointer position in view coordinates
   double fLocalExtents[6];
@@ -1143,8 +1184,8 @@ void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
   //Convert to image pixel coordinates (rounded)
   int iLocalExtents[6];
   for(int i=0; i<3; i++) {
-    fLocalExtents[i*2  ] = (fLocalExtents[i*2  ] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
-    fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - this->GetInput()->GetOrigin()[i])/this->GetInput()->GetSpacing()[i];
+    fLocalExtents[i*2  ] = (fLocalExtents[i*2  ] - image->GetOrigin()[i])/image->GetSpacing()[i];
+    fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - image->GetOrigin()[i])/image->GetSpacing()[i];
 
     iLocalExtents[i*2  ] = lrint(fLocalExtents[i*2  ]);
     iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
@@ -1154,7 +1195,7 @@ void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max)
   }
 
   vtkSmartPointer<vtkExtractVOI> voiFilter = vtkSmartPointer<vtkExtractVOI>::New();
-  voiFilter->SetInput(this->GetInput());
+  voiFilter->SetInput(image);
   voiFilter->SetVOI(iLocalExtents);
   voiFilter->Update();
   if (!voiFilter->GetOutput()->GetNumberOfPoints()) {
@@ -1224,7 +1265,9 @@ void vvSlicer::Render()
       int ix, iy, iz;
       double value = this->GetScalarComponentAsDouble(this->GetInput(), X, Y, Z, ix, iy, iz);
 
-      worldPos << "data value : " << value << std::endl;
+      if(ImageActor->GetVisibility())
+        worldPos << "data value : " << value << std::endl;
+
       worldPos << "mm : " << lrint(mCurrent[0]) << ' '
                           << lrint(mCurrent[1]) << ' '
                           << lrint(mCurrent[2]) << ' '
@@ -1267,8 +1310,10 @@ void vvSlicer::Render()
 
 
   if (mOverlay && mOverlayActor->GetVisibility()) {
-    mOverlayMapper->SetWindow(this->GetColorWindow());
-    mOverlayMapper->SetLevel(this->GetColorLevel());
+    if(mLinkOverlayWindowLevel) {
+      mOverlayMapper->SetWindow(this->GetColorWindow());
+      mOverlayMapper->SetLevel(this->GetColorLevel());
+    }
     mOverlayMapper->GetOutput()->SetUpdateExtent(mOverlayActor->GetDisplayExtent());
     mOverlayMapper->GetOutput()->Update();
     mOverlayMapper->Update();
@@ -1284,13 +1329,11 @@ void vvSlicer::Render()
 //----------------------------------------------------------------------------
 void vvSlicer::UpdateCursorPosition()
 {
-  if (this->GetImageActor()->GetVisibility()) {
-    pdmA->SetVisibility(true);
-    mCursor[0] = mCurrent[0];
-    mCursor[1] = mCurrent[1];
-    mCursor[2] = mCurrent[2];
-    mCursor[3] = mCurrentTSlice;
-  }
+  pdmA->SetVisibility(true);
+  mCursor[0] = mCurrent[0];
+  mCursor[1] = mCurrent[1];
+  mCursor[2] = mCurrent[2];
+  mCursor[3] = mCurrentTSlice;
 }
 //----------------------------------------------------------------------------
 
@@ -1345,9 +1388,12 @@ void vvSlicer::SetContourSlice()
 {
   if (mSurfaceCutActors.size() > 0)
     for (std::vector<vvMeshActor*>::iterator i=mSurfaceCutActors.begin();
-         i!=mSurfaceCutActors.end(); i++)
+         i!=mSurfaceCutActors.end(); i++) {
+         
+      (*i)->SetSlicingOrientation(this->SliceOrientation);
       (*i)->SetCutSlice((this->Slice)*this->GetImage()->GetSpacing()[this->SliceOrientation]+
                         this->GetImage()->GetOrigin()[this->SliceOrientation]);
+    }
 }
 //----------------------------------------------------------------------------
 
index 0246723ad1b69837694dccc6fd1b32b39cc13730..a5156f28bc92e4f3c08e49db2c30b74c46d44ff9 100644 (file)
@@ -28,6 +28,7 @@
 #include <vtkSmartPointer.h>
 #include <vtkImageViewer2.h>
 #include <vtkImageReslice.h>
+#include <vtkImageMapToColors.h>
 
 class vtkActor;
 class vtkActor2D;
@@ -70,7 +71,7 @@ public:
   }
   vtkImageMapToWindowLevelColors* GetOverlayMapper(); 
   vvBlendImageActor* GetOverlayActor() ;
-  vtkImageMapToWindowLevelColors* GetFusionMapper() ;
+  vtkImageMapToColors* GetFusionMapper() ;
   vtkImageActor* GetFusionActor() ;
   vtkActor* GetVFActor() ;
   vtkCornerAnnotation* GetAnnotation();
@@ -80,9 +81,10 @@ public:
     return mFusion;
   }
 
-  /**Set an actor's visibility ("overlay, fusion, vf, contour...")
+  /**Get/Set an actor's visibility ("overlay, fusion, vf, contour...")
      Overlay index is the index of the overlay by type, eg. if there are
      5 contours and we want to activate the 3rd one, pass 2 **/
+  bool GetActorVisibility(const std::string& actor_type, int overlay_index);
   void SetActorVisibility(const std::string& actor_type, int overlay_index,bool vis);
   void RemoveActor(const std::string& actor_type, int overlay_index);
 
@@ -151,7 +153,7 @@ public:
   void SetCornerAnnotationVisibility(bool s);
   bool GetCornerAnnotationVisibility();
 
-  void GetExtremasAroundMousePointer(double & min, double & max);
+  void GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image);
 
   void UpdateLandmarks();
   void ForceUpdateDisplayExtent();
@@ -166,7 +168,19 @@ public:
   virtual void SetColorWindow(double s);
   virtual void SetColorLevel(double s);
 
-    
+  double GetOverlayColorWindow();
+  double GetOverlayColorLevel();
+  bool GetLinkOverlayWindowLevel() { return mLinkOverlayWindowLevel; }
+
+  void SetOverlayColorWindow(double s);
+  void SetOverlayColorLevel(double s);
+  void SetLinkOverlayWindowLevel(bool b) { mLinkOverlayWindowLevel = b; }
+
+  /**
+   * When it is enabled, beware of a call to GetExtent.
+   * we must have setted mReducedExtent otherwhise random values
+   * are returned by GetExtent
+   * */
   void EnableReducedExtent(bool b);
   void SetReducedExtent(int * ext);
 
@@ -196,7 +210,7 @@ protected:
   vtkSmartPointer<vtkImageMapToWindowLevelColors> mOverlayMapper;
   vtkSmartPointer<vvBlendImageActor> mOverlayActor;
   vtkSmartPointer<vtkImageReslice> mFusionReslice;
-  vtkSmartPointer<vtkImageMapToWindowLevelColors> mFusionMapper;
+  vtkSmartPointer<vtkImageMapToColors> mFusionMapper;
   vtkSmartPointer<vtkImageActor> mFusionActor;
   vtkSmartPointer<vtkCornerAnnotation> ca;
   vtkSmartPointer<vtkCursor2D> crossCursor;
@@ -229,6 +243,7 @@ protected:
   bool mUseReducedExtent;
   int * mReducedExtent;
   int * mInitialExtent;
+  bool mLinkOverlayWindowLevel;
 
 private:
   void UpdateOrientation();
index c3f5c0c4bc2d278dfc03ebfb15045f2a2315a7bf..c38496e5ab50b2389311eb4788f8f8ee428a0178 100644 (file)
@@ -40,6 +40,8 @@
 #include <vtksys/SystemTools.hxx>
 #include <vtkCamera.h>
 
+#include <qfileinfo.h>
+
 //----------------------------------------------------------------------------
 vvSlicerManager::vvSlicerManager(int numberOfSlicers)
 {
@@ -56,6 +58,7 @@ vvSlicerManager::vvSlicerManager(int numberOfSlicers)
   mOverlayColor = 130;
 
   mFusionOpacity = 70;
+  mFusionThresOpacity = 1;
   mFusionColorMap = 3;
   mFusionWindow = 1000;
   mFusionLevel = 1000;
@@ -121,6 +124,34 @@ void vvSlicerManager::ToggleContourSuperposition()
 }
 //----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
+std::string vvSlicerManager::GetListOfAbsoluteFilePathInOneString(const std::string &actorType)
+{
+  vvImageReader *reader = NULL;
+
+  if(actorType=="image")
+    reader = mReader;
+  else if(actorType=="overlay")
+    reader = mOverlayReader;
+  else if(actorType=="fusion")
+    reader = mFusionReader;
+  else if(actorType=="vector")
+    reader = mVectorReader;
+
+  if(!reader)
+    return "";
+
+  std::string list;
+  for(unsigned int i=0; i<reader->GetInputFilenames().size(); i++){
+    QFileInfo fileinfo(reader->GetInputFilenames()[i].c_str()); //Do not show the path
+    if(i)
+      list += '\n';
+    list += fileinfo.absoluteFilePath().toStdString();
+  }
+  return list;
+}
+//----------------------------------------------------------------------------
+
 
 //----------------------------------------------------------------------------
 bool vvSlicerManager::SetImage(std::string filename, vvImageReader::LoadedImageType type, int n, unsigned int slice)
@@ -262,6 +293,7 @@ bool vvSlicerManager::SetFusion(std::string filename,int dim, std::string compon
   double *fusRange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();
   mFusionLevel = (fusRange[0]+fusRange[1])/2;
   mFusionWindow = fusRange[1]-fusRange[0];
+
   return true;
 }
 //----------------------------------------------------------------------------
@@ -273,7 +305,11 @@ bool vvSlicerManager::SetVF(std::string filename)
   if (mVectorReader.IsNull())
     mVectorReader = vvImageReader::New();
   mVectorReader->SetInputFilename(filename);
-  mVectorReader->Update(vvImageReader::VECTORFIELD);
+  
+  if (mType == vvImageReader::IMAGEWITHTIME)
+    mVectorReader->Update(vvImageReader::VECTORFIELDWITHTIME);
+  else
+    mVectorReader->Update(vvImageReader::VECTORFIELD);
   if (mVectorReader->GetLastError().size() != 0) {
     mLastError = mVectorReader->GetLastError();
     return false;
@@ -381,6 +417,13 @@ void vvSlicerManager::LeftButtonReleaseEvent(int slicer)
 }
 //----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetSliceOrientation(int slicer, int orientation)
+{
+  mSlicers[slicer]->SetSliceOrientation(orientation);
+  emit UpdateOrientation(slicer, orientation);
+}
+//----------------------------------------------------------------------------
 
 //----------------------------------------------------------------------------
 void vvSlicerManager::SetTSlice(int slice)
@@ -394,7 +437,6 @@ void vvSlicerManager::SetTSlice(int slice)
   for ( unsigned int i = 0; i < mSlicers.size(); i++) {
     if (slice != mSlicers[i]->GetTSlice()) {
       mSlicers[i]->SetTSlice(slice);
-      if (mSlicers[i]->GetImageActor()->GetVisibility())
         UpdateTSlice(i);
     }
   }
@@ -409,6 +451,7 @@ void vvSlicerManager::SetNextTSlice(int originating_slicer)
   t++;
   if (t > mSlicers[0]->GetTMax())
     t = 0;
+  //std::cout << "vvSlicerManager::SetNextTSlice" << std::endl;
   emit UpdateTSlice(originating_slicer,t);
 }
 //----------------------------------------------------------------------------
@@ -421,6 +464,7 @@ void vvSlicerManager::SetPreviousTSlice(int originating_slicer)
   t--;
   if (t < 0)
     t = mSlicers[0]->GetTMax();
+  //std::cout << "vvSlicerManager::SetPreviousTSlice" << std::endl;
   emit UpdateTSlice(originating_slicer,t);
 }
 //----------------------------------------------------------------------------
@@ -454,8 +498,7 @@ void vvSlicerManager::SetTSliceInSlicer(int tslice, int slicer)
   if (mSlicers[slicer]->GetTSlice() == tslice) return;
 
   mSlicers[slicer]->SetTSlice(tslice);
-  if (mSlicers[slicer]->GetImageActor()->GetVisibility())
-    UpdateTSlice(slicer);
+  UpdateTSlice(slicer);
 }
 //----------------------------------------------------------------------------
 
@@ -469,7 +512,6 @@ void vvSlicerManager::SetColorWindow(double s)
 }
 //----------------------------------------------------------------------------
 
-
 //----------------------------------------------------------------------------
 void vvSlicerManager::SetColorLevel(double s)
 {
@@ -479,6 +521,33 @@ void vvSlicerManager::SetColorLevel(double s)
 }
 //----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetOverlayColorWindow(double s)
+{
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetOverlayColorWindow(s);
+  }
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetOverlayColorLevel(double s)
+{
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetOverlayColorLevel(s);
+  }
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void vvSlicerManager::SetLinkOverlayWindowLevel(bool b)
+{
+  for ( unsigned int i = 0; i < mSlicers.size(); i++) {
+    mSlicers[i]->SetLinkOverlayWindowLevel(b);
+  }
+}
+//----------------------------------------------------------------------------
+
 //----------------------------------------------------------------------------
 void vvSlicerManager::SetCursorAndCornerAnnotationVisibility(int s)
 {
@@ -535,7 +604,8 @@ void vvSlicerManager::UpdateViews(int current,int slicer)
     mSlicers[slicer]->Render();
 
     for ( unsigned int i = 0; i < mSlicers.size(); i++) {
-      if (i != (unsigned int)slicer && mSlicers[i]->GetImageActor()->GetVisibility()
+      if (i != (unsigned int)slicer
+          && mSlicers[i]->GetRenderer()->GetDraw()
           && mSlicers[i]->GetRenderWindow()->GetSize()[0] > 2
           && mSlicers[i]->GetRenderWindow()->GetSize()[1] > 2) {
         mSlicers[i]->SetCurrentPosition(mSlicers[slicer]->GetCurrentPosition()[0],
@@ -692,6 +762,54 @@ double vvSlicerManager::GetColorLevel()
 }
 //----------------------------------------------------------------------------
 
+//----------------------------------------------------------------------------
+double vvSlicerManager::GetOverlayColorWindow()
+{
+  if (mSlicers.size())
+    return mSlicers[0]->GetOverlayColorWindow();
+  return -1;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+double vvSlicerManager::GetOverlayColorLevel()
+{
+  if (mSlicers.size())
+    return mSlicers[0]->GetOverlayColorLevel();
+  return -1;
+}
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+bool vvSlicerManager::GetLinkOverlayWindowLevel()
+{
+  if (mSlicers.size())
+    return mSlicers[0]->GetLinkOverlayWindowLevel();
+  return -1;
+}
+//----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvSlicerManager::ResetTransformationToIdentity(const std::string actorType)
+{
+  if(actorType == "image")
+    this->GetImage()->GetTransform()->Identity();
+  else if(actorType == "overlay")
+    this->GetSlicer(0)->GetOverlay()->GetTransform()->Identity();
+  else if(actorType == "fusion")
+    this->GetSlicer(0)->GetFusion()->GetTransform()->Identity();
+  else if(actorType == "vf")
+    this->GetVF()->GetTransform()->Identity();
+  else
+    return;
+
+  for(int i=0; i< this->GetNumberOfSlicers(); i++){
+    this->GetSlicer(i)->ForceUpdateDisplayExtent();
+    this->GetSlicer(i)->ResetCamera();
+    this->GetSlicer(i)->Render();
+  }
+}
+//------------------------------------------------------------------------------
 
 //----------------------------------------------------------------------------
 void vvSlicerManager::Render()
@@ -824,7 +942,7 @@ void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer)
       Z <= mSlicers[slicer]->GetInput()->GetWholeExtent()[5]) {
     value = this->GetScalarComponentAsDouble(mSlicers[slicer]->GetInput(), X, Y, Z);
 
-    if (mSlicers[slicer]->GetVFActor() && mSlicers[slicer]->GetVFActor()->GetVisibility()) {
+    if (mSlicers[slicer]->GetVFActor() ) {
       displayVec = 1;
       unsigned int currentTime = mSlicers[slicer]->GetTSlice();
       vtkImageData *vf = NULL;
@@ -844,7 +962,7 @@ void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer)
         valueVec = sqrt(xVec*xVec + yVec*yVec + zVec*zVec);
       }
     }
-    if (mSlicers[slicer]->GetOverlayActor() && mSlicers[slicer]->GetOverlayActor()->GetVisibility()) {
+    if (mSlicers[slicer]->GetOverlayActor() ) {
       displayOver = 1;
       vtkImageData *overlay = dynamic_cast<vtkImageData*>(mSlicers[slicer]->GetOverlayMapper()->GetInput());
       double Xover = (x - overlay->GetOrigin()[0]) / overlay->GetSpacing()[0];
@@ -852,7 +970,7 @@ void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer)
       double Zover = (z - overlay->GetOrigin()[2]) / overlay->GetSpacing()[2];
       valueOver = this->GetScalarComponentAsDouble(overlay, Xover, Yover, Zover);
     }
-    if (mSlicers[slicer]->GetFusionActor() && mSlicers[slicer]->GetFusionActor()->GetVisibility()) {
+    if (mSlicers[slicer]->GetFusionActor() ) {
       displayFus = 1;
       vtkImageData *fusion = dynamic_cast<vtkImageData*>(mSlicers[slicer]->GetFusionMapper()->GetInput());
       double Xover = (x - fusion->GetOrigin()[0]) / fusion->GetSpacing()[0];
@@ -865,12 +983,6 @@ void vvSlicerManager::UpdateInfoOnCursorPosition(int slicer)
     emit UpdateVector(displayVec,xVec, yVec, zVec, valueVec);
     emit UpdateOverlay(displayOver,valueOver,value);
     emit UpdateFusion(displayFus,valueFus);
-    for (unsigned int i = 0; i < mSlicers.size(); i++) {
-      if (mSlicers[i]->GetImageActor()->GetVisibility() == 1)
-        emit UpdateWindows(i,mSlicers[i]->GetSliceOrientation(),mSlicers[i]->GetSlice());
-      else
-        emit UpdateWindows(i,-1,-1);
-    }
   }
 }
 //----------------------------------------------------------------------------
@@ -891,10 +1003,11 @@ void vvSlicerManager::Picked()
 }
 //----------------------------------------------------------------------------
 
+
 //----------------------------------------------------------------------------
 void vvSlicerManager::UpdateWindowLevel()
 {
-  emit WindowLevelChanged(mSlicers[0]->GetColorWindow(),mSlicers[0]->GetColorLevel(),mPreset,mColorMap);
+  emit WindowLevelChanged();
 }
 //----------------------------------------------------------------------------
 
@@ -906,6 +1019,7 @@ void vvSlicerManager::UpdateSlice(int slicer)
     //DD("============= NOTHING");
     return;
   }
+  //std::cout << "vvSlicerManager::UpdateSlice " << slicer << " " << mSlicers[slicer]->GetSlice() << std::endl;
   emit UpdateSlice(slicer, mSlicers[slicer]->GetSlice());
   mSlicers[slicer]->Render(); // DS <-- I add this, this could/must be the only Render ...
   mPreviousSlice[slicer] = mSlicers[slicer]->GetSlice();
@@ -916,15 +1030,18 @@ void vvSlicerManager::UpdateSlice(int slicer)
 //----------------------------------------------------------------------------
 void vvSlicerManager::UpdateTSlice(int slicer)
 {
-  if (mPreviousSlice[slicer] == mSlicers[slicer]->GetSlice()) {
-    if (mPreviousTSlice[slicer] == mSlicers[slicer]->GetTSlice()) {
+  int slice = mSlicers[slicer]->GetSlice();
+  int tslice = mSlicers[slicer]->GetTSlice();
+  if (mPreviousSlice[slicer] == slice) {
+    if (mPreviousTSlice[slicer] == tslice) {
       //      DD("************** NOTHING ***********");
       return;
     }
   }
-  mPreviousSlice[slicer] = mSlicers[slicer]->GetSlice();
-  mPreviousTSlice[slicer] = mSlicers[slicer]->GetTSlice();
-  emit UpdateTSlice(slicer,mSlicers[slicer]->GetTSlice());
+  mPreviousSlice[slicer] = slice;
+  mPreviousTSlice[slicer] = tslice;
+  //std::cout << "vvSlicerManager::UpdateTSlice " << slicer << " " << tslice << std::endl;
+  emit UpdateTSlice(slicer, tslice);
 }
 //----------------------------------------------------------------------------
 
@@ -994,22 +1111,34 @@ void vvSlicerManager::SetPreset(int preset)
 
 
 //----------------------------------------------------------------------------
-void vvSlicerManager::SetLocalColorWindowing(const int slicer)
+void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlKey)
 {
   double min, max;
-  this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max);
-  this->SetColorWindow(max-min);
-  this->SetColorLevel(0.5*(min+max));
-  this->UpdateWindowLevel();
+  int t = this->mSlicers[slicer]->GetTSlice();
+  if(bCtrlKey && this->mSlicers[slicer]->GetFusion()) {
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t]);
+    this->SetFusionWindow(max-min);
+    this->SetFusionLevel(0.5*(min+max));
+    this->SetColorMap(mColorMap);
+  }
+  else if(bCtrlKey && this->mSlicers[slicer]->GetOverlay()) {
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t]);
+    if(this->mSlicers[slicer]->GetLinkOverlayWindowLevel()){
+      this->SetColorWindow(max-min);
+      this->SetColorLevel(0.5*(min+max));
+    } else {
+      this->SetOverlayColorWindow(max-min);
+      this->SetOverlayColorLevel(0.5*(min+max));
+    }
+  }
+  else {
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetInput());
+    this->SetColorWindow(max-min);
+    this->SetColorLevel(0.5*(min+max));
+    this->SetPreset(6);
+  }
   this->Render();
-}
-//----------------------------------------------------------------------------
-
-
-//----------------------------------------------------------------------------
-void vvSlicerManager::SetColorMap()
-{
-  SetColorMap(mColorMap);
+  this->UpdateWindowLevel();
 }
 //----------------------------------------------------------------------------
 
@@ -1046,6 +1175,13 @@ void vvSlicerManager::SetColorMap(int colormap)
     LUT->SetHueRange(0.4,0.80);
     break;
   case 3:
+    if (LUT == NULL)
+      LUT = vtkLookupTable::New();
+    LUT->SetValueRange(0.5,1);
+    LUT->SetSaturationRange(1,1);
+    LUT->SetHueRange(0.666,0);
+    break;
+  case 4:
     if (LUT == NULL)
       LUT = vtkLookupTable::New();
     LUT->SetValueRange(0,1);
@@ -1065,27 +1201,51 @@ void vvSlicerManager::SetColorMap(int colormap)
     LUT->SetTableRange(level-fabs(window)/4,level+fabs(window)/4);
     LUT->Build();
   }
-  vtkLookupTable* fusLUT = NULL;
-  if (mSlicers[0]->GetFusion()) {
-    fusLUT = vtkLookupTable::New();
+  vtkWindowLevelLookupTable* fusLUT = NULL;
+  if (mSlicers[0]->GetFusion()) { // && mFusionColorMap >= 0) {
+    fusLUT = vtkWindowLevelLookupTable::New();
     double fusRange [2];
     fusRange[0] = mFusionLevel - mFusionWindow/2;
     fusRange[1] = mFusionLevel + mFusionWindow/2;
-    fusLUT->SetTableRange(fusRange[0],fusRange[1]);
+    double* frange = mFusionReader->GetOutput()->GetVTKImages()[0]->GetScalarRange();
+    fusLUT->SetTableRange(frange);
     fusLUT->SetValueRange(1,1);
     fusLUT->SetSaturationRange(1,1);
+    fusLUT->SetAlphaRange(1, 1);
+    fusLUT->SetWindow(mFusionWindow);
+    fusLUT->SetLevel(mFusionLevel);
     if (mFusionColorMap == 1)
       fusLUT->SetHueRange(0,0.18);
     else if (mFusionColorMap == 2)
       fusLUT->SetHueRange(0.4,0.80);
     else if (mFusionColorMap == 3)
+    {
+      fusLUT->SetHueRange(0.666, 0);
+      fusLUT->SetValueRange(0.5, 1);
+    }
+    else if (mFusionColorMap == 4)
       fusLUT->SetHueRange(0,1);
-    fusLUT->Build();
-    if (mFusionColorMap == 0)
-      fusLUT = NULL;
+    else if (mFusionColorMap <= 0)
+    {
+      fusLUT->SetValueRange(0,1);
+      fusLUT->SetSaturationRange(0,0);
+    }
+    
+    fusLUT->ForceBuild();
+    
+    // set color table transparency
+    double alpha_range_end = frange[0] + (double)mFusionThresOpacity*(frange[1] - frange[0])/100;
+    for (double i = frange[0]; i < alpha_range_end; i++) {
+      double v[4];
+      vtkIdType index = fusLUT->GetIndex(i);
+      fusLUT->GetTableValue(index, v);
+      v[3] = 0;
+      fusLUT->SetTableValue(index, v);
+    }
   }
   for ( unsigned int i = 0; i < mSlicers.size(); i++) {
-    if (mSlicers[i]->GetOverlay() && mSlicers[i]->GetOverlayActor()->GetVisibility()) {
+    
+    if (mSlicers[i]->GetOverlay()) {
       vtkLookupTable* supLUT = vtkLookupTable::New();
       supLUT->SetTableRange(range[0],range[1]);
       supLUT->SetValueRange(1,1);
@@ -1111,11 +1271,10 @@ void vvSlicerManager::SetColorMap(int colormap)
     } else {
       mSlicers[i]->GetWindowLevel()->SetLookupTable(LUT);
     }
-    if (mSlicers[i]->GetFusion() && mSlicers[i]->GetFusionActor()->GetVisibility()) {
-      mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100);
+    
+    if (mSlicers[i]->GetFusion()) {
       mSlicers[i]->GetFusionMapper()->SetLookupTable(fusLUT);
-      mSlicers[i]->GetFusionMapper()->SetWindow(mFusionWindow);
-      mSlicers[i]->GetFusionMapper()->SetLevel(mFusionLevel);
+      mSlicers[i]->GetFusionActor()->SetOpacity(double(mFusionOpacity)/100);
     }
   }
   if (fusLUT)
index bb30f54d5aa255611b6fb9901de7463a078ea6b3..e8a229b877d8dc3e9d669c58d429742401e2753d 100644 (file)
@@ -80,6 +80,7 @@ class vvSlicerManager : public QObject {
   std::string GetVFName()        { return mVFName; }
   std::string GetOverlayName()   { return mOverlayName; }
   std::string GetFusionName()    { return mFusionName; }
+  std::string GetListOfAbsoluteFilePathInOneString(const std::string &actorType);
 
   ///Switch between nearest neighbor and linear interpolation
   void ToggleInterpolation();
@@ -101,6 +102,7 @@ class vvSlicerManager : public QObject {
 
   void SetFilename(std::string f, int number=0);
 
+  void SetSliceOrientation(int slicer, int orientation);
   void SetTSlice(int slice);
   void SetNextTSlice(int originating_slicer);
   void SetPreviousTSlice(int originating_slicer);
@@ -109,9 +111,11 @@ class vvSlicerManager : public QObject {
   void GenerateDefaultLookupTable();
   void SetColorWindow(double s);
   void SetColorLevel(double s);
-  void SetLocalColorWindowing(const int slicer);
+  void SetOverlayColorWindow(double s);
+  void SetOverlayColorLevel(double s);
+  void SetLinkOverlayWindowLevel(bool b);
+  void SetLocalColorWindowing(const int slicer, const bool bCtrlKey);
   void SetOpacity(int i, double factor);
-  void SetColorMap();
   void SetColorMap(int colormap);
   void SetPreset(int preset);
   void SetOverlayColor(int color) {
@@ -120,6 +124,9 @@ class vvSlicerManager : public QObject {
   void SetFusionOpacity(int opacity) {
     mFusionOpacity = opacity;
   }
+  void SetFusionThresholdOpacity(int thresOpacity) {
+    mFusionThresOpacity = thresOpacity;
+  }
   void SetFusionColorMap(int colorMap) {
     mFusionColorMap = colorMap;
   }
@@ -132,6 +139,9 @@ class vvSlicerManager : public QObject {
 
   double GetColorWindow();
   double GetColorLevel();
+  double GetOverlayColorWindow();
+  double GetOverlayColorLevel();
+  bool GetLinkOverlayWindowLevel();
   int GetColorMap() {
     return mColorMap;
   }
@@ -141,10 +151,12 @@ class vvSlicerManager : public QObject {
   int GetOverlayColor() {
     return mOverlayColor;
   }
-
   int GetFusionOpacity() {
     return mFusionOpacity;
   }
+  int GetFusionThresholdOpacity() {
+    return mFusionThresOpacity;
+  }
   int GetFusionColorMap() {
     return mFusionColorMap;
   }
@@ -159,6 +171,7 @@ class vvSlicerManager : public QObject {
   void UpdateViews(int current, int slicer);
   void UpdateLinked(int slicer);
   void UpdateLinkedNavigation(vvSlicer *slicer, bool bPropagate=false);
+  void ResetTransformationToIdentity(const std::string actorType);
   void Render();
 
   void AddLink(std::string newId) {
@@ -204,11 +217,11 @@ signals :
   void UpdateVector(int display, double x, double y, double z, double value);
   void UpdateOverlay(int display, double valueOver, double valueRef);
   void UpdateFusion(int display, double valueFus);
-  void UpdateWindows(int slicer, int view, int slice);
+  void UpdateOrientation(int slicer, int orientation);
   void UpdateSlice(int slicer, int slice);
   void UpdateTSlice(int slicer, int slice);
   void UpdateSliceRange(int slice, int min, int max, int tmin, int tmax);
-  void WindowLevelChanged(double window, double level, int preset, int colormap);
+  void WindowLevelChanged();
   void UpdateLinkManager(std::string, int slicer, double x, double y, double z, int temps);
   void UpdateLinkedNavigation(std::string, vvSlicerManager*, vvSlicer*);
   void LandmarkAdded();
@@ -228,6 +241,7 @@ protected:
   int mOverlayColor;
 
   int mFusionOpacity;
+  int mFusionThresOpacity;
   int mFusionColorMap;
   double mFusionWindow;
   double mFusionLevel;
index d373d980ba1433c1362f2f39f3612b5b5d31b1d1..1b7103301b7d9f0544c731c14ccca913a623657d 100644 (file)
@@ -96,6 +96,7 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
     if ( VisibleInWindow > -1 ) {
       if (event == vtkCommand::KeyPressEvent) {
         std::string KeyPress = isi->GetInteractor()->GetKeySym();
+        bool bCtrlKey = isi->GetInteractor()->GetControlKey();
         if (KeyPress == "Tab") {
           if(isi->GetInteractor()->GetShiftKey())
             this->SM->PrevImage(VisibleInWindow);
@@ -108,7 +109,7 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
           return;
         }
         if (KeyPress == "w") {
-          this->SM->SetLocalColorWindowing(VisibleInWindow);
+          this->SM->SetLocalColorWindowing(VisibleInWindow, bCtrlKey);
           return;
         }
         if (KeyPress == "0") {
@@ -185,7 +186,6 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
           return;
         }
         if (KeyPress == "h") {
-          std::cout << "KeyPress == \"h\"\n";
           this->SM->SetCursorAndCornerAnnotationVisibility(0);
           this->SM->Render();
           return;
@@ -210,9 +210,13 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
           return;
         }
         if (KeyPress == "g") {
-          double* cursorPos = this->SM->GetSlicer(VisibleInWindow)->GetCursorPosition();
-          this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(
-            cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
+          if(bCtrlKey)
+            this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(0,0,0,0);
+          else {
+            double* cursorPos = this->SM->GetSlicer(VisibleInWindow)->GetCursorPosition();
+            this->SM->GetSlicer(VisibleInWindow)->SetCurrentPosition(
+              cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
+          }
           this->SM->UpdateViews(1,VisibleInWindow);
           this->SM->UpdateLinked(VisibleInWindow);
           return;
@@ -245,17 +249,20 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
 
         if (KeyPress == "F2") {
           this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Sagital\n<slice>");
-          this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(0);
+          //this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(0);
+          this->SM->SetSliceOrientation(VisibleInWindow, 0);
           this->SM->UpdateSliceRange(VisibleInWindow);
         }
         if (KeyPress == "F3") {
           this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Coronal\n<slice>");
-          this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(1);
+          //this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(1);
+          this->SM->SetSliceOrientation(VisibleInWindow, 1);
           this->SM->UpdateSliceRange(VisibleInWindow);
         }
         if (KeyPress == "F4") {
           this->SM->GetSlicer(VisibleInWindow)->GetAnnotation()->SetText(2,"Axial\n<slice>");
-          this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(2);
+          //this->SM->GetSlicer(VisibleInWindow)->SetSliceOrientation(2);
+          this->SM->SetSliceOrientation(VisibleInWindow, 2);
           this->SM->UpdateSliceRange(VisibleInWindow);
         }
 
@@ -397,8 +404,8 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
       this->SM->SetColorWindow(window*dx);
       this->SM->SetColorLevel(level-dy);
       this->SM->SetPreset(6);
-      this->SM->UpdateWindowLevel();
       this->SM->Render();
+      this->SM->UpdateWindowLevel();
       return;
     }
   }
index 5cde3234b373ce4bc70ee972514b366b9dbdcfcd..fa22daad122e54bb2337d1feb1700f40bbd152e0 100644 (file)
@@ -225,6 +225,8 @@ void vvToolBinarize::InputIsSelected(vvSlicerManager * m)
 
   connect(mCurrentSlicerManager,SIGNAL(UpdateSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
   connect(mCurrentSlicerManager,SIGNAL(UpdateTSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
+  
+  connect(mCurrentSlicerManager,SIGNAL(UpdateOrientation(int,int)),this,SLOT(UpdateOrientation(int, int)));
 
   //  connect(mCurrentSlicerManager, SIGNAL(LeftButtonReleaseSignal(int)), SLOT(LeftButtonReleaseEvent(int)));
   
@@ -244,8 +246,22 @@ void vvToolBinarize::InputIsSelected(vvSlicerManager * m)
 //------------------------------------------------------------------------------
 
 
+//------------------------------------------------------------------------------
+void vvToolBinarize::UpdateOrientation(int slicer,int orientation)
+{
+  Update(slicer);
+}
+//------------------------------------------------------------------------------
+
 //------------------------------------------------------------------------------
 void vvToolBinarize::UpdateSlice(int slicer,int slices)
+{
+  Update(slicer);
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvToolBinarize::Update(int slicer)
 {
   if (!mInteractiveDisplayIsEnabled) return;
   if (!mCurrentSlicerManager) close();
@@ -255,7 +271,6 @@ void vvToolBinarize::UpdateSlice(int slicer,int slices)
 }
 //------------------------------------------------------------------------------
 
-
 //------------------------------------------------------------------------------
 void vvToolBinarize::GetArgsInfoFromGUI()
 {
index 7251f8e8133494aaa88f78d48f857f80fca8b6e0..9e61e683cd284872456b3d5030fbdbef1987af90 100644 (file)
@@ -50,6 +50,7 @@ class vvToolBinarize:
   virtual void reject();
   void valueChangedT1(double v);
   void valueChangedT2(double v);
+  void UpdateOrientation(int slicer, int orientation);
   void UpdateSlice(int slicer,int slices);
   void enableLowerThan(bool b);
   void useFGBGtoggled(bool);
@@ -64,6 +65,8 @@ class vvToolBinarize:
   std::vector<vvImageContour::Pointer> mImageContour;
   std::vector<vvImageContour::Pointer> mImageContourLower;
   bool mInteractiveDisplayIsEnabled;
+  
+  void Update(int slicer);
 
 }; // end class vvToolBinarize
 //------------------------------------------------------------------------------
index 671c0800e91456b06b669b55c3df1d4bcdf56304..50a448941e8f524c0e567191f9356fa51264ff6b 100644 (file)
@@ -22,7 +22,7 @@
 #include <QMenu>
 
 //------------------------------------------------------------------------------
-vvToolCreatorBase::vvToolCreatorBase(QString name): mExperimental(false)
+vvToolCreatorBase::vvToolCreatorBase(QString name): mAction(NULL), mExperimental(false)
 {
   mUseContextMenu = false;
   mToolName = name;
index 9fe30f398e60f052f219e48780584ac09691aff3..c3b55709722033a6445b9b3d0fb0c239ec1d5628 100644 (file)
@@ -30,6 +30,7 @@
 #include <QCursor>
 #include <QApplication>
 #include <QMessageBox>
+#include <QSignalMapper>
 
 // vtk
 #include <vtkImageClip.h>
 ADD_TOOL(vvToolCropImage);
 //------------------------------------------------------------------------------
 
-
+//same order of int* returned by VtkImageData::WholeExtent
+enum sliderId {xmin, xmax, ymin, ymax, zmin, zmax, tmin, tmax};
 //------------------------------------------------------------------------------
 vvToolCropImage::vvToolCropImage(vvMainWindowBase * parent, Qt::WindowFlags f):
   vvToolWidgetBase(parent, f),
   vvToolBase<vvToolCropImage>(parent),
-  Ui::vvToolCropImage()
+  Ui::vvToolCropImage(),mSliders(8)
 {
 
   // GUI Initialization
   Ui_vvToolCropImage::setupUi(mToolWidget);
-  // mTLabel2->setHidden(false);
-  // tminSlider->setHidden(false);
-  // tmaxSlider->setHidden(false);
-  // spin_tmin->setHidden(false);
-  // spin_tmax->setHidden(false);
-  // mLabelTimeCropping->setHidden(false);
   mTLabel1->setHidden(true);
   mTLabel2->setHidden(true);
   tminSlider->setHidden(true);
@@ -69,6 +65,19 @@ vvToolCropImage::vvToolCropImage(vvMainWindowBase * parent, Qt::WindowFlags f):
 
   // Set how many inputs are needed for this tool
   AddInputSelector("Select one image");
+  
+  mSliders[xmin]=xminSlider;
+  mSliders[xmax]=xmaxSlider;
+  mSliders[ymin]=yminSlider;
+  mSliders[ymax]=ymaxSlider;
+  mSliders[zmin]=zminSlider;
+  mSliders[zmax]=zmaxSlider;
+  mSliders[tmin]=tminSlider;
+  mSliders[tmax]=tmaxSlider;
+  
+  // Record initial extend
+  mReducedExtent = new int[6];
+  mInitialExtent = new int[6];
 }
 //------------------------------------------------------------------------------
 
@@ -76,7 +85,8 @@ vvToolCropImage::vvToolCropImage(vvMainWindowBase * parent, Qt::WindowFlags f):
 //------------------------------------------------------------------------------
 vvToolCropImage::~vvToolCropImage()
 {
-
+  delete [] mReducedExtent;
+  delete [] mInitialExtent;
 }
 //------------------------------------------------------------------------------
 
@@ -84,10 +94,14 @@ vvToolCropImage::~vvToolCropImage()
 //------------------------------------------------------------------------------
 void vvToolCropImage::closeEvent(QCloseEvent *event)
 {
-  // Reset extends
-  for(int i=0; i<mExtentSize; i++) mReducedExtent[i] = mInitialExtent[i];
-  UpdateExtent();
-  event->accept();
+  if(mCurrentSlicerManager){
+//     Reset extends
+    for(int i=0; i<mExtentSize; i++){
+      mReducedExtent[i] = mInitialExtent[i];
+    }
+    UpdateExtent();
+  }
+  vvToolWidgetBase::closeEvent(event);
 }
 //------------------------------------------------------------------------------
 
@@ -111,78 +125,15 @@ void vvToolCropImage::reject()
 
 
 //------------------------------------------------------------------------------
-void vvToolCropImage::sliderXMinValueChanged(int s)
-{
-  xmaxSlider->setMinimum(xminSlider->value());
-  mReducedExtent[0] = xminSlider->value();
-  UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderXMaxValueChanged(int s)
-{
-  xminSlider->setMaximum(xmaxSlider->value());
-  mReducedExtent[1] = xmaxSlider->value();
-  UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderYMinValueChanged(int s)
-{
-  ymaxSlider->setMinimum(yminSlider->value());
-  mReducedExtent[2] = yminSlider->value();
-  UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderYMaxValueChanged(int s)
-{
-  yminSlider->setMaximum(ymaxSlider->value());
-  mReducedExtent[3] = ymaxSlider->value();
-  UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderZMinValueChanged(int s)
-{
-  zmaxSlider->setMinimum(zminSlider->value());
-  mReducedExtent[4] = zminSlider->value();
-  UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderZMaxValueChanged(int s)
+void vvToolCropImage::sliderValueChanged(int dim)
 {
-  zminSlider->setMaximum(zmaxSlider->value());
-  mReducedExtent[5] = zmaxSlider->value();
-  UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderTMinValueChanged(int s) {
-  tmaxSlider->setMinimum(tminSlider->value());
-  mReducedExtent[6] = tminSlider->value();
-  UpdateExtent();
-}
-//------------------------------------------------------------------------------
-
-
-//------------------------------------------------------------------------------
-void vvToolCropImage::sliderTMaxValueChanged(int s) {
-  tminSlider->setMaximum(tmaxSlider->value());
-  mReducedExtent[7] = tmaxSlider->value();
+  int dimMin = dim;
+  if(dim%2==0){//case we are minimum
+    mSliders[dim+1]->setMinimum(mSliders[dim]->value());
+  }else {
+    mSliders[--dimMin]->setMaximum(mSliders[dim]->value());
+  }
+  mReducedExtent[dim] = mSliders[dim]->value() + mInitialExtent[dimMin];
   UpdateExtent();
 }
 //------------------------------------------------------------------------------
@@ -203,7 +154,6 @@ void vvToolCropImage::UpdateExtent()
 //------------------------------------------------------------------------------
 void vvToolCropImage::InputIsSelected(vvSlicerManager * slicer)
 {
-
   // Change interface according to number of dimension
   mExtentSize = 2*slicer->GetDimension();
    if (slicer->GetDimension()<4) {
@@ -224,37 +174,23 @@ void vvToolCropImage::InputIsSelected(vvSlicerManager * slicer)
     spin_zmax->setHidden(true);
   }
 
-  // Record initial extend
-  mReducedExtent = new int[mExtentSize];
-  mInitialExtent = new int[mExtentSize];
-  mReducedExtent = mCurrentSlicerManager->GetImage()->GetFirstVTKImageData()->GetWholeExtent();
-  for(int i=0; i<mExtentSize; i++) mInitialExtent[i] = mReducedExtent[i];
+  int *a = mCurrentImage->GetFirstVTKImageData()->GetWholeExtent();
+  for(int i=0; i<6; i++){
+    mInitialExtent[i] = a[i];
+    mReducedExtent[i] = a[i];
+  }
   for(int i=0; i<mCurrentSlicerManager->GetNumberOfSlicers(); i++) {
     mCurrentSlicerManager->GetSlicer(i)->EnableReducedExtent(true);
+    mCurrentSlicerManager->GetSlicer(i)->SetReducedExtent(mInitialExtent);
   }
 
-  // Set initial sliders values
+//   Set initial sliders values
   std::vector<int> imsize = mCurrentSlicerManager->GetImage()->GetSize();
-  xminSlider->setMaximum(imsize[0]-1);
-  xmaxSlider->setMaximum(imsize[0]-1);
-  xmaxSlider->setValue(imsize[0]-1);
-
-  yminSlider->setMaximum(imsize[1]-1);
-  ymaxSlider->setMaximum(imsize[1]-1);
-  ymaxSlider->setValue(imsize[1]-1);
-
-  if (slicer->GetDimension() >2) {
-    zminSlider->setMaximum(imsize[2]-1);
-    zmaxSlider->setMaximum(imsize[2]-1);
-    zmaxSlider->setValue(imsize[2]-1);
-  }
-
-  if (slicer->GetDimension() >3) {
-    tminSlider->setMaximum(imsize[3]-1);
-    tmaxSlider->setMaximum(imsize[3]-1);
-    tmaxSlider->setValue(imsize[3]-1);
+  for(int dim=0; dim<slicer->GetDimension() && dim<3; ++dim){
+    mSliders[dim*2]->setMaximum(imsize[dim]-1);
+    mSliders[dim*2+1]->setMaximum(imsize[dim]-1);
+    mSliders[dim*2+1]->setValue(imsize[dim]-1);
   }
-
   spin_xmin->setMaximum(imsize[0]-1);
   spin_xmax->setMaximum(imsize[0]-1);
   spin_xmax->setValue(imsize[0]-1);
@@ -275,20 +211,12 @@ void vvToolCropImage::InputIsSelected(vvSlicerManager * slicer)
     spin_tmax->setValue(imsize[3]-1);
   }
 
-  // Connect
-  connect(xminSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderXMinValueChanged(int)));
-  connect(xmaxSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderXMaxValueChanged(int)));
-  connect(yminSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderYMinValueChanged(int)));
-  connect(ymaxSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderYMaxValueChanged(int)));
-  connect(zminSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderZMinValueChanged(int)));
-  connect(zmaxSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderZMaxValueChanged(int)));
-  connect(tminSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderTMinValueChanged(int)));
-  connect(tmaxSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderTMaxValueChanged(int)));
-
-  //  connect(mCurrentSlicerManager,SIGNAL(UpdateSlice(int,int)),this,SLOT(UpdateExtent()));
-  //connect(mCurrentSlicerManager,SIGNAL(UpdateTSlice(int,int)),this,SLOT(UpdateExtent()));
-
-  //  connect(mIntensitySlider, SIGNAL(valueChanged(double)), this, SLOT(autoCropValueChanged(double)));
+  QSignalMapper* signalMapper = new QSignalMapper(this);
+  connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(sliderValueChanged(int)));
+  for(unsigned int i=0; i<mSliders.size(); ++i){
+    signalMapper->setMapping(mSliders[i], i);
+    connect(mSliders[i], SIGNAL(valueChanged(int)), signalMapper, SLOT(map()));
+  }
   UpdateExtent();
 }
 //------------------------------------------------------------------------------
@@ -318,30 +246,22 @@ void vvToolCropImage::apply()
   int n = mCurrentSlicerManager->GetDimension()*2;  // 2D and 3D only
   mArgsInfo.boundingBox_given = n;
   mArgsInfo.boundingBox_arg = new int[n];
-  mArgsInfo.boundingBox_arg[0] = xminSlider->value();
-  mArgsInfo.boundingBox_arg[1] = xmaxSlider->value();
-  mArgsInfo.boundingBox_arg[2] = yminSlider->value();
-  mArgsInfo.boundingBox_arg[3] = ymaxSlider->value();
-  if (n>3) { // 3D
-    mArgsInfo.boundingBox_arg[4] = zminSlider->value();
-    mArgsInfo.boundingBox_arg[5] = zmaxSlider->value();
+  
+  for(int dim=0; dim<mCurrentSlicerManager->GetDimension() && dim<3; ++dim){
+    mArgsInfo.boundingBox_arg[dim*2] = mSliders[dim*2]->value();
+    mArgsInfo.boundingBox_arg[dim*2+1] = mSliders[dim*2+1]->value();
   }
-
   if (n>6) { // 4D
-    // mArgsInfo.boundingBox_arg[6] = tminSlider->value();
-    // mArgsInfo.boundingBox_arg[7] = tmaxSlider->value();
     mArgsInfo.boundingBox_arg[6] = 0;
     mArgsInfo.boundingBox_arg[7] = mCurrentImage->GetSize()[3]-1;
   }
-
   // We MUST reset initial extend to input image before using the
   // filter to retrieve the correct image size
   for(int i=0; i<mExtentSize; i++) {
     mReducedExtent[i] = mInitialExtent[i];
-    // DD(mArgsInfo.boundingBox_arg[i]);
   }
+  
   UpdateExtent();
-
   // Main filter
   CropFilterType::Pointer filter = CropFilterType::New();
   filter->SetInputVVImage(mCurrentImage);
@@ -354,50 +274,20 @@ void vvToolCropImage::apply()
   catch(clitk::ExceptionObject & e) {
     DD(e.what());
     QApplication::restoreOverrideCursor();
+    delete [] mArgsInfo.boundingBox_arg;
     close();
   }
-
+  std::ostringstream croppedImageName;
+  croppedImageName << "Cropped_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
   // Retrieve result and display it
   vvImage::Pointer output = filter->GetOutputVVImage();
-  std::ostringstream osstream;
-  osstream << "Croped_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
-  AddImage(output,osstream.str());
-
+  
+  AddImage(output,croppedImageName.str());
+  
   // End
   QApplication::restoreOverrideCursor();
+  delete [] mArgsInfo.boundingBox_arg;
   close();
-
-  /** 
-      // OLD approach with VTK
-
-  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
-  vvImage::Pointer mResult=vvImage::New();
-  vvImage::Pointer image= mCurrentSlicerManager->GetImage();
-  for (std::vector<vtkImageData*>::const_iterator i=image->GetVTKImages().begin();
-       i!=image->GetVTKImages().end(); i++) {
-    vtkSmartPointer<vtkImageClip> filter=vtkSmartPointer<vtkImageClip>::New();
-    ///Vtk is very weird, you need to "translate the extent" to get the correct origin
-    //http://markmail.org/message/vndc2tr6kcabiakp#query:vtkImageClip%20origin+page:1+mid:6na7y57floutklvz+state:results
-    vtkSmartPointer<vtkImageTranslateExtent> translate=vtkSmartPointer<vtkImageTranslateExtent>::New();
-    filter->SetInput(*i);
-    filter->SetOutputWholeExtent(xminSlider->value(),xmaxSlider->value(),
-                                 yminSlider->value(),ymaxSlider->value(),
-                                 zminSlider->value(),zmaxSlider->value());
-    translate->SetTranslation(-xminSlider->value(),-yminSlider->value(),-zminSlider->value());
-    translate->SetInput(filter->GetOutput());
-    filter->ClipDataOn(); //Really create a cropped copy of the image
-    translate->Update();
-    vtkImageData* output=vtkImageData::New();
-    output->ShallowCopy(translate->GetOutput());
-    mResult->AddImage(output);
-  }
-  QApplication::restoreOverrideCursor();
-  std::ostringstream osstream;
-  osstream << "Crop_" << mCurrentSlicerManager->GetSlicer(0)->GetFileName() << ".mhd";
-  AddImage(mResult, osstream.str());
-  close();
-
-  **/
 }
 //------------------------------------------------------------------------------
 
index 76e5b6f5e58e613d5caba160edc52c3b5c445798..27a334c3de83c5b7d4e3db96bc0abeda7261b182 100644 (file)
@@ -21,7 +21,7 @@
 //qt
 #include <QtDesigner/QDesignerExportWidget>
 #include <QDialog>
-
+#include <QSlider>
 // vv
 #include "vvToolBase.h"
 #include "vvToolWidgetBase.h"
@@ -45,15 +45,9 @@ public slots:
   virtual void apply();
   virtual bool close();
   virtual void reject();
-  void sliderXMinValueChanged(int s);
-  void sliderXMaxValueChanged(int s);
-  void sliderYMinValueChanged(int s);
-  void sliderYMaxValueChanged(int s);
-  void sliderZMinValueChanged(int s);
-  void sliderZMaxValueChanged(int s);
-  void sliderTMinValueChanged(int s);
-  void sliderTMaxValueChanged(int s);
   void autoCropValueChanged(double v);
+  void sliderValueChanged(int id);
+
 
   //-----------------------------------------------------
   static void Initialize() {
@@ -71,6 +65,7 @@ public slots:
   void UpdateExtent();
   virtual void closeEvent(QCloseEvent *event);
 
+  std::vector<QSlider*> mSliders;
 }; // end class vvToolCropImage
 //------------------------------------------------------------------------------
 
index ac699cef92ca5062fe11a3f581bad785e37bd10c..01835f8cda5c82b7e043f240b153c9bde3e8d9a9 100644 (file)
@@ -19,7 +19,7 @@
 #include "vvToolManager.h"
 #include "vvToolCreatorBase.h"
 #include "vvMainWindowBase.h"
-
+#include <QAction>
 //------------------------------------------------------------------------------
 /// Unique static instance
 vvToolManager* vvToolManager::mSingleton=0;
@@ -55,3 +55,13 @@ void vvToolManager::InsertToolsInMenu(vvMainWindowBase * m)
 }
 //------------------------------------------------------------------------------
 
+
+//------------------------------------------------------------------------------
+void vvToolManager::EnableToolsInMenu(vvMainWindowBase * m, bool enable){
+  std::vector<vvToolCreatorBase *>::iterator it;
+  for(it=GetInstance()->mListOfTools.begin(); it!=GetInstance()->mListOfTools.end(); ++it){
+    if((*it)->mAction){
+      (*it)->mAction->setEnabled(enable);
+    }
+  }
+}
index 1c62f16aed98d09e647395fd09233e1cb8a8d091..82d2e5bd4ea649589829f72465cfabdb418b8cdb 100644 (file)
@@ -40,6 +40,9 @@ public:
   /// Called in MainWindow, insert all tools into the menu
   static void InsertToolsInMenu(vvMainWindowBase * m);
   
+  /// Called in MainWindow, make the tools enabled/disabled
+  static void EnableToolsInMenu(vvMainWindowBase * m, bool enable);
+
 protected:
 
   /// Singleton object pointer
index 16d53cb91cce2c0bcf8d5ed9dfe10c7e2bf693aa..151435faaf2c4d8f7f8480eaa79101029c431ba5 100644 (file)
@@ -137,6 +137,7 @@ void vvToolStructureSetManager::InputIsSelected(vvSlicerManager *m)
   if (mCurrentImage->GetNumberOfDimensions() != 3) {
     QMessageBox::information(this,tr("Sorry only 3D yet"), tr("Sorry only 3D yet"));
     close();
+    return;
   }
   // Hide selector
   HideInputSelector(); // splitter
index 441b4b3731970f44b92e8a7a013b6f5219ebf3d8..3ef9cc606b2d6d7a87a6ee97b2699ce01056aadf 100644 (file)
   - BSD        See included LICENSE.txt file
   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
 ===========================================================================**/
-#include <fstream>
+#include <sstream>
 #include <algorithm>
 #include <QDir>
-
 #include "clitkCommon.h"
 #include "vvUtils.h"
 
 const std::string vv_user_file=".vv_settings.txt";
+const std::string recentFileList="recentFiles";
 typedef std::list<std::string> FileListType;
 
+QString getVVSettingsPath(){
+  return QDir::homePath()+QString::fromStdString("/"+vv_user_file);
+}
+
+QSettings::Format getSettingsOptionFormat(){
+  return QSettings::IniFormat;
+}
+
 ///Returns the last images opened by the user
 FileListType GetRecentlyOpenedImages()
 {
-  std::ifstream in((QDir::homePath().toStdString() + "/" + vv_user_file).c_str());
-  std::string current_file;
+  QSettings settings(getVVSettingsPath(), getSettingsOptionFormat());
   FileListType result;
-  in >> current_file;
-  while (in.good()) {
-    result.push_back(current_file);
-    in >> current_file;
-  }
-  in.close();
+  settings.beginGroup(QString::fromStdString(recentFileList));
+    QStringList keys = settings.childKeys();
+    for(int i=0; i<keys.size(); i++){
+      std::string value=settings.value(QString::fromStdString (keys[i].toStdString())).toString().toStdString();
+      result.push_back(value);
+    }
+  settings.endGroup();
   return result;
 }
 
 ///Adds an image to the list of recently opened images
 void AddToRecentlyOpenedImages(std::string filename)
 {
+  QSettings settings(getVVSettingsPath(), getSettingsOptionFormat());
   FileListType file_list = GetRecentlyOpenedImages();
+  
   FileListType::iterator i = std::find(file_list.begin(),file_list.end(),filename);
   if (i != file_list.end()) // avoid dupes
     file_list.erase(i);
   while (file_list.size() >= 6) //keep list to a reasonable size
     file_list.pop_back();
   file_list.push_front(filename);
-  std::ofstream out((QDir::homePath().toStdString() + "/" + vv_user_file).c_str(),std::ios_base::out | std::ios_base::trunc);
-  for (FileListType::iterator j = file_list.begin() ; j != file_list.end() ; j++)
-    out << (*j) << std::endl;
-  out.close();
+  
+  settings.beginGroup(QString::fromStdString(recentFileList));
+    int index=0;
+    for (FileListType::iterator j = file_list.begin() ; j != file_list.end() ; j++){
+      QString s=QString(index++);
+      settings.setValue(s, QString::fromStdString ( *j ));
+    }
+  settings.endGroup();
 }
+
index f8631dd8f09af720b639f25ad2a970d60f4ff1c6..5854b5b6141c6e6221acf7d4ddf4faf1b4d7a908 100644 (file)
@@ -19,6 +19,7 @@
 #define vvXXX_h
 #include <list>
 #include <string>
+#include <QSettings>
 
 ///Returns the last images opened by the user
 std::list<std::string> GetRecentlyOpenedImages();
@@ -26,4 +27,10 @@ std::list<std::string> GetRecentlyOpenedImages();
 ///Adds an image to the list of recently opened images
 void AddToRecentlyOpenedImages(std::string filename);
 
+///path to user settings
+QString getVVSettingsPath();
+
+///by default nativeFormat
+QSettings::Format getSettingsOptionFormat();
+
 #endif
diff --git a/vv/write.php b/vv/write.php
new file mode 100644 (file)
index 0000000..18a9579
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+define('HIDDEN_DATABASE_FILE_NAME', './customers.csv');
+$file=fopen(HIDDEN_DATABASE_FILE_NAME, 'a');
+if($file===FALSE)exit(1);
+define('TOKEN_CSV', '|');
+define('ENTRY_SEPARATOR', "\n");
+define('NAME_LENGTH', 30);
+define('EMAIL_LENGTH', 40);
+define('GROUP_LENGTH', 30);
+define('OS_LENGTH', 20);
+define('VV_VERSION_LENGTH', 30);
+define('COUNTRY_LENGTH', 30); 
+define('ARCHITECTURE_LENGTH',10);
+define('ADRESSING_LENGTH',10);
+define('COMPILATION_DATE_LENGTH', 30); 
+function ensureString($var, $length){
+  $var = str_replace("\n", '',$var);
+  $var = str_replace(TOKEN_CSV, '', $var);
+  return substr($var, 0, $length);
+}
+function writeLine($file, $data){
+ fwrite($file, implode(TOKEN_CSV, $data).ENTRY_SEPARATOR);
+}
+$data['name']    = ensureString($_GET['name'], NAME_LENGTH);
+$data['lastname'] = ensureString($_GET['lastName'], NAME_LENGTH);
+$data['email']   = ensureString($_GET['email'], EMAIL_LENGTH);
+$data['group']   = ensureString($_GET['group'], GROUP_LENGTH);
+$data['ip']      = $_SERVER['REMOTE_ADDR'];
+$data['os']      = ensureString($_GET['os'], OS_LENGTH);
+$data['vvVersion']= ensureString($_GET['vvVersion'], VV_VERSION_LENGTH);
+$data['time']    = date("F j, Y, g:i a");
+$data['geoloc']          = ensureString(file_get_contents('http://api.hostip.info/country.php?ip='.$_SERVER['REMOTE_ADDR']), COUNTRY_LENGTH);
+$data['architecture'] = ensureString($_GET['architecture'], ARCHITECTURE_LENGTH);
+$data['adressing'] = ensureString($_GET['adressing'], ADRESSING_LENGTH);
+$data['compilationDate'] = ensureString($_GET['compilationDate'], COMPILATION_DATE_LENGTH);
+writeLine($file, $data);
+fclose();