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


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