OFFIS DCMTK  Version 3.6.0
diinpxt.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: DicomInputPixelTemplate (Header)
19  *
20  * Last Update: $Author: joergr $
21  * Update Date: $Date: 2010-10-14 13:16:26 $
22  * CVS/RCS Revision: $Revision: 1.42 $
23  * Status: $State: Exp $
24  *
25  * CVS/RCS Log at end of file
26  *
27  */
28 
29 
30 #ifndef DIINPXT_H
31 #define DIINPXT_H
32 
33 #include "dcmtk/config/osconfig.h"
34 #include "dcmtk/dcmdata/dcpixel.h"
35 
36 #include "dcmtk/ofstd/ofbmanip.h"
37 #include "dcmtk/ofstd/ofcast.h"
38 
39 #include "dcmtk/dcmimgle/diinpx.h"
40 #include "dcmtk/dcmimgle/didocu.h"
41 #include "dcmtk/dcmimgle/dipxrept.h"
42 
43 
44 /*--------------------*
45  * helper functions *
46  *--------------------*/
47 
48 static inline Uint8 expandSign(const Uint8 Value,
49  const Uint8,
50  const Uint8)
51 {
52  return Value;
53 }
54 
55 
56 static inline Uint16 expandSign(const Uint16 Value,
57  const Uint16,
58  const Uint16)
59 {
60  return Value;
61 }
62 
63 
64 static inline Uint32 expandSign(const Uint32 Value,
65  const Uint32,
66  const Uint32)
67 {
68  return Value;
69 }
70 
71 
72 static inline Sint8 expandSign(const Sint8 Value,
73  const Sint8 SignBit,
74  const Sint8 SignMask)
75 {
76  return (Value & SignBit) ? (Value | SignMask) : Value;
77 }
78 
79 
80 static inline Sint16 expandSign(const Sint16 Value,
81  const Sint16 SignBit,
82  const Sint16 SignMask)
83 {
84  return (Value & SignBit) ? (Value | SignMask) : Value;
85 }
86 
87 
88 static inline Sint32 expandSign(const Sint32 Value,
89  const Sint32 SignBit,
90  const Sint32 SignMask)
91 {
92  return (Value & SignBit) ? (Value | SignMask) : Value;
93 }
94 
95 
96 static Uint32 getPixelData(DcmPixelData *PixelData,
97  Uint8 *&pixel)
98 {
99  PixelData->getUint8Array(pixel);
100  return PixelData->getLength();
101 }
102 
103 
104 static Uint32 getPixelData(DcmPixelData *PixelData,
105  Uint16 *&pixel)
106 {
107  PixelData->getUint16Array(pixel);
108  return PixelData->getLength();
109 }
110 
111 
112 /*---------------------*
113  * class declaration *
114  *---------------------*/
115 
118 template<class T1, class T2>
120  : public DiInputPixel,
122 {
123 
124  public:
125 
139  const Uint16 alloc,
140  const Uint16 stored,
141  const Uint16 high,
142  const unsigned long first,
143  const unsigned long number,
144  const unsigned long fsize,
145  DcmFileCache *fileCache,
146  Uint32 &fragment)
147  : DiInputPixel(stored, first, number, fsize),
148  Data(NULL)
149  {
150  MinValue[0] = 0;
151  MinValue[1] = 0;
152  MaxValue[0] = 0;
153  MaxValue[1] = 0;
154  if (this->isSigned())
155  {
156  AbsMinimum = -OFstatic_cast(double, DicomImageClass::maxval(Bits - 1, 0));
157  AbsMaximum = OFstatic_cast(double, DicomImageClass::maxval(Bits - 1));
158  } else {
159  AbsMinimum = 0;
160  AbsMaximum = OFstatic_cast(double, DicomImageClass::maxval(Bits));
161  }
162  if ((document != NULL) && (document->getPixelData() != NULL))
163  convert(document, alloc, stored, high, fileCache, fragment);
164  if ((PixelCount == 0) || (PixelStart + PixelCount > Count)) // check for corrupt pixel length
165  {
167  DCMIMGLE_DEBUG("setting number of pixels to be processed (PixelCount) to: " << PixelCount);
168  }
169  }
170 
174  {
175 #if defined(HAVE_STD__NOTHROW) && defined(HAVE_NOTHROW_DELETE)
176  /* use a non-throwing delete (if available) */
177  operator delete[] (Data, std::nothrow);
178 #else
179  delete[] Data;
180 #endif
181  }
182 
188  {
189  if (Data != NULL)
190  {
191  DCMIMGLE_DEBUG("determining minimum and maximum pixel values for input data");
192  register T2 *p = Data;
193  register unsigned long i;
194  const unsigned long ocnt = OFstatic_cast(unsigned long, getAbsMaxRange());
195  Uint8 *lut = NULL;
196  if ((sizeof(T2) <= 2) && (Count > 3 * ocnt)) // optimization criteria
197  {
198  lut = new Uint8[ocnt];
199  if (lut != NULL)
200  {
201  DCMIMGLE_DEBUG("using optimized routine with additional LUT");
203  register Uint8 *q = lut - OFstatic_cast(T2, getAbsMinimum());
204  for (i = Count; i != 0; --i) // fill lookup table
205  *(q + *(p++)) = 1;
206  q = lut;
207  for (i = 0; i < ocnt; ++i) // search for minimum
208  {
209  if (*(q++) != 0)
210  {
211  MinValue[0] = OFstatic_cast(T2, OFstatic_cast(double, i) + getAbsMinimum());
212  break;
213  }
214  }
215  q = lut + ocnt;
216  for (i = ocnt; i != 0; --i) // search for maximum
217  {
218  if (*(--q) != 0)
219  {
220  MaxValue[0] = OFstatic_cast(T2, OFstatic_cast(double, i - 1) + getAbsMinimum());
221  break;
222  }
223  }
224  if (Count >= PixelCount) // use global min/max value
225  {
226  MinValue[1] = MinValue[0];
227  MaxValue[1] = MaxValue[0];
228  } else { // calculate min/max for selected range
230  p = Data + PixelStart;
231  q = lut - OFstatic_cast(T2, getAbsMinimum());
232  for (i = PixelCount; i != 0; --i) // fill lookup table
233  *(q + *(p++)) = 1;
234  q = lut;
235  for (i = 0; i < ocnt; ++i) // search for minimum
236  {
237  if (*(q++) != 0)
238  {
239  MinValue[1] = OFstatic_cast(T2, OFstatic_cast(double, i) + getAbsMinimum());
240  break;
241  }
242  }
243  q = lut + ocnt;
244  for (i = ocnt; i != 0; --i) // search for maximum
245  {
246  if (*(--q) != 0)
247  {
248  MaxValue[1] = OFstatic_cast(T2, OFstatic_cast(double, i - 1) + getAbsMinimum());
249  break;
250  }
251  }
252  }
253  }
254  }
255  if (lut == NULL) // use conventional method
256  {
257  register T2 value = *p;
258  MinValue[0] = value;
259  MaxValue[0] = value;
260  for (i = Count; i > 1; --i)
261  {
262  value = *(++p);
263  if (value < MinValue[0])
264  MinValue[0] = value;
265  else if (value > MaxValue[0])
266  MaxValue[0] = value;
267  }
268  if (Count <= PixelCount) // use global min/max value
269  {
270  MinValue[1] = MinValue[0];
271  MaxValue[1] = MaxValue[0];
272  } else { // calculate min/max for selected range
273  p = Data + PixelStart;
274  value = *p;
275  MinValue[1] = value;
276  MaxValue[1] = value;
277  for (i = PixelCount; i > 1; --i)
278  {
279  value = *(++p);
280  if (value < MinValue[1])
281  MinValue[1] = value;
282  else if (value > MaxValue[1])
283  MaxValue[1] = value;
284  }
285  }
286  }
287  delete[] lut;
288  return 1;
289  }
290  return 0;
291  }
292 
297  inline EP_Representation getRepresentation() const
298  {
300  }
301 
306  inline const void *getData() const
307  {
308  return OFstatic_cast(const void *, Data);
309  }
310 
315  virtual void *getDataPtr()
316  {
317  return OFstatic_cast(void *, Data);
318  }
319 
322  inline void removeDataReference()
323  {
324  Data = NULL;
325  }
326 
334  inline double getMinValue(const int idx) const
335  {
336  return (idx == 0) ? OFstatic_cast(double, MinValue[0]) : OFstatic_cast(double, MinValue[1]);
337  }
338 
346  inline double getMaxValue(const int idx) const
347  {
348  return (idx == 0) ? OFstatic_cast(double, MaxValue[0]) : OFstatic_cast(double, MaxValue[1]);
349  }
350 
351 
352  private:
353 
363  void convert(const DiDocument *document,
364  const Uint16 bitsAllocated,
365  const Uint16 bitsStored,
366  const Uint16 highBit,
367  DcmFileCache *fileCache,
368  Uint32 &fragment)
369  {
370  T1 *pixel = NULL;
371  OFBool deletePixel = OFFalse;
372  Uint32 lengthBytes = 0;
373  DcmPixelData *pixelData = document->getPixelData();
374  const Uint16 bitsof_T1 = bitsof(T1);
375  const Uint16 bitsof_T2 = bitsof(T2);
376  const OFBool uncompressed = pixelData->canWriteXfer(EXS_LittleEndianExplicit, EXS_Unknown);
377  /* check whether to use partial read */
378  if ((document->getFlags() & CIF_UsePartialAccessToPixelData) && (PixelCount > 0) &&
379  (!uncompressed || !pixelData->valueLoaded()) && (bitsAllocated % 8 == 0))
380  {
381  /* Bits Allocated is always a multiple of 8 (see above), same for bits of T1 */
382  const Uint32 byteFactor = bitsAllocated / 8;
383  const Uint32 bytes_T1 = bitsof_T1 / 8;
384  const Uint32 count_T1 = (byteFactor == bytes_T1) ? PixelCount : (PixelCount * byteFactor + bytes_T1 - 1) / bytes_T1;
385 #ifdef DEBUG
386  DCMIMGLE_TRACE("PixelCount: " << PixelCount << ", byteFactor: " << byteFactor << ", bytes_T1: " << bytes_T1 << ", count_T1: " << count_T1);
387 #endif
388  /* allocate temporary buffer, even number of bytes required for getUncompressedFrame() */
389  const Uint32 extraByte = ((sizeof(T1) == 1) && (count_T1 & 1)) ? 1 : 0;
390 #ifdef HAVE_STD__NOTHROW
391  /* use a non-throwing new here (if available) because the allocated buffer can be huge */
392  pixel = new (std::nothrow) T1[count_T1 + extraByte];
393 #else
394  pixel = new T1[count_T1 + extraByte];
395 #endif
396  if (pixel != NULL)
397  {
398  if (uncompressed)
399  {
400  DCMIMGLE_DEBUG("using partial read access to uncompressed pixel data");
401  const Uint32 offset = PixelStart * byteFactor;
402  const Uint32 bufSize = PixelCount * byteFactor;
403  const OFCondition status = pixelData->getPartialValue(pixel, offset, bufSize, fileCache);
404  if (status.good())
405  {
406  PixelStart = 0;
407  lengthBytes = bufSize;
408  } else {
409  DCMIMGLE_ERROR("can't access partial value from byte offset " << offset << " to "
410  << (offset + bufSize - 1) << ": " << status.text());
411  }
412  } else {
413  DCMIMGLE_DEBUG("using partial read access to compressed pixel data");
414  OFCondition status = EC_IllegalCall;
415  OFString decompressedColorModel;
416  const Uint32 fsize = FrameSize * byteFactor;
417  for (Uint32 frame = 0; frame < NumberOfFrames; ++frame)
418  {
419  /* make sure that the buffer always has an even number of bytes as required for getUncompressedFrame() */
420  const Uint32 bufSize = (fsize & 1) ? fsize + 1 : fsize;
421  status = pixelData->getUncompressedFrame(document->getDataset(), FirstFrame + frame, fragment,
422  OFreinterpret_cast(Uint8 *, pixel) + lengthBytes, bufSize, decompressedColorModel, fileCache);
423  if (status.good())
424  {
425  DCMIMGLE_TRACE("successfully decompressed frame " << FirstFrame + frame);
426  lengthBytes += fsize;
427  } else {
428  DCMIMGLE_ERROR("can't decompress frame " << FirstFrame + frame << ": " << status.text());
429  break;
430  }
431  }
432  if (status.good())
433  PixelStart = 0;
434  /* check whether color model changed during decompression */
435  if (!decompressedColorModel.empty() && (decompressedColorModel != document->getPhotometricInterpretation()))
436  {
437  DCMIMGLE_WARN("Photometric Interpretation of decompressed pixel data deviates from original image: "
438  << decompressedColorModel);
439  }
440  }
441  deletePixel = OFTrue;
442  }
443  } else {
444  DCMIMGLE_DEBUG("reading uncompressed pixel data completely into memory");
445  /* always access complete pixel data */
446  lengthBytes = getPixelData(pixelData, pixel);
447  }
448  if ((pixel != NULL) && (lengthBytes > 0))
449  {
450  const Uint32 length_T1 = lengthBytes / sizeof(T1);
451  /* need to split 'length' in order to avoid integer overflow for large pixel data */
452  const Uint32 length_B1 = lengthBytes / bitsAllocated;
453  const Uint32 length_B2 = lengthBytes % bitsAllocated;
454 // # old code: Count = ((lengthBytes * 8) + bitsAllocated - 1) / bitsAllocated;
455  Count = 8 * length_B1 + (8 * length_B2 + bitsAllocated - 1) / bitsAllocated;
456  register unsigned long i;
457 #ifdef HAVE_STD__NOTHROW
458  /* use a non-throwing new here (if available) because the allocated buffer can be huge */
459  Data = new (std::nothrow) T2[Count];
460 #else
461  Data = new T2[Count];
462 #endif
463  if (Data != NULL)
464  {
465  DCMIMGLE_TRACE("Input length: " << lengthBytes << " bytes, Pixel count: " << Count
466  << " (" << PixelCount << "), In: " << bitsof_T1 << " bits, Out: " << bitsof_T2
467  << " bits (" << (this->isSigned() ? "signed" : "unsigned") << ")");
468  register const T1 *p = pixel;
469  register T2 *q = Data;
470  if (bitsof_T1 == bitsAllocated) // case 1: equal 8/16 bit
471  {
472  if (bitsStored == bitsAllocated)
473  {
474  DCMIMGLE_DEBUG("convert input pixel data: case 1a (single copy)");
475  for (i = Count; i != 0; --i)
476  *(q++) = OFstatic_cast(T2, *(p++));
477  }
478  else /* bitsStored < bitsAllocated */
479  {
480  register T1 mask = 0;
481  for (i = 0; i < bitsStored; ++i)
482  mask |= OFstatic_cast(T1, 1 << i);
483  const T2 sign = 1 << (bitsStored - 1);
484  T2 smask = 0;
485  for (i = bitsStored; i < bitsof_T2; ++i)
486  smask |= OFstatic_cast(T2, 1 << i);
487  const Uint16 shift = highBit + 1 - bitsStored;
488  if (shift == 0)
489  {
490  DCMIMGLE_DEBUG("convert input pixel data: case 1b (mask & sign)");
491  for (i = length_T1; i != 0; --i)
492  *(q++) = expandSign(OFstatic_cast(T2, *(p++) & mask), sign, smask);
493  }
494  else /* shift > 0 */
495  {
496  DCMIMGLE_DEBUG("convert input pixel data: case 1c (shift & mask & sign)");
497  for (i = length_T1; i != 0; --i)
498  *(q++) = expandSign(OFstatic_cast(T2, (*(p++) >> shift) & mask), sign, smask);
499  }
500  }
501  }
502  else if ((bitsof_T1 > bitsAllocated) && (bitsof_T1 % bitsAllocated == 0)) // case 2: divisor of 8/16 bit
503  {
504  const Uint16 times = bitsof_T1 / bitsAllocated;
505  register T1 mask = 0;
506  for (i = 0; i < bitsStored; ++i)
507  mask |= OFstatic_cast(T1, 1 << i);
508  register Uint16 j;
509  register T1 value;
510  if ((bitsStored == bitsAllocated) && (bitsStored == bitsof_T2))
511  {
512  if (times == 2)
513  {
514  DCMIMGLE_DEBUG("convert input pixel data: case 2a (simple mask)");
515  for (i = length_T1; i != 0; --i, ++p)
516  {
517  *(q++) = OFstatic_cast(T2, *p & mask);
518  *(q++) = OFstatic_cast(T2, *p >> bitsAllocated);
519  }
520  }
521  else
522  {
523  DCMIMGLE_DEBUG("convert input pixel data: case 2b (mask)");
524  for (i = length_T1; i != 0; --i)
525  {
526  value = *(p++);
527  for (j = times; j != 0; --j)
528  {
529  *(q++) = OFstatic_cast(T2, value & mask);
530  value >>= bitsAllocated;
531  }
532  }
533  }
534  }
535  else
536  {
537  DCMIMGLE_DEBUG("convert input pixel data: case 2c (shift & mask & sign)");
538  const T2 sign = 1 << (bitsStored - 1);
539  T2 smask = 0;
540  for (i = bitsStored; i < bitsof_T2; ++i)
541  smask |= OFstatic_cast(T2, 1 << i);
542  const Uint16 shift = highBit + 1 - bitsStored;
543  for (i = length_T1; i != 0; --i)
544  {
545  value = *(p++) >> shift;
546  for (j = times; j != 0; --j)
547  {
548  *(q++) = expandSign(OFstatic_cast(T2, value & mask), sign, smask);
549  value >>= bitsAllocated;
550  }
551  }
552  }
553  }
554  else if ((bitsof_T1 < bitsAllocated) && (bitsAllocated % bitsof_T1 == 0) // case 3: multiplicant of 8/16
555  && (bitsStored == bitsAllocated))
556  {
557  DCMIMGLE_DEBUG("convert input pixel data: case 3 (multi copy)");
558  const Uint16 times = bitsAllocated / bitsof_T1;
559  register Uint16 j;
560  register Uint16 shift;
561  register T2 value;
562  for (i = length_T1; i != 0; --i)
563  {
564  shift = 0;
565  value = OFstatic_cast(T2, *(p++));
566  for (j = times; j > 1; --j, --i)
567  {
568  shift += bitsof_T1;
569  value |= OFstatic_cast(T2, *(p++)) << shift;
570  }
571  *(q++) = value;
572  }
573  }
574  else // case 4: anything else
575  {
576  DCMIMGLE_DEBUG("convert input pixel data: case 4 (general)");
577  register T2 value = 0;
578  register Uint16 bits = 0;
579  register Uint32 skip = highBit + 1 - bitsStored;
580  register Uint32 times;
581  T1 mask[bitsof_T1];
582  mask[0] = 1;
583  for (i = 1; i < bitsof_T1; ++i)
584  mask[i] = (mask[i - 1] << 1) | 1;
585  T2 smask = 0;
586  for (i = bitsStored; i < bitsof_T2; ++i)
587  smask |= OFstatic_cast(T2, 1 << i);
588  const T2 sign = 1 << (bitsStored - 1);
589  const Uint32 gap = bitsAllocated - bitsStored;
590  i = 0;
591  while (i < length_T1)
592  {
593  if (skip < bitsof_T1)
594  {
595  if (skip + bitsStored - bits < bitsof_T1) // -++- --++
596  {
597  value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsStored - bits - 1]) << bits);
598  skip += bitsStored - bits + gap;
599  bits = bitsStored;
600  }
601  else // ++-- ++++
602  {
603  value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsof_T1 - skip - 1]) << bits);
604  bits += bitsof_T1 - OFstatic_cast(Uint16, skip);
605  skip = (bits == bitsStored) ? gap : 0;
606  ++i;
607  ++p;
608  }
609  if (bits == bitsStored)
610  {
611  *(q++) = expandSign(value, sign, smask);
612  value = 0;
613  bits = 0;
614  }
615  }
616  else
617  {
618  times = skip / bitsof_T1;
619  i += times;
620  p += times;
621  skip -= times * bitsof_T1;
622  }
623  }
624  }
625  }
626  } else {
627  /* in case of error, reset pixel count variable */
628  Count = 0;
629  }
630  if (deletePixel)
631  {
632  /* delete temporary buffer */
633 #if defined(HAVE_STD__NOTHROW) && defined(HAVE_NOTHROW_DELETE)
634  /* use a non-throwing delete (if available) */
635  operator delete[] (pixel, std::nothrow);
636 #else
637  delete[] pixel;
638 #endif
639  }
640  }
641 
643  T2 *Data;
644 
646  T2 MinValue[2];
648  T2 MaxValue[2];
649 
650  // --- declarations to avoid compiler warnings
651 
654 };
655 
656 
657 #endif
658 
659 
660 /*
661  *
662  * CVS/RCS Log:
663  * $Log: diinpxt.h,v $
664  * Revision 1.42 2010-10-14 13:16:26 joergr
665  * Updated copyright header. Added reference to COPYRIGHT file.
666  *
667  * Revision 1.41 2010-07-22 10:27:30 joergr
668  * Made sure that the size of the buffer for partial access to pixel data is
669  * always an even number of bytes.
670  *
671  * Revision 1.40 2010-04-16 12:56:46 joergr
672  * Further enhanced computation of buffer size when using partial read access
673  * to pixel data. Now also some rare cases of BitsAllocated are supported.
674  *
675  * Revision 1.39 2010-04-15 14:18:36 joergr
676  * Fixed possibly wrong computation of a buffer size when using partial read
677  * access to pixel data. This could lead to a crash under certain conditions.
678  *
679  * Revision 1.38 2010-03-01 09:08:46 uli
680  * Removed some unnecessary include directives in the headers.
681  *
682  * Revision 1.37 2009-11-25 16:05:40 joergr
683  * Adapted code for new approach to access individual frames of a DICOM image.
684  * Added more logging messages. Revised logging messages.
685  *
686  * Revision 1.36 2009-10-28 14:38:16 joergr
687  * Fixed minor issues in log output.
688  *
689  * Revision 1.35 2009-10-28 09:53:40 uli
690  * Switched to logging mechanism provided by the "new" oflog module.
691  *
692  * Revision 1.34 2007-08-30 13:39:30 joergr
693  * Added further check on pixel pointer (possibly avoids crash under certain
694  * conditions).
695  *
696  * Revision 1.33 2006/10/27 14:59:26 joergr
697  * Fixed possible integer overflow for images with very large pixel data.
698  *
699  * Revision 1.32 2006/08/15 16:30:11 meichel
700  * Updated the code in module dcmimgle to correctly compile when
701  * all standard C++ classes remain in namespace std.
702  *
703  * Revision 1.31 2006/01/17 18:35:42 joergr
704  * Fixed compilation problem with gcc 4.0 on Linux x86_64.
705  *
706  * Revision 1.30 2005/12/08 16:47:44 meichel
707  * Changed include path schema for all DCMTK header files
708  *
709  * Revision 1.29 2004/04/21 10:00:36 meichel
710  * Minor modifications for compilation with gcc 3.4.0
711  *
712  * Revision 1.28 2004/02/06 11:07:50 joergr
713  * Distinguish more clearly between const and non-const access to pixel data.
714  *
715  * Revision 1.27 2004/01/05 14:52:20 joergr
716  * Removed acknowledgements with e-mail addresses from CVS log.
717  *
718  * Revision 1.26 2003/12/23 15:53:22 joergr
719  * Replaced post-increment/decrement operators by pre-increment/decrement
720  * operators where appropriate (e.g. 'i++' by '++i').
721  *
722  * Revision 1.25 2003/12/08 19:10:52 joergr
723  * Adapted type casts to new-style typecast operators defined in ofcast.h.
724  * Removed leading underscore characters from preprocessor symbols (reserved
725  * symbols). Updated copyright header.
726  *
727  * Revision 1.24 2002/10/21 10:13:50 joergr
728  * Corrected wrong calculation of min/max pixel value in cases where the
729  * stored pixel data exceeds the expected size.
730  *
731  * Revision 1.23 2001/11/13 18:07:36 joergr
732  * Fixed bug occurring when processing monochrome images with an odd number of
733  * pixels.
734  *
735  * Revision 1.22 2001/10/10 15:25:09 joergr
736  * Removed redundant variable declarations to avoid compiler warnings
737  * ("declaration of ... shadows previous local").
738  *
739  * Revision 1.21 2001/09/28 13:04:59 joergr
740  * Enhanced algorithm to determine the min and max value.
741  *
742  * Revision 1.20 2001/06/01 15:49:42 meichel
743  * Updated copyright header
744  *
745  * Revision 1.19 2000/05/03 09:46:28 joergr
746  * Removed most informational and some warning messages from release built
747  * (#ifndef DEBUG).
748  *
749  * Revision 1.18 2000/04/28 12:32:30 joergr
750  * DebugLevel - global for the module - now derived from OFGlobal (MF-safe).
751  *
752  * Revision 1.17 2000/04/27 13:08:39 joergr
753  * Dcmimgle library code now consistently uses ofConsole for error output.
754  *
755  * Revision 1.16 2000/03/08 16:24:17 meichel
756  * Updated copyright header.
757  *
758  * Revision 1.15 2000/03/03 14:09:12 meichel
759  * Implemented library support for redirecting error messages into memory
760  * instead of printing them to stdout/stderr for GUI applications.
761  *
762  * Revision 1.14 1999/09/17 12:21:57 joergr
763  * Added/changed/completed DOC++ style comments in the header files.
764  * Enhanced efficiency of some "for" loops and of the implementation to
765  * determine min/max values of the input pixels.
766  *
767  * Revision 1.13 1999/07/23 13:54:38 joergr
768  * Optimized memory usage for converting input pixel data (reference instead
769  * of copying where possible).
770  *
771  * Revision 1.12 1999/05/04 09:20:39 meichel
772  * Minor code purifications to keep IBM xlC quiet
773  *
774  * Revision 1.11 1999/04/30 16:23:59 meichel
775  * Minor code purifications to keep IBM xlC quiet
776  *
777  * Revision 1.10 1999/04/28 14:48:39 joergr
778  * Introduced new scheme for the debug level variable: now each level can be
779  * set separately (there is no "include" relationship).
780  *
781  * Revision 1.9 1999/03/24 17:20:03 joergr
782  * Added/Modified comments and formatting.
783  *
784  * Revision 1.8 1999/02/11 16:00:54 joergr
785  * Removed inline declarations from several methods.
786  *
787  * Revision 1.7 1999/02/03 17:04:37 joergr
788  * Moved global functions maxval() and determineRepresentation() to class
789  * DicomImageClass (as static methods).
790  *
791  * Revision 1.6 1999/01/20 15:01:31 joergr
792  * Replaced invocation of getCount() by member variable Count where possible.
793  *
794  * Revision 1.5 1999/01/11 09:34:28 joergr
795  * Corrected bug in determing 'AbsMaximum' (removed '+ 1').
796  *
797  * Revision 1.4 1998/12/22 14:23:16 joergr
798  * Added calculation of member variables AbsMinimum/AbsMaximum.
799  * Replaced method copyMem by for-loop copying each item.
800  * Removed some '#ifdef DEBUG'.
801  *
802  * Revision 1.3 1998/12/16 16:30:34 joergr
803  * Added methods to determine absolute minimum and maximum value for given
804  * value representation.
805  *
806  * Revision 1.2 1998/12/14 17:18:23 joergr
807  * Reformatted source code.
808  *
809  * Revision 1.1 1998/11/27 15:08:21 joergr
810  * Added copyright message.
811  * Introduced global debug level for dcmimage module to control error output.
812  * Added support for new bit manipulation class.
813  *
814  * Revision 1.8 1998/07/01 08:39:21 joergr
815  * Minor changes to avoid compiler warnings (gcc 2.8.1 with additional
816  * options), e.g. add copy constructors.
817  *
818  * Revision 1.7 1998/05/11 14:53:17 joergr
819  * Added CVS/RCS header to each file.
820  *
821  *
822  */


Generated on Thu May 30 2013 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.8.3.1