diff --git a/Core/Code/Testing/CMakeLists.txt b/Core/Code/Testing/CMakeLists.txt
index 2e3e2808a3..cbff306220 100644
--- a/Core/Code/Testing/CMakeLists.txt
+++ b/Core/Code/Testing/CMakeLists.txt
@@ -1,26 +1,29 @@
MITK_CREATE_MODULE_TESTS(LABELS MITK-Core)
# MITK_INSTALL_TARGETS(EXECUTABLES MitkTestDriver)
mitkAddCustomModuleTest(mitkPicFileReaderTest_emptyFile mitkPicFileReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/Data/emptyFile.pic)
mitkAddCustomModuleTest(mitkPicFileReaderTest_emptyGzipFile mitkPicFileReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/Data/emptyFile.pic.gz)
mitkAddCustomModuleTest(mitkDICOMLocaleTest_spacingOk_CT mitkDICOMLocaleTest ${MITK_DATA_DIR}/spacing-ok-ct.dcm)
mitkAddCustomModuleTest(mitkDICOMLocaleTest_spacingOk_MR mitkDICOMLocaleTest ${MITK_DATA_DIR}/spacing-ok-mr.dcm)
mitkAddCustomModuleTest(mitkDICOMLocaleTest_spacingOk_SC mitkDICOMLocaleTest ${MITK_DATA_DIR}/spacing-ok-sc.dcm)
mitkAddCustomModuleTest(mitkEventMapperTest_Test1And2 mitkEventMapperTest ${MITK_DATA_DIR}/TestStateMachine1.xml ${MITK_DATA_DIR}/TestStateMachine2.xml)
mitkAddCustomModuleTest(mitkNodeDependentPointSetInteractorTest mitkNodeDependentPointSetInteractorTest ${MITK_DATA_DIR}/Pic3D.pic.gz ${MITK_DATA_DIR}/BallBinary30x30x30.pic.gz)
mitkAddCustomModuleTest(mitkDataStorageTest_US4DCyl mitkDataStorageTest ${MITK_DATA_DIR}/US4DCyl.pic.gz)
mitkAddCustomModuleTest(mitkStateMachineFactoryTest_TestStateMachine1_2 mitkStateMachineFactoryTest ${MITK_DATA_DIR}/TestStateMachine1.xml ${MITK_DATA_DIR}/TestStateMachine2.xml)
ADD_TEST(mitkPointSetLocaleTest ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkPointSetLocaleTest ${MITK_DATA_DIR}/pointSet.mps)
SET_PROPERTY(TEST mitkPointSetLocaleTest PROPERTY LABELS MITK-Core)
ADD_TEST(mitkPicFileReaderTest_emptyGzipFile ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkPicFileReaderTest ${CMAKE_CURRENT_SOURCE_DIR}/Data/emptyFile.pic.gz)
SET_PROPERTY(TEST mitkPicFileReaderTest_emptyGzipFile PROPERTY LABELS MITK-Core)
ADD_TEST(mitkImageTest_brainImage ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTDRIVER} mitkImageTest ${MITK_DATA_DIR}/brain.mhd)
SET_PROPERTY(TEST mitkImageTest_brainImage PROPERTY LABELS MITK-Core)
+
+add_subdirectory(DICOMTesting)
+
diff --git a/Core/Code/Testing/DICOMTesting/CMakeLists.txt b/Core/Code/Testing/DICOMTesting/CMakeLists.txt
new file mode 100644
index 0000000000..2ba6f34a77
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/CMakeLists.txt
@@ -0,0 +1,35 @@
+if (BUILD_TESTING)
+if (MITK_USE_GDCMIO)
+if (GDCM_DIR)
+
+# clear variables from prior files.cmake
+set(MODULE_TESTS)
+set(MODULE_IMAGE_TESTS)
+set(MODULE_TESTIMAGES)
+set(MODULE_CUSTOM_TESTS)
+set(H_FILES)
+set(CPP_FILES)
+
+# now create a new module only for testing purposes
+MITK_CREATE_MODULE( mitkDICOMTesting
+ DEPENDS Mitk # mitkCore.so
+)
+
+
+# add helpful applications
+MITK_USE_MODULE( mitkDICOMTesting )
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${ALL_INCLUDE_DIRECTORIES})
+
+# dumps out image information
+add_executable(DumpDICOMMitkImage DumpDICOMMitkImage.cpp)
+target_link_libraries(DumpDICOMMitkImage ${ALL_LIBRARIES})
+
+# compares dumped out image information against reference dump
+add_executable(VerifyDICOMMitkImageDump VerifyDICOMMitkImageDump.cpp)
+target_link_libraries(VerifyDICOMMitkImageDump ${ALL_LIBRARIES})
+
+add_subdirectory(Testing)
+
+endif()
+endif()
+endif()
diff --git a/Core/Code/Testing/DICOMTesting/DICOMTesting.dox b/Core/Code/Testing/DICOMTesting/DICOMTesting.dox
new file mode 100644
index 0000000000..4fb69d36b1
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/DICOMTesting.dox
@@ -0,0 +1,78 @@
+/**
+
+\page DICOMTesting MITK DICOM testing
+
+\section DICOMTesting_introduction Introduction
+
+Since loading a set of DICOM images is not a trivial task, MITK implements some tests
+which verify its DICOM loading ability.
+
+\section DICOMTesting_problem Problem description
+
+The task of loading DICOM files into mitk::Images is a challenge because of major differences
+in the way that DICOM and MITK represent images:
+
+ - DICOM images
+ - are mostly stored as one slice per file
+ - do not describe how they can be arraged into image stacks with orthogonal axis
+ - sometimes they cannot be arranged in image stacks as described above (e.g. tilted gantry)
+ - mitk::Image (at least its mature areas)
+ - represents image stacks with orthogonal axis (nothing like a tilted gantry)
+ - have a concept of a fourth dimension (time steps)
+
+Because image processing applications based on MITK still need a way to load DICOM images into
+mitk::Image objects, MITK needs to put a lot of effort into building image stacks as best as it can. And this needs to be well tested.
+
+For more background information, see David Clunie's most valuable posts on comp.protocols.dicom, e.g.:
+
+ - http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/6db91972e161f0d4/6e0304ac264a6eb5
+ - http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/e9bd1497bea3e66b/187a7dc8810613d2
+ - http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/5d80bb0b7fafcb81/cf96119e3b024ed8
+ - http://groups.google.com/group/comp.protocols.dicom/browse_thread/thread/4568635e083a3fba/e2a8ceec23032601
+
+\section DICOMTesting_testidea Test principle
+
+The test idea is simple: load known sets of DICOM files,
+analyze relevant aspects of the generated mitk::Image
+objects and compare against stored expected results:
+ - number of 3D images generated
+ - origin, orientation
+ - pixel type, spacing, extent
+
+\section DICOMTesting_implementation Implementation
+
+\section DICOMTesting_implementation_utils Test helpers (applications and classes)
+
+Application DumpDICOMMitkImage
+
+Takes a list of DICOM images, loads them using TestDICOMLoading, then dumps information
+about the resulting mitk::Images to standard output.
+
+This application is helpful when defining reference data for tests.
+
+Application VerifyDICOMMitkImageDump
+
+Takes a list of DICOM images and loads them using TestDICOMLoading.
+Takes a dump file as generated by DumpDICOMMitkImage, parses it and
+compares it to actually generated mitk::Images.
+
+This application is used to implement the majority of test cases. They all
+load images, then verify the expected result structure.
+
+Class TestDICOMLoading
+
+\section DICOMTesting_testlist Specific tests
+
+This list is meant to provide an up-to-date list of all implemented DICOM loading tests.
+If you ever find this outdated, please update it or make the persons who invalidated the list update it.
+
+mitkDICOMTestingSanityTest_*
+These tests implement basic testing of the implemented helper classes. The tests use DicomSeriesReader to load
+a number of DICOM image. They verify:
+ - DicomSeriesReader recognizes all input files as DICOM images
+ - DicomSeriesReader generates a number of mitk::Images from the DICOM images
+ - the number of mitk::Images matches a number given on the command line or CTest's add_test()
+ - helper methods in class TestDICOMLoading make minimal sense (comparison of an image dump to itself must be valid)
+
+*/
+
diff --git a/Core/Code/Testing/DICOMTesting/DumpDICOMMitkImage.cpp b/Core/Code/Testing/DICOMTesting/DumpDICOMMitkImage.cpp
new file mode 100644
index 0000000000..f7e0522545
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/DumpDICOMMitkImage.cpp
@@ -0,0 +1,26 @@
+#include "mitkTestDICOMLoading.h"
+
+int main(int argc, char** argv)
+{
+ mitk::TestDICOMLoading loader;
+ mitk::TestDICOMLoading::StringContainer files;
+
+ for (int arg = 1; arg < argc; ++arg) files.push_back( argv[arg] );
+
+ mitk::TestDICOMLoading::ImageList images = loader.LoadFiles(files);
+
+ // combine individual dumps in a way that VerifyDICOMMitkImageDump is able to separate again.
+ // I.e.: when changing this piece of code, always change VerifyDICOMMitkImageDump, too.
+ unsigned int imageCounter(0);
+ for ( mitk::TestDICOMLoading::ImageList::const_iterator imageIter = images.begin();
+ imageIter != images.end();
+ ++imageIter )
+ {
+ std::cout << "--------------------------------------------------------------------------------\n";
+ std::cout << "-- Image " << ++imageCounter;
+ std::cout << "--------------------------------------------------------------------------------\n";
+ std::cout << loader.DumpImageInformation( *imageIter ) << "\n";
+ std::cout << "--------------------------------------------------------------------------------\n";
+ }
+}
+
diff --git a/Core/Code/Testing/DICOMTesting/Testing/CMakeLists.txt b/Core/Code/Testing/DICOMTesting/Testing/CMakeLists.txt
new file mode 100644
index 0000000000..8ab610c5d9
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/Testing/CMakeLists.txt
@@ -0,0 +1,11 @@
+
+MITK_CREATE_MODULE_TESTS(LABELS MITK-Core)
+
+# verify minimum expectations:
+# files are recognized as DICOM
+# loading files results in a given number of images
+mitkAddCustomModuleTest(mitkDICOMTestingSanityTest_NoFiles mitkDICOMTestingSanityTest 0)
+mitkAddCustomModuleTest(mitkDICOMTestingSanityTest_CTImage mitkDICOMTestingSanityTest 1 ${MITK_DATA_DIR}/spacing-ok-ct.dcm)
+mitkAddCustomModuleTest(mitkDICOMTestingSanityTest_MRImage mitkDICOMTestingSanityTest 1 ${MITK_DATA_DIR}/spacing-ok-mr.dcm)
+mitkAddCustomModuleTest(mitkDICOMTestingSanityTest_SCImage mitkDICOMTestingSanityTest 1 ${MITK_DATA_DIR}/spacing-ok-sc.dcm)
+
diff --git a/Core/Code/Testing/DICOMTesting/Testing/files.cmake b/Core/Code/Testing/DICOMTesting/Testing/files.cmake
new file mode 100644
index 0000000000..92af05e67b
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/Testing/files.cmake
@@ -0,0 +1,6 @@
+
+# tests with no extra command line parameter
+SET(MODULE_CUSTOM_TESTS
+ mitkDICOMTestingSanityTest.cpp
+)
+
diff --git a/Core/Code/Testing/DICOMTesting/Testing/mitkDICOMTestingSanityTest.cpp b/Core/Code/Testing/DICOMTesting/Testing/mitkDICOMTestingSanityTest.cpp
new file mode 100644
index 0000000000..eb4da0b568
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/Testing/mitkDICOMTestingSanityTest.cpp
@@ -0,0 +1,54 @@
+
+
+#include "mitkTestDICOMLoading.h"
+#include "mitkTestingMacros.h"
+
+int mitkDICOMTestingSanityTest(int argc, char** argv)
+{
+ MITK_TEST_BEGIN("DICOMTestingSanity")
+
+ mitk::TestDICOMLoading loader;
+ mitk::TestDICOMLoading::StringContainer files;
+
+ // adapt expectations depending on configuration
+ std::string configuration = mitk::DicomSeriesReader::GetConfigurationString();
+ MITK_TEST_OUTPUT(<< "Configuration: " << configuration)
+ /*
+ MITK_TEST_CONDITION_REQUIRED( configuration.find( "GDCM_VERSION: 2." ) != std::string::npos,
+ "Expect at least GDCM version 2" )
+ */
+
+ // load files from commandline
+ int numberOfExpectedImages = 0;
+ if (argc > 1) numberOfExpectedImages = atoi(argv[1]);
+ for (int arg = 2; arg < argc; ++arg) files.push_back( argv[arg] );
+
+ // verify all files are DICOM
+ for (mitk::TestDICOMLoading::StringContainer::const_iterator fileIter = files.begin();
+ fileIter != files.end();
+ ++fileIter)
+ {
+ MITK_TEST_CONDITION_REQUIRED( mitk::DicomSeriesReader::IsDicom(*fileIter) , *fileIter << " is recognized as loadable DICOM object" )
+
+ }
+
+ // compare with expected number of images from commandline
+ mitk::TestDICOMLoading::ImageList images = loader.LoadFiles(files);
+ MITK_TEST_CONDITION_REQUIRED( images.size() == numberOfExpectedImages, "Loading " << files.size()
+ << " files from commandline results in " << numberOfExpectedImages
+ << " images (see test invocation)" )
+
+ // check dump equality (dumping image information must always equal itself)
+ for ( mitk::TestDICOMLoading::ImageList::const_iterator imageIter = images.begin();
+ imageIter != images.end();
+ ++imageIter )
+ {
+ const mitk::Image* image = *imageIter;
+ MITK_TEST_CONDITION( loader.CompareImageInformationDumps( loader.DumpImageInformation(image),
+ loader.DumpImageInformation(image) ) == true,
+ "Image information dumping is able to reproduce its result." )
+ }
+
+ MITK_TEST_END()
+}
+
diff --git a/Core/Code/Testing/DICOMTesting/VerifyDICOMMitkImageDump.cpp b/Core/Code/Testing/DICOMTesting/VerifyDICOMMitkImageDump.cpp
new file mode 100644
index 0000000000..cd4ba9a06a
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/VerifyDICOMMitkImageDump.cpp
@@ -0,0 +1,31 @@
+
+#include "mitkTestDICOMLoading.h"
+
+int main(int argc, char** argv)
+{
+ /**
+ Loads a list of DICOM images, compares generated mitk::Images against stored references.
+
+ first argument: file with reference dumps
+ following arguments: file names to load
+ */
+ mitk::TestDICOMLoading loader;
+ mitk::TestDICOMLoading::StringContainer files;
+
+ // TODO load reference dumps
+
+ for (int arg = 2; arg < argc; ++arg) files.push_back( argv[arg] );
+
+ mitk::TestDICOMLoading::ImageList images = loader.LoadFiles(files);
+
+ unsigned int imageCounter(0);
+ for ( mitk::TestDICOMLoading::ImageList::const_iterator imageIter = images.begin();
+ imageIter != images.end();
+ ++imageIter )
+ {
+ std::string imageDump = loader.DumpImageInformation( *imageIter );
+
+ // TODO compare against reference
+ }
+}
+
diff --git a/Core/Code/Testing/DICOMTesting/files.cmake b/Core/Code/Testing/DICOMTesting/files.cmake
new file mode 100644
index 0000000000..f6fd6ff9d6
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/files.cmake
@@ -0,0 +1,4 @@
+
+SET(CPP_FILES
+ mitkTestDICOMLoading.cpp
+)
diff --git a/Core/Code/Testing/DICOMTesting/mitkTestDICOMLoading.cpp b/Core/Code/Testing/DICOMTesting/mitkTestDICOMLoading.cpp
new file mode 100644
index 0000000000..7bf5d72949
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/mitkTestDICOMLoading.cpp
@@ -0,0 +1,299 @@
+#define MBILOG_ENABLE_DEBUG
+
+#include "mitkTestDICOMLoading.h"
+
+#include
+
+mitk::TestDICOMLoading::TestDICOMLoading()
+{
+ MITK_INFO << "TestDICOMLoading()";
+}
+
+void mitk::TestDICOMLoading::SetDefaultLocale()
+{
+ // remember old locale only once
+ if (m_PreviousCLocale == NULL)
+ {
+ m_PreviousCLocale = setlocale(LC_NUMERIC, NULL);
+
+ // set to "C"
+ setlocale(LC_NUMERIC, "C");
+
+ m_PreviousCppLocale = std::cin.getloc();
+
+ std::locale l( "C" );
+ std::cin.imbue(l);
+ std::cout.imbue(l);
+ }
+}
+
+void mitk::TestDICOMLoading::ResetUserLocale()
+{
+ if (m_PreviousCLocale)
+ {
+ setlocale(LC_NUMERIC, m_PreviousCLocale);
+
+ std::cin.imbue(m_PreviousCppLocale);
+ std::cout.imbue(m_PreviousCppLocale);
+
+ m_PreviousCLocale = NULL;
+ }
+}
+
+
+
+mitk::TestDICOMLoading::ImageList mitk::TestDICOMLoading::LoadFiles( const StringContainer& files )
+{
+ for (StringContainer::const_iterator iter = files.begin();
+ iter != files.end();
+ ++iter)
+ {
+ MITK_DEBUG << "File " << *iter;
+ }
+
+ StringContainer sortedFiles = DicomSeriesReader::SortSeriesSlices( files );
+
+ DataNode::Pointer node = DicomSeriesReader::LoadDicomSeries( sortedFiles );
+
+ ImageList result;
+
+ if (node.IsNotNull())
+ {
+ Image::Pointer image = dynamic_cast( node->GetData() );
+
+ result.push_back( image );
+ }
+ else
+ {
+ }
+
+ return result;
+}
+
+// add a line to stringstream result (see DumpImageInformation
+#define DumpLine(field, data) DumpILine(0, field, data)
+
+// add an indented(!) line to stringstream result (see DumpImageInformation
+#define DumpILine(indent, field, data) \
+{ \
+ std::string DumpLine_INDENT; DumpLine_INDENT.resize(indent, ' ' ); \
+ result << DumpLine_INDENT << field << ": " << data << "\n"; \
+}
+
+std::string
+mitk::TestDICOMLoading::DumpImageInformation( const Image* image )
+{
+ std::stringstream result;
+
+ if (image == NULL) return result.str();
+
+ SetDefaultLocale();
+
+ // basic image data
+ DumpLine( "Pixeltype", image->GetPixelType().GetTypeId()->name() );
+ DumpLine( "BitsPerPixel", image->GetPixelType().GetBpe() );
+ DumpLine( "Dimension", image->GetDimension() );
+
+ result << "Dimensions: ";
+ for (unsigned int dim = 0; dim < image->GetDimension(); ++dim)
+ result << image->GetDimension(dim) << " ";
+ result << "\n";
+
+ // geometry data
+ result << "Geometry: \n";
+ Geometry3D* geometry = image->GetGeometry();
+ if (geometry)
+ {
+ AffineTransform3D* transform = geometry->GetIndexToWorldTransform();
+ if (transform)
+ {
+ result << " " << "Matrix: ";
+ const AffineTransform3D::MatrixType& matrix = transform->GetMatrix();
+ for (unsigned int i = 0; i < 3; ++i)
+ for (unsigned int j = 0; j < 3; ++j)
+ result << matrix[i][j] << " ";
+ result << "\n";
+
+ result << " " << "Offset: ";
+ const AffineTransform3D::OutputVectorType& offset = transform->GetOffset();
+ for (unsigned int i = 0; i < 3; ++i)
+ result << offset[i] << " ";
+ result << "\n";
+
+ result << " " << "Center: ";
+ const AffineTransform3D::InputPointType& center = transform->GetCenter();
+ for (unsigned int i = 0; i < 3; ++i)
+ result << center[i] << " ";
+ result << "\n";
+
+ result << " " << "Translation: ";
+ const AffineTransform3D::OutputVectorType& translation = transform->GetTranslation();
+ for (unsigned int i = 0; i < 3; ++i)
+ result << translation[i] << " ";
+ result << "\n";
+
+ result << " " << "Scale: ";
+ const double* scale = transform->GetScale();
+ for (unsigned int i = 0; i < 3; ++i)
+ result << scale[i] << " ";
+ result << "\n";
+
+ result << " " << "Origin: ";
+ const Point3D& origin = geometry->GetOrigin();
+ for (unsigned int i = 0; i < 3; ++i)
+ result << origin[i] << " ";
+ result << "\n";
+
+ result << " " << "Spacing: ";
+ const Vector3D& spacing = geometry->GetSpacing();
+ for (unsigned int i = 0; i < 3; ++i)
+ result << spacing[i] << " ";
+ result << "\n";
+
+ result << " " << "TimeBounds: ";
+ const TimeBounds timeBounds = geometry->GetTimeBounds();
+ for (unsigned int i = 0; i < 2; ++i)
+ result << timeBounds[i] << " ";
+ result << "\n";
+
+
+ }
+ }
+
+ ResetUserLocale();
+
+ MITK_DEBUG << "\n----------------------------------------\n"
+ << result.str()
+ << "----------------------------------------\n";
+
+ return result.str();
+}
+
+bool
+mitk::TestDICOMLoading::CompareSpacedValueFields( const std::string& reference,
+ const std::string& test,
+ double eps )
+{
+ // TODO this should better do a real comparison and tolerate float differences up to 'eps'
+
+ return reference == test;
+}
+
+bool
+mitk::TestDICOMLoading::CompareImageInformationDumps( const std::string& referenceDump,
+ const std::string& testDump )
+{
+ KeyValueMap reference = ParseDump(referenceDump);
+ KeyValueMap test = ParseDump(testDump);
+
+ bool testResult(true);
+
+ // verify all expected values
+ for (KeyValueMap::const_iterator refIter = reference.begin();
+ refIter != reference.end();
+ ++refIter)
+ {
+ const std::string& refKey = refIter->first;
+ const std::string& refValue = refIter->second;
+
+ if ( reference.find(refKey) != reference.end() )
+ {
+ const std::string& testValue = test[refKey];
+
+ testResult &= CompareSpacedValueFields( refValue, testValue );
+ }
+ else
+ {
+ MITK_ERROR << "Reference dump contains a key'" << refKey << "' (value '" << refValue << "')." ;
+ MITK_ERROR << "This key is expected to be generated for tests (but was not). Most probably you need to update your test data.";
+ return false;
+ }
+ }
+
+ // now check test dump does not contain any additional keys
+ for (KeyValueMap::const_iterator testIter = test.begin();
+ testIter != test.end();
+ ++testIter)
+ {
+ const std::string& key = testIter->first;
+ const std::string& value = testIter->second;
+
+ if ( reference.find(key) == reference.end() )
+ {
+ MITK_ERROR << "Test dump contains an unexpected key'" << key << "' (value '" << value << "')." ;
+ MITK_ERROR << "This key is not expected. Most probably you need to update your test data.";
+ return false;
+ }
+ }
+
+ return testResult;
+}
+
+mitk::TestDICOMLoading::KeyValueMap
+mitk::TestDICOMLoading::ParseDump( const std::string& dump )
+{
+ KeyValueMap parsedResult;
+
+ std::string shredder(dump);
+
+ std::stack surroundingKeys;
+
+ std::stack expectedIndents;
+ expectedIndents.push(0);
+
+ while (true)
+ {
+ std::string::size_type newLinePos = shredder.find( '\n' );
+ if (newLinePos == std::string::npos) break;
+
+ std::string line = shredder.substr( 0, newLinePos );
+ shredder = shredder.erase( 0, newLinePos+1 );
+
+ MITK_DEBUG << "Line: '" << line << "'";
+
+ std::string::size_type keyPosition = line.find_first_not_of( ' ' );
+ std::string::size_type colonPosition = line.find( ':' );
+
+ std::string key = line.substr(keyPosition, colonPosition - keyPosition);
+ std::string::size_type firstSpacePosition = key.find_first_of(" ");
+ if (firstSpacePosition != std::string::npos)
+ {
+ key.erase(firstSpacePosition);
+ }
+
+ if ( keyPosition > expectedIndents.top() )
+ {
+ // more indent than before
+ expectedIndents.push(keyPosition);
+ }
+ else if (keyPosition == expectedIndents.top() )
+ {
+ if (!surroundingKeys.empty())
+ {
+ surroundingKeys.pop(); // last of same length
+ }
+ }
+ else
+ {
+ // less indent than before
+ do expectedIndents.pop();
+ while (expectedIndents.top() != keyPosition); // unwind until current indent is found
+ }
+
+ if (!surroundingKeys.empty())
+ {
+ key = surroundingKeys.top() + "." + key; // construct current key name
+ }
+
+ surroundingKeys.push(key); // this is the new embracing key
+
+ std::string value = line.substr(colonPosition+1);
+
+ MITK_DEBUG << " Key: '" << key << "' value '" << value << "'" ;
+
+ parsedResult[key] = value; // store parsing result
+ }
+
+ return parsedResult;
+}
+
diff --git a/Core/Code/Testing/DICOMTesting/mitkTestDICOMLoading.h b/Core/Code/Testing/DICOMTesting/mitkTestDICOMLoading.h
new file mode 100644
index 0000000000..833adc0c57
--- /dev/null
+++ b/Core/Code/Testing/DICOMTesting/mitkTestDICOMLoading.h
@@ -0,0 +1,60 @@
+#ifndef mitkTestDICOMLoading_h
+#define mitkTestDICOMLoading_h
+
+#include "mitkDicomSeriesReader.h"
+
+namespace mitk
+{
+
+class TestDICOMLoading
+{
+ public:
+
+ typedef DicomSeriesReader::StringContainer StringContainer;
+ typedef std::list NodeList;
+ typedef std::list ImageList;
+
+ TestDICOMLoading();
+
+ ImageList
+ LoadFiles( const StringContainer& files );
+
+ /**
+ \brief Dump relevant image information for later comparison.
+ \sa CompareImageInformationDumps
+ */
+ std::string
+ DumpImageInformation( const Image* image );
+
+ /**
+ \brief Compare two image information dumps.
+ \return true, if dumps are sufficiently equal (see parameters)
+ \sa DumpImageInformation
+ */
+ bool
+ CompareImageInformationDumps( const std::string& reference,
+ const std::string& test );
+
+ private:
+
+ typedef std::map KeyValueMap;
+
+ void SetDefaultLocale();
+
+ void ResetUserLocale();
+
+ KeyValueMap ParseDump( const std::string& dump );
+
+ bool CompareSpacedValueFields( const std::string& reference,
+ const std::string& test,
+ double eps = mitk::eps );
+
+ const char* m_PreviousCLocale;
+ std::locale m_PreviousCppLocale;
+
+};
+
+}
+
+#endif
+