Skip to content

Commit

Permalink
Merge branch 'release'
Browse files Browse the repository at this point in the history
  • Loading branch information
malaterre committed Apr 29, 2024
2 parents 6efa526 + 836f7a7 commit 7ccabc4
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 8 deletions.
10 changes: 5 additions & 5 deletions Source/DataDictionary/gdcmPrivateDefaultDicts.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7418,11 +7418,11 @@ static const DICT_ENTRY DICOMV3DataDict [] = {
/* end of dups */
{0x2005,0x0032,"Philips MR Imaging DD 002",VR::SQ,VM::VM1,"Protocol Data Sequence",false },
{0x2005,0x0034,"Philips MR Imaging DD 002",VR::LT,VM::VM1,"?SeriesTransactionUID?",false },
{0x2005,0x0037,"Philips MR Imaging DD 002",VR::PN,VM::VM1,"Protocol Data Name",false },
{0x2005,0x0038,"Philips MR Imaging DD 002",VR::PN,VM::VM1,"?MRApplicationName",false },
{0x2005,0x0039,"Philips MR Imaging DD 002",VR::PN,VM::VM1,"Protocol Data Type",false },
{0x2005,0x0040,"Philips MR Imaging DD 002",VR::PN,VM::VM1,"?MRVersionStr",false },
{0x2005,0x0041,"Philips MR Imaging DD 002",VR::PN,VM::VM1,"?MRCommentStr",false },
{0x2005,0x0037,"Philips MR Imaging DD 002",VR::LO,VM::VM1,"Protocol Data Name",false },
{0x2005,0x0038,"Philips MR Imaging DD 002",VR::LO,VM::VM1,"?MRApplicationName",false },
{0x2005,0x0039,"Philips MR Imaging DD 002",VR::LO,VM::VM1,"Protocol Data Type",false },
{0x2005,0x0040,"Philips MR Imaging DD 002",VR::LO,VM::VM1,"?MRVersionStr",false },
{0x2005,0x0041,"Philips MR Imaging DD 002",VR::LO,VM::VM1,"?MRCommentStr",false },
{0x2005,0x0043,"Philips MR Imaging DD 002",VR::SL,VM::VM1,"Protocol Data Block Length (non-padded)",false },
{0x2005,0x0044,"Philips MR Imaging DD 002",VR::OW,VM::VM1,"Protocol Data Block",false },
{0x2005,0x0047,"Philips MR Imaging DD 002",VR::CS,VM::VM1,"Protocol Data Boolean",false },
Expand Down
37 changes: 34 additions & 3 deletions Source/MediaStorageAndFileFormat/gdcmImageHelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace gdcm
bool ImageHelper::ForceRescaleInterceptSlope = false;
bool ImageHelper::PMSRescaleInterceptSlope = true;
bool ImageHelper::ForcePixelSpacing = false;
// By default, this is off, if you want behavior documented in DICOM CP 2330, turn it on
bool ImageHelper::SecondaryCaptureImagePlaneModule = false;

static bool GetOriginValueFromSequence(const DataSet& ds, const Tag& tfgs, std::vector<double> &ori)
Expand Down Expand Up @@ -1278,6 +1279,9 @@ Tag ImageHelper::GetSpacingTagFromMediaStorage(MediaStorage const &ms)
if( ImageHelper::SecondaryCaptureImagePlaneModule ) {
// Make SecondaryCaptureImagePlaneModule act as ForcePixelSpacing
// This is different from Basic Pixel Spacing Calibration Macro Attributes
//
// Per the note: https://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_A.8.html#sect_A.8.1.3
gdcmDebugMacro( "FIXME: Multiple tags can identify Secondary Capture spacing. This function should not be used for Secondary Capture data." );
t = Tag(0x0028,0x0030);
} else {
t = Tag(0x0018,0x2010);
Expand Down Expand Up @@ -1372,6 +1376,13 @@ Warning - Dicom dataset contains attributes not present in standard DICOM IOD -
case MediaStorage::UltrasoundMultiFrameImageStorageRetired:
// SC:
case MediaStorage::SecondaryCaptureImageStorage:
// (0018,0088) DS [3] # 2, 1 SpacingBetweenSlices
if( ImageHelper::SecondaryCaptureImagePlaneModule ) {
t = Tag(0x0018,0x0088);
} else {
t = Tag(0xffff,0xffff);
}
break;
case MediaStorage::MultiframeSingleBitSecondaryCaptureImageStorage:
case MediaStorage::MultiframeGrayscaleByteSecondaryCaptureImageStorage:
case MediaStorage::MultiframeGrayscaleWordSecondaryCaptureImageStorage:
Expand Down Expand Up @@ -1471,7 +1482,25 @@ std::vector<double> ImageHelper::GetSpacingValue(File const & f)
}
}

Tag spacingtag = GetSpacingTagFromMediaStorage(ms);
Tag spacingtag = Tag(0xffff,0xffff);
if( ms == MediaStorage::SecondaryCaptureImageStorage && SecondaryCaptureImagePlaneModule )
{
// See the note: https://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_A.8.html#sect_A.8.1.3
if( ds.FindDataElement( Tag(0x0028,0x0030) ) )
{
// Type 1C in 'SC Image' (for calibrated images)
spacingtag = Tag(0x0028,0x0030);
}
else if( ds.FindDataElement( Tag(0x0018,0x2010) ) )
{
// Type 3 in 'SC Image'
spacingtag = Tag(0x0018,0x2010);
}
}
else
{
spacingtag = GetSpacingTagFromMediaStorage(ms);
}
if( spacingtag != Tag(0xffff,0xffff) && ds.FindDataElement( spacingtag ) && !ds.GetDataElement( spacingtag ).IsEmpty() )
{
const DataElement& de = ds.GetDataElement( spacingtag );
Expand Down Expand Up @@ -1972,7 +2001,7 @@ void ImageHelper::SetOriginValue(DataSet & ds, const Image & image)
ms.SetFromDataSet(ds);
assert( MediaStorage::IsImage( ms ) );

if( ms == MediaStorage::SecondaryCaptureImageStorage )
if( ms == MediaStorage::SecondaryCaptureImageStorage && !ImageHelper::SecondaryCaptureImagePlaneModule )
{
// https://sourceforge.net/p/gdcm/bugs/322/
// default behavior is simply to pass
Expand All @@ -1986,6 +2015,7 @@ void ImageHelper::SetOriginValue(DataSet & ds, const Image & image)
&& ms != MediaStorage::PETImageStorage
//&& ms != MediaStorage::ComputedRadiographyImageStorage
&& ms != MediaStorage::SegmentationStorage
&& ms != MediaStorage::SecondaryCaptureImageStorage /* CP 2330 */
&& ms != MediaStorage::MultiframeSingleBitSecondaryCaptureImageStorage
&& ms != MediaStorage::MultiframeGrayscaleByteSecondaryCaptureImageStorage
&& ms != MediaStorage::MultiframeGrayscaleWordSecondaryCaptureImageStorage
Expand Down Expand Up @@ -2123,7 +2153,7 @@ void ImageHelper::SetDirectionCosinesValue(DataSet & ds, const std::vector<doubl
ms.SetFromDataSet(ds);
assert( MediaStorage::IsImage( ms ) );

if( ms == MediaStorage::SecondaryCaptureImageStorage )
if( ms == MediaStorage::SecondaryCaptureImageStorage && !ImageHelper::SecondaryCaptureImagePlaneModule )
{
// https://sourceforge.net/p/gdcm/bugs/322/
// default behavior is simply to pass
Expand All @@ -2136,6 +2166,7 @@ void ImageHelper::SetDirectionCosinesValue(DataSet & ds, const std::vector<doubl
&& ms != MediaStorage::RTDoseStorage
&& ms != MediaStorage::PETImageStorage
//&& ms != MediaStorage::ComputedRadiographyImageStorage
&& ms != MediaStorage::SecondaryCaptureImageStorage /* CP 2330 */
&& ms != MediaStorage::MultiframeSingleBitSecondaryCaptureImageStorage
&& ms != MediaStorage::MultiframeGrayscaleByteSecondaryCaptureImageStorage
&& ms != MediaStorage::MultiframeGrayscaleWordSecondaryCaptureImageStorage
Expand Down
1 change: 1 addition & 0 deletions Source/MediaStorageAndFileFormat/gdcmImageHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class GDCM_EXPORT ImageHelper

/// Set/Get Spacing from/to a File
static std::vector<double> GetSpacingValue(File const & f);
/// \warning You need to call SetSpacingValue after SetOriginValue / SetDirectionCosinesValue
static void SetSpacingValue(DataSet & ds, const std::vector<double> & spacing);

/// DO NOT USE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ set(MSFF_TEST_SRCS
TestOrientation.cxx
TestIconImage.cxx
TestImageHelper.cxx
TestImageHelper3.cxx
TestImageToImageFilter.cxx
TestImageChangeTransferSyntax1.cxx
#TestImageChangePhotometricInterpretation.cxx
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

int TestImageHelper(int, char *[])
{
// Test written before DICOM CP 2330,
if( gdcm::ImageHelper::GetSecondaryCaptureImagePlaneModule() ) return 1;
// gdcm::ImageHelper sh;
const double pos[] = { 0,0,0,
1,1,1};
Expand Down
124 changes: 124 additions & 0 deletions Testing/Source/MediaStorageAndFileFormat/Cxx/TestImageHelper3.cxx
Original file line number Diff line number Diff line change
@@ -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.
=========================================================================*/
#include "gdcmImageHelper.h"
#include "gdcmMediaStorage.h"
#include "gdcmDataSet.h"
#include "gdcmAttribute.h"
#include "gdcmDirectionCosines.h"
#include "gdcmImage.h"
#include "gdcmFile.h"

int TestImageHelper3(int, char *[])
{

std::vector<double> impos;
impos.resize(3);
impos[0] = 1;
impos[1] = 2;
impos[2] = 3;
std::vector<double> spacing;
spacing.resize(3);
spacing[0] = 0.6;
spacing[1] = 0.5;
spacing[2] = 0.4;

std::vector<double> dircos;
dircos.resize(6);
dircos[0] = 0;
dircos[1] = 1;
dircos[2] = 0;
dircos[3] = 1;
dircos[4] = 0;
dircos[5] = 0;

gdcm::Image img;
img.SetNumberOfDimensions(3);
img.SetOrigin( impos.data() );
img.SetSpacing( spacing.data() );
img.SetDirectionCosines( dircos.data() );
// Try SC
gdcm::File file;
{
gdcm::ImageHelper::SetSecondaryCaptureImagePlaneModule( false );
gdcm::MediaStorage ms( gdcm::MediaStorage::SecondaryCaptureImageStorage );
gdcm::DataSet&ds = file.GetDataSet();

gdcm::DataElement de( gdcm::Tag(0x0008, 0x0016) );
const char* msstr = gdcm::MediaStorage::GetMSString(ms);
de.SetByteValue( msstr, (uint32_t)strlen(msstr) );
de.SetVR( gdcm::Attribute<0x0008, 0x0016>::GetVR() );
ds.Insert( de );

gdcm::ImageHelper::SetDirectionCosinesValue( ds, dircos );
gdcm::ImageHelper::SetOriginValue( ds, img );
gdcm::ImageHelper::SetSpacingValue( ds, spacing );

std::cout << ds << std::endl;

gdcm::Tag nominal(0x0018,0x2010 );
if( !ds.FindDataElement( nominal ) ) return 1;
gdcm::Tag iop(0x0020,0x0037);
if( ds.FindDataElement( iop ) ) return 1;

std::vector<double> ret = gdcm::ImageHelper::GetSpacingValue( file );
// warning;: only two dim:
if( ret[0] != spacing[0] || ret[1] != spacing[1] ) {
std::cerr << ret[0] << "," << ret[1] << std::endl;
return 1;
}
}
gdcm::File cp2330file;
{
// New CP 2330 behavior
gdcm::ImageHelper::SetSecondaryCaptureImagePlaneModule( true );
gdcm::MediaStorage ms( gdcm::MediaStorage::SecondaryCaptureImageStorage );
gdcm::DataSet&ds = cp2330file.GetDataSet();

gdcm::DataElement de( gdcm::Tag(0x0008, 0x0016) );
const char* msstr = gdcm::MediaStorage::GetMSString(ms);
de.SetByteValue( msstr, (uint32_t)strlen(msstr) );
de.SetVR( gdcm::Attribute<0x0008, 0x0016>::GetVR() );
ds.Insert( de );

// New CP 2330 behavior
gdcm::ImageHelper::SetDirectionCosinesValue( ds, dircos );
gdcm::ImageHelper::SetOriginValue( ds, img );
gdcm::ImageHelper::SetSpacingValue( ds, spacing );

std::cout << ds << std::endl;

// previous call added the attribute
gdcm::Tag pixelspacing(0x0028,0x0030);
if( !ds.FindDataElement( pixelspacing ) ) return 1;
gdcm::Tag iop(0x0020,0x0037);
if( !ds.FindDataElement( iop ) ) return 1;

std::vector<double> ret = gdcm::ImageHelper::GetSpacingValue( cp2330file );
if( ret != spacing ) {
std::cerr << ret[0] << "," << ret[1] << "," << ret[2] << std::endl;
return 1;
}
// make sure legacy still works:
ret = gdcm::ImageHelper::GetSpacingValue( file );
if( ret[0] != spacing[0] || ret[1] != spacing[1] || ret[2] != 1 ) {
std::cerr << ret[0] << "," << ret[1] << std::endl;
return 1;
}

}


std::cout << "success" << std::endl;
return 0;
}

0 comments on commit 7ccabc4

Please sign in to comment.