dihsvpxt.h

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


Generated on 20 Dec 2005 for OFFIS DCMTK Version 3.5.4 by Doxygen 1.4.5