OFFIS DCMTK  Version 3.6.0
dimopxt.h
1 /*
2  *
3  * Copyright (C) 1996-2010, OFFIS e.V.
4  * All rights reserved. See COPYRIGHT file for details.
5  *
6  * This software and supporting documentation were developed by
7  *
8  * OFFIS e.V.
9  * R&D Division Health
10  * Escherweg 2
11  * D-26121 Oldenburg, Germany
12  *
13  *
14  * Module: dcmimgle
15  *
16  * Author: Joerg Riesmeier
17  *
18  * Purpose: DicomMonochromePixelTemplate (Header)
19  *
20  * Last Update: $Author: joergr $
21  * Update Date: $Date: 2010-10-14 13:16:26 $
22  * CVS/RCS Revision: $Revision: 1.34 $
23  * Status: $State: Exp $
24  *
25  * CVS/RCS Log at end of file
26  *
27  */
28 
29 
30 #ifndef DIMOPXT_H
31 #define DIMOPXT_H
32 
33 #include "dcmtk/config/osconfig.h"
34 
35 #include "dcmtk/ofstd/ofbmanip.h"
36 #include "dcmtk/ofstd/ofcast.h"
37 
38 #include "dcmtk/dcmimgle/dipxrept.h"
39 #include "dcmtk/dcmimgle/dimopx.h"
40 #include "dcmtk/dcmimgle/dimoopx.h"
41 
42 
43 /*---------------------*
44  * class declaration *
45  *---------------------*/
46 
49 template<class T>
51  : public DiMonoPixel,
53 {
54 
55  public:
56 
61  DiMonoPixelTemplate(const unsigned long count)
62  : DiMonoPixel(count),
63  Data(NULL)
64  {
65  MinValue[0] = 0;
66  MinValue[1] = 0;
67  MaxValue[0] = 0;
68  MaxValue[1] = 0;
69  // allocate buffer of given size
70  Data = new T[Count];
71  }
72 
79  DiMonoModality *modality)
80  : DiMonoPixel(pixel, modality),
81  Data(NULL)
82  {
83  MinValue[0] = 0;
84  MinValue[1] = 0;
85  MaxValue[0] = 0;
86  MaxValue[1] = 0;
87  }
88 
95  DiMonoModality *modality)
96  : DiMonoPixel(pixel, modality),
97  Data(OFstatic_cast(T *, pixel->getDataPtr()))
98  {
99  MinValue[0] = 0;
100  MinValue[1] = 0;
101  MaxValue[0] = 0;
102  MaxValue[1] = 0;
103  }
104 
108  {
109  delete[] Data;
110  }
111 
116  inline EP_Representation getRepresentation() const
117  {
119  }
120 
125  inline const void *getData() const
126  {
127  return OFstatic_cast(const void *, Data);
128  }
129 
134  inline void *getDataPtr()
135  {
136  return OFstatic_cast(void *, Data);
137  }
138 
145  inline void *getDataArrayPtr()
146  {
147  return OFstatic_cast(void *, &Data);
148  }
149 
157  inline int getMinMaxValues(double &min,
158  double &max) const
159  {
160  min = MinValue[0];
161  max = MaxValue[0];
162  return 1;
163  }
164 
173  inline int getMinMaxWindow(const int idx,
174  double &center,
175  double &width)
176  {
177  int result = 0;
178  if ((idx >= 0) && (idx <= 1))
179  {
180  if ((idx == 1) && (MinValue[1] == 0) && (MaxValue[1] == 0))
181  determineMinMax(0, 0, 0x2); // determine on demand
182  /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
183  selects the range of input values from 0 to 2^n-1."
184  */
185  center = (OFstatic_cast(double, MinValue[idx]) + OFstatic_cast(double, MaxValue[idx]) + 1) / 2; // type cast to avoid overflows !
186  width = OFstatic_cast(double, MaxValue[idx]) - OFstatic_cast(double, MinValue[idx]) + 1;
187  result = (width > 0); // check for valid value
188  }
189  return result;
190  }
191 
206  virtual int getRoiWindow(const unsigned long left_pos,
207  const unsigned long top_pos,
208  const unsigned long width,
209  const unsigned long height,
210  const unsigned long columns,
211  const unsigned long rows,
212  const unsigned long frame,
213  double &voiCenter,
214  double &voiWidth)
215  {
216  int result = 0;
217  if ((Data != NULL) && (left_pos < columns) && (top_pos < rows))
218  {
219  register T *p = Data + (columns * rows * frame) + (top_pos * columns) + left_pos;
220  const unsigned long right_pos = (left_pos + width < columns) ? left_pos + width : columns;
221  const unsigned long bottom = (top_pos + height < rows) ? top_pos + height : rows;
222  const unsigned long skip_x = left_pos + (columns - right_pos);
223  register unsigned long x;
224  register unsigned long y;
225  register T value = 0;
226  register T min = *p; // get first pixel as initial value for min ...
227  register T max = min; // ... and max
228  for (y = top_pos; y < bottom; ++y)
229  {
230  for (x = left_pos; x < right_pos; ++x)
231  {
232  value = *(p++);
233  if (value < min)
234  min = value;
235  else if (value > max)
236  max = value;
237  }
238  p += skip_x; // skip rest of current line and beginning of next
239  }
240  /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
241  selects the range of input values from 0 to 2^n-1."
242  */
243  voiCenter = (OFstatic_cast(double, min) + OFstatic_cast(double, max) + 1) / 2; // type cast to avoid overflows !
244  voiWidth = OFstatic_cast(double, max) - OFstatic_cast(double, min) + 1;
245  result = (width > 0); // check for valid value
246  }
247  return result;
248  }
249 
258  int getHistogramWindow(const double thresh, // could be optimized if necessary (see diinpxt.h)!
259  double &center,
260  double &width)
261  {
262  if ((Data != NULL) && (MinValue[0] < MaxValue[0]))
263  {
264  const Uint32 count = OFstatic_cast(Uint32, MaxValue[0] - MinValue[0] + 1);
265  Uint32 *quant = new Uint32[count];
266  if (quant != NULL)
267  {
268  register unsigned long i;
269  OFBitmanipTemplate<Uint32>::zeroMem(quant, count); // initialize array
270  for (i = 0; i < Count; ++i)
271  {
272  if ((Data[i] >= MinValue[0]) && (Data[i] <= MaxValue[0])) // only for stability !
273  ++quant[OFstatic_cast(Uint32, Data[i] - MinValue[0])]; // count values
274 #ifdef DEBUG
275  else
276  DCMIMGLE_WARN("invalid value (" << Data[i] << ") in DiMonoPixelTemplate<T>::getHistogramWindow()");
277 #endif
278  }
279  const Uint32 threshvalue = OFstatic_cast(Uint32, thresh * OFstatic_cast(double, Count));
280  register Uint32 t = 0;
281  i = 0;
282  while ((i < count) && (t < threshvalue))
283  t += quant[i++];
284  const T minvalue = (i < count) ? OFstatic_cast(T, MinValue[0] + i) : 0;
285  t = 0;
286  i = count;
287  while ((i > 0) && (t < threshvalue))
288  t += quant[--i];
289  const T maxvalue = (i > 0) ? OFstatic_cast(T, MinValue[0] + i) : 0;
290  delete[] quant;
291  if (minvalue < maxvalue)
292  {
293  /* suppl. 33: "A Window Center of 2^n-1 and a Window Width of 2^n
294  selects the range of input values from 0 to 2^n-1."
295  */
296  center = (OFstatic_cast(double, minvalue) + OFstatic_cast(double, maxvalue) + 1) / 2;
297  width = OFstatic_cast(double, maxvalue) - OFstatic_cast(double, minvalue) + 1;
298  return (width > 0);
299  }
300  }
301  }
302  return 0;
303  }
304 
305 
306  protected:
307 
314  DiMonoModality *modality)
315  : DiMonoPixel(pixel, modality),
316  Data(NULL)
317  {
318  MinValue[0] = 0;
319  MinValue[1] = 0;
320  MaxValue[0] = 0;
321  MaxValue[1] = 0;
322  }
323 
330  const unsigned long count)
331  : DiMonoPixel(pixel, count),
332  Data(NULL)
333  {
334  MinValue[0] = 0;
335  MinValue[1] = 0;
336  MaxValue[0] = 0;
337  MaxValue[1] = 0;
338  }
339 
347  void determineMinMax(T minvalue = 0,
348  T maxvalue = 0,
349  const int mode = 0x1)
350  {
351  if (Data != NULL)
352  {
353  if (mode & 0x1)
354  {
355  if ((minvalue == 0) && (maxvalue == 0))
356  {
357  DCMIMGLE_DEBUG("determining global minimum and maximum pixel values for monochrome image");
358  register T *p = Data;
359  register T value = *p;
360  register unsigned long i;
361  minvalue = value;
362  maxvalue = value;
363  for (i = Count; i > 1; --i) // could be optimized if necessary (see diinpxt.h) !
364  {
365  value = *(++p);
366  if (value < minvalue)
367  minvalue = value;
368  else if (value > maxvalue)
369  maxvalue = value;
370  }
371  }
372  MinValue[0] = minvalue; // global minimum
373  MaxValue[0] = maxvalue; // global maximum
374  MinValue[1] = 0; // invalidate value
375  MaxValue[1] = 0;
376  } else {
377  minvalue = MinValue[0];
378  maxvalue = MaxValue[0];
379  }
380  if (mode & 0x2)
381  {
382  DCMIMGLE_DEBUG("determining next minimum and maximum pixel values for monochrome image");
383  register T *p = Data;
384  register T value;
385  register int firstmin = 1;
386  register int firstmax = 1;
387  register unsigned long i;
388  for (i = Count; i != 0; --i) // could be optimized if necessary (see diinpxt.h) !
389  {
390  value = *(p++);
391  if ((value > minvalue) && ((value < MinValue[1]) || firstmin))
392  {
393  MinValue[1] = value;
394  firstmin = 0;
395  }
396  if ((value < maxvalue) && ((value > MaxValue[1]) || firstmax))
397  {
398  MaxValue[1] = value;
399  firstmax = 0;
400  }
401  }
402  }
403  }
404  }
405 
407  T *Data;
408 
409 
410  private:
411 
413  T MinValue[2];
415  T MaxValue[2];
416 
417  // --- declarations to avoid compiler warnings
418 
421 };
422 
423 
424 #endif
425 
426 
427 /*
428  *
429  * CVS/RCS Log:
430  * $Log: dimopxt.h,v $
431  * Revision 1.34 2010-10-14 13:16:26 joergr
432  * Updated copyright header. Added reference to COPYRIGHT file.
433  *
434  * Revision 1.33 2010-03-01 09:08:47 uli
435  * Removed some unnecessary include directives in the headers.
436  *
437  * Revision 1.32 2009-11-25 16:09:22 joergr
438  * Removed inclusion of header file "ofconsol.h". Added more logging messages.
439  *
440  * Revision 1.31 2009-10-28 14:38:17 joergr
441  * Fixed minor issues in log output.
442  *
443  * Revision 1.30 2009-10-28 09:53:40 uli
444  * Switched to logging mechanism provided by the "new" oflog module.
445  *
446  * Revision 1.29 2009-09-28 13:27:30 joergr
447  * Moved general purpose definition file from module dcmdata to ofstd, and
448  * added new defines in order to make the usage easier.
449  *
450  * Revision 1.28 2006/08/15 16:30:11 meichel
451  * Updated the code in module dcmimgle to correctly compile when
452  * all standard C++ classes remain in namespace std.
453  *
454  * Revision 1.27 2005/12/08 16:47:56 meichel
455  * Changed include path schema for all DCMTK header files
456  *
457  * Revision 1.26 2004/10/19 12:58:24 joergr
458  * Enhanced API documentation.
459  *
460  * Revision 1.25 2004/02/06 11:07:50 joergr
461  * Distinguish more clearly between const and non-const access to pixel data.
462  *
463  * Revision 1.24 2004/01/05 14:52:20 joergr
464  * Removed acknowledgements with e-mail addresses from CVS log.
465  *
466  * Revision 1.23 2003/12/23 15:53:22 joergr
467  * Replaced post-increment/decrement operators by pre-increment/decrement
468  * operators where appropriate (e.g. 'i++' by '++i').
469  *
470  * Revision 1.22 2003/12/09 10:02:04 joergr
471  * Adapted type casts to new-style typecast operators defined in ofcast.h.
472  * Removed leading underscore characters from preprocessor symbols (reserved
473  * symbols). Updated copyright header.
474  *
475  * Revision 1.21 2002/12/09 13:32:54 joergr
476  * Renamed parameter/local variable to avoid name clashes with global
477  * declaration left and/or right (used for as iostream manipulators).
478  *
479  * Revision 1.20 2002/10/21 10:13:51 joergr
480  * Corrected wrong calculation of min/max pixel value in cases where the
481  * stored pixel data exceeds the expected size.
482  *
483  * Revision 1.19 2002/06/26 16:05:43 joergr
484  * Enhanced handling of corrupted pixel data and/or length.
485  *
486  * Revision 1.18 2001/11/19 12:56:27 joergr
487  * Added parameter 'frame' to setRoiWindow().
488  *
489  * Revision 1.17 2001/09/28 13:09:30 joergr
490  * Added method setRoiWindow() which automatically calculates a min-max VOI
491  * window for a specified rectangular region of the image.
492  * Made min-max window calculation consistent with latest release of the DICOM
493  * standard (supplement 33).
494  *
495  * Revision 1.16 2001/06/01 15:49:47 meichel
496  * Updated copyright header
497  *
498  * Revision 1.15 2000/05/03 09:46:29 joergr
499  * Removed most informational and some warning messages from release built
500  * (#ifndef DEBUG).
501  *
502  * Revision 1.14 2000/04/28 12:32:32 joergr
503  * DebugLevel - global for the module - now derived from OFGlobal (MF-safe).
504  *
505  * Revision 1.13 2000/04/27 13:08:41 joergr
506  * Dcmimgle library code now consistently uses ofConsole for error output.
507  *
508  * Revision 1.12 2000/03/08 16:24:21 meichel
509  * Updated copyright header.
510  *
511  * Revision 1.11 2000/03/03 14:09:14 meichel
512  * Implemented library support for redirecting error messages into memory
513  * instead of printing them to stdout/stderr for GUI applications.
514  *
515  * Revision 1.10 1999/10/06 13:44:35 joergr
516  * Corrected creation of PrintBitmap pixel data: VOI windows should be applied
517  * before clipping to avoid that the region outside the image (border) is also
518  * windowed (this requires a new method in dcmimgle to create a DicomImage
519  * with the grayscale transformations already applied).
520  *
521  * Revision 1.9 1999/09/17 12:42:40 joergr
522  * Added/changed/completed DOC++ style comments in the header files.
523  * Enhanced efficiency of the implementation to determine min/max values of
524  * the input pixels.
525  *
526  * Revision 1.8 1999/05/31 12:35:16 joergr
527  * Corrected bug concerning the conversion of color images to grayscale.
528  *
529  * Revision 1.7 1999/04/30 16:10:51 meichel
530  * Minor code purifications to keep IBM xlC quiet
531  *
532  * Revision 1.6 1999/04/28 14:52:12 joergr
533  * Introduced new scheme for the debug level variable: now each level can be
534  * set separately (there is no "include" relationship).
535  *
536  * Revision 1.5 1999/03/24 17:20:16 joergr
537  * Added/Modified comments and formatting.
538  *
539  * Revision 1.4 1999/01/20 15:11:38 joergr
540  * Replaced invocation of getCount() by member variable Count where possible.
541  *
542  * Revision 1.3 1999/01/11 09:36:13 joergr
543  * Corrected some typos and formatting.
544  *
545  * Revision 1.2 1998/12/22 14:34:30 joergr
546  * Corrected some typos and formatting.
547  *
548  * Revision 1.1 1998/11/27 15:36:43 joergr
549  * Added copyright message.
550  * Replaced delete by delete[] for array types.
551  * Added method to give direct (non-const) access to internal data buffer.
552  * Added support for new bit manipulation class.
553  *
554  * Revision 1.7 1998/07/01 08:39:25 joergr
555  * Minor changes to avoid compiler warnings (gcc 2.8.1 with additional
556  * options), e.g. add copy constructors.
557  *
558  * Revision 1.6 1998/05/11 14:53:23 joergr
559  * Added CVS/RCS header to each file.
560  *
561  *
562  */


Generated on Thu Dec 20 2012 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.8.2