1 /*
2  *
3  *  Copyright (C) 1996-2016, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  dcmimage
15  *
16  *  Author:  Joerg Riesmeier
17  *
18  *  Purpose: DicomARGBPixelTemplate (Header) - UNTESTED !!!
19  *
20  */
21 
22 
23 #ifndef DIARGPXT_H
24 #define DIARGPXT_H
25 
26 #include "dcmtk/config/osconfig.h"
27 
28 #include "dcmtk/dcmimage/dicopxt.h"
29 #include "dcmtk/dcmimgle/diluptab.h"
30 #include "dcmtk/dcmimgle/diinpx.h"  /* gcc 3.4 needs this */
31 
32 /*---------------------*
33  *  class declaration  *
34  *---------------------*/
35 
36 /** Template class to handle ARGB pixel data
37  */
38 template<class T1, class T2, class T3>
39 class DiARGBPixelTemplate
40   : public DiColorPixelTemplate<T3>
41 {
42 
43  public:
44 
45     /** constructor
46      *
47      ** @param  docu       pointer to DICOM document
48      *  @param  pixel      pointer to input pixel representation
49      *  @param  palette    pointer to RGB color palette
50      *  @param  status     reference to status variable
51      *  @param  planeSize  number of pixels in a plane
52      *  @param  bits       number of bits per sample
53      */
DiARGBPixelTemplate(const DiDocument * docu,const DiInputPixel * pixel,DiLookupTable * palette[3],EI_Status & status,const unsigned long planeSize,const int bits)54     DiARGBPixelTemplate(const DiDocument *docu,
55                         const DiInputPixel *pixel,
56                         DiLookupTable *palette[3],
57                         EI_Status &status,
58                         const unsigned long planeSize,
59                         const int bits)
60       : DiColorPixelTemplate<T3>(docu, pixel, 4, status)
61     {
62         if ((pixel != NULL) && (this->Count > 0) && (status == EIS_Normal))
63             convert(OFstatic_cast(const T1 *, pixel->getData()) + pixel->getPixelStart(), palette, planeSize, bits);
64     }
65 
66     /** destructor
67      */
~DiARGBPixelTemplate()68     virtual ~DiARGBPixelTemplate()
69     {
70     }
71 
72 
73  private:
74 
75     /** convert input pixel data to intermediate representation
76      *
77      ** @param  pixel      pointer to input pixel data
78      *  @param  palette    pointer to RGB color palette
79      *  @param  planeSize  number of pixels in a plane
80      *  @param  bits       number of bits per sample
81      */
convert(const T1 * pixel,DiLookupTable * palette[3],const unsigned long planeSize,const int bits)82     void convert(const T1 *pixel,
83                  DiLookupTable *palette[3],
84                  const unsigned long planeSize,
85                  const int bits)
86     {                                             // not very much optimized, but no one really uses ARGB !!
87         if (this->Init(pixel))
88         {
89             T2 value;
90             const T1 offset = OFstatic_cast(T1, DicomImageClass::maxval(bits - 1));
91             // use the number of input pixels derived from the length of the 'PixelData'
92             // attribute), but not more than the size of the intermediate buffer
93             const unsigned long count = (this->InputCount < this->Count) ? this->InputCount : this->Count;
94             if (this->PlanarConfiguration)
95             {
96 /*
97                 const T1 *a = pixel;                                            // points to alpha plane
98                 const T1 *rgb[3];
99                 rgb[0] = a + this->InputCount;                                  // points to red plane
100                 rgb[1] = rgb[0] + this->InputCount;                             // points to green plane
101                 rgb[2] = rgb[1] + this->InputCount;                             // points to blue plane
102                 for (i = 0; i < count; ++i)
103                 {
104                     value = OFstatic_cast(T2, *(a++));                          // get alpha value
105                     if (value > 0)
106                     {
107                         for (int j = 0; j < 3; ++j)                             // set palette color
108                         {
109                             if (value <= palette[j]->getFirstEntry(value))
110                                 this->Data[j][i] = OFstatic_cast(T3, palette[j]->getFirstValue());
111                             else if (value >= palette[j]->getLastEntry(value))
112                                 this->Data[j][i] = OFstatic_cast(T3, palette[j]->getLastValue());
113                             else
114                                 this->Data[j][i] = OFstatic_cast(T3, palette[j]->getValue(value));
115                             ++rgb[j];                                           // skip RGB values
116                         }
117                     }
118                     else
119                     {
120                         for (j = 0; j < 3; ++j)                                 // copy RGB values
121                             this->Data[j][i] = OFstatic_cast(T3, removeSign(*(rgb[j]++), offset));
122                     }
123                 }
124 */
125                 unsigned long l;
126                 unsigned long i = 0;
127                 const T1 *a = pixel;                                            // points to alpha plane
128                 const T1 *rgb[3];
129                 rgb[0] = a + planeSize;                                         // points to red plane
130                 rgb[1] = rgb[0] + planeSize;                                    // points to green plane
131                 rgb[2] = rgb[1] + planeSize;                                    // points to blue plane
132                 while (i < count)
133                 {
134                     /* convert a single frame */
135                     for (l = planeSize; (l != 0) && (i < count); --l, ++i)
136                     {
137                         value = OFstatic_cast(T2, *(a++));                      // get alpha value
138                         if (value > 0)
139                         {
140                             for (int j = 0; j < 3; ++j)                         // set palette color
141                             {
142                                 if (value <= palette[j]->getFirstEntry(value))
143                                     this->Data[j][i] = OFstatic_cast(T3, palette[j]->getFirstValue());
144                                 else if (value >= palette[j]->getLastEntry(value))
145                                     this->Data[j][i] = OFstatic_cast(T3, palette[j]->getLastValue());
146                                 else
147                                     this->Data[j][i] = OFstatic_cast(T3, palette[j]->getValue(value));
148                                 ++rgb[j];                                       // skip RGB values
149                             }
150                         }
151                         else
152                         {
153                             for (int j = 0; j < 3; ++j)                         // copy RGB values
154                                 this->Data[j][i] = OFstatic_cast(T3, removeSign(*(rgb[j]++), offset));
155                         }
156                     }
157                     /* jump to next frame start (skip 2 planes) */
158                     a += 2 * planeSize;
159                     for (int j = 0; j < 3; ++j)
160                        rgb[j] += 2 * planeSize;
161                 }
162             } else {
163                 unsigned long i;
164                 const T1 *p = pixel;
165                 for (i = 0; i < count; ++i)
166                 {
167                     value = OFstatic_cast(T2, *(p++));                          // get alpha value
168                     if (value > 0)
169                     {
170                         for (int j = 0; j < 3; ++j)                             // set palette color
171                         {
172                             if (value <= palette[j]->getFirstEntry(value))
173                                 this->Data[j][i] = OFstatic_cast(T3, palette[j]->getFirstValue());
174                             else if (value >= palette[j]->getLastEntry(value))
175                                 this->Data[j][i] = OFstatic_cast(T3, palette[j]->getLastValue());
176                             else
177                                 this->Data[j][i] = OFstatic_cast(T3, palette[j]->getValue(value));
178                         }
179                         p += 3;                                                 // skip RGB values
180                     }
181                     else
182                     {
183                         for (int j = 0; j < 3; ++j)                             // copy RGB values
184                             this->Data[j][i] = OFstatic_cast(T3, removeSign(*(p++), offset));
185                     }
186                 }
187             }
188         }
189     }
190 };
191 
192 
193 #endif
194