Skip to content

Commit 4e328a6

Browse files
committed
Backport from master onto release branch
1 parent 778b495 commit 4e328a6

48 files changed

Lines changed: 747 additions & 189 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# back-up
2+
*~
3+
*.bak
4+
5+
# files when there are conflicts
6+
*.orig
7+
8+
# qtcreator files
9+
CMakeLists.txt.user*
10+
11+
# kdevelop files
12+
*.kdev*

‎Applications/Cxx/gdcmanon.cxx‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,21 @@ static bool AnonymizeOneFileDumb(gdcm::Anonymizer &anon, const char *filename, c
7171
}
7272

7373
std::vector<gdcm::Tag>::const_iterator it = empty_tags.begin();
74+
bool success = true;
7475
for(; it != empty_tags.end(); ++it)
7576
{
76-
anon.Empty( *it );
77+
success = success && anon.Empty( *it );
7778
}
7879
it = remove_tags.begin();
7980
for(; it != remove_tags.end(); ++it)
8081
{
81-
anon.Remove( *it );
82+
success = success && anon.Remove( *it );
8283
}
8384

8485
std::vector< std::pair<gdcm::Tag, std::string> >::const_iterator it2 = replace_tags.begin();
8586
for(; it2 != replace_tags.end(); ++it2)
8687
{
87-
anon.Replace( it2->first, it2->second.c_str() );
88+
success = success && anon.Replace( it2->first, it2->second.c_str() );
8889
}
8990

9091
gdcm::Writer writer;
@@ -104,7 +105,7 @@ static bool AnonymizeOneFileDumb(gdcm::Anonymizer &anon, const char *filename, c
104105

105106
return false;
106107
}
107-
return true;
108+
return success;
108109
}
109110

110111
static bool AnonymizeOneFile(gdcm::Anonymizer &anon, const char *filename, const char *outfilename, bool continuemode = false)

‎Applications/Cxx/gdcmdump.cxx‎

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,162 @@ int ignoreerrors = 0;
6262

6363
namespace cleanup
6464
{
65+
// {"1.3.46.670589.11.0.0.12.2" ,"Philips Private MR Series Data Storage"},
66+
enum {
67+
TYPE_FLOAT = 0, // float
68+
TYPE_INT32 = 1, // int32
69+
TYPE_STRING = 2, // 80 bytes string (+1)
70+
TYPE_UINT32 = 4, // uint32
71+
};
72+
73+
template <typename T>
74+
void printvaluet(std::istream & is, uint32_t numels)
75+
{
76+
T buffer;
77+
for( uint32_t i = 0; i < numels; ++i )
78+
{
79+
if( i ) std::cout << "\\";
80+
is.read( (char*)&buffer, sizeof(T) );
81+
std::cout << buffer;
82+
}
83+
}
84+
85+
void printvalue(std::istream &is, uint32_t type, uint32_t numels, uint32_t pos)
86+
{
87+
assert( numels > 0 );
88+
std::streampos start = is.tellg();
89+
is.seekg( pos );
90+
std::cout << "[";
91+
typedef char (string81)[81]; // 80'th byte == 0
92+
assert( sizeof( string81 ) == 81 );
93+
switch( type )
94+
{
95+
case TYPE_FLOAT:
96+
printvaluet<float>(is, numels);
97+
break;
98+
case TYPE_INT32:
99+
printvaluet<int32_t>(is, numels);
100+
break;
101+
case TYPE_STRING:
102+
printvaluet<string81>(is, numels);
103+
break;
104+
case TYPE_UINT32:
105+
printvaluet<uint32_t>(is, numels);
106+
break;
107+
default:
108+
assert( 0 );
109+
}
110+
std::cout << "]";
111+
std::cout << " # " << numels;
112+
is.seekg( start );
113+
}
114+
115+
struct PDFElement
116+
{
117+
const char *getname() const { return name; }
118+
uint32_t gettype() const { return getvalue(0); }
119+
uint32_t getnumelems() const { return getvalue(1); }
120+
uint32_t getdummy() const { return getvalue(2); }
121+
uint32_t getoffset() const { return getvalue(3); }
122+
private:
123+
char name[50];
124+
// type , numel and offset needs to be read starting from the end
125+
// the data in between name and those value can contains garbage stuff
126+
uint32_t getvalue(int n) const {
127+
uint32_t val = 0;
128+
memcpy( (char*)&val, name + 50 - 16 + n * 4, sizeof( val ) );
129+
return val;
130+
}
131+
};
132+
133+
void printbinary(std::istream &is, PDFElement const & pdfel )
134+
{
135+
const char *bufferref = pdfel.getname();
136+
std::cout << " " << bufferref << " ";
137+
uint32_t type = pdfel.gettype();
138+
uint32_t numels = pdfel.getnumelems();
139+
uint32_t dummy = pdfel.getdummy();
140+
assert( dummy == 0 );
141+
uint32_t offset = pdfel.getoffset();
142+
uint32_t pos = offset + is.tellg() - 4;
143+
printvalue(is, type, numels, pos);
144+
}
145+
146+
void ProcessSDSData( std::istream & is )
147+
{
148+
// havent been able to figure out what was the begin meant for
149+
is.seekg( 0x20 - 8 );
150+
uint32_t version = 0;
151+
is.read( (char*)&version, sizeof(version) );
152+
assert( version == 8 );
153+
uint32_t numel = 0;
154+
is.read( (char*)&numel, sizeof(numel) );
155+
for( uint32_t el = 0; el < numel; ++el )
156+
{
157+
PDFElement pdfel;
158+
assert( sizeof(pdfel) == 50 );
159+
is.read( (char*)&pdfel, 50 );
160+
if( *pdfel.getname() )
161+
{
162+
printbinary( is, pdfel );
163+
std::cout << std::endl;
164+
}
165+
}
166+
167+
}
168+
// PMS MR Series Data Storage
169+
int DumpPMS_MRSDS(const gdcm::DataSet & ds)
170+
{
171+
const gdcm::PrivateTag tdata(0x2005,0x32,"Philips MR Imaging DD 002");
172+
if( !ds.FindDataElement( tdata ) ) return 1;
173+
const gdcm::DataElement &data = ds.GetDataElement( tdata );
174+
gdcm::SmartPointer<gdcm::SequenceOfItems> sqi = data.GetValueAsSQ();
175+
if( !sqi ) return 1;
176+
std::cout << "PMS Dumping info from tag " << tdata << std::endl;
177+
gdcm::SequenceOfItems::ConstIterator it = sqi->Begin();
178+
for( ; it != sqi->End(); ++it )
179+
{
180+
const gdcm::Item & item = *it;
181+
const gdcm::DataSet & nestedds = item.GetNestedDataSet();
182+
const gdcm::PrivateTag tprotocoldataname(0x2005,0x37,"Philips MR Imaging DD 002");
183+
const gdcm::DataElement & protocoldataname = nestedds.GetDataElement( tprotocoldataname );
184+
const gdcm::ByteValue *bv1 = protocoldataname.GetByteValue();
185+
const gdcm::PrivateTag tprotocoldatatype(0x2005,0x39,"Philips MR Imaging DD 002");
186+
const gdcm::DataElement & protocoldatatype = nestedds.GetDataElement( tprotocoldatatype );
187+
const gdcm::ByteValue *bv2 = protocoldatatype.GetByteValue();
188+
const gdcm::PrivateTag tprotocoldatablock(0x2005,0x44,"Philips MR Imaging DD 002");
189+
const gdcm::DataElement & protocoldatablock = nestedds.GetDataElement( tprotocoldatablock );
190+
const gdcm::ByteValue *bv3 = protocoldatablock.GetByteValue();
191+
const gdcm::PrivateTag tprotocoldatabool(0x2005,0x47,"Philips MR Imaging DD 002");
192+
const gdcm::DataElement & protocoldatabool = nestedds.GetDataElement( tprotocoldatabool );
193+
const gdcm::ByteValue *bv4 = protocoldatabool.GetByteValue();
194+
std::string s1;
195+
if( bv1 )
196+
{
197+
s1 = std::string( bv1->GetPointer(), bv1->GetLength() );
198+
}
199+
std::string s2;
200+
if( bv2 )
201+
{
202+
s2 = std::string( bv2->GetPointer(), bv2->GetLength() );
203+
}
204+
std::string s3;
205+
if( bv3 )
206+
{
207+
s3 = std::string( bv3->GetPointer(), bv3->GetLength() );
208+
}
209+
std::string s4;
210+
if( bv4 )
211+
{
212+
s4 = std::string( bv4->GetPointer(), bv4->GetLength() );
213+
}
214+
std::istringstream is( s3 );
215+
std::cout << "PMS/Item name: [" << s1 << "/" << s2 << "/" << s4 << "]" << std::endl;
216+
ProcessSDSData( is );
217+
}
218+
return 0;
219+
}
220+
65221
// VEPRO
66222
/*
67223
[VIMDATA2]
@@ -465,6 +621,24 @@ int PrintVEPRO(const std::string & filename, bool verbose)
465621
return ret;
466622
}
467623

624+
int PrintSDS(const std::string & filename, bool verbose)
625+
{
626+
(void)verbose;
627+
gdcm::Reader reader;
628+
reader.SetFileName( filename.c_str() );
629+
if( !reader.Read() )
630+
{
631+
std::cerr << "Failed to read: " << filename << std::endl;
632+
return 1;
633+
}
634+
635+
const gdcm::DataSet& ds = reader.GetFile().GetDataSet();
636+
int ret = cleanup::DumpPMS_MRSDS( ds );
637+
638+
return ret;
639+
}
640+
641+
468642
int PrintPDB(const std::string & filename, bool verbose)
469643
{
470644
(void)verbose;
@@ -614,6 +788,7 @@ void PrintHelp()
614788
std::cout << " -P --pdb print GEMS Protocol Data Block (0025,1b,GEMS_SERS_01)." << std::endl;
615789
std::cout << " --elscint print ELSCINT Protocol Information (01f7,26,ELSCINT1)." << std::endl;
616790
std::cout << " --vepro print VEPRO Protocol Information (0055,20,VEPRO VIM 5.0 DATA)." << std::endl;
791+
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;
617792
std::cout << " -A --asn1 print encapsulated ASN1 structure >(0400,0520)." << std::endl;
618793
std::cout << " --map-uid-names map UID to names." << std::endl;
619794
std::cout << "General Options:" << std::endl;
@@ -641,6 +816,7 @@ int main (int argc, char *argv[])
641816
int printpdb = 0;
642817
int printelscint = 0;
643818
int printvepro = 0;
819+
int printsds = 0; // MR Series Data Storage
644820
int verbose = 0;
645821
int warning = 0;
646822
int debug = 0;
@@ -681,6 +857,7 @@ int main (int argc, char *argv[])
681857
{"map-uid-names", 0, &mapuidnames, 1},
682858
{"elscint", 0, &printelscint, 1},
683859
{"vepro", 0, &printvepro, 1},
860+
{"sds", 0, &printsds, 1},
684861
{0, 0, 0, 0} // required
685862
};
686863
static const char short_options[] = "i:xrpdcCPAVWDEhvI";
@@ -878,6 +1055,10 @@ int main (int argc, char *argv[])
8781055
{
8791056
res += PrintVEPRO(*it, verbose!= 0);
8801057
}
1058+
else if( printsds )
1059+
{
1060+
res += PrintSDS(*it, verbose!= 0);
1061+
}
8811062
else if( printelscint )
8821063
{
8831064
res += PrintELSCINT(*it, verbose!= 0);
@@ -917,6 +1098,10 @@ int main (int argc, char *argv[])
9171098
{
9181099
res += PrintVEPRO(filename, verbose!= 0);
9191100
}
1101+
else if( printsds )
1102+
{
1103+
res += PrintSDS(filename, verbose!= 0);
1104+
}
9201105
else if( printelscint )
9211106
{
9221107
res += PrintELSCINT(filename, verbose!= 0);

‎Applications/Cxx/gdcmimg.cxx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ bool PopulateSingeFile( gdcm::PixmapWriter & writer, gdcm::SequenceOfFragments *
282282
bool b = jpeg.GetHeaderInfo( is, ts );
283283
if( !b )
284284
{
285+
std::cerr << "Could not read: " << filename << std::endl;
285286
return false;
286287
}
287288

‎Applications/Cxx/gdcmpdf.cxx‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,10 @@ return ch;
536536
gdcm::Attribute<0x0008, 0x0050> at;
537537
ds.Insert( at.GetAsDataElement() );
538538
}
539-
//(0008,0060) CS [OT] # 2, 1 Modality
539+
//(0008,0060) CS [DOC] # 2, 1 Modality
540540
{
541541
gdcm::Attribute<0x0008, 0x0060> at;
542-
at.SetValue( "OT" );
542+
at.SetValue( "DOC " );
543543
ds.Insert( at.GetAsDataElement() );
544544
}
545545
//(0008,0064) CS [WSD] # 4, 1 ConversionType
@@ -559,6 +559,14 @@ return ch;
559559
gdcm::Attribute<0x0008, 0x0090> at;
560560
ds.Insert( at.GetAsDataElement() );
561561
}
562+
563+
// In past DICOM implementation there used to be those neat tags:
564+
// (0088,0904) Topic Title TopicTitle LO 1 RET
565+
// (0088,0906) Topic Subject TopicSubject ST 1 RET
566+
// (0088,0910) Topic Author TopicAuthor LO 1 RET
567+
// (0088,0912) Topic Keywords TopicKeywords LO 1-32 RET
568+
// However they are now deprecated...
569+
562570
//(0010,0010) PN (no value available) # 0, 0 PatientsName
563571
{
564572
gdcm::Attribute<0x0010, 0x0010> at;

‎CMake/FindCharLS.cmake‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#
2+
# Copyright (c) 2006-2011 Mathieu Malaterre <mathieu.malaterre@gmail.com>
3+
#
4+
# Redistribution and use is allowed according to the terms of the New
5+
# BSD license.
6+
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
7+
#
8+
9+
FIND_PATH(CHARLS_INCLUDE_DIR CharLS/interface.h
10+
/usr/local/include
11+
/usr/include
12+
)
13+
14+
FIND_LIBRARY(CHARLS_LIBRARY
15+
NAMES CharLS
16+
PATHS /usr/lib /usr/local/lib
17+
)
18+
19+
IF (CHARLS_LIBRARY AND CHARLS_INCLUDE_DIR)
20+
SET(CHARLS_LIBRARIES ${CHARLS_LIBRARY})
21+
SET(CHARLS_INCLUDE_DIRS ${CHARLS_INCLUDE_DIR})
22+
SET(CHARLS_FOUND "YES")
23+
ELSE (CHARLS_LIBRARY AND CHARLS_INCLUDE_DIR)
24+
SET(CHARLS_FOUND "NO")
25+
ENDIF (CHARLS_LIBRARY AND CHARLS_INCLUDE_DIR)
26+
27+
IF (CHARLS_FOUND)
28+
IF (NOT CHARLS_FIND_QUIETLY)
29+
MESSAGE(STATUS "Found CHARLS: ${CHARLS_LIBRARIES}")
30+
ENDIF (NOT CHARLS_FIND_QUIETLY)
31+
ELSE (CHARLS_FOUND)
32+
IF (CHARLS_FIND_REQUIRED)
33+
MESSAGE(FATAL_ERROR "Could not find CHARLS library")
34+
ENDIF (CHARLS_FIND_REQUIRED)
35+
ENDIF (CHARLS_FOUND)
36+
37+
MARK_AS_ADVANCED(
38+
CHARLS_LIBRARIES
39+
CHARLS_INCLUDE_DIR
40+
)

‎CMake/InstallMacros.cmake‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ MACRO (install_pdb library)
4040
get_target_property(library_dll ${library} LOCATION_${cfg})
4141
string(REPLACE .dll .pdb library_pdb ${library_dll})
4242
string(TOLOWER ${cfg} lcfg)
43-
if(lcfg STREQUAL "debug" or lcfg STREQUAL "relwithdebinfo")
43+
if(lcfg STREQUAL "debug" OR lcfg STREQUAL "relwithdebinfo")
4444
install (FILES ${library_pdb}
4545
DESTINATION ${GDCM_INSTALL_BIN_DIR}
4646
COMPONENT Development
@@ -55,7 +55,7 @@ MACRO (install_pdb library)
5555
get_target_property(library_dll ${library} LOCATION_${CMAKE_BUILD_TYPE})
5656
string(REPLACE .dll .pdb library_pdb ${library_dll})
5757
string(TOLOWER ${CMAKE_BUILD_TYPE} lcfg)
58-
if(lcfg STREQUAL "debug" or lcfg STREQUAL "relwithdebinfo")
58+
if(lcfg STREQUAL "debug" OR lcfg STREQUAL "relwithdebinfo")
5959
install (FILES ${library_pdb}
6060
DESTINATION ${GDCM_INSTALL_BIN_DIR}
6161
COMPONENT Development

0 commit comments

Comments
 (0)