00001 /* 00002 * 00003 * Copyright (C) 1996-2010, OFFIS e.V. 00004 * All rights reserved. See COPYRIGHT file for details. 00005 * 00006 * This software and supporting documentation were developed by 00007 * 00008 * OFFIS e.V. 00009 * R&D Division Health 00010 * Escherweg 2 00011 * D-26121 Oldenburg, Germany 00012 * 00013 * 00014 * Module: dcmimage 00015 * 00016 * Author: Joerg Riesmeier 00017 * 00018 * Purpose: DicomHSVPixelTemplate (Header) 00019 * 00020 * Last Update: $Author: joergr $ 00021 * Update Date: $Date: 2010-10-14 13:16:29 $ 00022 * CVS/RCS Revision: $Revision: 1.25 $ 00023 * Status: $State: Exp $ 00024 * 00025 * CVS/RCS Log at end of file 00026 * 00027 */ 00028 00029 00030 #ifndef DIHSVPXT_H 00031 #define DIHSVPXT_H 00032 00033 #include "dcmtk/config/osconfig.h" 00034 00035 #include "dcmtk/dcmimage/dicopxt.h" 00036 #include "dcmtk/dcmimgle/diinpx.h" /* gcc 3.4 needs this */ 00037 00038 00039 /*---------------------* 00040 * class declaration * 00041 *---------------------*/ 00042 00045 template<class T1, class T2> 00046 class DiHSVPixelTemplate 00047 : public DiColorPixelTemplate<T2> 00048 { 00049 00050 public: 00051 00060 DiHSVPixelTemplate(const DiDocument *docu, 00061 const DiInputPixel *pixel, 00062 EI_Status &status, 00063 const unsigned long planeSize, 00064 const int bits) 00065 : DiColorPixelTemplate<T2>(docu, pixel, 3, status) 00066 { 00067 if ((pixel != NULL) && (this->Count > 0) && (status == EIS_Normal)) 00068 convert(OFstatic_cast(const T1 *, pixel->getData()) + pixel->getPixelStart(), planeSize, bits); 00069 } 00070 00073 virtual ~DiHSVPixelTemplate() 00074 { 00075 } 00076 00077 00078 private: 00079 00086 void convert(const T1 *pixel, 00087 const unsigned long planeSize, 00088 const int bits) 00089 { 00090 if (Init(pixel)) 00091 { 00092 register T2 *r = this->Data[0]; 00093 register T2 *g = this->Data[1]; 00094 register T2 *b = this->Data[2]; 00095 const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits)); 00096 const T1 offset = OFstatic_cast(T1, DicomImageClass::maxval(bits - 1)); 00097 // use the number of input pixels derived from the length of the 'PixelData' 00098 // attribute), but not more than the size of the intermediate buffer 00099 const unsigned long count = (this->InputCount < this->Count) ? this->InputCount : this->Count; 00100 if (this->PlanarConfiguration) 00101 { 00102 /* 00103 register const T1 *h = pixel; 00104 register const T1 *s = h + this->InputCount; 00105 register const T1 *v = s + this->InputCount; 00106 for (i = count; i != 0; --i) 00107 convertValue(*(r++), *(g++), *(b++), removeSign(*(h++), offset), removeSign(*(s++), offset), 00108 removeSign(*(v++), offset), maxvalue); 00109 */ 00110 register unsigned long l; 00111 register unsigned long i = count; 00112 register const T1 *h = pixel; 00113 register const T1 *s = h + planeSize; 00114 register const T1 *v = s + planeSize; 00115 while (i != 0) 00116 { 00117 /* convert a single frame */ 00118 for (l = planeSize; (l != 0) && (i != 0); --l, --i) 00119 { 00120 convertValue(*(r++), *(g++), *(b++), removeSign(*(h++), offset), removeSign(*(s++), offset), 00121 removeSign(*(v++), offset), maxvalue); 00122 } 00123 /* jump to next frame start (skip 2 planes) */ 00124 h += 2 * planeSize; 00125 s += 2 * planeSize; 00126 v += 2 * planeSize; 00127 } 00128 } 00129 else 00130 { 00131 register const T1 *p = pixel; 00132 register T2 h; 00133 register T2 s; 00134 register T2 v; 00135 register unsigned long i; 00136 for (i = count; i != 0; --i) 00137 { 00138 h = removeSign(*(p++), offset); 00139 s = removeSign(*(p++), offset); 00140 v = removeSign(*(p++), offset); 00141 convertValue(*(r++), *(g++), *(b++), h, s, v, maxvalue); 00142 } 00143 } 00144 } 00145 } 00146 00149 void convertValue(T2 &red, 00150 T2 &green, 00151 T2 &blue, 00152 const T2 hue, 00153 const T2 saturation, 00154 const T2 value, 00155 const T2 maxvalue) 00156 { 00157 /* 00158 * conversion algorithm taken from Foley et al.: 'Computer Graphics: Principles and Practice' (1990) 00159 */ 00160 00161 if (saturation == 0) 00162 { 00163 red = value; 00164 green = value; 00165 blue = value; 00166 } 00167 else 00168 { 00169 const double h = (OFstatic_cast(double, hue) * 6) / (OFstatic_cast(double, maxvalue) + 1); // '... + 1' to assert h < 6 00170 const double s = OFstatic_cast(double, saturation) / OFstatic_cast(double, maxvalue); 00171 const double v = OFstatic_cast(double, value) / OFstatic_cast(double, maxvalue); 00172 const T2 hi = OFstatic_cast(T2, h); 00173 const double hf = h - hi; 00174 const T2 p = OFstatic_cast(T2, maxvalue * v * (1 - s)); 00175 const T2 q = OFstatic_cast(T2, maxvalue * v * (1 - s * hf)); 00176 const T2 t = OFstatic_cast(T2, maxvalue * v * (1 - s * (1 - hf))); 00177 switch (hi) 00178 { 00179 case 0: 00180 red = value; 00181 green = t; 00182 blue = p; 00183 break; 00184 case 1: 00185 red = q; 00186 green = value; 00187 blue = p; 00188 break; 00189 case 2: 00190 red = p; 00191 green = value; 00192 blue = t; 00193 break; 00194 case 3: 00195 red = p; 00196 green = q; 00197 blue = value; 00198 break; 00199 case 4: 00200 red = t; 00201 green = p; 00202 blue = value; 00203 break; 00204 case 5: 00205 red = value; 00206 green = p; 00207 blue = q; 00208 break; 00209 default: 00210 DCMIMAGE_WARN("invalid value for 'hi' while converting HSV to RGB"); 00211 } 00212 } 00213 } 00214 }; 00215 00216 00217 #endif 00218 00219 00220 /* 00221 * 00222 * CVS/RCS Log: 00223 * $Log: dihsvpxt.h,v $ 00224 * Revision 1.25 2010-10-14 13:16:29 joergr 00225 * Updated copyright header. Added reference to COPYRIGHT file. 00226 * 00227 * Revision 1.24 2010-03-01 09:08:46 uli 00228 * Removed some unnecessary include directives in the headers. 00229 * 00230 * Revision 1.23 2009-11-25 14:31:21 joergr 00231 * Removed inclusion of header file "ofconsol.h". 00232 * 00233 * Revision 1.22 2009-10-14 10:25:14 joergr 00234 * Fixed minor issues in log output. Also updated copyright date (if required). 00235 * 00236 * Revision 1.21 2009-10-13 14:08:33 uli 00237 * Switched to logging mechanism provided by the "new" oflog module 00238 * 00239 * Revision 1.20 2006-08-15 16:35:01 meichel 00240 * Updated the code in module dcmimage to correctly compile when 00241 * all standard C++ classes remain in namespace std. 00242 * 00243 * Revision 1.19 2005/12/08 16:01:39 meichel 00244 * Changed include path schema for all DCMTK header files 00245 * 00246 * Revision 1.18 2004/04/21 10:00:31 meichel 00247 * Minor modifications for compilation with gcc 3.4.0 00248 * 00249 * Revision 1.17 2003/12/23 11:48:23 joergr 00250 * Adapted type casts to new-style typecast operators defined in ofcast.h. 00251 * Removed leading underscore characters from preprocessor symbols (reserved 00252 * symbols). Updated copyright header. 00253 * Replaced post-increment/decrement operators by pre-increment/decrement 00254 * operators where appropriate (e.g. 'i++' by '++i'). 00255 * 00256 * Revision 1.16 2002/06/26 16:18:10 joergr 00257 * Enhanced handling of corrupted pixel data and/or length. 00258 * Corrected decoding of multi-frame, planar images. 00259 * 00260 * Revision 1.15 2001/11/09 16:47:01 joergr 00261 * Removed 'inline' specifier from certain methods. 00262 * 00263 * Revision 1.14 2001/06/01 15:49:30 meichel 00264 * Updated copyright header 00265 * 00266 * Revision 1.13 2000/04/28 12:39:32 joergr 00267 * DebugLevel - global for the module - now derived from OFGlobal (MF-safe). 00268 * 00269 * Revision 1.12 2000/04/27 13:15:13 joergr 00270 * Dcmimage library code now consistently uses ofConsole for error output. 00271 * 00272 * Revision 1.11 2000/03/08 16:21:52 meichel 00273 * Updated copyright header. 00274 * 00275 * Revision 1.10 2000/03/03 14:07:52 meichel 00276 * Implemented library support for redirecting error messages into memory 00277 * instead of printing them to stdout/stderr for GUI applications. 00278 * 00279 * Revision 1.9 1999/09/17 14:03:45 joergr 00280 * Enhanced efficiency of some "for" loops. 00281 * 00282 * Revision 1.8 1999/04/28 12:47:04 joergr 00283 * Introduced new scheme for the debug level variable: now each level can be 00284 * set separately (there is no "include" relationship). 00285 * 00286 * Revision 1.7 1999/02/03 16:54:27 joergr 00287 * Moved global functions maxval() and determineRepresentation() to class 00288 * DicomImageClass (as static methods). 00289 * 00290 * Revision 1.6 1999/01/20 14:46:15 joergr 00291 * Replaced invocation of getCount() by member variable Count where possible. 00292 * 00293 * Revision 1.5 1998/11/27 13:51:50 joergr 00294 * Added copyright message. 00295 * 00296 * Revision 1.4 1998/05/11 14:53:16 joergr 00297 * Added CVS/RCS header to each file. 00298 * 00299 * 00300 */