diff --git a/Source/MediaStorageAndFileFormat/gdcmEquipmentManufacturer.cxx b/Source/MediaStorageAndFileFormat/gdcmEquipmentManufacturer.cxx index 9626a53f2..d95dffb7c 100644 --- a/Source/MediaStorageAndFileFormat/gdcmEquipmentManufacturer.cxx +++ b/Source/MediaStorageAndFileFormat/gdcmEquipmentManufacturer.cxx @@ -16,112 +16,236 @@ #include "gdcmAttribute.h" #include "gdcmSystem.h" -namespace gdcm -{ - -static const char *TypeStrings[] = { - "UNKNOWN", - "FUJI", - "GEMS", - "HITACHI", - "KODAK", - "MARCONI", - "PMS", - "SIEMENS", - "TOSHIBA" -}; +namespace gdcm { + +// FIXME: fuji and hitachi are the same now +static const char* TypeStrings[] = {"UNKNOWN", "FUJI", "GEMS", "HITACHI", + "KODAK", "MARCONI", "PMS", "SIEMENS", + "TOSHIBA", "AGFA", "SAMSUNG", "UIH"}; -const char *EquipmentManufacturer::TypeToString( Type type ) -{ +const char* EquipmentManufacturer::TypeToString(Type type) { return TypeStrings[type]; } -struct Mapping -{ +struct Mapping { EquipmentManufacturer::Type type; size_t nstrings; - const char* const *strings; + const char* const* strings; }; -static const char* const fuji[] = {"FUJI", "FUJI PHOTO FILM Co., ltd.","FUJIFILM Corporation","FUJI PHOTO FILM CO. LTD."}; -static const char* const gems[] = {"GE MEDICAL SYSTEMS", "GE_MEDICAL_SYSTEMS", "GE Healthcare", "G.E. Medical Systems","GE Vingmed Ultrasound","\"GE Healthcare\""/*sigh*/}; -static const char* const hitachi[] = {"Hitachi Medical Corporation","ALOKA CO., LTD."}; +static const char* const agfa[] = {"Agfa"}; +static const char* const fuji[] = {"FUJI", + "FUJI PHOTO FILM Co., ltd.", + "FUJIFILM Healthcare Corporation", + "FUJIFILM SonoSite", + "FUJIFILM Corporation", + "FUJI PHOTO FILM CO. LTD."}; +static const char* const gems[] = {"GE MEDICAL SYSTEMS", + "GE_MEDICAL_SYSTEMS", + "GE Healthcare", + "G.E. Medical Systems", + "GE Healthcare IT Cardiology", + "GE Healthcare Austria GmbH & Co OG", + "GE Healthcare Ultrasound", + "GE MEDICAL SYSTEMS, NUCLEAR", + "GEMS Ultrasound", + "GE OEC Medical Systems GmbH", + "GE Vingmed Ultrasound", + "\"GE Healthcare\"" /*sigh*/}; +static const char* const hitachi[] = {"Hitachi Medical Corporation", + "Hitachi, Ltd.", "ALOKA CO., LTD."}; static const char* const kodak[] = {"Kodak"}; -static const char* const pms[] = { "Philips Medical Systems", "Philips Healthcare", "Philips Medical Systems, Inc.","Philips","Picker International, Inc." }; -static const char* const siemens[] = { "Siemens Healthineers", "SIEMENS", "Siemens HealthCare GmbH", "Siemens Health Services","Acuson" }; -static const char* const marconi[] = { "Marconi Medical Systems, Inc." }; -static const char* const toshiba[] = { "TOSHIBA_MEC", "Toshiba" }; - -#define ARRAY_SIZE( X ) \ - sizeof(X) / sizeof(*X) +static const char* const pms[] = { + "Philips Medical Systems", "Philips Healthcare", + "Philips Medical Systems, Inc.", "Philips", "Picker International, Inc."}; +static const char* const siemens[] = {"Siemens Healthineers", + "SIEMENS", + "SIEMENS NM", + "Siemens HealthCare GmbH", + "Siemens Health Services", + "Acuson"}; +static const char* const marconi[] = {"Marconi Medical Systems, Inc."}; +static const char* const samsung[] = {"SAMSUNG MEDISON CO., LTD.", + "SAMSUNG MEDISON CO.,LTD." /*sigh*/}; +static const char* const toshiba[] = {"TOSHIBA_MEC", "CANON_MEC", + "TOSHIBA_MEC_US", + "Toshiba"}; // must include canon +static const char* const uih[] = {"UIH"}; // United Imaging Healthcare + +#define ARRAY_SIZE(X) sizeof(X) / sizeof(*X) #define MAPPING(X, Y) \ { X, ARRAY_SIZE(Y), Y } static const Mapping mappings[] = { - MAPPING( EquipmentManufacturer::FUJI, fuji ), - MAPPING( EquipmentManufacturer::GEMS, gems ), - MAPPING( EquipmentManufacturer::HITACHI, hitachi ), - MAPPING( EquipmentManufacturer::KODAK, kodak ), - MAPPING( EquipmentManufacturer::PMS, pms ), - MAPPING( EquipmentManufacturer::SIEMENS, siemens ), - MAPPING( EquipmentManufacturer::MARCONI, marconi ), - MAPPING( EquipmentManufacturer::TOSHIBA, toshiba ) -}; + MAPPING(EquipmentManufacturer::AGFA, agfa), + MAPPING(EquipmentManufacturer::FUJI, fuji), + MAPPING(EquipmentManufacturer::GEMS, gems), + MAPPING(EquipmentManufacturer::HITACHI, hitachi), + MAPPING(EquipmentManufacturer::KODAK, kodak), + MAPPING(EquipmentManufacturer::PMS, pms), + MAPPING(EquipmentManufacturer::SIEMENS, siemens), + MAPPING(EquipmentManufacturer::MARCONI, marconi), + MAPPING(EquipmentManufacturer::SAMSUNG, samsung), + MAPPING(EquipmentManufacturer::TOSHIBA, toshiba), + MAPPING(EquipmentManufacturer::UIH, uih)}; + +// long story short, private creator could be moved around, what we are trying +// to achieve here is true modality check, so generally they should not have +// been moved in the process. +static bool IsPrivateCreatorFound(DataSet const& ds, Tag const& private_tag, + std::string const& creator_value) { + if (ds.FindDataElement(private_tag)) { + const DataElement& de = ds.GetDataElement(private_tag); + Element priv_creator; + priv_creator.SetFromDataElement(de); + if (priv_creator.GetValue().Trim() == creator_value) return true; + } + return false; +} -EquipmentManufacturer::Type EquipmentManufacturer::GuessFromPrivateAttributes( DataSet const & ds ) -{ +template +static std::string GetPrivateTagValueOrEmpty(DataSet const& ds, + PrivateTag const& pt) { + if (ds.FindDataElement(pt)) { + const DataElement& de = ds.GetDataElement(pt); + Element value = {""}; + value.SetFromDataElement(de); + return value.GetValue().Trim(); + } + return ""; +} + +EquipmentManufacturer::Type EquipmentManufacturer::GuessFromPrivateAttributes( + DataSet const& ds) { // try against with well known private tag: // watch out for private creator such as ELSCINT1 which can be found in // GEMS/PEMS and maybe even SIEMENS ! - gdcm::Tag gems_iden_01(0x0009,0x0010); - if( ds.FindDataElement( gems_iden_01 ) ) - { - const gdcm::DataElement & de = ds.GetDataElement( gems_iden_01 ); - gdcm::Element priv_creator; - priv_creator.SetFromDataElement( de ); - if( priv_creator.GetValue() == "GEMS_IDEN_01" ) return GEMS; - if( priv_creator.GetValue() == "GEMS_PETD_01" ) return GEMS; - } - - gdcm::PrivateTag siemens_manu(0x0021,0x0022,"SIEMENS MR SDS 01"); - if( ds.FindDataElement( siemens_manu ) ) - { - const gdcm::DataElement & de = ds.GetDataElement( siemens_manu ); - gdcm::Element value; - value.SetFromDataElement( de ); - if( value.GetValue().Trim() == "SIEMENS" ) return SIEMENS; - } + // Try to prefer those listed at: + // https://dicom.nema.org/medical/dicom/current/output/chtml/part15/sect_E.3.10.html#table_E.3.10-1 + if (ds.FindDataElement(PrivateTag(0x0019, 0x0023, "GEMS_ACQU_01")) || + ds.FindDataElement(PrivateTag(0x0043, 0x0039, "GEMS_PARM_01")) || + ds.FindDataElement(PrivateTag(0x0045, 0x0001, "GEMS_HELIOS_01")) || + ds.FindDataElement(PrivateTag(0x0025, 0x001b, "GEMS_SERS_01")) + /* extra */ + || ds.FindDataElement( + PrivateTag(0x6003, 0x0010, "GEMS_Ultrasound_ImageGroup_001")) || + ds.FindDataElement(PrivateTag(0x0019, 0x0007, "DLX_SERIE_01")) || + ds.FindDataElement(PrivateTag(0x0009, 0x0001, "GEMS_GENIE_1")) || + ds.FindDataElement(PrivateTag(0x0011, 0x0003, "GEMS_GDXE_FALCON_04"))) + return GEMS; + +#if 0 + if (IsPrivateCreatorFound(ds, Tag(0x0025, 0x0010), "GEMS_IDEN_01") || + IsPrivateCreatorFound(ds, Tag(0x0009, 0x0010), "GEMS_IDEN_01") || + IsPrivateCreatorFound(ds, Tag(0x0009, 0x0010), "GEMS_GENIE_1") || + IsPrivateCreatorFound(ds, Tag(0x0009, 0x0010), "GEMS_PETD_01")) + return GEMS; +#endif + + // Philips: + if (ds.FindDataElement( + PrivateTag(0x2005, 0x000d, "Philips MR Imaging DD 001")) || + ds.FindDataElement( + PrivateTag(0x2005, 0x000e, "Philips MR Imaging DD 001")) || + ds.FindDataElement( + PrivateTag(0x2001, 0x0003, "Philips Imaging DD 001")) || + ds.FindDataElement(PrivateTag(0x2001, 0x005f, "Philips Imaging DD 001"))) + return PMS; +#if 0 + if (IsPrivateCreatorFound(ds, Tag(0x2005, 0x0014), + "Philips MR Imaging DD 005")) + return PMS; +#endif + if (IsPrivateCreatorFound(ds, Tag(0x0019, 0x0010), "PHILIPS MR/PART") && + IsPrivateCreatorFound(ds, Tag(0x0021, 0x0010), "PHILIPS MR/PART")) + return PMS; + if (IsPrivateCreatorFound(ds, Tag(0x0009, 0x0010), "SPI-P Release 1") && + IsPrivateCreatorFound(ds, Tag(0x0019, 0x0010), "SPI-P Release 1")) + return PMS; + + // Siemens: + if (ds.FindDataElement(PrivateTag(0x0029, 0x0010, "SIEMENS CSA HEADER")) || + ds.FindDataElement(PrivateTag(0x0029, 0x0020, "SIEMENS CSA HEADER")) || + ds.FindDataElement(PrivateTag(0x0029, 0x0010, "SIEMENS MEDCOM OOG")) || + ds.FindDataElement( + PrivateTag(0x7fdf, 0x0000, "ACUSON:1.2.840.113680.1.0:7ffe")) || + ds.FindDataElement(PrivateTag(0x0019, 0x0012, "SIEMENS CM VA0 ACQU")) || + ds.FindDataElement(PrivateTag(0x0009, 0x0010, "SIEMENS CT VA0 IDE"))) + return SIEMENS; +#if 0 + if (GetPrivateTagValueOrEmpty( + ds, PrivateTag(0x0021, 0x0022, "SIEMENS MR SDS 01")) == "SIEMENS") + return SIEMENS; + // gdcm-MR-SIEMENS-16-2.acr + if (GetPrivateTagValueOrEmpty( + ds, PrivateTag(0x0019, 0x0012, "SIEMENS CM VA0 ACQU")) == "SIEMENS") + return SIEMENS; +#endif + + // toshiba: + if (ds.FindDataElement(PrivateTag(0x7005, 0x0008, "TOSHIBA_MEC_CT3")) || + ds.FindDataElement(PrivateTag(0x700d, 0x0008, "TOSHIBA_MEC_MR3")) || + ds.FindDataElement(PrivateTag(0x0029, 0x0001, "PMTF INFORMATION DATA")) || + ds.FindDataElement(PrivateTag(0x0029, 0x0001, "CANON_MEC_MR3")) || + ds.FindDataElement(PrivateTag(0x0029, 0x0001, "TOSHIBA_MEC_MR3"))) + return TOSHIBA; + // fuji + if (ds.FindDataElement(PrivateTag(0x0021, 0x0010, "FDMS 1.0"))) return FUJI; + // hitachi + if (ds.FindDataElement(PrivateTag(0x0009, 0x0000, "HMC - CT - ID")) || + ds.FindDataElement(PrivateTag(0x0009, 0x0003, "MMCPrivate")) || + ds.FindDataElement(PrivateTag(0x0009, 0x0050, "MMCPrivate")) || + ds.FindDataElement(PrivateTag(0x0019, 0x000e, "MMCPrivate")) || + ds.FindDataElement(PrivateTag(0x0019, 0x0021, "MMCPrivate")) || + ds.FindDataElement(PrivateTag(0x0029, 0x002f, "MMCPrivate")) || + ds.FindDataElement(PrivateTag(0x0029, 0x00d7, "MMCPrivate"))) + return HITACHI; + // UIH + if (ds.FindDataElement(PrivateTag(0x0065, 0x000a, "Image Private Header"))) + return UIH; return UNKNOWN; } -EquipmentManufacturer::Type EquipmentManufacturer::Compute( DataSet const & ds ) -{ - EquipmentManufacturer::Type ret = GuessFromPrivateAttributes( ds ); +EquipmentManufacturer::Type EquipmentManufacturer::Compute(DataSet const& ds) { + EquipmentManufacturer::Type ret = GuessFromPrivateAttributes(ds); // proper anonymizer should not touch Manufacturer attribute value: // http://dicom.nema.org/medical/dicom/current/output/chtml/part15/chapter_E.html#table_E.1-1 - gdcm::Attribute<0x0008,0x0070> manu = { "" }; // Manufacturer - manu.SetFromDataSet( ds ); - const std::string manufacturer = manu.GetValue().Trim(); - for( const Mapping * mapping = mappings; mapping != mappings + ARRAY_SIZE(mappings); ++mapping ) - { - for( size_t i = 0; i < mapping->nstrings; ++i ) - { - // case insensitive to handle: "GE MEDICAL SYSTEMS" vs "GE Medical Systems" - if( System::StrCaseCmp( mapping->strings[i], manufacturer.c_str() ) == 0 ) { - if( ret != UNKNOWN && ret != mapping->type ) { - gdcmErrorMacro(" Impossible happen: " << ret << " vs " << mapping->type ); - return UNKNOWN; + Attribute<0x0008, 0x0070> manu = {""}; // Manufacturer + std::string manufacturer; + if (ds.FindDataElement(manu.GetTag())) { + manu.SetFromDataSet(ds); + manufacturer = manu.GetValue().Trim(); + // TODO: contributing equipement ? + } else { + // MFSPLIT export seems to remove the attribute completely: + manufacturer = GetPrivateTagValueOrEmpty( + ds, PrivateTag(0x0021, 0x0022, "SIEMENS MR SDS 01")); + } + if (!manufacturer.empty()) { + for (const Mapping* mapping = mappings; + mapping != mappings + ARRAY_SIZE(mappings); ++mapping) { + for (size_t i = 0; i < mapping->nstrings; ++i) { + // case insensitive to handle: "GE MEDICAL SYSTEMS" vs "GE Medical + // Systems" + if (System::StrCaseCmp(mapping->strings[i], manufacturer.c_str()) == + 0) { + if (ret != UNKNOWN && ret != mapping->type) { + gdcmErrorMacro(" Impossible happen: " << ret << " vs " + << mapping->type); + return UNKNOWN; + } + return mapping->type; } - return mapping->type; } } } - gdcmWarningMacro( "Unknown Manufacturer [" << manufacturer << "] trying guess." ); + gdcmWarningMacro("Unknown Manufacturer [" << manufacturer + << "] trying guess."); return ret; } -} // end namespace gdcm +} // end namespace gdcm diff --git a/Source/MediaStorageAndFileFormat/gdcmEquipmentManufacturer.h b/Source/MediaStorageAndFileFormat/gdcmEquipmentManufacturer.h index fde8cf528..6b835306e 100644 --- a/Source/MediaStorageAndFileFormat/gdcmEquipmentManufacturer.h +++ b/Source/MediaStorageAndFileFormat/gdcmEquipmentManufacturer.h @@ -16,41 +16,42 @@ #include "gdcmTypes.h" -namespace gdcm -{ +namespace gdcm { class DataSet; /** - * \brief - * \details + * \brief + * \details * The intent is for private tags handling. This class is not meant to handle * all possible vendors in the world, simply those well known where we intend * to read private tags afterwards (typically SIEMENS+CSA, GEMS+PDB ...) */ -class GDCM_EXPORT EquipmentManufacturer -{ -public: - +class GDCM_EXPORT EquipmentManufacturer { + public: typedef enum { UNKNOWN = 0, - FUJI, - GEMS, - HITACHI, - KODAK, - MARCONI, - PMS, - SIEMENS, - TOSHIBA + FUJI = 1, + GEMS = 2, + HITACHI = 3, + KODAK = 4, + MARCONI = 5, + PMS = 6, + SIEMENS = 7, + TOSHIBA = 8, + AGFA = 9, + SAMSUNG = 10, + UIH = 11 } Type; - static Type Compute( DataSet const & ds ); + static Type Compute(DataSet const &ds); - static const char *TypeToString( Type type ); + static const char *TypeToString(Type type); -private: - static EquipmentManufacturer::Type GuessFromPrivateAttributes( DataSet const & ds ); + private: + static EquipmentManufacturer::Type GuessFromPrivateAttributes( + DataSet const &ds); }; -} // end namespace gdcm +} // end namespace gdcm -#endif // GDCMEQUIPMENTMANUFACTURER_H +#endif // GDCMEQUIPMENTMANUFACTURER_H diff --git a/Testing/Source/MediaStorageAndFileFormat/Cxx/TestEquipmentManufacturer.cxx b/Testing/Source/MediaStorageAndFileFormat/Cxx/TestEquipmentManufacturer.cxx index 16a81de09..15be21d1b 100644 --- a/Testing/Source/MediaStorageAndFileFormat/Cxx/TestEquipmentManufacturer.cxx +++ b/Testing/Source/MediaStorageAndFileFormat/Cxx/TestEquipmentManufacturer.cxx @@ -12,110 +12,150 @@ =========================================================================*/ #include "gdcmEquipmentManufacturer.h" -#include "gdcmReader.h" #include "gdcmFilename.h" +#include "gdcmReader.h" #include "gdcmTesting.h" -static int TestEquipmentManufacturerFunc(const char* filename, bool verbose = false) -{ - if( verbose ) - std::cerr << "Reading: " << filename << std::endl; +static int TestEquipmentManufacturerFunc(const char *filename, + bool verbose = false) { + if (verbose) std::cerr << "Reading: " << filename << std::endl; const gdcm::Tag pixeldata(0x7fe0, 0x0010); gdcm::Reader reader; - reader.SetFileName( filename ); - if (!reader.ReadUpToTag(pixeldata)) - { + reader.SetFileName(filename); + if (!reader.ReadUpToTag(pixeldata)) { std::cerr << "TestReadError: Failed to read: " << filename << std::endl; return 1; - } + } - const gdcm::File & file = reader.GetFile(); + gdcm::File &file = reader.GetFile(); gdcm::MediaStorage ms; - ms.SetFromFile( file ); - if(ms == gdcm::MediaStorage::MediaStorageDirectoryStorage) return 0; // skip DICOMDIR + ms.SetFromFile(file); + if (ms == gdcm::MediaStorage::MediaStorageDirectoryStorage) + return 0; // skip DICOMDIR - gdcm::Filename fn( filename ); + gdcm::Filename fn(filename); const char *name = fn.GetName(); // Special handling: - if( strcmp(name, "OsirixFake16BitsStoredFakeSpacing.dcm" ) == 0 - || strcmp(name, "simpleImageWithIcon.dcm" ) == 0 - || strcmp(name, "rle16sti.dcm" ) == 0 - || strcmp(name, "rle16loo.dcm" ) == 0 - || strcmp(name, "gdcm-CR-DCMTK-16-NonSamplePerPix.dcm" ) == 0 - || strcmp(name, "XA-MONO2-8-12x-catheter.dcm" ) == 0 - || strcmp(name, "US-RGB-8-esopecho.dcm" ) == 0 - || strcmp(name, "US-PAL-8-10x-echo.dcm" ) == 0 - || strcmp(name, "US-MONO2-8-8x-execho.dcm" ) == 0 - || strcmp(name, "THERALYS-12-MONO2-Uncompressed-Even_Length_Tag.dcm" ) == 0 - || strcmp(name, "SignedShortLosslessBug.dcm" ) == 0 - || strcmp(name, "SC16BitsAllocated_8BitsStoredJPEG.dcm" ) == 0 - || strcmp(name, "SC16BitsAllocated_8BitsStoredJ2K.dcm" ) == 0 - || strcmp(name, "RadBWLossLess.dcm" ) == 0 - || strcmp(name, "RLEDebianBug816607Orig.dcm" ) == 0 - || strcmp(name, "DermaColorLossLess.dcm" ) == 0 - || strcmp(name, "00191113.dcm" ) == 0 - || strcmp(name, "test.acr" ) == 0 - || strcmp(name, "LIBIDO-8-ACR_NEMA-Lena_128_128.acr" ) == 0 - || strcmp(name, "gdcm-ACR-LibIDO.acr" ) == 0 - || strcmp(name, "libido1.0-vol.acr" ) == 0 - || strcmp(name, "DCMTK_JPEGExt_12Bits.dcm" ) == 0 - || strcmp(name, "DMCPACS_ExplicitImplicit_BogusIOP.dcm" ) == 0 - || strcmp(name, "DX_J2K_0Padding.dcm" ) == 0 - || strcmp(name, "GDCMJ2K_TextGBR.dcm" ) == 0 - || strcmp(name, "ITK_GDCM124_MultiframeSecondaryCaptureInvalid.dcm" ) == 0 - || strcmp(name, "JPEGLS_CharLS_10742.dcm" ) == 0 - || strcmp(name, "JPEGLosslessYBR_FULL_422.dcm" ) == 0 - || strcmp(name, "JPEGLosslessSeNonZero.dcm" ) == 0 - || strcmp(name, "US-YBR_FULL_422-EVRLE.dcm" ) == 0 - || strcmp(name, "LIBIDO-24-ACR_NEMA-Rectangle.dcm" ) == 0 - || strcmp(name, "MR-Brucker-CineTagging-NonSquarePixels.dcm" ) == 0 - || strcmp(name, "MR16BitsAllocated_8BitsStored.dcm" ) == 0 - || strcmp(name, "NM-MONO2-16-13x-heart.dcm" ) == 0 - || strcmp(name, "NM-PAL-16-PixRep1.dcm" ) == 0 - || strcmp(name, "NM_Kakadu44_SOTmarkerincons.dcm" ) == 0 - || strcmp(name, "PICKER-16-MONO2-No_DicomV3_Preamble.dcm" ) == 0 - || strcmp(name, "OT-PAL-8-face.dcm" ) == 0 - || strcmp(name, "TG18-CH-2k-01.dcm" ) == 0 // wotsit ? - || strcmp(name, "HardcopyColor_YBR_RCT_J2K_PC1.dcm" ) == 0 // RamSoft Inc. - || strncmp(name, "D_CLUNIE", 8) == 0 // D_CLUNIE* - || strncmp(name, "LEADTOOLS_FLOWERS", 17) == 0 // LEADTOOLS_FLOWERS* - || strncmp(name, "JDDICOM", 7) == 0 // JDDICOM* - || strncmp(name, "JPEGNote", 8) == 0 // JPEGNote* - || strncmp(name, "KODAK", 5) == 0 // KODAK* - || strncmp(name, "DICOMDIR", 8) == 0 // DICOMDIR* - || strncmp(name, "dicomdir", 8) == 0 // dicomdir* - ) - { - if( verbose ) - std::cout << "skip: " << filename << std::endl; + if (strcmp(name, "OsirixFake16BitsStoredFakeSpacing.dcm") == 0 || + strcmp(name, "simpleImageWithIcon.dcm") == 0 || + strcmp(name, "rle16sti.dcm") == 0 || strcmp(name, "rle16loo.dcm") == 0 || + strcmp(name, "gdcm-CR-DCMTK-16-NonSamplePerPix.dcm") == 0 || + strcmp(name, "XA-MONO2-8-12x-catheter.dcm") == 0 || + strcmp(name, "US-RGB-8-esopecho.dcm") == 0 || + strcmp(name, "US-PAL-8-10x-echo.dcm") == 0 || + strcmp(name, "US-MONO2-8-8x-execho.dcm") == 0 || + strcmp(name, "THERALYS-12-MONO2-Uncompressed-Even_Length_Tag.dcm") == 0 || + strcmp(name, "SignedShortLosslessBug.dcm") == 0 || + strcmp(name, "SC16BitsAllocated_8BitsStoredJPEG.dcm") == 0 || + strcmp(name, "SC16BitsAllocated_8BitsStoredJ2K.dcm") == 0 || + strcmp(name, "RadBWLossLess.dcm") == 0 || + strcmp(name, "RLEDebianBug816607Orig.dcm") == 0 || + strcmp(name, "DermaColorLossLess.dcm") == 0 || + strcmp(name, "00191113.dcm") == 0 || strcmp(name, "test.acr") == 0 || + strcmp(name, "MARCONI_MxTWin-12-MONO2-JpegLossless-ZeroLengthSQ.dcm") == + 0 || + strcmp(name, "PICKER-16-MONO2-Nested_icon.dcm") == 0 || + strcmp(name, "MR_ELSCINT1_00e1_1042_SQ_feff_00e0_Item.dcm") == 0 || + strcmp(name, "PrivateGEImplicitVRBigEndianTransferSyntax16Bits.dcm") == + 0 || + strcmp(name, "LIBIDO-8-ACR_NEMA-Lena_128_128.acr") == 0 || + strcmp(name, "gdcm-ACR-LibIDO.acr") == 0 || + strcmp(name, "libido1.0-vol.acr") == 0 || + strcmp(name, "DCMTK_JPEGExt_12Bits.dcm") == 0 || + strcmp(name, "DMCPACS_ExplicitImplicit_BogusIOP.dcm") == 0 || + strcmp(name, "DX_J2K_0Padding.dcm") == 0 || + strcmp(name, "GDCMJ2K_TextGBR.dcm") == 0 || + strcmp(name, "ITK_GDCM124_MultiframeSecondaryCaptureInvalid.dcm") == 0 || + strcmp(name, "JPEGLS_CharLS_10742.dcm") == 0 || + strcmp(name, "JPEGLosslessYBR_FULL_422.dcm") == 0 || + strcmp(name, "JPEGLosslessSeNonZero.dcm") == 0 || + strcmp(name, "US-YBR_FULL_422-EVRLE.dcm") == 0 || + strcmp(name, "LIBIDO-24-ACR_NEMA-Rectangle.dcm") == 0 || + strcmp(name, "MR-Brucker-CineTagging-NonSquarePixels.dcm") == 0 || + strcmp(name, "MR16BitsAllocated_8BitsStored.dcm") == 0 || + strcmp(name, "NM-MONO2-16-13x-heart.dcm") == 0 || + strcmp(name, "NM-PAL-16-PixRep1.dcm") == 0 || + strcmp(name, "NM_Kakadu44_SOTmarkerincons.dcm") == 0 || + strcmp(name, "PICKER-16-MONO2-No_DicomV3_Preamble.dcm") == 0 || + strcmp(name, "OT-PAL-8-face.dcm") == 0 || + strcmp(name, "TG18-CH-2k-01.dcm") == 0 // wotsit ? + || strcmp(name, "HardcopyColor_YBR_RCT_J2K_PC1.dcm") == 0 // RamSoft Inc. + || strncmp(name, "D_CLUNIE", 8) == 0 // D_CLUNIE* + || strncmp(name, "LEADTOOLS_FLOWERS", 17) == 0 // LEADTOOLS_FLOWERS* + || strncmp(name, "JDDICOM", 7) == 0 // JDDICOM* + || strncmp(name, "JPEGNote", 8) == 0 // JPEGNote* + || strncmp(name, "KODAK", 5) == 0 // KODAK* + || strncmp(name, "DICOMDIR", 8) == 0 // DICOMDIR* + || strncmp(name, "dicomdir", 8) == 0 // dicomdir* + ) { + if (verbose) std::cout << "skip: " << filename << std::endl; return 0; - } + } - const gdcm::DataSet & ds = file.GetDataSet(); - gdcm::EquipmentManufacturer::Type manufacturer = gdcm::EquipmentManufacturer::Compute( ds ); - if( verbose ) - { - std::cout << "Found: " << gdcm::EquipmentManufacturer::TypeToString(manufacturer) << " -> " << manufacturer << std::endl; - } - if( manufacturer == gdcm::EquipmentManufacturer::UNKNOWN ) - { + gdcm::DataSet &ds = file.GetDataSet(); + gdcm::EquipmentManufacturer::Type manufacturer = + gdcm::EquipmentManufacturer::Compute(ds); + if (verbose) { + std::cout << "Found: " + << gdcm::EquipmentManufacturer::TypeToString(manufacturer) + << " -> " << manufacturer << std::endl; + } + if (manufacturer == gdcm::EquipmentManufacturer::UNKNOWN) { std::cerr << "Unknown: " << filename << std::endl; return 1; + } + ds.Remove(gdcm::Tag(0x8, 0x70)); + gdcm::EquipmentManufacturer::Type manufacturer2 = + gdcm::EquipmentManufacturer::Compute(ds); + if (manufacturer2 == gdcm::EquipmentManufacturer::UNKNOWN) { + if (strcmp(name, "gdcm-US-ALOKA-16.dcm") == 0 || + strcmp(name, "US-RGB-8-epicard.dcm") == 0 || + strcmp(name, "OT-MONO2-8-a7.dcm") == 0 || + strcmp(name, "MR-MONO2-8-16x-heart.dcm") == 0 || + strcmp(name, "MR-MONO2-16-head.dcm") == 0 || + strcmp(name, "MR-MONO2-12-shoulder.dcm") == 0 || + strcmp(name, "MR-MONO2-12-an2.acr") == 0 || + strcmp(name, "LJPEG_BuginGDCM12.dcm") == 0 || + strcmp(name, "ELSCINT1_PMSCT_RLE1.dcm") == 0 || + strcmp(name, "ELSCINT1_JP2vsJ2K.dcm") == 0 || + strcmp(name, "MAROTECH_CT_JP2Lossy.dcm") == 0 || + strcmp(name, "ALOKA_SSD-8-MONO2-RLE-SQ.dcm") == 0 || + strcmp(name, "CR-MONO1-10-chest.dcm") == 0 || + strcmp(name, "CT-MONO2-12-lomb-an2.acr") == 0 || + strcmp(name, "CT-MONO2-16-ankle.dcm") == 0 || + strcmp(name, "CT-MONO2-8-abdo.dcm") == 0 || + strcmp(name, "CT-MONO2-16-ort.dcm") == 0 || + strcmp(name, "CT-MONO2-16-chest.dcm") == 0 || + strcmp(name, "CT-MONO2-16-brain.dcm") == 0 || + strcmp(name, "EnhancedWithIPPPerFrameIOPShared.dcm") == 0 || + strcmp(name, "FUJI-10-MONO1-ACR_NEMA_2.dcm") == 0 || + strcmp(name, "JPEGDefinedLengthSequenceOfFragments.dcm") == 0 || + strcmp(name, "IM-0001-0066.CommandTag00.dcm") == 0 || + strcmp(name, "GE_GENESIS-16-MONO2-WrongLengthItem.dcm") == 0 || + strcmp(name, "MR_Spectroscopy_SIEMENS_OF.dcm") == 0 || + strcmp(name, "US-IRAD-NoPreambleStartWith0005.dcm") == 0 || + strcmp(name, "US-IRAD-NoPreambleStartWith0003.dcm") == 0 || + strcmp(name, "PHILIPS_Brilliance_ExtraBytesInOverlay.dcm") == 0 || + strcmp(name, "TOSHIBA_MRT150-16-MONO2-ACR_NEMA_2.dcm") == 0 || + strcmp(name, "fffc0000UN.dcm") == 0) { + } else { + std::cerr << "Unknown2: " << filename << std::endl; + return 1; } - + } else if (manufacturer2 != manufacturer) { + std::cerr << "Incompatible: " << filename << std::endl; + return 1; + } return 0; } - -int TestEquipmentManufacturer(int argc, char *argv[]) -{ - if( argc == 2 ) - { +int TestEquipmentManufacturer(int argc, char *argv[]) { + if (argc == 2) { const char *filename = argv[1]; return TestEquipmentManufacturerFunc(filename, true); - } + } // else // First of get rid of warning/debug message @@ -123,12 +163,11 @@ int TestEquipmentManufacturer(int argc, char *argv[]) gdcm::Trace::WarningOff(); int r = 0, i = 0; const char *filename; - const char * const *filenames = gdcm::Testing::GetFileNames(); - while( (filename = filenames[i]) ) - { + const char *const *filenames = gdcm::Testing::GetFileNames(); + while ((filename = filenames[i])) { r += TestEquipmentManufacturerFunc(filename); ++i; - } + } return r; }