Skip to content

Commit 51fda44

Browse files
GDCM Upstreamhjmjohnson
authored andcommitted
GDCM 2026-04-20 (244fdbea)
Code extracted from: https://github.com/malaterre/GDCM.git at commit 244fdbeadecbb03b29ace5542aa1c694d36195bb (244fdbeadecbb03b29ace5542aa1c694d36195bb).
1 parent 2fbfa6a commit 51fda44

13 files changed

Lines changed: 127 additions & 25 deletions

File tree

CMake/UseCopyright.cmake

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ macro(APPEND_COPYRIGHT)
1818
# need to raise an error if COPYRIGHT_MODULE_FILENAME is not set...
1919
if(EXISTS ${COPYRIGHT_MODULE_FILENAME} )
2020
foreach(filename ${ARGN})
21-
file(READ ${filename} content)
22-
file(APPEND ${COPYRIGHT_MODULE_FILENAME} ${content})
21+
if(EXISTS ${filename} )
22+
file(READ ${filename} content)
23+
file(APPEND ${COPYRIGHT_MODULE_FILENAME} ${content})
24+
else()
25+
message(WARNING "The file '${filename}' does not exist, so not appended to ${COPYRIGHT_MODULE_FILENAME}.")
26+
endif()
2327
endforeach()
2428
endif()
2529
endmacro()

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ endif()
1010
#----------------------------------------------------------------------------
1111

1212
project(GDCM
13-
VERSION 3.2.2
13+
VERSION 3.3.0
1414
LANGUAGES CXX C
1515
)
1616
## NOTE: the "DESCRIPTION" feature of project() was introduced in cmake 3.10.0

Source/DataDictionary/gdcmPrivateDefaultDicts.cxx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ using DICT_ENTRY = struct
3838
};
3939

4040
static const DICT_ENTRY DICOMV3DataDict [] = {
41+
{0x0033,0x0001,"KONICA MINOLTA QA 1.4",VR::SQ,VM::VM1,"?Possibly PHI?",false },
42+
{0x0033,0x0004,"KONICA MINOLTA QA 1.4",VR::SS,VM::VM1,"?",false },
43+
{0x0033,0x0006,"KONICA MINOLTA QA 1.4",VR::SS,VM::VM1,"?",false },
44+
{0x0033,0x0008,"KONICA MINOLTA QA 1.4",VR::SS,VM::VM1,"?",false },
45+
{0x0033,0x0010,"KONICA MINOLTA QA 1.4",VR::SS,VM::VM1,"?",false },
46+
{0x0033,0x0011,"KONICA MINOLTA QA 1.4",VR::SS,VM::VM1,"?",false },
47+
{0x0033,0x0014,"KONICA MINOLTA QA 1.4",VR::SS,VM::VM1,"?",false },
48+
{0x0033,0x0016,"KONICA MINOLTA QA 1.4",VR::SS,VM::VM1,"?",false },
4149
{0x0049,0x0010,"AIR",VR::LO,VM::VM1,"?Possibly PHI?",false },
4250
{0x0049,0x0011,"AIR",VR::LO,VM::VM1,"?number?",false },
4351
{0x0049,0x0013,"AIR",VR::LT,VM::VM1,"?Long desc possibly PHI?",false },
@@ -11007,7 +11015,7 @@ static const DICT_ENTRY DICOMV3DataDict [] = {
1100711015
{0x0019,0x0078,"SVISION",VR::DS,VM::VM1,"Filter Thickness 1",false },
1100811016
{0x0019,0x0079,"SVISION",VR::DS,VM::VM1,"Filter Thickness 2",false },
1100911017
{0x0019,0x0080,"SVISION",VR::IS,VM::VM1,"Bucky Format",false },
11010-
{0x0019,0x0081,"SVISION",VR::IS,VM::VM1,"Object Position",false },
11018+
{0x0019,0x0081,"SVISION",VR::LO,VM::VM1,"Object Position",false },
1101111019
{0x0019,0x0090,"SVISION",VR::LO,VM::VM1,"Desk Command",false },
1101211020
{0x0019,0x0091,"SVISION",VR::IS,VM::VM1,"Central Beam X",false },
1101311021
{0x0019,0x0092,"SVISION",VR::IS,VM::VM1,"Central Beam Y",false },

Source/DataStructureAndEncodingDefinition/gdcmExplicitDataElement.txx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,23 @@ std::istream &ExplicitDataElement::ReadValue(std::istream &is, bool readvalues)
242242
{
243243
//gdcm_assert( TagField != Tag(0x7fe0,0x0010) );
244244
ValueField = new ByteValue;
245+
if( readvalues )
246+
{
247+
const std::streampos cur = is.tellg();
248+
if( cur != std::streampos(-1) )
249+
{
250+
is.seekg(0, std::ios::end);
251+
const std::streampos end = is.tellg();
252+
is.seekg(cur);
253+
if( end != std::streampos(-1) && is.good()
254+
&& static_cast<uint64_t>(end - cur) < static_cast<uint32_t>(ValueLengthField) )
255+
{
256+
gdcmWarningMacro( "Value Length " << ValueLengthField
257+
<< " exceeds remaining stream size for tag " << TagField );
258+
throw Exception( "Value Length exceeds remaining stream size" );
259+
}
260+
}
261+
}
245262
}
246263
// We have the length we should be able to read the value
247264
this->SetValueFieldLength( ValueLengthField, readvalues );

Source/DataStructureAndEncodingDefinition/gdcmFragment.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@ class GDCM_EXPORT Fragment : public DataElement
9191
{
9292
// Self
9393
SmartPointer<ByteValue> bv = new ByteValue;
94+
const std::streampos cur = is.tellg();
95+
if( cur != std::streampos(-1) )
96+
{
97+
is.seekg(0, std::ios::end);
98+
const std::streampos end = is.tellg();
99+
is.seekg(cur);
100+
if( end != std::streampos(-1) && is.good()
101+
&& static_cast<uint64_t>(end - cur) < static_cast<uint32_t>(ValueLengthField) )
102+
{
103+
throw Exception( "Fragment Value Length exceeds remaining stream size" );
104+
}
105+
}
94106
bv->SetLength(ValueLengthField);
95107
if( !bv->Read<TSwap>(is) )
96108
{
@@ -144,6 +156,18 @@ class GDCM_EXPORT Fragment : public DataElement
144156

145157
// Self
146158
SmartPointer<ByteValue> bv = new ByteValue;
159+
const std::streampos cur2 = is.tellg();
160+
if( cur2 != std::streampos(-1) )
161+
{
162+
is.seekg(0, std::ios::end);
163+
const std::streampos end2 = is.tellg();
164+
is.seekg(cur2);
165+
if( end2 != std::streampos(-1) && is.good()
166+
&& static_cast<uint64_t>(end2 - cur2) < static_cast<uint32_t>(ValueLengthField) )
167+
{
168+
throw Exception( "Fragment Value Length exceeds remaining stream size" );
169+
}
170+
}
147171
bv->SetLength(ValueLengthField);
148172
if( !bv->Read<TSwap>(is) )
149173
{

Source/DataStructureAndEncodingDefinition/gdcmImplicitDataElement.txx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,23 @@ std::istream &ImplicitDataElement::ReadValue(std::istream &is, bool readvalues)
215215
ValueLengthField = 202; // 0xca
216216
}
217217
#endif
218+
if( !ValueLengthField.IsUndefined() && readvalues )
219+
{
220+
const std::streampos cur = is.tellg();
221+
if( cur != std::streampos(-1) )
222+
{
223+
is.seekg(0, std::ios::end);
224+
const std::streampos end = is.tellg();
225+
is.seekg(cur);
226+
if( end != std::streampos(-1) && is.good()
227+
&& static_cast<uint64_t>(end - cur) < static_cast<uint32_t>(ValueLengthField) )
228+
{
229+
gdcmWarningMacro( "Value Length " << ValueLengthField
230+
<< " exceeds remaining stream size for tag " << TagField );
231+
throw Exception( "Value Length exceeds remaining stream size" );
232+
}
233+
}
234+
}
218235
// We have the length we should be able to read the value
219236
this->SetValueFieldLength( ValueLengthField, readvalues );
220237
bool failed;

Source/DataStructureAndEncodingDefinition/gdcmSequenceOfFragments.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ std::istream& ReadValue(std::istream &is, bool /*readvalues*/)
167167
{
168168
gdcm_assert( Fragments.size() == 1 );
169169
const ByteValue *bv = Fragments[0].GetByteValue();
170-
gdcm_assert( (unsigned char)bv->GetPointer()[ bv->GetLength() - 1 ] == 0xfe );
170+
gdcm_assert( bv->GetLength() >= 1 && (unsigned char)bv->GetPointer()[ bv->GetLength() - 1 ] == 0xfe );
171171
// Yes this is an extra copy, this is a bug anyway, go fix YOUR code
172172
Fragments[0].SetByteValue( bv->GetPointer(), bv->GetLength() - 1 );
173173
gdcmWarningMacro( "JPEG Fragment length was declared with an extra byte"
@@ -188,7 +188,7 @@ std::istream& ReadValue(std::istream &is, bool /*readvalues*/)
188188
const size_t lastf = Fragments.size() - 1;
189189
const ByteValue *bv = Fragments[ lastf ].GetByteValue();
190190
const char *a = bv->GetPointer();
191-
gdcmAssertAlwaysMacro( (unsigned char)a[ bv->GetLength() - 1 ] == 0xfe );
191+
gdcmAssertAlwaysMacro( bv->GetLength() >= 1 && (unsigned char)a[ bv->GetLength() - 1 ] == 0xfe );
192192
Fragments[ lastf ].SetByteValue( bv->GetPointer(), bv->GetLength() - 1 );
193193
is.seekg( -9, std::ios::cur );
194194
gdcm_assert( is.good() );
@@ -212,7 +212,7 @@ std::istream& ReadValue(std::istream &is, bool /*readvalues*/)
212212
const size_t lastf = Fragments.size() - 1;
213213
const ByteValue *bv = Fragments[ lastf ].GetByteValue();
214214
const char *a = bv->GetPointer();
215-
gdcmAssertAlwaysMacro( (unsigned char)a[ bv->GetLength() - 2 ] == 0xfe );
215+
gdcmAssertAlwaysMacro( bv->GetLength() >= 2 && (unsigned char)a[ bv->GetLength() - 2 ] == 0xfe );
216216
Fragments[ lastf ].SetByteValue( bv->GetPointer(), bv->GetLength() - 2 );
217217
is.seekg( -10, std::ios::cur );
218218
gdcm_assert( is.good() );

Source/MediaStorageAndFileFormat/CMakeLists.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ set(MSFF_SRCS
120120
if(NOT BUILD_SHARED_LIBS)
121121
set_source_files_properties(gdcmJPEG2000Codec.cxx
122122
PROPERTIES
123-
COMPILE_FLAGS -DOPJ_STATIC
123+
COMPILE_DEFINITIONS OPJ_STATIC
124124
)
125125
set_source_files_properties(gdcmJPEGLSCodec.cxx
126126
PROPERTIES
@@ -129,10 +129,17 @@ if(NOT BUILD_SHARED_LIBS)
129129
else()
130130
set_source_files_properties(gdcmJPEGLSCodec.cxx
131131
PROPERTIES
132-
COMPILE_FLAGS -DCHARLS_DLL
132+
COMPILE_DEFINITIONS CHARLS_DLL
133133
)
134134
endif()
135135

136+
set_source_files_properties( ${GDCM_SOURCE_DIR}/Utilities/gdcmext/csa.c
137+
${GDCM_SOURCE_DIR}/Utilities/gdcmext/mec_mr3.c
138+
${GDCM_SOURCE_DIR}/Utilities/gdcmext/mec_mr3_io.c
139+
${GDCM_SOURCE_DIR}/Utilities/gdcmext/mec_mr3_dict.c
140+
PROPERTIES
141+
COMPILE_DEFINITIONS _POSIX_C_SOURCE=200809L # posix_memalign and strnlen
142+
)
136143

137144
# Add the include paths
138145
include_directories(

Source/MediaStorageAndFileFormat/gdcmImageHelper.cxx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,9 @@ void ImageHelper::SetDimensionsValue(File& f, const Pixmap & img)
976976
MediaStorage ms;
977977
ms.SetFromFile(f);
978978
DataSet& ds = f.GetDataSet();
979-
gdcm_assert( MediaStorage::IsImage( ms ) );
979+
if (!MediaStorage::IsImage(ms)) {
980+
gdcmWarningMacro("Wrong SOP Class");
981+
}
980982
{
981983
Attribute<0x0028,0x0010> rows;
982984
rows.SetValue( (uint16_t)dims[1] );
@@ -1779,7 +1781,9 @@ void ImageHelper::SetSpacingValue(DataSet & ds, const std::vector<double> & spac
17791781
{
17801782
MediaStorage ms;
17811783
ms.SetFromDataSet(ds);
1782-
gdcm_assert( MediaStorage::IsImage( ms ) );
1784+
if (!MediaStorage::IsImage(ms)) {
1785+
gdcmWarningMacro("Wrong SOP Class");
1786+
}
17831787
if( ms == MediaStorage::SecondaryCaptureImageStorage )
17841788
{
17851789
Tag pixelspacing(0x0028,0x0030);
@@ -2060,7 +2064,10 @@ void ImageHelper::SetOriginValue(DataSet & ds, const Image & image)
20602064
//gdcm_assert( origin.size() == 3 );
20612065
MediaStorage ms;
20622066
ms.SetFromDataSet(ds);
2063-
gdcm_assert( MediaStorage::IsImage( ms ) );
2067+
if (!MediaStorage::IsImage(ms)) {
2068+
gdcmWarningMacro("Wrong SOP Class");
2069+
}
2070+
20642071

20652072
if( ms == MediaStorage::SecondaryCaptureImageStorage && !ImageHelper::SecondaryCaptureImagePlaneModule )
20662073
{
@@ -2212,7 +2219,9 @@ void ImageHelper::SetDirectionCosinesValue(DataSet & ds, const std::vector<doubl
22122219
{
22132220
MediaStorage ms;
22142221
ms.SetFromDataSet(ds);
2215-
gdcm_assert( MediaStorage::IsImage( ms ) );
2222+
if (!MediaStorage::IsImage(ms)) {
2223+
gdcmWarningMacro("Wrong SOP Class");
2224+
}
22162225

22172226
if( ms == MediaStorage::SecondaryCaptureImageStorage && !ImageHelper::SecondaryCaptureImagePlaneModule )
22182227
{
@@ -2358,7 +2367,9 @@ void ImageHelper::SetRescaleInterceptSlopeValue(File & f, const Image & img)
23582367
MediaStorage ms;
23592368
// SetFromFile is required here, SetFromDataSet is not enough for all cases
23602369
ms.SetFromFile(f);
2361-
gdcm_assert( MediaStorage::IsImage( ms ) );
2370+
if (!MediaStorage::IsImage(ms)) {
2371+
gdcmWarningMacro("Wrong SOP Class");
2372+
}
23622373
DataSet &ds = f.GetDataSet();
23632374

23642375
// FIXME Hardcoded

Source/MediaStorageAndFileFormat/gdcmOverlay.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,12 @@ bool Overlay::GrabOverlayFromPixelData(DataSet const &ds)
266266
}
267267
const char *array = bv->GetPointer();
268268
const unsigned int length = ovlength * 8 * 1; //bv->GetLength();
269+
if( length > bv->GetLength() )
270+
{
271+
gdcmWarningMacro("Pixel data buffer too small for overlay extraction (need "
272+
<< length << " bytes, have " << bv->GetLength() << ").");
273+
return false;
274+
}
269275
const uint8_t *p = (const uint8_t*)(const void*)array;
270276
const uint8_t *end = (const uint8_t*)(const void*)(array + length);
271277
gdcm_assert( 8 * ovlength == (unsigned int)Internal->Rows * Internal->Columns );
@@ -317,6 +323,12 @@ bool Overlay::GrabOverlayFromPixelData(DataSet const &ds)
317323
// SIEMENS_GBS_III-16-ACR_NEMA_1.acr is pain to support,
318324
// I cannot simply use the bv->GetLength I have to use the image dim:
319325
const unsigned int length = ovlength * 8 * 2; //bv->GetLength();
326+
if( length > bv->GetLength() )
327+
{
328+
gdcmWarningMacro("Pixel data buffer too small for overlay extraction (need "
329+
<< length << " bytes, have " << bv->GetLength() << ").");
330+
return false;
331+
}
320332
const uint16_t *p = (const uint16_t*)(const void*)array;
321333
const uint16_t *end = (const uint16_t*)(const void*)(array + length);
322334
//const unsigned int ovlength = length / (8*2);

0 commit comments

Comments
 (0)