]> Creatis software - gdcm.git/blob - Example/AnonymizeDicomDir.cxx
424390b5ddc444c250747ff763b2bda29b294536
[gdcm.git] / Example / AnonymizeDicomDir.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: AnonymizeDicomDir.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/06/07 11:12:10 $
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 "gdcmGlobal.h"
19 #include "gdcmCommon.h"
20 #include "gdcmDebug.h"
21 #include "gdcmUtil.h"
22
23 #include "gdcmSQItem.h"
24 #include "gdcmSeqEntry.h"
25 #include "gdcmValEntry.h"
26
27 #include "gdcmDocument.h"
28 #include "gdcmFile.h"
29
30 #include "gdcmArgMgr.h"
31
32 #include <iostream>
33
34 void AnoNoLoad(gdcm::SQItem *s, std::fstream *fp, 
35                uint16_t group, uint16_t elem, 
36                std::string val);
37
38 void AnoNoLoad(gdcm::SQItem *s, std::fstream *fp, 
39                uint16_t group, uint16_t elem, 
40                std::string val)
41 {
42    gdcm::DocEntry *d;
43    uint32_t offset;
44    uint32_t lgth;
45    uint32_t valLgth = 0;
46    std::string *spaces;
47    std::string v;
48
49    d = s->GetDocEntry( group, elem);
50
51    if ( d == NULL)
52       return;
53
54    if ( ! dynamic_cast<gdcm::ValEntry *>(d) )
55       return;
56
57    offset = d->GetOffset();
58    lgth =   d->GetLength();
59    if (valLgth < lgth)
60    {
61       spaces = new std::string( lgth-valLgth, ' ');
62       v = val + *spaces;
63       delete spaces;
64    }
65    fp->seekp( offset, std::ios::beg );
66    fp->write( v.c_str(), lgth );
67 }
68
69 int main(int argc, char *argv[])
70
71
72    START_USAGE(usage)
73    " \n AnonymizeDicomDir :\n",
74    " Anonymize a gdcm-readable DICOMDIR ",
75    "           even when some 'Objects' are not yet taken into account",
76    "           Warning : the DICOMDIR is overwritten",
77    " usage: AnonymizeDicomDir filein=dicomDirName [debug] ",
78    "        debug    : user wants to run the program in 'debug mode' ",
79    FINISH_USAGE
80
81    // ----- Initialize Arguments Manager ------   
82    gdcm::ArgMgr *am = new gdcm::ArgMgr(argc, argv);
83   
84    if (am->ArgMgrDefined("usage")) 
85    {
86       am->ArgMgrUsage(usage); // Display 'usage'
87       delete am;
88       return 0;
89    }
90  
91    char *fileName  = am->ArgMgrWantString("filein",usage); 
92
93    delete am;  // we don't need Argument Manager any longer
94
95 // ============================================================
96 //   Read the input DICOMDIR
97 // ============================================================
98
99    gdcm::File *f1 = new gdcm::File( fileName );
100    if (!f1->IsReadable()) {
101        std::cerr << "Sorry, " << fileName <<"  not a gdcm-readable "
102                  << "file" <<std::endl;
103    }
104    std::cout << " ... is readable " << std::endl;
105
106    // Directory record sequence
107    gdcm::DocEntry *e = f1->GetDocEntry(0x0004, 0x1220);
108    if ( !e )
109    {
110       std::cout << "No Directory Record Sequence (0004,1220) found" <<std::endl;;
111       delete f1;
112       delete e;
113       return 0;         
114    }
115    
116    gdcm::SeqEntry *s = dynamic_cast<gdcm::SeqEntry *>(e);
117    if ( !s )
118    {
119       std::cout << "Element (0004,1220) is not a Sequence ?!?" <<std::endl;
120       delete f1;
121       delete e;
122       return 0;
123    }
124
125    // Open the file LTTG (aka ALAP)
126    std::fstream *fp = new std::fstream(fileName, 
127                               std::ios::in | std::ios::out | std::ios::binary);
128    gdcm::DocEntry *d;
129    std::string v;
130
131    int patientNumber = 0;
132    std::ostringstream oss;
133
134    gdcm::SQItem *tmpSI=s->GetFirstSQItem();  // For all the SQItems
135    while(tmpSI)
136    {
137       d = tmpSI->GetDocEntry(0x0004, 0x1430); // Directory Record Type
138       if ( gdcm::ValEntry* valEntry = dynamic_cast<gdcm::ValEntry *>(d) )
139       {
140          v = valEntry->GetValue();
141       }
142       else
143       {
144          std::cout << "(0004,1430) not a ValEntry ?!?" << std::endl;
145          continue;
146       }
147
148       if( v != "PATIENT " )
149       {
150          continue;          // Work only on PATIENT
151       }
152
153       oss << patientNumber;      
154
155       //   Overwrite the sensitive Entries
156
157       // Patient's Name
158       AnoNoLoad(tmpSI, fp, 0x0010, 0x0010, oss.str());
159       // Patient's ID
160       AnoNoLoad(tmpSI, fp, 0x0010, 0x0020, oss.str());
161       // Patient's Birth Date
162       AnoNoLoad(tmpSI, fp, 0x0010, 0x0030, oss.str());
163      // Telephone
164       AnoNoLoad(tmpSI, fp, 0x0010, 0x2154, oss.str()); 
165
166     // Aware use will add more Entries he wants to rubb out here
167
168       oss << "";
169       patientNumber++;
170       tmpSI=s->GetNextSQItem();
171    }
172
173    // Close the file ASAP
174
175    fp->close();
176
177    delete fp;
178    delete e;   
179    delete f1;
180    return 0;
181 }
182