]> Creatis software - gdcm.git/blob - Example/exExtractOverlaysDCM.cxx
Avoid warning
[gdcm.git] / Example / exExtractOverlaysDCM.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: exExtractOverlaysDCM.cxx,v $
5   Language:  C++
6   Date:      $Date: 2007/09/14 08:23:34 $
7   Version:   $Revision: 1.2 $
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 "gdcmDataEntry.h"
23 #include "gdcmDirList.h"
24 #include "gdcmArgMgr.h"
25
26 #include <iostream>
27
28 // Each BIT of Overlay Data (0x6000,0x3000) corresponds 
29 // to a BYTE of overlay image.
30 void explodeByte(unsigned char byte, unsigned char* result) 
31 {
32    unsigned char mask = 1;
33    for (int i=0;i<8;i++) 
34    {
35       if ((byte & mask)==0) 
36          result[i]=0;
37       else 
38          result[i]=1;
39       mask<<=1;
40    }
41    return;
42 }
43
44 int main(int argc, char *argv[])
45 {
46    START_USAGE(usage)
47    " \n ExtractOverlays :\n                                                   ",
48    " Extract DICOM style overlays from an image                               ",
49    " usage: exExtractOverlaysDCM filein=inputFileName  [debug]                ",
50    "        debug    : developper wants to run the program in 'debug mode'    ",
51    FINISH_USAGE
52
53    // ----- Initialize Arguments Manager ------
54    
55    GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
56
57    if (argc == 1 || am->ArgMgrDefined("usage"))
58    {
59       am->ArgMgrUsage(usage); // Display 'usage'
60       delete am;
61       return 0;
62    }
63
64    const char *fileName  = am->ArgMgrWantString("filein", usage);
65
66    if (am->ArgMgrDefined("debug"))
67       GDCM_NAME_SPACE::Debug::DebugOn();
68       
69    if (am->ArgMgrDefined("warning"))
70       GDCM_NAME_SPACE::Debug::WarningOn();
71       
72    // if unused Param we give up
73    if ( am->ArgMgrPrintUnusedLabels() )
74    {
75       am->ArgMgrUsage(usage);
76       delete am;
77       return 0;
78    }
79
80    delete am;  // we don't need Argument Manager any longer
81
82    // ========================== Now, we can do the job! ================ 
83
84    GDCM_NAME_SPACE::File *f;
85
86 // ============================================================
87 //   Read the input image.
88 // ============================================================
89
90    f = GDCM_NAME_SPACE::File::New( );
91    
92    f->AddForceLoadElement(0x6000,0x3000);  // Overlay Data
93    f->AddForceLoadElement(0x6002,0x3000); 
94    f->AddForceLoadElement(0x6004,0x3000); 
95    f->AddForceLoadElement(0x6006,0x3000);    
96    f->AddForceLoadElement(0x6008,0x3000);    
97    f->AddForceLoadElement(0x600a,0x3000); 
98    f->AddForceLoadElement(0x600c,0x3000); 
99    f->AddForceLoadElement(0x600e,0x3000);
100    f->AddForceLoadElement(0x6010,0x3000);
101    f->AddForceLoadElement(0x6012,0x3000);             
102    f->AddForceLoadElement(0x6014,0x3000);             
103    f->AddForceLoadElement(0x6016,0x3000); 
104    f->AddForceLoadElement(0x6018,0x3000); 
105    f->AddForceLoadElement(0x601a,0x3000);                
106    f->AddForceLoadElement(0x601c,0x3000); 
107    f->AddForceLoadElement(0x601e,0x3000); // Hope it's enought : Dicom says 60xx ...
108
109    f->SetLoadMode(GDCM_NAME_SPACE::LD_NOSEQ | GDCM_NAME_SPACE::LD_NOSHADOW);
110    f->SetFileName( fileName );
111    bool res = f->Load();
112
113    if (!res) {
114        std::cout << "Sorry, " << fileName <<"  not a gdcm-readable "
115            << "DICOM / ACR File"
116            <<std::endl;
117       f->Delete();
118       return 0;
119    }
120    std::cout << fileName << " ... is readable " << std::endl;
121
122 // ============================================================
123 //   Check whether image contains Overlays DICOM style.
124 // ============================================================
125
126    unsigned int nx = f->GetXSize();
127    unsigned int ny = f->GetYSize();
128    unsigned int nxy=nx*ny;   
129    uint16_t currentOvlGroup;
130    int i;
131
132    std::ostringstream str;
133
134    uint8_t *outputData = new uint8_t[nxy]; // uint8 is enought to hold 1 bit !
135
136    GDCM_NAME_SPACE::File *fileToBuild = 0;
137    GDCM_NAME_SPACE::FileHelper *fh = 0;
138
139 // ============================================================
140 //   Get each overlay 
141 // ============================================================
142    for(i=0, currentOvlGroup=0x6000; i<32; i+=2 ,currentOvlGroup+=2)
143    {
144       GDCM_NAME_SPACE::DataEntry *e10 = f->GetDataEntry(currentOvlGroup, 0x0010); // nb Row Ovly
145       if (e10 == 0)
146       {
147          if( GDCM_NAME_SPACE::Debug::GetWarningFlag() )
148             std::cout << " Image doesn't contain Overlay on " <<std::hex
149                       << currentOvlGroup+i << std::endl;
150          continue;
151       }
152
153       uint8_t *outputData = new uint8_t[nxy];
154
155       GDCM_NAME_SPACE::DataEntry *e = f->GetDataEntry(currentOvlGroup, 0x3000);
156       if (e == 0)
157       {
158          if( GDCM_NAME_SPACE::Debug::GetWarningFlag() )
159             std::cout << " Image doesn't contain DICOM Overlay Data " <<std::hex
160                       << currentOvlGroup+i << std::endl;
161       }
162       else
163       {
164          uint8_t *overlay = (uint8_t *)(e->GetBinArea());
165          if ( overlay == 0 )
166          {
167             std::cerr << "Sorry, Overlays of [" << fileName << "] are not "
168                        << " gdcm-readable."    << std::endl;
169              continue;
170          }
171          if( GDCM_NAME_SPACE::Debug::GetWarningFlag() )
172             std::cout << " Overlay on group [" << std::hex << currentOvlGroup<< "] is read! " << std::endl;
173
174       // ============================================================
175       //  DICOM Overlay Image data generation
176       // ============================================================
177
178          unsigned char *result=outputData;
179          for (unsigned int i=0;i<(nxy/8);i++)
180          {
181             explodeByte(overlay[i], result);
182             result+=8;
183          }
184       }
185    // ============================================================
186    //   Write a new file
187    // ============================================================
188
189       fileToBuild = GDCM_NAME_SPACE::File::New();
190       str.str("");
191       str << nx;
192       fileToBuild->InsertEntryString(str.str(),0x0028,0x0011, "US"); // Columns
193       str.str("");
194       str << ny;
195       fileToBuild->InsertEntryString(str.str(),0x0028,0x0010, "US"); // Rows
196
197       fileToBuild->InsertEntryString("8",0x0028,0x0100, "US"); // Bits Allocated
198       fileToBuild->InsertEntryString("8",0x0028,0x0101, "US"); // Bits Stored
199       fileToBuild->InsertEntryString("7",0x0028,0x0102, "US"); // High Bit
200       fileToBuild->InsertEntryString("0",0x0028,0x0103, "US"); // Pixel Representation
201       fileToBuild->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel
202       fileToBuild->InsertEntryString("MONOCHROME2 ",0x0028,0x0004, "LO");
203
204       // feel free to add any field (Dicom Data Entry) you like, here.
205       // ...
206       // Other mandatory fields will be set automatically,
207       // just before Write(), by FileHelper::CheckMandatoryElements()
208
209       fh = GDCM_NAME_SPACE::FileHelper::New(fileToBuild);
210
211       fh->SetImageData(outputData,nx*ny);
212       fh->SetWriteTypeToDcmExplVR();
213
214 std::ostringstream tmp;
215 tmp <<std::hex;
216 tmp <<currentOvlGroup;
217
218       str.str("");
219 // -> Why doesn't it work ?!?
220       //str << fileName << std::hex << currentOvlGroup << ".dcm" << std::ends;
221
222 str << fileName << ".ovly." << tmp.str() << ".dcm" << std::ends;
223
224       //   Write the current 'overlay' file
225
226       if( !fh->Write(str.str()) )
227       {
228          std::cout << "Failed\n"
229                    << "File [" << str.str() << "] is unwrittable" << std::endl;
230       }
231       else
232       {
233          std::cout << "File written successfully [" << str.str()  << "]" << std::endl;
234       }
235
236    } // end on loop on 60xx
237
238    if (f)
239       fh->Delete();
240    if (fileToBuild)
241       fileToBuild->Delete();
242    f->Delete();
243
244    return 0;
245 }
246