]> Creatis software - gdcm.git/blob - exOverlaysACR.cxx
00fa7520850e2002f58e46139ab9f7510e84242c
[gdcm.git] / exOverlaysACR.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: exOverlaysACR.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/07/07 17:31:54 $
7   Version:   $Revision: 1.4 $
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
24 #include <iostream>
25  #include <stdio.h>
26  
27  // WARNING :
28  // unfinished : DO NOT to be used as is !
29  
30  /*
31  // Example (sorry, we've got no more than this one ...)
32  
33 V 0028|0010[US] [Rows] [256] x(100)
34 V 0028|0011[US] [Columns] [256] x(100)
35 V 0028|0030[DS] [Pixel Spacing] [01.56\1.56]
36 V 0028|0100[US] [Bits Allocated] [16] x(10)
37 V 0028|0101[US] [Bits Stored] [12] x(c)
38 V 0028|0102[US] [High Bit] [11] x(b)
39 V 0028|0103[US] [Pixel Representation] [0] x(0)
40  
41 V 6000|0000[UL] [Group Length] [96] x(60)
42 V 6000|0010[US] [Rows] [256] x(100)
43 V 6000|0011[US] [Columns] [256] x(100)
44 V 6000|0040[CS] [Overlay Type] [R ]
45 V 6000|0050[SS] [Overlay Origin] [23601\8241] x(5c31)
46 V 6000|0100[US] [Overlay Bits Allocated] [16] x(10)
47 V 6000|0102[US] [Overlay Bit Position] [12] x(c)
48 ...
49 ...
50 V 6006|0000[UL] [Group Length] [96] x(60)
51 V 6006|0010[US] [Rows] [256] x(100)
52 V 6006|0011[US] [Columns] [256] x(100)
53 V 6006|0040[CS] [Overlay Type] [R ]
54 V 6006|0050[SS] [Overlay Origin] [23601\8241] x(5c31)
55 V 6006|0100[US] [Overlay Bits Allocated] [16] x(10)
56 V 6006|0102[US] [Overlay Bit Position] [15] x(f)
57  */
58  
59 int main(int argc, char *argv[])
60 {  
61    gdcm::File *f;
62  
63    //gdcm::Debug::DebugOn();
64
65    std::cout << "------------------------------------------------" << std::endl;
66    std::cout << "Gets the 'Overlays' from a full gdcm-readable ACR-NEMA "
67              << "uncompressed image" << std::endl;
68    std::cout << "Writes them in DicomV3 files named 'gdcmOverlay-xxx.dcm'"
69              << std::endl;
70    std::cout << "(Note :  we just have ONE image : "
71              << "SIEMENS_GBS_III-16-ACR_NEMA_1.acr)"
72              << std::endl;
73    std::cout << "------------------------------------------------" << std::endl;
74
75    std::string fileName;
76    if( argc > 1 )
77       fileName = argv[1];
78    else
79       fileName = "SIEMENS_GBS_III-16-ACR_NEMA_1.acr";  
80
81    std::cout << fileName << std::endl;
82 // ============================================================
83 //   Read the input image.
84 // ============================================================
85
86    //std::cout << argv[1] << std::endl;
87
88    f = new gdcm::File( );
89
90    f->SetLoadMode(NO_SEQ | NO_SHADOW);
91    f->SetFileName( fileName );
92    bool res = f->Load();  
93
94    if( gdcm::Debug::GetDebugFlag() )
95    {
96       std::cout << "---------------------------------------------" << std::endl;
97       f->Print();
98       std::cout << "---------------------------------------------" << std::endl;
99    }
100    if (!res) {
101        std::cout << "Sorry, " << fileName <<"  not a gdcm-readable "
102            << "DICOM / ACR File"
103            <<std::endl;
104       delete f;
105       return 0;
106    }
107    std::cout << " ... is readable " << std::endl;
108
109 // ============================================================
110 //   Check whether image contains Overlays ACR-NEMA style.
111 // ============================================================
112
113    int bitsAllocated = f->GetBitsAllocated();
114    if ( bitsAllocated <= 8 )
115    {
116       std::cout << " 8 bits pixel image cannot contain Overlays " << std::endl;
117       delete f;
118       return 0;
119    }
120    std::string s1 = f->GetEntryValue(0x6000, 0x0102);
121    if (s1 == gdcm::GDCM_UNFOUND)
122    {
123       std::cout << " Image doesn't contain any Overlay " << std::endl;
124       delete f;
125       return 0;
126    }
127    std::cout << " File is read! " << std::endl;
128
129    
130 // ============================================================
131 //   Load the pixels in memory.
132 // ============================================================
133
134    // We don't use a gdcm::FileHelper, since it rubs out 
135    // the 'non image' bits of the pixels...
136
137    int nx = f->GetXSize();
138    int ny = f->GetYSize();
139  
140    std::cout << "Dimensions " << ny << "  " <<ny << std::endl;
141
142    gdcm::DocEntry *p = f->GetDocEntry(f->GetGrPixel(), f->GetNumPixel());
143    if (p == 0)
144       std::cout << "Pixels element  not found" << std::endl;
145    else
146       std::cout << "Pixels element FOUND" << std::endl;
147
148    int offset = (int)(p->GetOffset());
149
150    std::cout << "Offset " << offset << std::endl;
151
152    FILE *fp = fopen(fileName.c_str(), "r");
153
154    if (fp == 0)
155    {
156       std::cout << "Unable to open File" << std::endl;
157       delete f;
158       return 0;
159    }
160    else
161       std::cout << "File open successfully" << std::endl; 
162   
163    fseek(fp, (long) offset,SEEK_SET);      
164    uint16_t *pixels = new uint16_t[nx*ny];
165    size_t lgt = fread(pixels, 1,  nx*ny*sizeof( uint16_t) , fp );   
166
167    if ( lgt != (size_t)nx*ny*sizeof( uint16_t) )
168    {
169        std::cout << "Sorry, Pixels of" << fileName << "  are not "
170                  << "readable. expected length :" << nx*ny 
171                  << "  " << "read length : " << lgt
172                  << std::endl;
173        delete f;
174        delete pixels;  
175        return 0;
176    }
177    else
178    {
179       std::cout << "Pixels read as expected : length = " << lgt << std::endl;
180    } 
181
182
183 // ============================================================
184 //   Get each overlay Bit into an image
185 // ============================================================
186                                          
187    uint8_t *tabPixels = new uint8_t[nx*ny]; // uint8 is enought to hold 1 bit !
188    
189    uint16_t currentOvlGroup = 0x6000;
190    std::string strOvlBitPosition;
191    int ovlBitPosition;
192    uint16_t mask;
193    int i = 0;
194    uint16_t overlayLocation;
195    std::ostringstream str;
196    std::string strOverlayLocation;
197    gdcm::File *fileToBuild = 0;
198    gdcm::FileHelper *fh = 0;
199
200       
201 while ( (strOvlBitPosition = f->GetEntryValue(currentOvlGroup, 0x0102)) 
202           != gdcm::GDCM_UNFOUND )
203 {
204
205       strOverlayLocation = f->GetEntryValue(currentOvlGroup, 0x0200);
206       if ( strOverlayLocation != gdcm::GDCM_UNFOUND )
207       {
208          overlayLocation = atoi(strOverlayLocation.c_str());
209          if ( overlayLocation != f->GetGrPixel() )
210          {
211             std::cout << "Big Trouble : Overlays are NOT in the Pixels Group "
212                       << std::hex << "(" << overlayLocation << " vs " 
213                       << f->GetGrPixel() << std::endl;
214             // Actually, here, we should (try to) read the overlay location
215             // and go on the job.
216             continue;
217          }
218       }
219       ovlBitPosition = atoi(strOvlBitPosition.c_str());
220       mask = 1 << ovlBitPosition; 
221       std::cout << "Mask :[" <<std::hex << mask << "]" << std::endl;          
222       for (int j=0; j<nx*ny ; j++)
223       {
224          if( gdcm::Debug::GetDebugFlag() )
225             if (pixels[j] >= 0x1000)// if it contains at least one overlay bit
226                printf("%d : %04x\n",j, pixels[j]);
227
228          if ( (pixels[j] & mask) == 0 )
229             tabPixels[j] = 0;
230          else
231             tabPixels[j] = 128;
232       }
233       if( gdcm::Debug::GetDebugFlag() )
234          std::cout << "About to built empty file"  << std::endl;
235
236       fileToBuild = new gdcm::File();
237
238       if( gdcm::Debug::GetDebugFlag() )
239          std::cout << "Finish to built empty file"  << std::endl;
240
241       str.str("");
242       str << nx;
243       fileToBuild->InsertValEntry(str.str(),0x0028,0x0011); // Columns
244       str.str("");
245       str << ny;
246       fileToBuild->InsertValEntry(str.str(),0x0028,0x0010); // Rows
247
248       fileToBuild->InsertValEntry("8",0x0028,0x0100); // Bits Allocated
249       fileToBuild->InsertValEntry("8",0x0028,0x0101); // Bits Stored
250       fileToBuild->InsertValEntry("7",0x0028,0x0102); // High Bit
251       fileToBuild->InsertValEntry("0",0x0028,0x0103); // Pixel Representation
252       fileToBuild->InsertValEntry("1",0x0028,0x0002); // Samples per Pixel
253
254       fileToBuild->InsertValEntry("MONOCHROME2 ",0x0028,0x0004);
255       // Other mandatory fields will be set automatically,
256       // just before Write(), by FileHelper::CheckMandatoryElements()
257
258       if( gdcm::Debug::GetDebugFlag() )
259          std::cout << "-------------About to built FileHelper"  << std::endl;
260
261       fh = new gdcm::FileHelper(fileToBuild);
262
263       if( gdcm::Debug::GetDebugFlag() )
264          std::cout << "-------------Finish to built FileHelper"  << std::endl;
265
266       fh->SetImageData(tabPixels,nx*ny);
267       fh->SetWriteTypeToDcmExplVR();
268
269       str.str("");
270       str<<"gdcmOverlay-"<<i << ".dcm";
271       //   Write the current 'overlay' file
272
273       if( !fh->Write(str.str()) )
274       {
275          std::cout << "Failed\n"
276                    << "File in unwrittable\n";
277          delete fh;
278          if (fileToBuild)
279             delete fileToBuild;
280          delete pixels;
281          delete tabPixels;
282          return 0;
283       }
284       else
285       {
286          std::cout << "File written successfully" << std::endl;
287       }
288       currentOvlGroup += 2;
289       i++;
290    }
291     
292    delete f;
293    if (f)
294       delete fh;
295    if (fileToBuild)
296       delete fileToBuild;
297    delete pixels;
298    delete tabPixels;
299    return 0;
300 }
301