]> Creatis software - gdcm.git/commitdiff
Brutal commit. Changelog to come.... Frog
authorfrog <frog>
Mon, 7 Apr 2003 15:04:37 +0000 (15:04 +0000)
committerfrog <frog>
Mon, 7 Apr 2003 15:04:37 +0000 (15:04 +0000)
ChangeLog
gdcmPython/testSuite.py
src/gdcm.h
src/gdcmDict.cxx
src/gdcmElValSet.cxx
src/gdcmElValSet.h
src/gdcmFile.cxx
src/gdcmFile.h
src/gdcmHeader.cxx
src/gdcmHeader.h

index 157a564c3a60cf1f2488475e45b879950a1b51b1..801ece7f1e17b6437041c5d1baa74c6b605467e1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2003-04-7 Eric Boix <Eric.Boix@creatis.insa-lyon.fr> with JPR
+      * Data/im_00001 renamed to gdcm-MR-PHILIPS-16-Multi-Seq.dcm
+
 2003-03-31 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
       * src/gdcmHeader.h: LoadElements() is not a public method anymore
         (to avoid double call by end user).
index 28edf76699a31e246ddde627b88da399119b33f1..06ad408d5b41e67ae35516db2305c053a80ef879 100644 (file)
@@ -3,502 +3,535 @@ import os
 from gdcmPython import *
 
 class gdcmTestCase(unittest.TestCase):
-       # The files whose name starts with a modality (e.g. CR-MONO1-10-chest.dcm)
-       # come from Sebastien Barre's Dicom2 highly recommendable site
-       # http://www.barre.nom.fr/medical/samples/index.html
-       BarreFiles = [
-               ####################################
-               # CR modality examples:
-               ####################################
-               ["CR-MONO1-10-chest.dcm",
-                       [ ["Modality", "CR"],
-                         #"Transfer Syntax UID" is absent.
-                         ["Rows", "440"],
-                         ["Columns", "440"],
-                         ["Bits Stored", "10"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "9"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "FUJI PHOTO FILM CO. LTD."],
-                         ["Manufacturer Model Name", "9000"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:776 Length:387200"] ] ],
-               ####################################
-               # CT modality examples:
-               ####################################
-               ["CT-MONO2-16-brain.dcm",
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],  # Explicit VR, LE
-                         ["Modality", "CT"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "16"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "15"],
-                         ["Pixel Representation", "1"],
-                         ["Manufacturer", "Picker International, Inc."],
-                         ["Manufacturer Model Name", "PQ5000"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1680 Length:524288"] ] ],
-               ["CT-MONO2-16-ort.dcm",
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit VR, LE
-                         ["Modality", "CT"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "16"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "15"],
-                         ["Pixel Representation", "1"],
-                         ["Manufacturer", "GE MEDICAL SYSTEMS"],
-                         ["Manufacturer Model Name", "HiSpeed CT/i"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1674 Length:524288"] ] ],
-               ["CT-MONO2-16-ankle.dcm",
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit, little
-                         ["Modality", "CT"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "16"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "15"],
-                         ["Pixel Representation", "1"],
-                         ["Manufacturer", "GE MEDICAL SYSTEMS"],
-                         ["Manufacturer Model Name", "GENESIS_ZEUS"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1148 Length:524288"] ] ],
-               ["CT-MONO2-8-abdo.dcm",
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit, little
-                         ["Modality", "CT"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "FUJI"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:796 Length:262144"] ] ],
-               ["CT-MONO2-12-lomb-an2.acr2",
-                       [ ["Modality", "CT"],
-                         #"Transfer Syntax UID" and "Photometric Interpretation" are absent.
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "SIEMENS"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1230 Length:524288"] ] ],
-               ["CT-MONO2-16-chest.dcm",
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg...
-                         ["Modality", "CT"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "400"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "16"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "15"],
-                         ["Pixel Representation", "1"],
-                         ["Manufacturer", "GE MEDICAL SYSTEMS"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1638 Length:143498"] ] ],
-               ####################################
-               ### MR modality examples:
-               ####################################
-               ["MR-MONO2-12-angio-an1.acr1",
-                       [ ["Recognition Code", "ACR-NEMA 1.0"],
-                         ["Modality", "MR"],
-                         #"Transfer Syntax UID" and "Photometric Interpretation" are absent.
-                         ["Rows", "256"],
-                         ["Columns", "256"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "12"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Philips"],
-                         # Note: 256*256*12/8 = 98304
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:650 Length:98304"] ] ],
-               ["MR-MONO2-12-an2.acr2",
-                       [ ["Modality", "MR"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "256"],
-                         ["Columns", "256"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "SIEMENS"],
-                         ["Manufacturer Model Name", "MAGNETOM VISION"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1866 Length:131072"] ] ],
-               ["MR-MONO2-16-head.dcm",
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Imp VR, LE
-                         ["Modality", "MR"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "256"],
-                         ["Columns", "256"],
-                         ["Bits Stored", "16"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "15"],
-                         ["Pixel Representation", "1"],
-                         ["Manufacturer", "GE MEDICAL SYSTEMS"],
-                         ["Manufacturer Model Name", "GENESIS_SIGNA"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1804 Length:131072"] ] ],
-               # MR-MONO2-12-shoulder example is present in the Jpeg section.
-               # MR-MONO2-16-knee is not present in the test suite since it is too
-               #    closely related to MR-MONO2-16-head.dcm to be of interest.
-               ####################################
-               # OT modality examples:
-               ####################################
-               # OT-MONO2-8-hip is not present in the test suite since it is too
-               #    closely related to OT-MONO2-8-a7 to be of interest.
-               ["OT-PAL-8-face.dcm",
-                       # Interest: has a color palette
-                       [#"Transfer Syntax UID", and "Manufacturer" are absent.
-                         ["Modality", "OT"],
-                         ["Photometric Interpretation", "PALETTE COLOR"],
-                         ["Rows", "480"],
-                         ["Columns", "640"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1654 Length:307200"] ] ],
-               # OT-MONO2-8-colon is not present in the test suite since it is too
-               #    closely related to OT-MONO2-8-a7 to be of interest.
-               ["OT-MONO2-8-a7.dcm",
-                       [#"Transfer Syntax UID" is absent.
-                         ["Modality", "OT"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Philips Medical Systems"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:438 Length:262144"] ] ],
-               ####################################
-               # US (Ultra Sound) modality examples:
-               ####################################
-               ["US-RGB-8-esopecho.dcm",
-                       # Interest: RGB image
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],  # Exp VR, LE
-                         ["Modality", "US"],
-                         ["Photometric Interpretation", "RGB"],
-                         ["Rows", "120"],
-                         ["Columns", "256"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Acme Products"],
-                       # FIXME: 92160 / (120*256) = 3 bytes per pixel NOT 1. Maybe
-                       # it has something to do with [Samples Per Pixel] = [3] ???
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:904 Length:92160"] ] ],
-               ["US-RGB-8-epicard.dcm",
-                       # Interest: Big endian transfert syntax
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.2"],  # Big endian
-                         ["Modality", "US"],
-                         ["Photometric Interpretation", "RGB"],
-                         ["Rows", "480"],
-                         ["Columns", "640"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "G.E. Medical Systems"],
-                         ["Manufacturer Model Name", "LOGIQ 700"],
-                       # FIXME: 921600/(480*640) = 3 bytes per pixel NOT 1. Maybe
-                       # it has something to do with [Samples Per Pixel] = [3] ???
-                         ["Implementation Version Name", "OFFIS-DCMTK-311"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1012 Length:921600"] ] ],
-       ]
+   # The files whose name starts with a modality (e.g. CR-MONO1-10-chest.dcm)
+   # come from Sebastien Barre's Dicom2 highly recommendable site
+   # http://www.barre.nom.fr/medical/samples/index.html
+   BarreFiles = [
+      ####################################
+      # CR modality examples:
+      ####################################
+      ["CR-MONO1-10-chest.dcm",
+         [ ["Modality", "CR"],
+           #"Transfer Syntax UID" is absent.
+           ["Rows", "440"],
+           ["Columns", "440"],
+           ["Bits Stored", "10"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "9"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "FUJI PHOTO FILM CO. LTD."],
+           ["Manufacturer Model Name", "9000"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:776 Length:387200"] ] ],
+      ####################################
+      # CT modality examples:
+      ####################################
+      ["CT-MONO2-16-brain.dcm",
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],  # Explicit VR, LE
+           ["Modality", "CT"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "16"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "15"],
+           ["Pixel Representation", "1"],
+           ["Manufacturer", "Picker International, Inc."],
+           ["Manufacturer Model Name", "PQ5000"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1680 Length:524288"] ] ],
+      ["CT-MONO2-16-ort.dcm",
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit VR, LE
+           ["Modality", "CT"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "16"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "15"],
+           ["Pixel Representation", "1"],
+           ["Manufacturer", "GE MEDICAL SYSTEMS"],
+           ["Manufacturer Model Name", "HiSpeed CT/i"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1674 Length:524288"] ] ],
+      ["CT-MONO2-16-ankle.dcm",
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit, little
+           ["Modality", "CT"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "16"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "15"],
+           ["Pixel Representation", "1"],
+           ["Manufacturer", "GE MEDICAL SYSTEMS"],
+           ["Manufacturer Model Name", "GENESIS_ZEUS"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1148 Length:524288"] ] ],
+      ["CT-MONO2-8-abdo.dcm",
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit, little
+           ["Modality", "CT"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "FUJI"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:796 Length:262144"] ] ],
+      ["CT-MONO2-12-lomb-an2.acr2",
+         [ ["Modality", "CT"],
+           #"Transfer Syntax UID" and "Photometric Interpretation" are absent.
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "SIEMENS"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1230 Length:524288"] ] ],
+      ["CT-MONO2-16-chest.dcm",
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg...
+           ["Modality", "CT"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "400"],
+           ["Columns", "512"],
+           ["Bits Stored", "16"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "15"],
+           ["Pixel Representation", "1"],
+           ["Manufacturer", "GE MEDICAL SYSTEMS"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1638 Length:143498"] ] ],
+      ####################################
+      ### MR modality examples:
+      ####################################
+      ["MR-MONO2-12-angio-an1.acr1",
+         [ ["Recognition Code", "ACR-NEMA 1.0"],
+           ["Modality", "MR"],
+           #"Transfer Syntax UID" and "Photometric Interpretation" are absent.
+           ["Rows", "256"],
+           ["Columns", "256"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "12"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Philips"],
+           # Note: 256*256*12/8 = 98304
+           ["7fe0|0010", "gdcm::NotLoaded. Address:650 Length:98304"] ] ],
+      ["MR-MONO2-12-an2.acr2",
+         [ ["Modality", "MR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "256"],
+           ["Columns", "256"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "SIEMENS"],
+           ["Manufacturer Model Name", "MAGNETOM VISION"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1866 Length:131072"] ] ],
+      ["MR-MONO2-16-head.dcm",
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2"], # Imp VR, LE
+           ["Modality", "MR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "256"],
+           ["Columns", "256"],
+           ["Bits Stored", "16"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "15"],
+           ["Pixel Representation", "1"],
+           ["Manufacturer", "GE MEDICAL SYSTEMS"],
+           ["Manufacturer Model Name", "GENESIS_SIGNA"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1804 Length:131072"] ] ],
+      # MR-MONO2-12-shoulder example is present in the Jpeg section.
+      # MR-MONO2-16-knee is not present in the test suite since it is too
+      #    closely related to MR-MONO2-16-head.dcm to be of interest.
+      ####################################
+      # OT modality examples:
+      ####################################
+      # OT-MONO2-8-hip is not present in the test suite since it is too
+      #    closely related to OT-MONO2-8-a7 to be of interest.
+      ["OT-PAL-8-face.dcm",
+         # Interest: has a color palette
+         [#"Transfer Syntax UID", and "Manufacturer" are absent.
+           ["Modality", "OT"],
+           ["Photometric Interpretation", "PALETTE COLOR"],
+           ["Rows", "480"],
+           ["Columns", "640"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1654 Length:307200"] ] ],
+      # OT-MONO2-8-colon is not present in the test suite since it is too
+      #    closely related to OT-MONO2-8-a7 to be of interest.
+      ["OT-MONO2-8-a7.dcm",
+         [#"Transfer Syntax UID" is absent.
+           ["Modality", "OT"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Philips Medical Systems"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:438 Length:262144"] ] ],
+      ####################################
+      # US (Ultra Sound) modality examples:
+      ####################################
+      ["US-RGB-8-esopecho.dcm",
+         # Interest: RGB image
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],  # Exp VR, LE
+           ["Modality", "US"],
+           ["Photometric Interpretation", "RGB"],
+           ["Rows", "120"],
+           ["Columns", "256"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Acme Products"],
+         # FIXME: 92160 / (120*256) = 3 bytes per pixel NOT 1. Maybe
+         # it has something to do with [Samples Per Pixel] = [3] ???
+           ["7fe0|0010", "gdcm::NotLoaded. Address:904 Length:92160"] ] ],
+      ["US-RGB-8-epicard.dcm",
+         # Interest: Big endian transfert syntax
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.2"],  # Big endian
+           ["Modality", "US"],
+           ["Photometric Interpretation", "RGB"],
+           ["Rows", "480"],
+           ["Columns", "640"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "G.E. Medical Systems"],
+           ["Manufacturer Model Name", "LOGIQ 700"],
+         # FIXME: 921600/(480*640) = 3 bytes per pixel NOT 1. Maybe
+         # it has something to do with [Samples Per Pixel] = [3] ???
+           ["Implementation Version Name", "OFFIS-DCMTK-311"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1012 Length:921600"] ] ],
+   ]
 
-       MultiFrameFiles = [
-       # The number of images is contained in the "Number of Frames" element
-               ["MR-MONO2-8-16x-heart.dcm",
-                       # Interest: multi-frame
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
-                         ["Number of Frames", "16"],
-                         ["Modality", "MR"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "256"],
-                         ["Columns", "256"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Philips"],
-                         # Note: 256*256*16=1048576 (16 is the number of Frames) 
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:920 Length:1048576"] ] ],
-               ["NM-MONO2-16-13x-heart.dcm",
-                       # Interest: NM modality, multi-frame
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
-                         ["Number of Frames", "13"],
-                         ["Modality", "NM"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "64"],
-                         ["Columns", "64"],
-                         ["Bits Stored", "16"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "15"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "ACME Products"],
-                         # Note: 64*64*13*2=106496
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1234 Length:106496"] ] ],
-               ["US-MONO2-8-8x-execho.dcm",
-                       # Interest: multi-frame
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
-                         ["Number of Frames", "8"],
-                         ["Modality", "US"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "120"],
-                         ["Columns", "128"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Acme Products"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:976 Length:122880"] ] ],
-               ["US-PAL-8-10x-echo.dcm",
-                       # Interest: RLE (Run Length Encoded) compression, multiframe
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.5"], # RLE
-                         ["Number of Frames", "10"],
-                         ["Modality", "US"],
-                         ["Photometric Interpretation", "PALETTE COLOR"],
-                         ["Rows", "430"],
-                         ["Columns", "600"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "ACME Products"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:2428 Length:481182"] ] ],
-               ["XA-MONO2-8-12x-catheter.dcm",
-                       # Interest: XA modality, multi-frame
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg
-                         ["Number of Frames", "12"],  # 12 images
-                         ["Modality", "XA"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Acme Products"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1006 Length:920072"] ] ],
-       ]
+   MultiFrameFiles = [
+   # The number of images is contained in the "Number of Frames" element
+      ["MR-MONO2-8-16x-heart.dcm",
+         # Interest: multi-frame
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
+           ["Number of Frames", "16"],
+           ["Modality", "MR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "256"],
+           ["Columns", "256"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Philips"],
+           # Note: 256*256*16=1048576 (16 is the number of Frames) 
+           ["7fe0|0010", "gdcm::NotLoaded. Address:920 Length:1048576"] ] ],
+      ["NM-MONO2-16-13x-heart.dcm",
+         # Interest: NM modality, multi-frame
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
+           ["Number of Frames", "13"],
+           ["Modality", "NM"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "64"],
+           ["Columns", "64"],
+           ["Bits Stored", "16"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "15"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "ACME Products"],
+           # Note: 64*64*13*2=106496
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1234 Length:106496"] ] ],
+      ["US-MONO2-8-8x-execho.dcm",
+         # Interest: multi-frame
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"], # ExpVR, LE
+           ["Number of Frames", "8"],
+           ["Modality", "US"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "120"],
+           ["Columns", "128"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Acme Products"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:976 Length:122880"] ] ],
+      ["US-PAL-8-10x-echo.dcm",
+         # Interest: RLE (Run Length Encoded) compression, multiframe
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.5"], # RLE
+           ["Number of Frames", "10"],
+           ["Modality", "US"],
+           ["Photometric Interpretation", "PALETTE COLOR"],
+           ["Rows", "430"],
+           ["Columns", "600"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "ACME Products"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:2428 Length:481182"] ] ],
+      ["XA-MONO2-8-12x-catheter.dcm",
+         # Interest: XA modality, multi-frame
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"], # jpeg
+           ["Number of Frames", "12"],  # 12 images
+           ["Modality", "XA"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Acme Products"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1006 Length:920072"] ] ],
+   ]
 
-       GdcmFiles = [
-               ["gdcm-MR-SIEMENS-16.acr1",
-                       # Interest: good old Acr-Nema Version 1, see also Oddities below
-                       [ ["Recognition Code", "ACR-NEMA 1.0"],
-                         ["Modality", "MR"],
-                         ["Rows", "256"],
-                         ["Columns", "256"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "SIEMENS"],
-                         ["Manufacturer Model Name", "GBS III"],
-                       # FIXME: this image looks padded at the end. The length of the file
-                       # is 140288. Notice that, 256*256*2 + 1024 = 131072 + 1024 = 132096
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:8192 Length:132096"],
-                         # Oddities: "Study ID" and "Series Number" are empty
-                         ["Study ID", ""],
-                         ["Series Number", ""] ] ],
-                         # Oddities: "Study" and "Serie Instance UID" are not present
-               ["gdcm-MR-SIEMENS-16.acr2",
-                       # Interest: Acr-Nema Version 2
-                       [ ["Recognition Code", "ACR-NEMA 2.0"],
-                         ["Modality", "MR"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "SIEMENS"],
-                         ["Manufacturer Model Name", "MAGNETOM VISION"],
-                         ["Study Instance UID",
-                          "1.3.12.2.1107.5.2.4.7630.20000918174641000"],
-                         ["Study ID", "1"],
-                         ["Series Instance UID",
-                          "1.3.12.2.1107.5.2.4.7630.20000918175714000007"],
-                         ["Series Number", "7"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:6052 Length:524288"] ] ],
-               ["gdcm-US-ALOKA-16.dcm",
-                       # Interest: - possesses 3 LUTS: a Green (checked), a Red and BLue.
-                       #           - announced as implicit VR, but really explicit VR.
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit VR, LE
-                         ["Modality", "US"],
-                         ["Photometric Interpretation", "PALETTE COLOR"],
-                         ["Segmented Green Palette Color LUT Data",
-                          "gdcm::NotLoaded. Address:89576 Length:113784"],
-                         ["Rows", "480"],
-                         ["Columns", "640"],
-                         ["Bits Stored", "16"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "15"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "ALOKA CO., LTD."],
-                         ["Manufacturer Model Name", "SSD-4000"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:258740 Length:614400"] ] ],
-               ["gdcm-MR-PHILIPS-16.dcm",
-                       # Interest: - possesses a sequence
-                       #           - dicom file, with a recognition code of ACR-NEMA1
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit VR, LE
-                         ["Recognition Code", "ACR-NEMA 1.0"],
-                         ["Modality", "MR"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "256"],
-                         ["Columns", "256"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Philips Medical Systems"],
-                         ["Manufacturer Model Name", "Gyroscan Intera"],
-                         ["Sequence Variant", "OTHER"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:6584 Length:131072"] ] ],
-               ["gdcm-MR-PHILIPS-16-NonRectPix.dcm",
-                       # Interest: - pixels are non rectangular
-                       #           - private elements are in explicit VR (which is normal)
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],  # Explicit VR, LE
-                         ["Modality", "MR"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "64"],
-                         ["Columns", "160"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Philips Medical Systems"],
-                         ["Manufacturer Model Name", "Gyroscan Intera"],
-                         ["Pixel Spacing", "0.487416\\0.194966"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:5010 Length:20480"] ] ],
-               ["gdcm-CR-DCMTK-16-NonSamplePerPix.dcm",
-                       # Interest: - Misses the "Samples Per Pixel" element which prevents
-                  #             e-film from reading it.
-                       #           - Misses the Manufacturer related info
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],  # Explicit VR, LE
-                         ["Modality", "CR"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "750"],
-                         ["Columns", "750"],
-                         ["Bits Stored", "8"],
-                         ["Bits Allocated", "8"],
-                         ["High Bit", "7"],
-                         ["Pixel Representation", "0"],
-                         ["Implementation Version Name", "OFFIS_DCMTK_341"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:740 Length:562500"] ] ],
-       ]
+   GdcmFiles = [
+      ["gdcm-MR-SIEMENS-16.acr1",
+         # Interest: good old Acr-Nema Version 1, see also Oddities below
+         [ ["Recognition Code", "ACR-NEMA 1.0"],
+           ["Modality", "MR"],
+           ["Rows", "256"],
+           ["Columns", "256"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "SIEMENS"],
+           ["Manufacturer Model Name", "GBS III"],
+         # FIXME: this image looks padded at the end. The length of the file
+         # is 140288. Notice that, 256*256*2 + 1024 = 131072 + 1024 = 132096
+           ["7fe0|0010", "gdcm::NotLoaded. Address:8192 Length:132096"],
+           # Oddities: "Study ID" and "Series Number" are empty
+           ["Study ID", ""],
+           ["Series Number", ""] ] ],
+           # Oddities: "Study" and "Serie Instance UID" are not present
+      ["gdcm-MR-SIEMENS-16.acr2",
+         # Interest: Acr-Nema Version 2
+         [ ["Recognition Code", "ACR-NEMA 2.0"],
+           ["Modality", "MR"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "SIEMENS"],
+           ["Manufacturer Model Name", "MAGNETOM VISION"],
+           ["Study Instance UID",
+            "1.3.12.2.1107.5.2.4.7630.20000918174641000"],
+           ["Study ID", "1"],
+           ["Series Instance UID",
+            "1.3.12.2.1107.5.2.4.7630.20000918175714000007"],
+           ["Series Number", "7"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:6052 Length:524288"] ] ],
+      ["gdcm-US-ALOKA-16.dcm",
+         # Interest: - possesses 3 LUTS: a Green (checked), a Red and BLue.
+         #           - announced as implicit VR, but really explicit VR.
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit VR, LE
+           ["Modality", "US"],
+           ["Photometric Interpretation", "PALETTE COLOR"],
+           ["Segmented Green Palette Color LUT Data",
+            "gdcm::NotLoaded. Address:89576 Length:113784"],
+           ["Rows", "480"],
+           ["Columns", "640"],
+           ["Bits Stored", "16"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "15"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "ALOKA CO., LTD."],
+           ["Manufacturer Model Name", "SSD-4000"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:258740 Length:614400"] ] ],
+      ["gdcm-MR-PHILIPS-16.dcm",
+         # Interest: - possesses a sequence
+         #           - dicom file, with a recognition code of ACR-NEMA1
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2"],  # Implicit VR, LE
+           ["Recognition Code", "ACR-NEMA 1.0"],
+           ["Modality", "MR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "256"],
+           ["Columns", "256"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Philips Medical Systems"],
+           ["Manufacturer Model Name", "Gyroscan Intera"],
+           ["Sequence Variant", "OTHER"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:6584 Length:131072"] ] ],
+      ["gdcm-MR-PHILIPS-16-Multi-Seq.dcm",
+         # Interest: - possesses many sequences in group 0x0029
+         #           - Big sequence 28808 bytes at (0x0029, 0x263d)
+         #           - dicom file, with a recognition code of ACR-NEMA1
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],
+           ["Recognition Code", "ACR-NEMA 1.0"],
+           ["Modality", "MR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "128"],
+           ["Columns", "128"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Philips Medical Systems"],
+           ["Manufacturer Model Name", "Gyroscan Intera"],
+           ["Sequence Variant", "OTHER"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:35846 Length:32768"] ] ],
+      ["gdcm-MR-PHILIPS-16-NonRectPix.dcm",
+         # Interest: - pixels are non rectangular
+         #           - private elements are in explicit VR (which is normal)
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],  # Explicit VR, LE
+           ["Modality", "MR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "64"],
+           ["Columns", "160"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Philips Medical Systems"],
+           ["Manufacturer Model Name", "Gyroscan Intera"],
+           ["Pixel Spacing", "0.487416\\0.194966"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:5010 Length:20480"] ] ],
+      ["gdcm-CR-DCMTK-16-NonSamplePerPix.dcm",
+         # Interest: - Misses the "Samples Per Pixel" element which prevents
+         #             e-film from reading it.
+         #           - Misses the Manufacturer related info
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.1"],  # Explicit VR, LE
+           ["Modality", "CR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "750"],
+           ["Columns", "750"],
+           ["Bits Stored", "8"],
+           ["Bits Allocated", "8"],
+           ["High Bit", "7"],
+           ["Pixel Representation", "0"],
+           ["Implementation Version Name", "OFFIS_DCMTK_341"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:740 Length:562500"] ] ],
+   ]
 
-       GdcmJpegFiles = [
-               ["gdcm-JPEG-Extended.dcm",
-                       # Interest: Jpeg compression [Extended (2,4)]
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.51"],
-                         ["Modality", "CT"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "SIEMENS"],
-                         ["Manufacturer Model Name", "Volume Zoom"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:2946 Length:192218"] ] ],
-               ["MR-MONO2-12-shoulder.dcm",
-                       # Interest: Jpeg compression [Lossless, non-hierar. (14)]
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.57"],
-                         ["Modality", "MR"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "1024"],
-                         ["Columns", "1024"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Philips Medical Systems"],
-                         ["Manufacturer Model Name", "Gyroscan NT"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:1580 Length:718948"] ] ],
-               ["gdcm-JPEG-LossLess3a.dcm",
-                       # Interest: - Jpeg compression [Lossless, hierar., first-order
-                       #             pred. 14, Select. Val. 1]
-                       #           - contains a sequence [circa (0008,2112)]
-                       #           - contains additional data after the pixels ???
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"],
-                         ["Modality", "CT"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "512"],
-                         ["Columns", "512"],
-                         ["Bits Stored", "12"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "11"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "SIEMENS"],
-                         ["Manufacturer Model Name", "Volume Zoom"] ] ],
-                       # FIXME: the pixel data looks like corrupted. As stated by "od -A d -c"
-                       #   0002528     à 177 020 \0  O  B \0 \0   ÿ  ÿ   ÿ   ÿ  þ  ÿ \0  à
-                       #   0002544    \0  \0  \0 \0  þ  ÿ \0  à 202  ? 003  \0  ÿ  Ø  ÿ  Ã
-                       # which we interpret as follows:
-                       #   - 2528: (à 177, 020 \0) = (0x7fe0, 0x0010) i.e. Pixel Data tag,
-                       #   - 2532: OB i.e. encapsulated encoded Pixel Data,
-                       #   - 2534: Two bytes reserved,
-                       #   - 2536: ÿ ÿ ÿ ÿ = 0xffffffff i.e. data element length is undefined.
-                       #   - 2540: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. basic offset table
-                       #           item tag
-                       #   - 2544: \0 \0 \0 \0 i.e. offset table as length zero, i.e. no
-                       #           item value for offset table.
-                       #   - 2548: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. item tag of first
-                       #           fragment of (encoded) pixel data.
-                       #   - 2552: 202 ? 003 \0 = 212866 bytes i.e. length of first fragment
-                       #           of (encoded) pixel data.
-                       # and so the next item tag should be found at the 2556+212866 th
-                       # octet i.e. at address 215422. But, as stated by od, we find:
-                       #   0215408   E   u Ö 026   Î   É 7 ¬ Ã ¸ ó ¿ ÿ Ù \f °
-                       #   0215424   ¶ 016 P   Ñ 002 016
-                       # and (\f °, ¶ 016) is NOT an OB item TAG which is required to be
-                       # present (at least there should be a sequence delimiter), refer to
-                       # PS 3.5-2001 page 50. 
-               ["gdcm-JPEG-LossLess3b.dcm",
-                       # Interest: - Jpeg compression [Lossless, hierar., first-order
-                       #             pred. 14, Select. Val. 1]
-                       #           - encoding is sligthly different from LossLess3a.dcm ???
-                       [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"],
-                         ["Modality", "CR"],
-                         ["Photometric Interpretation", "MONOCHROME2"],
-                         ["Rows", "2076"],
-                         ["Columns", "1876"],
-                         ["Bits Stored", "15"],
-                         ["Bits Allocated", "16"],
-                         ["High Bit", "14"],
-                         ["Pixel Representation", "0"],
-                         ["Manufacturer", "Philips Medical Systems"],
-                         ["Manufacturer Model Name", "Cassette Holder Type 9840 500 35201"],
-                         ["7fe0|0010", "gdcm::NotLoaded. Address:3144 Length:4795668"] ] ],
-       ]
+   GdcmJpegFiles = [
+      ["gdcm-JPEG-Extended.dcm",
+         # Interest: Jpeg compression [Extended (2,4)]
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.51"],
+           ["Modality", "CT"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "SIEMENS"],
+           ["Manufacturer Model Name", "Volume Zoom"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:2946 Length:192218"] ] ],
+      ["MR-MONO2-12-shoulder.dcm",
+         # Interest: Jpeg compression [Lossless, non-hierar. (14)]
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.57"],
+           ["Modality", "MR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "1024"],
+           ["Columns", "1024"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Philips Medical Systems"],
+           ["Manufacturer Model Name", "Gyroscan NT"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:1580 Length:718948"] ] ],
+      ["gdcm-JPEG-LossLess3a.dcm",
+         # Interest: - Jpeg compression [Lossless, hierar., first-order
+         #             pred. 14, Select. Val. 1]
+         #           - contains a sequence [circa (0008,2112)]
+         #           - contains additional data after the pixels ???
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"],
+           ["Modality", "CT"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "512"],
+           ["Columns", "512"],
+           ["Bits Stored", "12"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "11"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "SIEMENS"],
+           ["Manufacturer Model Name", "Volume Zoom"] ] ],
+         # FIXME: the pixel data looks like corrupted. As stated by "od -A d -c"
+         #   0002528     à 177 020 \0  O  B \0 \0   ÿ  ÿ   ÿ   ÿ  þ  ÿ \0  à
+         #   0002544    \0  \0  \0 \0  þ  ÿ \0  à 202  ? 003  \0  ÿ  Ø  ÿ  Ã
+         # which we interpret as follows:
+         #   - 2528: (à 177, 020 \0) = (0x7fe0, 0x0010) i.e. Pixel Data tag,
+         #   - 2532: OB i.e. encapsulated encoded Pixel Data,
+         #   - 2534: Two bytes reserved,
+         #   - 2536: ÿ ÿ ÿ ÿ = 0xffffffff i.e. data element length is undefined.
+         #   - 2540: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. basic offset table
+         #           item tag
+         #   - 2544: \0 \0 \0 \0 i.e. offset table as length zero, i.e. no
+         #           item value for offset table.
+         #   - 2548: (þ ÿ, \0 à) = (0xfffe, 0xe000) i.e. item tag of first
+         #           fragment of (encoded) pixel data.
+         #   - 2552: 202 ? 003 \0 = 212866 bytes i.e. length of first fragment
+         #           of (encoded) pixel data.
+         # and so the next item tag should be found at the 2556+212866 th
+         # octet i.e. at address 215422. But, as stated by od, we find:
+         #   0215408   E   u Ö 026   Î   É 7 ¬ Ã ¸ ó ¿ ÿ Ù \f °
+         #   0215424   ¶ 016 P   Ñ 002 016
+         # and (\f °, ¶ 016) is NOT an OB item TAG which is required to be
+         # present (at least there should be a sequence delimiter), refer to
+         # PS 3.5-2001 page 50. 
+      ["gdcm-JPEG-LossLess3b.dcm",
+         # Interest: - Jpeg compression [Lossless, hierar., first-order
+         #             pred. 14, Select. Val. 1]
+         #           - encoding is sligthly different from LossLess3a.dcm ???
+         [ ["Transfer Syntax UID", "1.2.840.10008.1.2.4.70"],
+           ["Modality", "CR"],
+           ["Photometric Interpretation", "MONOCHROME2"],
+           ["Rows", "2076"],
+           ["Columns", "1876"],
+           ["Bits Stored", "15"],
+           ["Bits Allocated", "16"],
+           ["High Bit", "14"],
+           ["Pixel Representation", "0"],
+           ["Manufacturer", "Philips Medical Systems"],
+           ["Manufacturer Model Name", "Cassette Holder Type 9840 500 35201"],
+           ["7fe0|0010", "gdcm::NotLoaded. Address:3144 Length:4795668"] ] ],
+   ]
 
-       def _BaseTest(self, FileSet):
-               for entry in FileSet:
-                       fileName = os.path.join(GDCM_DATA_PATH, entry[0])
-                       toRead = gdcmHeader(fileName)
-                       valDict = toRead.GetPubElVal()
-                       for subEntry in entry[1]:
-                               element = subEntry[0]
-                               value   = subEntry[1]
-                               self.assertEqual(valDict[element], value, 
-                                                ("Wrong %s for file %s (got %s, shoud be %s)"
-                                                  % (element,fileName, valDict[element], value)) )
+   def _BaseTest(self, FileSet):
+      for entry in FileSet:
+         fileName = os.path.join(GDCM_DATA_PATH, entry[0])
+         toRead = gdcmHeader(fileName)
+         valDict = toRead.GetPubElVal()
+         for subEntry in entry[1]:
+            element = subEntry[0]
+            value   = subEntry[1]
+            self.assertEqual(valDict[element], value, 
+                             ("Wrong %s for file %s (got %s, shoud be %s)"
+                               % (element,fileName, valDict[element], value)) )
 
-       def testBarre(self):
-               gdcmTestCase._BaseTest(self, gdcmTestCase.BarreFiles)
+   def testBarre(self):
+      gdcmTestCase._BaseTest(self, gdcmTestCase.BarreFiles)
 
-       def testMultiFram(self):
-               gdcmTestCase._BaseTest(self, gdcmTestCase.MultiFrameFiles)
+   def testMultiFram(self):
+      gdcmTestCase._BaseTest(self, gdcmTestCase.MultiFrameFiles)
 
-       def testFiles(self):
-               gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmFiles)
+   def testFiles(self):
+      gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmFiles)
 
-       def testJpeg(self):
-               gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmJpegFiles)
+   def testJpeg(self):
+      gdcmTestCase._BaseTest(self, gdcmTestCase.GdcmJpegFiles)
+
+   def testWrite(self):
+      import md5
+      SourceFileName = os.path.join(GDCM_DATA_PATH,
+                                    'gdcm-MR-PHILIPS-16-Multi-Seq.dcm')
+      Source = gdcmFile(SourceFileName);
+      Source.GetImageData()
+      TargetFileName = "junk"
+      Target = Source.WriteDcm(TargetFileName)
+      Sign = 'c7d6bedae1bef3851f35b29952fbbd4b'
+      ComputeSign = md5.new(open(TargetFileName).read()).hexdigest()
+      #print ComputeSign
+      self.assertEqual(ComputeSign, Sign,
+          ("Wrong signature for file %s (got %s, shoud be %s)"
+           % (SourceFileName, ComputeSign, Sign)) )
 
 if __name__ == '__main__':
-       unittest.main()
+   unittest.main()
 
index 03fde1e83be0eefdedc2b543e273f6ade21ff6d9..802f5ed05ca7620b56cf497c1bf8a283158762ec 100644 (file)
@@ -3,23 +3,6 @@
 #ifndef GDCM_H
 #define GDCM_H
 
-//using namespace std;
-
-// JPR CLEAN
-// En fait, je disais que dans LE Directory Dicom (dans son etat 2001)
-// il y a +/- 1600 entrees.
-// Une valeur raisonable pour un  majorant du nombre d'entrees
-// dans une entete DICOM d'une image semble semble etre 300
-// Si on 'decortique' les elements SQ (ce qui ne semble pas etre fait pour le moment)
-// on risque en fait de depasser ... un nombre non previsible dans le cas d'une entree SQ
-// contenant lui même un tres grand nombre d'entrees ?!?)
-// Quant au nombre d'entrees dans un DICOMDIR, c'est encore pire : il n'est limité
-// que par la taille d'un CD-ROM (les DVD-ROM ne sont pas encore pris en compte)
-// On peut s'attendre a 30 entrees par fichier dicom présent sur le CD-ROM
-// REMARQUE : il faudra se pencher sur le pb de la creation du DICOMDIR lorsqu'on voudra 
-// exporter des images lisibles par les consoles cliniques 
-// et pas seulement importables dans e-film. 
-
 ////////////////////////////////////////////////////////////////////////////
 // Tag based hash tables.
 // We shall use as keys the strings (as the C++ type) obtained by
index 645dcf855be65846dc5871302eafc8d4395dec02..aae1daff119699bdbade8cd48101c647211cb9ed 100644 (file)
@@ -81,9 +81,6 @@ gdcmDictEntry * gdcmDict::GetTagByKey(guint16 group, guint16 element) {
        TagKey key = gdcmDictEntry::TranslateToKey(group, element);
        if ( ! KeyHt.count(key))
                return (gdcmDictEntry*)0; 
-       if (KeyHt.count(key) > 1)
-               dbg.Verbose(0, "gdcmDict::GetTagByName", 
-                           "multiple entries for this key (FIXME) !");
        return KeyHt.find(key)->second;
 }
 
@@ -96,63 +93,44 @@ gdcmDictEntry * gdcmDict::GetTagByKey(guint16 group, guint16 element) {
 gdcmDictEntry * gdcmDict::GetTagByName(TagName name) {
        if ( ! NameHt.count(name))
                return (gdcmDictEntry*)0; 
-       if (NameHt.count(name) > 1)
-               dbg.Verbose(0, "gdcmDict::GetTagByName", 
-                           "multiple entries for this key (FIXME) !");
        return NameHt.find(name)->second;
 }
 
-
 int gdcmDict::ReplaceEntry(gdcmDictEntry* NewEntry) {
-       //JPRCLEAN
-       // au cas ou la NewEntry serait incomplete
-       // Question : cela peut-il se produire ?
-       //
-       // --> NON : voir constructeur
-       //TagKey key;
-       //key = NewEntry->GetKey();
-       //if (key =="") {
-       //      NewEntry->gdcmDictEntry::SetKey(
-       //                      gdcmDictEntry::TranslateToKey(NewEntry->GetGroup(), NewEntry->GetElement())
-       //                      );
-       //}
-       
-       KeyHt.erase (NewEntry->gdcmDictEntry::GetKey());
-       KeyHt[ NewEntry->GetKey()] = NewEntry;
-       return (1);
-       // Question(jpr): Dans quel cas ça peut planter ?
-       // Reponse(frog): dans les mauvais cas...
+   if ( RemoveEntry(NewEntry->gdcmDictEntry::GetKey()) ) {
+       KeyHt[ NewEntry->GetKey()] = NewEntry;
+       return (1);
+   } 
+   return (0);
 }
 
 int gdcmDict::AddNewEntry(gdcmDictEntry* NewEntry) {
 
        TagKey key;
        key = NewEntry->GetKey();
        
-       if(KeyHt.count(key) >= 1) {
+       if(KeyHt.count(key) == 1) {
                dbg.Verbose(1, "gdcmDict::AddNewEntry allready present", key.c_str());
                return(0);
        } else {
                KeyHt[NewEntry->GetKey()] = NewEntry;
                return(1);
        }
-       }
+}
 
 
-int gdcmDict::RemoveEntry(TagKey key) {        
-       if(KeyHt.count(key) == 1) {
-               KeyHt.erase(key);
-               return (1);
-       } else {
-               dbg.Verbose(1, "gdcmDict::RemoveEntry unfound entry", key.c_str());
-               return (0);
-       }
+int gdcmDict::RemoveEntry(TagKey key) {
+   if(KeyHt.count(key) == 1) {
+      KeyHt.erase(key);
+      return (1);
+   } else {
+      dbg.Verbose(1, "gdcmDict::RemoveEntry unfound entry", key.c_str());
+      return (0);
+  }
 }
 
 
 int gdcmDict::RemoveEntry (guint16 group, guint16 element) {
-
        return( RemoveEntry(gdcmDictEntry::TranslateToKey(group, element)) );
 }
 
index 3dd24f1cce7b37e7755c113110d2cb540515449f..5cc9841cd77cb397f66ffcdfe04b5d10643d27b4 100644 (file)
@@ -40,93 +40,59 @@ void gdcmElValSet::PrintByName(ostream & os) {
        }
 }
 
-gdcmElValue* gdcmElValSet::GetElementByNumber(guint32 group, guint32 element) {
+gdcmElValue* gdcmElValSet::GetElementByNumber(guint16 group, guint16 element) {
        TagKey key = gdcmDictEntry::TranslateToKey(group, element);
        if ( ! tagHt.count(key))
                return (gdcmElValue*)0;
-       if (tagHt.count(key) > 1)
-               dbg.Verbose(0, "gdcmElValSet::GetElementByNumber",
-                           "multiple entries for this key (FIXME) !");
        return tagHt.find(key)->second;
 }
 
 gdcmElValue* gdcmElValSet::GetElementByName(string TagName) {
    if ( ! NameHt.count(TagName))
       return (gdcmElValue*)0;
-   if (NameHt.count(TagName) > 1)
-      dbg.Verbose(0, "gdcmElValSet::GetElement",
-                  "multipe entries for this key (FIXME) !");
    return NameHt.find(TagName)->second;
 }
 
-string gdcmElValSet::GetElValueByNumber(guint32 group, guint32 element) {
+string gdcmElValSet::GetElValueByNumber(guint16 group, guint16 element) {
        TagKey key = gdcmDictEntry::TranslateToKey(group, element);
        if ( ! tagHt.count(key))
                return "gdcm::Unfound";
-       if (tagHt.count(key) > 1)
-               dbg.Verbose(0, "gdcmElValSet::GetElValueByNumber",
-                           "multiple entries for this key (FIXME) !");
        return tagHt.find(key)->second->GetValue();
 }
 
 string gdcmElValSet::GetElValueByName(string TagName) {
        if ( ! NameHt.count(TagName))
                return "gdcm::Unfound";
-       if (NameHt.count(TagName) > 1)
-               dbg.Verbose(0, "gdcmElValSet::GetElValue",
-                           "multipe entries for this key (FIXME) !");
        return NameHt.find(TagName)->second->GetValue();
 }
 
 
 int gdcmElValSet::SetElValueByNumber(string content,
-                                     guint32 group, guint32 element) {
-                                     
-// TODO : comprendre pourquoi ils sont déclares comme des guint32, alors que c'est des guint16
-
+                                     guint16 group, guint16 element) {
        TagKey key = gdcmDictEntry::TranslateToKey(group, element);
        if ( ! tagHt.count(key))
                return 0;
-       if (tagHt.count(key) > 1) {
-               dbg.Verbose(0, "gdcmElValSet::SetElValueByNumber",
-                           "multiple entries for this key (FIXME) !");
-               return (0); 
-       }
-                                              
        tagHt[key]->SetValue(content);
-
-       // Question : m à j LgrElem ?
-       tagHt[key]->SetLength(strlen(content.c_str()));  
-
-       // FIXME should we really update the element length ?
        tagHt[key]->SetLength(content.length());         
-
-       return(1);              
+       return 1;
 }
 
 int gdcmElValSet::SetElValueByName(string content, string TagName) {
        if ( ! NameHt.count(TagName))
                return 0;
-       if (NameHt.count(TagName) > 1) {
-               dbg.Verbose(0, "gdcmElValSet::SetElValueByName",
-                           "multipe entries for this key (FIXME) !");
-               return 0;
-       }
-       NameHt.find(TagName)->second->SetValue(content);
-       NameHt.find(TagName)->second->SetLength(strlen(content.c_str()));        
-       return(1);              
+       NameHt[TagName]->SetValue(content);
+       NameHt[TagName]->SetLength(content.length());
+       return 1;               
 }
 
 /**
- * \ingroup  gdcmElValSet
- * \brief    Generate a free TagKey i.e. a TagKey that is not present
- *           in the TagHt dictionary. One of the potential usage is
- *           to add  gdcm generated additional informartion to the ElValSet
- *           (see gdcmHeader::AddAndDefaultElements).
- * @param group The generated tag must belong to this group.  
- * @return   The element of tag with given group which is fee.
+ * \ingroup gdcmElValSet
+ * \brief   Generate a free TagKey i.e. a TagKey that is not present
+ *          in the TagHt dictionary.
+ * @param   group The generated tag must belong to this group.  
+ * @return  The element of tag with given group which is fee.
  */
-guint32 gdcmElValSet::GenerateFreeTagKeyInGroup(guint32 group) {
+guint32 gdcmElValSet::GenerateFreeTagKeyInGroup(guint16 group) {
    for (guint32 elem = 0; elem < UINT32_MAX; elem++) {
       TagKey key = gdcmDictEntry::TranslateToKey(group, elem);
       if (tagHt.count(key) == 0)
@@ -135,50 +101,24 @@ guint32 gdcmElValSet::GenerateFreeTagKeyInGroup(guint32 group) {
    return UINT32_MAX;
 }
 
-int gdcmElValSet::SetElValueLengthByNumber(guint32 l,
-                                           guint32 group, guint32 element) {
+int gdcmElValSet::SetElValueLengthByNumber(guint32 length,
+                                           guint16 group, guint16 element) {
        TagKey key = gdcmDictEntry::TranslateToKey(group, element);
        if ( ! tagHt.count(key))
                return 0;
-       tagHt[key]->SetLength(l);        
+       tagHt[key]->SetLength(length);   
        return 1 ;              
 }
 
 
-int gdcmElValSet::SetElValueLengthByName(guint32 l, string TagName) {
+int gdcmElValSet::SetElValueLengthByName(guint32 length, string TagName) {
        if ( ! NameHt.count(TagName))
                return 0;
-       NameHt.find(TagName)->second->SetLength(l);      
+       NameHt.find(TagName)->second->SetLength(length);         
        return 1 ;              
 }
 
-// Sorry for the DEBUG's, but tomorow is gonna be hoter than today
-
-int gdcmElValSet::Write(FILE * _fp) {
-
-       guint16 gr, el;
-       guint32 lgr;
-       const char * val;
-       string vr;
-       guint32 val_uint32;
-       guint16 val_uint16;
-       
-       vector<string> tokens;
-       
-       void *ptr;
-       
-       string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
-       
-       // Utilisées pour le calcul Group Length
-       guint32 lgrCalcGroupe=0;
-       gdcmElValue *elem, *elemZ, *elemZPrec;
-       guint16 grCourant = 0;
-       
-       // Question :
-       // Comment pourrait-on tester si on est TrueDicom ou non ,
-       // (FileType est un champ de gdcmHeader ...)
-       //
-
+void gdcmElValSet::UpdateGroupLength(bool SkipSequence) {
        // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
        // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
        // dans l'image native
@@ -188,10 +128,12 @@ int gdcmElValSet::Write(FILE * _fp) {
        // On fait de l'implicit VR little Endian 
        // (pour moins se fairche sur processeur INTEL)
        // On force le TRANSFERT SYNTAX UID
+   guint16 gr, el;
+   string vr;
+   guint32 lgrCalcGroupe=0;
+   gdcmElValue *elem, *elemZ, *elemZPrec;
+   guint16 grCourant = 0;
                                
-       SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);  
-       SetElValueLengthByNumber(18, 0x0002, 0x0010);  // Le 0 de fin de chaine doit etre stocké, dans ce cas   
-                       
        TagElValueHT::iterator tag = tagHt.begin();
        
        elem = tag->second;
@@ -219,7 +161,15 @@ int gdcmElValSet::Write(FILE * _fp) {
                elem = tag->second;
                gr = elem->GetGroup();
                el = elem->GetElement();
-
+      vr = elem->GetVR();
+
+      if (SkipSequence && vr == "SQ")
+         // pas SEQUENCE en ACR-NEMA
+         // WARNING : risque de pb 
+         //           si on est descendu 'a l'interieur' des SQ 
+         continue;
+            //
+            //
                if ( (gr != grCourant) /*&&     // On arrive sur un nv Groupe     
                     (el != 0xfffe) */  ) {
                            
@@ -252,7 +202,113 @@ int gdcmElValSet::Write(FILE * _fp) {
                                                                elem->GetLength(), el, lgrCalcGroupe, gr);
                }               
        }
+}
+
+void gdcmElValSet::WriteElements(FileType type, FILE * _fp) {
+   guint16 gr, el;
+   guint32 lgr;
+   const char * val;
+   string vr;
+   guint32 val_uint32;
+   guint16 val_uint16;
+
+   vector<string> tokens;
+
+   void *ptr;
+
+   for (TagElValueHT::iterator tag2 = tagHt.begin();
+        tag2 != tagHt.end();
+        ++tag2){
+
+      gr =  tag2->second->GetGroup();
+      el =  tag2->second->GetElement();
+      lgr = tag2->second->GetLength();
+      val = tag2->second->GetValue().c_str();
+      vr =  tag2->second->GetVR();
+      if(DEBUG)printf ("%04x %04x [%s] : [%s]\n",gr, el, vr.c_str(), val);
+
+      if ( type == ACR ) { 
+         if (gr < 0x0008) continue;
+         if (gr %2)   continue;
+         if (vr == "SQ" ) continue;
+      } 
+
+
+      fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp);  //group
+      fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp);  //element
+
+      if ( (type == ExplicitVR) && (gr <= 0x0002) ) {
+         // On est en EXPLICIT VR
+         guint16 z=0, shortLgr;
+         fwrite (vr.c_str(),(size_t)2 ,(size_t)1 ,_fp);
+
+         if ( (vr == "OB") || (vr == "OW") || (vr == "SQ") ) {
+            fwrite ( &z,  (size_t)2 ,(size_t)1 ,_fp);
+            fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);
+
+         } else {
+            shortLgr=lgr;
+            fwrite ( &shortLgr,(size_t)2 ,(size_t)1 ,_fp);
+         }
+      } else {
+         fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);
+      }
+
+      tokens.erase(tokens.begin(),tokens.end());
+      Tokenize (tag2->second->GetValue(), tokens, "\\");
+
+      if (vr == "US" || vr == "SS") {
+         for (unsigned int i=0; i<tokens.size();i++) {
+            val_uint16 = atoi(tokens[i].c_str());
+            ptr = &val_uint16;
+            fwrite ( ptr,(size_t)2 ,(size_t)1 ,_fp);
+         }
+         continue;
+      }
+      if (vr == "UL" || vr == "SL") {
+         for (unsigned int i=0; i<tokens.size();i++) {
+            val_uint32 = atoi(tokens[i].c_str());
+            ptr = &val_uint32;
+            fwrite ( ptr,(size_t)4 ,(size_t)1 ,_fp);
+         }
+         continue;
+      }
+
+      // Les pixels ne sont pas chargés dans l'element !
+      if ((gr == 0x7fe0) && (el == 0x0010) ) break;
+
+      fwrite ( val,(size_t)lgr ,(size_t)1 ,_fp); //valeur Elem
+   }
+}
+
+// Sorry for the DEBUG's, but tomorow is gonna be hoter than today
+
+int gdcmElValSet::Write(FILE * _fp) {
+
+       guint16 gr, el;
+       guint32 lgr;
+       const char * val;
+       string vr;
+       guint32 val_uint32;
+       guint16 val_uint16;
        
+       vector<string> tokens;
+       
+       void *ptr;
+       
+       string implicitVRTransfertSyntax = "1.2.840.10008.1.2";
+       SetElValueByNumber(implicitVRTransfertSyntax, 0x0002, 0x0010);  
+   //FIXME Refer to standards on page 21, chapter 6.2 "Value representation":
+   //      values with a VR of UI shall be padded with a single trailing null
+   //      Dans le cas suivant on doit pader manuellement avec un 0.
+       SetElValueLengthByNumber(18, 0x0002, 0x0010); 
+       
+       // Question :
+       // Comment pourrait-on tester si on est TrueDicom ou non ,
+       // (FileType est un champ de gdcmHeader ...)
+       //
+   UpdateGroupLength();
+
        // restent à tester les echecs en écriture (apres chaque fwrite)
        
        for (TagElValueHT::iterator tag2 = tagHt.begin();
@@ -269,8 +325,6 @@ int gdcmElValSet::Write(FILE * _fp) {
                fwrite ( &gr,(size_t)2 ,(size_t)1 ,_fp);        //group
                fwrite ( &el,(size_t)2 ,(size_t)1 ,_fp);        //element
                
-               //fwrite ( vr,(size_t)2 ,(size_t)1 ,_fp);       //VR
-               
                // si on n'est pas en IMPLICIT VR voir pb (lgr  + VR)
                
                fwrite ( &lgr,(size_t)4 ,(size_t)1 ,_fp);       //lgr
@@ -278,8 +332,6 @@ int gdcmElValSet::Write(FILE * _fp) {
                tokens.erase(tokens.begin(),tokens.end());
                Tokenize (tag2->second->GetValue(), tokens, "\\");
                
-               //if (tokens.size() > 1) { printf ("size : %d\n",tokens.size());}
-               
                if (vr == "US" || vr == "SS") {
                        for (unsigned int i=0; i<tokens.size();i++) {
                                val_uint16 = atoi(tokens[i].c_str());           
@@ -324,84 +376,17 @@ int gdcmElValSet::WriteAcr(FILE * _fp) {
        void *ptr;
        
        //string implicitVRTransfertSyntax = "1.2.840.10008.1.2"; // supprime par rapport à Write
-       
-       // Utilisées pour le calcul Group Length
+   //CLEANME Utilisées pour le calcul Group Length
+   //CLEANMEguint32 lgrCalcGroupe=0;
+   //CLEANMEgdcmElValue *elem, *elemZ, *elemZPrec;
+   //CLEANMEguint16 grCourant = 0;
+  
+   // Question :
+   // Comment pourrait-on tester si on est TrueDicom ou non ,
+   // (FileType est un champ de gdcmHeader ...)
+   //
+   UpdateGroupLength(true);
 
-       guint32 lgrCalcGroupe=0;
-       gdcmElValue *elem, *elemZ, *elemZPrec;
-       guint16 grCourant = 0;
-       
-       // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
-       // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
-       // dans l'image native
-       //
-       // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
-                                       
-       TagElValueHT::iterator tag = tagHt.begin();
-       
-       elem = tag->second;
-       gr   = elem->GetGroup();
-       el   = elem->GetElement();
-                       
-       if (el != 0x0000) {
-               if(DEBUG)printf("ajout elem OOOO premiere fois\n");
-               gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
-               elemZPrec = new gdcmElValue(tagZ);      // on le cree
-               elemZPrec->SetLength(4);
-               Add(elemZPrec);                         // On l'accroche à sa place
-       } else {
-               elemZPrec = elem;
-               if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
-       }
-       lgrCalcGroupe = 0;
-       if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
-       grCourant = gr;
-       
-       for (tag = ++tagHt.begin();
-                 tag != tagHt.end();
-                 ++tag){
-                 
-               elem = tag->second;
-               gr = elem->GetGroup();
-               el = elem->GetElement();
-               vr = elem->GetVR();
-               
-               if (vr == "SQ") continue;       // pas SEQUENCE en ACR-NEMA
-                                               // WARNING : risque de pb 
-                                               // si on est descendu 'a l'interieur' des SQ    
-
-               if ( (gr != grCourant) /*&&     // On arrive sur un nv Groupe     
-                    (el != 0xfffe) */  ) {
-                           
-                       if (el != 0x0000) {
-                               gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
-                               elemZ = new gdcmElValue(tagZ); // on le cree
-                               elemZ->SetLength(4);
-                               Add(elemZ);                     // On l'accroche à sa place 
-                               if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
-                       } else { 
-                               elemZ=elem;
-                               if(DEBUG)printf("maj elmeZ\n");
-                       }
-                       
-                       ostringstream f;
-                       f << lgrCalcGroupe; 
-                       elemZPrec->SetValue(f.str());
-                       if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, f.str().c_str(), grCourant);
-                       if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),
-                                                       elemZPrec->GetValue().c_str());
-                       if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
-                       elemZPrec=elemZ;
-                       lgrCalcGroupe = 0;
-                       grCourant     = gr;     
-                       if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);                    
-               } else {                        // On n'EST PAS sur un nv Groupe
-                       lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength();  // Gr + Num + Lgr + LgrElem
-                       if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), el, 
-                                                       lgrCalcGroupe, gr);
-               }               
-       }
-       
        // Si on fait de l'implicit VR little Endian 
        // (pour moins se fairche sur processeur INTEL)
        // penser a forcer le TRANSFERT SYNTAX UID
@@ -488,89 +473,24 @@ int gdcmElValSet::WriteExplVR(FILE * _fp) {
 
        string explicitVRTransfertSyntax = "1.2.840.10008.1.2.1";
        
-       // Utilisées pour le calcul Group Length
-       guint32 lgrCalcGroupe=0;
-       gdcmElValue *elem, *elemZ, *elemZPrec;
-       guint16 grCourant = 0;
        
        // Question :
        // Comment pourrait-on tester si on est TrueDicom ou non ,
        // (FileType est un champ de gdcmHeader ...)
        //
 
-       // On parcourt la table pour recalculer la longueur des 'elements 0x0000'
-       // au cas ou un tag ai été ajouté par rapport à ce qui a été lu
-       // dans l'image native
-       //
-       // cf : code IdDcmWriteFile dans libido/src/dcmwrite.c
-               
-               
        // On fait de l'Explicit VR little Endian 
        
                                
        SetElValueByNumber(explicitVRTransfertSyntax, 0x0002, 0x0010);  
        SetElValueLengthByNumber(20, 0x0002, 0x0010);  // Le 0 de fin de chaine doit etre stocké, dans ce cas  // ???   
                        
-       TagElValueHT::iterator tag = tagHt.begin();
-       
-       elem = tag->second;
-       gr   = elem->GetGroup();
-       el   = elem->GetElement();
-                       
-       if (el != 0x0000) {
-               if(DEBUG)printf("ajout elem OOOO premiere fois\n");
-               gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
-               elemZPrec = new gdcmElValue(tagZ);      // on le cree
-               elemZPrec->SetLength(4);
-               Add(elemZPrec);                         // On l'accroche à sa place
-       } else {
-               elemZPrec = elem;
-               if(DEBUG)printf("Pas d'ajout elem OOOO premiere fois\n");
-       }
-       lgrCalcGroupe = 0;
-       if(DEBUG)printf("init-1 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);
-       grCourant = gr;
-       
-       for (tag = ++tagHt.begin();
-                 tag != tagHt.end();
-                 ++tag){
-                 
-               elem = tag->second;
-               gr = elem->GetGroup();
-               el = elem->GetElement();
+   // Question :
+   // Comment pourrait-on tester si on est TrueDicom ou non ,
+   // (FileType est un champ de gdcmHeader ...)
+   //
+   UpdateGroupLength();
 
-               if ( (gr != grCourant) /*&&     // On arrive sur un nv Groupe     
-                    (el != 0xfffe) */  ) {
-                           
-                       if (el != 0x0000) {
-                               gdcmDictEntry * tagZ = new gdcmDictEntry(gr, 0x0000, "UL");
-                               elemZ = new gdcmElValue(tagZ); // on le cree
-                               elemZ->SetLength(4);
-                               Add(elemZ);                     // On l'accroche à sa place 
-                               if(DEBUG)printf("ajout elem OOOO pour gr %04x\n",gr);
-                       } else { 
-                               elemZ=elem;
-                               if(DEBUG)printf("maj elemZ\n");
-                       }
-                       
-                       ostringstream f;
-                       f << lgrCalcGroupe; 
-                       //sprintf(str_lgrCalcGroupe,"%d",lgrCalcGroupe);
-                       elemZPrec->SetValue(f.str());
-                       if(DEBUG)printf("ecriture lgr (%d, %s) pour gr %04x\n",lgrCalcGroupe, f.str().c_str(), grCourant);
-                       if(DEBUG)printf ("%04x %04x [%s]\n",elemZPrec->GetGroup(), elemZPrec->GetElement(),
-                                                       elemZPrec->GetValue().c_str());
-                       if(DEBUG)cout << "Addresse elemZPrec " << elemZPrec<< endl;
-                       elemZPrec=elemZ;
-                       lgrCalcGroupe = 0;
-                       grCourant     = gr;     
-                       if(DEBUG)printf("init-2 lgr (%d) pour gr %04x\n",lgrCalcGroupe, gr);                    
-               } else {                        // On n'EST PAS sur un nv Groupe
-                       lgrCalcGroupe += 2 + 2 + 4 + elem->GetLength();  // Gr + Num + Lgr + LgrElem
-                       if(DEBUG)printf("increment (%d) el %04x-->lgr (%d) pour gr %04x\n",elem->GetLength(), 
-                                                       el, lgrCalcGroupe, gr);
-               }               
-       }
                
        // restent à tester les echecs en écriture (apres chaque fwrite)
        
index b2ff14c6c616e470da9105f1dfd1663aad093183..d5494a7d31597bc5054cd716a31bf59a2dda028e 100644 (file)
@@ -1,4 +1,4 @@
-// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.6 2003/04/01 14:07:40 jpr Exp $
+// $Header: /cvs/public/gdcm/src/Attic/gdcmElValSet.h,v 1.7 2003/04/07 15:04:40 frog Exp $
 
 #ifndef GDCMELVALSET_H
 #define GDCMELVALSET_H
@@ -16,6 +16,11 @@ typedef map<string, gdcmElValue*> TagElValueNameHT;
 class GDCM_EXPORT gdcmElValSet {
        TagElValueHT tagHt;             // Both accesses with a TagKey or with a
        TagElValueNameHT NameHt;        // the DictEntry.Name are required.
+//FIXME This is redundant with gdcmHeader::FileType enum. That sux !
+enum FileType {
+      TrueDicom,
+      ExplicitVR,
+      ACR};
 public:        
        void Add(gdcmElValue*); 
        // TODO
@@ -26,20 +31,24 @@ public:
        int  WriteAcr(FILE *fp);
        int  WriteExplVR(FILE *fp);
 
-       gdcmElValue* GetElementByNumber(guint32 group, guint32 element);
+       gdcmElValue* GetElementByNumber(guint16 group, guint16 element);
        gdcmElValue* GetElementByName  (string);
-       string   GetElValueByNumber(guint32 group, guint32 element);
+       string   GetElValueByNumber(guint16 group, guint16 element);
        string   GetElValueByName  (string);
        
        TagElValueHT & GetTagHt(void);  
        
-       int SetElValueByNumber(string content, guint32 group, guint32 element);
+       int SetElValueByNumber(string content, guint16 group, guint16 element);
        int SetElValueByName  (string content, string TagName);
        
-       int SetElValueLengthByNumber(guint32 l, guint32 group, guint32 element);
+       int SetElValueLengthByNumber(guint32 l, guint16 group, guint16 element);
        int SetElValueLengthByName  (guint32 l, string TagName);
+
+   guint32 GenerateFreeTagKeyInGroup(guint16 group);
        
-   guint32 GenerateFreeTagKeyInGroup(guint32 group);
+private:
+   void UpdateGroupLength(bool SkipSequence = false);
+   void WriteElements(FileType type, FILE *);
 
 };
 
index 5ae6e8b769fd95e82ad9530a98fe814c63f72b67..f6cf79c91cb22a93595f09bc8690323514152f1b 100644 (file)
@@ -27,9 +27,13 @@ gdcmFile::gdcmFile(string & filename)
 {
 }
 
+gdcmFile::gdcmFile(const char * filename) 
+       :gdcmHeader(filename)   
+{
+}
+
 
 /////////////////////////////////////////////////////////////////
-// FIXME JPR: comments in English please !
 /**
  * \ingroup   gdcmFile
  * \brief     Renvoie la longueur A ALLOUER pour recevoir les pixels de l'image
@@ -397,16 +401,19 @@ int gdcmFile::WriteDcm (string nomFichier) {
        fclose (fp1);
        return(1);
 }
+
+int gdcmFile::WriteDcm (const char* nomFichier) {
+   WriteDcm (string (nomFichier));
+}
        
        
 /////////////////////////////////////////////////////////////////
 /**
  * \ingroup   gdcmFile
- * \ TODO
  *
- * @param 
+ * @param  nomFichier TODO JPR
  *
- * @return     
+ * @return TODO JPR
  */
 
 int gdcmFile::WriteDcmExplVR (string nomFichier) {
index fa41817c8be4bbbd7d9d9ef315f40da266c0e109..82b02c65667301bfa8868e1664861e5e77c7be62 100644 (file)
@@ -44,6 +44,7 @@ public:
        //    seen as a side effect).
        
        gdcmFile(string & filename);
+       gdcmFile(const char * filename);
        
        // For promotion (performs a deepcopy of pointed header object)
        // TODO Swig gdcmFile(gdcmHeader* header);
@@ -90,6 +91,7 @@ public:
                
        int WriteRawData        (string nomFichier);
        int WriteDcm            (string nomFichier);
+       int WriteDcm            (const char * nomFichier);
        int WriteDcmExplVR      (string nomFichier);
        int WriteAcr            (string nomFichier);
 };
index fdc6dee91ebae49d0ea5215f5066343e68a5229d..f5f385b2b0266897f3ad6bfc5fb278cccaf82bf2 100644 (file)
@@ -44,7 +44,6 @@ gdcmHeader::gdcmHeader(const char *InFilename, bool exception_on_error)
     dbg.Error(!fp, "gdcmHeader::gdcmHeader cannot open file", InFilename);
   ParseHeader();
   LoadElements();
-  AddAndDefaultElements();
 }
 
 
@@ -146,8 +145,12 @@ void gdcmHeader::CheckSwap()
       // * the 4 bytes of the first tag (0002, 0000),or (0002, 0001)
       // i.e. a total of  136 bytes.
       entCur = deb + 136;
+      ///// FIXME
+      ///// Use gdcmHeader::dicom_vr to test all the possibilities
+      ///// insteadn of just checking for UL, OB and UI !?
       if(  (memcmp(entCur, "UL", (size_t)2) == 0) ||
-          (memcmp(entCur, "OB", (size_t)2) == 0) )
+         (memcmp(entCur, "OB", (size_t)2) == 0) ||
+         (memcmp(entCur, "UI", (size_t)2) == 0) )
        {
          filetype = ExplicitVR;
          dbg.Verbose(1, "gdcmHeader::CheckSwap:",
@@ -494,6 +497,18 @@ bool gdcmHeader::IsJPEGSpectralSelectionProcess6_8TransferSyntax(void) {
       return true;
    return false;
 }
+/**
+ * \ingroup gdcmHeader
+ * \brief   Predicate for dicom version 3 file.
+ * @return  True when the file is a dicom version 3.
+ */
+bool gdcmHeader::IsDicomV3(void) {
+   if (   (filetype == TrueDicom)
+       || (filetype == ExplicitVR)
+       || (filetype == ImplicitVR) )
+      return true;
+   return false;
+}
 
 /**
  * \ingroup gdcmHeader
@@ -1390,108 +1405,99 @@ void gdcmHeader::ParseHeader(bool exception_on_error) throw(gdcmFormatError) {
 
 /**
  * \ingroup gdcmHeader
- * \brief   accessor to get Rows nbr
+ * \brief   Retrieve the number of columns of image.
+ * @return  The encountered size when found, 0 by default.
  */
-string gdcmHeader::GetYSize(void) {
-       return (GetElValByName("Rows"));
+int gdcmHeader::GetXSize(void) {
+   // We cannot check for "Columns" because the "Columns" tag is present
+   // both in IMG (0028,0011) and OLY (6000,0011) sections of the dictionary.
+   string StrSize = GetPubElValByNumber(0x0028,0x0011);
+   if (StrSize == "gdcm::Unfound")
+      return 0;
+   return atoi(StrSize.c_str());
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   accessor to get Columns nbr
+ * \brief   Retrieve the number of lines of image.
+ * \warning The defaulted value is 1 as opposed to gdcmHeader::GetXSize()
+ * @return  The encountered size when found, 1 by default.
  */
-string gdcmHeader::GetXSize(void) {
-       return (GetElValByName("Columns"));
+int gdcmHeader::GetYSize(void) {
+   // We cannot check for "Rows" because the "Rows" tag is present
+   // both in IMG (0028,0010) and OLY (6000,0010) sections of the dictionary.
+   string StrSize = GetPubElValByNumber(0x0028,0x0010);
+   if (StrSize != "gdcm::Unfound")
+      return atoi(StrSize.c_str());
+   if ( IsDicomV3() )
+      return 0;
+   else
+      // The Rows (0028,0010) entry is optional for ACR/NEMA. It might
+      // hence be a signal (1d image). So we default to 1:
+      return 1;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   accessor to get Planes nbr
- * (ACR-NEMA volume file or Multiframe Dicom V3 image file)
+ * \brief   Retrieve the number of planes of volume or the number
+ *          of frames of a multiframe.
+ * \warning When present we consider the "Number of Frames" as the third
+ *          dimension. When absent we consider the third dimension as
+ *          being the "Planes" tag content.
+ * @return  The encountered size when found, 1 by default.
  */
-string gdcmHeader::GetZSize(void) {
-       string NewVal;
-       NewVal = GetElValByNumber(0x0028,0x0008); // Number of Frames (DICOM)
-
-       if (NewVal == "gdcm::Unfound") {
-               NewVal = GetElValByNumber(0x0028,0x0012); // Planes (ACR-NEMA)
-                               // 6000 0012 : US OLY Planes
-                               // 'xxxByName' function not applicable
-               if (NewVal == "gdcm::Unfound") {
-                       NewVal = "0";
-               }
-       }
-       return(NewVal);
+int gdcmHeader::GetZSize(void) {
+   // Both in DicomV3 and ACR/Nema the consider the "Number of Frames"
+   // as the third dimension.
+   string StrSize = GetPubElValByNumber(0x0028,0x0008);
+   if (StrSize != "gdcm::Unfound")
+      return atoi(StrSize.c_str());
+
+   // We then consider the "Planes" entry as the third dimension [we
+   // cannot retrieve by name since "Planes tag is present both in
+   // IMG (0028,0012) and OLY (6000,0012) sections of the dictionary]. 
+   StrSize = GetPubElValByNumber(0x0028,0x0012);
+   if (StrSize != "gdcm::Unfound")
+      return atoi(StrSize.c_str());
+   return 1;
 }
 
 /**
  * \ingroup gdcmHeader
- * \brief   accessor to get Pixel Type 
- * (U8, S8, U16, S16, U32, S32)
- *
- * \warning : NOT YET MADE
- * 
+ * \brief   Build the Pixel Type of the image.
+ *          Possible values are:
+ *          - U8  unsigned  8 bit,
+ *          - S8    signed  8 bit,
+ *          - U16 unsigned 16 bit,
+ *          - S16   signed 16 bit,
+ *          - U32 unsigned 32 bit,
+ *          - S32   signed 32 bit,
+ * \warning 12 bit images appear as 16 bit.
+ * @return 
  */
 string gdcmHeader::GetPixelType(void) {
-   string NewVal;
-   // TODO
-   return(NewVal);
-}
-
-/**
- * \ingroup gdcmHeader
- * \brief   Once the header is parsed add some gdcm convenience/helper elements
- *          in the gdcmElValSet. For example add:
- *          - gdcmImageType which is an entry containing a short for the
- *            type of image and whose value ranges in 
- *               I8   (unsigned 8 bit image)
- *               I16  (unsigned 8 bit image)
- *               IS16 (signed 8 bit image)
- *                                             Replace by U8, S8, U16, S16, U32, S32 
- *
- *          - gdcmXsize, gdcmYsize, gdcmZsize whose values are respectively
- *            the ones of the official DICOM fields Rows, Columns and [Number of Frames/Planes]
- */
-void gdcmHeader::AddAndDefaultElements(void) {
-   gdcmElValue* NewElVal = (gdcmElValue*)0;
-   string NewVal;
-
-   NewElVal = NewManualElValToPubDict("gdcmXSize", "US");
-   if (!NewElVal) return;
-   NewVal = GetElValByName("Rows");
-   if (NewVal != "gdcm::Unfound")
-      NewElVal->SetValue(NewVal);
-   else 
-      NewElVal->SetValue("0");
-
-   NewElVal = NewManualElValToPubDict("gdcmYSize", "US");
-   if (!NewElVal) return;
-   NewVal = GetElValByName("Columns");
-   if (NewVal != "gdcm::Unfound")
-      NewElVal->SetValue(NewVal);
+   string BitsAlloc;
+   BitsAlloc = GetElValByName("Bits Allocated");
+   if (BitsAlloc == "gdcm::Unfound") {
+      dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
+      BitsAlloc = string("16");
+   }
+   if (BitsAlloc == "12")
+      BitsAlloc = string("16");
+
+   string Signed;
+   Signed = GetElValByName("Pixel Representation");
+   if (Signed == "gdcm::Unfound") {
+      dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
+      BitsAlloc = string("0");
+   }
+   if (Signed == "0")
+      Signed = string("U");
    else
-      NewElVal->SetValue("0");
-
-
-   NewElVal = NewManualElValToPubDict("gdcmZSize", "US");
-   if (!NewElVal) return;
-   NewVal = GetElValByNumber(0x0028,0x0008); // 0028 0008 IS IMG Number of Frames (DICOM)
-   if (NewVal == "gdcm::Unfound") {
-       NewVal = GetElValByNumber(0x0028,0x0012); // 028 0012 US IMG Planes (ACR-NEMA)
-       if (NewVal == "gdcm::Unfound") {          // Warning !!! : 6000 0012 US OLY Planes
-               NewElVal->SetValue("0");
-       } else {
-               NewElVal->SetValue(NewVal);
-       }               
-   } else {
-      NewElVal->SetValue(NewVal);
-   }                                           // length is still wrong 
-}                                              // do we care about it?
+      Signed = string("S");
 
+   return( BitsAlloc + Signed);
+}
 
 /**
  * \ingroup gdcmHeader
@@ -1518,13 +1524,11 @@ bool gdcmHeader::IsReadable(void) {
    return true;
 }
 
-
 /**
  * \ingroup gdcmHeader
  * \brief   Small utility function that creates a new manually crafted
  *          (as opposed as read from the file) gdcmElValue with user
  *          specified name and adds it to the public tag hash table.
- *          Refer to gdcmHeader::AddAndDefaultElements for a typical usage.
  * \note    A fake TagKey is generated so the PubDict can keep it's coherence.
  * @param   NewTagName The name to be given to this new tag.
  * @param   VR The Value Representation to be given to this new tag.
index c733cd5435fa406d8d9e8be4c5cb98abe6c1257e..b69cb7f70246f0eb2fb0a806a011d9ac163f5b37 100644 (file)
@@ -79,8 +79,8 @@ private:
    void CheckSwap(void);
    void InitVRDict(void);
    void SwitchSwapToBigEndian(void);
+   // CLEAN ME: NewManualElValToPubDict is NOT called any more.
    gdcmElValue*  NewManualElValToPubDict(string NewTagName, string VR);
-   void AddAndDefaultElements(void);
    void SetMaxSizeLoadElementValue(long);
 
    gdcmDictEntry * GetDictEntryByKey(guint16, guint16);
@@ -109,6 +109,7 @@ private:
    bool IsJPEGSpectralSelectionProcess6_8TransferSyntax(void); 
    
    bool IsJPEGLossless(void); 
+   bool IsDicomV3(void); 
       
 protected:
    // FIXME: is this enum still necessary ??
@@ -169,13 +170,9 @@ public:
 
    gdcmElValSet GetPubElValSet() { return(PubElValSet); }
    
-   // a mettre en inline
-   // --> ou met-on les doxygeneries ?
-   
-   string GetXSize(void);  
-   string GetYSize(void);
-    
-   string GetZSize(void);       
+   int GetXSize(void);  
+   int GetYSize(void);
+   int GetZSize(void);       
    string GetPixelType(void);  
    
 };