]> Creatis software - gdcm.git/blob - src/gdcmTS.cxx
Minor typo fixes
[gdcm.git] / src / gdcmTS.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmTS.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/12/09 12:23:39 $
7   Version:   $Revision: 1.53 $
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 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 
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   // Unknown
82   "Unknown Transfer Syntax", // Pretty sure we never use this case...
83   NULL // Compilers have no obligation to finish by NULL, do it ourself
84 };
85
86 //-----------------------------------------------------------------------------
87 /// \brief auto generated function, to fill up the Dicom Dictionnary,
88 ///       if relevant file is not found on user's disk
89 void FillDefaultTSDict(TSHT &ts);
90
91 //-----------------------------------------------------------------------------
92 // Constructor / Destructor
93 TS::TS() 
94 {
95    std::string filename = DictSet::BuildDictPath() + DICT_TS;
96    std::ifstream from(filename.c_str());
97    if ( !from )
98    {
99       gdcmWarningMacro("Can't open dictionary" << filename.c_str());
100       FillDefaultTSDict( TsMap );
101    }
102    else
103    {
104       TSKey key;
105       TSAtr name;
106
107       while (!from.eof())
108       {
109          from >> key;
110          from >> std::ws;
111          std::getline(from, name);
112
113          if (key != "")
114          {
115             TsMap[key] = name;
116          }
117       }
118       from.close();
119    }
120 }
121
122 TS::~TS() 
123 {
124    TsMap.clear();
125 }
126
127 //-----------------------------------------------------------------------------
128 // Public
129
130 /// \brief returns occurence number of the given key
131 int TS::Count(TSKey const &key) 
132 {
133    return TsMap.count(key);
134 }
135
136 /// \brief returns the human readable value of a Transfer Syntax string 
137 TSAtr const &TS::GetValue(TSKey const &key) 
138 {
139    // First thing clean up the string 
140    // (sometimes the transfer syntax is padded with spaces)
141    std::string copy = key;
142    while ( copy.size() && !isdigit((unsigned char)copy[copy.size()-1]) )
143    {
144       copy.erase(copy.size()-1, 1);
145    }
146
147    TSHT::const_iterator it = TsMap.find(copy);
148    if (it == TsMap.end())
149    {
150       return GDCM_UNFOUND;
151    }
152    return it->second;
153 }
154 /**
155  * \brief   Determines if the key passed corresponds to a 'Transfer Syntax'
156  *          as defined in DICOM (and stored in gdcm::TS class)
157  * @return  True when key is an actual 'Transfer Syntax'. 
158  *          False in all other cases.
159  */
160 bool TS::IsTransferSyntax(TSKey const &key)
161 {
162    TSHT::const_iterator it = TsMap.find(key);
163    return it != TsMap.end();
164 }
165
166 /**
167  * \brief   Determines if the Transfer Syntax was already encountered
168  *          and if it corresponds to a Run Length Encoding Lossless one
169  * @return  True when Run Length Encoding Lossless found. 
170  *          False in all other cases.
171  */
172 bool TS::IsRLELossless(TSKey const &key)
173 {
174    bool r = false;
175    // First check this is an actual transfer syntax
176    if ( IsTransferSyntax(key) )
177    {
178       if ( key == SpecialStrings[RLELossless] )
179       {
180          r = true;
181       }
182    }
183    return r;
184 }
185
186 /**
187  * \brief   Determines if the Transfer Syntax was already encountered
188  *          and if it corresponds to a 'classical' JPEG Lossless one
189  * @return  True when 'classical' Lossless found. 
190  *          False in all other cases.
191  */
192 bool TS::IsJPEGLossless(TSKey const &key)
193 {
194    bool r = false;
195    // First check this is an actual transfer syntax
196    if ( IsTransferSyntax(key) )
197    {
198       if ( key == SpecialStrings[JPEGFullProgressionProcess10_12]
199         || key == SpecialStrings[JPEGLosslessProcess14]
200         || key == SpecialStrings[JPEGLosslessProcess14_1] )
201       {
202          r = true;
203       }
204    }
205    return r;
206 }
207
208 /**
209  * \brief   Determines if the Transfer Syntax was already encountered
210  *          and if it corresponds to a 'classical' JPEG Lossy one
211  * @return  True when 'classical' Lossy found. 
212  *          False in all other cases.
213  */
214 bool TS::IsJPEGLossy(TSKey const &key)
215 {
216    bool r = false;
217    // First check this is an actual transfer syntax
218    if ( IsTransferSyntax(key) )
219    {
220       if ( key == SpecialStrings[JPEGBaselineProcess1]
221         || key == SpecialStrings[JPEGExtendedProcess2_4]
222         || key == SpecialStrings[JPEGExtendedProcess3_5]
223         || key == SpecialStrings[JPEGSpectralSelectionProcess6_8] )
224       {
225          r = true;
226       }
227    }
228    return r;
229 }
230
231 /**
232  * \brief   Determines if the Transfer Syntax was already encountered
233  *          and if it corresponds to a JPEG2000 one
234  * @return  True when JPEG2000 (Lossly or LossLess) found. 
235  *          False in all other cases.
236  */
237 bool TS::IsJPEG2000(TSKey const &key)
238 {
239    bool r = false;
240    // First check this is an actual transfer syntax
241    if ( IsTransferSyntax(key) )
242    {
243       if ( key == SpecialStrings[JPEG2000Lossless]
244         || key == SpecialStrings[JPEG2000] )
245       {
246          r = true;
247       }
248    }
249    return r;
250 }
251
252 /**
253  * \brief   Determines if the Transfer Syntax corresponds to 
254  *          'classical' Jpeg Lossless or Jpeg lossy.
255  * @return  True when any form of JPEG found. False otherwise.
256  */
257 bool TS::IsJPEG(TSKey const &key)
258 {
259    bool r = false;
260    // First check this is an actual transfer syntax
261    if ( IsTransferSyntax(key) )
262    {
263       if ( IsJPEGLossy( key )
264         || IsJPEGLossless( key )
265         || IsJPEG2000( key )
266         || IsJPEGLS( key )
267          )
268       {
269          r = true;
270       }
271    }
272    return r;
273 }
274
275 /**
276  * \brief   Determines if the Transfer Syntax corresponds to any form
277  *          of Jpeg-LS encoded Pixel data.
278  * @return  True when any form of JPEG-LS found. False otherwise.
279  */
280 bool TS::IsJPEGLS(TSKey const &key)
281 {
282    bool r = false;
283    // First check this is an actual transfer syntax
284    if ( IsTransferSyntax(key) )
285    {
286       if ( key == SpecialStrings[JPEGLSLossless]
287         || key == SpecialStrings[JPEGLSNearLossless] ) 
288       {
289          r = true;
290       }
291    }
292    return r;
293 }
294
295 /**
296  * \brief   Determines if the Transfer Syntax corresponds to any form
297  *          of MPEG encoded Pixel data.
298  * @return  True when any form of MPEG found. False otherwise.
299  */
300 bool TS::IsMPEG(TSKey const &key)
301 {
302    bool r = false;
303    // First check this is an actual transfer syntax
304    if ( IsTransferSyntax(key) )
305    {
306       if ( key == SpecialStrings[MPEG2MainProfile] ) 
307       {
308          r = true;
309       }
310    }
311    return r;
312 }
313
314 /**
315  * \brief   GetSpecialTransferSyntax ??
316  * @param  key TSKey const &key ??
317  * @return  TS::SpecialType ??.
318  */
319 TS::SpecialType TS::GetSpecialTransferSyntax(TSKey const &key)
320 {
321    for (int i = 0; SpecialStrings[i] != NULL; i++)
322    {
323       if ( SpecialStrings[i] == key )
324       {
325          return SpecialType(i);
326       }
327    }
328    return UnknownTS;
329 }
330
331 /**
332  * \brief   GetSpecialTransferSyntax ??
333  * @param  t SpecialType t ??
334  * @return  char* TS : SpecialStrings[t] ??.
335  */
336 const char* TS::GetSpecialTransferSyntax(SpecialType t)
337 {
338    return SpecialStrings[t];
339 }
340
341 //-----------------------------------------------------------------------------
342 // Protected
343
344 //-----------------------------------------------------------------------------
345 // Private
346
347 //-----------------------------------------------------------------------------
348 // Print
349 /**
350  * \brief   Print all 
351  * @param   os The output stream to be written to.
352  */
353 void TS::Print(std::ostream &os,std::string const &)
354 {
355    std::ostringstream s;
356
357    for (TSHT::const_iterator it = TsMap.begin(); it != TsMap.end(); ++it)
358    {
359       s << "TS : " << it->first << " = " << it->second << std::endl;
360    }
361    os << s.str();
362 }
363
364 //-----------------------------------------------------------------------------
365 } // end namespace gdcm