]> Creatis software - gdcm.git/blob - Example/exCurveData.cxx
Coding style + minor modif
[gdcm.git] / Example / exCurveData.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: exCurveData.cxx,v $
5   Language:  C++
6   Date:      $Date: 2007/05/23 14:18:05 $
7   Version:   $Revision: 1.6 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 #include "gdcmFile.h"
19 #include "gdcmFileHelper.h"
20 #include "gdcmCommon.h"
21 #include "gdcmDebug.h"
22 #include "gdcmDocEntry.h"
23 #include "gdcmDataEntry.h"
24
25 static const char* TypeOfDataArrays[13][2] = {
26     { "TAC" , "time activity curve" },
27     { "PROF" , "image profile" },
28     { "HIST" , "histogram" },
29     { "ROI" , "polygraphic region of interest" },
30     { "TABL" , "table of values" },
31     { "FILT" , "filter kernel" },
32     { "POLY" , "poly line" },
33     { "ECG" , "ecg data" },
34     { "PRESSURE" , "pressure data" },
35     { "FLOW" , "flow data" },
36     { "PHYSIO" , "physio data" },
37     { "RESP" , "Respiration trace" },
38     { NULL, NULL }
39 };
40
41 // Part 3, C.10.2.1.1 Type of data
42 // Convert from acronym to full description
43 const char *ConvertTypeOfData(std::string const &type)
44 {
45   const char **p = *TypeOfDataArrays;
46   while(*p != NULL)
47     {
48     if( p[0] == type ) // std::string== operator
49       {
50       // ok we found it:
51       return p[1];
52       }
53     p+=2;
54     }
55   return NULL;
56 }
57
58 // Helper function
59 template<class DataValueRepresentation>
60 inline size_t PrintCurveData(DataValueRepresentation* data, unsigned short numPts)
61 {
62    for(unsigned int i=0; i<numPts;++i)
63      {
64      std::cout << "Pt(" << i <<  ") = " << data[i] << std::endl;
65      }
66
67    // ok this is ugly but I need the size outside of the function
68    return sizeof(DataValueRepresentation);
69 }
70  
71 /*
72  // Example (sorry, we've got no more than this one ...)
73  * V 5004|0000 [UL]                  [Group Length] [1998] x(7ce)
74  * V 5004|0005 [US]              [Curve Dimensions] [1] x(1)
75  * V 5004|0010 [US]              [Number of Points] [969] x(3c9)
76  * V 5004|0020 [CS]                  [Type of Data] [PHYSIO]
77  * V 5004|0022 [LO]             [Curve Description] []
78  * V 5004|0103 [US]     [Data Value Representation] [0] x(0)
79  * B 5004|3000 [OW]                    [Curve Data] [GDCM_NAME_SPACE::Binary data loaded;length = 1938]
80  */
81  
82 int main(int argc, char *argv[])
83 {  
84    GDCM_NAME_SPACE::File *f;
85  
86    std::cout << "------------------------------------------------" << std::endl;
87    std::cout << "Gets the 'Curve Data' from a full gdcm-readable DICOM " << std::endl;
88    std::cout << "(Note :  we just have ONE image : "
89              << "GE_DLX-8-MONO2-Multiframe.dcm"
90              << std::endl;
91    std::cout << "------------------------------------------------" << std::endl;
92
93    std::string fileName;
94    if( argc > 1 )
95       fileName = argv[1];
96    else
97       fileName = "GE_DLX-8-MONO2-Multiframe.dcm";
98
99    std::cout << fileName << std::endl;
100 // ============================================================
101 //   Read the input image.
102 // ============================================================
103
104    f = GDCM_NAME_SPACE::File::New( );
105
106    f->SetLoadMode(GDCM_NAME_SPACE::LD_NOSEQ | GDCM_NAME_SPACE::LD_NOSHADOW);
107    f->SetFileName( fileName );
108    bool res = f->Load();  
109
110    if( GDCM_NAME_SPACE::Debug::GetDebugFlag() )
111    {
112       std::cout << "---------------------------------------------" << std::endl;
113       f->Print();
114       std::cout << "---------------------------------------------" << std::endl;
115    }
116    if (!res) {
117        std::cout << "Sorry, " << fileName <<"  not a gdcm-readable "
118            << "DICOM / ACR File"
119            <<std::endl;
120       f->Delete();
121       return 1;
122    }
123    std::cout << " ... is readable " << std::endl;
124
125 // ============================================================
126 //   Check whether image contains Overlays ACR-NEMA style.
127 // ============================================================
128
129    //* B 5004|3000 [OW]                    [Curve Data] [GDCM_NAME_SPACE::Binary data loaded;length = 1938]
130    std::string curve_data_str = f->GetEntryString(0x5004, 0x3000);
131    if (curve_data_str == GDCM_NAME_SPACE::GDCM_UNFOUND)
132    {
133       std::cout << " Image doesn't contain any Curve Data" << std::endl;
134       f->Delete();
135       return 1;
136    }
137    std::cout << " File is read! " << std::endl;
138
139
140 // ============================================================
141 //   Load the Curve Data in memory.
142 // ============================================================
143   std::istringstream convert;
144  //* V 5004|0005 [US]              [Curve Dimensions] [1] x(1)
145    std::string curve_dim_str = f->GetEntryString(0x5004,0x0005);
146    unsigned short curve_dim;
147    convert.str(curve_dim_str);
148    convert >> curve_dim;
149    std::cout << "Curve Dimensions: " << curve_dim << std::endl;
150  //* V 5004|0010 [US]              [Number of Points] [969] x(3c9)
151    std::string num_points_str = f->GetEntryString(0x5004,0x0010);
152    unsigned short num_points;
153    convert.clear(); //important
154    convert.str(num_points_str);
155    convert >> num_points;
156    std::cout << "Number of Points: " << num_points << std::endl;
157  //* V 5004|0020 [CS]                  [Type of Data] [PHYSIO]
158    std::string data_type = f->GetEntryString(0x5004,0x0020);
159    std::cout << "Type of Data: " << data_type << std::endl;
160    std::cout << " this is thus a : " << ConvertTypeOfData(data_type) << std::endl;
161  //* V 5004|0022 [LO]             [Curve Description] []
162    std::string curve_desc = f->GetEntryString(0x5004,0x0022);
163    std::cout << "Curve Description: " << curve_desc << std::endl;
164  //* V 5004|0103 [US]     [Data Value Representation] [0] x(0)
165    std::string data_rep_str = f->GetEntryString(0x5004,0x0103);
166    unsigned short data_rep;
167    convert.clear(); //important
168    convert.str(data_rep_str);
169    convert >> data_rep;
170
171
172    GDCM_NAME_SPACE::DocEntry *pCurveDataDoc = f->GetDocEntry(0x5004, 0x3000);
173    GDCM_NAME_SPACE::DataEntry *pCurveData = dynamic_cast<GDCM_NAME_SPACE::DataEntry *>(pCurveDataDoc);
174    uint8_t *curve_data = pCurveData->GetBinArea();
175    
176    // From Part3, C.10.2.1.2 Data value representation (p668)
177    size_t sz;
178    switch( data_rep)
179    {
180       case 0:
181          sz = PrintCurveData((unsigned short*)(curve_data), num_points);
182          break;
183       case 1:
184          sz = PrintCurveData((signed short*)(curve_data), num_points);
185          break;
186       case 2:
187          sz = PrintCurveData((float*)(curve_data), num_points);
188          break;
189       case 3:
190          sz = PrintCurveData((double*)(curve_data), num_points);
191          break;
192       case 4:
193          sz = PrintCurveData((signed long*)(curve_data), num_points);
194          break;
195       default:
196          std::cerr << "Error don't know the type: " << data_rep_str << std::endl;
197          f->Delete();
198          return 1;
199    }
200    // Just to make sure that values read are consistant and we won't read out of bound data:
201    assert( sz*num_points == pCurveData->GetLength());
202
203    // Write out the data as a file:
204    //std::ofstream o("/tmp/curve_data.raw");
205    //o.write((char*)curve_data, num_points*sz);
206    //o.close();
207
208    f->Delete();
209    return 0;
210 }
211
212