]> Creatis software - gdcm.git/blob - src/gdcmRLEFramesInfo.cxx
ENH: Yet another pass to get RLE stuff similar to JPEG. I am still unhappy with the...
[gdcm.git] / src / gdcmRLEFramesInfo.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmRLEFramesInfo.cxx,v $
5   Language:  C++
6   Date:      $Date: 2005/01/31 06:17:22 $
7   Version:   $Revision: 1.10 $
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 "gdcmRLEFramesInfo.h"
20 #include "gdcmDebug.h"
21
22 namespace gdcm 
23 {
24
25 RLEFramesInfo::~RLEFramesInfo()
26 {
27    for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it)
28    {
29       delete (*it);
30    }
31    Frames.clear();
32 }
33
34 /**
35  * \brief        Print self.
36  * @param indent Indentation string to be prepended during printing.
37  * @param os     Stream to print to.
38  */
39 void RLEFramesInfo::Print( std::ostream &os, std::string indent )
40 {
41    os << std::endl;
42    os << indent
43       << "----------------- RLE frames --------------------------------"
44       << std::endl;
45    os << indent
46       << "Total number of Frames : " << Frames.size()
47       << std::endl;
48    int frameNumber = 0;
49    for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it)
50    {
51       os << indent
52          << "   frame number :" << frameNumber++
53          << std::endl;
54       (*it)->Print( os, indent + "   " );
55    }
56 }
57
58 void RLEFramesInfo::AddFrame(RLEFrame *frame)
59 {
60    Frames.push_back(frame);
61 }
62
63 RLEFrame *RLEFramesInfo::GetFirstFrame()
64 {
65    ItFrames = Frames.begin();
66    if (ItFrames != Frames.end())
67       return  *ItFrames;
68    return NULL;
69 }
70
71 RLEFrame *RLEFramesInfo::GetNextFrame()
72 {
73    gdcmAssertMacro (ItFrames != Frames.end());
74
75    ++ItFrames;
76    if (ItFrames != Frames.end())
77       return  *ItFrames;
78    return NULL;
79 }
80
81 /**
82  * \brief     Reads from disk the Pixel Data of 'Run Length Encoded'
83  *            Dicom encapsulated file and decompress it.
84  * @param     fp already open File Pointer
85  *            at which the pixel data should be copied
86  * @return    Boolean
87  */
88 bool RLEFramesInfo::DecompressRLEFile( std::ifstream *fp , uint8_t *raw, int xSize, int ySize, int zSize, int bitsAllocated )
89 {
90    uint8_t *subRaw = raw;
91    long rawSegmentSize = xSize * ySize;
92
93    // Loop on the frame[s]
94    for(RLEFrameList::iterator it = Frames.begin(); it != Frames.end(); ++it)
95    {
96       subRaw = (*it)->ReadAndDecompressRLEFrame( subRaw, rawSegmentSize, fp);
97    }
98
99    if ( bitsAllocated == 16 )
100    {
101       // Try to deal with RLE 16 Bits
102       ConvertRLE16BitsFromRLE8Bits( raw, xSize, ySize, zSize );
103    }
104
105    return true;
106 }
107
108 /**
109  * \brief     Try to deal with RLE 16 Bits. 
110  *            We assume the RLE has already been parsed and loaded in
111  *            Raw (through \ref ReadAndDecompressJPEGFile ).
112  *            We here need to make 16 Bits Pixels from Low Byte and
113  *            High Byte 'Planes'...(for what it may mean)
114  * @return    Boolean
115  */
116 bool RLEFramesInfo::ConvertRLE16BitsFromRLE8Bits( uint8_t* raw, int xSize, 
117                                              int ySize,int numberOfFrames  )
118 {
119    size_t pixelNumber = xSize * ySize;
120    size_t rawSize = xSize * ySize * numberOfFrames;
121
122    // We assumed Raw contains the decoded RLE pixels but as
123    // 8 bits per pixel. In order to convert those pixels to 16 bits
124    // per pixel we cannot work in place within Raw and hence
125    // we copy it in a safe place, say copyRaw.
126
127    uint8_t* copyRaw = new uint8_t[rawSize * 2];
128    memmove( copyRaw, raw, rawSize * 2 );
129
130    uint8_t* x = raw;
131    uint8_t* a = copyRaw;
132    uint8_t* b = a + pixelNumber;
133
134    for ( int i = 0; i < numberOfFrames; i++ )
135    {
136       for ( unsigned int j = 0; j < pixelNumber; j++ )
137       {
138          *(x++) = *(b++);
139          *(x++) = *(a++);
140       }
141    }
142
143    delete[] copyRaw;
144       
145    /// \todo check that operator new []didn't fail, and sometimes return false
146    return true;
147 }
148
149
150 } // end namespace gdcm