dcmimage/include/dcmtk/dcmimage/dihsvpxt.h

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  */


Generated on 6 Jan 2011 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.5.1