dcmimage/include/dcmtk/dcmimage/diybrpxt.h

00001 /*
00002  *
00003  *  Copyright (C) 1998-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: DicomYBRPixelTemplate (Header)
00019  *
00020  *  Last Update:      $Author: joergr $
00021  *  Update Date:      $Date: 2010-10-14 13:16:30 $
00022  *  CVS/RCS Revision: $Revision: 1.19 $
00023  *  Status:           $State: Exp $
00024  *
00025  *  CVS/RCS Log at end of file
00026  *
00027  */
00028 
00029 
00030 #ifndef DIYBRPXT_H
00031 #define DIYBRPXT_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 DiYBRPixelTemplate
00047   : public DiColorPixelTemplate<T2>
00048 {
00049 
00050  public:
00051 
00061     DiYBRPixelTemplate(const DiDocument *docu,
00062                        const DiInputPixel *pixel,
00063                        EI_Status &status,
00064                        const unsigned long planeSize,
00065                        const int bits,
00066                        const OFBool rgb)
00067       : DiColorPixelTemplate<T2>(docu, pixel, 3, status)
00068     {
00069         if ((pixel != NULL) && (this->Count > 0) && (status == EIS_Normal))
00070             convert(OFstatic_cast(const T1 *, pixel->getData()) + pixel->getPixelStart(), planeSize, bits, rgb);
00071     }
00072 
00075     virtual ~DiYBRPixelTemplate()
00076     {
00077     }
00078 
00079 
00080  private:
00081 
00089     void convert(const T1 *pixel,
00090                  const unsigned long planeSize,
00091                  const int bits,
00092                  const OFBool rgb)
00093     {
00094         if (Init(pixel))
00095         {
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 (rgb)    /* convert to RGB model */
00101             {
00102                 register T2 *r = this->Data[0];
00103                 register T2 *g = this->Data[1];
00104                 register T2 *b = this->Data[2];
00105                 const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits));
00106                 DiPixelRepresentationTemplate<T1> rep;
00107                 if (bits == 8 && !rep.isSigned())          // only for unsigned 8 bit
00108                 {
00109                     Sint16 rcr_tab[256];
00110                     Sint16 gcb_tab[256];
00111                     Sint16 gcr_tab[256];
00112                     Sint16 bcb_tab[256];
00113                     const double r_const = 0.7010 * OFstatic_cast(double, maxvalue);
00114                     const double g_const = 0.5291 * OFstatic_cast(double, maxvalue);
00115                     const double b_const = 0.8859 * OFstatic_cast(double, maxvalue);
00116                     register unsigned long l;
00117                     for (l = 0; l < 256; ++l)
00118                     {
00119                         rcr_tab[l] = OFstatic_cast(Sint16, 1.4020 * OFstatic_cast(double, l) - r_const);
00120                         gcb_tab[l] = OFstatic_cast(Sint16, 0.3441 * OFstatic_cast(double, l));
00121                         gcr_tab[l] = OFstatic_cast(Sint16, 0.7141 * OFstatic_cast(double, l) - g_const);
00122                         bcb_tab[l] = OFstatic_cast(Sint16, 1.7720 * OFstatic_cast(double, l) - b_const);
00123                     }
00124                     register Sint32 sr;
00125                     register Sint32 sg;
00126                     register Sint32 sb;
00127                     if (this->PlanarConfiguration)
00128                     {
00129 /*
00130                         register const T1 *y = pixel;
00131                         register const T1 *cb = y + this->InputCount;
00132                         register const T1 *cr = cb + this->InputCount;
00133                         for (i = count; i != 0; --i, ++y, ++cb, ++cr)
00134                         {
00135                             sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
00136                             sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
00137                             sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
00138                             *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
00139                             *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
00140                             *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
00141                         }
00142 */
00143                         register const T1 *y = pixel;
00144                         register const T1 *cb = y + planeSize;
00145                         register const T1 *cr = cb + planeSize;
00146                         register unsigned long i = count;
00147                         while (i != 0)
00148                         {
00149                             /* convert a single frame */
00150                             for (l = planeSize; (l != 0) && (i != 0); --l, --i, ++y, ++cb, ++cr)
00151                             {
00152                                 sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, *cr)]);
00153                                 sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, *cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, *cr)]);
00154                                 sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, *cb)]);
00155                                 *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
00156                                 *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
00157                                 *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
00158                             }
00159                             /* jump to next frame start (skip 2 planes) */
00160                             y += 2 * planeSize;
00161                             cb += 2 * planeSize;
00162                             cr += 2 * planeSize;
00163                         }
00164                     }
00165                     else
00166                     {
00167                         register const T1 *p = pixel;
00168                         register T1 y;
00169                         register T1 cb;
00170                         register T1 cr;
00171                         register unsigned long i;
00172                         for (i = count; i != 0; --i)
00173                         {
00174                             y  = *(p++);
00175                             cb = *(p++);
00176                             cr = *(p++);
00177                             sr = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, cr)]);
00178                             sg = OFstatic_cast(Sint32, y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, cr)]);
00179                             sb = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, cb)]);
00180                             *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
00181                             *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
00182                             *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
00183                         }
00184                     }
00185                 }
00186                 else
00187                 {
00188                     if (this->PlanarConfiguration)
00189                     {
00190 /*
00191                         register const T1 *y = pixel;
00192                         register const T1 *cb = y + this->InputCount;
00193                         register const T1 *cr = cb + this->InputCount;
00194                         for (i = count; i != 0; --i)
00195                             convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
00196                                 removeSign(*(cr++), offset), maxvalue);
00197 */
00198                         register unsigned long l;
00199                         register unsigned long i = count;
00200                         register const T1 *y = pixel;
00201                         register const T1 *cb = y + planeSize;
00202                         register const T1 *cr = cb + planeSize;
00203                         while (i != 0)
00204                         {
00205                             /* convert a single frame */
00206                             for (l = planeSize; (l != 0) && (i != 0); --l, --i)
00207                             {
00208                                 convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
00209                                     removeSign(*(cr++), offset), maxvalue);
00210                             }
00211                             /* jump to next frame start (skip 2 planes) */
00212                             y += 2 * planeSize;
00213                             cb += 2 * planeSize;
00214                             cr += 2 * planeSize;
00215                         }
00216                     }
00217                     else
00218                     {
00219                         register const T1 *p = pixel;
00220                         register T2 y;
00221                         register T2 cb;
00222                         register T2 cr;
00223                         register unsigned long i;
00224                         for (i = count; i != 0; --i)
00225                         {
00226                             y = removeSign(*(p++), offset);
00227                             cb = removeSign(*(p++), offset);
00228                             cr = removeSign(*(p++), offset);
00229                             convertValue(*(r++), *(g++), *(b++), y, cb, cr, maxvalue);
00230                         }
00231                     }
00232                 }
00233             } else {    /* retain YCbCr model */
00234                 register const T1 *p = pixel;
00235                 if (this->PlanarConfiguration)
00236                 {
00237 /*
00238                     register T2 *q;
00239                     // number of pixels to be skipped (only applicable if 'PixelData' contains more
00240                     // pixels than expected)
00241                     const unsigned long skip = (this->InputCount > this->Count) ? (this->InputCount - this->Count) : 0;
00242                     for (int j = 0; j < 3; ++j)
00243                     {
00244                         q = this->Data[j];
00245                         for (i = count; i != 0; --i)
00246                             *(q++) = removeSign(*(p++), offset);
00247                         // skip to beginning of next plane
00248                         p += skip;
00249                     }
00250 */
00251                     register unsigned long l;
00252                     register unsigned long i = 0;
00253                     while (i < count)
00254                     {
00255                         /* store current pixel index */
00256                         const unsigned long iStart = i;
00257                         for (int j = 0; j < 3; ++j)
00258                         {
00259                             /* convert a single plane */
00260                             for (l = planeSize, i = iStart; (l != 0) && (i < count); --l, ++i)
00261                                 this->Data[j][i] = removeSign(*(p++), offset);
00262                         }
00263                     }
00264                 }
00265                 else
00266                 {
00267                     register int j;
00268                     register unsigned long i;
00269                     for (i = 0; i < count; ++i)                         /* for all pixel ... */
00270                         for (j = 0; j < 3; ++j)
00271                             this->Data[j][i] = removeSign(*(p++), offset);    /* ... copy planes */
00272                 }
00273             }
00274         }
00275     }
00276 
00279     inline void convertValue(T2 &red, T2 &green, T2 &blue, const T2 y, const T2 cb, const T2 cr, const T2 maxvalue)
00280     {
00281         double dr = OFstatic_cast(double, y) + 1.4020 * OFstatic_cast(double, cr) - 0.7010 * OFstatic_cast(double, maxvalue);
00282         double dg = OFstatic_cast(double, y) - 0.3441 * OFstatic_cast(double, cb) - 0.7141 * OFstatic_cast(double, cr) + 0.5291 * OFstatic_cast(double, maxvalue);
00283         double db = OFstatic_cast(double, y) + 1.7720 * OFstatic_cast(double, cb) - 0.8859 * OFstatic_cast(double, maxvalue);
00284         red   = (dr < 0.0) ? 0 : (dr > OFstatic_cast(double, maxvalue)) ? maxvalue : OFstatic_cast(T2, dr);
00285         green = (dg < 0.0) ? 0 : (dg > OFstatic_cast(double, maxvalue)) ? maxvalue : OFstatic_cast(T2, dg);
00286         blue  = (db < 0.0) ? 0 : (db > OFstatic_cast(double, maxvalue)) ? maxvalue : OFstatic_cast(T2, db);
00287     }
00288 };
00289 
00290 
00291 #endif
00292 
00293 
00294 /*
00295  *
00296  * CVS/RCS Log:
00297  * $Log: diybrpxt.h,v $
00298  * Revision 1.19  2010-10-14 13:16:30  joergr
00299  * Updated copyright header. Added reference to COPYRIGHT file.
00300  *
00301  * Revision 1.18  2010-03-01 09:08:46  uli
00302  * Removed some unnecessary include directives in the headers.
00303  *
00304  * Revision 1.17  2005-12-08 16:02:01  meichel
00305  * Changed include path schema for all DCMTK header files
00306  *
00307  * Revision 1.16  2004/04/21 10:00:31  meichel
00308  * Minor modifications for compilation with gcc 3.4.0
00309  *
00310  * Revision 1.15  2004/02/06 11:16:35  joergr
00311  * Added typecast to array indexes to avoid warning messages on MacOS X 10.3
00312  * with gcc 3.3.
00313  *
00314  * Revision 1.14  2003/12/23 12:30:34  joergr
00315  * Adapted type casts to new-style typecast operators defined in ofcast.h.
00316  * Removed leading underscore characters from preprocessor symbols (reserved
00317  * symbols). Updated copyright header.
00318  * Replaced post-increment/decrement operators by pre-increment/decrement
00319  * operators where appropriate (e.g. 'i++' by '++i').
00320  *
00321  * Revision 1.13  2002/06/26 16:20:19  joergr
00322  * Enhanced handling of corrupted pixel data and/or length.
00323  * Corrected decoding of multi-frame, planar images.
00324  *
00325  * Revision 1.12  2001/11/09 16:47:03  joergr
00326  * Removed 'inline' specifier from certain methods.
00327  *
00328  * Revision 1.11  2001/09/28 13:55:41  joergr
00329  * Added new flag (CIF_KeepYCbCrColorModel) which avoids conversion of YCbCr
00330  * color models to RGB.
00331  *
00332  * Revision 1.10  2001/06/01 15:49:32  meichel
00333  * Updated copyright header
00334  *
00335  * Revision 1.9  2000/04/27 13:15:15  joergr
00336  * Dcmimage library code now consistently uses ofConsole for error output.
00337  *
00338  * Revision 1.8  2000/03/08 16:21:54  meichel
00339  * Updated copyright header.
00340  *
00341  * Revision 1.7  1999/09/17 14:03:46  joergr
00342  * Enhanced efficiency of some "for" loops.
00343  *
00344  * Revision 1.6  1999/04/28 12:52:04  joergr
00345  * Corrected some typos, comments and formatting.
00346  *
00347  * Revision 1.5  1999/02/03 16:55:29  joergr
00348  * Moved global functions maxval() and determineRepresentation() to class
00349  * DicomImageClass (as static methods).
00350  *
00351  * Revision 1.4  1999/01/20 14:47:20  joergr
00352  * Replaced invocation of getCount() by member variable Count where possible.
00353  *
00354  * Revision 1.3  1998/11/27 14:18:56  joergr
00355  * Added copyright message.
00356  *
00357  * Revision 1.2  1998/05/11 14:53:32  joergr
00358  * Added CVS/RCS header to each file.
00359  *
00360  *
00361  */


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