]> Creatis software - gdcm.git/blob - src/gdcmParsePixels.cxx
new version of TestCopyDicom
[gdcm.git] / src / gdcmParsePixels.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmParsePixels.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/07/17 22:47:01 $
7   Version:   $Revision: 1.9 $
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,ItemTagEl; 
72    int ln;
73    long ftellRes;
74    //char * destination = NULL;
75
76   // -------------------- for Parsing : Position on begining of Jpeg/RLE Pixels 
77
78    if( !Header->IsRLELossLessTransferSyntax()) {
79
80       // JPEG Image
81       ftellRes=ftell(fp);
82       fread(&ItemTagGr,2,1,fp);  //Reading (fffe):Basic Offset Table Item Tag Gr
83       fread(&ItemTagEl,2,1,fp);  //Reading (e000):Basic Offset Table Item Tag El
84       if(Header->GetSwapCode()) {
85          ItemTagGr=Header->SwapShort(ItemTagGr); 
86          ItemTagEl=Header->SwapShort(ItemTagEl);            
87       }
88       printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
89                 (unsigned)ftellRes,ItemTagGr,ItemTagEl );
90       ftellRes=ftell(fp);
91       fread(&ln,4,1,fp); 
92       if(Header->GetSwapCode()) 
93          ln=Header->SwapLong(ln);    // Basic Offset Table Item Length
94       printf("at %x : Basic Offset Table Item Length (\?\?) %d x(%08x)\n",
95             (unsigned)ftellRes,ln,ln);
96       if (ln != 0) {
97          // What is it used for ??
98          char * BasicOffsetTableItemValue= new char[ln+1];
99          fread(BasicOffsetTableItemValue,ln,1,fp); 
100          uint32_t a;
101          for (int i=0;i<ln;i+=4){
102             a=str2num(&BasicOffsetTableItemValue[i],uint32_t);
103             printf("      x(%08x)  %d\n",a,a);
104          }              
105       }
106       
107       ftellRes=ftell(fp);
108       fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
109       fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
110       if(Header->GetSwapCode()) {
111          ItemTagGr=Header->SwapShort(ItemTagGr); 
112          ItemTagEl=Header->SwapShort(ItemTagEl);            
113       }  
114       printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
115             (unsigned)ftellRes,ItemTagGr,ItemTagEl );
116       
117       while ( ( ItemTagGr==0xfffe) && (ItemTagEl!=0xe0dd) ) { // Parse fragments
118       
119          ftellRes=ftell(fp);
120          fread(&ln,4,1,fp); 
121          if(Header->GetSwapCode()) 
122             ln=Header->SwapLong(ln);    // length
123          printf("      at %x : fragment length %d x(%08x)\n",
124                 (unsigned)ftellRes, ln,ln);
125
126         // destination += taille * nBytes; // location in user's memory        
127         //printf ("      Destination will be x(%x) = %d \n",
128         //     destination,destination );
129
130          // ------------------------                                     
131          fseek(fp,ln,SEEK_CUR); // skipping (not reading) fragment pixels    
132          // ------------------------              
133      
134          ftellRes=ftell(fp);
135          fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
136          fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
137          if(Header->GetSwapCode()) {
138             ItemTagGr=Header->SwapShort(ItemTagGr); 
139             ItemTagEl=Header->SwapShort(ItemTagEl);            
140          }
141          printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
142                (unsigned)ftellRes,ItemTagGr,ItemTagEl );
143       } 
144
145    } else {
146
147       // RLE Image
148       long RleSegmentLength[15],fragmentLength;
149       uint32_t nbRleSegments;
150       uint32_t RleSegmentOffsetTable[15];
151       ftellRes=ftell(fp);
152       // Basic Offset Table with Item Value
153          // Item Tag
154       fread(&ItemTagGr,2,1,fp);  //Reading (fffe):Basic Offset Table Item Tag Gr
155       fread(&ItemTagEl,2,1,fp);  //Reading (e000):Basic Offset Table Item Tag El
156       if(Header->GetSwapCode()) {
157          ItemTagGr=Header->SwapShort(ItemTagGr); 
158          ItemTagEl=Header->SwapShort(ItemTagEl);            
159       }
160       printf ("at %x : ItemTag (should be fffe,e000): %04x,%04x\n",
161                 (unsigned)ftellRes,ItemTagGr,ItemTagEl );
162          // Item Length
163       ftellRes=ftell(fp);
164       fread(&ln,4,1,fp); 
165       if(Header->GetSwapCode()) 
166          ln=Header->SwapLong(ln);    // Basic Offset Table Item Length
167       printf("at %x : Basic Offset Table Item Length (\?\?) %d x(%08x)\n",
168             (unsigned)ftellRes,ln,ln);
169       if (ln != 0) {
170          // What is it used for ??
171          char * BasicOffsetTableItemValue= new char[ln+1];
172          fread(BasicOffsetTableItemValue,ln,1,fp); 
173          uint32_t a;
174          for (int i=0;i<ln;i+=4){
175             a=str2num(&BasicOffsetTableItemValue[i],uint32_t);
176             printf("      x(%08x)  %d\n",a,a);
177          }              
178       }
179
180       ftellRes=ftell(fp);
181       fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
182       fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
183       if(Header->GetSwapCode()) {
184          ItemTagGr=Header->SwapShort(ItemTagGr); 
185          ItemTagEl=Header->SwapShort(ItemTagEl);            
186       }  
187       printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
188             (unsigned)ftellRes,ItemTagGr,ItemTagEl );
189
190       // while 'Sequence Delimiter Item' (fffe,e0dd) not found
191       while (  ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) { 
192       // Parse fragments of the current Fragment (Frame)    
193          ftellRes=ftell(fp);
194          fread(&fragmentLength,4,1,fp); 
195          if(Header->GetSwapCode()) 
196             fragmentLength=Header->SwapLong(fragmentLength);    // length
197          printf("      at %x : 'fragment' length %d x(%08x)\n",
198                 (unsigned)ftellRes, (unsigned)fragmentLength,(unsigned)fragmentLength);
199                        
200           //------------------ scanning (not reading) fragment pixels
201  
202          fread(&nbRleSegments,4,1,fp);  // Reading : Number of RLE Segments
203          if(Header->GetSwapCode()) 
204             nbRleSegments=Header->SwapLong(nbRleSegments);
205             printf("   Nb of RLE Segments : %d\n",nbRleSegments);
206  
207          for(int k=1; k<=15; k++) { // Reading RLE Segments Offset Table
208             ftellRes=ftell(fp);
209             fread(&RleSegmentOffsetTable[k],4,1,fp);
210             if(Header->GetSwapCode())
211                RleSegmentOffsetTable[k]=Header->SwapLong(RleSegmentOffsetTable[k]);
212             printf("        at : %x Offset Segment %d : %d (%x)\n",
213                     (unsigned)ftellRes,k,RleSegmentOffsetTable[k],
214                     RleSegmentOffsetTable[k]);
215          }
216
217           if (nbRleSegments>1) { // skipping (not reading) RLE Segments
218              for(unsigned int k=1; k<=nbRleSegments-1; k++) { 
219                 RleSegmentLength[k]=   RleSegmentOffsetTable[k+1]
220                                      - RleSegmentOffsetTable[k];
221                 ftellRes=ftell(fp);
222                 printf ("  Segment %d : Length = %d x(%x) Start at %x\n",
223                            k,(unsigned)RleSegmentLength[k],(unsigned)RleSegmentLength[k], (unsigned)ftellRes);
224                 fseek(fp,RleSegmentLength[k],SEEK_CUR);    
225              }
226           }
227           RleSegmentLength[nbRleSegments]= fragmentLength 
228                                          - RleSegmentOffsetTable[nbRleSegments];
229           ftellRes=ftell(fp);
230           printf ("  Segment %d : Length = %d x(%x) Start at %x\n",
231                            nbRleSegments,(unsigned)RleSegmentLength[nbRleSegments],
232                            (unsigned)RleSegmentLength[nbRleSegments],(unsigned)ftellRes);
233
234           fseek(fp,RleSegmentLength[nbRleSegments],SEEK_CUR); 
235             
236          // ------------------ end of scanning fragment pixels        
237       
238          ftellRes=ftell(fp);
239          fread(&ItemTagGr,2,1,fp);  // Reading (fffe) : Item Tag Gr
240          fread(&ItemTagEl,2,1,fp);  // Reading (e000) : Item Tag El
241          if(Header->GetSwapCode()) {
242             ItemTagGr=Header->SwapShort(ItemTagGr); 
243             ItemTagEl=Header->SwapShort(ItemTagEl);            
244          }
245          printf ("at %x : ItemTag (should be fffe,e000 or e0dd): %04x,%04x\n",
246                (unsigned)ftellRes,ItemTagGr,ItemTagEl );
247       } 
248    }
249    return true;            
250 }
251
252 //-----------------------------------------------------------------------------