merge upstream 3.0.21

This commit is contained in:
zhouganqing 2024-02-29 18:13:02 +08:00
parent b753e6a8e2
commit a01a6be004
503 changed files with 20025 additions and 4396 deletions

8
.gitattributes vendored
View File

@ -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

26
.github/workflows/c-cpp.yml vendored Normal file
View File

@ -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

12
.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
# back-up
*~
*.bak
# files when there are conflicts
*.orig
# qtcreator files
CMakeLists.txt.user*
# kdevelop files
*.kdev*

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "Testing/Data"]
path = Testing/Data
url = git://git.code.sf.net/p/gdcm/gdcmdata

View File

@ -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} .

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
*/

View File

@ -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)

View File

@ -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 )
{

View File

@ -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 )
{

View File

@ -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

View File

@ -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) );

View File

@ -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() );

View File

@ -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);
}

View File

@ -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 );

View File

@ -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 \

View File

@ -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

View File

@ -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)

View File

@ -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
"

View File

@ -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'
#

View File

@ -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'
#

View File

@ -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()

View File

@ -32,6 +32,7 @@ set(CSHARP_EXAMPLES
if(BUILD_TESTING)
list(APPEND CSHARP_EXAMPLES
BasicAnonymizer
Cleaner
ClinicalTrialIdentificationWorkflow
)
endif()

124
Examples/Csharp/Cleaner.cs Normal file
View File

@ -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;
}
}

View File

@ -48,6 +48,7 @@ set(EXAMPLES_SRCS
CreateJPIPDataSet
DumpADAC
DumpToshibaDTI
DumpToshibaDTI2
DumpImageHeaderInfo
ReadMultiTimesException
pmsct_rgb1

View File

@ -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;

View File

@ -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 );

View File

@ -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( &copy[0], copy.size() );
of.close();
#else
std::istringstream is;
std::string dup( &copy[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;
}

View File

@ -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 (...)

View File

@ -15,6 +15,7 @@ set(examples
DecompressImage
ScanDirectory
ReadFiles
SimplePrint
FileAnonymize
)
foreach(example ${examples})

View File

@ -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, "" );
}
}

View File

@ -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)

View File

@ -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;

View File

@ -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 ...
*/

View File

@ -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 :

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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: \

View File

@ -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;

View File

@ -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 ?

View File

@ -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;

View File

@ -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:
//

View File

@ -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;

View File

@ -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

View File

@ -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." );

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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. */

View File

@ -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]);
}

View File

@ -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)

View File

@ -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

View File

@ -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]);

View File

@ -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;
}

View File

@ -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 }
};

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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)
{

View File

@ -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()

View File

@ -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="&#xA0;" vm="&#xA0;" 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="&gt;Referenced SOP Class UID" type="1C" vr="UI" vm="1" description="Uniquely identifies the referenced SOP Class"/>
<entry name="&gt;Referenced SOP Instance UID" type="1C" vr="UI" vm="1" description="Uniquely identifies the referenced SOP Instance"/>
<entry name="&gt; 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="&gt; 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="&gt;Referenced SOP Class UID" type="1C" vr="UI" vm="1" description="Uniquely identifies the referenced SOP Class"/>
<entry name="&gt;Referenced SOP Instance UID" type="1C" vr="UI" vm="1" description="Uniquely identifies the referenced SOP Instance"/>
<entry name="&gt; 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="&gt; 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="&#xA0;" type="1" vr="&#xA0;" vm="&#xA0;" description="&#xA0;"/-->
<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="&#xA0;" vm="&#xA0;" description="&#xA0;"/-->
<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 .&#xB7;"/>
<entry name="SequenceMask" type="1" vr="UL" vm="1" description="Parameters used for acquisition, e.g. door open, interpolation, raw filter, Siemens sequence .&#xB7;"/>
<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="&#xA0;" vm="&#xA0;" description="&#xA0;"/-->

View File

@ -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()

View File

@ -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">

View File

@ -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)

View File

@ -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

View File

@ -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
-->
<!--

View File

@ -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
-->
<!--

View File

@ -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

View File

@ -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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</FONT></TD>
<TD ALIGN="right"><FONT FACE="Arial" SIZE=-2>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</FONT></TD>
</TR>

View File

@ -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()

View File

@ -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

View File

@ -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"},

View File

@ -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 =

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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

View File

@ -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() ];
}

View File

@ -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 ];
}

View File

@ -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

View File

@ -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];

View File

@ -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;

View File

@ -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

View File

@ -41,7 +41,7 @@ public:
{
gdcmDebugMacro( "Odd length" );
Internal.resize(vl+1);
Length++;
++Length;
}
}

View File

@ -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()
{

View File

@ -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'

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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