dcmimgle/include/dcmtk/dcmimgle/dimopxt.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:  dcmimgle
00015  *
00016  *  Author:  Joerg Riesmeier
00017  *
00018  *  Purpose: DicomMonochromePixelTemplate (Header)
00019  *
00020  *  Last Update:      $Author: joergr $
00021  *  Update Date:      $Date: 2010-10-14 13:16:26 $
00022  *  CVS/RCS Revision: $Revision: 1.34 $
00023  *  Status:           $State: Exp $
00024  *
00025  *  CVS/RCS Log at end of file
00026  *
00027  */
00028 
00029 
00030 #ifndef DIMOPXT_H
00031 #define DIMOPXT_H
00032 
00033 #include "dcmtk/config/osconfig.h"
00034 
00035 #include "dcmtk/ofstd/ofbmanip.h"
00036 #include "dcmtk/ofstd/ofcast.h"
00037 
00038 #include "dcmtk/dcmimgle/dipxrept.h"
00039 #include "dcmtk/dcmimgle/dimopx.h"
00040 #include "dcmtk/dcmimgle/dimoopx.h"
00041 
00042 
00043 /*---------------------*
00044  *  class declaration  *
00045  *---------------------*/
00046 
00049 template<class T>
00050 class DiMonoPixelTemplate
00051   : public DiMonoPixel,
00052     public DiPixelRepresentationTemplate<T>
00053 {
00054 
00055  public:
00056 
00061     DiMonoPixelTemplate(const unsigned long count)
00062       : DiMonoPixel(count),
00063         Data(NULL)
00064     {
00065         MinValue[0] = 0;
00066         MinValue[1] = 0;
00067         MaxValue[0] = 0;
00068         MaxValue[1] = 0;
00069         // allocate buffer of given size
00070         Data = new T[Count];
00071     }
00072 
00078     DiMonoPixelTemplate(const DiInputPixel *pixel,
00079                         DiMonoModality *modality)
00080       : DiMonoPixel(pixel, modality),
00081         Data(NULL)
00082     {
00083         MinValue[0] = 0;
00084         MinValue[1] = 0;
00085         MaxValue[0] = 0;
00086         MaxValue[1] = 0;
00087     }
00088 
00094     DiMonoPixelTemplate(DiMonoOutputPixel *pixel,
00095                         DiMonoModality *modality)
00096       : DiMonoPixel(pixel, modality),
00097         Data(OFstatic_cast(T *, pixel->getDataPtr()))
00098     {
00099         MinValue[0] = 0;
00100         MinValue[1] = 0;
00101         MaxValue[0] = 0;
00102         MaxValue[1] = 0;
00103     }
00104 
00107     virtual ~DiMonoPixelTemplate()
00108     {
00109         delete[] Data;
00110     }
00111 
00116     inline EP_Representation getRepresentation() const
00117     {
00118         return DiPixelRepresentationTemplate<T>::getRepresentation();
00119     }
00120 
00125     inline const void *getData() const
00126     {
00127         return OFstatic_cast(const void *, Data);
00128     }
00129 
00134     inline void *getDataPtr()
00135     {
00136         return OFstatic_cast(void *, Data);
00137     }
00138 
00145     inline void *getDataArrayPtr()
00146     {
00147         return OFstatic_cast(void *, &Data);
00148     }
00149 
00157     inline int getMinMaxValues(double &min,
00158                                double &max) const
00159     {
00160         min = MinValue[0];
00161         max = MaxValue[0];
00162         return 1;
00163     }
00164 
00173     inline int getMinMaxWindow(const int idx,
00174                                double &center,
00175                                double &width)
00176     {
00177         int result = 0;
00178         if ((idx >= 0) && (idx <= 1))
00179         {
00180             if ((idx == 1) && (MinValue[1] == 0) && (MaxValue[1] == 0))
00181                 determineMinMax(0, 0, 0x2);                                     // determine on demand
00182             /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
00183                            selects the range of input values from 0 to 2^n-1."
00184             */
00185             center = (OFstatic_cast(double, MinValue[idx]) + OFstatic_cast(double, MaxValue[idx]) + 1) / 2;  // type cast to avoid overflows !
00186             width = OFstatic_cast(double, MaxValue[idx]) - OFstatic_cast(double, MinValue[idx]) + 1;
00187             result = (width > 0);                                               // check for valid value
00188         }
00189         return result;
00190     }
00191 
00206     virtual int getRoiWindow(const unsigned long left_pos,
00207                              const unsigned long top_pos,
00208                              const unsigned long width,
00209                              const unsigned long height,
00210                              const unsigned long columns,
00211                              const unsigned long rows,
00212                              const unsigned long frame,
00213                              double &voiCenter,
00214                              double &voiWidth)
00215     {
00216         int result = 0;
00217         if ((Data != NULL) && (left_pos < columns) && (top_pos < rows))
00218         {
00219             register T *p = Data + (columns * rows * frame) + (top_pos * columns) + left_pos;
00220             const unsigned long right_pos = (left_pos + width < columns) ? left_pos + width : columns;
00221             const unsigned long bottom = (top_pos + height < rows) ? top_pos + height : rows;
00222             const unsigned long skip_x = left_pos + (columns - right_pos);
00223             register unsigned long x;
00224             register unsigned long y;
00225             register T value = 0;
00226             register T min = *p;                    // get first pixel as initial value for min ...
00227             register T max = min;                   // ... and max
00228             for (y = top_pos; y < bottom; ++y)
00229             {
00230                 for (x = left_pos; x < right_pos; ++x)
00231                 {
00232                     value = *(p++);
00233                     if (value < min)
00234                         min = value;
00235                     else if (value > max)
00236                         max = value;
00237                 }
00238                 p += skip_x;                        // skip rest of current line and beginning of next
00239             }
00240             /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
00241                            selects the range of input values from 0 to 2^n-1."
00242             */
00243             voiCenter = (OFstatic_cast(double, min) + OFstatic_cast(double, max) + 1) / 2;  // type cast to avoid overflows !
00244             voiWidth = OFstatic_cast(double, max) - OFstatic_cast(double, min) + 1;
00245             result = (width > 0);                               // check for valid value
00246         }
00247         return result;
00248     }
00249 
00258     int getHistogramWindow(const double thresh,                 // could be optimized if necessary (see diinpxt.h)!
00259                            double &center,
00260                            double &width)
00261     {
00262         if ((Data != NULL) && (MinValue[0] < MaxValue[0]))
00263         {
00264             const Uint32 count = OFstatic_cast(Uint32, MaxValue[0] - MinValue[0] + 1);
00265             Uint32 *quant = new Uint32[count];
00266             if (quant != NULL)
00267             {
00268                 register unsigned long i;
00269                 OFBitmanipTemplate<Uint32>::zeroMem(quant, count);                  // initialize array
00270                 for (i = 0; i < Count; ++i)
00271                 {
00272                     if ((Data[i] >= MinValue[0]) && (Data[i] <= MaxValue[0]))       // only for stability !
00273                         ++quant[OFstatic_cast(Uint32, Data[i] - MinValue[0])];      // count values
00274 #ifdef DEBUG
00275                     else
00276                         DCMIMGLE_WARN("invalid value (" << Data[i] << ") in DiMonoPixelTemplate<T>::getHistogramWindow()");
00277 #endif
00278                 }
00279                 const Uint32 threshvalue = OFstatic_cast(Uint32, thresh * OFstatic_cast(double, Count));
00280                 register Uint32 t = 0;
00281                 i = 0;
00282                 while ((i < count) && (t < threshvalue))
00283                     t += quant[i++];
00284                 const T minvalue = (i < count) ? OFstatic_cast(T, MinValue[0] + i) : 0;
00285                 t = 0;
00286                 i = count;
00287                 while ((i > 0) && (t < threshvalue))
00288                     t += quant[--i];
00289                 const T maxvalue = (i > 0) ? OFstatic_cast(T, MinValue[0] + i) : 0;
00290                 delete[] quant;
00291                 if (minvalue < maxvalue)
00292                 {
00293                     /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
00294                                    selects the range of input values from 0 to 2^n-1."
00295                     */
00296                     center = (OFstatic_cast(double, minvalue) + OFstatic_cast(double, maxvalue) + 1) / 2;
00297                     width = OFstatic_cast(double, maxvalue) - OFstatic_cast(double, minvalue) + 1;
00298                     return (width > 0);
00299                 }
00300             }
00301         }
00302         return 0;
00303     }
00304 
00305 
00306  protected:
00307 
00313     DiMonoPixelTemplate(const DiPixel *pixel,
00314                         DiMonoModality *modality)
00315       : DiMonoPixel(pixel, modality),
00316         Data(NULL)
00317     {
00318         MinValue[0] = 0;
00319         MinValue[1] = 0;
00320         MaxValue[0] = 0;
00321         MaxValue[1] = 0;
00322     }
00323 
00329     DiMonoPixelTemplate(const DiMonoPixel *pixel,
00330                         const unsigned long count)
00331       : DiMonoPixel(pixel, count),
00332         Data(NULL)
00333     {
00334         MinValue[0] = 0;
00335         MinValue[1] = 0;
00336         MaxValue[0] = 0;
00337         MaxValue[1] = 0;
00338     }
00339 
00347     void determineMinMax(T minvalue = 0,
00348                          T maxvalue = 0,
00349                          const int mode = 0x1)
00350     {
00351         if (Data != NULL)
00352         {
00353             if (mode & 0x1)
00354             {
00355                 if ((minvalue == 0) && (maxvalue == 0))
00356                 {
00357                     DCMIMGLE_DEBUG("determining global minimum and maximum pixel values for monochrome image");
00358                     register T *p = Data;
00359                     register T value = *p;
00360                     register unsigned long i;
00361                     minvalue = value;
00362                     maxvalue = value;
00363                     for (i = Count; i > 1; --i)                 // could be optimized if necessary (see diinpxt.h) !
00364                     {
00365                         value = *(++p);
00366                         if (value < minvalue)
00367                             minvalue = value;
00368                         else if (value > maxvalue)
00369                             maxvalue = value;
00370                     }
00371                 }
00372                 MinValue[0] = minvalue;                         // global minimum
00373                 MaxValue[0] = maxvalue;                         // global maximum
00374                 MinValue[1] = 0;                                // invalidate value
00375                 MaxValue[1] = 0;
00376             } else {
00377                 minvalue = MinValue[0];
00378                 maxvalue = MaxValue[0];
00379             }
00380             if (mode & 0x2)
00381             {
00382                 DCMIMGLE_DEBUG("determining next minimum and maximum pixel values for monochrome image");
00383                 register T *p = Data;
00384                 register T value;
00385                 register int firstmin = 1;
00386                 register int firstmax = 1;
00387                 register unsigned long i;
00388                 for (i = Count; i != 0; --i)                    // could be optimized if necessary (see diinpxt.h) !
00389                 {
00390                     value = *(p++);
00391                     if ((value > minvalue) && ((value < MinValue[1]) || firstmin))
00392                     {
00393                         MinValue[1] = value;
00394                         firstmin = 0;
00395                     }
00396                     if ((value < maxvalue) && ((value > MaxValue[1]) || firstmax))
00397                     {
00398                         MaxValue[1] = value;
00399                         firstmax = 0;
00400                     }
00401                 }
00402             }
00403         }
00404     }
00405 
00407     T *Data;
00408 
00409 
00410  private:
00411 
00413     T MinValue[2];
00415     T MaxValue[2];
00416 
00417  // --- declarations to avoid compiler warnings
00418 
00419     DiMonoPixelTemplate(const DiMonoPixelTemplate<T> &);
00420     DiMonoPixelTemplate<T> &operator=(const DiMonoPixelTemplate<T> &);
00421 };
00422 
00423 
00424 #endif
00425 
00426 
00427 /*
00428  *
00429  * CVS/RCS Log:
00430  * $Log: dimopxt.h,v $
00431  * Revision 1.34  2010-10-14 13:16:26  joergr
00432  * Updated copyright header. Added reference to COPYRIGHT file.
00433  *
00434  * Revision 1.33  2010-03-01 09:08:47  uli
00435  * Removed some unnecessary include directives in the headers.
00436  *
00437  * Revision 1.32  2009-11-25 16:09:22  joergr
00438  * Removed inclusion of header file "ofconsol.h". Added more logging messages.
00439  *
00440  * Revision 1.31  2009-10-28 14:38:17  joergr
00441  * Fixed minor issues in log output.
00442  *
00443  * Revision 1.30  2009-10-28 09:53:40  uli
00444  * Switched to logging mechanism provided by the "new" oflog module.
00445  *
00446  * Revision 1.29  2009-09-28 13:27:30  joergr
00447  * Moved general purpose definition file from module dcmdata to ofstd, and
00448  * added new defines in order to make the usage easier.
00449  *
00450  * Revision 1.28  2006/08/15 16:30:11  meichel
00451  * Updated the code in module dcmimgle to correctly compile when
00452  *   all standard C++ classes remain in namespace std.
00453  *
00454  * Revision 1.27  2005/12/08 16:47:56  meichel
00455  * Changed include path schema for all DCMTK header files
00456  *
00457  * Revision 1.26  2004/10/19 12:58:24  joergr
00458  * Enhanced API documentation.
00459  *
00460  * Revision 1.25  2004/02/06 11:07:50  joergr
00461  * Distinguish more clearly between const and non-const access to pixel data.
00462  *
00463  * Revision 1.24  2004/01/05 14:52:20  joergr
00464  * Removed acknowledgements with e-mail addresses from CVS log.
00465  *
00466  * Revision 1.23  2003/12/23 15:53:22  joergr
00467  * Replaced post-increment/decrement operators by pre-increment/decrement
00468  * operators where appropriate (e.g. 'i++' by '++i').
00469  *
00470  * Revision 1.22  2003/12/09 10:02:04  joergr
00471  * Adapted type casts to new-style typecast operators defined in ofcast.h.
00472  * Removed leading underscore characters from preprocessor symbols (reserved
00473  * symbols). Updated copyright header.
00474  *
00475  * Revision 1.21  2002/12/09 13:32:54  joergr
00476  * Renamed parameter/local variable to avoid name clashes with global
00477  * declaration left and/or right (used for as iostream manipulators).
00478  *
00479  * Revision 1.20  2002/10/21 10:13:51  joergr
00480  * Corrected wrong calculation of min/max pixel value in cases where the
00481  * stored pixel data exceeds the expected size.
00482  *
00483  * Revision 1.19  2002/06/26 16:05:43  joergr
00484  * Enhanced handling of corrupted pixel data and/or length.
00485  *
00486  * Revision 1.18  2001/11/19 12:56:27  joergr
00487  * Added parameter 'frame' to setRoiWindow().
00488  *
00489  * Revision 1.17  2001/09/28 13:09:30  joergr
00490  * Added method setRoiWindow() which automatically calculates a min-max VOI
00491  * window for a specified rectangular region of the image.
00492  * Made min-max window calculation consistent with latest release of the DICOM
00493  * standard (supplement 33).
00494  *
00495  * Revision 1.16  2001/06/01 15:49:47  meichel
00496  * Updated copyright header
00497  *
00498  * Revision 1.15  2000/05/03 09:46:29  joergr
00499  * Removed most informational and some warning messages from release built
00500  * (#ifndef DEBUG).
00501  *
00502  * Revision 1.14  2000/04/28 12:32:32  joergr
00503  * DebugLevel - global for the module - now derived from OFGlobal (MF-safe).
00504  *
00505  * Revision 1.13  2000/04/27 13:08:41  joergr
00506  * Dcmimgle library code now consistently uses ofConsole for error output.
00507  *
00508  * Revision 1.12  2000/03/08 16:24:21  meichel
00509  * Updated copyright header.
00510  *
00511  * Revision 1.11  2000/03/03 14:09:14  meichel
00512  * Implemented library support for redirecting error messages into memory
00513  *   instead of printing them to stdout/stderr for GUI applications.
00514  *
00515  * Revision 1.10  1999/10/06 13:44:35  joergr
00516  * Corrected creation of PrintBitmap pixel data: VOI windows should be applied
00517  * before clipping to avoid that the region outside the image (border) is also
00518  * windowed (this requires a new method in dcmimgle to create a DicomImage
00519  * with the grayscale transformations already applied).
00520  *
00521  * Revision 1.9  1999/09/17 12:42:40  joergr
00522  * Added/changed/completed DOC++ style comments in the header files.
00523  * Enhanced efficiency of the implementation to determine min/max values of
00524  * the input pixels.
00525  *
00526  * Revision 1.8  1999/05/31 12:35:16  joergr
00527  * Corrected bug concerning the conversion of color images to grayscale.
00528  *
00529  * Revision 1.7  1999/04/30 16:10:51  meichel
00530  * Minor code purifications to keep IBM xlC quiet
00531  *
00532  * Revision 1.6  1999/04/28 14:52:12  joergr
00533  * Introduced new scheme for the debug level variable: now each level can be
00534  * set separately (there is no "include" relationship).
00535  *
00536  * Revision 1.5  1999/03/24 17:20:16  joergr
00537  * Added/Modified comments and formatting.
00538  *
00539  * Revision 1.4  1999/01/20 15:11:38  joergr
00540  * Replaced invocation of getCount() by member variable Count where possible.
00541  *
00542  * Revision 1.3  1999/01/11 09:36:13  joergr
00543  * Corrected some typos and formatting.
00544  *
00545  * Revision 1.2  1998/12/22 14:34:30  joergr
00546  * Corrected some typos and formatting.
00547  *
00548  * Revision 1.1  1998/11/27 15:36:43  joergr
00549  * Added copyright message.
00550  * Replaced delete by delete[] for array types.
00551  * Added method to give direct (non-const) access to internal data buffer.
00552  * Added support for new bit manipulation class.
00553  *
00554  * Revision 1.7  1998/07/01 08:39:25  joergr
00555  * Minor changes to avoid compiler warnings (gcc 2.8.1 with additional
00556  * options), e.g. add copy constructors.
00557  *
00558  * Revision 1.6  1998/05/11 14:53:23  joergr
00559  * Added CVS/RCS header to each file.
00560  *
00561  *
00562  */


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