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