Skip to content

Commit 176b72c

Browse files
GDCM Upstreamdzenanz
authored andcommitted
GDCM 2025-09-26 (2d66f145)
Code extracted from: https://github.com/malaterre/GDCM.git at commit 2d66f14563fb5e32fd538744f6c9fe532ddd3526 (v3.2.2).
1 parent fe39191 commit 176b72c

File tree

6 files changed

+64
-7
lines changed

6 files changed

+64
-7
lines changed

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.1
13+
VERSION 3.2.2
1414
LANGUAGES CXX C
1515
)
1616
## NOTE: the "DESCRIPTION" feature of project() was introduced in cmake 3.10.0

Source/DataStructureAndEncodingDefinition/gdcmSequenceOfFragments.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ std::istream& ReadValue(std::istream &is, bool /*readvalues*/)
237237
const size_t lastf = Fragments.size() - 1;
238238
const ByteValue *bv = Fragments[ lastf ].GetByteValue();
239239
const char *a = bv->GetPointer();
240-
gdcmAssertAlwaysMacro( (unsigned char)a[ bv->GetLength() - 3 ] == 0xfe );
240+
gdcmAssertAlwaysMacro( bv->GetLength() >= 3 && (unsigned char)a[ bv->GetLength() - 3 ] == 0xfe );
241241
Fragments[ lastf ].SetByteValue( bv->GetPointer(), bv->GetLength() - 3 );
242242
is.seekg( -11, std::ios::cur );
243243
gdcm_assert( is.good() );

Source/MediaStorageAndFileFormat/gdcmPixelFormat.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ bool PixelFormat::Validate()
278278
gdcmDebugMacro( "Bits Stored is 0. Setting is to max value" );
279279
BitsStored = BitsAllocated;
280280
}
281+
if ( HighBit == 0 && BitsStored > 1 )
282+
{
283+
gdcmDebugMacro( "High Bit is 0. Setting is to BitStored - 1" );
284+
HighBit = BitsStored - 1;
285+
}
281286
if ( BitsAllocated == 24 )
282287
{
283288
gdcmDebugMacro( "ACR-NEMA way of storing RGB data. Updating" );

Source/MediaStorageAndFileFormat/gdcmPixelFormat.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ class GDCM_EXPORT PixelFormat
165165
case 0x0ffe: hb = 11; break;
166166
case 0x00fe: hb = 7; break;
167167
}
168-
if( hb < BitsStored )
168+
if( BitsStored > 1 && hb == 0 )
169+
HighBit = BitsStored - 1;
170+
else if( hb < BitsStored )
169171
HighBit = hb;
170172
}
171173

Source/MediaStorageAndFileFormat/gdcmSplitMosaicFilter.cxx

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "gdcmAttribute.h"
1717
#include "gdcmImageHelper.h"
1818
#include "gdcmDirectionCosines.h"
19+
#include "gdcmEquipmentManufacturer.h"
1920

2021
#include <cmath>
2122

@@ -120,14 +121,57 @@ bool SplitMosaicFilter::GetAcquisitionSize(unsigned int size[2], DataSet const &
120121
return found;
121122
}
122123

124+
const DataElement& ComputeCSAHeaderInfo(const DataSet& ds, const PrivateTag &pt, const Tag &hardcodedCsaLocation, bool handleMissingPrivateCreator ) {
125+
if ( handleMissingPrivateCreator && !ds.FindDataElement(pt) ) {
126+
// check hardcoded location first:
127+
if ( ds.FindDataElement(hardcodedCsaLocation) ) {
128+
Attribute<0x0008, 0x0008> imageType;
129+
imageType.SetFromDataSet(ds);
130+
const unsigned int nvalues = imageType.GetNumberOfValues();
131+
const std::string str4 = nvalues >= 5 ? imageType.GetValue(4).Trim() : "";
132+
const char mosaic[] = "MOSAIC";
133+
if ( str4 == mosaic ) {
134+
gdcmWarningMacro( "CSAImageHeaderInfo private creator missing. Using hardcoded location (0029,1010)" );
135+
return ds.GetDataElement(hardcodedCsaLocation);
136+
}
137+
const EquipmentManufacturer::Type manufacturer = EquipmentManufacturer::Compute(ds);
138+
if ( manufacturer == EquipmentManufacturer::SIEMENS ) {
139+
gdcmWarningMacro( "CSAImageHeaderInfo private creator missing. Using hardcoded location (0029,1010)" );
140+
return ds.GetDataElement(hardcodedCsaLocation);
141+
}
142+
}
143+
}
144+
return ds.GetDataElement(pt);
145+
}
146+
147+
// For some reason anoymizer from ADNI DICOM remove the private creator for SIEMENS CSA
148+
// Since dcm2niix has a hardcoded location for SIEMENS CSA tag 0029,1010 we want to reproduce
149+
// the behavior for the average user.
150+
// ref: LEVEY^ADNI3 Basic / Axial rsfMRI (Eyes Open)
151+
// (0029,1008) CS [IMAGE NUM 4] # 12, 1 Unknown Tag & Data
152+
// (0029,1010) OB 53\56\31\30\04\03\02\01\65\00\00\00\4d\00\00\00\45\63\68\6f\4c\69... # 13012, 1 Unknown Tag & Data
153+
// (0029,1018) CS [MR] # 2, 1 Unknown Tag & Data
154+
// (0029,1020) OB 53\56\31\30\04\03\02\01\4f\00\00\00\4d\00\00\00\55\73\65\64\50\61... # 132968, 1 Unknown Tag & Data
155+
const DataElement& SplitMosaicFilter::ComputeCSAImageHeaderInfo(const DataSet& ds, const bool handleMissingPrivateCreator ) {
156+
const PrivateTag &pt = CSAHeader::GetCSAImageHeaderInfoTag();
157+
const Tag hardcodedCsaLocation(0x0029,0x1010);
158+
return ComputeCSAHeaderInfo(ds, pt, hardcodedCsaLocation, handleMissingPrivateCreator);
159+
}
160+
161+
const DataElement& SplitMosaicFilter::ComputeCSASeriesHeaderInfo(const DataSet& ds, const bool handleMissingPrivateCreator ) {
162+
const PrivateTag &pt = CSAHeader::GetCSASeriesHeaderInfoTag();
163+
const Tag hardcodedCsaLocation(0x0029,0x1020);
164+
return ComputeCSAHeaderInfo(ds, pt, hardcodedCsaLocation, handleMissingPrivateCreator);
165+
}
166+
123167
unsigned int SplitMosaicFilter::GetNumberOfImagesInMosaic( File const & file )
124168
{
125169
unsigned int numberOfImagesInMosaic = 0;
126170
DataSet const &ds = file.GetDataSet();
127171
CSAHeader csa;
128172

129-
const PrivateTag &t1 = csa.GetCSAImageHeaderInfoTag();
130-
if( csa.LoadFromDataElement( ds.GetDataElement( t1 ) ) )
173+
const DataElement& csaEl = ComputeCSAImageHeaderInfo( ds ) ;
174+
if( csa.LoadFromDataElement( csaEl ) )
131175
{
132176
if( csa.FindCSAElementByName( "NumberOfImagesInMosaic" ) )
133177
{
@@ -234,9 +278,9 @@ bool SplitMosaicFilter::ComputeMOSAICSliceNormal( double slicenormalvector[3], b
234278

235279
double normal[3];
236280
bool snvfound = false;
237-
const PrivateTag &t1 = csa.GetCSAImageHeaderInfoTag();
238281
static const char snvstr[] = "SliceNormalVector";
239-
if( csa.LoadFromDataElement( ds.GetDataElement( t1 ) ) )
282+
const DataElement& csaEl = ComputeCSAImageHeaderInfo( ds ) ;
283+
if( csa.LoadFromDataElement( csaEl ) )
240284
{
241285
if( csa.FindCSAElementByName( snvstr ) )
242286
{

Source/MediaStorageAndFileFormat/gdcmSplitMosaicFilter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ class GDCM_EXPORT SplitMosaicFilter
8181

8282
/// Return the value for NumberOfImagesInMosaic, or compute it from Acquisition Size
8383
static unsigned int GetNumberOfImagesInMosaic( File const & file );
84+
85+
/// Return the DataElement for the CSA Image Header
86+
static const DataElement& ComputeCSAImageHeaderInfo(const DataSet& ds, bool handleMissingPrivateCreator = true);
87+
88+
/// Return the DataElement for the CSA Series Header
89+
static const DataElement& ComputeCSASeriesHeaderInfo(const DataSet& ds, bool handleMissingPrivateCreator = true);
8490

8591
protected:
8692

0 commit comments

Comments
 (0)