]> Creatis software - gdcm.git/blob - src/gdcmBinEntry.cxx
* Testing/TestWriteSimple.cxx, TestSequence.cxx : fix memroy leaks
[gdcm.git] / src / gdcmBinEntry.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmBinEntry.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/02/10 14:23:18 $
7   Version:   $Revision: 1.68 $
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 "gdcmBinEntry.h"
20 #include "gdcmContentEntry.h"
21
22 #include "gdcmDebug.h"
23
24 #include <fstream>
25 #include <sstream>
26 #include <iostream> // for std::ios_base, since <ios> does not exist on gcc/Solaris
27
28 namespace gdcm 
29 {
30 //-----------------------------------------------------------------------------
31 // Constructor / Destructor
32 /**
33  * \brief   Constructor from a given BinEntry
34  */
35 BinEntry::BinEntry(DictEntry *e) 
36          :ContentEntry(e)
37 {
38    BinArea = 0;
39    SelfArea = true;
40 }
41
42 /**
43  * \brief   Constructor from a given BinEntry
44  * @param   e Pointer to existing Doc entry
45  */
46 BinEntry::BinEntry(DocEntry *e) 
47         : ContentEntry(e->GetDictEntry())
48 {
49    Copy(e);
50
51    BinArea = 0;
52    SelfArea = true;
53 }
54
55 /**
56  * \brief   Canonical destructor.
57  */
58 BinEntry::~BinEntry()
59 {
60    if (BinArea && SelfArea)
61    {
62       delete[] BinArea;
63       BinArea = 0; // let's be carefull !
64    }
65 }
66
67 //-----------------------------------------------------------------------------
68 // Public
69 /**
70  * \brief   canonical Writer
71  * @param fp already open file pointer
72  * @param filetype type of the file (ACR, ImplicitVR, ExplicitVR, ...)
73 */
74 void BinEntry::WriteContent(std::ofstream *fp, FileType filetype)
75
76    DocEntry::WriteContent(fp, filetype);
77    void* binArea = GetBinArea();
78    int lgr = GetLength();
79    if (binArea) // the binArea was *actually* loaded
80    {
81
82    // TODO FIME
83    // Probabely, the same operation will have to be done when we want 
84    // to write image with Big Endian Transfert Syntax, 
85    //   and we are working on Little Endian Processor
86
87 #ifdef GDCM_WORDS_BIGENDIAN
88       const int BUFFER_SIZE = 4096;
89       // TODO FIXME Right now, we only care of Pixels element
90
91       // 8 Bits Pixels *are* OB, 16 Bits Pixels *are* OW
92       // -value forced while Reading process-
93       if (GetGroup() == 0x7fe0 && GetVR() == "OW")
94       {     
95          uint16_t *buffer = new uint16_t[BUFFER_SIZE/2];
96
97          // how many BUFFER_SIZE long pieces in binArea ?
98          int nbPieces = lgr/BUFFER_SIZE; //(16 bits = 2 Bytes)
99          int remainingSize = lgr%BUFFER_SIZE;
100
101          uint16_t *binArea16 = (uint16_t*)binArea;
102          for (int j=0;j<nbPieces;j++)
103          {
104             for (int i = 0; i < BUFFER_SIZE/2; i++)
105             {
106                //buffer[i] =  (binArea16[i] >> 8) | (binArea16[i] << 8);
107                uint16_t val = binArea16[i];
108                buffer[i] = ((( val << 8 ) & 0xff00 ) | (( val >> 8 ) & 0x00ff ) );
109             }
110             fp->write ( (char*)buffer, BUFFER_SIZE );
111             binArea16 += BUFFER_SIZE/2;
112          }
113          if ( remainingSize > 0)
114          {
115             for (int i = 0; i < remainingSize/2; i++)
116             {
117                //buffer[i] =  (binArea16[i] >> 8) | (binArea16[i] << 8);
118                uint16_t val = binArea16[i];
119                buffer[i] = ((( val << 8 ) & 0xff00 ) | (( val >> 8 ) & 0x00ff ) );
120             }
121             fp->write ( (char*)buffer, remainingSize );
122          } 
123          delete[] buffer;
124       }
125       else
126       { 
127          // For any other VR, BinEntry is re-written as-is
128          fp->write ( (char*)binArea, lgr );
129       }
130 #else
131       fp->write ( (char*)binArea, lgr ); // Elem value
132 #endif //GDCM_WORDS_BIGENDIAN
133
134    }
135    else
136    {
137       // nothing was loaded, but we need to skip space on disc
138       fp->seekp(lgr, std::ios::cur);
139    }
140 }
141
142 /**
143  * \brief Sets the value (non string) of the current Dicom Header Entry
144  */
145 void BinEntry::SetBinArea( uint8_t *area, bool self )  
146
147    if (BinArea && SelfArea)
148       delete[] BinArea;
149
150    BinArea = area;
151    SelfArea=self;
152 }
153
154 //-----------------------------------------------------------------------------
155 // Protected
156
157 //-----------------------------------------------------------------------------
158 // Private
159    
160 //-----------------------------------------------------------------------------
161 // Print
162 /**
163  * \brief   Prints a BinEntry (Dicom entry)
164  * @param   os ostream we want to print in
165  * @param indent Indentation string to be prepended during printing
166  */
167 void BinEntry::Print(std::ostream &os, std::string const & )
168 {
169    os << "B ";
170    DocEntry::Print(os);
171    std::ostringstream s;
172    void* binArea = GetBinArea();
173    if (binArea)
174    {
175       s << " [" << GetValue()
176         << "; length = " << GetLength() << "]";
177    }
178    else
179    {
180       if ( GetLength() == 0 )
181       {
182          s << " []";
183       }
184       else 
185       {
186          s << " [" <<GetValue() << "]";
187       }         
188    }
189    os << s.str();
190 }
191
192 //-----------------------------------------------------------------------------
193 } // end namespace gdcm