]> Creatis software - gdcm.git/blob - src/gdcmTS.cxx
add SetFlipY()
[gdcm.git] / src / gdcmTS.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmTS.cxx,v $
5   Language:  C++
6   Date:      $Date: 2009/03/04 08:57:42 $
7   Version:   $Revision: 1.56 $
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 "gdcmTS.h"
20 #include "gdcmDebug.h"
21 #include "gdcmUtil.h"
22 #include "gdcmDictSet.h"
23
24 #include <fstream>
25 #include <string>
26 #include <iostream>
27 #include <ctype.h> // for isdigit
28
29 // TODO
30 // troubles expected with TS : 1.2.840.113619.5.2
31 // Implicit VR - Big Endian
32 // http://www.gemedicalsystemseurope.com/euen/it_solutions/pdf/lsqxi_rev2.pdf
33 // G.E. deliberately violated a lot of Dicom rules are
34 // (probabely to avoid other people to read their images)
35 // Just try and error on new images :
36 // PrintFile debug filein=...
37 // and fix the bugs
38
39 namespace GDCM_NAME_SPACE 
40 {
41 //-----------------------------------------------------------------------------
42 /// \brief Transfer Syntaxes gdcm deals with (internal use only)
43 static const char *SpecialStrings[] =  {
44   // Implicit VR Little Endian
45   "1.2.840.10008.1.2",
46   // Implicit VR Big Endian (G.E Private)
47   "1.2.840.113619.5.2",
48   // Explicit VR Little Endian
49   "1.2.840.10008.1.2.1",
50   // Deflated Explicit VR Little Endian
51   "1.2.840.10008.1.2.1.99",
52   // Explicit VR Big Endian
53   "1.2.840.10008.1.2.2",
54   // JPEG Baseline (Process 1)
55   "1.2.840.10008.1.2.4.50",
56   // JPEG Extended (Process 2 & 4)
57   "1.2.840.10008.1.2.4.51",
58   // JPEG Extended (Process 3 & 5)
59   "1.2.840.10008.1.2.4.52",
60   // JPEG Spectral Selection, Non-Hierarchical (Process 6 & 8)
61   "1.2.840.10008.1.2.4.53",
62   // JPEG Full Progression, Non-Hierarchical (Process 10 & 12)
63   "1.2.840.10008.1.2.4.55",
64   // JPEG Lossless, Non-Hierarchical (Process 14)
65   "1.2.840.10008.1.2.4.57",
66   // JPEG Lossless, Hierarchical, First-Order Prediction (Process 14,
67   //                                                       [Selection Value 1])
68   "1.2.840.10008.1.2.4.70",
69   // JPEG-LS Lossless Image Compression
70   "1.2.840.10008.1.2.4.80",
71   // JPEG-LS Lossy (Near-Lossless) Image Compression
72   "1.2.840.10008.1.2.4.81",
73   // JPEG 2000 Lossless
74   "1.2.840.10008.1.2.4.90",
75   // JPEG 2000
76   "1.2.840.10008.1.2.4.91",
77   // RLE Lossless
78   "1.2.840.10008.1.2.5",
79   // MPEG2 Main Profile @ Main Level
80   "1.2.840.10008.1.2.4.100",
81   
82   // The following are *not* t.s. but SOP uid
83   // Ultrasound Image Storage (Retired)
84   "1.2.840.10008.5.1.4.1.1.6",
85      
86   // Unknown
87   "Unknown Transfer Syntax", // Pretty sure we never use this case...
88   NULL // Compilers have no obligation to finish by NULL, do it ourself
89 };
90
91 //-----------------------------------------------------------------------------
92 /// \brief auto generated function, to fill up the Dicom Dictionnary,
93 ///       if relevant file is not found on user's disk
94 void FillDefaultTSDict(TSHT &ts);
95
96 //-----------------------------------------------------------------------------
97 // Constructor / Destructor
98 TS::TS() 
99 {
100
101    std::string filename = DictSet::BuildDictPath() + DICT_TS;
102    std::ifstream from(filename.c_str());
103    if ( !from )
104    {
105       gdcmWarningMacro("Can't open dictionary" << filename.c_str());
106       FillDefaultTSDict( TsMap );
107    }
108    else
109    {
110       TSKey key;
111       TSAtr name;
112
113       while (!from.eof())
114       {
115          from >> key;
116          from >> std::ws;
117          std::getline(from, name);
118
119          if (key != "")
120          {
121             TsMap[key] = name;
122          }
123       }
124
125       from.close();
126    }
127 }
128
129 TS::~TS() 
130 {
131    TsMap.clear();
132 }
133
134 //-----------------------------------------------------------------------------
135 // Public
136
137 /// \brief returns occurence number of the given key
138 int TS::Count(TSKey const &key) 
139 {
140    return TsMap.count(key);
141 }
142
143 /// \brief returns the human readable value of a Transfer Syntax string 
144 TSAtr const &TS::GetValue(TSKey const &key) 
145 {
146    // First thing clean up the string 
147    // (sometimes the transfer syntax is padded with spaces)
148    std::string copy = key;
149    while ( copy.size() && !isdigit((unsigned char)copy[copy.size()-1]) )
150    {
151       copy.erase(copy.size()-1, 1);
152    }
153
154    TSHT::const_iterator it = TsMap.find(copy);
155    if (it == TsMap.end())
156    {
157       return GDCM_UNFOUND;
158    }
159    return it->second;
160 }
161 /**
162  * \brief   Determines if the key passed corresponds to a 'Transfer Syntax'
163  *          as defined in DICOM (and stored in gdcm::TS class)
164  * @return  True when key is an actual 'Transfer Syntax'. 
165  *          False in all other cases.
166  */
167 bool TS::IsTransferSyntax(TSKey const &key)
168 {
169    TSHT::const_iterator it = TsMap.find(key);
170    return it != TsMap.end();
171 }
172
173 /**
174  * \brief   Determines if the Transfer Syntax was already encountered
175  *          and if it corresponds to a Run Length Encoding Lossless one
176  * @return  True when Run Length Encoding Lossless found. 
177  *          False in all other cases.
178  */
179 bool TS::IsRLELossless(TSKey const &key)
180 {
181    bool r = false;
182    // First check this is an actual transfer syntax
183    if ( IsTransferSyntax(key) )
184    {
185       if ( key == SpecialStrings[RLELossless] )
186       {
187          r = true;
188       }
189    }
190    return r;
191 }
192
193 /**
194  * \brief   Determines if the Transfer Syntax was already encountered
195  *          and if it corresponds to a 'classical' JPEG Lossless one
196  * @return  True when 'classical' Lossless found. 
197  *          False in all other cases.
198  */
199 bool TS::IsJPEGLossless(TSKey const &key)
200 {
201    bool r = false;
202    // First check this is an actual transfer syntax
203    if ( IsTransferSyntax(key) )
204    {
205       if ( key == SpecialStrings[JPEGFullProgressionProcess10_12]
206         || key == SpecialStrings[JPEGLosslessProcess14]
207         || key == SpecialStrings[JPEGLosslessProcess14_1] )
208       {
209          r = true;
210       }
211    }
212    return r;
213 }
214
215 /**
216  * \brief   Determines if the Transfer Syntax was already encountered
217  *          and if it corresponds to a 'classical' JPEG Lossy one
218  * @return  True when 'classical' Lossy found. 
219  *          False in all other cases.
220  */
221 bool TS::IsJPEGLossy(TSKey const &key)
222 {
223    bool r = false;
224    // First check this is an actual transfer syntax
225    if ( IsTransferSyntax(key) )
226    {
227       if ( key == SpecialStrings[JPEGBaselineProcess1]
228         || key == SpecialStrings[JPEGExtendedProcess2_4]
229         || key == SpecialStrings[JPEGExtendedProcess3_5]
230         || key == SpecialStrings[JPEGSpectralSelectionProcess6_8] )
231       {
232          r = true;
233       }
234    }
235    return r;
236 }
237
238 /**
239  * \brief   Determines if the Transfer Syntax was already encountered
240  *          and if it corresponds to a JPEG2000 one
241  * @return  True when JPEG2000 (Lossly or LossLess) found. 
242  *          False in all other cases.
243  */
244 bool TS::IsJPEG2000(TSKey const &key)
245 {
246    bool r = false;
247    // First check this is an actual transfer syntax
248    if ( IsTransferSyntax(key) )
249    {
250       if ( key == SpecialStrings[JPEG2000Lossless]
251         || key == SpecialStrings[JPEG2000] )
252       {
253          r = true;
254       }
255    }
256    return r;
257 }
258
259 /**
260  * \brief   Determines if the Transfer Syntax corresponds to 
261  *          'classical' Jpeg Lossless or Jpeg lossy.
262  * @return  True when any form of JPEG found. False otherwise.
263  */
264 bool TS::IsJPEG(TSKey const &key)
265 {
266    bool r = false;
267    // First check this is an actual transfer syntax
268    if ( IsTransferSyntax(key) )
269    {
270       if ( IsJPEGLossy( key )
271         || IsJPEGLossless( key )
272         || IsJPEG2000( key )
273         || IsJPEGLS( key )
274          )
275       {
276          r = true;
277       }
278    }
279    return r;
280 }
281
282 /**
283  * \brief   Determines if the Transfer Syntax corresponds to any form
284  *          of Jpeg-LS encoded Pixel data.
285  * @return  True when any form of JPEG-LS found. False otherwise.
286  */
287 bool TS::IsJPEGLS(TSKey const &key)
288 {
289    bool r = false;
290    // First check this is an actual transfer syntax
291    if ( IsTransferSyntax(key) )
292    {
293       if ( key == SpecialStrings[JPEGLSLossless]
294         || key == SpecialStrings[JPEGLSNearLossless] ) 
295       {
296          r = true;
297       }
298    }
299    return r;
300 }
301
302 /**
303  * \brief   Determines if the Transfer Syntax corresponds to any form
304  *          of MPEG encoded Pixel data.
305  * @return  True when any form of MPEG found. False otherwise.
306  */
307 bool TS::IsMPEG(TSKey const &key)
308 {
309    bool r = false;
310    // First check this is an actual transfer syntax
311    if ( IsTransferSyntax(key) )
312    {
313       if ( key == SpecialStrings[MPEG2MainProfile] ) 
314       {
315          r = true;
316       }
317    }
318    return r;
319 }
320
321 /**
322  * \brief   Determines if the SOP id corresponds to any form
323  *          of UltrasoundImageStorage_Retired.
324  * @return  True when Ultrasound Image Storage Retired. False otherwise.
325  */
326 bool TS::IsUltrasoundImageStorage_Retired(TSKey const &key)
327 {
328    bool r = false;
329    // First check this is an actual SOP id
330    if ( IsTransferSyntax(key) )
331    {
332       if ( key == SpecialStrings[UltrasoundImageStorage_Retired] ) 
333       {
334          r = true;
335       }
336    }
337    return r;
338 }
339 /**
340  * \brief   GetSpecialTransferSyntax ??
341  * @param  key TSKey const &key ??
342  * @return  TS::SpecialType ??.
343  */
344 TS::SpecialType TS::GetSpecialTransferSyntax(TSKey const &key)
345 {
346    for (int i = 0; SpecialStrings[i] != NULL; i++)
347    {
348       if ( SpecialStrings[i] == key )
349       {
350          return SpecialType(i);
351       }
352    }
353    return UnknownTS;
354 }
355
356 /**
357  * \brief   GetSpecialTransferSyntax ??
358  * @param  t SpecialType t ??
359  * @return  char* TS : SpecialStrings[t] ??.
360  */
361 const char *TS::GetSpecialTransferSyntax(SpecialType t)
362 {
363    return SpecialStrings[t];
364 }
365
366 //-----------------------------------------------------------------------------
367 // Protected
368
369 //-----------------------------------------------------------------------------
370 // Private
371
372 //-----------------------------------------------------------------------------
373 // Print
374 /**
375  * \brief   Print all 
376  * @param   os The output stream to be written to.
377  */
378 void TS::Print(std::ostream &os,std::string const &)
379 {
380    std::ostringstream s;
381
382    for (TSHT::const_iterator it = TsMap.begin(); it != TsMap.end(); ++it)
383    {
384       s << "TS : " << it->first << " = " << it->second << std::endl;
385    }
386    os << s.str();
387 }
388
389 //-----------------------------------------------------------------------------
390 } // end namespace gdcm