mirror of https://gitee.com/openkylin/gdcm.git
merge upstream 3.0.21
This commit is contained in:
parent
b753e6a8e2
commit
a01a6be004
|
@ -1,5 +1,9 @@
|
|||
appveyor.yml merge=ours
|
||||
* -whitespace
|
||||
|
||||
/Source/DataDictionary/gdcmDefaultDicts.cxx hooks.MaxObjectKiB=2048
|
||||
/Source/InformationObjectDefinition/Part3.xml hooks.MaxObjectKiB=4096
|
||||
/Source/DataDictionary/gdcmDefaultDicts.cxx hooks-max-size=1500000
|
||||
/Source/DataDictionary/gdcmPrivateDefaultDicts.cxx hooks-max-size=1500000
|
||||
/Source/DataDictionary/gdcmTagToType.h hooks-max-size=1500000
|
||||
/Source/InformationObjectDefinition/Part3.xml hooks-max-size=3000000
|
||||
/Source/DataDictionary/privatedicts.xml hooks-max-size=1500000
|
||||
/Utilities/gdcmopenjpeg/src/lib/openjp2/j2k.c hooks-max-size=750000
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
name: C/C++ CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "release" ]
|
||||
pull_request:
|
||||
branches: [ "release" ]
|
||||
|
||||
jobs:
|
||||
example_matrix:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: checkout source
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 2
|
||||
- name: configure
|
||||
run: cmake -DGDCM_BUILD_SHARED_LIBS=ON -DGDCM_BUILD_DOCBOOK_MANPAGES:BOOL=OFF -DCMAKE_BUILD_TYPE:STRING=None -B build
|
||||
- name: make
|
||||
run: cmake --build build
|
||||
- name: make check
|
||||
run: ctest --test-dir build --parallel 2 --output-on-failure || true
|
|
@ -0,0 +1,12 @@
|
|||
# back-up
|
||||
*~
|
||||
*.bak
|
||||
|
||||
# files when there are conflicts
|
||||
*.orig
|
||||
|
||||
# qtcreator files
|
||||
CMakeLists.txt.user*
|
||||
|
||||
# kdevelop files
|
||||
*.kdev*
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "Testing/Data"]
|
||||
path = Testing/Data
|
||||
url = git://git.code.sf.net/p/gdcm/gdcmdata
|
|
@ -73,9 +73,9 @@ before_install:
|
|||
#- if [ "$TRAVIS_OS_NAME" == "osx" ]; then virtualenv env -p python3 ; fi
|
||||
#- if [ "$TRAVIS_OS_NAME" == "osx" ]; then source env/bin/activate ; fi
|
||||
# kakadu setup for linux/system:
|
||||
- if [ "$B_NAME" == "system" ]; then wget http://kakadusoftware.com/wp-content/uploads/2014/06/KDU77_Demo_Apps_for_Linux-x86-64_150710.zip; fi
|
||||
- if [ "$B_NAME" == "system" ]; then unzip KDU77_Demo_Apps_for_Linux-x86-64_150710.zip; fi
|
||||
- if [ "$B_NAME" == "system" ]; then export PATH=$PATH:$PWD/KDU77_Demo_Apps_for_Linux-x86-64_150710; fi
|
||||
- if [ "$B_NAME" == "system" ]; then wget http://kakadusoftware.com/wp-content/uploads/KDU805_Demo_Apps_for_Linux-x86-64_200602.zip; fi
|
||||
- if [ "$B_NAME" == "system" ]; then unzip KDU805_Demo_Apps_for_Linux-x86-64_200602.zip; fi
|
||||
- if [ "$B_NAME" == "system" ]; then export PATH=$PATH:$PWD/KDU805_Demo_Apps_for_Linux-x86-64_200602; fi
|
||||
install: true
|
||||
before_script:
|
||||
- cmake -Wno-dev -G "Unix Makefiles" -DCMAKE_BUILD_TYPE:STRING=None -DGDCM_BUILD_TESTING:BOOL=ON -DGDCM_BUILD_APPLICATIONS:BOOL=ON -DGDCM_BUILD_SHARED_LIBS:BOOL=ON -DBUILDNAME:STRING=${TRAVIS_OS_NAME}-${TRAVIS_BRANCH}-${B_NAME} ${CMAKE_EXTRA} .
|
||||
|
|
2
AUTHORS
2
AUTHORS
|
@ -21,7 +21,7 @@ GDCM 2.x:
|
|||
Joel Spaltenstein : Developer (Mac OS X)
|
||||
|
||||
|
||||
GDCM 1.x (Developpers and contributors, alphabetical order)
|
||||
GDCM 1.x (Developers and contributors, alphabetical order)
|
||||
--------
|
||||
Aris Basic
|
||||
Fabrice Bellet
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# gdcmanon
|
||||
|
||||
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
if(WIN32 AND NOT CYGWIN AND NOT MINGW)
|
||||
include_directories(
|
||||
"${GDCM_SOURCE_DIR}/Utilities/getopt"
|
||||
)
|
||||
|
@ -46,6 +46,7 @@ set(GDCM_EXECUTABLE_NAME
|
|||
gdcmraw
|
||||
gdcmscanner
|
||||
gdcmanon
|
||||
gdcmclean
|
||||
gdcmgendir
|
||||
#gdcmoverlay
|
||||
gdcmimg
|
||||
|
@ -72,13 +73,12 @@ if(GDCM_USE_SYSTEM_POPPLER)
|
|||
if(LIBPOPPLER_GLOBALPARAMS_CSTOR_HAS_PARAM)
|
||||
list(APPEND libpoppler_flags -DLIBPOPPLER_GLOBALPARAMS_CSTOR_HAS_PARAM)
|
||||
endif()
|
||||
if(NOT LIBPOPPLER_GLOBALPARAMS_CSTOR_HAS_PARAM)
|
||||
CHECK_CXX_SOURCE_COMPILES(
|
||||
"\#include <poppler/GlobalParams.h>\nint main() { globalParams = new GlobalParams(); return 0;}"
|
||||
LIBPOPPLER_GLOBALPARAMS_IS_NOT_UNIQUE_PTR)
|
||||
if(NOT LIBPOPPLER_GLOBALPARAMS_IS_NOT_UNIQUE_PTR)
|
||||
list(APPEND libpoppler_flags -DLIBPOPPLER_GLOBALPARAMS_IS_UNIQUE_PTR)
|
||||
endif()
|
||||
"\#include <poppler/GlobalParams.h>\nint main() { globalParams.reset( new GlobalParams()); return 0;}"
|
||||
LIBPOPPLER_GLOBALPARAMS_HAS_RESET)
|
||||
set(libpoppler_flags)
|
||||
if(LIBPOPPLER_GLOBALPARAMS_HAS_RESET)
|
||||
list(APPEND libpoppler_flags -DLIBPOPPLER_GLOBALPARAMS_HAS_RESET)
|
||||
endif()
|
||||
CHECK_CXX_SOURCE_COMPILES(
|
||||
"\#include <poppler/PDFDoc.h>\nint main() { PDFDoc d((GooString*)NULL,(GooString*)NULL,(GooString*)NULL); d.getPDFVersion(); return 0;}"
|
||||
|
@ -110,6 +110,18 @@ if(GDCM_USE_SYSTEM_POPPLER)
|
|||
if(LIBPOPPLER_GOOSTRING_HAS_GETCSTRING)
|
||||
list(APPEND libpoppler_flags -DLIBPOPPLER_GOOSTRING_HAS_GETCSTRING)
|
||||
endif()
|
||||
CHECK_CXX_SOURCE_COMPILES(
|
||||
"\#include <poppler/UnicodeMap.h>\nint main() { Unicode u; char buf[8]; const UnicodeMap *uMap; uMap->mapUnicode(u, buf, sizeof(buf)); return 0; }"
|
||||
LIBPOPPLER_UNICODEMAP_HAS_CONSTMAPUNICODE)
|
||||
if(LIBPOPPLER_UNICODEMAP_HAS_CONSTMAPUNICODE)
|
||||
list(APPEND libpoppler_flags -DLIBPOPPLER_UNICODEMAP_HAS_CONSTMAPUNICODE)
|
||||
endif()
|
||||
CHECK_CXX_SOURCE_COMPILES(
|
||||
"\#include <poppler/PDFDoc.h>\nint main() { std::optional<GooString> ownerPW, userPW; PDFDoc d((BaseStream*)nullptr,ownerPW,userPW); return 0;}"
|
||||
LIBPOPPLER_PDFDOC_HAS_OPTIONAL)
|
||||
if(LIBPOPPLER_PDFDOC_HAS_OPTIONAL)
|
||||
list(APPEND libpoppler_flags -DLIBPOPPLER_PDFDOC_HAS_OPTIONAL)
|
||||
endif()
|
||||
if(libpoppler_flags)
|
||||
string(REPLACE ";" " " libpoppler_flags_string "${libpoppler_flags}")
|
||||
set_source_files_properties(
|
||||
|
@ -151,6 +163,12 @@ if(GDCM_USE_SYSTEM_PAPYRUS3)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(NOT GDCM_USE_SYSTEM_ZLIB)
|
||||
include_directories(
|
||||
"${GDCM_BINARY_DIR}/Utilities/gdcmzlib"
|
||||
)
|
||||
endif()
|
||||
|
||||
foreach(exename ${GDCM_EXECUTABLE_NAME})
|
||||
if(${exename} STREQUAL "gdcminfo")
|
||||
add_executable(${exename} ${exename}.cxx puff.c)
|
||||
|
@ -170,6 +188,8 @@ foreach(exename ${GDCM_EXECUTABLE_NAME})
|
|||
endif()
|
||||
elseif(${exename} STREQUAL "gdcmstream")
|
||||
target_link_libraries(${exename} ${GDCM_OPENJPEG_LIBRARIES})
|
||||
elseif(${exename} STREQUAL "gdcmdump")
|
||||
target_link_libraries(${exename} ${GDCM_ZLIB_LIBRARIES})
|
||||
elseif(${exename} STREQUAL "gdcminfo")
|
||||
if(GDCM_USE_SYSTEM_POPPLER)
|
||||
target_link_libraries(${exename} ${POPPLER_LIBRARIES})
|
||||
|
@ -178,7 +198,7 @@ foreach(exename ${GDCM_EXECUTABLE_NAME})
|
|||
if(GDCM_EXECUTABLE_PROPERTIES)
|
||||
set_target_properties(${exename} PROPERTIES ${GDCM_EXECUTABLE_PROPERTIES})
|
||||
endif()
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
if(WIN32 AND NOT CYGWIN AND NOT MINGW)
|
||||
target_link_libraries(${exename} gdcmgetopt)
|
||||
endif()
|
||||
if(NOT GDCM_INSTALL_NO_RUNTIME)
|
||||
|
|
|
@ -45,7 +45,9 @@ static void PrintVersion()
|
|||
|
||||
|
||||
static bool AnonymizeOneFileDumb(gdcm::Anonymizer &anon, const char *filename, const char *outfilename,
|
||||
std::vector<gdcm::Tag> const &empty_tags, std::vector<gdcm::Tag> const &remove_tags, std::vector< std::pair<gdcm::Tag, std::string> > const & replace_tags, bool continuemode = false)
|
||||
std::vector<gdcm::Tag> const &empty_tags, std::vector<gdcm::Tag> const &clear_tags, std::vector<gdcm::Tag> const &remove_tags, std::vector< std::pair<gdcm::Tag, std::string> > const & replace_tags,
|
||||
std::vector<gdcm::PrivateTag> const &empty_privatetags, std::vector<gdcm::PrivateTag> const &clear_privatetags, std::vector<gdcm::PrivateTag> const &remove_privatetags, std::vector< std::pair<gdcm::PrivateTag, std::string> > const & replace_privatetags,
|
||||
bool continuemode = false)
|
||||
{
|
||||
gdcm::Reader reader;
|
||||
reader.SetFileName( filename );
|
||||
|
@ -67,28 +69,65 @@ static bool AnonymizeOneFileDumb(gdcm::Anonymizer &anon, const char *filename, c
|
|||
|
||||
anon.SetFile( file );
|
||||
|
||||
if( empty_tags.empty() && replace_tags.empty() && remove_tags.empty() )
|
||||
if( empty_tags.empty() && clear_tags.empty() && replace_tags.empty() && remove_tags.empty()
|
||||
&& empty_privatetags.empty() && clear_privatetags.empty() && replace_privatetags.empty() && remove_privatetags.empty() )
|
||||
{
|
||||
std::cerr << "No operation to be done." << std::endl;
|
||||
std::cerr << "No operation(s) to be done." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<gdcm::Tag>::const_iterator it = empty_tags.begin();
|
||||
bool success = true;
|
||||
// Private Creator(s) must be done first:
|
||||
{
|
||||
std::vector< std::pair<gdcm::Tag, std::string> >::const_iterator it2 = replace_tags.begin();
|
||||
for(; it2 != replace_tags.end(); ++it2)
|
||||
{
|
||||
success = success && anon.Replace( it2->first, it2->second.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
// Regular Private:
|
||||
{
|
||||
std::vector<gdcm::PrivateTag>::const_iterator it = empty_privatetags.begin();
|
||||
for(; it != empty_privatetags.end(); ++it)
|
||||
{
|
||||
success = success && anon.Empty( *it );
|
||||
}
|
||||
it = clear_privatetags.begin();
|
||||
for(; it != clear_privatetags.end(); ++it)
|
||||
{
|
||||
success = success && anon.Clear( *it );
|
||||
}
|
||||
it = remove_privatetags.begin();
|
||||
for(; it != remove_privatetags.end(); ++it)
|
||||
{
|
||||
success = success && anon.Remove( *it );
|
||||
}
|
||||
|
||||
std::vector< std::pair<gdcm::PrivateTag, std::string> >::const_iterator it2 = replace_privatetags.begin();
|
||||
for(; it2 != replace_privatetags.end(); ++it2)
|
||||
{
|
||||
success = success && anon.Replace( it2->first, it2->second.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
// Public Remove or Empty may impact Private Creator, so do them last.
|
||||
{
|
||||
std::vector<gdcm::Tag>::const_iterator it = empty_tags.begin();
|
||||
for(; it != empty_tags.end(); ++it)
|
||||
{
|
||||
success = success && anon.Empty( *it );
|
||||
}
|
||||
it = clear_tags.begin();
|
||||
for(; it != clear_tags.end(); ++it)
|
||||
{
|
||||
success = success && anon.Clear( *it );
|
||||
}
|
||||
it = remove_tags.begin();
|
||||
for(; it != remove_tags.end(); ++it)
|
||||
{
|
||||
success = success && anon.Remove( *it );
|
||||
}
|
||||
|
||||
std::vector< std::pair<gdcm::Tag, std::string> >::const_iterator it2 = replace_tags.begin();
|
||||
for(; it2 != replace_tags.end(); ++it2)
|
||||
{
|
||||
success = success && anon.Replace( it2->first, it2->second.c_str() );
|
||||
}
|
||||
|
||||
gdcm::Writer writer;
|
||||
|
@ -237,8 +276,13 @@ static void PrintHelp()
|
|||
std::cout << " --aes256 AES 256 (default)." << std::endl;
|
||||
std::cout << "Dumb mode options:" << std::endl;
|
||||
std::cout << " --empty %d,%d DICOM tag(s) to empty" << std::endl;
|
||||
std::cout << " %d,%d,%s DICOM private tag(s) to empty" << std::endl;
|
||||
std::cout << " --clear %d,%d DICOM tag(s) to clear" << std::endl;
|
||||
std::cout << " %d,%d,%s DICOM private tag(s) to clear" << std::endl;
|
||||
std::cout << " --remove %d,%d DICOM tag(s) to remove" << std::endl;
|
||||
std::cout << " %d,%d,%s DICOM private tag(s) to remove" << std::endl;
|
||||
std::cout << " --replace %d,%d=%s DICOM tag(s) to replace" << std::endl;
|
||||
std::cout << " %d,%d,%s=%s DICOM private tag(s) to replace" << std::endl;
|
||||
std::cout << "General Options:" << std::endl;
|
||||
std::cout << " -V --verbose more verbose (warning+error)." << std::endl;
|
||||
std::cout << " -W --warning print warning info." << std::endl;
|
||||
|
@ -308,13 +352,20 @@ int main(int argc, char *argv[])
|
|||
int recursive = 0;
|
||||
int continuemode = 0;
|
||||
int empty_tag = 0;
|
||||
int clear_tag = 0;
|
||||
int remove_tag = 0;
|
||||
int replace_tag = 0;
|
||||
int crypto_api = 0;
|
||||
std::vector<gdcm::Tag> empty_tags;
|
||||
std::vector<gdcm::Tag> clear_tags;
|
||||
std::vector<gdcm::Tag> remove_tags;
|
||||
std::vector< std::pair<gdcm::Tag, std::string> > replace_tags_value;
|
||||
std::vector<gdcm::PrivateTag> empty_privatetags;
|
||||
std::vector<gdcm::PrivateTag> clear_privatetags;
|
||||
std::vector<gdcm::PrivateTag> remove_privatetags;
|
||||
std::vector< std::pair<gdcm::PrivateTag, std::string> > replace_privatetags_value;
|
||||
gdcm::Tag tag;
|
||||
gdcm::PrivateTag privatetag;
|
||||
gdcm::CryptoFactory::CryptoLib crypto_lib;
|
||||
crypto_lib = gdcm::CryptoFactory::DEFAULT;
|
||||
|
||||
|
@ -340,10 +391,11 @@ int main(int argc, char *argv[])
|
|||
{"recursive", no_argument, nullptr, 'r'},
|
||||
{"dumb", no_argument, &dumb_mode, 1},
|
||||
{"empty", required_argument, &empty_tag, 1}, // 15
|
||||
{"clear", required_argument, &clear_tag, 1}, // 16
|
||||
{"remove", required_argument, &remove_tag, 1},
|
||||
{"replace", required_argument, &replace_tag, 1},
|
||||
{"continue", no_argument, &continuemode, 1},
|
||||
{"crypto", required_argument, &crypto_api, 1}, //19
|
||||
{"crypto", required_argument, &crypto_api, 1}, //20
|
||||
|
||||
{"verbose", no_argument, nullptr, 'V'},
|
||||
{"warning", no_argument, nullptr, 'W'},
|
||||
|
@ -409,31 +461,51 @@ int main(int argc, char *argv[])
|
|||
else if( option_index == 15 ) /* empty */
|
||||
{
|
||||
assert( strcmp(s, "empty") == 0 );
|
||||
if( !tag.ReadFromCommaSeparatedString(optarg) )
|
||||
if( privatetag.ReadFromCommaSeparatedString(optarg) )
|
||||
empty_privatetags.push_back( privatetag );
|
||||
else if( tag.ReadFromCommaSeparatedString(optarg) )
|
||||
empty_tags.push_back( tag );
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not read Tag: " << optarg << std::endl;
|
||||
std::cerr << "Could not read Tag/PrivateTag: " << optarg << std::endl;
|
||||
return 1;
|
||||
}
|
||||
empty_tags.push_back( tag );
|
||||
}
|
||||
else if( option_index == 16 ) /* remove */
|
||||
else if( option_index == 16 ) /* clear */
|
||||
{
|
||||
assert( strcmp(s, "clear") == 0 );
|
||||
if( privatetag.ReadFromCommaSeparatedString(optarg) )
|
||||
clear_privatetags.push_back( privatetag );
|
||||
else if( tag.ReadFromCommaSeparatedString(optarg) )
|
||||
clear_tags.push_back( tag );
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not read Tag/PrivateTag: " << optarg << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if( option_index == 17 ) /* remove */
|
||||
{
|
||||
assert( strcmp(s, "remove") == 0 );
|
||||
if( !tag.ReadFromCommaSeparatedString(optarg) )
|
||||
if( privatetag.ReadFromCommaSeparatedString(optarg) )
|
||||
remove_privatetags.push_back( privatetag );
|
||||
else if( tag.ReadFromCommaSeparatedString(optarg) )
|
||||
remove_tags.push_back( tag );
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not read Tag: " << optarg << std::endl;
|
||||
std::cerr << "Could not read Tag/PrivateTag: " << optarg << std::endl;
|
||||
return 1;
|
||||
}
|
||||
remove_tags.push_back( tag );
|
||||
}
|
||||
else if( option_index == 17 ) /* replace */
|
||||
else if( option_index == 18 ) /* replace */
|
||||
{
|
||||
assert( strcmp(s, "replace") == 0 );
|
||||
if( !tag.ReadFromCommaSeparatedString(optarg) )
|
||||
if( privatetag.ReadFromCommaSeparatedString(optarg) )
|
||||
{
|
||||
std::cerr << "Could not read Tag: " << optarg << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else if( tag.ReadFromCommaSeparatedString(optarg) )
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.str( optarg );
|
||||
uint16_t dummy;
|
||||
|
@ -451,7 +523,13 @@ int main(int argc, char *argv[])
|
|||
std::getline(ss, str); // do not skip whitespace
|
||||
replace_tags_value.emplace_back(tag, str );
|
||||
}
|
||||
else if( option_index == 19 ) /* crypto */
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not read Tag/PrivateTag: " << optarg << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if( option_index == 20 ) /* crypto */
|
||||
{
|
||||
assert( strcmp(s, "crypto") == 0 );
|
||||
if (strcmp(optarg, "openssl") == 0)
|
||||
|
@ -674,6 +752,11 @@ int main(int argc, char *argv[])
|
|||
std::cerr << "Input directory should be different from output directory" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
if (outfilename.back() == '\\')
|
||||
outfilename = outfilename.substr(0, outfilename.size() - 1);
|
||||
#endif
|
||||
if( outfilename.back() != '/' ) outfilename += '/';
|
||||
nfiles = dir.Load(filename, (recursive > 0 ? true : false));
|
||||
filenames = dir.GetFilenames();
|
||||
gdcm::Directory::FilenamesType::const_iterator it = filenames.begin();
|
||||
|
@ -810,7 +893,8 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
const char *in = filenames[i].c_str();
|
||||
const char *out = outfilenames[i].c_str();
|
||||
if( !AnonymizeOneFileDumb(anon, in, out, empty_tags, remove_tags, replace_tags_value, (continuemode > 0 ? true: false)) )
|
||||
if( !AnonymizeOneFileDumb(anon, in, out, empty_tags, clear_tags, remove_tags, replace_tags_value,
|
||||
empty_privatetags, clear_privatetags, remove_privatetags, replace_privatetags_value, (continuemode > 0 ? true: false)) )
|
||||
{
|
||||
//std::cerr << "Could not anonymize: " << in << std::endl;
|
||||
delete cms_ptr;
|
||||
|
|
|
@ -0,0 +1,544 @@
|
|||
/*=========================================================================
|
||||
|
||||
Program: GDCM (Grassroots DICOM). A DICOM library
|
||||
|
||||
Copyright (c) 2006-2011 Mathieu Malaterre
|
||||
All rights reserved.
|
||||
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html 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 notice for more information.
|
||||
|
||||
=========================================================================*/
|
||||
/*
|
||||
*/
|
||||
#include "gdcmCSAHeader.h"
|
||||
#include "gdcmCleaner.h"
|
||||
#include "gdcmDPath.h"
|
||||
#include "gdcmDefs.h"
|
||||
#include "gdcmDict.h"
|
||||
#include "gdcmDicts.h"
|
||||
#include "gdcmDirectory.h"
|
||||
#include "gdcmGlobal.h"
|
||||
#include "gdcmReader.h"
|
||||
#include "gdcmSystem.h"
|
||||
#include "gdcmVR.h"
|
||||
#include "gdcmVersion.h"
|
||||
#include "gdcmWriter.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <memory>
|
||||
|
||||
static void PrintVersion() {
|
||||
std::cout << "gdcmclean: gdcm " << gdcm::Version::GetVersion() << " ";
|
||||
const char date[] = "$Date$";
|
||||
std::cout << date << std::endl;
|
||||
}
|
||||
|
||||
static bool CleanOneFile(gdcm::Cleaner &cleaner, const char *filename,
|
||||
const char *outfilename, bool skipmeta,
|
||||
bool continuemode = false) {
|
||||
gdcm::Reader reader;
|
||||
reader.SetFileName(filename);
|
||||
if (!reader.Read()) {
|
||||
std::cerr << "Could not read : " << filename << std::endl;
|
||||
if (continuemode) {
|
||||
std::cerr << "Skipping from cleaning process (continue mode)."
|
||||
<< std::endl;
|
||||
return true;
|
||||
} else {
|
||||
std::cerr << "Check [--continue] option for skipping files." << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
gdcm::File &file = reader.GetFile();
|
||||
cleaner.SetFile(file);
|
||||
if (!cleaner.Clean()) {
|
||||
std::cerr << "Could not clean: " << filename << std::endl;
|
||||
if (continuemode) {
|
||||
std::cerr << "Skipping from cleaning process (continue mode)."
|
||||
<< std::endl;
|
||||
return true;
|
||||
} else {
|
||||
std::cerr << "Check [--continue] option for skipping files." << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
gdcm::Writer writer;
|
||||
writer.SetFileName(outfilename);
|
||||
writer.SetCheckFileMetaInformation(!skipmeta);
|
||||
writer.SetFile(file);
|
||||
if (!writer.Write()) {
|
||||
std::cerr << "Could not Write : " << outfilename << std::endl;
|
||||
if (strcmp(filename, outfilename) != 0) {
|
||||
gdcm::System::RemoveFile(outfilename);
|
||||
} else {
|
||||
std::cerr << "gdcmclean just corrupted: " << filename
|
||||
<< " for you (data lost)." << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool isValidPublicKeyword(const char *keyword, gdcm::Tag &tag) {
|
||||
static const gdcm::Global &g = gdcm::Global::GetInstance();
|
||||
static const gdcm::Dicts &dicts = g.GetDicts();
|
||||
static const gdcm::Dict &pubdict = dicts.GetPublicDict();
|
||||
|
||||
pubdict.GetDictEntryByKeyword(keyword, tag);
|
||||
if (tag != gdcm::Tag(0xffff, 0xffff)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void PrintHelp() {
|
||||
PrintVersion();
|
||||
std::cout << "Usage: gdcmclean [OPTION]... FILE..." << std::endl;
|
||||
std::cout << "Options:" << std::endl;
|
||||
std::cout << " -i --input DICOM filename / directory"
|
||||
<< std::endl;
|
||||
std::cout << " -o --output DICOM filename / directory"
|
||||
<< std::endl;
|
||||
std::cout
|
||||
<< " -r --recursive recursively process (sub-)directories."
|
||||
<< std::endl;
|
||||
std::cout << " --continue Do not stop when file found is "
|
||||
"not DICOM."
|
||||
<< std::endl;
|
||||
std::cout << "Edition options:" << std::endl;
|
||||
std::cout << " --empty %d,%d DICOM tag(s) to empty"
|
||||
<< std::endl;
|
||||
std::cout << " %d,%d,%s DICOM private tag(s) to empty"
|
||||
<< std::endl;
|
||||
std::cout << " %s DICOM keyword/path(s) to empty"
|
||||
<< std::endl;
|
||||
std::cout << " --remove %d,%d DICOM tag(s) to remove"
|
||||
<< std::endl;
|
||||
std::cout << " %d,%d,%s DICOM private tag(s) to remove"
|
||||
<< std::endl;
|
||||
std::cout << " %s DICOM keyword/path(s) to remove"
|
||||
<< std::endl;
|
||||
std::cout << " --scrub %d,%d DICOM tag(s) to scrub"
|
||||
<< std::endl;
|
||||
std::cout << " %d,%d,%s DICOM private tag(s) to scrub"
|
||||
<< std::endl;
|
||||
std::cout << " %s DICOM keyword/path(s) to scrub"
|
||||
<< std::endl;
|
||||
std::cout << " --preserve %s DICOM path(s) to preserve"
|
||||
<< std::endl;
|
||||
std::cout << " --preserve-missing-private-creator Whether or "
|
||||
"not preserve private attributes with missing private creator."
|
||||
<< std::endl;
|
||||
std::cout << " --preserve-group-length Whether or "
|
||||
"not preserve deprecated group length attributes (will not be "
|
||||
"re-computed)."
|
||||
<< std::endl;
|
||||
std::cout << " --preserve-illegal Whether or "
|
||||
"not preserve illegal attributes (eg. group 0003...)."
|
||||
<< std::endl;
|
||||
std::cout << "General Options:" << std::endl;
|
||||
std::cout << " -V --verbose more verbose (warning+error)."
|
||||
<< std::endl;
|
||||
std::cout << " -W --warning print warning info." << std::endl;
|
||||
std::cout << " -D --debug print debug info." << std::endl;
|
||||
std::cout << " -E --error print error info." << std::endl;
|
||||
std::cout << " -h --help print help." << std::endl;
|
||||
std::cout << " -v --version print version." << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int c;
|
||||
|
||||
std::string filename;
|
||||
gdcm::Directory::FilenamesType filenames;
|
||||
std::string outfilename;
|
||||
gdcm::Directory::FilenamesType outfilenames;
|
||||
int skipmeta = 0;
|
||||
int continuemode = 0;
|
||||
int verbose = 0;
|
||||
int warning = 0;
|
||||
int debug = 0;
|
||||
int error = 0;
|
||||
int help = 0;
|
||||
int version = 0;
|
||||
int recursive = 0;
|
||||
int empty_tag = 0;
|
||||
int remove_tag = 0;
|
||||
int scrub_tag = 0;
|
||||
int preserve_tag = 0;
|
||||
int preserveAllMissingPrivateCreator = 0;
|
||||
int preserveAllGroupLength = 0;
|
||||
int preserveAllIllegal = 0;
|
||||
std::vector<gdcm::DPath> empty_dpaths;
|
||||
std::vector<gdcm::DPath> remove_dpaths;
|
||||
std::vector<gdcm::DPath> scrub_dpaths;
|
||||
std::vector<gdcm::DPath> preserve_dpaths;
|
||||
std::vector<gdcm::VR> empty_vrs;
|
||||
std::vector<gdcm::Tag> empty_tags;
|
||||
std::vector<gdcm::PrivateTag> empty_privatetags;
|
||||
std::vector<gdcm::VR> remove_vrs;
|
||||
std::vector<gdcm::Tag> remove_tags;
|
||||
std::vector<gdcm::PrivateTag> remove_privatetags;
|
||||
std::vector<gdcm::Tag> scrub_tags; // clean-digital-trash
|
||||
std::vector<gdcm::PrivateTag> scrub_privatetags; // clean-digital-trash
|
||||
gdcm::Tag tag;
|
||||
gdcm::PrivateTag privatetag;
|
||||
gdcm::DPath dpath;
|
||||
|
||||
while (1) {
|
||||
// int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{"input", required_argument, NULL, 'i'}, // i
|
||||
{"output", required_argument, NULL, 'o'}, // o
|
||||
{"recursive", no_argument, NULL, 'r'},
|
||||
{"empty", required_argument, &empty_tag, 1}, // 3
|
||||
{"remove", required_argument, &remove_tag, 1}, // 4
|
||||
{"scrub", required_argument, &scrub_tag, 1}, // 5
|
||||
{"preserve", required_argument, &preserve_tag, 1}, // 5
|
||||
{"continue", no_argument, NULL, 'c'},
|
||||
{"skip-meta", 0, &skipmeta, 1}, // should I document this one ?
|
||||
{"preserve-missing-private-creator", 0,
|
||||
&preserveAllMissingPrivateCreator, 1}, //
|
||||
{"preserve-group-length", 0, &preserveAllGroupLength, 1}, //
|
||||
{"preserve-illegal", 0, &preserveAllIllegal, 1}, //
|
||||
|
||||
{"verbose", no_argument, NULL, 'V'},
|
||||
{"warning", no_argument, NULL, 'W'},
|
||||
{"debug", no_argument, NULL, 'D'},
|
||||
{"error", no_argument, NULL, 'E'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"version", no_argument, NULL, 'v'},
|
||||
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
c = getopt_long(argc, argv, "i:o:rcVWDEhv", long_options, &option_index);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 0: {
|
||||
const char *s = long_options[option_index].name;
|
||||
(void)s;
|
||||
if (optarg) {
|
||||
if (option_index == 3) /* empty */
|
||||
{
|
||||
assert(strcmp(s, "empty") == 0);
|
||||
if (gdcm::VR::IsValid(optarg))
|
||||
empty_vrs.push_back(gdcm::VR::GetVRTypeFromFile(optarg));
|
||||
else if (privatetag.ReadFromCommaSeparatedString(optarg))
|
||||
empty_privatetags.push_back(privatetag);
|
||||
else if (tag.ReadFromCommaSeparatedString(optarg))
|
||||
empty_tags.push_back(tag);
|
||||
else if (isValidPublicKeyword(optarg, tag))
|
||||
empty_tags.push_back(tag);
|
||||
else if (dpath.ConstructFromString(optarg))
|
||||
empty_dpaths.push_back(dpath);
|
||||
else {
|
||||
std::cerr << "Could not read Tag/PrivateTag/DPath: " << optarg
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if (option_index == 4) /* remove */
|
||||
{
|
||||
if (gdcm::VR::IsValid(optarg))
|
||||
remove_vrs.push_back(gdcm::VR::GetVRTypeFromFile(optarg));
|
||||
if (privatetag.ReadFromCommaSeparatedString(optarg))
|
||||
remove_privatetags.push_back(privatetag);
|
||||
else if (tag.ReadFromCommaSeparatedString(optarg))
|
||||
remove_tags.push_back(tag);
|
||||
else if (isValidPublicKeyword(optarg, tag))
|
||||
remove_tags.push_back(tag);
|
||||
else if (dpath.ConstructFromString(optarg))
|
||||
remove_dpaths.push_back(dpath);
|
||||
else {
|
||||
std::cerr << "Could not read Tag/PrivateTag/DPath: " << optarg
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if (option_index == 5) /* scrub */
|
||||
{
|
||||
if (privatetag.ReadFromCommaSeparatedString(optarg))
|
||||
scrub_privatetags.push_back(privatetag);
|
||||
else if (tag.ReadFromCommaSeparatedString(optarg))
|
||||
scrub_tags.push_back(tag);
|
||||
else if (isValidPublicKeyword(optarg, tag))
|
||||
scrub_tags.push_back(tag);
|
||||
else {
|
||||
std::cerr << "Could not read Tag/PrivateTag/DPath: " << optarg
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else if (option_index == 6) /* preserve */
|
||||
{
|
||||
if (dpath.ConstructFromString(optarg))
|
||||
preserve_dpaths.push_back(dpath);
|
||||
else {
|
||||
std::cerr << "Could not read DPath: " << optarg << std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case 'i':
|
||||
assert(filename.empty());
|
||||
filename = optarg;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
assert(outfilename.empty());
|
||||
outfilename = optarg;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
continuemode = 1;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
recursive = 1;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
verbose = 1;
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
warning = 1;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
debug = 1;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
error = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
help = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
version = 1;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
std::vector<std::string> files;
|
||||
while (optind < argc) {
|
||||
files.push_back(argv[optind++]);
|
||||
}
|
||||
if (files.size() == 2 && filename.empty() && outfilename.empty()) {
|
||||
filename = files[0];
|
||||
outfilename = files[1];
|
||||
} else {
|
||||
PrintHelp();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (version) {
|
||||
PrintVersion();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (help) {
|
||||
PrintHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (filename.empty()) {
|
||||
PrintHelp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!gdcm::System::FileExists(filename.c_str())) {
|
||||
std::cerr << "Could not find file: " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Are we in single file or directory mode:
|
||||
unsigned int nfiles = 1;
|
||||
gdcm::Directory dir;
|
||||
if (gdcm::System::FileIsDirectory(filename.c_str())) {
|
||||
if (!gdcm::System::FileIsDirectory(outfilename.c_str())) {
|
||||
if (gdcm::System::FileExists(outfilename.c_str())) {
|
||||
std::cerr << "Could not create directory since " << outfilename
|
||||
<< " is already a file" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// For now avoid user mistake
|
||||
if (filename == outfilename) {
|
||||
std::cerr << "Input directory should be different from output directory"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (*outfilename.rbegin() != '/') outfilename += '/';
|
||||
nfiles = dir.Load(filename, (recursive > 0 ? true : false));
|
||||
filenames = dir.GetFilenames();
|
||||
gdcm::Directory::FilenamesType::const_iterator it = filenames.begin();
|
||||
// Prepare outfilenames
|
||||
for (; it != filenames.end(); ++it) {
|
||||
std::string dup = *it; // make a copy
|
||||
std::string &out = dup.replace(0, filename.size(), outfilename);
|
||||
outfilenames.push_back(out);
|
||||
}
|
||||
// Prepare outdirectory
|
||||
gdcm::Directory::FilenamesType const &dirs = dir.GetDirectories();
|
||||
gdcm::Directory::FilenamesType::const_iterator itdir = dirs.begin();
|
||||
for (; itdir != dirs.end(); ++itdir) {
|
||||
std::string dirdup = *itdir; // make a copy
|
||||
std::string &dirout = dirdup.replace(0, filename.size(), outfilename);
|
||||
if (!gdcm::System::MakeDirectory(dirout.c_str())) {
|
||||
std::cerr << "Could not create directory: " << dirout << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filenames.push_back(filename);
|
||||
outfilenames.push_back(outfilename);
|
||||
}
|
||||
|
||||
if (filenames.size() != outfilenames.size()) {
|
||||
std::cerr << "Something went really wrong" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Debug is a little too verbose
|
||||
gdcm::Trace::SetDebug((debug > 0 ? true : false));
|
||||
gdcm::Trace::SetWarning((warning > 0 ? true : false));
|
||||
gdcm::Trace::SetError((error > 0 ? true : false));
|
||||
// when verbose is true, make sure warning+error are turned on:
|
||||
if (verbose) {
|
||||
gdcm::Trace::SetWarning((verbose > 0 ? true : false));
|
||||
gdcm::Trace::SetError((verbose > 0 ? true : false));
|
||||
}
|
||||
|
||||
gdcm::FileMetaInformation::SetSourceApplicationEntityTitle("gdcmclean");
|
||||
|
||||
// Setup gdcm::Cleaner
|
||||
gdcm::Cleaner cleaner;
|
||||
cleaner.RemoveAllMissingPrivateCreator(!preserveAllMissingPrivateCreator);
|
||||
cleaner.RemoveAllGroupLength(!preserveAllGroupLength);
|
||||
cleaner.RemoveAllIllegal(!preserveAllIllegal);
|
||||
// Preserve
|
||||
for (std::vector<gdcm::DPath>::const_iterator it = preserve_dpaths.begin();
|
||||
it != preserve_dpaths.end(); ++it) {
|
||||
if (!cleaner.Preserve(*it)) {
|
||||
std::cerr << "Impossible to Preserve: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// VR
|
||||
for (std::vector<gdcm::VR>::const_iterator it = empty_vrs.begin();
|
||||
it != empty_vrs.end(); ++it) {
|
||||
if (!cleaner.Empty(*it)) {
|
||||
std::cerr << "Impossible to Empty: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (std::vector<gdcm::VR>::const_iterator it = remove_vrs.begin();
|
||||
it != remove_vrs.end(); ++it) {
|
||||
if (!cleaner.Remove(*it)) {
|
||||
std::cerr << "Impossible to Remove: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Empty
|
||||
for (std::vector<gdcm::Tag>::const_iterator it = empty_tags.begin();
|
||||
it != empty_tags.end(); ++it) {
|
||||
if (!cleaner.Empty(*it)) {
|
||||
std::cerr << "Impossible to Empty: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (std::vector<gdcm::PrivateTag>::const_iterator it =
|
||||
empty_privatetags.begin();
|
||||
it != empty_privatetags.end(); ++it) {
|
||||
if (!cleaner.Empty(*it)) {
|
||||
std::cerr << "Impossible to Empty: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (std::vector<gdcm::DPath>::const_iterator it = empty_dpaths.begin();
|
||||
it != empty_dpaths.end(); ++it) {
|
||||
if (!cleaner.Empty(*it)) {
|
||||
std::cerr << "Impossible to Empty: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Remove
|
||||
for (std::vector<gdcm::Tag>::const_iterator it = remove_tags.begin();
|
||||
it != remove_tags.end(); ++it) {
|
||||
if (!cleaner.Remove(*it)) {
|
||||
std::cerr << "Impossible to Remove: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (std::vector<gdcm::PrivateTag>::const_iterator it =
|
||||
remove_privatetags.begin();
|
||||
it != remove_privatetags.end(); ++it) {
|
||||
if (!cleaner.Remove(*it)) {
|
||||
std::cerr << "Impossible to Remove: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (std::vector<gdcm::DPath>::const_iterator it = remove_dpaths.begin();
|
||||
it != remove_dpaths.end(); ++it) {
|
||||
if (!cleaner.Remove(*it)) {
|
||||
std::cerr << "Impossible to Remove: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Scrub
|
||||
for (std::vector<gdcm::Tag>::const_iterator it = scrub_tags.begin();
|
||||
it != scrub_tags.end(); ++it) {
|
||||
if (!cleaner.Scrub(*it)) {
|
||||
std::cerr << "Impossible to Scrub: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (std::vector<gdcm::PrivateTag>::const_iterator it =
|
||||
scrub_privatetags.begin();
|
||||
it != scrub_privatetags.end(); ++it) {
|
||||
if (!cleaner.Scrub(*it)) {
|
||||
std::cerr << "Impossible to Scrub: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (std::vector<gdcm::DPath>::const_iterator it = scrub_dpaths.begin();
|
||||
it != scrub_dpaths.end(); ++it) {
|
||||
if (!cleaner.Scrub(*it)) {
|
||||
std::cerr << "Impossible to Scrub: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
for (unsigned int i = 0; i < nfiles; ++i) {
|
||||
const char *in = filenames[i].c_str();
|
||||
const char *out = outfilenames[i].c_str();
|
||||
if (!CleanOneFile(cleaner, in, out, skipmeta > 0 ? true : false,
|
||||
continuemode > 0 ? true : false)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -13,10 +13,10 @@
|
|||
=========================================================================*/
|
||||
/*
|
||||
* HISTORY:
|
||||
* In GDCM 1.X the prefered terms was 'ReWrite', however one author of GDCM dislike
|
||||
* In GDCM 1.X the preferred term was 'ReWrite', however one author of GDCM dislike
|
||||
* the term ReWrite since it is associated with the highly associated with the Rewrite
|
||||
* notion in software programming where using reinvent the wheel and rewrite from scratch code
|
||||
* the term convert was prefered
|
||||
* the term convert was preferred
|
||||
*
|
||||
* Tools to conv. Goals being to 'purify' a DICOM file.
|
||||
* For now it will do the minimum:
|
||||
|
@ -25,7 +25,7 @@
|
|||
* simply discarded (not written).
|
||||
* - Elements are written in alphabetical order
|
||||
* - 32bits VR have the residue bytes sets to 0x0,0x0
|
||||
* - Same goes from Item Length end delimitor, sets to 0x0,0x0
|
||||
* - Same goes from Item Length end delimiter, sets to 0x0,0x0
|
||||
* - All buggy files (wrong length: GE, 13 and Siemens Leonardo) are fixed
|
||||
* - All size are even (no odd length from gdcm 1.x)
|
||||
*
|
||||
|
@ -44,7 +44,7 @@
|
|||
* - Any broken JPEG file (wrong bits) should be fixed
|
||||
* - DicomObject bug should be fixed
|
||||
* - Meta and Dataset should have a matching UID (more generally File Meta
|
||||
* should be correct (Explicit!) and consistant with DataSet)
|
||||
* should be correct (Explicit!) and consistent with DataSet)
|
||||
* - User should be able to specify he wants Group Length (or remove them)
|
||||
* - Media SOP should be correct (deduct from something else or set to
|
||||
* SOP Secondary if all else fail).
|
||||
|
@ -153,7 +153,7 @@ static void PrintHelp()
|
|||
std::cout << " -F --force Force decompression/merging before recompression/splitting." << std::endl;
|
||||
std::cout << " --generate-icon Generate icon." << std::endl;
|
||||
std::cout << " --icon-minmax %d,%d Min/Max value for icon." << std::endl;
|
||||
std::cout << " --icon-auto-minmax Automatically commpute best Min/Max values for icon." << std::endl;
|
||||
std::cout << " --icon-auto-minmax Automatically compute best Min/Max values for icon." << std::endl;
|
||||
std::cout << " --compress-icon Decide whether icon follows main TransferSyntax or remains uncompressed." << std::endl;
|
||||
std::cout << " --planar-configuration [01] Change planar configuration." << std::endl;
|
||||
std::cout << " -Y --lossy Use the lossy (if possible) compressor." << std::endl;
|
||||
|
@ -926,7 +926,7 @@ int main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
// Handle here the general file (not required to be image)
|
||||
if ( explicitts || implicit || deflated )
|
||||
if ( !raw && (explicitts || implicit || deflated) )
|
||||
{
|
||||
if( explicitts && implicit ) return 1; // guard
|
||||
if( explicitts && deflated ) return 1; // guard
|
||||
|
@ -1178,6 +1178,10 @@ int main (int argc, char *argv[])
|
|||
{
|
||||
if( lossy )
|
||||
{
|
||||
const gdcm::PixelFormat &pf = image.GetPixelFormat();
|
||||
if( pf.GetBitsAllocated() > 8 )
|
||||
change.SetTransferSyntax(gdcm::TransferSyntax::JPEGExtendedProcess2_4);
|
||||
else
|
||||
change.SetTransferSyntax( gdcm::TransferSyntax::JPEGBaselineProcess1 );
|
||||
jpegcodec.SetLossless( false );
|
||||
if( quality )
|
||||
|
@ -1261,11 +1265,15 @@ int main (int argc, char *argv[])
|
|||
if( ts.IsExplicit() )
|
||||
{
|
||||
change.SetTransferSyntax( gdcm::TransferSyntax::ExplicitVRLittleEndian );
|
||||
if( implicit )
|
||||
change.SetTransferSyntax( gdcm::TransferSyntax::ImplicitVRLittleEndian );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( ts.IsImplicit() );
|
||||
change.SetTransferSyntax( gdcm::TransferSyntax::ImplicitVRLittleEndian );
|
||||
if( explicitts )
|
||||
change.SetTransferSyntax( gdcm::TransferSyntax::ExplicitVRLittleEndian );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
* TODO: Is this really usefull ?
|
||||
* Dump the dict from a DICOM file. Usefull for the private dict
|
||||
* TODO: Is this really useful ?
|
||||
* Dump the dict from a DICOM file. Useful for the private dict
|
||||
*/
|
||||
|
|
|
@ -232,8 +232,8 @@ static void difference_of_sequences(const gdcm::DataElement& sqde1,
|
|||
{
|
||||
gdcm::SmartPointer<gdcm::SequenceOfItems> sqi1 = sqde1.GetValueAsSQ();
|
||||
gdcm::SmartPointer<gdcm::SequenceOfItems> sqi2 = sqde2.GetValueAsSQ();
|
||||
size_t n1 = sqi1->GetNumberOfItems();
|
||||
size_t n2 = sqi2->GetNumberOfItems();
|
||||
size_t n1 = sqi1 ? sqi1->GetNumberOfItems() : 0;
|
||||
size_t n2 = sqi2 ? sqi2->GetNumberOfItems() : 0;
|
||||
size_t n = (n1 < n2) ? n1 : n2 ;
|
||||
std::stringstream sq_note;
|
||||
if (n1 != n2)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* - dcmInfo (SIEMENS)
|
||||
* - PrintFile (GDCM 1.x)
|
||||
*
|
||||
* For now all layout are harcoded (see --color/--xml-dict for instance)
|
||||
* For now all layout are hardcoded (see --color/--xml-dict for instance)
|
||||
*
|
||||
* gdcmdump has some feature not described in the DICOM standard:
|
||||
* --csa : to print CSA information (dcmInfo.exe compatible)
|
||||
|
@ -49,10 +49,16 @@
|
|||
#include "gdcmASN1.h"
|
||||
#include "gdcmAttribute.h"
|
||||
#include "gdcmBase64.h"
|
||||
#include "gdcmMEC_MR3.h"
|
||||
#include "gdcmTagKeywords.h"
|
||||
#include "gdcmDeflateStream.h"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#ifdef GDCM_HAVE_CODECVT
|
||||
#include <codecvt>
|
||||
#endif
|
||||
#include <locale>
|
||||
|
||||
#include <stdio.h> /* for printf */
|
||||
#include <stdlib.h> /* for exit */
|
||||
|
@ -190,7 +196,7 @@ static void ProcessSDSDataString( std::istream & is )
|
|||
|
||||
static void ProcessSDSData( std::istream & is )
|
||||
{
|
||||
// havent been able to figure out what was the begin meant for
|
||||
// haven't been able to figure out what was the begin meant for
|
||||
is.seekg( 0x20 - 8 );
|
||||
uint32_t version = 0;
|
||||
assert( sizeof(uint32_t) == 4 );
|
||||
|
@ -355,6 +361,7 @@ static bool DumpToshibaDTI( const char * input, size_t len )
|
|||
ds.Read<gdcm::ExplicitDataElement,gdcm::SwapperNoOp>( is );
|
||||
|
||||
gdcm::Printer p;
|
||||
//gdcm::DictPrinter p;
|
||||
p.SetFile( file );
|
||||
p.SetColor( color != 0 );
|
||||
p.Print( std::cout );
|
||||
|
@ -363,13 +370,12 @@ static bool DumpToshibaDTI( const char * input, size_t len )
|
|||
}
|
||||
|
||||
|
||||
static int DumpTOSHIBA_PMTF_INFORMATION_DATA(const gdcm::DataSet & ds)
|
||||
static int DumpTOSHIBA_Reverse(const gdcm::DataSet & ds, const gdcm::PrivateTag &tpmtf, const gdcm::PrivateTag &tseq)
|
||||
{
|
||||
// (0029,0010) ?? (LO) [PMTF INFORMATION DATA ] # 22,1 Private Creator
|
||||
// (0029,1001) ?? (SQ) (Sequence with undefined length) # u/l,1 ?
|
||||
|
||||
const gdcm::PrivateTag tpmtf(0x0029,0x1,"PMTF INFORMATION DATA");
|
||||
if( !ds.FindDataElement( tpmtf) ) return 1;
|
||||
if( !ds.FindDataElement( tpmtf) ) return 0; // this is not an error at this point
|
||||
const gdcm::DataElement& pmtf = ds.GetDataElement( tpmtf );
|
||||
if ( pmtf.IsEmpty() ) return 1;
|
||||
gdcm::SmartPointer<gdcm::SequenceOfItems> seq = pmtf.GetValueAsSQ();
|
||||
|
@ -383,7 +389,6 @@ static int DumpTOSHIBA_PMTF_INFORMATION_DATA(const gdcm::DataSet & ds)
|
|||
gdcm::DataSet &subds = item.GetNestedDataSet();
|
||||
// (0029,0010) ?? (LO) [PMTF INFORMATION DATA ] # 22,1 Private Creator
|
||||
// (0029,1090) ?? (OB) 00\05\00\13\00\12\00\22\ # 202,1 ?
|
||||
const gdcm::PrivateTag tseq(0x0029,0x90,"PMTF INFORMATION DATA");
|
||||
|
||||
if( subds.FindDataElement( tseq ) )
|
||||
{
|
||||
|
@ -491,7 +496,7 @@ struct Data2
|
|||
os << " UserAdress4: " << std::string(UserAdress4,32) << "\n";
|
||||
os << " UserAdress5: " << std::string(UserAdress5,32) << "\n";
|
||||
os << " RecDate: " << std::string(RecDate,8) << "\n";
|
||||
os << " RecTime: " << std::string(RecTime,64) << "\n";
|
||||
os << " RecTime: " << std::string(RecTime,6) << "\n";
|
||||
os << " RecPlace: " << std::string(RecPlace,64) << "\n";
|
||||
os << " RecSource: " << std::string(RecSource,64) << "\n";
|
||||
os << " DF1: " << std::string(DF1,64) << "\n";
|
||||
|
@ -698,6 +703,26 @@ static int DumpEl2_new(const gdcm::DataSet & ds)
|
|||
const gdcm::ByteValue * bv = de01f7_26.GetByteValue();
|
||||
|
||||
const char *begin = bv->GetPointer();
|
||||
const size_t buf_len= bv->GetLength();
|
||||
|
||||
bool isgzip = false;
|
||||
if( buf_len > (0x15f + 3) ) {
|
||||
const unsigned char *sig = (const unsigned char*)begin + 0x15f;
|
||||
isgzip = sig[0] == 0x1f && sig[1] == 0x8b && sig[2] == 0x08 /* DEFLATE */;
|
||||
}
|
||||
|
||||
if( isgzip ) {
|
||||
size_t offset = 0x15f;
|
||||
size_t len = buf_len - 0x15f;
|
||||
std::string str( begin + offset, begin + len );
|
||||
std::istringstream is( str );
|
||||
|
||||
zlib_stream::zip_istream gzis( is );
|
||||
std::string out;
|
||||
while( std::getline(gzis, out) ) {
|
||||
std::cout << out << std::endl;
|
||||
}
|
||||
} else {
|
||||
uint32_t val0[3];
|
||||
memcpy( &val0, begin, sizeof( val0 ) );
|
||||
assert( val0[0] == 0xF22D );
|
||||
|
@ -717,6 +742,7 @@ static int DumpEl2_new(const gdcm::DataSet & ds)
|
|||
std::cout << std::endl;
|
||||
begin += o;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -851,6 +877,38 @@ static int PrintCT3(const std::string & filename, bool verbose)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int PrintMEC_MR3(const std::string & filename, bool verbose)
|
||||
{
|
||||
(void)verbose;
|
||||
gdcm::Reader reader;
|
||||
reader.SetFileName( filename.c_str() );
|
||||
if( !reader.Read() )
|
||||
{
|
||||
std::cerr << "Failed to read: " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const gdcm::DataSet& ds = reader.GetFile().GetDataSet();
|
||||
|
||||
// Original Data
|
||||
const gdcm::PrivateTag tmecmr3(0x700d,0x08,"TOSHIBA_MEC_MR3");
|
||||
if( !ds.FindDataElement( tmecmr3) ) return 1;
|
||||
const gdcm::DataElement& mecmr3 = ds.GetDataElement( tmecmr3 );
|
||||
if ( mecmr3.IsEmpty() ) return 1;
|
||||
const gdcm::ByteValue * bv = mecmr3.GetByteValue();
|
||||
|
||||
const char *inbuffer = bv->GetPointer();
|
||||
const size_t buf_len= bv->GetLength();
|
||||
|
||||
int ret = 0;
|
||||
if (!gdcm::MEC_MR3::Print(inbuffer, buf_len))
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int PrintPMTF(const std::string & filename, bool verbose)
|
||||
{
|
||||
(void)verbose;
|
||||
|
@ -863,11 +921,91 @@ static int PrintPMTF(const std::string & filename, bool verbose)
|
|||
}
|
||||
|
||||
const gdcm::DataSet& ds = reader.GetFile().GetDataSet();
|
||||
int ret = cleanup::DumpTOSHIBA_PMTF_INFORMATION_DATA( ds );
|
||||
int ret = 0;
|
||||
{
|
||||
const gdcm::PrivateTag tpmtf(0x0029,0x1,"PMTF INFORMATION DATA");
|
||||
static const gdcm::PrivateTag &tseq = gdcm::MEC_MR3::GetPMTFInformationDataTag();
|
||||
ret += cleanup::DumpTOSHIBA_Reverse( ds, tpmtf, tseq );
|
||||
}
|
||||
|
||||
{
|
||||
const gdcm::PrivateTag tpmtf(0x0029,0x1,"CANON_MEC_MR3");
|
||||
static const gdcm::PrivateTag &tseq = gdcm::MEC_MR3::GetCanonMECMR3Tag();
|
||||
ret += cleanup::DumpTOSHIBA_Reverse( ds, tpmtf, tseq );
|
||||
|
||||
// PAS Reproduct Information
|
||||
const gdcm::PrivateTag tpasri(0x700d,0x19,"CANON_MEC_MR3^10");
|
||||
if( ds.FindDataElement( tpasri) ) {
|
||||
const gdcm::DataElement& pasri = ds.GetDataElement( tpasri );
|
||||
if (! pasri.IsEmpty() ) {
|
||||
const gdcm::ByteValue * bv = pasri.GetByteValue();
|
||||
std::string s(bv->GetPointer(), bv->GetLength() );
|
||||
std::cout << std::endl;
|
||||
std::cout << "PAS Reproduct Information (XML)" << std::endl;
|
||||
// header states:
|
||||
// <?xml version="1.0" encoding="UTF-8"?>
|
||||
// so simply dump without further cleanup:
|
||||
std::cout << s.c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const gdcm::PrivateTag tpmtf(0x0029,0x1,"TOSHIBA_MEC_MR3");
|
||||
static const gdcm::PrivateTag &tseq = gdcm::MEC_MR3::GetToshibaMECMR3Tag();
|
||||
ret += cleanup::DumpTOSHIBA_Reverse( ds, tpmtf, tseq );
|
||||
|
||||
const gdcm::PrivateTag tpmtf2(0x0029,0x2,"TOSHIBA_MEC_MR3");
|
||||
ret += cleanup::DumpTOSHIBA_Reverse( ds, tpmtf2, tseq );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void print_utf8(std::string const& s)
|
||||
{
|
||||
const char delim = 0;
|
||||
auto start = 0U;
|
||||
auto end = s.find(delim);
|
||||
while (end != std::string::npos)
|
||||
{
|
||||
std::cout << s.substr(start, end - start) << std::endl;
|
||||
start = end + 1;
|
||||
end = s.find(delim, start);
|
||||
}
|
||||
}
|
||||
|
||||
static int PrintMedComHistory(const std::string & filename, bool verbose)
|
||||
{
|
||||
(void)verbose;
|
||||
gdcm::Reader reader;
|
||||
reader.SetFileName( filename.c_str() );
|
||||
if( !reader.Read() )
|
||||
{
|
||||
std::cerr << "Failed to read: " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const gdcm::DataSet& ds = reader.GetFile().GetDataSet();
|
||||
const gdcm::PrivateTag tmedcom(0x0029,0x20,"SIEMENS MEDCOM HEADER");
|
||||
if( !ds.FindDataElement( tmedcom) ) return 1;
|
||||
const gdcm::DataElement& medcom = ds.GetDataElement( tmedcom);
|
||||
if ( medcom.IsEmpty() ) return 1;
|
||||
const gdcm::ByteValue * bv = medcom.GetByteValue();
|
||||
|
||||
const size_t size = bv->GetLength();
|
||||
std::u16string u16((size / 2) + 0, '\0');
|
||||
bv->GetBuffer( (char*)&u16[0], size );
|
||||
|
||||
#ifdef GDCM_HAVE_CODECVT
|
||||
std::string utf8 = std::wstring_convert<
|
||||
std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(u16);
|
||||
print_utf8(utf8);
|
||||
#else
|
||||
std::cerr << "Missing GDCM_HAVE_CODECVT support" << std::endl;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PrintPDB(const std::string & filename, bool verbose)
|
||||
{
|
||||
|
@ -902,26 +1040,14 @@ static int PrintPDB(const std::string & filename, bool verbose)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int PrintCSABase64(const std::string & filename, const char * name)
|
||||
static int PrintCSABase64Impl(gdcm::CSAHeader &csa, std::string const & csaname )
|
||||
{
|
||||
gdcm::Reader reader;
|
||||
reader.SetFileName( filename.c_str() );
|
||||
if( !reader.Read() )
|
||||
{
|
||||
std::cerr << "Failed to read: " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
const gdcm::DataSet& ds = reader.GetFile().GetDataSet();
|
||||
|
||||
gdcm::CSAHeader csa;
|
||||
const gdcm::PrivateTag &t1 = csa.GetCSAImageHeaderInfoTag();
|
||||
if( !ds.FindDataElement( t1 ) ) return 1;
|
||||
csa.LoadFromDataElement( ds.GetDataElement( t1 ) );
|
||||
|
||||
const char *name = csaname.c_str();
|
||||
if( csa.FindCSAElementByName(name) )
|
||||
{
|
||||
const gdcm::CSAElement & el = csa.GetCSAElementByName(name);
|
||||
if( el.IsEmpty() ) return 1;
|
||||
// this is not error if empty:
|
||||
if( el.IsEmpty() ) return 0;
|
||||
const gdcm::ByteValue* bv = el.GetByteValue();
|
||||
std::string str( bv->GetPointer(), bv->GetLength() );
|
||||
str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());
|
||||
|
@ -948,12 +1074,48 @@ static int PrintCSABase64(const std::string & filename, const char * name)
|
|||
return 1;
|
||||
}
|
||||
gdcm::Printer p;
|
||||
//gdcm::DictPrinter p;
|
||||
p.SetFile( file );
|
||||
//p.SetColor( 1 );
|
||||
std::cout << "--" << csaname << "--" << std::endl;
|
||||
p.Print(std::cout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PrintCSABase64(const std::string & filename, std::vector<std::string> const & csanames )
|
||||
{
|
||||
gdcm::Reader reader;
|
||||
reader.SetFileName( filename.c_str() );
|
||||
if( !reader.Read() )
|
||||
{
|
||||
std::cerr << "Failed to read: " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
const gdcm::DataSet& ds = reader.GetFile().GetDataSet();
|
||||
|
||||
int ret = 0;
|
||||
|
||||
gdcm::CSAHeader csa;
|
||||
const gdcm::PrivateTag &t1 = csa.GetCSAImageHeaderInfoTag();
|
||||
if( !ds.FindDataElement( t1 ) ) return 1;
|
||||
csa.LoadFromDataElement( ds.GetDataElement( t1 ) );
|
||||
for( std::vector<std::string>::const_iterator it = csanames.begin();
|
||||
it != csanames.end(); ++it ) {
|
||||
ret += PrintCSABase64Impl(csa, *it );
|
||||
}
|
||||
|
||||
const gdcm::PrivateTag &t2 = csa.GetCSASeriesHeaderInfoTag();
|
||||
if( !ds.FindDataElement( t2 ) ) return 1;
|
||||
csa.LoadFromDataElement( ds.GetDataElement( t2 ) );
|
||||
for( std::vector<std::string>::const_iterator it = csanames.begin();
|
||||
it != csanames.end(); ++it ) {
|
||||
ret += PrintCSABase64Impl(csa, *it );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int PrintCSA(const std::string & filename)
|
||||
{
|
||||
gdcm::Reader reader;
|
||||
|
@ -1133,7 +1295,9 @@ static void PrintHelp()
|
|||
std::cout << " -C --csa print SIEMENS CSA Header (0029,[12]0,SIEMENS CSA HEADER)." << std::endl;
|
||||
std::cout << " --csa-asl print decoded SIEMENS CSA MR_ASL (base64)." << std::endl;
|
||||
std::cout << " --csa-diffusion print decoded SIEMENS CSA MRDiffusion (base64)." << std::endl;
|
||||
std::cout << " --csa64 print decoded SIEMENS CSA FMRI/MR_ASL/MRDiffusion... (base64)." << std::endl;
|
||||
std::cout << " --mrprotocol print SIEMENS CSA MrProtocol only (within ASCCONV BEGIN/END)." << std::endl;
|
||||
std::cout << " or Phoenix Meta Protocol (0021,19,SIEMENS MR SDS 01)." << std::endl;
|
||||
std::cout << " -P --pdb print GEMS Protocol Data Block (0025,1b,GEMS_SERS_01)." << std::endl;
|
||||
std::cout << " --elscint print ELSCINT Protocol Information (01f7,26,ELSCINT1)." << std::endl;
|
||||
std::cout << " --vepro print VEPRO Protocol Information (0055,20,VEPRO VIF 3.0 DATA)." << std::endl;
|
||||
|
@ -1141,6 +1305,10 @@ static void PrintHelp()
|
|||
std::cout << " --sds print Philips MR Series Data Storage (1.3.46.670589.11.0.0.12.2) Information (2005,32,Philips MR Imaging DD 002)." << std::endl;
|
||||
std::cout << " --ct3 print CT Private Data 2 (7005,10,TOSHIBA_MEC_CT3)." << std::endl;
|
||||
std::cout << " --pmtf print PMTF INFORMATION DATA sub-sequences (0029,01,PMTF INFORMATION DATA)." << std::endl;
|
||||
std::cout << " or TOSHIBA_MEC_MR3 sub-sequences (0029,01,TOSHIBA_MEC_MR3)." << std::endl;
|
||||
std::cout << " or CANON_MEC_MR3 sub-sequences (0029,01,CANON_MEC_MR3)." << std::endl;
|
||||
std::cout << " --medcom print MedCom History Information as UTF-8 (0029,20,SIEMENS MEDCOM HEADER)." << std::endl;
|
||||
std::cout << " --mr3 print Original Data as UTF-8 (700d,08,TOSHIBA_MEC_MR3)." << std::endl;
|
||||
std::cout << " -A --asn1 print encapsulated ASN1 structure >(0400,0520)." << std::endl;
|
||||
std::cout << " --map-uid-names map UID to names." << std::endl;
|
||||
std::cout << "General Options:" << std::endl;
|
||||
|
@ -1166,14 +1334,17 @@ int main (int argc, char *argv[])
|
|||
int printcsa = 0;
|
||||
int printmrprotocol = 0;
|
||||
int printcsabase64 = 0;
|
||||
int printmedcom = 0; // MedCom History Information
|
||||
int printcsaasl = 0;
|
||||
int printcsadiffusion = 0;
|
||||
int printcsa64 = 0;
|
||||
int printpdb = 0;
|
||||
int printelscint = 0;
|
||||
int printvepro = 0;
|
||||
int printsds = 0; // MR Series Data Storage
|
||||
int printct3 = 0; // TOSHIBA_MEC_CT3
|
||||
int printpmtf = 0; // TOSHIBA / PMTF INFORMATION DATA
|
||||
int printmecmr3 = 0; // TOSHIBA_MEC_MR3
|
||||
int printpmtf = 0; // TOSHIBA / PMTF INFORMATION DATA & TOSHIBA / TOSHIBA_MEC_MR3 & CANON_MEC_MR3
|
||||
int verbose = 0;
|
||||
int warning = 0;
|
||||
int debug = 0;
|
||||
|
@ -1218,8 +1389,12 @@ int main (int argc, char *argv[])
|
|||
{"ct3", 0, &printct3, 1},
|
||||
{"csa-asl", 0, &printcsaasl, 1},
|
||||
{"csa-diffusion", 0, &printcsadiffusion, 1},
|
||||
{"csa64", 0, &printcsa64, 1},
|
||||
{"mrprotocol", 0, &printmrprotocol, 1},
|
||||
{"pmtf", 0, &printpmtf, 1},
|
||||
{"mecmr3", 0, &printpmtf, 1},
|
||||
{"medcom", 0, &printmedcom, 1},
|
||||
{"mr3", 0, &printmecmr3, 1},
|
||||
{nullptr, 0, nullptr, 0} // required
|
||||
};
|
||||
static const char short_options[] = "i:xrpdcCPAVWDEhvI";
|
||||
|
@ -1391,16 +1566,26 @@ int main (int argc, char *argv[])
|
|||
std::cerr << "Not handled for now" << std::endl;
|
||||
}
|
||||
|
||||
const char * csaname = nullptr;
|
||||
std::vector<std::string> csanames;
|
||||
if( printcsaasl )
|
||||
{
|
||||
printcsabase64 = 1;
|
||||
csaname = "MR_ASL";
|
||||
csanames.push_back( "MR_ASL" );
|
||||
}
|
||||
else if( printcsadiffusion )
|
||||
{
|
||||
printcsabase64 = 1;
|
||||
csaname = "MRDiffusion";
|
||||
csanames.push_back( "MRDiffusion" );
|
||||
}
|
||||
else if( printcsa64 )
|
||||
{
|
||||
printcsabase64 = 1;
|
||||
// keep me sorted
|
||||
csanames.push_back( "FmriAcquisitionDescriptionSequence" );
|
||||
csanames.push_back( "FmriConditionsDataSequence" );
|
||||
csanames.push_back( "FmriResultSequence" );
|
||||
csanames.push_back( "MR_ASL" );
|
||||
csanames.push_back( "MRDiffusion" );
|
||||
}
|
||||
|
||||
// else
|
||||
|
@ -1441,6 +1626,14 @@ int main (int argc, char *argv[])
|
|||
{
|
||||
res += PrintPMTF(*it, verbose!= 0);
|
||||
}
|
||||
else if( printmecmr3 )
|
||||
{
|
||||
res += PrintMEC_MR3(*it, verbose!=0);
|
||||
}
|
||||
else if( printmedcom )
|
||||
{
|
||||
res += PrintMedComHistory(*it, verbose!=0);
|
||||
}
|
||||
else if( printelscint )
|
||||
{
|
||||
res += PrintELSCINT(*it, verbose!= 0);
|
||||
|
@ -1459,7 +1652,7 @@ int main (int argc, char *argv[])
|
|||
}
|
||||
else if( printcsabase64 )
|
||||
{
|
||||
res += PrintCSABase64(*it, csaname);
|
||||
res += PrintCSABase64(*it, csanames);
|
||||
}
|
||||
else if( dump )
|
||||
{
|
||||
|
@ -1500,6 +1693,14 @@ int main (int argc, char *argv[])
|
|||
{
|
||||
res += PrintPMTF(filename, verbose!= 0);
|
||||
}
|
||||
else if( printmecmr3 )
|
||||
{
|
||||
res += PrintMEC_MR3(filename, verbose!= 0);
|
||||
}
|
||||
else if( printmedcom )
|
||||
{
|
||||
res += PrintMedComHistory(filename, verbose!= 0);
|
||||
}
|
||||
else if( printelscint )
|
||||
{
|
||||
res += PrintELSCINT(filename, verbose!= 0);
|
||||
|
@ -1518,7 +1719,7 @@ int main (int argc, char *argv[])
|
|||
}
|
||||
else if( printcsabase64 )
|
||||
{
|
||||
res += PrintCSABase64(filename, csaname);
|
||||
res += PrintCSABase64(filename, csanames);
|
||||
}
|
||||
else if( dump )
|
||||
{
|
||||
|
|
|
@ -346,6 +346,7 @@ static bool PopulateSingeFile( gdcm::PixmapWriter & writer,
|
|||
|
||||
static bool Populate( gdcm::PixmapWriter & writer, gdcm::ImageCodec & jpeg, gdcm::Directory::FilenamesType const & filenames, unsigned int ndim = 2, std::streampos const & pos = 0 )
|
||||
{
|
||||
assert( !filenames.empty() );
|
||||
std::vector<std::string>::const_iterator it = filenames.begin();
|
||||
bool b = true;
|
||||
gdcm::Pixmap &image = writer.GetPixmap();
|
||||
|
@ -511,6 +512,7 @@ int main (int argc, char *argv[])
|
|||
assert( strcmp(s, "input") == 0 );
|
||||
assert( filename.IsEmpty() );
|
||||
filename = optarg;
|
||||
filenames.emplace_back(filename);
|
||||
}
|
||||
else if( option_index == 2 ) /* depth */
|
||||
{
|
||||
|
@ -606,6 +608,7 @@ int main (int argc, char *argv[])
|
|||
//printf ("option i with value '%s'\n", optarg);
|
||||
assert( filename.IsEmpty() );
|
||||
filename = optarg;
|
||||
filenames.emplace_back(filename);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
|
@ -1180,9 +1183,9 @@ int main (int argc, char *argv[])
|
|||
if ( region[0] > region[1]
|
||||
|| region[2] > region[3]
|
||||
|| region[4] > region[5]
|
||||
|| region[1] > dims[0]
|
||||
|| region[3] > dims[1]
|
||||
|| (imageori.GetNumberOfDimensions() > 2 && region[5] > dims[2]) )
|
||||
|| region[1] >= dims[0]
|
||||
|| region[3] >= dims[1]
|
||||
|| (imageori.GetNumberOfDimensions() > 2 && region[5] >= dims[2]) )
|
||||
{
|
||||
if( imageori.GetNumberOfDimensions() == 2 )
|
||||
{
|
||||
|
|
|
@ -196,12 +196,15 @@ static std::string getInfoDate(Dict *infoDict, const char *key)
|
|||
std::string out;
|
||||
|
||||
#ifdef LIBPOPPLER_NEW_OBJECT_API
|
||||
if ((obj = infoDict->lookup((char*)key)).isString())
|
||||
if ((obj = infoDict->lookup(const_cast<char*>(key))).isString())
|
||||
#else
|
||||
if (infoDict->lookup((char*)key, &obj)->isString())
|
||||
#endif
|
||||
{
|
||||
const GooString* gs = obj.getString();
|
||||
#ifndef LIBPOPPLER_GOOSTRING_HAS_GETCSTRING
|
||||
const
|
||||
#endif
|
||||
GooString* gs = obj.getString();
|
||||
#ifdef LIBPOPPLER_GOOSTRING_HAS_GETCSTRING
|
||||
s = gs->getCString();
|
||||
#else
|
||||
|
@ -216,11 +219,11 @@ static std::string getInfoDate(Dict *infoDict, const char *key)
|
|||
{
|
||||
switch (n)
|
||||
{
|
||||
case 1: mon = 1;
|
||||
case 2: day = 1;
|
||||
case 3: hour = 0;
|
||||
case 4: min = 0;
|
||||
case 5: sec = 0;
|
||||
case 1: mon = 1; /* fall through */
|
||||
case 2: day = 1; /* fall through */
|
||||
case 3: hour = 0; /* fall through */
|
||||
case 4: min = 0; /* fall through */
|
||||
case 5: sec = 0; /* fall through */
|
||||
}
|
||||
tmStruct.tm_year = year - 1900;
|
||||
tmStruct.tm_mon = mon - 1;
|
||||
|
@ -258,7 +261,11 @@ static std::string getInfoDate(Dict *infoDict, const char *key)
|
|||
return out;
|
||||
}
|
||||
|
||||
#ifdef LIBPOPPLER_UNICODEMAP_HAS_CONSTMAPUNICODE
|
||||
static std::string getInfoString(Dict *infoDict, const char *key, const UnicodeMap *uMap)
|
||||
#else
|
||||
static std::string getInfoString(Dict *infoDict, const char *key, UnicodeMap *uMap)
|
||||
#endif
|
||||
{
|
||||
Object obj;
|
||||
#ifdef LIBPOPPLER_GOOSTRING_HAS_CONSTGETCHAR
|
||||
|
@ -273,7 +280,7 @@ static std::string getInfoString(Dict *infoDict, const char *key, const UnicodeM
|
|||
std::string out;
|
||||
|
||||
#ifdef LIBPOPPLER_NEW_OBJECT_API
|
||||
if ((obj = infoDict->lookup((char*)key)).isString())
|
||||
if ((obj = infoDict->lookup(const_cast<char*>(key))).isString())
|
||||
#else
|
||||
if (infoDict->lookup((char*)key, &obj)->isString())
|
||||
#endif
|
||||
|
@ -487,15 +494,19 @@ static int ProcessOneFile( std::string const & filename, gdcm::Defs const & defs
|
|||
|
||||
MemStream *appearStream;
|
||||
|
||||
appearStream = new MemStream((char*)bv->GetPointer(), 0,
|
||||
appearStream = new MemStream(const_cast<char*>(bv->GetPointer()), 0,
|
||||
#ifdef LIBPOPPLER_NEW_OBJECT_API
|
||||
bv->GetLength(), std::move(appearDict));
|
||||
#else
|
||||
bv->GetLength(), &appearDict);
|
||||
#endif
|
||||
#ifdef LIBPOPPLER_PDFDOC_HAS_OPTIONAL
|
||||
std::optional<GooString> ownerPW, userPW;
|
||||
#else
|
||||
GooString *ownerPW, *userPW;
|
||||
ownerPW = NULL;
|
||||
userPW = NULL;
|
||||
#endif
|
||||
|
||||
PDFDoc *doc;
|
||||
doc = new PDFDoc(appearStream, ownerPW, userPW);
|
||||
|
@ -509,12 +520,16 @@ static int ProcessOneFile( std::string const & filename, gdcm::Defs const & defs
|
|||
std::string creationdate;
|
||||
std::string moddate;
|
||||
|
||||
#ifdef LIBPOPPLER_UNICODEMAP_HAS_CONSTMAPUNICODE
|
||||
const UnicodeMap *uMap;
|
||||
#ifdef LIBPOPPLER_GLOBALPARAMS_IS_UNIQUE_PTR
|
||||
globalParams = std::make_unique<GlobalParams>();
|
||||
#else
|
||||
UnicodeMap *uMap;
|
||||
#endif
|
||||
#ifdef LIBPOPPLER_GLOBALPARAMS_CSTOR_HAS_PARAM
|
||||
globalParams = new GlobalParams(0);
|
||||
#else
|
||||
#ifdef LIBPOPPLER_GLOBALPARAMS_HAS_RESET
|
||||
globalParams.reset(new GlobalParams());
|
||||
#else
|
||||
globalParams = new GlobalParams();
|
||||
#endif
|
||||
|
|
|
@ -110,7 +110,7 @@ static bool DecompressPapyrus3( int pap3handle, int itemnum, gdcm::TransferSynta
|
|||
|
||||
gdcm::DataSet & nested = file.GetDataSet();
|
||||
|
||||
/* position the file pointer to the begining of the data set */
|
||||
/* position the file pointer to the beginning of the data set */
|
||||
PapyShort err = Papy3GotoNumber (fileNb, (PapyShort)imageNb, DataSetID);
|
||||
|
||||
gdcm::DataElement pixeldata( gdcm::Tag(0x7fe0,0x0010) );
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include <poppler/UnicodeMap.h>
|
||||
#include <poppler/PDFDocEncoding.h>
|
||||
#include <poppler/GlobalParams.h>
|
||||
#ifdef LIBPOPPLER_PDFDOC_HAS_OPTIONAL
|
||||
#include <poppler/PDFDocFactory.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
@ -44,12 +47,15 @@ static std::string getInfoDate(Dict *infoDict, const char *key)
|
|||
std::string out;
|
||||
|
||||
#ifdef LIBPOPPLER_NEW_OBJECT_API
|
||||
if ((obj = infoDict->lookup((char*)key)).isString())
|
||||
if ((obj = infoDict->lookup(const_cast<char*>(key))).isString())
|
||||
#else
|
||||
if (infoDict->lookup((char*)key, &obj)->isString())
|
||||
#endif
|
||||
{
|
||||
const GooString* gs = obj.getString();
|
||||
#ifndef LIBPOPPLER_GOOSTRING_HAS_GETCSTRING
|
||||
const
|
||||
#endif
|
||||
GooString* gs = obj.getString();
|
||||
#ifdef LIBPOPPLER_GOOSTRING_HAS_GETCSTRING
|
||||
s = gs->getCString();
|
||||
#else
|
||||
|
@ -64,11 +70,11 @@ static std::string getInfoDate(Dict *infoDict, const char *key)
|
|||
{
|
||||
switch (n)
|
||||
{
|
||||
case 1: mon = 1;
|
||||
case 2: day = 1;
|
||||
case 3: hour = 0;
|
||||
case 4: min = 0;
|
||||
case 5: sec = 0;
|
||||
case 1: mon = 1; /* fall through */
|
||||
case 2: day = 1; /* fall through */
|
||||
case 3: hour = 0; /* fall through */
|
||||
case 4: min = 0; /* fall through */
|
||||
case 5: sec = 0; /* fall through */
|
||||
}
|
||||
tmStruct.tm_year = year - 1900;
|
||||
tmStruct.tm_mon = mon - 1;
|
||||
|
@ -106,7 +112,11 @@ static std::string getInfoDate(Dict *infoDict, const char *key)
|
|||
return out;
|
||||
}
|
||||
|
||||
#ifdef LIBPOPPLER_UNICODEMAP_HAS_CONSTMAPUNICODE
|
||||
static std::string getInfoString(Dict *infoDict, const char *key, const UnicodeMap *uMap, bool & unicode)
|
||||
#else
|
||||
static std::string getInfoString(Dict *infoDict, const char *key, UnicodeMap *uMap, bool & unicode)
|
||||
#endif
|
||||
{
|
||||
Object obj;
|
||||
#ifdef LIBPOPPLER_GOOSTRING_HAS_CONSTGETCHAR
|
||||
|
@ -121,7 +131,7 @@ static std::string getInfoString(Dict *infoDict, const char *key, const UnicodeM
|
|||
std::string out;
|
||||
|
||||
#ifdef LIBPOPPLER_NEW_OBJECT_API
|
||||
if ((obj = infoDict->lookup((char*)key)).isString())
|
||||
if ((obj = infoDict->lookup(const_cast<char*>(key))).isString())
|
||||
#else
|
||||
if (infoDict->lookup((char*)key, &obj)->isString())
|
||||
#endif
|
||||
|
@ -329,18 +339,32 @@ int main (int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LIBPOPPLER_PDFDOC_HAS_OPTIONAL
|
||||
std::optional<GooString> ownerPW, userPW;
|
||||
#else
|
||||
GooString *ownerPW, *userPW;
|
||||
#endif
|
||||
GooString *fileName;
|
||||
#ifdef LIBPOPPLER_PDFDOC_HAS_OPTIONAL
|
||||
std::unique_ptr<PDFDoc> doc;
|
||||
#else
|
||||
PDFDoc *doc;
|
||||
#endif
|
||||
Object info;
|
||||
#ifdef LIBPOPPLER_UNICODEMAP_HAS_CONSTMAPUNICODE
|
||||
const UnicodeMap *uMap;
|
||||
#else
|
||||
UnicodeMap *uMap;
|
||||
#endif
|
||||
#ifndef LIBPOPPLER_PDFDOC_HAS_OPTIONAL
|
||||
ownerPW = NULL;
|
||||
userPW = NULL;
|
||||
#ifdef LIBPOPPLER_GLOBALPARAMS_IS_UNIQUE_PTR
|
||||
globalParams = std::make_unique<GlobalParams>();
|
||||
#else
|
||||
#endif
|
||||
#ifdef LIBPOPPLER_GLOBALPARAMS_CSTOR_HAS_PARAM
|
||||
globalParams = new GlobalParams(0);
|
||||
#else
|
||||
#ifdef LIBPOPPLER_GLOBALPARAMS_HAS_RESET
|
||||
globalParams.reset(new GlobalParams());
|
||||
#else
|
||||
globalParams = new GlobalParams();
|
||||
#endif
|
||||
|
@ -368,7 +392,11 @@ int main (int argc, char *argv[])
|
|||
#ifndef LIBPOPPLER_NEW_OBJECT_API
|
||||
obj.initNull();
|
||||
#endif
|
||||
#ifdef LIBPOPPLER_PDFDOC_HAS_OPTIONAL
|
||||
doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
|
||||
#else
|
||||
doc = new PDFDoc(fileName, ownerPW, userPW);
|
||||
#endif
|
||||
|
||||
if (doc->isEncrypted())
|
||||
{
|
||||
|
@ -397,8 +425,13 @@ return ch;
|
|||
http://msdn.microsoft.com/en-us/library/078sfkak(VS.80).aspx
|
||||
}
|
||||
*/
|
||||
#ifdef LIBPOPPLER_PDFDOC_HAS_OPTIONAL
|
||||
ownerPW = GooString( password.c_str() );
|
||||
doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
|
||||
#else
|
||||
ownerPW = new GooString( password.c_str() );
|
||||
doc = new PDFDoc(fileName, ownerPW, userPW);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string title;
|
||||
|
@ -462,7 +495,7 @@ http://msdn.microsoft.com/en-us/library/078sfkak(VS.80).aspx
|
|||
char date[22];
|
||||
const size_t datelen = 8;
|
||||
int res = gdcm::System::GetCurrentDateTime(date);
|
||||
if( !res ) return false;
|
||||
if( !res ) return 1;
|
||||
{
|
||||
gdcm::DataElement de( gdcm::Tag(0x0008,0x0020) );
|
||||
// Do not copy the whole cstring:
|
||||
|
@ -687,6 +720,17 @@ http://msdn.microsoft.com/en-us/library/078sfkak(VS.80).aspx
|
|||
at.SetValue( "application/pdf" );
|
||||
ds.Insert( at.GetAsDataElement() );
|
||||
}
|
||||
{
|
||||
// gdcm::Attribute<0x0042, 0x0015> at;
|
||||
// at.SetValue( length );
|
||||
// ds.Insert( at.GetAsDataElement() );
|
||||
gdcm::Element<gdcm::VR::UL,gdcm::VM::VM1> el;
|
||||
el.SetValue( length );
|
||||
gdcm::DataElement de = el.GetAsDataElement();
|
||||
de.SetTag( gdcm::Tag(0x0042, 0x0015) );
|
||||
ds.Insert( de );
|
||||
}
|
||||
|
||||
|
||||
|
||||
writer.SetFileName( outfilename.c_str() );
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
* --bench...
|
||||
*/
|
||||
|
||||
#include "gdcmScanner.h"
|
||||
#include "gdcmStrictScanner.h"
|
||||
#include "gdcmScanner2.h"
|
||||
#include "gdcmStrictScanner2.h"
|
||||
#include "gdcmTrace.h"
|
||||
#include "gdcmVersion.h"
|
||||
#include "gdcmSimpleSubjectWatcher.h"
|
||||
|
@ -84,18 +84,26 @@ static int DoIt(
|
|||
gdcm::Directory const & d,
|
||||
bool const & print , int table,
|
||||
VectorTags const & tags,
|
||||
VectorPrivateTags const & privatetags)
|
||||
VectorPrivateTags const & privatetags, bool header)
|
||||
{
|
||||
gdcm::SmartPointer<TScanner> ps = new TScanner;
|
||||
TScanner &s = *ps;
|
||||
//gdcm::SimpleSubjectWatcher watcher(ps, "Scanner");
|
||||
for( VectorTags::const_iterator it = tags.begin(); it != tags.end(); ++it)
|
||||
{
|
||||
s.AddTag( *it );
|
||||
if(!s.AddPublicTag( *it ))
|
||||
{
|
||||
std::cerr << "Failure to add public tag: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for( VectorPrivateTags::const_iterator it = privatetags.begin(); it != privatetags.end(); ++it)
|
||||
{
|
||||
s.AddPrivateTag( *it );
|
||||
if(!s.AddPrivateTag( *it ))
|
||||
{
|
||||
std::cerr << "Failure to add private tag: " << *it << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
bool b = s.Scan( d.GetFilenames() );
|
||||
if( !b )
|
||||
|
@ -106,7 +114,7 @@ static int DoIt(
|
|||
if (print)
|
||||
{
|
||||
if(table)
|
||||
s.PrintTable( std::cout );
|
||||
s.PrintTable( std::cout, header );
|
||||
else
|
||||
s.Print( std::cout );
|
||||
}
|
||||
|
@ -133,6 +141,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
int strict = 0;
|
||||
int table = 0;
|
||||
int header = 0;
|
||||
int verbose = 0;
|
||||
int warning = 0;
|
||||
int debug = 0;
|
||||
|
@ -152,6 +161,7 @@ int main(int argc, char *argv[])
|
|||
{"keyword", required_argument, nullptr, 'k'},
|
||||
{"strict", no_argument, &strict, 1},
|
||||
{"table", no_argument, &table, 1},
|
||||
{"header", no_argument, &header, 1},
|
||||
|
||||
// General options !
|
||||
{"verbose", no_argument, nullptr, 'V'},
|
||||
|
@ -325,6 +335,6 @@ int main(int argc, char *argv[])
|
|||
std::cout << "done retrieving file list " << nfiles << " files found." << std::endl;
|
||||
|
||||
if( strict )
|
||||
return DoIt<gdcm::StrictScanner>(d,print,table,tags,privatetags);
|
||||
return DoIt<gdcm::Scanner>(d,print,table,tags,privatetags);
|
||||
return DoIt<gdcm::StrictScanner2>(d,print,table,tags,privatetags,header>0);
|
||||
return DoIt<gdcm::Scanner2>(d,print,table,tags,privatetags,header > 0);
|
||||
}
|
||||
|
|
|
@ -813,15 +813,15 @@ static int MakeImageEnhanced( std::string const & filename, std::string const &o
|
|||
namespace gdcm
|
||||
{
|
||||
|
||||
static const DataElement &GetNestedDataElement( const DataSet &ds, const Tag & t1, const Tag & t2 )
|
||||
static inline void ReplaceIf(DataSet &rootds, const DataSet &ds, const Tag & t1, const Tag & t2 )
|
||||
{
|
||||
assert( ds.FindDataElement( t1 ) );
|
||||
if( !ds.FindDataElement( t1 ) ) return ;
|
||||
SmartPointer<SequenceOfItems> sqi1 = ds.GetDataElement( t1 ).GetValueAsSQ();
|
||||
assert( sqi1 );
|
||||
if( !sqi1 || sqi1->IsEmpty() ) return ;
|
||||
const Item &item1 = sqi1->GetItem(1);
|
||||
const DataSet & ds1 = item1.GetNestedDataSet();
|
||||
assert( ds1.FindDataElement( t2 ) );
|
||||
return ds1.GetDataElement( t2 );
|
||||
if( !ds1.FindDataElement( t2 ) ) return ;
|
||||
rootds.Replace(ds1.GetDataElement( t2 ));
|
||||
}
|
||||
|
||||
static bool RemapSharedIntoOld( gdcm::DataSet & ds,
|
||||
|
@ -837,53 +837,53 @@ static bool RemapSharedIntoOld( gdcm::DataSet & ds,
|
|||
const DataSet & sfgs_ds = item1.GetNestedDataSet();
|
||||
#if 1
|
||||
// Repetition Time
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x0080) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x0080) );
|
||||
// Echo Train Length
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x0091) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x0091) );
|
||||
// Flip Angle
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x1314) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x1314) );
|
||||
// Number of Averages
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9119), Tag(0x0018,0x0083) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9119), Tag(0x0018,0x0083) );
|
||||
|
||||
// Percent Sampling
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9125), Tag(0x0018,0x0093) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9125), Tag(0x0018,0x0093) );
|
||||
// Percent Phase Field of View
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9125), Tag(0x0018,0x0094) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9125), Tag(0x0018,0x0094) );
|
||||
// Receive Coil Name
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9042), Tag(0x0018,0x1250) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9042), Tag(0x0018,0x1250) );
|
||||
// Transmit Coil Name
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9049), Tag(0x0018,0x1251) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9049), Tag(0x0018,0x1251) );
|
||||
// InPlanePhaseEncodingDirection
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9125), Tag(0x0018,0x1312) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9125), Tag(0x0018,0x1312) );
|
||||
// TransmitterFrequency
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9006), Tag(0x0018,0x9098) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9006), Tag(0x0018,0x9098) );
|
||||
// InversionRecovery
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9115), Tag(0x0018,0x9009) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9115), Tag(0x0018,0x9009) );
|
||||
// FlowCompensation
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9115), Tag(0x0018,0x9010) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9115), Tag(0x0018,0x9010) );
|
||||
// ReceiveCoilType
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9042), Tag(0x0018,0x9043) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9042), Tag(0x0018,0x9043) );
|
||||
// QuadratureReceiveCoil
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9042), Tag(0x0018,0x9044) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9042), Tag(0x0018,0x9044) );
|
||||
// SlabThickness
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9107), Tag(0x0018,0x9104) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9107), Tag(0x0018,0x9104) );
|
||||
// MultiCoilDefinitionSequence
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9042), Tag(0x0018,0x9045) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9042), Tag(0x0018,0x9045) );
|
||||
// SlabOrientation
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9107), Tag(0x0018,0x9105) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9107), Tag(0x0018,0x9105) );
|
||||
// MidSlabPosition
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9107), Tag(0x0018,0x9106) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9107), Tag(0x0018,0x9106) );
|
||||
// OperatingModeSequence
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x9176) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x9176) );
|
||||
// MRAcquisitionPhaseEncodingStepsOutOf
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9125), Tag(0x0018,0x9232) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9125), Tag(0x0018,0x9232) );
|
||||
// SpecificAbsorptionRateSequence
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x9239) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0018,0x9112), Tag(0x0018,0x9239) );
|
||||
// AnatomicRegionSequence
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0020,0x9071), Tag(0x0008,0x2218) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0020,0x9071), Tag(0x0008,0x2218) );
|
||||
// Purpose of Reference Code Sequence
|
||||
// FIXME what if there is multiple purpose of rcs ?
|
||||
ds.Replace( GetNestedDataElement(sfgs_ds, Tag(0x0008,0x1140), Tag(0x0040,0xa170) ) );
|
||||
ReplaceIf(ds, sfgs_ds, Tag(0x0008,0x1140), Tag(0x0040,0xa170) );
|
||||
#else
|
||||
for(
|
||||
DataSet::ConstIterator it = sfgs_ds.Begin();
|
||||
|
@ -898,44 +898,44 @@ static bool RemapSharedIntoOld( gdcm::DataSet & ds,
|
|||
|
||||
#if 1
|
||||
// Effective Echo Time
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0018,0x9114), Tag(0x0018,0x9082) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0018,0x9114), Tag(0x0018,0x9082) );
|
||||
// -> should also be Echo Time
|
||||
// Nominal Cardiac Trigger Delay Time
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0018,0x9118), Tag(0x0020,0x9153) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0018,0x9118), Tag(0x0020,0x9153) );
|
||||
// Metabolite Map Description
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0018,0x9152), Tag(0x0018,0x9080) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0018,0x9152), Tag(0x0018,0x9080) );
|
||||
// IPP
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0020,0x9113), Tag(0x0020,0x0032) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0020,0x9113), Tag(0x0020,0x0032) );
|
||||
// IOP
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0020,0x9116), Tag(0x0020,0x0037) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0020,0x9116), Tag(0x0020,0x0037) );
|
||||
// Slice Thickness
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0028,0x9110), Tag(0x0018,0x0050) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0028,0x9110), Tag(0x0018,0x0050) );
|
||||
// Pixel Spacing
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0028,0x9110), Tag(0x0028,0x0030) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0028,0x9110), Tag(0x0028,0x0030) );
|
||||
|
||||
// window level
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0028,0x9132), Tag(0x0028,0x1050) ) );
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0028,0x9132), Tag(0x0028,0x1051) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0028,0x9132), Tag(0x0028,0x1050) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0028,0x9132), Tag(0x0028,0x1051) );
|
||||
|
||||
// rescale slope/intercept
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0028,0x9145), Tag(0x0028,0x1052) ) );
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0028,0x9145), Tag(0x0028,0x1053) ) );
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0028,0x9145), Tag(0x0028,0x1054) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0028,0x9145), Tag(0x0028,0x1052) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0028,0x9145), Tag(0x0028,0x1053) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0028,0x9145), Tag(0x0028,0x1054) );
|
||||
|
||||
// FrameReferenceDateTime
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0020,0x9111), Tag(0x0018,0x9151) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0020,0x9111), Tag(0x0018,0x9151) );
|
||||
// FrameAcquisitionDuration
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0020,0x9111), Tag(0x0018,0x9220) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0020,0x9111), Tag(0x0018,0x9220) );
|
||||
// TemporalPositionIndex
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0020,0x9111), Tag(0x0020,0x9128) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0020,0x9111), Tag(0x0020,0x9128) );
|
||||
// InStackPositionNumber
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0020,0x9111), Tag(0x0020,0x9057) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0020,0x9111), Tag(0x0020,0x9057) );
|
||||
// FrameType
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0018,0x9226), Tag(0x0008,0x9007) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0018,0x9226), Tag(0x0008,0x9007) );
|
||||
// DimensionIndexValues
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0020,0x9111), Tag(0x0020,0x9157) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0020,0x9111), Tag(0x0020,0x9157) );
|
||||
// FrameAcquisitionDateTime
|
||||
ds.Replace( GetNestedDataElement(pffgs_ds, Tag(0x0020,0x9111), Tag(0x0018,0x9074) ) );
|
||||
ReplaceIf(ds, pffgs_ds, Tag(0x0020,0x9111), Tag(0x0018,0x9074) );
|
||||
// Nominal Cardiac Trigger Delay Time -> Trigger Time
|
||||
//const DataElement &NominalCardiacTriggerDelayTime =
|
||||
// GetNestedDataElement(pffgs_ds, Tag(0x0018,0x9226), Tag(0x0008,0x9007) );
|
||||
|
@ -1392,7 +1392,7 @@ int main (int argc, char *argv[])
|
|||
gdcm::UIDs uid;
|
||||
uid.SetFromUID( ms.GetString() );
|
||||
|
||||
if( uid != gdcm::UIDs::EnhancedMRImageStorage )
|
||||
if( uid != gdcm::UIDs::uid_1_2_840_10008_5_1_4_1_1_4_1 ) //NOTE: uid_1_2_840_10008_5_1_4_1_1_4_1 = 121, // Enhanced MR Image Storage
|
||||
{
|
||||
std::cerr << "MediaStorage is not handled " << ms << " [" << uid.GetName() << "]" << std::endl;
|
||||
return 1;
|
||||
|
@ -1416,6 +1416,11 @@ int main (int argc, char *argv[])
|
|||
const gdcm::DataElement &pixeldata = image.GetDataElement();
|
||||
//const gdcm::ByteValue *bv = pixeldata.GetByteValue();
|
||||
gdcm::SmartPointer<gdcm::ByteValue> bv = const_cast<gdcm::ByteValue*>(pixeldata.GetByteValue());
|
||||
if( !bv )
|
||||
{
|
||||
std::cerr << "decompress first" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
unsigned long slice_len = image.GetBufferLength() / dims[2];
|
||||
assert( slice_len * dims[2] == image.GetBufferLength() );
|
||||
//assert( image.GetBufferLength() == bv->GetLength() );
|
||||
|
@ -1466,7 +1471,7 @@ int main (int argc, char *argv[])
|
|||
|
||||
char date[22];
|
||||
const size_t datelen = 8;
|
||||
//int res = gdcm::System::GetCurrentDateTime(date);
|
||||
gdcm::System::GetCurrentDateTime(date);
|
||||
gdcm::Attribute<0x8,0x12> instcreationdate;
|
||||
instcreationdate.SetValue( gdcm::DTComp( date, datelen ) );
|
||||
ds.Replace( instcreationdate.GetAsDataElement() );
|
||||
|
@ -1514,6 +1519,7 @@ int main (int argc, char *argv[])
|
|||
// gdcm::DataElement &pd = slice.GetDataElement();
|
||||
const char *sliceptr = bv->GetPointer() + i * slice_len;
|
||||
gdcm::DataElement newpixeldata( gdcm::Tag(0x7fe0,0x0010) );
|
||||
newpixeldata.SetVR( pixeldata.GetVR() );
|
||||
newpixeldata.SetByteValue( sliceptr, (uint32_t)slice_len); // slow !
|
||||
ds.Replace( newpixeldata );
|
||||
|
||||
|
|
|
@ -355,7 +355,7 @@ static void PopulateDataSet(xmlTextReaderPtr reader,DataSet &DS, int depth, bool
|
|||
READ_NEXT \
|
||||
char *value_char = (char*)xmlTextReaderConstValue(reader); \
|
||||
int nvalue = sscanf(value_char,"%d",&(values[count++])); \
|
||||
assert( nvalue == 1 ); \
|
||||
assert( nvalue == 1 ); (void)nvalue; \
|
||||
READ_NEXT /*Value ending tag*/ \
|
||||
name = (const char*)xmlTextReaderConstName(reader); \
|
||||
READ_NEXT \
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
* - Use pointers instead of long to specify source and
|
||||
* destination sizes to avoid arbitrary 4 GB limits
|
||||
* 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!),
|
||||
* but leave simple version for readabilty
|
||||
* but leave simple version for readability
|
||||
* - Make sure invalid distances detected if pointers
|
||||
* are 16 bits
|
||||
* - Fix fixed codes table error
|
||||
|
|
|
@ -37,9 +37,9 @@ get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
|||
if(EXISTS ${SELF_DIR}/GDCMTargets.cmake)
|
||||
# This is an install tree
|
||||
include(${SELF_DIR}/GDCMTargets.cmake)
|
||||
get_filename_component(GDCM_INCLUDE_ROOT "${SELF_DIR}/../../../@GDCM_INSTALL_INCLUDE_DIR@" ABSOLUTE)
|
||||
get_filename_component(GDCM_INCLUDE_ROOT "${SELF_DIR}/../../@GDCM_INSTALL_INCLUDE_DIR@" ABSOLUTE)
|
||||
set(GDCM_INCLUDE_DIRS ${GDCM_INCLUDE_ROOT})
|
||||
get_filename_component(GDCM_LIB_ROOT "${SELF_DIR}/../../../@GDCM_INSTALL_LIB_DIR@" ABSOLUTE)
|
||||
get_filename_component(GDCM_LIB_ROOT "${SELF_DIR}/../../@GDCM_INSTALL_LIB_DIR@" ABSOLUTE)
|
||||
set(GDCM_LIBRARY_DIRS ${GDCM_LIB_ROOT})
|
||||
else()
|
||||
if(EXISTS ${SELF_DIR}/GDCMExports.cmake)
|
||||
|
|
|
@ -20,7 +20,7 @@ endif ()
|
|||
macro(COMPUTE_MD5SUMS DIRECTORY OUTPUT_FILE)
|
||||
|
||||
# Super ugly and barely readable but you need that in order to
|
||||
# work around a deficiency in EXECUTE_PROCESS which does not have dependencie scanning
|
||||
# work around a deficiency in EXECUTE_PROCESS which does not have dependencies scanning
|
||||
file(WRITE
|
||||
${CMAKE_BINARY_DIR}/md5sum.cmake
|
||||
"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# set(ENV{PYTHONPATH} ${LIBRARY_OUTPUT_PATH})
|
||||
# set(my_test "from test_mymodule import *\;test_mymodule()")
|
||||
# add_test(PYTHON-TEST-MYMODULE python -c ${my_test})
|
||||
# Since cmake is only transmitting the ADD_TEST line to ctest thus you are loosing
|
||||
# Since cmake is only transmitting the ADD_TEST line to ctest thus you are losing
|
||||
# the env var. The only way to store the env var is to physically write in the cmake script
|
||||
# whatever PYTHONPATH you want and then add the test as 'cmake -P python_test.cmake'
|
||||
#
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# set(ENV{PYTHONPATH} ${LIBRARY_OUTPUT_PATH})
|
||||
# set(my_test "from test_mymodule import *\;test_mymodule()")
|
||||
# add_test(PYTHON-TEST-MYMODULE python -c ${my_test})
|
||||
# Since cmake is only transmitting the ADD_TEST line to ctest thus you are loosing
|
||||
# Since cmake is only transmitting the ADD_TEST line to ctest thus you are losing
|
||||
# the env var. The only way to store the env var is to physically write in the cmake script
|
||||
# whatever PYTHONPATH you want and then add the test as 'cmake -P python_test.cmake'
|
||||
#
|
||||
|
|
124
CMakeLists.txt
124
CMakeLists.txt
|
@ -17,7 +17,7 @@ endif()
|
|||
#----------------------------------------------------------------------------
|
||||
|
||||
project(GDCM
|
||||
VERSION 3.0.5
|
||||
VERSION 3.0.21
|
||||
LANGUAGES CXX C
|
||||
)
|
||||
## NOTE: the "DESCRIPTION" feature of project() was introduced in cmake 3.10.0
|
||||
|
@ -28,6 +28,7 @@ set(GDCM_MAJOR_VERSION ${GDCM_VERSION_MAJOR})
|
|||
set(GDCM_MINOR_VERSION ${GDCM_VERSION_MINOR})
|
||||
set(GDCM_BUILD_VERSION ${GDCM_VERSION_PATCH})
|
||||
set(GDCM_VERSION "${GDCM_VERSION_MAJOR}.${GDCM_VERSION_MINOR}.${GDCM_VERSION_PATCH}") # ${GDCM_VERSION_TWEAK}
|
||||
set(GDCM_SHORT_VERSION "${GDCM_VERSION_MAJOR}.${GDCM_VERSION_MINOR}")
|
||||
|
||||
mark_as_advanced(CMAKE_BACKWARDS_COMPATIBILITY CMAKE_BUILD_TYPE CMAKE_INSTALL_PREFIX)
|
||||
set(GDCM_CMAKE_DIR "${GDCM_SOURCE_DIR}/CMake" CACHE INTERNAL "")
|
||||
|
@ -133,6 +134,12 @@ if(NOT LIBRARY_OUTPUT_PATH)
|
|||
mark_as_advanced(LIBRARY_OUTPUT_PATH)
|
||||
endif()
|
||||
|
||||
# TODO: The following should be used for CMake 3 and beyond,
|
||||
# EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH are deprecated
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH})
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Adding GDCM_DATA_ROOT
|
||||
if(GDCM_STANDALONE)
|
||||
|
@ -180,23 +187,12 @@ macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
|
|||
endif()
|
||||
endmacro()
|
||||
|
||||
CHECK_INCLUDE_FILE("stdint.h" GDCM_HAVE_STDINT_H)
|
||||
if(UNIX) #Avoid polluting Win32 cmakecache
|
||||
CHECK_INCLUDE_FILE("inttypes.h" GDCM_HAVE_INTTYPES_H)
|
||||
endif()
|
||||
|
||||
#include(${GDCM_SOURCE_DIR}/CMake/gdcmPlatformCxxTests.cmake)
|
||||
#
|
||||
#GDCM_PLATFORM_CXX_TEST(GDCM_CXX_HAS_FUNCTION
|
||||
# "Checking whether compiler has __FUNCTION__" DIRECT)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the main lib...
|
||||
if(NOT GDCM_HAVE_STDINT_H)
|
||||
message(FATAL_ERROR "You system does not have stdint.h")
|
||||
endif()
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Configure the export configuration
|
||||
|
||||
|
@ -508,11 +504,14 @@ endif()
|
|||
#-----------------------------------------------------------------------------
|
||||
# Wrapping
|
||||
if(GDCM_STANDALONE)
|
||||
option(GDCM_WRAP_PYTHON "build python wrapping" OFF)
|
||||
option(GDCM_WRAP_PYTHON "build gdcm/python wrapping" OFF)
|
||||
option(VTKGDCM_WRAP_PYTHON "build vtkgdcm/python wrapping" OFF)
|
||||
option(GDCM_WRAP_PERL "build perl wrapping (experimental !)" OFF)
|
||||
option(GDCM_WRAP_PHP "build php wrapping" OFF)
|
||||
option(GDCM_WRAP_JAVA "build java wrapping" OFF)
|
||||
option(GDCM_WRAP_CSHARP "build csharp wrapping" OFF)
|
||||
option(GDCM_WRAP_JAVA "build gdcm/java wrapping" OFF)
|
||||
option(VTKGDCM_WRAP_JAVA "build vtkgdcm/java wrapping" OFF)
|
||||
option(GDCM_WRAP_CSHARP "build gdcm/csharp wrapping" OFF)
|
||||
option(VTKGDCM_WRAP_CSHARP "build vtkgdcm/csharp wrapping" OFF)
|
||||
mark_as_advanced(GDCM_WRAP_PHP)
|
||||
mark_as_advanced(GDCM_WRAP_PERL)
|
||||
mark_as_advanced(GDCM_USE_ACTIVIZ)
|
||||
|
@ -661,7 +660,96 @@ if(GDCM_STANDALONE)
|
|||
mark_as_advanced(VTK_DIR)
|
||||
set(GDCM_VTK_DIR ${VTK_DIR})
|
||||
mark_as_advanced(GDCM_USE_PARAVIEW)
|
||||
|
||||
set(VTKGDCM_NAME vtkgdcm CACHE STRING "vtk-gdcm lib name")
|
||||
mark_as_advanced(VTKGDCM_NAME)
|
||||
|
||||
if(VTK_VERSION VERSION_LESS 8.90)
|
||||
add_subdirectory(Utilities/VTK)
|
||||
else()
|
||||
message(STATUS "Building Utilities/VTK as a VTK 9 Module")
|
||||
# TODO: use VTKGDCM_NAME instead of vtkgdcm
|
||||
|
||||
option(VTKGDCM_VERSIONED_INSTALL "Install with versioned names." ON)
|
||||
mark_as_advanced(VTKGDCM_VERSIONED_INSTALL)
|
||||
if(VTKGDCM_VERSIONED_INSTALL)
|
||||
set(vtk_version_suffix "-${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}")
|
||||
set(vtkgdcm_library_suffix "${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}")
|
||||
else()
|
||||
set(vtk_version_suffix "")
|
||||
set(vtkgdcm_library_suffix "")
|
||||
endif()
|
||||
if(DEFINED GDCM_CUSTOM_LIBRARY_SUFFIX)
|
||||
set(vtkgdcm_library_suffix "${GDCM_CUSTOM_LIBRARY_SUFFIX}")
|
||||
endif()
|
||||
|
||||
vtk_module_scan(
|
||||
MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/VTK/vtkgdcm.module"
|
||||
REQUEST_MODULES "GDCM::vtkgdcm"
|
||||
PROVIDES_MODULES vtkgdcm_modules
|
||||
ENABLE_TESTS "${GDCM_BUILD_TESTING}"
|
||||
)
|
||||
|
||||
# documented at https://vtk.org/doc/nightly/html/group__module.html
|
||||
vtk_module_build(
|
||||
MODULES ${vtkgdcm_modules}
|
||||
INSTALL_EXPORT GDCM
|
||||
ARCHIVE_DESTINATION "${GDCM_INSTALL_LIB_DIR}"
|
||||
HEADERS_DESTINATION "${GDCM_INSTALL_INCLUDE_DIR}/vtk${vtk_version_suffix}"
|
||||
CMAKE_DESTINATION "${GDCM_INSTALL_PACKAGE_DIR}"
|
||||
LICENSE_DESTINATION "${GDCM_INSTALL_DATA_DIR}/vtkgdcm-${GDCM_SHORT_VERSION}"
|
||||
HIERARCHY_DESTINATION "${GDCM_INSTALL_LIB_DIR}/vtk${vtk_version_suffix}/hierarchy/vtkgdcm"
|
||||
LIBRARY_NAME_SUFFIX "${vtkgdcm_library_suffix}"
|
||||
VERSION "${GDCM_VERSION}"
|
||||
SOVERSION "1"
|
||||
# TODO: these are probably not set as they should be
|
||||
#USE_EXTERNAL "${GDCM_USE_EXTERNAL}"
|
||||
#TEST_DATA_TARGET vtkgdcmData
|
||||
#TEST_INPUT_DATA_DIRECTORY "${vtkgdcm_test_data_directory_input}"
|
||||
#TEST_OUTPUT_DATA_DIRECTORY "${vtkgdcm_test_data_directory_output}"
|
||||
)
|
||||
|
||||
if(VTKGDCM_WRAP_PYTHON)
|
||||
find_package(PythonInterp ${VTK_PYTHON_VERSION} QUIET)
|
||||
|
||||
vtk_module_wrap_python(
|
||||
MODULES ${vtkgdcm_modules}
|
||||
TARGET GDCM::vtkgdcmpython
|
||||
INSTALL_EXPORT vtkgdcmPython
|
||||
PYTHON_PACKAGE "vtkgdcm"
|
||||
CMAKE_DESTINATION "${GDCM_INSTALL_PACKAGE_DIR}"
|
||||
LIBRARY_DESTINATION "${GDCM_INSTALL_LIB_DIR}"
|
||||
MODULE_DESTINATION "${GDCM_VTK_INSTALL_PYTHONMODULE_DIR}"
|
||||
SOABI "${Python${VTK_PYTHON_VERSION}_SOABI}"
|
||||
BUILD_STATIC OFF
|
||||
)
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT "${CMAKE_BINARY_DIR}/${GDCM_VTK_INSTALL_PYTHONMODULE_DIR}/vtkgdcm/__init__.py"
|
||||
CONTENT "from .vtkgdcm import *\n\n__all__ = ['vtkgdcm']\n__version__ = \"${GDCM_VERSION}\"\n")
|
||||
install(
|
||||
FILES "${CMAKE_BINARY_DIR}/${GDCM_VTK_INSTALL_PYTHONMODULE_DIR}/vtkgdcm/__init__.py"
|
||||
DESTINATION "${GDCM_VTK_INSTALL_PYTHONMODULE_DIR}/vtkgdcm/")
|
||||
|
||||
export(
|
||||
EXPORT vtkgdcmPython
|
||||
NAMESPACE GDCM::
|
||||
FILE "${GDCM_INSTALL_PACKAGE_DIR}/vtkgdcmPython-targets.cmake")
|
||||
install(
|
||||
EXPORT vtkgdcmPython
|
||||
NAMESPACE GDCM::
|
||||
FILE vtkgdcmPython-targets.cmake
|
||||
DESTINATION "${GDCM_INSTALL_PACKAGE_DIR}")
|
||||
endif()
|
||||
|
||||
if(VTKGDCM_WRAP_JAVA)
|
||||
# TODO: this is broken, incomplete, needs lots of work
|
||||
vtk_module_wrap_java(
|
||||
MODULES ${vtkgdcm_modules}
|
||||
WRAPPED_MODULES vtkgdcm_java_wrapped_modules
|
||||
JAVA_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -800,7 +888,7 @@ if(GDCM_STANDALONE) # disabled for ITK distribution of gdcm
|
|||
set(CPACK_NUGET_PACKAGE_DESCRIPTION "Grassroots DiCoM is a C++ library for DICOM medical files. It is accessible from Python, C#, Java and PHP. It supports RAW, JPEG, JPEG 2000, JPEG-LS, RLE and deflated transfer syntax.
|
||||
It comes with a super fast scanner implementation to quickly scan hundreds of DICOM files.
|
||||
It supports SCU network operations (C-ECHO, C-FIND, C-STORE, C-MOVE). PS 3.3 & 3.6 are distributed as XML files.
|
||||
It also provides PS 3.15 certificates and password based mecanism to anonymize and de-identify DICOM datasets.")
|
||||
It also provides PS 3.15 certificates and password based mechanism to anonymize and de-identify DICOM datasets.")
|
||||
set(CPACK_NUGET_PACKAGE_LICENSEURL "http://gdcm.sourceforge.net/Copyright.html")
|
||||
set(CPACK_NUGET_PACKAGE_HOMEPAGE_URL "http://gdcm.sourceforge.net")
|
||||
set(CPACK_NUGET_PACKAGE_TAGS "dicom" "medical")
|
||||
|
@ -816,11 +904,11 @@ if(GDCM_STANDALONE) # disabled for ITK distribution of gdcm
|
|||
if(GDCM_USE_VTK)
|
||||
foreach(comp ${components})
|
||||
if( "${comp}" STREQUAL "PythonModule" )
|
||||
if(VTK_WRAP_PYTHON)
|
||||
if(VTK_WRAP_PYTHON AND VTKGDCM_WRAP_PYTHON)
|
||||
list(APPEND components VTK${comp})
|
||||
endif()
|
||||
elseif( "${comp}" STREQUAL "JavaModule" )
|
||||
if(VTK_WRAP_JAVA)
|
||||
if(VTK_WRAP_JAVA AND VTKGDCM_WRAP_JAVA)
|
||||
list(APPEND components VTK${comp})
|
||||
endif()
|
||||
else()
|
||||
|
|
|
@ -32,6 +32,7 @@ set(CSHARP_EXAMPLES
|
|||
if(BUILD_TESTING)
|
||||
list(APPEND CSHARP_EXAMPLES
|
||||
BasicAnonymizer
|
||||
Cleaner
|
||||
ClinicalTrialIdentificationWorkflow
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/*=========================================================================
|
||||
|
||||
Program: GDCM (Grassroots DICOM). A DICOM library
|
||||
|
||||
Copyright (c) 2006-2011 Mathieu Malaterre
|
||||
All rights reserved.
|
||||
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html 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 notice for more information.
|
||||
|
||||
=========================================================================*/
|
||||
|
||||
/**
|
||||
*/
|
||||
/*
|
||||
* Usage:
|
||||
* $ export LD_LIBRARY_PATH=$HOME/Projects/gdcm/debug-gcc/bin
|
||||
* $ mono bin/Cleaner.exe gdcmData/012345.002.050.dcm out.dcm
|
||||
*/
|
||||
using System;
|
||||
using gdcm;
|
||||
|
||||
public class MyWatcher : SimpleSubjectWatcher
|
||||
{
|
||||
public MyWatcher(Subject s):base(s,"Override String"){}
|
||||
protected override void StartFilter() {
|
||||
System.Console.WriteLine( "This is my start" );
|
||||
}
|
||||
protected override void EndFilter(){
|
||||
System.Console.WriteLine( "This is my end" );
|
||||
}
|
||||
protected override void ShowProgress(Subject caller, Event evt){
|
||||
ProgressEvent pe = ProgressEvent.Cast(evt);
|
||||
System.Console.WriteLine( "This is my progress: " + pe.GetProgress() );
|
||||
}
|
||||
protected override void ShowIteration(){
|
||||
System.Console.WriteLine( "This is my iteration" );
|
||||
}
|
||||
protected override void ShowAnonymization(Subject caller, Event evt){
|
||||
/*
|
||||
* A couple of explanation are necessary here to understand how SWIG work
|
||||
* http://www.swig.org/Doc1.3/Java.html#adding_downcasts
|
||||
*
|
||||
* System.Console.WriteLine( "This is my Anonymization. Type: " + evt.GetEventName() );
|
||||
* System.Type type = evt.GetType();
|
||||
* System.Console.WriteLine( "This is my Anonymization. System.Type: " + type.ToString() );
|
||||
* System.Console.WriteLine( "This is my Anonymization. CheckEvent: " + ae.CheckEvent( evt ) );
|
||||
* System.Console.WriteLine( "This is my Anonymization. Processing Tag #" + ae.GetTag().toString() );
|
||||
*/
|
||||
AnonymizeEvent ae = AnonymizeEvent.Cast(evt);
|
||||
if( ae != null )
|
||||
{
|
||||
Tag t = ae.GetTag();
|
||||
System.Console.WriteLine( "This is my Anonymization. Processing Tag #" + t.toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Console.WriteLine( "This is my Anonymization. Unhandled Event type: " + evt.GetEventName() );
|
||||
}
|
||||
}
|
||||
protected override void ShowAbort(){
|
||||
System.Console.WriteLine( "This is my abort" );
|
||||
}
|
||||
}
|
||||
|
||||
public class Cleaner
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
gdcm.Global global = gdcm.Global.GetInstance();
|
||||
if( !global.LoadResourcesFiles() )
|
||||
{
|
||||
System.Console.WriteLine( "Could not LoadResourcesFiles" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
string file1 = args[0];
|
||||
string file2 = args[1];
|
||||
Reader reader = new Reader();
|
||||
reader.SetFileName( file1 );
|
||||
bool ret = reader.Read();
|
||||
if( !ret )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
SmartPtrCleaner scleaner = gdcm.Cleaner.New();
|
||||
gdcm.Cleaner cleaner = scleaner.__ref__();
|
||||
|
||||
//SimpleSubjectWatcher watcher = new SimpleSubjectWatcher(cleaner, "Anonymizer");
|
||||
MyWatcher watcher = new MyWatcher(cleaner);
|
||||
|
||||
cleaner.SetFile( reader.GetFile() );
|
||||
cleaner.Empty( new gdcm.VR(gdcm.VR.VRType.PN) );
|
||||
gdcm.DPath dpath = new gdcm.DPath();
|
||||
dpath.ConstructFromString( "/0010,0010" );
|
||||
cleaner.Preserve( dpath );
|
||||
gdcm.Tag t1 = new gdcm.Tag(0x10, 0x30);
|
||||
cleaner.Empty( t1 );
|
||||
gdcm.PrivateTag pt0 = new gdcm.PrivateTag( new gdcm.Tag(0x29,0x60), "SIEMENS MEDCOM HEADER2" );
|
||||
cleaner.Remove( pt0 );
|
||||
gdcm.PrivateTag pt1 = new gdcm.PrivateTag( new gdcm.Tag(0x29,0x10), "SIEMENS CSA HEADER" );
|
||||
gdcm.PrivateTag pt2 = new gdcm.PrivateTag( new gdcm.Tag(0x29,0x20), "SIEMENS CSA HEADER" );
|
||||
cleaner.Scrub( pt1 );
|
||||
cleaner.Scrub( pt2 );
|
||||
if( !cleaner.Clean() )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Writer writer = new Writer();
|
||||
writer.SetFileName( file2 );
|
||||
writer.SetFile( cleaner.GetFile() );
|
||||
ret = writer.Write();
|
||||
if( !ret )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@ set(EXAMPLES_SRCS
|
|||
CreateJPIPDataSet
|
||||
DumpADAC
|
||||
DumpToshibaDTI
|
||||
DumpToshibaDTI2
|
||||
DumpImageHeaderInfo
|
||||
ReadMultiTimesException
|
||||
pmsct_rgb1
|
||||
|
|
|
@ -49,7 +49,9 @@ int main(int argc, char *argv[])
|
|||
// the dataset is the the set of element we are interested in:
|
||||
//gdcm::DataSet &ds = file.GetDataSet();
|
||||
|
||||
const gdcm::Image &image = reader.GetImage();
|
||||
gdcm::Image &image = reader.GetImage();
|
||||
// image.SetSpacing(0, 0.1);
|
||||
// image.SetSpacing(1, 0.2);
|
||||
image.Print( std::cout );
|
||||
|
||||
gdcm::ImageChangeTransferSyntax change;
|
||||
|
|
|
@ -194,7 +194,7 @@ struct param
|
|||
assert( bla < sizeof(name0) );
|
||||
is.read( name0, bla);
|
||||
size_t l = strlen(name0);
|
||||
assert( l == bla );
|
||||
assert( l == bla ); (void)l;
|
||||
char * ptr = strdup( name0 );
|
||||
v4.ptr = ptr;
|
||||
type = param_string;
|
||||
|
@ -209,7 +209,7 @@ struct param
|
|||
assert( bla < sizeof(name0) );
|
||||
is.read( name0, bla);
|
||||
size_t l = strlen(name0);
|
||||
assert( l == bla );
|
||||
assert( l == bla ); (void)l;
|
||||
memcpy( this->name, name0, bla );
|
||||
is.read( (char*)&bla, sizeof(bla) );
|
||||
assert( bla == 0x1 );
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*=========================================================================
|
||||
|
||||
Program: GDCM (Grassroots DICOM). A DICOM library
|
||||
|
||||
Copyright (c) 2006-2011 Mathieu Malaterre
|
||||
All rights reserved.
|
||||
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html 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 notice for more information.
|
||||
|
||||
=========================================================================*/
|
||||
/*
|
||||
* https://gazelle.ihe.net/EVSClient/dicomResult.seam;jsessionid=x+Rf9Zs+ip49P+jC3L8SLZb8?&oid=1.3.6.1.4.1.12559.11.1.2.1.4.1622284
|
||||
*/
|
||||
#include "gdcmReader.h"
|
||||
#include "gdcmPrivateTag.h"
|
||||
#include "gdcmPrinter.h"
|
||||
#include "gdcmDictPrinter.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static bool DumpToshibaDTI2( const char * input, size_t len )
|
||||
{
|
||||
static int i = 0;
|
||||
++i;
|
||||
if( len % 2 ) return false;
|
||||
|
||||
std::vector<char> copy( input, input + len );
|
||||
std::reverse( copy.begin(), copy.end() );
|
||||
|
||||
#if 0
|
||||
std::ostringstream f;
|
||||
f << "debug" << i;
|
||||
std::ofstream of( f.str().c_str(), std::ios::binary );
|
||||
of.write( ©[0], copy.size() );
|
||||
of.close();
|
||||
#else
|
||||
|
||||
std::istringstream is;
|
||||
std::string dup( ©[0], copy.size() );
|
||||
is.str( dup );
|
||||
|
||||
gdcm::File file;
|
||||
gdcm::FileMetaInformation & fmi = file.GetHeader();
|
||||
fmi.SetDataSetTransferSyntax( gdcm::TransferSyntax::ExplicitVRLittleEndian );
|
||||
gdcm::DataSet & ds = file.GetDataSet();
|
||||
ds.Read<gdcm::ExplicitDataElement,gdcm::SwapperNoOp>( is );
|
||||
|
||||
//gdcm::DictPrinter p;
|
||||
gdcm::Printer p;
|
||||
p.SetFile( file );
|
||||
p.SetColor( true );
|
||||
p.Print( std::cout );
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if( argc < 2 ) return 1;
|
||||
const char *filename = argv[1];
|
||||
gdcm::Reader reader;
|
||||
reader.SetFileName( filename );
|
||||
if( !reader.Read() )
|
||||
{
|
||||
std::cerr << "Failed to read: " << filename << std::endl;
|
||||
return 1;
|
||||
}
|
||||
const gdcm::DataSet& ds = reader.GetFile().GetDataSet();
|
||||
|
||||
/*
|
||||
(0029,1001) SQ (Sequence with explicit length #=6) # 18746, 1 Unknown Tag & Data
|
||||
(fffe,e000) na (Item with explicit length #=2) # 206, 1 Item
|
||||
(0029,0010) LO [TOSHIBA_MEC_MR3] # 16, 1 PrivateCreator
|
||||
(0029,1090) OB 00\07\00\06\00\05\00\04\00\03\00\02\00\0c\00\01\00\00\00\00\00\12... # 170, 1 Unknown Tag & Data
|
||||
(fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem
|
||||
(fffe,e000) na (Item with explicit length #=2) # 866, 1 Item
|
||||
(0029,0010) LO [TOSHIBA_MEC_MR3] # 16, 1 PrivateCreator
|
||||
(0029,1090) OB 45\4e\49\50\53\4c\20\52\41\5c\45\4e\49\50\53\4c\54\5c\52\45\53\55... # 830, 1 Unknown Tag & Data
|
||||
[...]
|
||||
(0029,1002) SQ (Sequence with explicit length #=1) # 120, 1 Unknown Tag & Data
|
||||
(fffe,e000) na (Item with explicit length #=2) # 112, 1 Item
|
||||
(0029,0010) LO [TOSHIBA_MEC_MR3] # 16, 1 PrivateCreator
|
||||
(0029,1090) OB 00\10\00\02\53\55\10\80\70\0d\30\31\5e\33\52\4d\5f\43\45\4d\5f\41... # 76, 1 Unknown Tag & Data
|
||||
(fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem
|
||||
*/
|
||||
|
||||
const gdcm::PrivateTag tmecmr3(0x0029,0x1,"TOSHIBA_MEC_MR3");
|
||||
if( !ds.FindDataElement( tmecmr3) ) return 1;
|
||||
const gdcm::DataElement& mecmr3 = ds.GetDataElement( tmecmr3 );
|
||||
if ( mecmr3.IsEmpty() ) return 1;
|
||||
gdcm::SmartPointer<gdcm::SequenceOfItems> seq = mecmr3.GetValueAsSQ();
|
||||
if ( !seq || !seq->GetNumberOfItems() ) return 1;
|
||||
|
||||
size_t n = seq->GetNumberOfItems();
|
||||
for( size_t i = 1; i <= n; ++i )
|
||||
{
|
||||
gdcm::Item &item = seq->GetItem(i);
|
||||
gdcm::DataSet &subds = item.GetNestedDataSet();
|
||||
const gdcm::PrivateTag tseq(0x0029,0x90,"TOSHIBA_MEC_MR3");
|
||||
|
||||
if( subds.FindDataElement( tseq ) )
|
||||
{
|
||||
const gdcm::DataElement & de = subds.GetDataElement( tseq );
|
||||
const gdcm::ByteValue * bv = de.GetByteValue();
|
||||
if( !bv ) return 1;
|
||||
|
||||
bool b = DumpToshibaDTI2( bv->GetPointer(), bv->GetLength() );
|
||||
if( !b ) return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -43,8 +43,9 @@ int main(int argc, char* argv[])
|
|||
char *buffer = new char[ len ];
|
||||
img.GetBuffer( buffer ); // do NOT de-allocate buffer !
|
||||
}
|
||||
catch (std::bad_alloc)
|
||||
catch (std::bad_alloc &ba)
|
||||
{
|
||||
(void)ba;
|
||||
std::cerr << "BAD ALLOC Exception caught!" << std::endl;
|
||||
}
|
||||
catch (...)
|
||||
|
|
|
@ -15,6 +15,7 @@ set(examples
|
|||
DecompressImage
|
||||
ScanDirectory
|
||||
ReadFiles
|
||||
SimplePrint
|
||||
FileAnonymize
|
||||
)
|
||||
foreach(example ${examples})
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*=========================================================================
|
||||
|
||||
Program: GDCM (Grassroots DICOM). A DICOM library
|
||||
|
||||
Copyright (c) 2006-2011 Mathieu Malaterre
|
||||
All rights reserved.
|
||||
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html 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 notice for more information.
|
||||
|
||||
=========================================================================*/
|
||||
/*
|
||||
* Compilation:
|
||||
* $ CLASSPATH=gdcm.jar javac ../../gdcm/Examples/Java/SimplePrint.java -d .
|
||||
*
|
||||
* Usage:
|
||||
* $ LD_LIBRARY_PATH=. CLASSPATH=gdcm.jar:. java SimplePrint gdcmData/012345.002.050.dcm
|
||||
*/
|
||||
import gdcm.*;
|
||||
|
||||
public class SimplePrint
|
||||
{
|
||||
public static void RecurseDataSet(File f, DataSet ds, String indent)
|
||||
{
|
||||
JavaDataSet cds = new JavaDataSet(ds);
|
||||
while(!cds.IsAtEnd())
|
||||
{
|
||||
DataElement de = cds.GetCurrent();
|
||||
// Compute VR from the toplevel file, and the currently processed dataset:
|
||||
VR vr = DataSetHelper.ComputeVR(f, ds, de.GetTag() );
|
||||
|
||||
if( vr.Compatible( new VR(VR.VRType.SQ) ) )
|
||||
{
|
||||
long uvl = de.GetVL().GetValueLength(); // Test cast is ok
|
||||
System.out.println( indent + de.GetTag().toString() + ":" + uvl ); // why not ?
|
||||
//SequenceOfItems sq = de.GetSequenceOfItems();
|
||||
// GetValueAsSQ handle more cases than GetSequenceOfItems
|
||||
SmartPtrSQ sq = de.GetValueAsSQ();
|
||||
long n = sq.GetNumberOfItems();
|
||||
for( long i = 1; i <= n; i++) // item starts at 1, not 0
|
||||
{
|
||||
Item item = sq.GetItem( i );
|
||||
DataSet nested = item.GetNestedDataSet();
|
||||
RecurseDataSet( f, nested, indent + " " );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println( indent + de.toString() );
|
||||
}
|
||||
cds.Next();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
String filename = args[0];
|
||||
Reader reader = new Reader();
|
||||
reader.SetFileName( filename );
|
||||
boolean ret = reader.Read();
|
||||
if( !ret )
|
||||
{
|
||||
throw new Exception("Could not read: " + filename );
|
||||
}
|
||||
File f = reader.GetFile();
|
||||
DataSet ds = f.GetDataSet();
|
||||
|
||||
RecurseDataSet( f, ds, "" );
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ option(GDCM_SUPPORT_BROKEN_IMPLEMENTATION "Handle broken DICOM" ON)
|
|||
mark_as_advanced(
|
||||
GDCM_ALWAYS_TRACE_MACRO
|
||||
GDCM_SUPPORT_BROKEN_IMPLEMENTATION
|
||||
GDCM_AUTOLOAD_GDCMJNI
|
||||
)
|
||||
|
||||
#if(WIN32)
|
||||
|
@ -63,6 +64,9 @@ CHECK_CXX_SOURCE_COMPILES(
|
|||
CHECK_CXX_SOURCE_COMPILES(
|
||||
"\#include <fstream>\nint main() { const wchar_t fn[10] = {}; std::ifstream is( fn ); return 0;}"
|
||||
GDCM_HAVE_WCHAR_IFSTREAM)
|
||||
CHECK_CXX_SOURCE_COMPILES(
|
||||
"\#include <string>\n#include <codecvt>\n#include <locale>\nint main() { std::u16string u16; std::string utf8 = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(u16); }"
|
||||
GDCM_HAVE_CODECVT)
|
||||
if(GDCM_USE_SYSTEM_OPENSSL)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}
|
||||
|
@ -73,6 +77,9 @@ CHECK_CXX_SOURCE_COMPILES(
|
|||
#HAVE_CMS_RECIPIENT_KEY)
|
||||
"\#include <openssl/cms.h>\nint main() { CMS_add0_recipient_password(0,0,0,0,0,0,0); return 0;}"
|
||||
GDCM_HAVE_CMS_RECIPIENT_PASSWORD)
|
||||
CHECK_CXX_SOURCE_COMPILES(
|
||||
"\#include <openssl/bio.h>\nint main() { const void*mem; int len; BIO_new_mem_buf(mem, len); }"
|
||||
OPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
@ -163,6 +170,11 @@ set(Common_SRCS ${Common_SRCS}
|
|||
gdcmOpenSSLP7CryptoFactory.cxx
|
||||
gdcmOpenSSLP7CryptographicMessageSyntax.cxx
|
||||
)
|
||||
if(OPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF)
|
||||
set_source_files_properties(
|
||||
gdcmOpenSSLP7CryptographicMessageSyntax.cxx
|
||||
PROPERTIES COMPILE_FLAGS "-DOPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(GDCM_USE_SYSTEM_OPENSSL AND GDCM_HAVE_CMS_RECIPIENT_PASSWORD)
|
||||
|
@ -170,6 +182,11 @@ set(Common_SRCS ${Common_SRCS}
|
|||
gdcmOpenSSLCryptoFactory.cxx
|
||||
gdcmOpenSSLCryptographicMessageSyntax.cxx
|
||||
)
|
||||
if(OPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF)
|
||||
set_source_files_properties(
|
||||
gdcmOpenSSLCryptographicMessageSyntax.cxx
|
||||
PROPERTIES COMPILE_FLAGS "-DOPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(GDCM_BUILD_TESTING)
|
||||
|
|
|
@ -59,7 +59,6 @@ static std::string base64_encode(unsigned char const* bytes_to_encode, size_t in
|
|||
{
|
||||
std::string ret;
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
|
@ -79,7 +78,7 @@ static std::string base64_encode(unsigned char const* bytes_to_encode, size_t in
|
|||
|
||||
if (i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
for(size_t j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (unsigned char)((char_array_3[0] & 0xfc) >> 2);
|
||||
|
@ -87,7 +86,7 @@ static std::string base64_encode(unsigned char const* bytes_to_encode, size_t in
|
|||
char_array_4[2] = (unsigned char)(((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6));
|
||||
char_array_4[3] = (unsigned char)(char_array_3[2] & 0x3f);
|
||||
|
||||
for (j = 0; j < i + 1; j++)
|
||||
for (size_t j = 0; j < i + 1; j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
|
@ -102,7 +101,6 @@ static std::string base64_decode(std::string const& encoded_string)
|
|||
{
|
||||
size_t in_len = encoded_string.size();
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
size_t in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
@ -124,17 +122,18 @@ static std::string base64_decode(std::string const& encoded_string)
|
|||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
for (size_t j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
for (size_t j = 0; j <4; j++)
|
||||
char_array_4[j] = (unsigned char)base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (unsigned char)((char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4));
|
||||
char_array_3[1] = (unsigned char)(((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2));
|
||||
char_array_3[2] = (unsigned char)(((char_array_4[2] & 0x3) << 6) + char_array_4[3]);
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||
for (size_t j = 0; (j < i - 1); j++)
|
||||
ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace gdcm
|
|||
|
||||
/**
|
||||
* \brief ByteSwap
|
||||
* \details Perform machine dependent byte swaping (Little Endian,
|
||||
* \details Perform machine dependent byte swapping (Little Endian,
|
||||
* Big Endian, Bad Little Endian, Bad Big Endian).
|
||||
* TODO: bswap_32 / bswap_64 ...
|
||||
*/
|
||||
|
|
|
@ -105,10 +105,10 @@ template<class T>
|
|||
void Swap4(T &a, SwapCode const &swapcode)
|
||||
{
|
||||
#ifndef GDCM_WORDS_BIGENDIAN
|
||||
if ( swapcode == 4321 || swapcode == 2143 )
|
||||
a = (T)(( a << 8 ) | ( a >> 8 ));
|
||||
if ( swapcode == gdcm::SwapCode::BigEndian || swapcode == gdcm::SwapCode::BadBigEndian )
|
||||
a = ( a << 8 ) | ( a >> 8 );
|
||||
#else
|
||||
if ( swapcode == 1234 || swapcode == 3412 )
|
||||
if ( swapcode == gdcm::SwapCode::LittleEndian || swapcode == gdcm::SwapCode::BadLittleEndian )
|
||||
a = ( a << 8 ) | ( a >> 8 );
|
||||
// On big endian as long as the SwapCode is Unknown let's pretend we were
|
||||
// on a LittleEndian system (might introduce overhead on those system).
|
||||
|
@ -129,20 +129,20 @@ inline void Swap8(T &a, SwapCode const &swapcode)
|
|||
a= (( a<<24) | ((a<<8) & 0x00ff0000) | ((a>>8) & 0x0000ff00) | (a>>24) );
|
||||
#endif
|
||||
break;
|
||||
case 1234 :
|
||||
case gdcm::SwapCode::LittleEndian :
|
||||
#ifdef GDCM_WORDS_BIGENDIAN
|
||||
a= (( a<<24) | ((a<<8) & 0x00ff0000) | ((a>>8) & 0x0000ff00) | (a>>24) );
|
||||
#endif
|
||||
break;
|
||||
case 4321 :
|
||||
case gdcm::SwapCode::BigEndian :
|
||||
#ifndef GDCM_WORDS_BIGENDIAN
|
||||
a= (( a<<24) | ((a<<8) & 0x00ff0000) | ((a>>8) & 0x0000ff00) | (a>>24) );
|
||||
#endif
|
||||
break;
|
||||
case 3412 :
|
||||
case gdcm::SwapCode::BadLittleEndian :
|
||||
a= ((a<<16) | (a>>16) );
|
||||
break;
|
||||
case 2143 :
|
||||
case gdcm::SwapCode::BadBigEndian :
|
||||
a= (((a<< 8) & 0xff00ff00) | ((a>>8) & 0x00ff00ff) );
|
||||
break;
|
||||
default :
|
||||
|
@ -160,21 +160,21 @@ inline void Swap8<uint16_t>(uint16_t &a, SwapCode const &swapcode)
|
|||
a= (( a<<24) | ((a<<8) & 0x00ff0000) | ((a>>8) & 0x0000ff00) | (a>>24) );
|
||||
#endif
|
||||
break;
|
||||
case 1234 :
|
||||
case gdcm::SwapCode::LittleEndian :
|
||||
#ifdef GDCM_WORDS_BIGENDIAN
|
||||
a= (( a<<24) | ((a<<8) & 0x00ff0000) | ((a>>8) & 0x0000ff00) | (a>>24) );
|
||||
#endif
|
||||
break;
|
||||
case 4321 :
|
||||
case gdcm::SwapCode::BigEndian :
|
||||
#ifndef GDCM_WORDS_BIGENDIAN
|
||||
// probably not really useful since the lowest 0x0000 are what's used in unsigned shorts
|
||||
// a= (( a<<24) | ((a<<8) & 0x00ff0000) | ((a>>8) & 0x0000ff00) | (a>>24) );
|
||||
#endif
|
||||
break;
|
||||
case 3412 :
|
||||
case gdcm::SwapCode::BadLittleEndian :
|
||||
//a= ((a<<16) | (a>>16) );//do nothing, a = a
|
||||
break;
|
||||
case 2143 :
|
||||
case gdcm::SwapCode::BadBigEndian :
|
||||
a= (uint16_t)(((a<< 8) & 0xff00) | ((a>>8) & 0x00ff) );
|
||||
break;
|
||||
default :
|
||||
|
|
|
@ -32,13 +32,10 @@
|
|||
# define GDCM_WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
/* Allow access to UINT32_MAX , cf gdcmCommon.h */
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
/* Hard code the path to the public dictionary */
|
||||
#define PUB_DICT_PATH "@GDCM_PUB_DICT_PATH@"
|
||||
|
||||
/* Usefull in particular for loadshared where the full path
|
||||
/* Useful in particular for loadshared where the full path
|
||||
* to the lib is needed */
|
||||
#define GDCM_SOURCE_DIR "@GDCM_SOURCE_DIR@"
|
||||
#define GDCM_EXECUTABLE_OUTPUT_PATH "@EXECUTABLE_OUTPUT_PATH@"
|
||||
|
@ -78,10 +75,6 @@
|
|||
|
||||
#cmakedefine GDCM_AUTOLOAD_GDCMJNI
|
||||
|
||||
/* I guess something important */
|
||||
#cmakedefine GDCM_HAVE_STDINT_H
|
||||
#cmakedefine GDCM_HAVE_INTTYPES_H
|
||||
|
||||
/* This variable allows you to have helpful debug statement */
|
||||
/* That are in between #ifdef / endif in the gdcm code */
|
||||
/* That means if GDCM_DEBUG is OFF there shouldn't be any 'cout' at all ! */
|
||||
|
@ -124,6 +117,10 @@
|
|||
// UTF-8
|
||||
#cmakedefine GDCM_HAVE_WCHAR_IFSTREAM
|
||||
|
||||
// https://stackoverflow.com/questions/15615136/is-codecvt-not-a-std-header
|
||||
// https://stackoverflow.com/questions/50867257/c-use-of-wstring-convert-on-linux
|
||||
#cmakedefine GDCM_HAVE_CODECVT
|
||||
|
||||
#cmakedefine GDCM_FORCE_BIGENDIAN_EMULATION
|
||||
|
||||
#ifndef GDCM_OVERRIDE_BROKEN_IMPLEMENTATION
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace gdcm
|
|||
|
||||
/**
|
||||
* \brief Class to do handle the crypto factory
|
||||
* \details GDCM needs to access in a platform independant way
|
||||
* \details GDCM needs to access in a platform independent way
|
||||
* the user specified crypto engine. It can be:
|
||||
* \li CAPI (windows only)
|
||||
* \li OPENSSL (portable)
|
||||
|
|
|
@ -43,39 +43,54 @@ unsigned int Directory::Load(FilenameType const &name, bool recursive)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static inline std::string ToUtf8(std::wstring const &str) {
|
||||
std::string ret;
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length(),
|
||||
nullptr, 0, NULL, NULL);
|
||||
if (len > 0) {
|
||||
ret.resize(len);
|
||||
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.length(), &ret[0],
|
||||
len, NULL, NULL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int Directory::Explore(FilenameType const &name, bool recursive)
|
||||
{
|
||||
unsigned int nFiles = 0;
|
||||
std::string fileName;
|
||||
std::string dirName = name;
|
||||
//assert( System::FileIsDirectory( dirName ) );
|
||||
Directories.push_back( dirName );
|
||||
#ifdef _MSC_VER
|
||||
WIN32_FIND_DATA fileData;
|
||||
std::wstring fileName;
|
||||
std::wstring dirName = System::ConvertToUNC(name.c_str());
|
||||
Directories.push_back(ToUtf8(dirName));
|
||||
WIN32_FIND_DATAW fileData;
|
||||
if ('\\' == dirName[dirName.size() - 1])
|
||||
dirName = dirName.substr(0, dirName.size() - 1);
|
||||
if ('/' != dirName[dirName.size() - 1]) dirName.push_back('/');
|
||||
assert( '/' == dirName[dirName.size()-1] );
|
||||
const FilenameType firstfile = dirName+"*";
|
||||
HANDLE hFile = FindFirstFile(firstfile.c_str(), &fileData);
|
||||
const std::wstring firstfile = dirName+L"*";
|
||||
HANDLE hFile = FindFirstFileW(firstfile.c_str(), &fileData);
|
||||
|
||||
for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
|
||||
b = FindNextFile(hFile, &fileData))
|
||||
b = FindNextFileW(hFile, &fileData))
|
||||
{
|
||||
fileName = fileData.cFileName;
|
||||
if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
|
||||
{
|
||||
// Need to check for . and .. to avoid infinite loop
|
||||
if ( fileName != "." && fileName != ".."
|
||||
if ( fileName != L"." && fileName != L".."
|
||||
&& fileName[0] != '.' // discard any hidden dir
|
||||
&& recursive )
|
||||
{
|
||||
nFiles += Explore(dirName+fileName,recursive);
|
||||
nFiles += Explore(ToUtf8(dirName + fileName), recursive);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fileName[0] != '.') // discard "unix like" hidden files such as .git in submodules
|
||||
{
|
||||
Filenames.push_back(dirName+fileName);
|
||||
Filenames.push_back(ToUtf8(dirName+fileName));
|
||||
nFiles++;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +104,10 @@ unsigned int Directory::Explore(FilenameType const &name, bool recursive)
|
|||
}
|
||||
|
||||
#else
|
||||
std::string fileName;
|
||||
std::string dirName = name;
|
||||
// assert( System::FileIsDirectory( dirName ) );
|
||||
Directories.push_back(dirName);
|
||||
// Real POSIX implementation: scandir is a BSD extension only, and doesn't
|
||||
// work on debian for example
|
||||
|
||||
|
@ -101,7 +120,7 @@ unsigned int Directory::Explore(FilenameType const &name, bool recursive)
|
|||
}
|
||||
|
||||
// According to POSIX, the dirent structure contains a field char d_name[]
|
||||
// of unspecified size, with at most NAME_MAX characters preceeding the
|
||||
// of unspecified size, with at most NAME_MAX characters preceding the
|
||||
// terminating null character. Use of other fields will harm the porta-
|
||||
// bility of your programs.
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace gdcm
|
|||
* \brief Class for manipulation directories
|
||||
*
|
||||
* \note This implementation provide a cross platform implementation
|
||||
* for manipulating directores: basically traversing directories
|
||||
* for manipulating directories: basically traversing directories
|
||||
* and harvesting files
|
||||
*
|
||||
* \note
|
||||
|
|
|
@ -41,7 +41,7 @@ public :
|
|||
virtual void Print(std::ostream& os) const;
|
||||
|
||||
/** Return the StringName associated with the event. */
|
||||
virtual const char * GetEventName(void) const = 0;
|
||||
virtual const char * GetEventName() const = 0;
|
||||
|
||||
/** Check if given event matches or derives from this event. */
|
||||
virtual bool CheckEvent(const Event*) const = 0;
|
||||
|
@ -65,11 +65,11 @@ inline std::ostream& operator<<(std::ostream& os, Event &e)
|
|||
typedef classname Self; \
|
||||
typedef super Superclass; \
|
||||
classname() {} \
|
||||
virtual ~classname() {} \
|
||||
virtual const char * GetEventName() const { return #classname; } \
|
||||
virtual bool CheckEvent(const ::gdcm::Event* e) const \
|
||||
virtual ~classname() override = default; \
|
||||
virtual const char * GetEventName() const override { return #classname; } \
|
||||
virtual bool CheckEvent(const ::gdcm::Event* e) const override \
|
||||
{ return dynamic_cast<const Self*>(e) ? true : false; } \
|
||||
virtual ::gdcm::Event* MakeObject() const \
|
||||
virtual ::gdcm::Event* MakeObject() const override \
|
||||
{ return new Self; } \
|
||||
classname(const Self&s) : super(s){}; \
|
||||
private: \
|
||||
|
|
|
@ -54,9 +54,9 @@ class Exception : public std::exception
|
|||
const unsigned int lineNumber,
|
||||
const char* const func)
|
||||
{
|
||||
assert(desc != NULL);
|
||||
assert(file != NULL);
|
||||
assert(func != NULL);
|
||||
assert(desc != nullptr);
|
||||
assert(file != nullptr);
|
||||
assert(func != nullptr);
|
||||
std::ostringstream oswhat;
|
||||
oswhat << file << ":" << lineNumber << " (" << func << "):\n";
|
||||
oswhat << desc;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace gdcm
|
|||
{
|
||||
/**
|
||||
* \brief Class to manipulate file name's
|
||||
* \note OS independant representation of a filename (to query path, name and extension from a filename)
|
||||
* \note OS independent representation of a filename (to query path, name and extension from a filename)
|
||||
*/
|
||||
class GDCM_EXPORT Filename
|
||||
{
|
||||
|
@ -55,9 +55,9 @@ public:
|
|||
operator const char * () const { return GetFileName(); }
|
||||
|
||||
// FIXME: I don't like this function
|
||||
// It hides the realpath call (maybe usefull)
|
||||
// It hides the realpath call (maybe useful)
|
||||
// and it forces file to exist on the disk whereas Filename
|
||||
// should be independant from file existence.
|
||||
// should be independent from file existence.
|
||||
bool IsIdentical(Filename const &fn) const;
|
||||
|
||||
/// Does the filename ends with a particular string ?
|
||||
|
|
|
@ -84,7 +84,7 @@ bool FilenameGenerator::Generate()
|
|||
if ( num_percent != 1 )
|
||||
{
|
||||
// Bug: what if someone wants to output file such as %%%02 ... oh well
|
||||
gdcmDebugMacro( "No more than one % in string formating please" );
|
||||
gdcmDebugMacro( "No more than one % in string formatting please" );
|
||||
return false;
|
||||
}
|
||||
bool success = true;
|
||||
|
|
|
@ -45,6 +45,17 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/** The `static_assert(true, "")` idiom is commonly employed for
|
||||
* C++11 or greater to ensure that it is compile-time only
|
||||
* check that can not be part of the binary file.
|
||||
* This allows a macro to be used anywhere that a statement
|
||||
* is expected, and to enforce consistent use of ; after
|
||||
* a macro. The static_assert is a constexpr that can be used
|
||||
* in places where raw statements (i.e. 'do{} while(0)') are
|
||||
* not allowed (i.e. after class member function definitions).
|
||||
* */
|
||||
# define GDCM_NOOP_STATEMENT static_assert(true, "")
|
||||
|
||||
// Macros to create runtime deprecation warning messages in function
|
||||
// bodies. Example usage:
|
||||
//
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#endif
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
// http://stackoverflow.com/questions/13256446/compute-md5-hash-value-by-c-winapi
|
||||
namespace gdcm
|
||||
|
@ -39,17 +43,17 @@ bool MD5::Compute(const char *buffer, size_t buf_len, char digest_str[33])
|
|||
MD5_Update(&ctx, buffer, buf_len);
|
||||
MD5_Final(digest, &ctx);
|
||||
for (int di = 0; di < 16; ++di)
|
||||
sprintf(digest_str+2*di, "%02x", digest[di]);
|
||||
snprintf(digest_str+2*di, 3, "%02x", digest[di]);
|
||||
digest_str[2*16] = '\0';
|
||||
return true;
|
||||
#elif defined(GDCM_BUILD_TESTING)
|
||||
md5_byte_t digest[16];
|
||||
md5_state_t state;
|
||||
md5_init(&state);
|
||||
md5_append(&state, (const md5_byte_t *)buffer, (int)buf_len);
|
||||
md5_append(&state, (const md5_byte_t *)buffer, buf_len);
|
||||
md5_finish(&state, digest);
|
||||
for (int di = 0; di < 16; ++di)
|
||||
sprintf(digest_str+2*di, "%02x", digest[di]);
|
||||
snprintf(digest_str+2*di, 3, "%02x", digest[di]);
|
||||
digest_str[2*16] = '\0';
|
||||
return true;
|
||||
#else
|
||||
|
@ -95,7 +99,7 @@ static bool process_file(const char *filename, md5_byte_t *digest)
|
|||
|
||||
md5_state_t state;
|
||||
md5_init(&state);
|
||||
md5_append(&state, (const md5_byte_t *)buffer, (int)file_size);
|
||||
md5_append(&state, (const md5_byte_t *)buffer, file_size);
|
||||
md5_finish(&state, digest);
|
||||
|
||||
return true;
|
||||
|
@ -124,7 +128,7 @@ bool MD5::ComputeFile(const char *filename, char digest_str[33])
|
|||
|
||||
for (int di = 0; di < 16; ++di)
|
||||
{
|
||||
sprintf(digest_str+2*di, "%02x", digest[di]);
|
||||
snprintf(digest_str+2*di, 3, "%02x", digest[di]);
|
||||
}
|
||||
digest_str[2*16] = '\0';
|
||||
return true;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace gdcm
|
|||
{
|
||||
// Don't ask why, but this is EXTREMELY important on Win32
|
||||
// Apparently the compiler is doing something special the first time it compiles
|
||||
// this instanciation unit
|
||||
// this instantiation unit
|
||||
// If this fake file is not present I get an unresolved symbol for each function
|
||||
// of the gdcm::Object class
|
||||
|
||||
|
|
|
@ -97,7 +97,11 @@ bool OpenSSLCryptographicMessageSyntax::Encrypt(char *output, size_t &outlen, co
|
|||
goto err;
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF
|
||||
in = BIO_new_mem_buf((const void*)array, (int)len);
|
||||
#else
|
||||
in = BIO_new_mem_buf((void*)array, (int)len);
|
||||
#endif
|
||||
if(!in)
|
||||
{
|
||||
gdcmErrorMacro( "Error at creating the input memory buffer." );
|
||||
|
@ -115,7 +119,7 @@ bool OpenSSLCryptographicMessageSyntax::Encrypt(char *output, size_t &outlen, co
|
|||
cms = CMS_encrypt(recips, in, internalCipherType, flags);
|
||||
if (!cms)
|
||||
{
|
||||
gdcmErrorMacro( "Error at creating the CMS strucutre." );
|
||||
gdcmErrorMacro( "Error at creating the CMS structure." );
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -183,7 +187,11 @@ bool OpenSSLCryptographicMessageSyntax::Decrypt(char *output, size_t &outlen, co
|
|||
goto err;
|
||||
}
|
||||
|
||||
#ifdef OPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF
|
||||
in = BIO_new_mem_buf((const void*)array, (int)len);
|
||||
#else
|
||||
in = BIO_new_mem_buf((void*)array, (int)len);
|
||||
#endif
|
||||
if (!in)
|
||||
{
|
||||
gdcmErrorMacro( "Error at creating the input memory buffer." );
|
||||
|
|
|
@ -153,7 +153,11 @@ public:
|
|||
gdcmErrorMacro( "len is too big: " << len );
|
||||
return false;
|
||||
}
|
||||
#ifdef OPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF
|
||||
BIO *data = BIO_new_mem_buf((const void*)array, (int)len);
|
||||
#else
|
||||
BIO *data = BIO_new_mem_buf((void*)array, (int)len);
|
||||
#endif
|
||||
if(!data)
|
||||
{
|
||||
gdcmErrorMacro( "BIO_new_mem_buf" );
|
||||
|
@ -308,7 +312,11 @@ bool OpenSSLP7CryptographicMessageSyntax::Decrypt(char *output, size_t &outlen,
|
|||
gdcmErrorMacro( "len is too big: " << len );
|
||||
return false;
|
||||
}
|
||||
#ifdef OPENSSL_HAS_CONST_VOID_BIO_NEW_MEM_BUF
|
||||
data = BIO_new_mem_buf((const void*)array, (int)len);
|
||||
#else
|
||||
data = BIO_new_mem_buf((void*)array, (int)len);
|
||||
#endif
|
||||
if(!data) goto err;
|
||||
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public :
|
|||
/// compute the area
|
||||
virtual size_t Area() const = 0;
|
||||
|
||||
// implementation detail of heterogenous container in C++
|
||||
// implementation detail of heterogeneous container in C++
|
||||
virtual Region *Clone() const = 0;
|
||||
|
||||
/// Return the Axis-Aligned minimum bounding box for all regions
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <string.h> // memcmp
|
||||
#include <stdlib.h> // malloc
|
||||
#include <stdio.h> // sprintf
|
||||
#include <stdio.h> // snprintf
|
||||
|
||||
/*
|
||||
*/
|
||||
|
@ -62,7 +62,7 @@ bool SHA1::Compute(const char *buffer, unsigned long buf_len, char digest[])
|
|||
|
||||
for (int di = 0; di < 20; ++di)
|
||||
{
|
||||
sprintf(digest+2*di, "%02x", output[di]);
|
||||
snprintf(digest+2*di, 3, "%02x", output[di]);
|
||||
}
|
||||
digest[2*20] = '\0';
|
||||
|
||||
|
@ -131,7 +131,7 @@ bool SHA1::ComputeFile(const char *filename, char digest_str[20*2+1])
|
|||
|
||||
for (int di = 0; di < 20; ++di)
|
||||
{
|
||||
sprintf(digest_str+2*di, "%02x", digest[di]);
|
||||
snprintf(digest_str+2*di, 3, "%02x", digest[di]);
|
||||
}
|
||||
digest_str[2*20] = '\0';
|
||||
return true;
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
}
|
||||
String(const value_type* s, size_type n): std::string(s, n)
|
||||
{
|
||||
// We are being passed a const char* pointer, so s[n] == 0 (garanteed!)
|
||||
// We are being passed a const char* pointer, so s[n] == 0 (guaranteed!)
|
||||
if( n % 2 )
|
||||
{
|
||||
push_back( TPadChar );
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
unsigned long AddObserver(const Event & event, Command *) const;
|
||||
|
||||
/** Get the command associated with the given tag. NOTE: This returns
|
||||
* a pointer to a Command, but it is safe to asign this to a
|
||||
* a pointer to a Command, but it is safe to assign this to a
|
||||
* Command::Pointer. Since Command inherits from LightObject, at this
|
||||
* point in the code, only a pointer or a reference to the Command can
|
||||
* be used. */
|
||||
|
|
|
@ -25,7 +25,7 @@ class SwapperDoOp
|
|||
{
|
||||
public:
|
||||
template <typename T> static T Swap(T val) {return val;}
|
||||
template <typename T> static void SwapArray(T *, unsigned int ) {}
|
||||
template <typename T> static void SwapArray(T *, size_t ) {}
|
||||
};
|
||||
|
||||
class SwapperNoOp
|
||||
|
@ -33,10 +33,10 @@ class SwapperNoOp
|
|||
public:
|
||||
template <typename T> static T Swap(T val);
|
||||
template <typename T>
|
||||
static void SwapArray(T *array, unsigned int n)
|
||||
static void SwapArray(T *array, size_t n)
|
||||
{
|
||||
// TODO: need to unroll loop:
|
||||
for(unsigned int i = 0; i < n; ++i)
|
||||
for(size_t i = 0; i < n; ++i)
|
||||
{
|
||||
array[i] = Swap<T>(array[i]);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#ifndef GDCMSWAPPER_TXX
|
||||
#define GDCMSWAPPER_TXX
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/a3140177
|
||||
|
@ -106,7 +108,12 @@ namespace gdcm
|
|||
}
|
||||
template <> inline float SwapperNoOp::Swap<float>(float val)
|
||||
{
|
||||
return Swap((uint32_t)val);
|
||||
uint32_t tempI;
|
||||
memcpy(&tempI, &val, sizeof(uint32_t));
|
||||
tempI = Swap(tempI);
|
||||
float tempF;
|
||||
memcpy(&tempF, &tempI, sizeof(uint32_t));
|
||||
return tempF;
|
||||
}
|
||||
template <> inline uint64_t SwapperNoOp::Swap<uint64_t>(uint64_t val)
|
||||
{
|
||||
|
@ -118,7 +125,12 @@ namespace gdcm
|
|||
}
|
||||
template <> inline double SwapperNoOp::Swap<double>(double val)
|
||||
{
|
||||
return Swap((uint64_t)val);
|
||||
uint64_t tempI;
|
||||
memcpy(&tempI, &val, sizeof(uint64_t));
|
||||
tempI = Swap(tempI);
|
||||
double tempF;
|
||||
memcpy(&tempF, &tempI, sizeof(uint64_t));
|
||||
return tempF;
|
||||
}
|
||||
|
||||
template <> inline Tag SwapperNoOp::Swap<Tag>(Tag val)
|
||||
|
@ -126,9 +138,9 @@ namespace gdcm
|
|||
return Tag( Swap(val.GetGroup()), Swap(val.GetElement()) );
|
||||
}
|
||||
|
||||
template <> inline void SwapperNoOp::SwapArray(uint8_t *, unsigned int ) {}
|
||||
template <> inline void SwapperNoOp::SwapArray(uint8_t *, size_t ) {}
|
||||
|
||||
template <> inline void SwapperNoOp::SwapArray(float *array, unsigned int n)
|
||||
template <> inline void SwapperNoOp::SwapArray(float *array, size_t n)
|
||||
{
|
||||
switch( sizeof(float) )
|
||||
{
|
||||
|
@ -140,7 +152,7 @@ namespace gdcm
|
|||
}
|
||||
}
|
||||
|
||||
template <> inline void SwapperNoOp::SwapArray(double *array, unsigned int n)
|
||||
template <> inline void SwapperNoOp::SwapArray(double *array, size_t n)
|
||||
{
|
||||
switch( sizeof(double) )
|
||||
{
|
||||
|
@ -172,7 +184,12 @@ namespace gdcm
|
|||
}
|
||||
template <> inline float SwapperDoOp::Swap<float>(float val)
|
||||
{
|
||||
return static_cast<float>(Swap((uint32_t)val));
|
||||
uint32_t tempI;
|
||||
memcpy(&tempI, &val, sizeof(uint32_t));
|
||||
tempI = Swap(tempI);
|
||||
float tempF;
|
||||
memcpy(&tempF, &tempI, sizeof(uint32_t));
|
||||
return tempF;
|
||||
}
|
||||
template <> inline uint64_t SwapperDoOp::Swap<uint64_t>(uint64_t val)
|
||||
{
|
||||
|
@ -184,7 +201,12 @@ namespace gdcm
|
|||
}
|
||||
template <> inline double SwapperDoOp::Swap<double>(double val)
|
||||
{
|
||||
return static_cast<double>(Swap((uint64_t)val));
|
||||
uint64_t tempI;
|
||||
memcpy(&tempI, &val, sizeof(uint64_t));
|
||||
tempI = Swap(tempI);
|
||||
double tempF;
|
||||
memcpy(&tempF, &tempI, sizeof(uint64_t));
|
||||
return tempF;
|
||||
}
|
||||
|
||||
template <> inline Tag SwapperDoOp::Swap<Tag>(Tag val)
|
||||
|
|
|
@ -135,6 +135,16 @@ const char * System::GetCWD()
|
|||
*/
|
||||
}
|
||||
|
||||
static inline int Mkdir2(const char *utf8)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
const std::wstring unc = System::ConvertToUNC(utf8);
|
||||
return _wmkdir(unc.c_str());
|
||||
#else
|
||||
return Mkdir(utf8);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool System::MakeDirectory(const char *path)
|
||||
{
|
||||
if( !path || !*path )
|
||||
|
@ -156,7 +166,7 @@ bool System::MakeDirectory(const char *path)
|
|||
while(ok && (pos = dir.find('/', pos)) != std::string::npos)
|
||||
{
|
||||
topdir = dir.substr(0, pos+1);
|
||||
ok = ok && (System::FileIsDirectory(topdir.c_str()) || 0 == Mkdir(topdir.c_str()));
|
||||
ok = ok && (System::FileIsDirectory(topdir.c_str()) || 0 == Mkdir2(topdir.c_str()));
|
||||
pos++;
|
||||
}
|
||||
if( !ok ) return false;
|
||||
|
@ -168,7 +178,7 @@ bool System::MakeDirectory(const char *path)
|
|||
{
|
||||
topdir = dir;
|
||||
}
|
||||
if(Mkdir(topdir.c_str()) != 0)
|
||||
if(Mkdir2(topdir.c_str()) != 0)
|
||||
{
|
||||
// There is a bug in the Borland Run time library which makes MKDIR
|
||||
// return EACCES when it should return EEXISTS
|
||||
|
@ -189,13 +199,15 @@ bool System::MakeDirectory(const char *path)
|
|||
// return true if the file exists
|
||||
bool System::FileExists(const char* filename)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
# define access _access
|
||||
#endif
|
||||
#ifndef R_OK
|
||||
# define R_OK 04
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
const std::wstring unc = System::ConvertToUNC(filename);
|
||||
if (_waccess(unc.c_str(), R_OK) != 0)
|
||||
#else
|
||||
if ( access(filename, R_OK) != 0 )
|
||||
#endif
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -208,8 +220,14 @@ bool System::FileExists(const char* filename)
|
|||
|
||||
bool System::FileIsDirectory(const char* name)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
struct _stat64i32 fs;
|
||||
const std::wstring wname = System::ConvertToUNC(name);
|
||||
if (_wstat(wname.c_str(), &fs) == 0)
|
||||
#else
|
||||
struct stat fs;
|
||||
if(stat(name, &fs) == 0)
|
||||
#endif
|
||||
{
|
||||
#if _WIN32
|
||||
return ((fs.st_mode & _S_IFDIR) != 0);
|
||||
|
@ -366,10 +384,83 @@ bool System::DeleteDirectory(const char *source)
|
|||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#ifdef _MSC_VER
|
||||
namespace {
|
||||
static inline std::wstring ToUtf16(std::string const &str) {
|
||||
std::wstring ret;
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.length(),
|
||||
nullptr, 0);
|
||||
if (len > 0) {
|
||||
ret.resize(len);
|
||||
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.length(), &ret[0],
|
||||
len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// http://arsenmk.blogspot.com/2015/12/handling-long-paths-on-windows.html
|
||||
static inline bool ComputeFullPath(std::wstring const &in,
|
||||
std::wstring &out) {
|
||||
// consider an input fileName of type PCWSTR (const wchar_t*)
|
||||
const wchar_t *fileName = in.c_str();
|
||||
DWORD requiredBufferLength =
|
||||
GetFullPathNameW(fileName, 0, nullptr, nullptr);
|
||||
|
||||
if (0 == requiredBufferLength) // means failure
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
out.resize(requiredBufferLength);
|
||||
wchar_t *buffer = &out[0];
|
||||
|
||||
DWORD result =
|
||||
GetFullPathNameW(fileName, requiredBufferLength, buffer, nullptr);
|
||||
|
||||
if (0 == result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// buffer now contains the full path name of fileName, use it.
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline std::wstring HandleMaxPath(std::wstring const &in) {
|
||||
if (in.size() >= MAX_PATH) {
|
||||
std::wstring out;
|
||||
bool ret = ComputeFullPath(in, out);
|
||||
if (!ret) return in;
|
||||
if (out.size() < 4) return in;
|
||||
if (out[0] == '\\' && out[1] == '\\' && out[2] == '?') {
|
||||
// nothing to do
|
||||
} else if (out[0] == '\\' && out[1] == '\\' && out[2] != '?') {
|
||||
// server path
|
||||
const std::wstring prefix = LR"(\\?\UNC\)";
|
||||
out = prefix + (out.c_str() + 2);
|
||||
} else {
|
||||
// regular C:\ style path:
|
||||
assert(out[1] == ':');
|
||||
const std::wstring prefix = LR"(\\?\)";
|
||||
out = prefix + out.c_str();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
std::wstring System::ConvertToUNC(const char *utf8path)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
const std::wstring uft16path = ToUtf16(utf8path);
|
||||
const std::wstring uncpath = HandleMaxPath(uft16path);
|
||||
return uncpath;
|
||||
#else
|
||||
(void)utf8path;
|
||||
return std::wstring();
|
||||
#endif
|
||||
}
|
||||
|
||||
// return size of file; also returns zero if no file exists
|
||||
size_t System::FileSize(const char* filename)
|
||||
{
|
||||
|
@ -476,7 +567,7 @@ const char *System::GetCurrentModuleFileName()
|
|||
if (dladdr( (void*)&where_am_i, &info ) == 0)
|
||||
{
|
||||
size_t len = strlen(info.dli_fname);
|
||||
if( len >= PATH_MAX ) return 0; // throw error ?
|
||||
if( len >= PATH_MAX ) return nullptr; // throw error ?
|
||||
// else
|
||||
strcpy(path,info.dli_fname);
|
||||
return path;
|
||||
|
@ -675,11 +766,11 @@ bool System::ParseDateTime(time_t &timep, long &milliseconds, const char date[22
|
|||
{
|
||||
switch (n)
|
||||
{
|
||||
case 1: mon = 1;
|
||||
case 2: day = 1;
|
||||
case 3: hour = 0;
|
||||
case 4: min = 0;
|
||||
case 5: sec = 0;
|
||||
case 1: mon = 1; /* Falls through. */
|
||||
case 2: day = 1; /* Falls through. */
|
||||
case 3: hour = 0; /* Falls through. */
|
||||
case 4: min = 0; /* Falls through. */
|
||||
case 5: sec = 0; /* Falls through. */
|
||||
break; // http://security.coverity.com/blog/2013/Sep/gimme-a-break.html
|
||||
}
|
||||
ptm.tm_year = year - 1900;
|
||||
|
@ -1009,8 +1100,8 @@ const char *System::GetLocaleCharset()
|
|||
const char *codeset2;
|
||||
codeset1 = buf1;
|
||||
codeset2 = buf2;
|
||||
sprintf(buf1, "CP%d", GetConsoleCP());
|
||||
sprintf(buf2, "CP%d", GetConsoleOutputCP());
|
||||
snprintf(buf1, sizeof(buf1), "CP%d", GetConsoleCP());
|
||||
snprintf(buf2, sizeof(buf2), "CP%d", GetConsoleOutputCP());
|
||||
|
||||
// BUG: both returns 'CP437' on debian + mingw32...
|
||||
// instead prefer GetACP() call:
|
||||
|
@ -1018,7 +1109,7 @@ const char *System::GetLocaleCharset()
|
|||
static char buf[2+10+1]; // 2 char, 10 bytes + 0
|
||||
// GetACP: Retrieves the current Windows ANSI code page identifier for the
|
||||
// operating system.
|
||||
sprintf (buf, "CP%u", GetACP ());
|
||||
snprintf (buf, sizeof(buf), "CP%u", GetACP ());
|
||||
codeset = CharsetAliasToName(buf);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class GDCM_EXPORT System
|
|||
public:
|
||||
/// Create a directory name path
|
||||
static bool MakeDirectory(const char *path);
|
||||
/// Check whether the specified file exist on the sytem
|
||||
/// Check whether the specified file exist on the system
|
||||
static bool FileExists(const char* filename);
|
||||
/// Check whether the file specified is a directory:
|
||||
static bool FileIsDirectory(const char* name);
|
||||
|
@ -39,6 +39,11 @@ public:
|
|||
/// remove a directory named source
|
||||
static bool DeleteDirectory(const char *source);
|
||||
|
||||
/// When needed convert a PATH into a UNC equivalent. This allow
|
||||
/// transparent support for path longer that MAX_PATH.
|
||||
/// Only on _MSC_VER compiler, return empty string otherwise.
|
||||
static std::wstring ConvertToUNC(const char *utf8path);
|
||||
|
||||
/// Return the last error
|
||||
static const char *GetLastSystemError();
|
||||
|
||||
|
@ -68,7 +73,7 @@ public:
|
|||
// Chdir
|
||||
// copy a file
|
||||
|
||||
/// Retrieve the hostname, only the first 255 byte are copyied.
|
||||
/// Retrieve the hostname, only the first 255 byte are copied.
|
||||
/// This may come handy to specify the Station Name
|
||||
static bool GetHostName(char hostname[255]);
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#include <iostream>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
@ -75,12 +79,12 @@ public:
|
|||
void setbgcolor(int col) { bgcolor = col; }
|
||||
//std::string resettextcolor() const {
|
||||
// char command[13];
|
||||
// sprintf(command, "%c[%d;%d;%dm", 0x1B, 0, 0, 0);
|
||||
// snprintf(command, sizeof(command), "%c[%d;%d;%dm", 0x1B, 0, 0, 0);
|
||||
// return command;
|
||||
//}
|
||||
std::string textcolor() const {
|
||||
char command[16];
|
||||
int n = sprintf(command, "%c[%d;%d;%dm", 0x1B, attribute, fgcolor + 30, bgcolor + 40);
|
||||
int n = snprintf(command, sizeof(command), "%c[%d;%d;%dm", 0x1B, attribute, fgcolor + 30, bgcolor + 40);
|
||||
assert( n < 16 ); (void)n;
|
||||
return command;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ const char * const * Testing::GetMediaStorageDataFile(unsigned int file)
|
|||
{
|
||||
if( file < Testing::GetNumberOfMediaStorageDataFiles() ) return gdcmMediaStorageDataFiles[file];
|
||||
// else return the {0x0, 0x0} sentinel:
|
||||
assert( *gdcmMediaStorageDataFiles[ Testing::GetNumberOfMediaStorageDataFiles() ] == 0 );
|
||||
assert( *gdcmMediaStorageDataFiles[ Testing::GetNumberOfMediaStorageDataFiles() ] == nullptr );
|
||||
return gdcmMediaStorageDataFiles[ Testing::GetNumberOfMediaStorageDataFiles() ];
|
||||
}
|
||||
const char * Testing::GetMediaStorageFromFile(const char *filepath)
|
||||
|
@ -119,7 +119,7 @@ const char * const * Testing::GetMD5DataImage(unsigned int file)
|
|||
{
|
||||
if( file < Testing::GetNumberOfMD5DataImages() ) return gdcmMD5DataImages[file];
|
||||
// else return the {0x0, 0x0} sentinel:
|
||||
assert( *gdcmMD5DataImages[ Testing::GetNumberOfMD5DataImages() ] == 0 );
|
||||
assert( *gdcmMD5DataImages[ Testing::GetNumberOfMD5DataImages() ] == nullptr );
|
||||
return gdcmMD5DataImages[ Testing::GetNumberOfMD5DataImages() ];
|
||||
}
|
||||
|
||||
|
@ -447,6 +447,11 @@ static const LossyFile gdcmLossyFilenames[] = {
|
|||
{ 0,"FUJI-ffff-MONO1-J2K.dcm" },
|
||||
{ 0,"JPEGLosslessSeNonZero.dcm" },
|
||||
{ 1,"US-YBR_FULL_422-EVRLE.dcm" },
|
||||
{ 0,"Osirix10vs8BitsStored.dcm" },
|
||||
{ 0,"Bug_Siemens_PrivateIconNoItem.dcm" },
|
||||
{ 0,"HardcopyColor_YBR_RCT_J2K_PC1.dcm" },
|
||||
{ 0,"PET-GE-dicomwrite-PixelDataSQUNv2.dcm" },
|
||||
{ 0,"MEDILABValidCP246_EVRLESQasOB.dcm" },
|
||||
{ 0, nullptr }
|
||||
};
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ private:
|
|||
* @param msg message part
|
||||
*/
|
||||
#if defined(NDEBUG) && !defined(GDCM_ALWAYS_TRACE_MACRO)
|
||||
#define gdcmDebugMacro(msg) {}
|
||||
#define gdcmDebugMacro(msg) GDCM_NOOP_STATEMENT
|
||||
#else
|
||||
#define gdcmDebugMacro(msg) \
|
||||
{ \
|
||||
|
@ -128,7 +128,8 @@ private:
|
|||
std::ostream &_os = gdcm::Trace::GetDebugStream(); \
|
||||
_os << osmacro.str() << "\n\n" << std::endl; \
|
||||
} \
|
||||
}
|
||||
} \
|
||||
GDCM_NOOP_STATEMENT
|
||||
#endif //NDEBUG
|
||||
|
||||
/**
|
||||
|
@ -136,7 +137,7 @@ private:
|
|||
* @param msg message part
|
||||
*/
|
||||
#if defined(NDEBUG) && !defined(GDCM_ALWAYS_TRACE_MACRO)
|
||||
#define gdcmWarningMacro(msg) {}
|
||||
#define gdcmWarningMacro(msg) GDCM_NOOP_STATEMENT
|
||||
#else
|
||||
#define gdcmWarningMacro(msg) \
|
||||
{ \
|
||||
|
@ -149,7 +150,8 @@ private:
|
|||
std::ostream &_os = gdcm::Trace::GetWarningStream(); \
|
||||
_os << osmacro.str() << std::endl; \
|
||||
} \
|
||||
}
|
||||
} \
|
||||
GDCM_NOOP_STATEMENT
|
||||
#endif //NDEBUG
|
||||
|
||||
/**
|
||||
|
@ -158,7 +160,7 @@ private:
|
|||
* @param msg second message part
|
||||
*/
|
||||
#if defined(NDEBUG) && !defined(GDCM_ALWAYS_TRACE_MACRO)
|
||||
#define gdcmErrorMacro(msg) {}
|
||||
#define gdcmErrorMacro(msg) GDCM_NOOP_STATEMENT
|
||||
#else
|
||||
#define gdcmErrorMacro(msg) \
|
||||
{ \
|
||||
|
@ -171,7 +173,8 @@ private:
|
|||
std::ostream &_os = gdcm::Trace::GetErrorStream(); \
|
||||
_os << osmacro.str() << std::endl; \
|
||||
} \
|
||||
}
|
||||
} \
|
||||
GDCM_NOOP_STATEMENT
|
||||
#endif //NDEBUG
|
||||
|
||||
/**
|
||||
|
@ -181,7 +184,7 @@ private:
|
|||
* gdcmAssertMacro( "my message" && 2 < 3 )
|
||||
*/
|
||||
#if defined(NDEBUG) && !defined(GDCM_ALWAYS_TRACE_MACRO)
|
||||
#define gdcmAssertMacro(arg) {}
|
||||
#define gdcmAssertMacro(arg) GDCM_NOOP_STATEMENT
|
||||
#else
|
||||
#define gdcmAssertMacro(arg) \
|
||||
{ \
|
||||
|
@ -195,7 +198,8 @@ private:
|
|||
_os << osmacro.str() << std::endl; \
|
||||
assert ( arg ); \
|
||||
} \
|
||||
}
|
||||
} \
|
||||
GDCM_NOOP_STATEMENT
|
||||
#endif //NDEBUG
|
||||
|
||||
/**
|
||||
|
@ -217,7 +221,8 @@ private:
|
|||
<< "\n\n"; \
|
||||
throw osmacro.str(); \
|
||||
} \
|
||||
}
|
||||
} \
|
||||
GDCM_NOOP_STATEMENT
|
||||
#else
|
||||
// Simply reproduce gdcmAssertMacro behavior:
|
||||
#define gdcmAssertAlwaysMacro(arg) gdcmAssertMacro(arg)
|
||||
|
|
|
@ -19,39 +19,7 @@
|
|||
#include "gdcmLegacyMacro.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef GDCM_HAVE_STDINT_H
|
||||
#ifndef __STDC_LIMIT_MACROS
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#endif // __STDC_LIMIT_MACROS
|
||||
#include <stdint.h>
|
||||
//#undef __STDC_LIMIT_MACROS
|
||||
#else
|
||||
#ifdef GDCM_HAVE_INTTYPES_H
|
||||
// Old system only have this
|
||||
#include <inttypes.h> // For uint8_t uint16_t and uint32_t
|
||||
#else
|
||||
// Broken plateforms do not respect C99 and do not provide those typedef
|
||||
// Special case for recent Borland compiler, comes with stdint.h
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x0560) || defined(__MINGW32__)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#elif defined(_MSC_VER)
|
||||
#include "stdint.h"
|
||||
#else
|
||||
#error "Sorry, your platform is not supported"
|
||||
#endif // defined(_MSC_VER) || defined(__BORLANDC__) && (__BORLANDC__ < 0x0560) || defined(__MINGW32__)
|
||||
#endif // GDCM_HAVE_INTTYPES_H
|
||||
#endif // GDCM_HAVE_STDINT_H
|
||||
|
||||
// Basically for VS6 and bcc 5.5.1:
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
#include <cstdint>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#endif //GDCMTYPES_H
|
||||
|
|
|
@ -129,21 +129,21 @@ public:
|
|||
int memory_level,
|
||||
size_t buffer_size);
|
||||
|
||||
~basic_zip_streambuf(void) override;
|
||||
~basic_zip_streambuf() override;
|
||||
|
||||
int sync (void) override;
|
||||
int sync () override;
|
||||
int_type overflow (int_type c) override;
|
||||
std::streamsize flush (void);
|
||||
std::streamsize flush ();
|
||||
inline
|
||||
ostream_reference get_ostream (void) const;
|
||||
ostream_reference get_ostream () const;
|
||||
inline
|
||||
int get_zerr (void) const;
|
||||
int get_zerr () const;
|
||||
inline
|
||||
unsigned long get_crc (void) const;
|
||||
unsigned long get_crc () const;
|
||||
inline
|
||||
unsigned long get_in_size (void) const;
|
||||
unsigned long get_in_size () const;
|
||||
inline
|
||||
long get_out_size(void) const;
|
||||
long get_out_size() const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -189,33 +189,33 @@ public:
|
|||
size_t read_buffer_size,
|
||||
size_t input_buffer_size);
|
||||
|
||||
~basic_unzip_streambuf(void) override;
|
||||
~basic_unzip_streambuf() override;
|
||||
|
||||
int_type underflow(void) override;
|
||||
int_type underflow() override;
|
||||
|
||||
/// returns the compressed input istream
|
||||
inline
|
||||
istream_reference get_istream (void);
|
||||
istream_reference get_istream ();
|
||||
inline
|
||||
z_stream& get_zip_stream (void);
|
||||
z_stream& get_zip_stream ();
|
||||
inline
|
||||
int get_zerr (void) const;
|
||||
int get_zerr () const;
|
||||
inline
|
||||
unsigned long get_crc (void) const;
|
||||
unsigned long get_crc () const;
|
||||
inline
|
||||
long get_out_size (void) const;
|
||||
long get_out_size () const;
|
||||
inline
|
||||
long get_in_size (void) const;
|
||||
long get_in_size () const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void put_back_from_zip_stream (void);
|
||||
void put_back_from_zip_stream ();
|
||||
|
||||
std::streamsize unzip_from_stream (char_type* buffer,
|
||||
std::streamsize buffer_size);
|
||||
|
||||
size_t fill_input_buffer (void);
|
||||
size_t fill_input_buffer ();
|
||||
|
||||
istream_reference _istream;
|
||||
z_stream _zip_stream;
|
||||
|
@ -250,21 +250,21 @@ public:
|
|||
int memory_level = 8,
|
||||
size_t buffer_size = zstream_default_buffer_size);
|
||||
|
||||
~basic_zip_ostream(void) override;
|
||||
~basic_zip_ostream() override;
|
||||
|
||||
inline
|
||||
bool is_gzip (void) const;
|
||||
bool is_gzip () const;
|
||||
inline
|
||||
basic_zip_ostream<charT, traits>& zflush (void);
|
||||
void finished (void);
|
||||
basic_zip_ostream<charT, traits>& zflush ();
|
||||
void finished ();
|
||||
|
||||
// void make_gzip()
|
||||
// { add_header(); _is_gzip = true; }
|
||||
|
||||
private:
|
||||
|
||||
basic_zip_ostream<charT,traits>& add_header(void);
|
||||
basic_zip_ostream<charT,traits>& add_footer(void);
|
||||
basic_zip_ostream<charT,traits>& add_header();
|
||||
basic_zip_ostream<charT,traits>& add_footer();
|
||||
|
||||
bool _is_gzip;
|
||||
bool _added_footer;
|
||||
|
@ -290,20 +290,20 @@ public:
|
|||
size_t input_buffer_size = zstream_default_buffer_size);
|
||||
|
||||
inline
|
||||
bool is_gzip (void) const;
|
||||
bool is_gzip () const;
|
||||
inline
|
||||
bool check_crc (void);
|
||||
bool check_crc ();
|
||||
inline
|
||||
bool check_data_size (void) const;
|
||||
bool check_data_size () const;
|
||||
inline
|
||||
long get_gzip_crc (void) const;
|
||||
long get_gzip_crc () const;
|
||||
inline
|
||||
long get_gzip_data_size(void) const;
|
||||
long get_gzip_data_size() const;
|
||||
|
||||
protected:
|
||||
|
||||
int check_header (void);
|
||||
void read_footer (void);
|
||||
int check_header ();
|
||||
void read_footer ();
|
||||
|
||||
bool _is_gzip;
|
||||
long _gzip_crc;
|
||||
|
|
|
@ -82,7 +82,7 @@ basic_zip_streambuf<charT, traits>::basic_zip_streambuf(ostream_reference ostrea
|
|||
/** Destructor
|
||||
*/
|
||||
template <class charT, class traits>
|
||||
basic_zip_streambuf<charT, traits>::~basic_zip_streambuf(void)
|
||||
basic_zip_streambuf<charT, traits>::~basic_zip_streambuf()
|
||||
{
|
||||
flush();
|
||||
// _ostream.flush(); CM already done in flush()
|
||||
|
@ -94,7 +94,7 @@ basic_zip_streambuf<charT, traits>::~basic_zip_streambuf(void)
|
|||
* document correctly!
|
||||
*/
|
||||
template <class charT, class traits>
|
||||
int basic_zip_streambuf<charT, traits>::sync(void)
|
||||
int basic_zip_streambuf<charT, traits>::sync()
|
||||
{
|
||||
if(this->pptr() && this->pptr() > this->pbase())
|
||||
{
|
||||
|
@ -141,7 +141,7 @@ basic_zip_streambuf<charT, traits>::overflow(int_type c)
|
|||
* multiple times, will lower the compression ratio.
|
||||
*/
|
||||
template <class charT, class traits>
|
||||
std::streamsize basic_zip_streambuf<charT, traits>::flush(void)
|
||||
std::streamsize basic_zip_streambuf<charT, traits>::flush()
|
||||
{
|
||||
std::streamsize written_byte_size = 0, total_written_byte_size = 0;
|
||||
|
||||
|
@ -158,7 +158,7 @@ std::streamsize basic_zip_streambuf<charT, traits>::flush(void)
|
|||
{
|
||||
written_byte_size = static_cast<std::streamsize>(_output_buffer.size()) - _zip_stream.avail_out;
|
||||
total_written_byte_size += written_byte_size;
|
||||
// ouput buffer is full, dumping to ostream
|
||||
// output buffer is full, dumping to ostream
|
||||
_ostream.write( (const char_type*) &(_output_buffer[0]),
|
||||
static_cast<std::streamsize>(written_byte_size/sizeof(char_type)*sizeof(char)));
|
||||
|
||||
|
@ -189,7 +189,7 @@ std::streamsize basic_zip_streambuf<charT, traits>::flush(void)
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
typename basic_zip_streambuf<charT, traits>::ostream_reference
|
||||
basic_zip_streambuf<charT, traits>::get_ostream(void) const
|
||||
basic_zip_streambuf<charT, traits>::get_ostream() const
|
||||
{
|
||||
return _ostream;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ basic_zip_streambuf<charT, traits>::get_ostream(void) const
|
|||
/** returns the latest zlib error status
|
||||
*/
|
||||
template <class charT, class traits> inline
|
||||
int basic_zip_streambuf<charT, traits>::get_zerr(void) const
|
||||
int basic_zip_streambuf<charT, traits>::get_zerr() const
|
||||
{
|
||||
return _err;
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ int basic_zip_streambuf<charT, traits>::get_zerr(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
unsigned long
|
||||
basic_zip_streambuf<charT, traits>:: get_crc(void) const
|
||||
basic_zip_streambuf<charT, traits>:: get_crc() const
|
||||
{
|
||||
return _crc;
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ basic_zip_streambuf<charT, traits>:: get_crc(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
unsigned long
|
||||
basic_zip_streambuf<charT, traits>::get_in_size(void) const
|
||||
basic_zip_streambuf<charT, traits>::get_in_size() const
|
||||
{
|
||||
return _zip_stream.total_in;
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ basic_zip_streambuf<charT, traits>::get_in_size(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
long
|
||||
basic_zip_streambuf<charT, traits>::get_out_size(void) const
|
||||
basic_zip_streambuf<charT, traits>::get_out_size() const
|
||||
{
|
||||
return _zip_stream.total_out;
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ bool basic_zip_streambuf<charT, traits>::zip_to_stream(
|
|||
written_byte_size= static_cast<std::streamsize>(_output_buffer.size()) -
|
||||
_zip_stream.avail_out;
|
||||
total_written_byte_size += written_byte_size;
|
||||
// ouput buffer is full, dumping to ostream
|
||||
// output buffer is full, dumping to ostream
|
||||
|
||||
_ostream.write((const char_type*) &_output_buffer[0],
|
||||
static_cast<std::streamsize>(written_byte_size / sizeof(char_type)));
|
||||
|
@ -334,7 +334,7 @@ basic_unzip_streambuf<charT, traits>::basic_unzip_streambuf(istream_reference is
|
|||
* @todo document!
|
||||
*/
|
||||
template <class charT, class traits>
|
||||
basic_unzip_streambuf<charT, traits>::~basic_unzip_streambuf(void)
|
||||
basic_unzip_streambuf<charT, traits>::~basic_unzip_streambuf()
|
||||
{
|
||||
inflateEnd(&_zip_stream);
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ basic_unzip_streambuf<charT, traits>::~basic_unzip_streambuf(void)
|
|||
*/
|
||||
template <class charT, class traits>
|
||||
typename basic_unzip_streambuf<charT, traits>::int_type
|
||||
basic_unzip_streambuf<charT, traits>::underflow(void)
|
||||
basic_unzip_streambuf<charT, traits>::underflow()
|
||||
{
|
||||
if(this->gptr() && ( this->gptr() < this->egptr()))
|
||||
return * reinterpret_cast<unsigned char *>(this->gptr());
|
||||
|
@ -379,7 +379,7 @@ basic_unzip_streambuf<charT, traits>::underflow(void)
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
typename basic_unzip_streambuf<charT, traits>::istream_reference
|
||||
basic_unzip_streambuf<charT, traits>::get_istream(void)
|
||||
basic_unzip_streambuf<charT, traits>::get_istream()
|
||||
{
|
||||
return _istream;
|
||||
}
|
||||
|
@ -388,7 +388,7 @@ basic_unzip_streambuf<charT, traits>::get_istream(void)
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
z_stream &
|
||||
basic_unzip_streambuf<charT, traits>::get_zip_stream(void)
|
||||
basic_unzip_streambuf<charT, traits>::get_zip_stream()
|
||||
{
|
||||
return _zip_stream;
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ basic_unzip_streambuf<charT, traits>::get_zip_stream(void)
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
int
|
||||
basic_unzip_streambuf<charT, traits>::get_zerr(void) const
|
||||
basic_unzip_streambuf<charT, traits>::get_zerr() const
|
||||
{
|
||||
return _err;
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ basic_unzip_streambuf<charT, traits>::get_zerr(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
unsigned long
|
||||
basic_unzip_streambuf<charT, traits>::get_crc(void) const
|
||||
basic_unzip_streambuf<charT, traits>::get_crc() const
|
||||
{
|
||||
return _crc;
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ basic_unzip_streambuf<charT, traits>::get_crc(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
long
|
||||
basic_unzip_streambuf<charT, traits>::get_out_size(void) const
|
||||
basic_unzip_streambuf<charT, traits>::get_out_size() const
|
||||
{
|
||||
return _zip_stream.total_out;
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ basic_unzip_streambuf<charT, traits>::get_out_size(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
long
|
||||
basic_unzip_streambuf<charT, traits>::get_in_size(void) const
|
||||
basic_unzip_streambuf<charT, traits>::get_in_size() const
|
||||
{
|
||||
return _zip_stream.total_in;
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ basic_unzip_streambuf<charT, traits>::get_in_size(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
void
|
||||
basic_unzip_streambuf<charT, traits>::put_back_from_zip_stream(void)
|
||||
basic_unzip_streambuf<charT, traits>::put_back_from_zip_stream()
|
||||
{
|
||||
if(_zip_stream.avail_in == 0)
|
||||
return;
|
||||
|
@ -496,7 +496,7 @@ basic_unzip_streambuf<charT, traits>::unzip_from_stream(char_type* buffer,
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
size_t
|
||||
basic_unzip_streambuf<charT, traits>::fill_input_buffer(void)
|
||||
basic_unzip_streambuf<charT, traits>::fill_input_buffer()
|
||||
{
|
||||
_zip_stream.next_in = &_input_buffer[0];
|
||||
_istream.read((char_type*) &_input_buffer[0],
|
||||
|
@ -565,7 +565,7 @@ basic_zip_ostream<charT, traits>::basic_zip_ostream(ostream_reference ostream,
|
|||
/** Destructor
|
||||
*/
|
||||
template <class charT, class traits>
|
||||
basic_zip_ostream<charT, traits>::~basic_zip_ostream(void)
|
||||
basic_zip_ostream<charT, traits>::~basic_zip_ostream()
|
||||
{
|
||||
//if(_is_gzip)
|
||||
add_footer();
|
||||
|
@ -574,7 +574,7 @@ basic_zip_ostream<charT, traits>::~basic_zip_ostream(void)
|
|||
/** returns true if it is a gzip
|
||||
*/
|
||||
template <class charT, class traits> inline
|
||||
bool basic_zip_ostream<charT, traits>::is_gzip(void) const
|
||||
bool basic_zip_ostream<charT, traits>::is_gzip() const
|
||||
{
|
||||
return _is_gzip;
|
||||
}
|
||||
|
@ -583,7 +583,7 @@ bool basic_zip_ostream<charT, traits>::is_gzip(void) const
|
|||
*/
|
||||
|
||||
template <class charT, class traits> inline
|
||||
basic_zip_ostream<charT, traits>& basic_zip_ostream<charT, traits>::zflush(void)
|
||||
basic_zip_ostream<charT, traits>& basic_zip_ostream<charT, traits>::zflush()
|
||||
{
|
||||
static_cast<std::basic_ostream<charT, traits> *>(this)->flush();
|
||||
static_cast<basic_zip_streambuf<charT, traits> *>(this)->flush();
|
||||
|
@ -591,7 +591,7 @@ basic_zip_ostream<charT, traits>& basic_zip_ostream<charT, traits>::zflush(void)
|
|||
}
|
||||
|
||||
template <class charT, class traits> inline
|
||||
void basic_zip_ostream<charT, traits>::finished(void)
|
||||
void basic_zip_ostream<charT, traits>::finished()
|
||||
{
|
||||
if(_is_gzip)
|
||||
add_footer();
|
||||
|
@ -608,7 +608,7 @@ void basic_zip_ostream<charT, traits>::finished(void)
|
|||
* @todo document!
|
||||
*/
|
||||
template <class charT, class traits>
|
||||
basic_zip_ostream<charT,traits>& basic_zip_ostream<charT, traits>::add_header(void)
|
||||
basic_zip_ostream<charT,traits>& basic_zip_ostream<charT, traits>::add_header()
|
||||
{
|
||||
char_type zero = 0;
|
||||
|
||||
|
@ -627,7 +627,7 @@ basic_zip_ostream<charT,traits>& basic_zip_ostream<charT, traits>::add_header(vo
|
|||
* @todo document!
|
||||
*/
|
||||
template <class charT, class traits>
|
||||
basic_zip_ostream<charT,traits>& basic_zip_ostream<charT, traits>::add_footer(void)
|
||||
basic_zip_ostream<charT,traits>& basic_zip_ostream<charT, traits>::add_footer()
|
||||
{
|
||||
if(_added_footer)
|
||||
return *this;
|
||||
|
@ -701,7 +701,7 @@ basic_zip_istream<charT, traits>::basic_zip_istream(istream_reference istream,
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
bool
|
||||
basic_zip_istream<charT, traits>::is_gzip(void) const
|
||||
basic_zip_istream<charT, traits>::is_gzip() const
|
||||
{
|
||||
return _is_gzip;
|
||||
}
|
||||
|
@ -711,11 +711,11 @@ basic_zip_istream<charT, traits>::is_gzip(void) const
|
|||
* This must be called after the reading of compressed data is finished! This
|
||||
* method compares it to the crc of the uncompressed data.
|
||||
*
|
||||
* \return true if crc check is succesful
|
||||
* \return true if crc check is successful
|
||||
*/
|
||||
template <class charT, class traits> inline
|
||||
bool
|
||||
basic_zip_istream<charT, traits>::check_crc(void)
|
||||
basic_zip_istream<charT, traits>::check_crc()
|
||||
{
|
||||
read_footer();
|
||||
return this->get_crc() == _gzip_crc;
|
||||
|
@ -725,7 +725,7 @@ basic_zip_istream<charT, traits>::check_crc(void)
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
bool
|
||||
basic_zip_istream<charT, traits>::check_data_size(void) const
|
||||
basic_zip_istream<charT, traits>::check_data_size() const
|
||||
{
|
||||
return this->get_out_size() == _gzip_data_size;
|
||||
}
|
||||
|
@ -734,7 +734,7 @@ basic_zip_istream<charT, traits>::check_data_size(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
long
|
||||
basic_zip_istream<charT, traits>::get_gzip_crc(void) const
|
||||
basic_zip_istream<charT, traits>::get_gzip_crc() const
|
||||
{
|
||||
return _gzip_crc;
|
||||
}
|
||||
|
@ -743,7 +743,7 @@ basic_zip_istream<charT, traits>::get_gzip_crc(void) const
|
|||
*/
|
||||
template <class charT, class traits> inline
|
||||
long
|
||||
basic_zip_istream<charT, traits>::get_gzip_data_size(void) const
|
||||
basic_zip_istream<charT, traits>::get_gzip_data_size() const
|
||||
{
|
||||
return _gzip_data_size;
|
||||
}
|
||||
|
@ -757,7 +757,7 @@ basic_zip_istream<charT, traits>::get_gzip_data_size(void) const
|
|||
*/
|
||||
template <class charT, class traits>
|
||||
int
|
||||
basic_zip_istream<charT, traits>::check_header(void)
|
||||
basic_zip_istream<charT, traits>::check_header()
|
||||
{
|
||||
int method; /* method byte */
|
||||
int flagsbyte; /* flags byte */
|
||||
|
@ -831,7 +831,7 @@ basic_zip_istream<charT, traits>::check_header(void)
|
|||
*/
|
||||
template <class charT, class traits>
|
||||
void
|
||||
basic_zip_istream<charT, traits>::read_footer(void)
|
||||
basic_zip_istream<charT, traits>::read_footer()
|
||||
{
|
||||
if(_is_gzip)
|
||||
{
|
||||
|
|
|
@ -166,7 +166,7 @@ generating group length for arbitrary even group number seems to get my xsltproc
|
|||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:text>
|
||||
{0,0,VR::INVALID,VM::VM0,0 } // Gard
|
||||
{0,0,VR::INVALID,VM::VM0,0 } // Guard
|
||||
};
|
||||
|
||||
void CSAHeaderDict::LoadDefault()
|
||||
|
|
|
@ -36,7 +36,7 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
|
||||
-->
|
||||
<dict>
|
||||
<!--entry name="Attribute Name" type="Type" vr="VR" vm="VM" description="Descriptiom"/-->
|
||||
<!--entry name="Attribute Name" type="Type" vr="VR" vm="VM" description="Description"/-->
|
||||
<!--entry name="General Image Attributes" type="1" vr=" " vm=" " description=""/-->
|
||||
<entry name="AcquisitionDate" type="3" vr="DA" vm="1" description="A number identifying the single continuous gathering of data over a period of time which resulted in this image"/>
|
||||
<entry name="ContentDate" type="2C" vr="DA" vm="1" description="The date the image data creation started. Required if image is part of a series in which the images are temporally related"/>
|
||||
|
@ -51,11 +51,11 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
<!--entry name="ReferencedImageSequence" type="3" vr="link" vm="1" description="A sequence which provides reference to a set of Image SOP Class/Instance identifying other images significantly related to this image (localizer images)"/-->
|
||||
<entry name=">Referenced SOP Class UID" type="1C" vr="UI" vm="1" description="Uniquely identifies the referenced SOP Class"/>
|
||||
<entry name=">Referenced SOP Instance UID" type="1C" vr="UI" vm="1" description="Uniquely identifies the referenced SOP Instance"/>
|
||||
<entry name="> Referenced Frame Number" type="3" vr="IS" vm="1-n" description="References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are siginificantly related to this image"/>
|
||||
<entry name="> Referenced Frame Number" type="3" vr="IS" vm="1-n" description="References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are significantly related to this image"/>
|
||||
<!--entry name="SourceImageSequence" type="3" vr="link" vm="1" description="A sequence which identifies the set of Image SOP Class/Instance pairs of the images which were use to derive this image"/-->
|
||||
<entry name=">Referenced SOP Class UID" type="1C" vr="UI" vm="1" description="Uniquely identifies the referenced SOP Class"/>
|
||||
<entry name=">Referenced SOP Instance UID" type="1C" vr="UI" vm="1" description="Uniquely identifies the referenced SOP Instance"/>
|
||||
<entry name="> Referenced Frame Number" type="3" vr="IS" vm="1-n" description="References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are siginificantly related to this image"/>
|
||||
<entry name="> Referenced Frame Number" type="3" vr="IS" vm="1-n" description="References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are significantly related to this image"/>
|
||||
<entry name="ImageType" type="3" vr="CS" vm="1-n" description="Image identification characteristics"/>
|
||||
<entry name="Lossy Image Compression" type="3" vr="CS" vm="1" description="Specifies whether an image has undergone lossy compression. Enumerated values: 00 = image has not been subjected to lossy compression. 01 = image has been subjected to lossy compression"/>
|
||||
<entry name="Quality Control Image" type="1C" vr="CS" vm="1" description="Indicates whether or not this image is a quality control or phantom image. Enumerated values: YES, NO"/>
|
||||
|
@ -70,9 +70,9 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
<entry name="ScanOptions" type="2" vr="CS" vm="1-n" description="Parameters of scanning sequence"/>
|
||||
<entry name="MRAcquisitionType" type="2" vr="CS" vm="1" description="Identification of date encoding scheme. Enumerated Values: 2D = frequency x phase 3D = frequency x phase x phase"/>
|
||||
<!--entry name=" " type="1" vr=" " vm=" " description=" "/-->
|
||||
<entry name="SequenceName" type="3" vr="SH" vm="1" description="User defined name for the Scanning Sequence and Sequence Varaint combination"/>
|
||||
<entry name="SequenceName" type="3" vr="SH" vm="1" description="User defined name for the Scanning Sequence and Sequence Variant combination"/>
|
||||
<entry name="AngioFlag" type="3" vr="CS" vm="1" description="Angio image indicator. Primary image for angio processing. Enumerated values: Y = image is Angio N = image is not Angio"/>
|
||||
<entry name="RepetitionTime" type="2C" vr="DS" vm="1" description="The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequnece Variant is not segmented k-space"/>
|
||||
<entry name="RepetitionTime" type="2C" vr="DS" vm="1" description="The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequence Variant is not segmented k-space"/>
|
||||
<entry name="EchoTime" type="2" vr="DS" vm="1" description="Time in msec between the middle of the excitation pulse and the peak of the echo produced. In the case of segmented k-space, the TE(eff) is the time between the middle of the excitation pulse to the peak of the echo that is used to cover the center of k-space)"/>
|
||||
<entry name="InversionTime" type="2C" vr="DS" vm="1" description="Time in msec after the middle of inverting RF pulse to middle of excitation pulse to detect the amount of longitudinal magnetization. Required if Scanning Sequence has value of IR"/>
|
||||
<entry name="NumberOfAverages" type="3" vr="DS" vm="1" description="Number of times a given pulse sequence is repeated before any parameter has changed"/>
|
||||
|
@ -97,7 +97,7 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
<entry name="Skip Beats" type="3" vr="IS" vm="1" description="Number of beats skipped after a detected arrhythmia"/>
|
||||
<entry name="HeartRate" type="3" vr="IS" vm="1" description="Beats per minute"/>
|
||||
<entry name="CardiacNumberOfImages" type="3" vr="IS" vm="1" description="Number of imagesb per cardiac cycle"/>
|
||||
<entry name="TriggerWindow" type="3" vr="IS" vm="1" description="Percent of R-R interval, based on Heart Rate (0018,1088), prescriped as a window for a valid/usable trigger"/>
|
||||
<entry name="TriggerWindow" type="3" vr="IS" vm="1" description="Percent of R-R interval, based on Heart Rate (0018,1088), prescribed as a window for a valid/usable trigger"/>
|
||||
<entry name="ReconstructionDiameter" type="3" vr="DS" vm="1" description="Diameter in mm of the region from within which data were used in creating the reconstruction of the image. Data may exist outside this region and portions of the patient may exist outside the region"/>
|
||||
<entry name="Receive Coil" type="3" vr="SH" vm="1" description="Received coil used"/>
|
||||
<entry name="TransmittingCoil" type="3" vr="SH" vm="1" description="Transmitted coil used"/>
|
||||
|
@ -146,7 +146,7 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
<entry name="InstitutionName" type="3" vr="LO" vm="1" description="Institution where the equipment is located that produced the digital images"/>
|
||||
<entry name="InstitutionAddress" type="3" vr="ST" vm="1" description="Mailing address of the institution where the equipment is located that produced the digital images"/>
|
||||
<entry name="ManufacturersModelName" type="3" vr="LO" vm="1" description="Manufacturer's model number of the equipment that produced the digital images"/>
|
||||
<entry name="DeviceSerialNumber" type="3" vr="LO" vm="1" description="Manufacturer's seriel number of the equipment that produced the digital images"/>
|
||||
<entry name="DeviceSerialNumber" type="3" vr="LO" vm="1" description="Manufacturer's serial number of the equipment that produced the digital images"/>
|
||||
<entry name="SoftwareVersions" type="3" vr="LO" vm="1-n" description="Manufacturer's designation of software of the equipment that produced the digital images"/>
|
||||
<!--entry name="Overlay Idendification Attributes" type="1" vr=" " vm=" " description=" "/-->
|
||||
<entry name="OverlayRows" type="1" vr="US" vm="1" description="Number of Rows in Overlay"/>
|
||||
|
@ -177,7 +177,7 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
<entry name="PixelFileName" type="1" vr="UN" vm="1" description="Used raw data file name for the performed acquisition"/>
|
||||
<entry name="SliceMeasurementDuration" type="1" vr="DS" vm="1" description="Time duration between two slices of the performed acquisition"/>
|
||||
<entry name="AcquisitionMatrixText" type="1" vr="SH" vm="1" description="Used acquisition matrix description"/>
|
||||
<entry name="SequenceMask" type="1" vr="UL" vm="1" description="Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens seqence ...."/>
|
||||
<entry name="SequenceMask" type="1" vr="UL" vm="1" description="Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens sequence ...."/>
|
||||
<entry name="MeasuredFourierLines" type="1" vr="IS" vm="1" description="Number of performed fourier lines"/>
|
||||
<entry name="FlowEncodingDirection" type="1" vr="IS" vm="1" description="Flow encoding direction"/>
|
||||
<entry name="FlowVenc" type="1" vr="FD" vm="1" description="Flow Quant attribute"/>
|
||||
|
@ -187,7 +187,7 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
<entry name="ImageGroup" type="1" vr="US" vm="1" description="Group of images"/>
|
||||
<entry name="SliceNormalVector" type="1" vr="FD" vm="3" description="X,y and z normal vector of the slices"/>
|
||||
<entry name="DiffusionDirection" type="1" vr="CS" vm="1" description="Diffusion direction"/>
|
||||
<entry name="TimeAfterStart" type="1" vr="DS" vm="1" description="Time delay after start of measurment"/>
|
||||
<entry name="TimeAfterStart" type="1" vr="DS" vm="1" description="Time delay after start of measurement"/>
|
||||
<entry name="FlipAngle" type="1" vr="DS" vm="1" description="Flip angle for SC images"/>
|
||||
<entry name="SequenceName" type="1" vr="SH" vm="1" description="Sequence name for SC images"/>
|
||||
<entry name="RepetitionTime" type="1" vr="DS" vm="1" description="Repetition time for SC images"/>
|
||||
|
@ -208,8 +208,8 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
<entry name="ReferencedImageSequence" type="1" vr="UI" vm="1_n" description="A sequence which provides reference to a set of Image SOP Class/Instance identifying other images significantly related to this image (localizer images)"/>
|
||||
<entry name="PatientOrientation" type="1" vr="CS" vm="1" description="Patient direction of the rows and columns of the image. Not required for MR images"/>
|
||||
<entry name="ScanningSequence" type="1" vr="CS" vm="1_n" description="Description of the type of data taken. Enumerated values: SE = Spin Echo; IR = Inversion Recovery; GR = Gradient Recalled; EP = Echo Planar; RM = Research Mode"/>
|
||||
<entry name="SequenceName" type="1" vr="SH" vm="1" description="User defined name for the Scanning Sequence and Sequence Varaint combination"/>
|
||||
<entry name="RepetitionTime" type="1" vr="DS" vm="1" description="The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequnece Variant is not segmented k-space"/>
|
||||
<entry name="SequenceName" type="1" vr="SH" vm="1" description="User defined name for the Scanning Sequence and Sequence Variant combination"/>
|
||||
<entry name="RepetitionTime" type="1" vr="DS" vm="1" description="The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequence Variant is not segmented k-space"/>
|
||||
<entry name="EchoTime" type="1" vr="DS" vm="1" description="Time in msec between the middle of the excitation pulse and the peak of the echo produced. In the case of segmented k-space, the TE(eff) is the time between the middle of the excitation pulse to the peak of the echo that is used to cover the center of k-space)"/>
|
||||
<entry name="InversionTime" type="1" vr="DS" vm="1" description="Time in msec after the middle of inverting RF pulse to middle of excitation pulse to detect the amount of longitudinal magnetization. Required if Scanning Sequence has value of IR"/>
|
||||
<entry name="NumberOfAverages" type="1" vr="DS" vm="1" description="Number of averages"/>
|
||||
|
@ -249,7 +249,7 @@ sKSpace.ucPhasePartialFourier = 0x10
|
|||
<entry name="SourceImageSequence" type="1" vr="UI" vm="1_n" description="A sequence which identifies the set of Image SOP Class/Instance pairs of the images which were use to derive this image"/>
|
||||
<entry name="PixelBandwidth" type="1" vr="DS" vm="1" description="Reciprocal of the total sampling period, in hertz per pixel"/>
|
||||
<entry name="SliceMeasurementDuration" type="1" vr="DS" vm="1" description="Time duration between two slices of the performed acquisition"/>
|
||||
<entry name="SequenceMask" type="1" vr="UL" vm="1" description="Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens seqence .·"/>
|
||||
<entry name="SequenceMask" type="1" vr="UL" vm="1" description="Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens sequence .·"/>
|
||||
<entry name="AcquisitionMatrixText" type="1" vr="SH" vm="1" description="Used acquisition matrix description"/>
|
||||
<entry name="MeasuredFourierLines" type="1" vr="IS" vm="1" description="Number of performed fourier lines"/>
|
||||
<!--entry name="MR Protocol" type="1" vr=" " vm=" " description=" "/-->
|
||||
|
|
|
@ -164,7 +164,7 @@ generating group length for arbitrary even group number seems to get my xsltproc
|
|||
<xsl:text>
|
||||
// FIXME: need a dummy element
|
||||
{0xffff,0xffff,VR::INVALID,VM::VM0,"","",true }, // dummy
|
||||
{0xffff,0xffff,VR::INVALID,VM::VM0,0,0,true } // Gard
|
||||
{0xffff,0xffff,VR::INVALID,VM::VM0,0,0,true } // Guard
|
||||
};
|
||||
|
||||
void Dict::LoadDefault()
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
|
||||
=========================================================================*/
|
||||
|
||||
#ifndef GDCMDEFAULTDICTS_CXX
|
||||
#define GDCMDEFAULTDICTS_CXX
|
||||
#ifndef GDCMPRIVATEDEFAULTDICTS_CXX
|
||||
#define GDCMPRIVATEDEFAULTDICTS_CXX
|
||||
|
||||
#include "gdcmDicts.h"
|
||||
#include "gdcmVR.h"
|
||||
|
@ -153,7 +153,7 @@ generating group length for arbitrary even group number seems to get my xsltproc
|
|||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<xsl:text>
|
||||
{0xffff,0xffff,0,VR::INVALID,VM::VM0,0,true } // Gard
|
||||
{0xffff,0xffff,0,VR::INVALID,VM::VM0,0,true } // Guard
|
||||
};
|
||||
|
||||
void Dict::LoadDefault()
|
||||
|
@ -191,7 +191,7 @@ void PrivateDict::LoadDefault()
|
|||
}
|
||||
|
||||
} // end namespace gdcm
|
||||
#endif // GDCMDEFAULTDICTS_CXX
|
||||
#endif // GDCMPRIVATEDEFAULTDICTS_CXX
|
||||
</xsl:text>
|
||||
</xsl:template>
|
||||
<xsl:template name="do-group-length">
|
||||
|
|
|
@ -124,7 +124,7 @@ class PdfTextParser:
|
|||
#print "Other Full line:", s2
|
||||
self.AddOutputLine(s2)
|
||||
else:
|
||||
# we have a suspicioulsy long line, so what that could
|
||||
# we have a suspiciously long line, so what that could
|
||||
# happen, let's check:
|
||||
if self.IsAFullLine(previousbuffer):
|
||||
self.AddOutputLine(previousbuffer)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
|
||||
<!-- XSL to convert XML GDCM2 data dictionay into
|
||||
<!-- XSL to convert XML GDCM2 data dictionary into
|
||||
dcm4che data dictionary
|
||||
Checked against:
|
||||
http://dcm4che.svn.sourceforge.net/viewvc/dcm4che/dcm4che2/trunk/dcm4che-core/src/xml/dictionary.xml
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:output method="text" indent="yes"/>
|
||||
<!-- XSL to convert XML GDCM2 data dictionay into
|
||||
<!-- XSL to convert XML GDCM2 data dictionary into
|
||||
C++ template code
|
||||
-->
|
||||
<!--
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:output method="text" indent="yes"/>
|
||||
<!-- XSL to convert XML GDCM2 data dictionay into
|
||||
<!-- XSL to convert XML GDCM2 data dictionary into
|
||||
C++ template code
|
||||
-->
|
||||
<!--
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:output method="text" indent="yes"/>
|
||||
<!-- XSL to convert XML GDCM2 data dictionay into
|
||||
<!-- XSL to convert XML GDCM2 data dictionary into
|
||||
David Clunie's dicom3tools data dictionary
|
||||
Checked against:
|
||||
dicom3tools_1.00.snapshot.20120808/libsrc/standard/elmdict/dicom3.tpl
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-1><B>Type</B></FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-1><B>VR</B></FONT></TD>
|
||||
<TD ALIGN="center" STYLE="vnd.ms-excel.numberformat:@"><FONT FACE="Arial" SIZE=-1><B>VM</B></FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-1><B>Descriptiom</B></FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-1><B>Description</B></FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-1><B>Creator</B></FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-1><B>Unit</B></FONT></TD>
|
||||
</TR>
|
||||
|
@ -164,7 +164,7 @@
|
|||
<TD BGCOLOR=#FFFFFF ALIGN="center"><FONT FACE="Arial" SIZE=-2>3</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="center"><FONT FACE="Arial" SIZE=-2>IS</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="center"><FONT FACE="Arial" SIZE=-2>1-n</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="left"><FONT FACE="Arial" SIZE=-2>References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are siginificantly related to this image</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="left"><FONT FACE="Arial" SIZE=-2>References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are significantly related to this image</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -204,7 +204,7 @@
|
|||
<TD BGCOLOR=#FFFFFF ALIGN="center"><FONT FACE="Arial" SIZE=-2>3</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="center"><FONT FACE="Arial" SIZE=-2>IS</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="center"><FONT FACE="Arial" SIZE=-2>1-n</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="left"><FONT FACE="Arial" SIZE=-2>References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are siginificantly related to this image</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="left"><FONT FACE="Arial" SIZE=-2>References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are significantly related to this image</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD BGCOLOR=#FFFFFF ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -357,7 +357,7 @@ Enumerated Values:
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>3</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>SH</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>User defined name for the Scanning Sequence and Sequence Varaint combination</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>User defined name for the Scanning Sequence and Sequence Variant combination</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -380,7 +380,7 @@ N = image is not Angio</FONT></TD>
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>2C</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>DS</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequnece Variant is not segmented k-space</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequence Variant is not segmented k-space</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>msec</FONT></TD>
|
||||
</TR>
|
||||
|
@ -633,7 +633,7 @@ N = no</FONT></TD>
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>3</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>IS</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Percent of R-R interval, based on Heart Rate (0018,1088), prescriped as a window for a valid/usable trigger</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Percent of R-R interval, based on Heart Rate (0018,1088), prescribed as a window for a valid/usable trigger</FONT></TD>
|
||||
<TD ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
<TD ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -1120,7 +1120,7 @@ contrast agent</FONT></TD>
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>3</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>LO</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Manufacturer's seriel number of the equipment that produced the digital images</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Manufacturer's serial number of the equipment that produced the digital images</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition/application</FONT></TD>
|
||||
<TD ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -1314,7 +1314,7 @@ contrast agent</FONT></TD>
|
|||
Example:
|
||||
channel 0: 00000001
|
||||
channel 3: 00000111
|
||||
·</FONT></TD>
|
||||
<EFBFBD></FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -1436,7 +1436,7 @@ E.g.: X_2_1_1_1_1_2_1_1</FONT></TD>
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>UL</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens seqence ....</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens sequence ....</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -1536,7 +1536,7 @@ E.g.: X_2_1_1_1_1_2_1_1</FONT></TD>
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>DS</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Time delay after start of measurment</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Time delay after start of measurement</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD ALIGN="right"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -1746,7 +1746,7 @@ E.g.: X_2_1_1_1_1_2_1_1</FONT></TD>
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>SH</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>User defined name for the Scanning Sequence and Sequence Varaint combination</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>User defined name for the Scanning Sequence and Sequence Variant combination</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -1756,7 +1756,7 @@ E.g.: X_2_1_1_1_1_2_1_1</FONT></TD>
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>DS</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequnece Variant is not segmented k-space</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequence Variant is not segmented k-space</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
@ -2164,7 +2164,7 @@ E.g.: X_2_1_1_1_1_2_1_1</FONT></TD>
|
|||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>UL</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2>1</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens seqence .·</FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens sequence .<2E></FONT></TD>
|
||||
<TD ALIGN="left"><FONT FACE="Arial" SIZE=-2>acquisition</FONT></TD>
|
||||
<TD ALIGN="center"><FONT FACE="Arial" SIZE=-2> </FONT></TD>
|
||||
</TR>
|
||||
|
|
|
@ -26,14 +26,14 @@
|
|||
|
||||
|
||||
namespace gdcm {
|
||||
typedef struct
|
||||
using CSA_DICT_ENTRY = struct
|
||||
{
|
||||
const char *name;
|
||||
const char *type;
|
||||
VR::VRType vr;
|
||||
VM::VMType vm;
|
||||
const char *description;
|
||||
} CSA_DICT_ENTRY;
|
||||
};
|
||||
|
||||
static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
||||
{"AcquisitionDate","3",VR::DA,VM::VM1,"A number identifying the single continuous gathering of data over a period of time which resulted in this image"},
|
||||
|
@ -48,10 +48,10 @@ static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
|||
{"ImageInAcquisition","3",VR::IS,VM::VM1,"Number of images that resulted from this acquisition of data"},
|
||||
{">Referenced SOP Class UID","1C",VR::UI,VM::VM1,"Uniquely identifies the referenced SOP Class"},
|
||||
{">Referenced SOP Instance UID","1C",VR::UI,VM::VM1,"Uniquely identifies the referenced SOP Instance"},
|
||||
{"> Referenced Frame Number","3",VR::IS,VM::VM1_n,"References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are siginificantly related to this image"},
|
||||
{"> Referenced Frame Number","3",VR::IS,VM::VM1_n,"References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are significantly related to this image"},
|
||||
//{">Referenced SOP Class UID","1C",VR::UI,VM::VM1,"Uniquely identifies the referenced SOP Class"},
|
||||
//{">Referenced SOP Instance UID","1C",VR::UI,VM::VM1,"Uniquely identifies the referenced SOP Instance"},
|
||||
//{"> Referenced Frame Number","3",VR::IS,VM::VM1_n,"References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are siginificantly related to this image"},
|
||||
//{"> Referenced Frame Number","3",VR::IS,VM::VM1_n,"References one or more image frames of a Multi-frame Image SOP Instance, identifying which frames are significantly related to this image"},
|
||||
{"ImageType","3",VR::CS,VM::VM1_n,"Image identification characteristics"},
|
||||
{"Lossy Image Compression","3",VR::CS,VM::VM1,"Specifies whether an image has undergone lossy compression. Enumerated values: 00 = image has not been subjected to lossy compression. 01 = image has been subjected to lossy compression"},
|
||||
{"Quality Control Image","1C",VR::CS,VM::VM1,"Indicates whether or not this image is a quality control or phantom image. Enumerated values: YES, NO"},
|
||||
|
@ -64,9 +64,9 @@ static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
|||
{"SequenceVariant","1",VR::CS,VM::VM1_n,"Variant of the Scanning Sequence"},
|
||||
{"ScanOptions","2",VR::CS,VM::VM1_n,"Parameters of scanning sequence"},
|
||||
{"MRAcquisitionType","2",VR::CS,VM::VM1,"Identification of date encoding scheme. Enumerated Values: 2D = frequency x phase 3D = frequency x phase x phase"},
|
||||
{"SequenceName","3",VR::SH,VM::VM1,"User defined name for the Scanning Sequence and Sequence Varaint combination"},
|
||||
{"SequenceName","3",VR::SH,VM::VM1,"User defined name for the Scanning Sequence and Sequence Variant combination"},
|
||||
{"AngioFlag","3",VR::CS,VM::VM1,"Angio image indicator. Primary image for angio processing. Enumerated values: Y = image is Angio N = image is not Angio"},
|
||||
{"RepetitionTime","2C",VR::DS,VM::VM1,"The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequnece Variant is not segmented k-space"},
|
||||
{"RepetitionTime","2C",VR::DS,VM::VM1,"The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequence Variant is not segmented k-space"},
|
||||
{"EchoTime","2",VR::DS,VM::VM1,"Time in msec between the middle of the excitation pulse and the peak of the echo produced. In the case of segmented k-space, the TE(eff) is the time between the middle of the excitation pulse to the peak of the echo that is used to cover the center of k-space)"},
|
||||
{"InversionTime","2C",VR::DS,VM::VM1,"Time in msec after the middle of inverting RF pulse to middle of excitation pulse to detect the amount of longitudinal magnetization. Required if Scanning Sequence has value of IR"},
|
||||
{"NumberOfAverages","3",VR::DS,VM::VM1,"Number of times a given pulse sequence is repeated before any parameter has changed"},
|
||||
|
@ -91,7 +91,7 @@ static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
|||
{"Skip Beats","3",VR::IS,VM::VM1,"Number of beats skipped after a detected arrhythmia"},
|
||||
{"HeartRate","3",VR::IS,VM::VM1,"Beats per minute"},
|
||||
{"CardiacNumberOfImages","3",VR::IS,VM::VM1,"Number of imagesb per cardiac cycle"},
|
||||
{"TriggerWindow","3",VR::IS,VM::VM1,"Percent of R-R interval, based on Heart Rate (0018,1088), prescriped as a window for a valid/usable trigger"},
|
||||
{"TriggerWindow","3",VR::IS,VM::VM1,"Percent of R-R interval, based on Heart Rate (0018,1088), prescribed as a window for a valid/usable trigger"},
|
||||
{"ReconstructionDiameter","3",VR::DS,VM::VM1,"Diameter in mm of the region from within which data were used in creating the reconstruction of the image. Data may exist outside this region and portions of the patient may exist outside the region"},
|
||||
{"Receive Coil","3",VR::SH,VM::VM1,"Received coil used"},
|
||||
{"TransmittingCoil","3",VR::SH,VM::VM1,"Transmitted coil used"},
|
||||
|
@ -134,7 +134,7 @@ static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
|||
{"InstitutionName","3",VR::LO,VM::VM1,"Institution where the equipment is located that produced the digital images"},
|
||||
{"InstitutionAddress","3",VR::ST,VM::VM1,"Mailing address of the institution where the equipment is located that produced the digital images"},
|
||||
{"ManufacturersModelName","3",VR::LO,VM::VM1,"Manufacturer's model number of the equipment that produced the digital images"},
|
||||
{"DeviceSerialNumber","3",VR::LO,VM::VM1,"Manufacturer's seriel number of the equipment that produced the digital images"},
|
||||
{"DeviceSerialNumber","3",VR::LO,VM::VM1,"Manufacturer's serial number of the equipment that produced the digital images"},
|
||||
{"SoftwareVersions","3",VR::LO,VM::VM1_n,"Manufacturer's designation of software of the equipment that produced the digital images"},
|
||||
{"OverlayRows","1",VR::US,VM::VM1,"Number of Rows in Overlay"},
|
||||
{"OverlayColumns","1",VR::US,VM::VM1,"Number of Columns in Overlay"},
|
||||
|
@ -162,7 +162,7 @@ static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
|||
{"PixelFileName","1",VR::UN,VM::VM1,"Used raw data file name for the performed acquisition"},
|
||||
{"SliceMeasurementDuration","1",VR::DS,VM::VM1,"Time duration between two slices of the performed acquisition"},
|
||||
{"AcquisitionMatrixText","1",VR::SH,VM::VM1,"Used acquisition matrix description"},
|
||||
{"SequenceMask","1",VR::UL,VM::VM1,"Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens seqence ...."},
|
||||
{"SequenceMask","1",VR::UL,VM::VM1,"Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens sequence ...."},
|
||||
{"MeasuredFourierLines","1",VR::IS,VM::VM1,"Number of performed fourier lines"},
|
||||
{"FlowEncodingDirection","1",VR::IS,VM::VM1,"Flow encoding direction"},
|
||||
{"FlowVenc","1",VR::FD,VM::VM1,"Flow Quant attribute"},
|
||||
|
@ -172,7 +172,7 @@ static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
|||
{"ImageGroup","1",VR::US,VM::VM1,"Group of images"},
|
||||
{"SliceNormalVector","1",VR::FD,VM::VM3,"X,y and z normal vector of the slices"},
|
||||
{"DiffusionDirection","1",VR::CS,VM::VM1,"Diffusion direction"},
|
||||
{"TimeAfterStart","1",VR::DS,VM::VM1,"Time delay after start of measurment"},
|
||||
{"TimeAfterStart","1",VR::DS,VM::VM1,"Time delay after start of measurement"},
|
||||
//{"FlipAngle","1",VR::DS,VM::VM1,"Flip angle for SC images"},
|
||||
//{"SequenceName","1",VR::SH,VM::VM1,"Sequence name for SC images"},
|
||||
//{"RepetitionTime","1",VR::DS,VM::VM1,"Repetition time for SC images"},
|
||||
|
@ -192,8 +192,8 @@ static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
|||
{"ReferencedImageSequence","1",VR::UI,VM::VM1_n,"A sequence which provides reference to a set of Image SOP Class/Instance identifying other images significantly related to this image (localizer images)"},
|
||||
//{"PatientOrientation","1",VR::CS,VM::VM1,"Patient direction of the rows and columns of the image. Not required for MR images"},
|
||||
{"ScanningSequence","1",VR::CS,VM::VM1_n,"Description of the type of data taken. Enumerated values: SE = Spin Echo; IR = Inversion Recovery; GR = Gradient Recalled; EP = Echo Planar; RM = Research Mode"},
|
||||
//{"SequenceName","1",VR::SH,VM::VM1,"User defined name for the Scanning Sequence and Sequence Varaint combination"},
|
||||
//{"RepetitionTime","1",VR::DS,VM::VM1,"The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequnece Variant is not segmented k-space"},
|
||||
//{"SequenceName","1",VR::SH,VM::VM1,"User defined name for the Scanning Sequence and Sequence Variant combination"},
|
||||
//{"RepetitionTime","1",VR::DS,VM::VM1,"The period of time in msec between the beginning of a pulse sequence and the beginning of a succeeding (essentially identical) pulse sequence. Required except when Scanning Sequence is EP and Sequence Variant is not segmented k-space"},
|
||||
//{"EchoTime","1",VR::DS,VM::VM1,"Time in msec between the middle of the excitation pulse and the peak of the echo produced. In the case of segmented k-space, the TE(eff) is the time between the middle of the excitation pulse to the peak of the echo that is used to cover the center of k-space)"},
|
||||
//{"InversionTime","1",VR::DS,VM::VM1,"Time in msec after the middle of inverting RF pulse to middle of excitation pulse to detect the amount of longitudinal magnetization. Required if Scanning Sequence has value of IR"},
|
||||
//{"NumberOfAverages","1",VR::DS,VM::VM1,"Number of averages"},
|
||||
|
@ -233,7 +233,7 @@ static const CSA_DICT_ENTRY CSAHeaderDataDict [] = {
|
|||
{"SourceImageSequence","1",VR::UI,VM::VM1_n,"A sequence which identifies the set of Image SOP Class/Instance pairs of the images which were use to derive this image"},
|
||||
//{"PixelBandwidth","1",VR::DS,VM::VM1,"Reciprocal of the total sampling period, in hertz per pixel"},
|
||||
//{"SliceMeasurementDuration","1",VR::DS,VM::VM1,"Time duration between two slices of the performed acquisition"},
|
||||
//{"SequenceMask","1",VR::UL,VM::VM1,"Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens seqence .·"},
|
||||
//{"SequenceMask","1",VR::UL,VM::VM1,"Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens sequence .·"},
|
||||
//{"AcquisitionMatrixText","1",VR::SH,VM::VM1,"Used acquisition matrix description"},
|
||||
//{"MeasuredFourierLines","1",VR::IS,VM::VM1,"Number of performed fourier lines"},
|
||||
{"ulVersion","3",VR::UL,VM::VM1,"Protocol version"},
|
||||
|
@ -336,7 +336,7 @@ docstrings, so ping me if you need clarification.
|
|||
*/
|
||||
{"sSliceArray.ucMode","1",VR::US,VM::VM1,"slice ordering 0x1,0x2,0x4 resp. asc,desc,inter"},
|
||||
|
||||
{nullptr,nullptr,VR::INVALID,VM::VM0,nullptr } // Gard
|
||||
{nullptr,nullptr,VR::INVALID,VM::VM0,nullptr } // Guard
|
||||
};
|
||||
|
||||
void CSAHeaderDict::LoadDefault()
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
namespace {
|
||||
using namespace gdcm;
|
||||
typedef struct
|
||||
using DICT_ENTRY = struct
|
||||
{
|
||||
uint16_t group;
|
||||
uint16_t element;
|
||||
|
@ -35,7 +35,7 @@ typedef struct
|
|||
const char *name;
|
||||
const char *keyword;
|
||||
bool ret;
|
||||
} DICT_ENTRY;
|
||||
};
|
||||
|
||||
static const DICT_ENTRY DICOMV3DataDict [] = {
|
||||
{0x0000,0x0000,VR::UL,VM::VM1,"Command Group Length","CommandGroupLength",false },
|
||||
|
@ -13868,7 +13868,7 @@ static const DICT_ENTRY DICOMV3DataDict [] = {
|
|||
|
||||
// FIXME: need a dummy element
|
||||
{0xffff,0xffff,VR::INVALID,VM::VM0,"","",true }, // dummy
|
||||
{0xffff,0xffff,VR::INVALID,VM::VM0,nullptr,nullptr,true } // Gard
|
||||
{0xffff,0xffff,VR::INVALID,VM::VM0,nullptr,nullptr,true } // Guard
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
|
||||
namespace gdcm {
|
||||
|
||||
typedef struct
|
||||
using GROUP_ENTRY = struct
|
||||
{
|
||||
uint16_t group;
|
||||
const char *abbreviation;
|
||||
const char *name;
|
||||
} GROUP_ENTRY;
|
||||
};
|
||||
|
||||
static GROUP_ENTRY groupname[] = {
|
||||
{0x0000,"CMD","Command"},
|
||||
|
@ -41,7 +41,7 @@ static GROUP_ENTRY groupname[] = {
|
|||
{0x0019,"SPIA","SPI Acquisition"},
|
||||
{0x0020,"IMG","Image"},
|
||||
{0x0021,"SPIIM","SPI Image"},
|
||||
{0x0022,"OPHY","Ophtalmology"},
|
||||
{0x0022,"OPHY","Ophthalmology"},
|
||||
{0x0028,"IMGP","Image Presentation"},
|
||||
{0x0032,"SDY","Study"},
|
||||
{0x0038,"VIS","Visit"},
|
||||
|
|
|
@ -150,8 +150,8 @@ public:
|
|||
}
|
||||
|
||||
/// Inefficient way of looking up tag by name. Technically DICOM
|
||||
/// does not garantee uniqueness (and Curve / Overlay are there to prove it). But
|
||||
/// most of the time name is in fact uniq and can be uniquely link to a tag
|
||||
/// does not guarantee uniqueness (and Curve / Overlay are there to prove it).
|
||||
/// But most of the time name is in fact uniq and can be uniquely link to a tag
|
||||
const DictEntry &GetDictEntryByName(const char *name, Tag & tag) const
|
||||
{
|
||||
MapDictEntry::const_iterator it =
|
||||
|
|
|
@ -226,7 +226,7 @@ bool DictConverter::Readuint16(const char *raw, uint16_t &ov)
|
|||
int r = sscanf(raw, "%04x", &v);
|
||||
assert( r == 1 && "Wrong Value read for uint16");
|
||||
char sv[4+1];
|
||||
r = sprintf(sv, "%04x", v);
|
||||
r = snprintf(sv, sizeof(sv), "%04x", v);
|
||||
assert( r == 4 && "Wrong Value printed for uint16");
|
||||
assert( strncmp(raw, sv, 4) == 0 );
|
||||
ov = v;
|
||||
|
|
|
@ -28,7 +28,7 @@ class DictConverterInternal;
|
|||
/**
|
||||
* \brief Class to convert a .dic file into something else:
|
||||
* \details
|
||||
* - CXX code : embeded dict into shared lib (DICT_DEFAULT)
|
||||
* - CXX code : embed dict into shared lib (DICT_DEFAULT)
|
||||
* - Debug mode (DICT_DEBUG)
|
||||
* - XML dict (DICT_XML)
|
||||
* \note
|
||||
|
@ -55,7 +55,7 @@ public:
|
|||
void Convert();
|
||||
|
||||
// Leaving them public for now. Not really user oriented but may be
|
||||
// usefull
|
||||
// useful
|
||||
static bool ReadVR(const char *raw, VR::VRType &type);
|
||||
static bool ReadVM(const char *raw, VM::VMType &type);
|
||||
static bool Readuint16(const char *raw, uint16_t &ov);
|
||||
|
|
|
@ -38,7 +38,6 @@ Dicts::~Dicts()
|
|||
|
||||
const DictEntry &Dicts::GetDictEntry(const Tag& tag, const char *owner) const
|
||||
{
|
||||
static DictEntry Dummy;
|
||||
if( tag.IsGroupLength() )
|
||||
{
|
||||
const DictEntry & de = PublicDict.GetDictEntry(tag);
|
||||
|
@ -49,18 +48,14 @@ const DictEntry &Dicts::GetDictEntry(const Tag& tag, const char *owner) const
|
|||
}
|
||||
else
|
||||
{
|
||||
Dummy.SetName( "Generic Group Length" );
|
||||
Dummy.SetKeyword( "GenericGroupLength" );
|
||||
bool retired = true; // Since DICOM 2008, all (but 0002,0004) group length are retired
|
||||
Dummy.SetVR( VR::UL );
|
||||
Dummy.SetVM( VM::VM1 );
|
||||
Dummy.SetRetired( retired );
|
||||
static const DictEntry Dummy("Generic Group Length", "GenericGroupLength", VR::UL, VM::VM1, retired);
|
||||
return Dummy;
|
||||
}
|
||||
}
|
||||
else if( tag.IsPublic() )
|
||||
{
|
||||
assert( owner == NULL );
|
||||
assert( owner == nullptr );
|
||||
return PublicDict.GetDictEntry(tag);
|
||||
}
|
||||
else
|
||||
|
@ -78,13 +73,7 @@ const DictEntry &Dicts::GetDictEntry(const Tag& tag, const char *owner) const
|
|||
// Check special private element: 0x0000 and [0x1,0xFF] are special cases:
|
||||
if( tag.IsIllegal() )
|
||||
{
|
||||
std::string pc ( "Illegal Element" );
|
||||
Dummy.SetName( pc.c_str() );
|
||||
std::string kw ( "IllegalElement" );
|
||||
Dummy.SetKeyword( kw.c_str() );
|
||||
Dummy.SetVR( VR::INVALID );
|
||||
Dummy.SetVM( VM::VM0 );
|
||||
Dummy.SetRetired( false ); // ??
|
||||
static const DictEntry Dummy("Illegal Element", "IllegalElement", VR::INVALID, VM::VM0, false);
|
||||
return Dummy;
|
||||
}
|
||||
else if( tag.IsPrivateCreator() )
|
||||
|
@ -92,36 +81,14 @@ const DictEntry &Dicts::GetDictEntry(const Tag& tag, const char *owner) const
|
|||
assert( !tag.IsIllegal() );
|
||||
assert( tag.GetElement() ); // Not a group length !
|
||||
assert( tag.IsPrivate() );
|
||||
assert( owner == 0x0 );
|
||||
{
|
||||
static const char pc[] = "Private Creator";
|
||||
static const char kw[] = "PrivateCreator";
|
||||
Dummy.SetName( pc );
|
||||
Dummy.SetKeyword( kw );
|
||||
}
|
||||
Dummy.SetVR( VR::LO );
|
||||
Dummy.SetVM( VM::VM1 );
|
||||
Dummy.SetRetired( false );
|
||||
assert( owner == nullptr );
|
||||
static const DictEntry Dummy("Private Creator", "PrivateCreator", VR::LO, VM::VM1, false);
|
||||
return Dummy;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( owner && *owner )
|
||||
{
|
||||
static const char pc[] = "Private Element Without Private Creator";
|
||||
static const char kw[] = "PrivateElementWithoutPrivateCreator";
|
||||
Dummy.SetName( pc );
|
||||
Dummy.SetKeyword( kw );
|
||||
}
|
||||
else
|
||||
{
|
||||
static const char pc[] = "Private Element With Empty Private Creator";
|
||||
static const char kw[] = "PrivateElementWithEmptyPrivateCreator";
|
||||
Dummy.SetName( pc );
|
||||
Dummy.SetKeyword( kw );
|
||||
}
|
||||
Dummy.SetVR( VR::INVALID );
|
||||
Dummy.SetVM( VM::VM0 );
|
||||
static const DictEntry Dummy("Private Element With Empty Private Creator",
|
||||
"PrivateElementWithEmptyPrivateCreator", VR::INVALID, VM::VM0);
|
||||
return Dummy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
/// owner is null for public dict
|
||||
/// \warning owner need to be set to appropriate owner for call to work. see
|
||||
// DataSet::GetPrivateCreator
|
||||
/// NOT THREAD SAFE
|
||||
/// THREAD SAFE
|
||||
const DictEntry &GetDictEntry(const Tag& tag, const char *owner = nullptr) const;
|
||||
|
||||
const DictEntry &GetDictEntry(const PrivateTag& tag) const;
|
||||
|
|
|
@ -37,46 +37,46 @@ public:
|
|||
// TODO need H table for TransferSyntax / MediaStorage / Part 3 ...
|
||||
Defs GlobalDefs;
|
||||
|
||||
// Ressource paths:
|
||||
// Resource paths:
|
||||
// By default only construct two paths:
|
||||
// - The official install dir (need to keep in sinc with cmakelist variable
|
||||
// - The official install dir (need to keep in sync with cmakelist variable
|
||||
// - a dynamic one, so that gdcm is somewhat rellocatable
|
||||
// - on some system where it make sense the path where the Resource should be located
|
||||
void LoadDefaultPaths()
|
||||
{
|
||||
assert( RessourcePaths.empty() );
|
||||
assert( ResourcePaths.empty() );
|
||||
const char filename2[] = GDCM_CMAKE_INSTALL_PREFIX "/" GDCM_INSTALL_DATA_DIR "/XML/";
|
||||
RessourcePaths.emplace_back(filename2 );
|
||||
ResourcePaths.emplace_back(filename2 );
|
||||
const char filename3[] = GDCM_CMAKE_INSTALL_PREFIX " " GDCM_API_VERSION "/" GDCM_INSTALL_DATA_DIR "/XML/";
|
||||
RessourcePaths.emplace_back(filename3 );
|
||||
ResourcePaths.emplace_back(filename3 );
|
||||
const char *curprocfn = System::GetCurrentProcessFileName();
|
||||
if( curprocfn )
|
||||
{
|
||||
Filename fn( curprocfn );
|
||||
std::string str = fn.GetPath();
|
||||
str += "/../" GDCM_INSTALL_DATA_DIR "/XML/";
|
||||
RessourcePaths.push_back( str );
|
||||
ResourcePaths.push_back( str );
|
||||
}
|
||||
const char *respath = System::GetCurrentResourcesDirectory();
|
||||
if( respath )
|
||||
{
|
||||
RessourcePaths.emplace_back(respath );
|
||||
ResourcePaths.emplace_back(respath );
|
||||
}
|
||||
#ifdef GDCM_BUILD_TESTING
|
||||
// Needed for backward compat and dashboard
|
||||
const char src_path[] = GDCM_SOURCE_DIR "/Source/InformationObjectDefinition/";
|
||||
RessourcePaths.emplace_back(src_path );
|
||||
std::rotate(RessourcePaths.rbegin(), RessourcePaths.rbegin() + 1, RessourcePaths.rend());
|
||||
ResourcePaths.emplace_back(src_path );
|
||||
std::rotate(ResourcePaths.rbegin(), ResourcePaths.rbegin() + 1, ResourcePaths.rend());
|
||||
#endif
|
||||
}
|
||||
std::vector<std::string> RessourcePaths;
|
||||
std::vector<std::string> ResourcePaths;
|
||||
};
|
||||
|
||||
Global::Global()
|
||||
{
|
||||
if(++GlobalCount == 1)
|
||||
{
|
||||
assert( Internals == NULL ); // paranoid
|
||||
assert( Internals == nullptr ); // paranoid
|
||||
Internals = new GlobalInternal;
|
||||
assert( Internals->GlobalDicts.IsEmpty() );
|
||||
// Fill in with default values now !
|
||||
|
@ -102,7 +102,7 @@ Global::~Global()
|
|||
|
||||
bool Global::LoadResourcesFiles()
|
||||
{
|
||||
assert( Internals != NULL ); // paranoid
|
||||
assert( Internals != nullptr ); // paranoid
|
||||
const char *filename = Locate( "Part3.xml" );
|
||||
if( filename )
|
||||
{
|
||||
|
@ -120,7 +120,7 @@ bool Global::Append(const char *path)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
Internals->RessourcePaths.emplace_back(path );
|
||||
Internals->ResourcePaths.emplace_back(path );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ bool Global::Prepend(const char *path)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
Internals->RessourcePaths.insert( Internals->RessourcePaths.begin(), path );
|
||||
Internals->ResourcePaths.insert( Internals->ResourcePaths.begin(), path );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -138,10 +138,6 @@ bool Global::Prepend(const char *path)
|
|||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
const char *Global::Locate(const char *resfile) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -150,8 +146,8 @@ const char *Global::Locate(const char *resfile) const
|
|||
static char path[PATH_MAX];
|
||||
#endif
|
||||
|
||||
std::vector<std::string>::const_iterator it = Internals->RessourcePaths.begin();
|
||||
for( ; it != Internals->RessourcePaths.end(); ++it)
|
||||
std::vector<std::string>::const_iterator it = Internals->ResourcePaths.begin();
|
||||
for( ; it != Internals->ResourcePaths.end(); ++it)
|
||||
{
|
||||
const std::string &p = *it;
|
||||
gdcmDebugMacro( "Trying to locate in: " << p );
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -127,6 +127,7 @@ namespace gdcm
|
|||
// private:
|
||||
{ "1.3.12.2.1107.5.9.1" , "Siemens Non-image IOD Modules"}, // CSA Non-Image Storage
|
||||
{ "1.2.392.200036.9125.1.1.2" , "Fuji Private CR Image IOD Modules"}, //
|
||||
{ "1.2.392.200036.9125.1.1.4" , "Fuji Private Mammo CR Image IOD Modules"}, //
|
||||
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
@ -187,7 +188,7 @@ SOPClassUIDToIOD::SOPClassUIDToIODType& SOPClassUIDToIOD::GetSOPClassUIDToIOD(un
|
|||
if( i < SOPClassUIDToIOD::GetNumberOfSOPClassToIOD() )
|
||||
return SOPClassUIDToIODStrings[i];
|
||||
// else return the {0x0, 0x0} sentinel:
|
||||
assert( *SOPClassUIDToIODStrings[ SOPClassUIDToIOD::GetNumberOfSOPClassToIOD() ] == 0 );
|
||||
assert( *SOPClassUIDToIODStrings[ SOPClassUIDToIOD::GetNumberOfSOPClassToIOD() ] == nullptr );
|
||||
return SOPClassUIDToIODStrings[ SOPClassUIDToIOD::GetNumberOfSOPClassToIOD() ];
|
||||
|
||||
}
|
||||
|
|
|
@ -454,7 +454,7 @@ namespace gdcm
|
|||
{"1.2.840.113619.4.30","GE Advance (PET) Raw Data Storage" },
|
||||
{"2.16.840.1.113709.1.5.1","GEPACS_PRIVATE_IMS_INFO Storage" },
|
||||
{"2.16.840.1.113709.1.2.2","COMPRESS_EXPRESS TRANSFER SYNTAX" },
|
||||
{"1.2.840.113543.6.6.1.3.10002","Unregistred (?) Philips3D" },
|
||||
{"1.2.840.113543.6.6.1.3.10002","Unregistered (?) Philips3D" },
|
||||
{"1.2.392.200036.9116.7.8.1.1.1","Toshiba Private Data Storage" },
|
||||
// business.fujifilm.co.uk/medical/downloads/DICOM_xg1.pdf
|
||||
{"1.2.392.200036.9125.1.1.2","Fuji Private CR Image Storage"},
|
||||
|
@ -490,6 +490,7 @@ namespace gdcm
|
|||
{"1.2.840.113619.5.2","Implicit VR Big Endian DLX (G.E Private)"},
|
||||
// DICOM_Conformance_Statement_GEMINI_R3.5_R3.6.pdf
|
||||
{"1.3.46.670589.33.1.4.1","CT-private-ELE"},
|
||||
{"1.2.392.200036.9125.1.1.4","Fuji Private Mammo CR Image Storage"},
|
||||
//
|
||||
//
|
||||
//
|
||||
|
@ -510,8 +511,8 @@ const char * const * UIDs::GetTransferSyntaxString(unsigned int ts)
|
|||
{
|
||||
if( ts > 0 && ts <= UIDs::GetNumberOfTransferSyntaxStrings() ) return TransferSyntaxStrings[ts];
|
||||
// else return the {0x0, 0x0} sentinel (begin or end)
|
||||
assert( *TransferSyntaxStrings[ UIDs::GetNumberOfTransferSyntaxStrings() + 1 ] == 0 );
|
||||
assert( *TransferSyntaxStrings[ 0 ] == 0 );
|
||||
assert( *TransferSyntaxStrings[ UIDs::GetNumberOfTransferSyntaxStrings() + 1 ] == nullptr );
|
||||
assert( *TransferSyntaxStrings[ 0 ] == nullptr );
|
||||
return TransferSyntaxStrings[ UIDs::GetNumberOfTransferSyntaxStrings() + 1 ];
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ version="1.0">
|
|||
<xsl:output method="xml" indent="yes"
|
||||
encoding="iso-8859-1"/-->
|
||||
|
||||
<!-- XSL to convert XML GDCM2 data dictionay into HTML form -->
|
||||
<!-- XSL to convert XML GDCM2 data dictionary into HTML form -->
|
||||
<!--
|
||||
Program: GDCM (Grassroots DICOM). A DICOM library
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -66,7 +66,7 @@ public:
|
|||
/**
|
||||
* \brief Attribute class
|
||||
* This class use template metaprograming tricks to let the user know when the template
|
||||
* instanciation does not match the public dictionary.
|
||||
* instantiation does not match the public dictionary.
|
||||
*
|
||||
* Typical example that compile is:
|
||||
* Attribute<0x0008,0x9007> a = {"ORIGINAL","PRIMARY","T1","NONE"};
|
||||
|
@ -118,7 +118,7 @@ public:
|
|||
os << GetTag() << " ";
|
||||
os << TagToType<Group,Element>::GetVRString() << " ";
|
||||
os << TagToType<Group,Element>::GetVMString() << " ";
|
||||
os << Internal[0]; // VM is at least garantee to be one
|
||||
os << Internal[0]; // VM is at least guarantee to be one
|
||||
for(unsigned int i=1; i<GetNumberOfValues(); ++i)
|
||||
os << "," << Internal[i];
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ public:
|
|||
os << GetTag() << " ";
|
||||
os << TagToType<Group,Element>::GetVRString() << " ";
|
||||
os << TagToType<Group,Element>::GetVMString() << " ";
|
||||
os << Internal; // VM is at least garantee to be one
|
||||
os << Internal; // VM is at least guarantee to be one
|
||||
}
|
||||
// copy:
|
||||
//ArrayType GetValue(unsigned int idx = 0) {
|
||||
|
@ -593,7 +593,7 @@ public:
|
|||
os << GetTag() << " ";
|
||||
os << GetVR() << " ";
|
||||
os << GetVM() << " ";
|
||||
os << Internal[0]; // VM is at least garantee to be one
|
||||
os << Internal[0]; // VM is at least guarantee to be one
|
||||
for(unsigned int i=1; i<GetNumberOfValues(); ++i)
|
||||
os << "," << Internal[i];
|
||||
}
|
||||
|
@ -628,7 +628,7 @@ public:
|
|||
}
|
||||
Own = own;
|
||||
Length = numel;
|
||||
assert( Internal == 0 );
|
||||
assert( Internal == nullptr );
|
||||
if( own ) // make a copy:
|
||||
{
|
||||
Internal = new ArrayType[numel];
|
||||
|
@ -763,7 +763,7 @@ public:
|
|||
|
||||
|
||||
// For particular case for ASCII string
|
||||
// WARNING: This template explicitly instanciates a particular
|
||||
// WARNING: This template explicitly instantiates a particular
|
||||
// EncodingImplementation THEREFORE it is required to be declared after the
|
||||
// EncodingImplementation is needs (doh!)
|
||||
#if 0
|
||||
|
@ -795,7 +795,7 @@ public:
|
|||
}
|
||||
// Implementation of Print is common to all Mode (ASCII/Binary)
|
||||
void Print(std::ostream &_os) const {
|
||||
_os << Internal[0]; // VM is at least garantee to be one
|
||||
_os << Internal[0]; // VM is at least guarantee to be one
|
||||
for(int i=1; i<VMToLength<TVM>::Length; ++i)
|
||||
_os << "," << Internal[i];
|
||||
}
|
||||
|
@ -869,7 +869,7 @@ public:
|
|||
void Print(std::ostream &_os) const {
|
||||
assert( Length );
|
||||
assert( Internal );
|
||||
_os << Internal[0]; // VM is at least garantee to be one
|
||||
_os << Internal[0]; // VM is at least guarantee to be one
|
||||
const unsigned long length = GetLength() < 25 ? GetLength() : 25;
|
||||
for(unsigned long i=1; i<length; ++i)
|
||||
_os << "," << Internal[i];
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
bv->SetLength(ValueLengthField);
|
||||
if( !bv->Read<TSwap>(is) )
|
||||
{
|
||||
assert(0 && "Should not happen");
|
||||
gdcmAssertAlwaysMacro(0 && "Should not happen");
|
||||
return is;
|
||||
}
|
||||
ValueField = bv;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace gdcm
|
|||
/**
|
||||
* \brief ByteBuffer
|
||||
*
|
||||
* \details Detailled description here
|
||||
* \details Detailed description here
|
||||
* \note
|
||||
* looks like a std::streambuf or std::filebuf class with the get and
|
||||
* peek pointer
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
{
|
||||
gdcmDebugMacro( "Odd length" );
|
||||
Internal.resize(vl+1);
|
||||
Length++;
|
||||
++Length;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -776,7 +776,7 @@ Series shadow data (0029,xx20)
|
|||
54 - 'MrEvaProtocol' VM 1, VR UN, SyngoDT 0, NoOfItems 0, Data
|
||||
*
|
||||
*
|
||||
WARNING: I think this is context dependant so 0029,1010 and 0029,1110 are not supposed to mean the same thing, eg:
|
||||
WARNING: I think this is context dependent so 0029,1010 and 0029,1110 are not supposed to mean the same thing, eg:
|
||||
(CSA image data)
|
||||
|
||||
(0029,0010)siemens csa header
|
||||
|
@ -961,13 +961,13 @@ bool CSAHeader::LoadFromDataElement(DataElement const &de)
|
|||
if( v2 == t1.GetElement() )
|
||||
{
|
||||
//std::cout << "Image shadow data (0029,xx10)\n\n";
|
||||
DataElementTag = t1;;
|
||||
DataElementTag = t1;
|
||||
}
|
||||
//else if( de.GetTag().GetPrivateCreator() == t2 )
|
||||
else if( v2 == t2.GetElement() )
|
||||
{
|
||||
//std::cout << "Series shadow data (0029,xx20)\n\n";
|
||||
DataElementTag = t2;;
|
||||
DataElementTag = t2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1116,6 +1116,7 @@ bool CSAHeader::LoadFromDataElement(DataElement const &de)
|
|||
ss.read((char*)&nitems, sizeof(nitems));
|
||||
SwapperNoOp::SwapArray(&nitems,1);
|
||||
csael.SetNoOfItems( nitems );
|
||||
if( InternalType == SV10) { assert( nitems % 6 == 0 );}
|
||||
//std::cout << "NoOfItems " << nitems << ", ";
|
||||
uint32_t xx;
|
||||
ss.read((char*)&xx, sizeof(xx));
|
||||
|
@ -1194,7 +1195,7 @@ void CSAHeader::Print(std::ostream &os) const
|
|||
|
||||
for(; it != InternalCSADataSet.end(); ++it)
|
||||
{
|
||||
std::cout << *it << std::endl;
|
||||
os << *it << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1236,15 +1237,15 @@ bool CSAHeader::FindCSAElementByName(const char *name)
|
|||
}
|
||||
|
||||
static const char csaheader[] = "SIEMENS CSA HEADER";
|
||||
static const gdcm::PrivateTag t1(0x0029,0x0010,csaheader); // CSA Image Header Info
|
||||
static const gdcm::PrivateTag t2(0x0029,0x0020,csaheader); // CSA Series Header Info
|
||||
static const gdcm::PrivateTag t1(0x0029,0x10,csaheader); // CSA Image Header Info
|
||||
static const gdcm::PrivateTag t2(0x0029,0x20,csaheader); // CSA Series Header Info
|
||||
|
||||
//static const char csaheader2[] = "SIEMENS MEDCOM HEADER2";
|
||||
//static const gdcm::PrivateTag t4(0x0029,0x0010,csaheader2); // CSA Image Header Info
|
||||
//static const gdcm::PrivateTag t5(0x0029,0x0020,csaheader2); // CSA Series Header Info
|
||||
|
||||
static const char csanonimage[] = "SIEMENS CSA NON-IMAGE";
|
||||
static const gdcm::PrivateTag t3(0x0029,0x0010,csanonimage); // CSA Data Info
|
||||
static const gdcm::PrivateTag t3(0x0029,0x10,csanonimage); // CSA Data Info
|
||||
|
||||
const PrivateTag & CSAHeader::GetCSAImageHeaderInfoTag()
|
||||
{
|
||||
|
|
|
@ -67,7 +67,7 @@ public :
|
|||
CSAHeader():InternalDataSet(),InternalType(UNKNOWN),InterfileData(nullptr) {};
|
||||
~CSAHeader() = default;
|
||||
|
||||
/// Divers format of CSAHeader as found 'in the wild'
|
||||
/// Diverse format of CSAHeader as found 'in the wild'
|
||||
typedef enum {
|
||||
UNKNOWN = 0,
|
||||
SV10,
|
||||
|
@ -94,15 +94,15 @@ public :
|
|||
CSAHeaderType GetFormat() const;
|
||||
|
||||
/// Return the private tag used by SIEMENS to store the CSA Image Header
|
||||
/// This is: PrivateTag(0x0029,0x0010,"SIEMENS CSA HEADER");
|
||||
/// This is: PrivateTag(0x0029,0x10,"SIEMENS CSA HEADER");
|
||||
static const PrivateTag & GetCSAImageHeaderInfoTag();
|
||||
|
||||
/// Return the private tag used by SIEMENS to store the CSA Series Header
|
||||
/// This is: PrivateTag(0x0029,0x0020,"SIEMENS CSA HEADER");
|
||||
/// This is: PrivateTag(0x0029,0x20,"SIEMENS CSA HEADER");
|
||||
static const PrivateTag & GetCSASeriesHeaderInfoTag();
|
||||
|
||||
/// Return the private tag used by SIEMENS to store the CSA Data Info
|
||||
/// This is: PrivateTag(0x0029,0x0010,"SIEMENS CSA NON-IMAGE");
|
||||
/// This is: PrivateTag(0x0029,0x10,"SIEMENS CSA NON-IMAGE");
|
||||
static const PrivateTag & GetCSADataInfo();
|
||||
|
||||
/// Return the CSAElement corresponding to name 'name'
|
||||
|
|
|
@ -156,6 +156,34 @@ namespace gdcm_ns
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
gdcmErrorMacro( "Could not read SQ, unknown exception" );
|
||||
delete sqi;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return sqi;
|
||||
}
|
||||
else if ( GetVR() & VR::OB_OW ) // pre-dicom 1993 ?
|
||||
{
|
||||
const ByteValue *bv = GetByteValue();
|
||||
assert( bv );
|
||||
SequenceOfItems *sqi = new SequenceOfItems;
|
||||
sqi->SetLength( bv->GetLength() );
|
||||
std::string s( bv->GetPointer(), bv->GetLength() );
|
||||
try
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss.str( s );
|
||||
sqi->Read<ImplicitDataElement,SwapperNoOp>( ss, true );
|
||||
}
|
||||
catch ( Exception &ex0 )
|
||||
{
|
||||
gdcmErrorMacro( "Could not read SQ as OB. Giving up" );
|
||||
gdcmErrorMacro(ex0.what()); (void)ex0;
|
||||
delete sqi;
|
||||
return nullptr;
|
||||
}
|
||||
return sqi;
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ public:
|
|||
}
|
||||
|
||||
/// Interpret the Value stored in the DataElement. This is more robust (but also more
|
||||
/// expensive) to call this function rather than the simpliest form: GetSequenceOfItems()
|
||||
/// expensive) to call this function rather than the simplest form: GetSequenceOfItems()
|
||||
/// It also return NULL when the Value is NOT of type SequenceOfItems
|
||||
/// \warning in case GetSequenceOfItems() succeed the function return this value, otherwise
|
||||
/// it creates a new SequenceOfItems, you should handle that in your case, for instance:
|
||||
|
@ -186,7 +186,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
// The following fonctionalities are dependant on:
|
||||
// The following functionalities are dependent on:
|
||||
// # The Transfer Syntax: Explicit or Implicit
|
||||
// # The Byte encoding: Little Endian / Big Endian
|
||||
|
||||
|
|
|
@ -25,10 +25,10 @@ const DataElement& DataSet::GetDEEnd() const
|
|||
|
||||
std::string DataSet::GetPrivateCreator(const Tag &t) const
|
||||
{
|
||||
if( t.IsPrivate() && !t.IsPrivateCreator() )
|
||||
if( t.IsPrivate() && !t.IsGroupLength() && !t.IsPrivateCreator() && !t.IsIllegal() )
|
||||
{
|
||||
Tag pc = t.GetPrivateCreator();
|
||||
if( pc.GetElement() )
|
||||
assert( pc.GetElement() );
|
||||
{
|
||||
const DataElement r(pc);
|
||||
ConstIterator it = DES.find(r);
|
||||
|
@ -41,7 +41,7 @@ std::string DataSet::GetPrivateCreator(const Tag &t) const
|
|||
if( de.IsEmpty() ) return "";
|
||||
const ByteValue *bv = de.GetByteValue();
|
||||
assert( bv );
|
||||
std::string owner = std::string(bv->GetPointer(),bv->GetLength());
|
||||
std::string owner = std::string(bv->GetPointer(),bv->GetLength()).c_str();
|
||||
// There should not be any trailing space character...
|
||||
// TODO: tmp.erase(tmp.find_last_not_of(' ') + 1);
|
||||
while( !owner.empty() && owner[owner.size()-1] == ' ' )
|
||||
|
@ -56,9 +56,17 @@ std::string DataSet::GetPrivateCreator(const Tag &t) const
|
|||
return "";
|
||||
}
|
||||
|
||||
PrivateTag DataSet::GetPrivateTag(const Tag &t) const
|
||||
{
|
||||
const std::string str = this->GetPrivateCreator(t);
|
||||
PrivateTag pt(t);
|
||||
pt.SetOwner(str.c_str());
|
||||
return pt;
|
||||
}
|
||||
|
||||
Tag DataSet::ComputeDataElement(const PrivateTag & t) const
|
||||
{
|
||||
gdcmDebugMacro( "Entering ComputeDataElement" );
|
||||
//gdcmDebugMacro( "Entering ComputeDataElement" );
|
||||
//assert( t.IsPrivateCreator() ); // No this is wrong to do the assert: eg. (0x07a1,0x000a,"ELSCINT1")
|
||||
// is valid because we have not yet done the mapping, so 0xa < 0x10 fails but might not later on
|
||||
const Tag start(t.GetGroup(), 0x0010 ); // First possible private creator (0x0 -> 0x9 are reserved...)
|
||||
|
@ -87,7 +95,7 @@ Tag DataSet::ComputeDataElement(const PrivateTag & t) const
|
|||
}
|
||||
++it;
|
||||
}
|
||||
gdcmDebugMacro( "In compute found is:" << found );
|
||||
//gdcmDebugMacro( "In compute found is:" << found );
|
||||
if (!found) return GetDEEnd().GetTag();
|
||||
// else
|
||||
// ok we found the Private Creator Data Element, let's construct the proper data element
|
||||
|
|
|
@ -196,8 +196,12 @@ public:
|
|||
const DataElement& operator() (uint16_t group, uint16_t element) const { return GetDataElement( Tag(group,element) ); }
|
||||
|
||||
/// Return the private creator of the private tag 't':
|
||||
/// or an empty string when not found
|
||||
std::string GetPrivateCreator(const Tag &t) const;
|
||||
|
||||
/// Return the private tag of the private tag 't', private creator will be set to empty if not found
|
||||
PrivateTag GetPrivateTag(const Tag &t) const;
|
||||
|
||||
/// Look up if private tag 't' is present in the dataset:
|
||||
bool FindDataElement(const PrivateTag &t) const;
|
||||
/// Return the dataelement
|
||||
|
@ -230,19 +234,6 @@ public:
|
|||
DataSet& operator=(DataSet const &)
|
||||
= default;
|
||||
|
||||
/*
|
||||
template <typename TOperation>
|
||||
void ExecuteOperation(TOperation & operation) {
|
||||
assert( !DES.empty() );
|
||||
DataElementSet::iterator it = Begin();
|
||||
for( ; it != End(); ++it)
|
||||
{
|
||||
DataElement &de = (DataElement&)*it;
|
||||
operation( de );
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
template <typename TDE, typename TSwap>
|
||||
std::istream &ReadNested(std::istream &is);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue