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