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