]> Creatis software - gdcm.git/blob - src/gdcmParse.cxx
*ENH gdcmHeader constructor has one more parameter (default value : false)
[gdcm.git] / src / gdcmParse.cxx
1 // gdcmParse.cxx
2
3 //This is needed when compiling in debug mode
4 #ifdef _MSC_VER
5 // 'type' : forcing value to bool 'true' or 'false' (performance warning)
6 //#pragma warning ( disable : 4800 )
7 // 'identifier' : class 'type' needs to have dll-interface to be used by
8 // clients of class 'type2'
9 #pragma warning ( disable : 4251 )
10 // 'identifier' : identifier was truncated to 'number' characters in the
11 // debug information
12 #pragma warning ( disable : 4786 )
13 #endif //_MSC_VER
14
15 #include "gdcmFile.h"
16 #include "gdcmUtil.h"
17
18 #define str2num(str, typeNum) *((typeNum *)(str))
19
20 /////////////////////////////////////////////////////////////////
21 /**
22  * \ingroup gdcmFile
23  * \brief   Parse pixel data from disk and *prints* the result
24  * \        For multi-fragment Jpeg/Rle files checking purpose *only*
25  * \        Allows to 'see' if the file *does* conform
26  * \       (some of them do not)
27  * \        with Dicom Part 3, Annex A (PS 3.5-2003, page 58, page 85)
28  *
29  */
30 bool gdcmFile::ParsePixelData(void) {
31
32    if ( !OpenFile())
33       return false;
34       
35     if ( fseek(fp, GetPixelOffset(), SEEK_SET) == -1 ) {
36       CloseFile();
37       return false;
38    } 
39    
40    if ( !IsDicomV3()                             ||
41         IsImplicitVRLittleEndianTransferSyntax() ||
42         IsExplicitVRLittleEndianTransferSyntax() ||
43         IsExplicitVRBigEndianTransferSyntax()    ||
44         IsDeflatedExplicitVRLittleEndianTransferSyntax() ) { 
45         
46         printf ("gdcmFile::ParsePixelData : non JPEG/RLE File\n");
47         return 0;       
48    }        
49
50    int nb;
51    std::string str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100);
52    if (str_nb == GDCM_UNFOUND ) {
53       nb = 16;
54    } else {
55       nb = atoi(str_nb.c_str() );
56       if (nb == 12) nb =16;
57    }
58    int nBytes= nb/8;
59       
60    int taille = GetXSize() *  GetYSize()  * GetSamplesPerPixel(); 
61          
62    printf ("Checking the Dicom-encapsulated Jpeg/RLE Pixels\n");
63       
64    guint16 ItemTagGr,ItemTagEl; 
65    int ln;
66    long ftellRes;
67    char * destination = NULL;
68
69   // -------------------- for Parsing : Position on begining of Jpeg/RLE Pixels 
70
71    if( !IsRLELossLessTransferSyntax()) {
72
73       // JPEG Image
74
75       std::cout << "JPEG image" << std::endl;
76       ftellRes=ftell(fp);
77       fread(&ItemTagGr,2,1,fp);  //Reading (fffe):Basic Offset Table Item Tag Gr
78       fread(&ItemTagEl,2,1,fp);  //Reading (e000):Basic Offset Table Item Tag El
79       if(GetSwapCode()) {
80          ItemTagGr=SwapShort(ItemTagGr); 
81          ItemTagEl=SwapShort(ItemTagEl);            
82       }
83       printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
84                 ftellRes,ItemTagGr,ItemTagEl );
85       ftellRes=ftell(fp);
86       fread(&ln,4,1,fp); 
87       if(GetSwapCode()) 
88          ln=SwapLong(ln);    // Basic Offset Table Item Lentgh
89       printf("at %x : Basic Offset Table Item Lentgh (??) %d x(%08x)\n",
90             ftellRes,ln,ln);
91       if (ln != 0) {
92          // What is it used for ??
93          char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
94          fread(BasicOffsetTableItemValue,ln,1,fp); 
95          guint32 a;
96          for (int i=0;i<ln;i+=4){
97             a=str2num(&BasicOffsetTableItemValue[i],guint32);
98             printf("      x(%08x)  %d\n",a,a);
99          }              
100       }
101       
102       ftellRes=ftell(fp);
103       fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
104       fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
105       if(GetSwapCode()) {
106          ItemTagGr=SwapShort(ItemTagGr); 
107          ItemTagEl=SwapShort(ItemTagEl);            
108       }  
109       printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
110             ftellRes,ItemTagGr,ItemTagEl );
111       
112       while ( ( ItemTagGr==0xfffe) && (ItemTagEl!=0xe0dd) ) { // Parse fragments
113       
114          ftellRes=ftell(fp);
115          fread(&ln,4,1,fp); 
116          if(GetSwapCode()) 
117             ln=SwapLong(ln);    // length
118          printf("      at %x : fragment length %d x(%08x)\n",
119                 ftellRes, ln,ln);
120
121         // destination += taille * nBytes; // location in user's memory        
122         //printf ("      Destination will be x(%x) = %d \n",
123         //     destination,destination );
124
125          // ------------------------                                     
126          fseek(fp,ln,SEEK_CUR); // skipping (not reading) fragment pixels    
127          // ------------------------              
128      
129          ftellRes=ftell(fp);
130          fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
131          fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
132          if(GetSwapCode()) {
133             ItemTagGr=SwapShort(ItemTagGr); 
134             ItemTagEl=SwapShort(ItemTagEl);            
135          }
136          printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
137                ftellRes,ItemTagGr,ItemTagEl );
138       } 
139
140    } else {
141
142       // RLE Image
143
144       std::cout << "RLE image" << std::endl;
145       long RleSegmentLength[15],fragmentLength;
146       guint32 nbRleSegments;
147       guint32 RleSegmentOffsetTable[15];
148       ftellRes=ftell(fp);
149       // Basic Offset Table with Item Value
150          // Item Tag
151       fread(&ItemTagGr,2,1,fp);  //Reading (fffe):Basic Offset Table Item Tag Gr
152       fread(&ItemTagEl,2,1,fp);  //Reading (e000):Basic Offset Table Item Tag El
153       if(GetSwapCode()) {
154          ItemTagGr=SwapShort(ItemTagGr); 
155          ItemTagEl=SwapShort(ItemTagEl);            
156       }
157       printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
158                 ftellRes,ItemTagGr,ItemTagEl );
159          // Item Length
160       ftellRes=ftell(fp);
161       fread(&ln,4,1,fp); 
162       if(GetSwapCode()) 
163          ln=SwapLong(ln);    // Basic Offset Table Item Lentgh
164       printf("at %x : Basic Offset Table Item Lentgh (??) %d x(%08x)\n",
165             ftellRes,ln,ln);
166       if (ln != 0) {
167          // What is it used for ??
168          char * BasicOffsetTableItemValue= (char *)malloc(ln+1);
169          fread(BasicOffsetTableItemValue,ln,1,fp); 
170          guint32 a;
171          for (int i=0;i<ln;i+=4){
172             a=str2num(&BasicOffsetTableItemValue[i],guint32);
173             printf("      x(%08x)  %d\n",a,a);
174          }              
175       }
176
177       ftellRes=ftell(fp);
178       fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
179       fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
180       if(GetSwapCode()) {
181          ItemTagGr=SwapShort(ItemTagGr); 
182          ItemTagEl=SwapShort(ItemTagEl);            
183       }  
184       printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
185             ftellRes,ItemTagGr,ItemTagEl );
186
187       // while 'Sequence Delimiter Item' (fffe,e0dd) not found
188       while (  ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { 
189       // Parse fragments of the current Fragment (Frame)    
190          ftellRes=ftell(fp);
191          fread(&fragmentLength,4,1,fp); 
192          if(GetSwapCode()) 
193             fragmentLength=SwapLong(fragmentLength);    // length
194          printf("      at %x : 'fragment' length %d x(%08x)\n",
195                 ftellRes, fragmentLength,fragmentLength);
196                        
197           //------------------ scanning (not reading) fragment pixels
198  
199          fread(&nbRleSegments,4,1,fp);  // Reading : Number of RLE Segments
200          if(GetSwapCode()) 
201             nbRleSegments=SwapLong(nbRleSegments);
202             printf("   Nb of RLE Segments : %d\n",nbRleSegments);
203  
204          for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
205             ftellRes=ftell(fp);
206             fread(&RleSegmentOffsetTable[k],4,1,fp);
207             if(GetSwapCode())
208                RleSegmentOffsetTable[k]=SwapLong(RleSegmentOffsetTable[k]);
209             printf("        at : %x Offset Segment %d : %d (%x)\n",
210                     ftellRes,k,RleSegmentOffsetTable[k],
211                     RleSegmentOffsetTable[k]);
212          }
213
214           if (nbRleSegments>1) { // skipping (not reading) RLE Segments
215              for(int k=1; k<=nbRleSegments-1; k++) { 
216                 RleSegmentLength[k]=   RleSegmentOffsetTable[k+1]
217                                      - RleSegmentOffsetTable[k];
218                 ftellRes=ftell(fp);
219                 printf ("  Segment %d : Length = %d x(%x) Start at %x\n",
220                            k,RleSegmentLength[k],RleSegmentLength[k], ftellRes);
221                 fseek(fp,RleSegmentLength[k],SEEK_CUR);    
222              }
223           }
224           RleSegmentLength[nbRleSegments]= fragmentLength 
225                                          - RleSegmentOffsetTable[nbRleSegments];
226           ftellRes=ftell(fp);
227           printf ("  Segment %d : Length = %d x(%x) Start at %x\n",
228                            nbRleSegments,RleSegmentLength[nbRleSegments],
229                            RleSegmentLength[nbRleSegments],ftellRes);
230
231           fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR); 
232             
233          // ------------------ end of scanning fragment pixels        
234       
235          ftellRes=ftell(fp);
236          fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
237          fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
238          if(GetSwapCode()) {
239             ItemTagGr=SwapShort(ItemTagGr); 
240             ItemTagEl=SwapShort(ItemTagEl);            
241          }
242          printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
243                ftellRes,ItemTagGr,ItemTagEl );
244       } 
245    }
246    return 1;            
247 }