Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | Related Pages

dimopxt.h

00001 /*
00002  *
00003  *  Copyright (C) 1996-2004, 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:  dcmimgle
00019  *
00020  *  Author:  Joerg Riesmeier
00021  *
00022  *  Purpose: DicomMonochromePixelTemplate (Header)
00023  *
00024  *  Last Update:      $Author: joergr $
00025  *  Update Date:      $Date: 2004/02/06 11:07:50 $
00026  *  CVS/RCS Revision: $Revision: 1.25 $
00027  *  Status:           $State: Exp $
00028  *
00029  *  CVS/RCS Log at end of file
00030  *
00031  */
00032 
00033 
00034 #ifndef DIMOPXT_H
00035 #define DIMOPXT_H
00036 
00037 #include "osconfig.h"
00038 #include "ofconsol.h"
00039 #include "ofbmanip.h"
00040 #include "ofcast.h"
00041 
00042 #include "dctypes.h"
00043 #include "dcdefine.h"
00044 
00045 #include "dimopx.h"
00046 #include "dipxrept.h"
00047 #include "dimomod.h"
00048 #include "diinpx.h"
00049 #include "dimoopx.h"
00050 
00051 
00052 /*---------------------*
00053  *  class declaration  *
00054  *---------------------*/
00055 
00058 template<class T>
00059 class DiMonoPixelTemplate
00060   : public DiMonoPixel,
00061     public DiPixelRepresentationTemplate<T>
00062 {
00063 
00064  public:
00065 
00070     DiMonoPixelTemplate(const unsigned long count)
00071       : DiMonoPixel(count),
00072         Data(NULL)
00073     {
00074         MinValue[0] = 0;
00075         MinValue[1] = 0;
00076         MaxValue[0] = 0;
00077         MaxValue[1] = 0;
00078         // allocate buffer of given size
00079         Data = new T[Count];
00080     }
00081 
00087     DiMonoPixelTemplate(const DiInputPixel *pixel,
00088                         DiMonoModality *modality)
00089       : DiMonoPixel(pixel, modality),
00090         Data(NULL)
00091     {
00092         MinValue[0] = 0;
00093         MinValue[1] = 0;
00094         MaxValue[0] = 0;
00095         MaxValue[1] = 0;
00096     }
00097 
00103     DiMonoPixelTemplate(DiMonoOutputPixel *pixel,
00104                         DiMonoModality *modality)
00105       : DiMonoPixel(pixel, modality),
00106         Data(OFstatic_cast(T *, pixel->getDataPtr()))
00107     {
00108         MinValue[0] = 0;
00109         MinValue[1] = 0;
00110         MaxValue[0] = 0;
00111         MaxValue[1] = 0;
00112     }
00113 
00116     virtual ~DiMonoPixelTemplate()
00117     {
00118         delete[] Data;
00119     }
00120 
00125     inline EP_Representation getRepresentation() const
00126     {
00127         return DiPixelRepresentationTemplate<T>::getRepresentation();
00128     }
00129 
00134     inline const void *getData() const
00135     {
00136         return OFstatic_cast(const void *, Data);
00137     }
00138 
00143     inline void *getDataPtr()
00144     {
00145         return OFstatic_cast(void *, Data);
00146     }
00147 
00152     inline void *getDataArrayPtr()
00153     {
00154         return OFstatic_cast(void *, &Data);
00155     }
00156 
00164     inline int getMinMaxValues(double &min,
00165                                double &max) const
00166     {
00167         min = MinValue[0];
00168         max = MaxValue[0];
00169         return 1;
00170     }
00171 
00180     inline int getMinMaxWindow(const int idx,
00181                                double &center,
00182                                double &width)
00183     {
00184         int result = 0;
00185         if ((idx >= 0) && (idx <= 1))
00186         {
00187             if ((idx == 1) && (MinValue[1] == 0) && (MaxValue[1] == 0))
00188                 determineMinMax(0, 0, 0x2);                                     // determine on demand
00189             /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
00190                            selects the range of input values from 0 to 2^n-1."
00191             */
00192             center = (OFstatic_cast(double, MinValue[idx]) + OFstatic_cast(double, MaxValue[idx]) + 1) / 2;  // type cast to avoid overflows !
00193             width = OFstatic_cast(double, MaxValue[idx]) - OFstatic_cast(double, MinValue[idx]) + 1;
00194             result = (width > 0);                                               // check for valid value
00195         }
00196         return result;
00197     }
00198 
00213     virtual int getRoiWindow(const unsigned long left_pos,
00214                              const unsigned long top_pos,
00215                              const unsigned long width,
00216                              const unsigned long height,
00217                              const unsigned long columns,
00218                              const unsigned long rows,
00219                              const unsigned long frame,
00220                              double &voiCenter,
00221                              double &voiWidth)
00222     {
00223         int result = 0;
00224         if ((Data != NULL) && (left_pos < columns) && (top_pos < rows))
00225         {
00226             register T *p = Data + (columns * rows * frame) + (top_pos * columns) + left_pos;
00227             const unsigned long right_pos = (left_pos + width < columns) ? left_pos + width : columns;
00228             const unsigned long bottom = (top_pos + height < rows) ? top_pos + height : rows;
00229             const unsigned long skip_x = left_pos + (columns - right_pos);
00230             register unsigned long x;
00231             register unsigned long y;
00232             register T value = 0;
00233             register T min = *p;                    // get first pixel as initial value for min ...
00234             register T max = min;                   // ... and max
00235             for (y = top_pos; y < bottom; ++y)
00236             {
00237                 for (x = left_pos; x < right_pos; ++x)
00238                 {
00239                     value = *(p++);
00240                     if (value < min)
00241                         min = value;
00242                     else if (value > max)
00243                         max = value;
00244                 }
00245                 p += skip_x;                        // skip rest of current line and beginning of next
00246             }
00247             /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
00248                            selects the range of input values from 0 to 2^n-1."
00249             */
00250             voiCenter = (OFstatic_cast(double, min) + OFstatic_cast(double, max) + 1) / 2;  // type cast to avoid overflows !
00251             voiWidth = OFstatic_cast(double, max) - OFstatic_cast(double, min) + 1;
00252             result = (width > 0);                               // check for valid value
00253         }
00254         return result;
00255     }
00256 
00265     int getHistogramWindow(const double thresh,                 // could be optimized if necessary (see diinpxt.h)!
00266                            double &center,
00267                            double &width)
00268     {
00269         if ((Data != NULL) && (MinValue[0] < MaxValue[0]))
00270         {
00271             const Uint32 count = OFstatic_cast(Uint32, MaxValue[0] - MinValue[0] + 1);
00272             Uint32 *quant = new Uint32[count];
00273             if (quant != NULL)
00274             {
00275                 register unsigned long i;
00276                 OFBitmanipTemplate<Uint32>::zeroMem(quant, count);                  // initialize array
00277                 for (i = 0; i < Count; ++i)
00278                 {
00279                     if ((Data[i] >= MinValue[0]) && (Data[i] <= MaxValue[0]))       // only for stability !
00280                         ++quant[OFstatic_cast(Uint32, Data[i] - MinValue[0])];      // count values
00281 #ifdef DEBUG
00282                     else if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Warnings))
00283                     {
00284                         ofConsole.lockCerr() << "WARNING: invalid value (" << Data[i] << ") in "
00285                                              << "int DiMonoPixelTemplate<T>::getHistogramWindow() ! " << endl;
00286                         ofConsole.unlockCerr();
00287                     }
00288 #endif
00289                 }
00290                 const Uint32 threshvalue = OFstatic_cast(Uint32, thresh * OFstatic_cast(double, Count));
00291                 register Uint32 t = 0;
00292                 i = 0;
00293                 while ((i < count) && (t < threshvalue))
00294                     t += quant[i++];
00295                 const T minvalue = (i < count) ? OFstatic_cast(T, MinValue[0] + i) : 0;
00296                 t = 0;
00297                 i = count;
00298                 while ((i > 0) && (t < threshvalue))
00299                     t += quant[--i];
00300                 const T maxvalue = (i > 0) ? OFstatic_cast(T, MinValue[0] + i) : 0;
00301                 delete[] quant;
00302                 if (minvalue < maxvalue)
00303                 {
00304                     /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
00305                                    selects the range of input values from 0 to 2^n-1."
00306                     */
00307                     center = (OFstatic_cast(double, minvalue) + OFstatic_cast(double, maxvalue) + 1) / 2;
00308                     width = OFstatic_cast(double, maxvalue) - OFstatic_cast(double, minvalue) + 1;
00309                     return (width > 0);
00310                 }
00311             }
00312         }
00313         return 0;
00314     }
00315 
00316 
00317  protected:
00318 
00324     DiMonoPixelTemplate(const DiPixel *pixel,
00325                         DiMonoModality *modality)
00326       : DiMonoPixel(pixel, modality),
00327         Data(NULL)
00328     {
00329         MinValue[0] = 0;
00330         MinValue[1] = 0;
00331         MaxValue[0] = 0;
00332         MaxValue[1] = 0;
00333     }
00334 
00340     DiMonoPixelTemplate(const DiMonoPixel *pixel,
00341                         const unsigned long count)
00342       : DiMonoPixel(pixel, count),
00343         Data(NULL)
00344     {
00345         MinValue[0] = 0;
00346         MinValue[1] = 0;
00347         MaxValue[0] = 0;
00348         MaxValue[1] = 0;
00349     }
00350 
00358     void determineMinMax(T minvalue = 0,
00359                          T maxvalue = 0,
00360                          const int mode = 0x1)
00361     {
00362         if (Data != NULL)
00363         {
00364             if (mode & 0x1)
00365             {
00366                 if ((minvalue == 0) && (maxvalue == 0))
00367                 {
00368                     register T *p = Data;
00369                     register T value = *p;
00370                     register unsigned long i;
00371                     minvalue = value;
00372                     maxvalue = value;
00373                     for (i = Count; i > 1; --i)                 // could be optimized if necessary (see diinpxt.h) !
00374                     {
00375                         value = *(++p);
00376                         if (value < minvalue)
00377                             minvalue = value;
00378                         else if (value > maxvalue)
00379                             maxvalue = value;
00380                     }
00381                 }
00382                 MinValue[0] = minvalue;                         // global minimum
00383                 MaxValue[0] = maxvalue;                         // global maximum
00384                 MinValue[1] = 0;                                // invalidate value
00385                 MaxValue[1] = 0;
00386             } else {
00387                 minvalue = MinValue[0];
00388                 maxvalue = MaxValue[0];
00389             }
00390             if (mode & 0x2)
00391             {
00392                 register T *p = Data;
00393                 register T value;
00394                 register int firstmin = 1;
00395                 register int firstmax = 1;
00396                 register unsigned long i;
00397                 for (i = Count; i != 0; --i)                    // could be optimized if necessary (see diinpxt.h) !
00398                 {
00399                     value = *(p++);
00400                     if ((value > minvalue) && ((value < MinValue[1]) || firstmin))
00401                     {
00402                         MinValue[1] = value;
00403                         firstmin = 0;
00404                     }
00405                     if ((value < maxvalue) && ((value > MaxValue[1]) || firstmax))
00406                     {
00407                         MaxValue[1] = value;
00408                         firstmax = 0;
00409                     }
00410                 }
00411             }
00412         }
00413     }
00414 
00416     T *Data;
00417 
00418 
00419  private:
00420 
00422     T MinValue[2];
00424     T MaxValue[2];
00425 
00426  // --- declarations to avoid compiler warnings
00427 
00428     DiMonoPixelTemplate(const DiMonoPixelTemplate<T> &);
00429     DiMonoPixelTemplate<T> &operator=(const DiMonoPixelTemplate<T> &);
00430 };
00431 
00432 
00433 #endif
00434 
00435 
00436 /*
00437  *
00438  * CVS/RCS Log:
00439  * $Log: dimopxt.h,v $
00440  * Revision 1.25  2004/02/06 11:07:50  joergr
00441  * Distinguish more clearly between const and non-const access to pixel data.
00442  *
00443  * Revision 1.24  2004/01/05 14:52:20  joergr
00444  * Removed acknowledgements with e-mail addresses from CVS log.
00445  *
00446  * Revision 1.23  2003/12/23 15:53:22  joergr
00447  * Replaced post-increment/decrement operators by pre-increment/decrement
00448  * operators where appropriate (e.g. 'i++' by '++i').
00449  *
00450  * Revision 1.22  2003/12/09 10:02:04  joergr
00451  * Adapted type casts to new-style typecast operators defined in ofcast.h.
00452  * Removed leading underscore characters from preprocessor symbols (reserved
00453  * symbols). Updated copyright header.
00454  *
00455  * Revision 1.21  2002/12/09 13:32:54  joergr
00456  * Renamed parameter/local variable to avoid name clashes with global
00457  * declaration left and/or right (used for as iostream manipulators).
00458  *
00459  * Revision 1.20  2002/10/21 10:13:51  joergr
00460  * Corrected wrong calculation of min/max pixel value in cases where the
00461  * stored pixel data exceeds the expected size.
00462  *
00463  * Revision 1.19  2002/06/26 16:05:43  joergr
00464  * Enhanced handling of corrupted pixel data and/or length.
00465  *
00466  * Revision 1.18  2001/11/19 12:56:27  joergr
00467  * Added parameter 'frame' to setRoiWindow().
00468  *
00469  * Revision 1.17  2001/09/28 13:09:30  joergr
00470  * Added method setRoiWindow() which automatically calculates a min-max VOI
00471  * window for a specified rectangular region of the image.
00472  * Made min-max window calculation consistent with latest release of the DICOM
00473  * standard (supplement 33).
00474  *
00475  * Revision 1.16  2001/06/01 15:49:47  meichel
00476  * Updated copyright header
00477  *
00478  * Revision 1.15  2000/05/03 09:46:29  joergr
00479  * Removed most informational and some warning messages from release built
00480  * (#ifndef DEBUG).
00481  *
00482  * Revision 1.14  2000/04/28 12:32:32  joergr
00483  * DebugLevel - global for the module - now derived from OFGlobal (MF-safe).
00484  *
00485  * Revision 1.13  2000/04/27 13:08:41  joergr
00486  * Dcmimgle library code now consistently uses ofConsole for error output.
00487  *
00488  * Revision 1.12  2000/03/08 16:24:21  meichel
00489  * Updated copyright header.
00490  *
00491  * Revision 1.11  2000/03/03 14:09:14  meichel
00492  * Implemented library support for redirecting error messages into memory
00493  *   instead of printing them to stdout/stderr for GUI applications.
00494  *
00495  * Revision 1.10  1999/10/06 13:44:35  joergr
00496  * Corrected creation of PrintBitmap pixel data: VOI windows should be applied
00497  * before clipping to avoid that the region outside the image (border) is also
00498  * windowed (this requires a new method in dcmimgle to create a DicomImage
00499  * with the grayscale transformations already applied).
00500  *
00501  * Revision 1.9  1999/09/17 12:42:40  joergr
00502  * Added/changed/completed DOC++ style comments in the header files.
00503  * Enhanced efficiency of the implementation to determine min/max values of
00504  * the input pixels.
00505  *
00506  * Revision 1.8  1999/05/31 12:35:16  joergr
00507  * Corrected bug concerning the conversion of color images to grayscale.
00508  *
00509  * Revision 1.7  1999/04/30 16:10:51  meichel
00510  * Minor code purifications to keep IBM xlC quiet
00511  *
00512  * Revision 1.6  1999/04/28 14:52:12  joergr
00513  * Introduced new scheme for the debug level variable: now each level can be
00514  * set separately (there is no "include" relationship).
00515  *
00516  * Revision 1.5  1999/03/24 17:20:16  joergr
00517  * Added/Modified comments and formatting.
00518  *
00519  * Revision 1.4  1999/01/20 15:11:38  joergr
00520  * Replaced invocation of getCount() by member variable Count where possible.
00521  *
00522  * Revision 1.3  1999/01/11 09:36:13  joergr
00523  * Corrected some typos and formatting.
00524  *
00525  * Revision 1.2  1998/12/22 14:34:30  joergr
00526  * Corrected some typos and formatting.
00527  *
00528  * Revision 1.1  1998/11/27 15:36:43  joergr
00529  * Added copyright message.
00530  * Replaced delete by delete[] for array types.
00531  * Added method to give direct (non-const) access to internal data buffer.
00532  * Added support for new bit manipulation class.
00533  *
00534  * Revision 1.7  1998/07/01 08:39:25  joergr
00535  * Minor changes to avoid compiler warnings (gcc 2.8.1 with additional
00536  * options), e.g. add copy constructors.
00537  *
00538  * Revision 1.6  1998/05/11 14:53:23  joergr
00539  * Added CVS/RCS header to each file.
00540  *
00541  *
00542  */


Generated on 29 Apr 2005 for OFFIS DCMTK Version 3.5.3 by Doxygen 1.4.2