]> Creatis software - gdcm.git/blob - src/gdcmFile.cxx
* src/gdcmDocument.[h|cxx] : set the Transfert Syntax values to the header
[gdcm.git] / src / gdcmFile.cxx
1   /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmFile.cxx,v $
5   Language:  C++
6   Date:      $Date: 2004/11/25 13:12:02 $
7   Version:   $Revision: 1.164 $
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 "gdcmFile.h"
20 #include "gdcmDocument.h"
21 #include "gdcmDebug.h"
22 #include "gdcmUtil.h"
23 #include "gdcmBinEntry.h"
24 #include <fstream>
25
26 namespace gdcm 
27 {
28 typedef std::pair<TagDocEntryHT::iterator,TagDocEntryHT::iterator> IterHT;
29
30 //-------------------------------------------------------------------------
31 // Constructor / Destructor
32 /**
33  * \brief Constructor dedicated to deal with the *pixels* area of a ACR/DICOMV3
34  *        file (Header only deals with the ... header)
35  *        Opens (in read only and when possible) an existing file and checks
36  *        for DICOM compliance. Returns NULL on failure.
37  *        It will be up to the user to load the pixels into memory
38  *        (see GetImageData, GetImageDataRaw)
39  * \note  the in-memory representation of all available tags found in
40  *        the DICOM header is post-poned to first header information access.
41  *        This avoid a double parsing of public part of the header when
42  *        user sets an a posteriori shadow dictionary (efficiency can be
43  *        seen as a side effect).   
44  * @param header already built Header
45  */
46 File::File(Header *header)
47 {
48    HeaderInternal = header;
49    SelfHeader = false;
50    Initialise();
51 }
52
53 /**
54  * \brief Constructor dedicated to deal with the *pixels* area of a ACR/DICOMV3
55  *        file (Header only deals with the ... header)
56  *        Opens (in read only and when possible) an existing file and checks
57  *        for DICOM compliance. Returns NULL on failure.
58  *        It will be up to the user to load the pixels into memory
59  *        (see GetImageData, GetImageDataRaw)
60  * \note  the in-memory representation of all available tags found in
61  *        the DICOM header is post-poned to first header information access.
62  *        This avoid a double parsing of public part of the header when
63  *        one sets an a posteriori shadow dictionary (efficiency can be
64  *        seen as a side effect).   
65  * @param filename file to be opened for parsing
66  */
67 File::File(std::string const & filename )
68 {
69    HeaderInternal = new Header( filename );
70    SelfHeader = true;
71    Initialise();
72 }
73
74 /**
75  * \brief Factorization for various forms of constructors.
76  */
77 void File::Initialise()
78 {
79    WriteMode = WMODE_DECOMPRESSED;
80    WriteType = WTYPE_IMPL_VR;
81
82    PixelConverter = new PixelConvert;
83    Archive = new DocEntryArchive( HeaderInternal );
84
85    if ( HeaderInternal->IsReadable() )
86    {
87       PixelConverter->GrabInformationsFromHeader( HeaderInternal );
88    }
89
90    Pixel_Data = 0;
91    ImageDataSize = 0;
92 }
93
94 /**
95  * \brief canonical destructor
96  * \note  If the Header was created by the File constructor,
97  *        it is destroyed by the File
98  */
99 File::~File()
100
101    if( PixelConverter )
102    {
103       delete PixelConverter;
104    }
105    if( Archive )
106    {
107       delete Archive;
108    }
109
110    if( SelfHeader )
111    {
112       delete HeaderInternal;
113    }
114    HeaderInternal = 0;
115 }
116
117 //-----------------------------------------------------------------------------
118 // Print
119
120 //-----------------------------------------------------------------------------
121 // Public
122 /**
123  * \brief   Get the size of the image data
124  * 
125  *          If the image can be RGB (with a lut or by default), the size 
126  *          corresponds to the RGB image
127  * @return  The image size
128  */
129 size_t File::GetImageDataSize()
130 {
131    return PixelConverter->GetRGBSize();
132 }
133
134 /**
135  * \brief   Get the size of the image data
136  * 
137  *          If the image can be RGB by transformation in a LUT, this
138  *          transformation isn't considered
139  * @return  The raw image size
140  */
141 size_t File::GetImageDataRawSize()
142 {
143    return PixelConverter->GetDecompressedSize();
144 }
145
146 /**
147  * \brief   - Allocates necessary memory, 
148  *          - Reads the pixels from disk (uncompress if necessary),
149  *          - Transforms YBR pixels, if any, into RGB pixels
150  *          - Transforms 3 planes R, G, B, if any, into a single RGB Plane
151  *          - Transforms single Grey plane + 3 Palettes into a RGB Plane
152  *          - Copies the pixel data (image[s]/volume[s]) to newly allocated zone.
153  * @return  Pointer to newly allocated pixel data.
154  *          NULL if alloc fails 
155  */
156 uint8_t* File::GetImageData()
157 {
158    if ( ! GetDecompressed() )
159    {
160       // If the decompression failed nothing can be done.
161       return 0;
162    }
163
164    if ( HeaderInternal->HasLUT() && PixelConverter->BuildRGBImage() )
165    {
166       return PixelConverter->GetRGB();
167    }
168    else
169    {
170       // When no LUT or LUT conversion fails, return the decompressed
171       return PixelConverter->GetDecompressed();
172    }
173 }
174
175 /**
176  * \brief
177  *          Read the pixels from disk (uncompress if necessary),
178  *          Transforms YBR pixels, if any, into RGB pixels
179  *          Transforms 3 planes R, G, B, if any, into a single RGB Plane
180  *          Transforms single Grey plane + 3 Palettes into a RGB Plane   
181  *          Copies at most MaxSize bytes of pixel data to caller allocated
182  *          memory space.
183  * \warning This function allows people that want to build a volume
184  *          from an image stack *not to* have, first to get the image pixels, 
185  *          and then move them to the volume area.
186  *          It's absolutely useless for any VTK user since vtk chooses 
187  *          to invert the lines of an image, that is the last line comes first
188  *          (for some axis related reasons?). Hence he will have 
189  *          to load the image line by line, starting from the end.
190  *          VTK users have to call GetImageData
191  *     
192  * @param   destination Address (in caller's memory space) at which the
193  *          pixel data should be copied
194  * @param   maxSize Maximum number of bytes to be copied. When MaxSize
195  *          is not sufficient to hold the pixel data the copy is not
196  *          executed (i.e. no partial copy).
197  * @return  On success, the number of bytes actually copied. Zero on
198  *          failure e.g. MaxSize is lower than necessary.
199  */
200 size_t File::GetImageDataIntoVector (void* destination, size_t maxSize)
201 {
202    if ( ! GetDecompressed() )
203    {
204       // If the decompression failed nothing can be done.
205       return 0;
206    }
207
208    if ( HeaderInternal->HasLUT() && PixelConverter->BuildRGBImage() )
209    {
210       if ( PixelConverter->GetRGBSize() > maxSize )
211       {
212          dbg.Verbose(0, "File::GetImageDataIntoVector: pixel data bigger"
213                         "than caller's expected MaxSize");
214          return 0;
215       }
216       memcpy( destination,
217               (void*)PixelConverter->GetRGB(),
218               PixelConverter->GetRGBSize() );
219       return PixelConverter->GetRGBSize();
220    }
221
222    // Either no LUT conversion necessary or LUT conversion failed
223    if ( PixelConverter->GetDecompressedSize() > maxSize )
224    {
225       dbg.Verbose(0, "File::GetImageDataIntoVector: pixel data bigger"
226                      "than caller's expected MaxSize");
227       return 0;
228    }
229    memcpy( destination,
230            (void*)PixelConverter->GetDecompressed(),
231            PixelConverter->GetDecompressedSize() );
232    return PixelConverter->GetDecompressedSize();
233 }
234
235 /**
236  * \brief   Allocates necessary memory, 
237  *          Transforms YBR pixels (if any) into RGB pixels
238  *          Transforms 3 planes R, G, B  (if any) into a single RGB Plane
239  *          Copies the pixel data (image[s]/volume[s]) to newly allocated zone. 
240  *          DOES NOT transform Grey plane + 3 Palettes into a RGB Plane
241  * @return  Pointer to newly allocated pixel data.
242  * \        NULL if alloc fails 
243  */
244 uint8_t* File::GetImageDataRaw ()
245 {
246    return GetDecompressed();
247 }
248
249 uint8_t* File::GetDecompressed()
250 {
251    uint8_t* decompressed = PixelConverter->GetDecompressed();
252    if ( ! decompressed )
253    {
254       // The decompressed image migth not be loaded yet:
255       std::ifstream* fp = HeaderInternal->OpenFile();
256       PixelConverter->ReadAndDecompressPixelData( fp );
257       if(fp) 
258          HeaderInternal->CloseFile();
259
260       decompressed = PixelConverter->GetDecompressed();
261       if ( ! decompressed )
262       {
263          dbg.Verbose(0, "File::GetDecompressed: read/decompress of "
264                         "pixel data apparently went wrong.");
265          return 0;
266       }
267    }
268
269    return decompressed;
270 }
271
272 /**
273  * \brief   Points the internal Pixel_Data pointer to the callers inData
274  *          image representation, BUT WITHOUT COPYING THE DATA.
275  *          'image' Pixels are presented as C-like 2D arrays : line per line.
276  *          'volume'Pixels are presented as C-like 3D arrays : plane per plane 
277  * \warning Since the pixels are not copied, it is the caller's responsability
278  *          not to deallocate it's data before gdcm uses them (e.g. with
279  *          the Write() method.
280  * @param inData user supplied pixel area
281  * @param expectedSize total image size, in Bytes
282  *
283  * @return boolean
284  */
285 bool File::SetImageData(uint8_t* inData, size_t expectedSize)
286 {
287 // FIXME : if already allocated, memory leak !
288    Pixel_Data     = inData;
289    ImageDataSize = expectedSize;
290 // FIXME : 7fe0, 0010 IS NOT set ...
291    return true;
292 }
293
294 /**
295  * \brief Writes on disk A SINGLE Dicom file
296  *        NO test is performed on  processor "Endiannity".
297  *        It's up to the user to call his Reader properly
298  * @param fileName name of the file to be created
299  *                 (any already existing file is over written)
300  * @return false if write fails
301  */
302
303 bool File::WriteRawData(std::string const & fileName)
304 {
305   std::ofstream fp1(fileName.c_str(), std::ios::out | std::ios::binary );
306    if (!fp1)
307    {
308       dbg.Verbose(2, "Fail to open (write) file:", fileName.c_str());
309       return false;
310    }
311    fp1.write((char*)Pixel_Data, ImageDataSize);
312    fp1.close();
313
314    return true;
315 }
316
317 /**
318  * \brief Writes on disk A SINGLE Dicom file, 
319  *        using the Implicit Value Representation convention
320  *        NO test is performed on  processor "Endiannity".
321  * @param fileName name of the file to be created
322  *                 (any already existing file is overwritten)
323  * @return false if write fails
324  */
325
326 bool File::WriteDcmImplVR (std::string const & fileName)
327 {
328    SetWriteTypeToDcmImplVR();
329    return Write(fileName);
330 }
331
332 /**
333 * \brief Writes on disk A SINGLE Dicom file, 
334  *        using the Explicit Value Representation convention
335  *        NO test is performed on  processor "Endiannity". * @param fileName name of the file to be created
336  *                 (any already existing file is overwritten)
337  * @return false if write fails
338  */
339
340 bool File::WriteDcmExplVR (std::string const & fileName)
341 {
342    SetWriteTypeToDcmExplVR();
343    return Write(fileName);
344 }
345
346 /**
347  * \brief Writes on disk A SINGLE Dicom file, 
348  *        using the ACR-NEMA convention
349  *        NO test is performed on  processor "Endiannity".
350  *        (a l'attention des logiciels cliniques 
351  *        qui ne prennent en entrée QUE des images ACR ...
352  * \warning if a DICOM_V3 header is supplied,
353  *         groups < 0x0008 and shadow groups are ignored
354  * \warning NO TEST is performed on processor "Endiannity".
355  * @param fileName name of the file to be created
356  *                 (any already existing file is overwritten)
357  * @return false if write fails
358  */
359
360 bool File::WriteAcr (std::string const & fileName)
361 {
362    SetWriteTypeToAcr();
363    return Write(fileName);
364 }
365
366 bool File::Write(std::string const& fileName)
367 {
368    switch(WriteType)
369    {
370       case WTYPE_IMPL_VR:
371          return WriteBase(fileName,ImplicitVR);
372       case WTYPE_EXPL_VR:
373          return WriteBase(fileName,ExplicitVR);
374       case WTYPE_ACR:
375          return WriteBase(fileName,ACR);
376    }
377    return(false);
378 }
379
380 /**
381  * \brief Access to the underlying \ref PixelConverter RGBA LUT
382  */
383 uint8_t* File::GetLutRGBA()
384 {
385    return PixelConverter->GetLutRGBA();
386 }
387
388 //-----------------------------------------------------------------------------
389 // Protected
390 /**
391  * \brief NOT a end user inteded function
392  *        (used by WriteDcmExplVR, WriteDcmImplVR, WriteAcr, etc)
393  * @param fileName name of the file to be created
394  *                 (any already existing file is overwritten)
395  * @param  type file type (ExplicitVR, ImplicitVR, ...)
396  * @return false if write fails
397  */
398 bool File::WriteBase (std::string const & fileName, FileType type)
399 {
400    switch(type)
401    {
402       case ImplicitVR:
403          SetWriteFileTypeToImplicitVR();
404          break;
405       case ExplicitVR:
406          SetWriteFileTypeToExplicitVR();
407          break;
408       case ACR:
409          SetWriteFileTypeToACR();
410          break;
411       case ACR_LIBIDO:
412          SetWriteFileTypeToACRLibido();
413          break;
414    }
415   
416    switch(WriteMode)
417    {
418       case WMODE_NATIVE :
419          SetWriteToNative();
420          break;
421       case WMODE_DECOMPRESSED :
422          SetWriteToDecompressed();
423          break;
424       case WMODE_RGB :
425          SetWriteToRGB();
426          break;
427    }
428
429    // --------------------------------------------------------------
430    // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
431    //
432    // if recognition code tells us we dealt with a LibIDO image
433    // we reproduce on disk the switch between lineNumber and columnNumber
434    // just before writting ...
435    /// \todo the best trick would be *change* the recognition code
436    ///       but pb expected if user deals with, e.g. COMPLEX images
437 /*   if ( HeaderInternal->GetFileType() == ACR_LIBIDO)
438    {
439       SetWriteToLibido();
440    }*/
441    // ----------------- End of Special Patch ----------------
442
443    bool check = CheckWriteIntegrity();
444    if(check)
445    {
446       check = HeaderInternal->Write(fileName,type);
447    }
448
449    // --------------------------------------------------------------
450    // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
451    // 
452    // ...and we restore the Header to be Dicom Compliant again 
453    // just after writting
454 /*   if ( HeaderInternal->GetFileType() == ACR_LIBIDO )
455    {
456       RestoreWriteFromLibido();
457    }*/
458    // ----------------- End of Special Patch ----------------
459
460    RestoreWrite();
461    RestoreWriteFileType();
462
463    return check;
464 }
465
466 /**
467  * \brief Check the write integrity
468  *
469  * The tests made are :
470  *  - verify the size of the image to write with the possible write
471  *    when the user set an image data
472  * @return true if the check successfulls
473  */
474 bool File::CheckWriteIntegrity()
475 {
476    if(Pixel_Data)
477    {
478       int numberBitsAllocated = HeaderInternal->GetBitsAllocated();
479       if ( numberBitsAllocated == 0 || numberBitsAllocated == 12 )
480       {
481          numberBitsAllocated = 16;
482       }
483
484       int decSize = HeaderInternal->GetXSize()
485                     * HeaderInternal->GetYSize() 
486                     * HeaderInternal->GetZSize()
487                     * ( numberBitsAllocated / 8 )
488                     * HeaderInternal->GetSamplesPerPixel();
489       int rgbSize = decSize;
490       if( HeaderInternal->HasLUT() )
491          rgbSize = decSize * 3;
492
493       switch(WriteMode)
494       {
495          case WMODE_NATIVE :
496             break;
497          case WMODE_DECOMPRESSED :
498             if( decSize!=ImageDataSize )
499             {
500                dbg.Verbose(0, "File::CheckWriteIntegrity: Data size is incorrect");
501                //std::cerr<<"Dec : "<<decSize<<" | "<<ImageDataSize<<std::endl;
502                return false;
503             }
504             break;
505          case WMODE_RGB :
506             if( rgbSize!=ImageDataSize )
507             {
508                dbg.Verbose(0, "File::CheckWriteIntegrity: Data size is incorrect");
509                //std::cerr<<"RGB : "<<decSize<<" | "<<ImageDataSize<<std::endl;
510                return false;
511             }
512             break;
513       }
514    }
515    
516    return true;
517 }
518
519 void File::SetWriteToNative()
520 {
521    if(Pixel_Data)
522    {
523       BinEntry* pixel = CopyBinEntry(GetHeader()->GetGrPixel(),GetHeader()->GetNumPixel());
524       pixel->SetValue(GDCM_BINLOADED);
525       pixel->SetBinArea(Pixel_Data,false);
526       pixel->SetLength(ImageDataSize);
527
528       Archive->Push(pixel);
529    }
530 }
531
532 void File::SetWriteToDecompressed()
533 {
534    if(HeaderInternal->GetNumberOfScalarComponents()==3 && !HeaderInternal->HasLUT())
535    {
536       SetWriteToRGB();
537    } 
538    else
539    {
540       ValEntry* photInt = CopyValEntry(0x0028,0x0004);
541       if(HeaderInternal->HasLUT())
542       {
543          photInt->SetValue("PALETTE COLOR ");
544          photInt->SetLength(14);
545       }
546       else
547       {
548          photInt->SetValue("MONOCHROME1 ");
549          photInt->SetLength(12);
550       }
551
552       BinEntry* pixel = CopyBinEntry(GetHeader()->GetGrPixel(),GetHeader()->GetNumPixel());
553       pixel->SetValue(GDCM_BINLOADED);
554       if(Pixel_Data)
555       {
556          pixel->SetBinArea(Pixel_Data,false);
557          pixel->SetLength(ImageDataSize);
558       }
559       else
560       {
561          pixel->SetBinArea(PixelConverter->GetDecompressed(),false);
562          pixel->SetLength(PixelConverter->GetDecompressedSize());
563       }
564
565       Archive->Push(photInt);
566       Archive->Push(pixel);
567    }
568 }
569
570 void File::SetWriteToRGB()
571 {
572    if(HeaderInternal->GetNumberOfScalarComponents()==3)
573    {
574       PixelConverter->BuildRGBImage();
575       
576       ValEntry* spp = CopyValEntry(0x0028,0x0002);
577       spp->SetValue("3 ");
578       spp->SetLength(2);
579
580       ValEntry* planConfig = CopyValEntry(0x0028,0x0006);
581       planConfig->SetValue("0 ");
582       planConfig->SetLength(2);
583
584       ValEntry* photInt = CopyValEntry(0x0028,0x0004);
585       photInt->SetValue("RGB ");
586       photInt->SetLength(4);
587
588       BinEntry* pixel = CopyBinEntry(GetHeader()->GetGrPixel(),GetHeader()->GetNumPixel());
589       pixel->SetValue(GDCM_BINLOADED);
590       if(Pixel_Data)
591       {
592          pixel->SetBinArea(Pixel_Data,false);
593          pixel->SetLength(ImageDataSize);
594       }
595       else if(PixelConverter->GetRGB())
596       {
597          pixel->SetBinArea(PixelConverter->GetRGB(),false);
598          pixel->SetLength(PixelConverter->GetRGBSize());
599       }
600       else // Decompressed data
601       {
602          pixel->SetBinArea(PixelConverter->GetDecompressed(),false);
603          pixel->SetLength(PixelConverter->GetDecompressedSize());
604       }
605
606       Archive->Push(spp);
607       Archive->Push(planConfig);
608       Archive->Push(photInt);
609       Archive->Push(pixel);
610
611       // Remove any LUT
612       Archive->Push(0x0028,0x1101);
613       Archive->Push(0x0028,0x1102);
614       Archive->Push(0x0028,0x1103);
615       Archive->Push(0x0028,0x1201);
616       Archive->Push(0x0028,0x1202);
617       Archive->Push(0x0028,0x1203);
618
619       // For old ACR-NEMA
620       // Thus, we have a RGB image and the bits allocated = 24 and 
621       // samples per pixels = 1 (in the read file)
622       if(HeaderInternal->GetBitsAllocated()==24) 
623       {
624          ValEntry* bitsAlloc = CopyValEntry(0x0028,0x0100);
625          bitsAlloc->SetValue("8 ");
626          bitsAlloc->SetLength(2);
627
628          ValEntry* bitsStored = CopyValEntry(0x0028,0x0101);
629          bitsStored->SetValue("8 ");
630          bitsStored->SetLength(2);
631
632          ValEntry* highBit = CopyValEntry(0x0028,0x0102);
633          highBit->SetValue("7 ");
634          highBit->SetLength(2);
635
636          Archive->Push(bitsAlloc);
637          Archive->Push(bitsStored);
638          Archive->Push(highBit);
639       }
640    }
641    else
642    {
643       SetWriteToDecompressed();
644    }
645 }
646
647 void File::RestoreWrite()
648 {
649    Archive->Restore(0x0028,0x0002);
650    Archive->Restore(0x0028,0x0004);
651    Archive->Restore(0x0028,0x0006);
652    Archive->Restore(GetHeader()->GetGrPixel(),GetHeader()->GetNumPixel());
653
654    // For old ACR-NEMA (24 bits problem)
655    Archive->Restore(0x0028,0x0100);
656    Archive->Restore(0x0028,0x0101);
657    Archive->Restore(0x0028,0x0102);
658
659    // For the LUT
660    Archive->Restore(0x0028,0x1101);
661    Archive->Restore(0x0028,0x1102);
662    Archive->Restore(0x0028,0x1103);
663    Archive->Restore(0x0028,0x1201);
664    Archive->Restore(0x0028,0x1202);
665    Archive->Restore(0x0028,0x1203);
666 }
667
668 void File::SetWriteFileTypeToACR()
669 {
670    Archive->Push(0x0002,0x0010);
671 }
672
673 void File::SetWriteFileTypeToACRLibido()
674 {
675    SetWriteFileTypeToACR();
676 }
677
678 void File::SetWriteFileTypeToExplicitVR()
679 {
680    std::string ts = 
681       Util::DicomString( TransferSyntaxStrings[ExplicitVRLittleEndian] );
682
683    ValEntry* tss = CopyValEntry(0x0002,0x0010);
684    tss->SetValue(ts);
685    tss->SetLength(ts.length());
686
687    Archive->Push(tss);
688 }
689
690 void File::SetWriteFileTypeToImplicitVR()
691 {
692    std::string ts = 
693       Util::DicomString( TransferSyntaxStrings[ImplicitVRLittleEndian] );
694
695    ValEntry* tss = CopyValEntry(0x0002,0x0010);
696    tss->SetValue(ts);
697    tss->SetLength(ts.length());
698 }
699
700 void File::RestoreWriteFileType()
701 {
702    Archive->Restore(0x0002,0x0010);
703 }
704
705 void File::SetWriteToLibido()
706 {
707    ValEntry *oldRow = dynamic_cast<ValEntry *>(HeaderInternal->GetDocEntryByNumber(0x0028, 0x0010));
708    ValEntry *oldCol = dynamic_cast<ValEntry *>(HeaderInternal->GetDocEntryByNumber(0x0028, 0x0011));
709    
710    if( oldRow && oldCol )
711    {
712       std::string rows, columns; 
713
714       ValEntry *newRow=new ValEntry(oldRow->GetDictEntry());
715       ValEntry *newCol=new ValEntry(oldCol->GetDictEntry());
716
717       newRow->Copy(oldCol);
718       newCol->Copy(oldRow);
719
720       newRow->SetValue(oldCol->GetValue());
721       newCol->SetValue(oldRow->GetValue());
722
723       Archive->Push(newRow);
724       Archive->Push(newCol);
725    }
726 }
727
728 void File::RestoreWriteFromLibido()
729 {
730    Archive->Restore(0x0028,0x0010);
731    Archive->Restore(0x0028,0x0011);
732 }
733
734 ValEntry* File::CopyValEntry(uint16_t group,uint16_t element)
735 {
736    DocEntry* oldE = HeaderInternal->GetDocEntryByNumber(group, element);
737    ValEntry* newE;
738
739    if(oldE)
740    {
741       newE = new ValEntry(oldE->GetDictEntry());
742       newE->Copy(oldE);
743    }
744    else
745    {
746       newE = GetHeader()->NewValEntryByNumber(group,element);
747    }
748
749    return(newE);
750 }
751
752 BinEntry* File::CopyBinEntry(uint16_t group,uint16_t element)
753 {
754    DocEntry* oldE = HeaderInternal->GetDocEntryByNumber(group, element);
755    BinEntry* newE;
756
757    if(oldE)
758    {
759       newE = new BinEntry(oldE->GetDictEntry());
760       newE->Copy(oldE);
761    }
762    else
763    {
764       newE = GetHeader()->NewBinEntryByNumber(group,element);
765    }
766
767
768    return(newE);
769 }
770
771 //-----------------------------------------------------------------------------
772 // Private
773 /**
774  * \brief Set the pixel datas in the good entry of the Header
775  */
776 void File::SetPixelData(uint8_t* data)
777 {
778    GetHeader()->SetEntryByNumber( GDCM_BINLOADED,
779       GetHeader()->GetGrPixel(), GetHeader()->GetNumPixel());
780
781    // Will be 7fe0, 0010 in standard case
782    DocEntry* currentEntry = GetHeader()->GetDocEntryByNumber(GetHeader()->GetGrPixel(), GetHeader()->GetNumPixel());
783    if ( currentEntry )
784    {
785       if ( BinEntry* binEntry = dynamic_cast<BinEntry *>(currentEntry) )
786          // Flag is to false because datas are kept in the gdcmPixelConvert
787          binEntry->SetBinArea( data, false );
788    }
789 }
790
791 //-----------------------------------------------------------------------------
792 } // end namespace gdcm
793