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: DicomInputPixelTemplate (Header) 00023 * 00024 * Last Update: $Author: meichel $ 00025 * Update Date: $Date: 2005/12/08 16:47:44 $ 00026 * CVS/RCS Revision: $Revision: 1.30 $ 00027 * Status: $State: Exp $ 00028 * 00029 * CVS/RCS Log at end of file 00030 * 00031 */ 00032 00033 00034 #ifndef DIINPXT_H 00035 #define DIINPXT_H 00036 00037 #include "dcmtk/config/osconfig.h" 00038 #include "dcmtk/dcmdata/dctypes.h" 00039 #include "dcmtk/dcmdata/dcpixel.h" 00040 00041 #include "dcmtk/ofstd/ofbmanip.h" 00042 #include "dcmtk/ofstd/ofcast.h" 00043 00044 #include "dcmtk/dcmimgle/diinpx.h" 00045 #include "dcmtk/dcmimgle/dipxrept.h" 00046 #include "dcmtk/dcmimgle/diutils.h" 00047 00048 00049 /*--------------------* 00050 * helper functions * 00051 *--------------------*/ 00052 00053 static inline Uint8 expandSign(const Uint8 Value, 00054 const Uint8, 00055 const Uint8) 00056 { 00057 return Value; 00058 } 00059 00060 00061 static inline Uint16 expandSign(const Uint16 Value, 00062 const Uint16, 00063 const Uint16) 00064 { 00065 return Value; 00066 } 00067 00068 00069 static inline Uint32 expandSign(const Uint32 Value, 00070 const Uint32, 00071 const Uint32) 00072 { 00073 return Value; 00074 } 00075 00076 00077 static inline Sint8 expandSign(const Sint8 Value, 00078 const Sint8 SignBit, 00079 const Sint8 SignMask) 00080 { 00081 return (Value & SignBit) ? (Value | SignMask) : Value; 00082 } 00083 00084 00085 static inline Sint16 expandSign(const Sint16 Value, 00086 const Sint16 SignBit, 00087 const Sint16 SignMask) 00088 { 00089 return (Value & SignBit) ? (Value | SignMask) : Value; 00090 } 00091 00092 00093 static inline Sint32 expandSign(const Sint32 Value, 00094 const Sint32 SignBit, 00095 const Sint32 SignMask) 00096 { 00097 return (Value & SignBit) ? (Value | SignMask) : Value; 00098 } 00099 00100 00101 static Uint32 getPixelData(DcmPixelData *PixelData, 00102 Uint8 *&pixel) 00103 { 00104 PixelData->getUint8Array(pixel); 00105 return PixelData->getLength(); 00106 } 00107 00108 00109 static Uint32 getPixelData(DcmPixelData *PixelData, 00110 Uint16 *&pixel) 00111 { 00112 PixelData->getUint16Array(pixel); 00113 return PixelData->getLength(); 00114 } 00115 00116 00117 /*---------------------* 00118 * class declaration * 00119 *---------------------*/ 00120 00123 template<class T1, class T2> 00124 class DiInputPixelTemplate 00125 : public DiInputPixel, 00126 public DiPixelRepresentationTemplate<T2> 00127 { 00128 00129 public: 00130 00140 DiInputPixelTemplate(/*const*/ DcmPixelData *pixel, 00141 const Uint16 alloc, 00142 const Uint16 stored, 00143 const Uint16 high, 00144 const unsigned long start, 00145 const unsigned long count) 00146 : DiInputPixel(stored, start, count), 00147 Data(NULL) 00148 { 00149 MinValue[0] = 0; 00150 MinValue[1] = 0; 00151 MaxValue[0] = 0; 00152 MaxValue[1] = 0; 00153 if (this->isSigned()) 00154 { 00155 AbsMinimum = -OFstatic_cast(double, DicomImageClass::maxval(Bits - 1, 0)); 00156 AbsMaximum = OFstatic_cast(double, DicomImageClass::maxval(Bits - 1)); 00157 } else { 00158 AbsMinimum = 0; 00159 AbsMaximum = OFstatic_cast(double, DicomImageClass::maxval(Bits)); 00160 } 00161 if (pixel != NULL) 00162 convert(pixel, alloc, stored, high); 00163 if ((PixelCount == 0) || (PixelStart + PixelCount > Count)) // check for corrupt pixel length 00164 PixelCount = Count - PixelStart; 00165 } 00166 00169 virtual ~DiInputPixelTemplate() 00170 { 00171 delete[] Data; 00172 } 00173 00178 int determineMinMax() 00179 { 00180 if (Data != NULL) 00181 { 00182 register T2 *p = Data; 00183 register unsigned long i; 00184 const unsigned long ocnt = OFstatic_cast(unsigned long, getAbsMaxRange()); 00185 Uint8 *lut = NULL; 00186 if ((sizeof(T2) <= 2) && (Count > 3 * ocnt)) // optimization criteria 00187 { 00188 lut = new Uint8[ocnt]; 00189 if (lut != NULL) 00190 { 00191 OFBitmanipTemplate<Uint8>::zeroMem(lut, ocnt); 00192 register Uint8 *q = lut - OFstatic_cast(T2, getAbsMinimum()); 00193 for (i = Count; i != 0; --i) // fill lookup table 00194 *(q + *(p++)) = 1; 00195 q = lut; 00196 for (i = 0; i < ocnt; ++i) // search for minimum 00197 { 00198 if (*(q++) != 0) 00199 { 00200 MinValue[0] = OFstatic_cast(T2, OFstatic_cast(double, i) + getAbsMinimum()); 00201 break; 00202 } 00203 } 00204 q = lut + ocnt; 00205 for (i = ocnt; i != 0; --i) // search for maximum 00206 { 00207 if (*(--q) != 0) 00208 { 00209 MaxValue[0] = OFstatic_cast(T2, OFstatic_cast(double, i - 1) + getAbsMinimum()); 00210 break; 00211 } 00212 } 00213 if (Count >= PixelCount) // use global min/max value 00214 { 00215 MinValue[1] = MinValue[0]; 00216 MaxValue[1] = MaxValue[0]; 00217 } else { // calculate min/max for selected range 00218 OFBitmanipTemplate<Uint8>::zeroMem(lut, ocnt); 00219 p = Data + PixelStart; 00220 q = lut - OFstatic_cast(T2, getAbsMinimum()); 00221 for (i = PixelCount; i != 0; --i) // fill lookup table 00222 *(q + *(p++)) = 1; 00223 q = lut; 00224 for (i = 0; i < ocnt; ++i) // search for minimum 00225 { 00226 if (*(q++) != 0) 00227 { 00228 MinValue[1] = OFstatic_cast(T2, OFstatic_cast(double, i) + getAbsMinimum()); 00229 break; 00230 } 00231 } 00232 q = lut + ocnt; 00233 for (i = ocnt; i != 0; --i) // search for maximum 00234 { 00235 if (*(--q) != 0) 00236 { 00237 MaxValue[1] = OFstatic_cast(T2, OFstatic_cast(double, i - 1) + getAbsMinimum()); 00238 break; 00239 } 00240 } 00241 } 00242 } 00243 } 00244 if (lut == NULL) // use conventional method 00245 { 00246 register T2 value = *p; 00247 MinValue[0] = value; 00248 MaxValue[0] = value; 00249 for (i = Count; i > 1; --i) 00250 { 00251 value = *(++p); 00252 if (value < MinValue[0]) 00253 MinValue[0] = value; 00254 else if (value > MaxValue[0]) 00255 MaxValue[0] = value; 00256 } 00257 if (Count <= PixelCount) // use global min/max value 00258 { 00259 MinValue[1] = MinValue[0]; 00260 MaxValue[1] = MaxValue[0]; 00261 } else { // calculate min/max for selected range 00262 p = Data + PixelStart; 00263 value = *p; 00264 MinValue[1] = value; 00265 MaxValue[1] = value; 00266 for (i = PixelCount; i > 1; --i) 00267 { 00268 value = *(++p); 00269 if (value < MinValue[1]) 00270 MinValue[1] = value; 00271 else if (value > MaxValue[1]) 00272 MaxValue[1] = value; 00273 } 00274 } 00275 } 00276 delete[] lut; 00277 return 1; 00278 } 00279 return 0; 00280 } 00281 00286 inline EP_Representation getRepresentation() const 00287 { 00288 return DiPixelRepresentationTemplate<T2>::getRepresentation(); 00289 } 00290 00295 inline const void *getData() const 00296 { 00297 return OFstatic_cast(const void *, Data); 00298 } 00299 00304 virtual void *getDataPtr() 00305 { 00306 return OFstatic_cast(void *, Data); 00307 } 00308 00311 inline void removeDataReference() 00312 { 00313 Data = NULL; 00314 } 00315 00323 inline double getMinValue(const int idx) const 00324 { 00325 return (idx == 0) ? OFstatic_cast(double, MinValue[0]) : OFstatic_cast(double, MinValue[1]); 00326 } 00327 00335 inline double getMaxValue(const int idx) const 00336 { 00337 return (idx == 0) ? OFstatic_cast(double, MaxValue[0]) : OFstatic_cast(double, MaxValue[1]); 00338 } 00339 00340 00341 private: 00342 00350 void convert(/*const*/ DcmPixelData *pixelData, 00351 const Uint16 bitsAllocated, 00352 const Uint16 bitsStored, 00353 const Uint16 highBit) 00354 { 00355 const Uint16 bitsof_T1 = bitsof(T1); 00356 const Uint16 bitsof_T2 = bitsof(T2); 00357 T1 *pixel; 00358 const Uint32 length_Bytes = getPixelData(pixelData, pixel); 00359 const Uint32 length_T1 = length_Bytes / sizeof(T1); 00360 Count = ((length_Bytes * 8) + bitsAllocated - 1) / bitsAllocated; 00361 register unsigned long i; 00362 Data = new T2[Count]; 00363 if (Data != NULL) 00364 { 00365 #ifdef DEBUG 00366 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00367 { 00368 ofConsole.lockCerr() << bitsAllocated << " " << bitsStored << " " << highBit << " " << isSigned() << endl; 00369 ofConsole.unlockCerr(); 00370 } 00371 #endif 00372 register const T1 *p = pixel; 00373 register T2 *q = Data; 00374 if (bitsof_T1 == bitsAllocated) // case 1: equal 8/16 bit 00375 { 00376 if (bitsStored == bitsAllocated) 00377 { 00378 #ifdef DEBUG 00379 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00380 { 00381 ofConsole.lockCerr() << "convert pixelData: case 1a (single copy)" << endl; 00382 ofConsole.unlockCerr(); 00383 } 00384 #endif 00385 for (i = Count; i != 0; --i) 00386 *(q++) = OFstatic_cast(T2, *(p++)); 00387 } 00388 else /* bitsStored < bitsAllocated */ 00389 { 00390 register T1 mask = 0; 00391 for (i = 0; i < bitsStored; ++i) 00392 mask |= OFstatic_cast(T1, 1 << i); 00393 const T2 sign = 1 << (bitsStored - 1); 00394 T2 smask = 0; 00395 for (i = bitsStored; i < bitsof_T2; ++i) 00396 smask |= OFstatic_cast(T2, 1 << i); 00397 const Uint16 shift = highBit + 1 - bitsStored; 00398 if (shift == 0) 00399 { 00400 #ifdef DEBUG 00401 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00402 { 00403 ofConsole.lockCerr() << "convert pixelData: case 1b (mask & sign)" << endl; 00404 ofConsole.unlockCerr(); 00405 } 00406 #endif 00407 for (i = length_T1; i != 0; --i) 00408 *(q++) = expandSign(OFstatic_cast(T2, *(p++) & mask), sign, smask); 00409 } 00410 else /* shift > 0 */ 00411 { 00412 #ifdef DEBUG 00413 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00414 { 00415 ofConsole.lockCerr() << "convert pixelData: case 1c (shift & mask & sign)" << endl; 00416 ofConsole.unlockCerr(); 00417 } 00418 #endif 00419 for (i = length_T1; i != 0; --i) 00420 *(q++) = expandSign(OFstatic_cast(T2, (*(p++) >> shift) & mask), sign, smask); 00421 } 00422 } 00423 } 00424 else if ((bitsof_T1 > bitsAllocated) && (bitsof_T1 % bitsAllocated == 0)) // case 2: divisor of 8/16 bit 00425 { 00426 const Uint16 times = bitsof_T1 / bitsAllocated; 00427 register T1 mask = 0; 00428 for (i = 0; i < bitsStored; ++i) 00429 mask |= OFstatic_cast(T1, 1 << i); 00430 register Uint16 j; 00431 register T1 value; 00432 if ((bitsStored == bitsAllocated) && (bitsStored == bitsof_T2)) 00433 { 00434 if (times == 2) 00435 { 00436 #ifdef DEBUG 00437 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00438 { 00439 ofConsole.lockCerr() << "convert pixelData: case 2a (simple mask)" << endl; 00440 ofConsole.unlockCerr(); 00441 } 00442 #endif 00443 for (i = length_T1; i != 0; --i, ++p) 00444 { 00445 *(q++) = OFstatic_cast(T2, *p & mask); 00446 *(q++) = OFstatic_cast(T2, *p >> bitsAllocated); 00447 } 00448 } 00449 else 00450 { 00451 #ifdef DEBUG 00452 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00453 { 00454 ofConsole.lockCerr() << "convert pixelData: case 2b (mask)" << endl; 00455 ofConsole.unlockCerr(); 00456 } 00457 #endif 00458 for (i = length_T1; i != 0; --i) 00459 { 00460 value = *(p++); 00461 for (j = times; j != 0; --j) 00462 { 00463 *(q++) = OFstatic_cast(T2, value & mask); 00464 value >>= bitsAllocated; 00465 } 00466 } 00467 } 00468 } 00469 else 00470 { 00471 #ifdef DEBUG 00472 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00473 { 00474 ofConsole.lockCerr() << "convert pixelData: case 2c (shift & mask & sign)" << endl; 00475 ofConsole.unlockCerr(); 00476 } 00477 #endif 00478 const T2 sign = 1 << (bitsStored - 1); 00479 T2 smask = 0; 00480 for (i = bitsStored; i < bitsof_T2; ++i) 00481 smask |= OFstatic_cast(T2, 1 << i); 00482 const Uint16 shift = highBit + 1 - bitsStored; 00483 for (i = length_T1; i != 0; --i) 00484 { 00485 value = *(p++) >> shift; 00486 for (j = times; j != 0; --j) 00487 { 00488 *(q++) = expandSign(OFstatic_cast(T2, value & mask), sign, smask); 00489 value >>= bitsAllocated; 00490 } 00491 } 00492 } 00493 } 00494 else if ((bitsof_T1 < bitsAllocated) && (bitsAllocated % bitsof_T1 == 0) // case 3: multiplicant of 8/16 00495 && (bitsStored == bitsAllocated)) 00496 { 00497 #ifdef DEBUG 00498 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00499 { 00500 ofConsole.lockCerr() << "convert pixelData: case 3 (multi copy)" << endl; 00501 ofConsole.unlockCerr(); 00502 } 00503 #endif 00504 const Uint16 times = bitsAllocated / bitsof_T1; 00505 register Uint16 j; 00506 register Uint16 shift; 00507 register T2 value; 00508 for (i = length_T1; i != 0; --i) 00509 { 00510 shift = 0; 00511 value = OFstatic_cast(T2, *(p++)); 00512 for (j = times; j > 1; --j, --i) 00513 { 00514 shift += bitsof_T1; 00515 value |= OFstatic_cast(T2, *(p++)) << shift; 00516 } 00517 *(q++) = value; 00518 } 00519 } 00520 else // case 4: anything else 00521 { 00522 #ifdef DEBUG 00523 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00524 { 00525 ofConsole.lockCerr() << "convert pixelData: case 4 (general)" << endl; 00526 ofConsole.unlockCerr(); 00527 } 00528 #endif 00529 register T2 value = 0; 00530 register Uint16 bits = 0; 00531 register Uint32 skip = highBit + 1 - bitsStored; 00532 register Uint32 times; 00533 T1 mask[bitsof_T1]; 00534 mask[0] = 1; 00535 for (i = 1; i < bitsof_T1; ++i) 00536 mask[i] = (mask[i - 1] << 1) | 1; 00537 T2 smask = 0; 00538 for (i = bitsStored; i < bitsof_T2; ++i) 00539 smask |= OFstatic_cast(T2, 1 << i); 00540 const T2 sign = 1 << (bitsStored - 1); 00541 const Uint32 gap = bitsAllocated - bitsStored; 00542 i = 0; 00543 while (i < length_T1) 00544 { 00545 if (skip < bitsof_T1) 00546 { 00547 if (skip + bitsStored - bits < bitsof_T1) // -++- --++ 00548 { 00549 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsStored - bits - 1]) << bits); 00550 skip += bitsStored - bits + gap; 00551 bits = bitsStored; 00552 } 00553 else // ++-- ++++ 00554 { 00555 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsof_T1 - skip - 1]) << bits); 00556 bits += bitsof_T1 - OFstatic_cast(Uint16, skip); 00557 skip = (bits == bitsStored) ? gap : 0; 00558 ++i; 00559 ++p; 00560 } 00561 if (bits == bitsStored) 00562 { 00563 *(q++) = expandSign(value, sign, smask); 00564 value = 0; 00565 bits = 0; 00566 } 00567 } 00568 else 00569 { 00570 times = skip / bitsof_T1; 00571 i += times; 00572 p += times; 00573 skip -= times * bitsof_T1; 00574 } 00575 } 00576 } 00577 } 00578 } 00579 00581 T2 *Data; 00582 00584 T2 MinValue[2]; 00586 T2 MaxValue[2]; 00587 00588 // --- declarations to avoid compiler warnings 00589 00590 DiInputPixelTemplate(const DiInputPixelTemplate<T1,T2> &); 00591 DiInputPixelTemplate<T1,T2> &operator=(const DiInputPixelTemplate<T1,T2> &); 00592 }; 00593 00594 00595 #endif 00596 00597 00598 /* 00599 * 00600 * CVS/RCS Log: 00601 * $Log: diinpxt.h,v $ 00602 * Revision 1.30 2005/12/08 16:47:44 meichel 00603 * Changed include path schema for all DCMTK header files 00604 * 00605 * Revision 1.29 2004/04/21 10:00:36 meichel 00606 * Minor modifications for compilation with gcc 3.4.0 00607 * 00608 * Revision 1.28 2004/02/06 11:07:50 joergr 00609 * Distinguish more clearly between const and non-const access to pixel data. 00610 * 00611 * Revision 1.27 2004/01/05 14:52:20 joergr 00612 * Removed acknowledgements with e-mail addresses from CVS log. 00613 * 00614 * Revision 1.26 2003/12/23 15:53:22 joergr 00615 * Replaced post-increment/decrement operators by pre-increment/decrement 00616 * operators where appropriate (e.g. 'i++' by '++i'). 00617 * 00618 * Revision 1.25 2003/12/08 19:10:52 joergr 00619 * Adapted type casts to new-style typecast operators defined in ofcast.h. 00620 * Removed leading underscore characters from preprocessor symbols (reserved 00621 * symbols). Updated copyright header. 00622 * 00623 * Revision 1.24 2002/10/21 10:13:50 joergr 00624 * Corrected wrong calculation of min/max pixel value in cases where the 00625 * stored pixel data exceeds the expected size. 00626 * 00627 * Revision 1.23 2001/11/13 18:07:36 joergr 00628 * Fixed bug occurring when processing monochrome images with an odd number of 00629 * pixels. 00630 * 00631 * Revision 1.22 2001/10/10 15:25:09 joergr 00632 * Removed redundant variable declarations to avoid compiler warnings 00633 * ("declaration of ... shadows previous local"). 00634 * 00635 * Revision 1.21 2001/09/28 13:04:59 joergr 00636 * Enhanced algorithm to determine the min and max value. 00637 * 00638 * Revision 1.20 2001/06/01 15:49:42 meichel 00639 * Updated copyright header 00640 * 00641 * Revision 1.19 2000/05/03 09:46:28 joergr 00642 * Removed most informational and some warning messages from release built 00643 * (#ifndef DEBUG). 00644 * 00645 * Revision 1.18 2000/04/28 12:32:30 joergr 00646 * DebugLevel - global for the module - now derived from OFGlobal (MF-safe). 00647 * 00648 * Revision 1.17 2000/04/27 13:08:39 joergr 00649 * Dcmimgle library code now consistently uses ofConsole for error output. 00650 * 00651 * Revision 1.16 2000/03/08 16:24:17 meichel 00652 * Updated copyright header. 00653 * 00654 * Revision 1.15 2000/03/03 14:09:12 meichel 00655 * Implemented library support for redirecting error messages into memory 00656 * instead of printing them to stdout/stderr for GUI applications. 00657 * 00658 * Revision 1.14 1999/09/17 12:21:57 joergr 00659 * Added/changed/completed DOC++ style comments in the header files. 00660 * Enhanced efficiency of some "for" loops and of the implementation to 00661 * determine min/max values of the input pixels. 00662 * 00663 * Revision 1.13 1999/07/23 13:54:38 joergr 00664 * Optimized memory usage for converting input pixel data (reference instead 00665 * of copying where possible). 00666 * 00667 * Revision 1.12 1999/05/04 09:20:39 meichel 00668 * Minor code purifications to keep IBM xlC quiet 00669 * 00670 * Revision 1.11 1999/04/30 16:23:59 meichel 00671 * Minor code purifications to keep IBM xlC quiet 00672 * 00673 * Revision 1.10 1999/04/28 14:48:39 joergr 00674 * Introduced new scheme for the debug level variable: now each level can be 00675 * set separately (there is no "include" relationship). 00676 * 00677 * Revision 1.9 1999/03/24 17:20:03 joergr 00678 * Added/Modified comments and formatting. 00679 * 00680 * Revision 1.8 1999/02/11 16:00:54 joergr 00681 * Removed inline declarations from several methods. 00682 * 00683 * Revision 1.7 1999/02/03 17:04:37 joergr 00684 * Moved global functions maxval() and determineRepresentation() to class 00685 * DicomImageClass (as static methods). 00686 * 00687 * Revision 1.6 1999/01/20 15:01:31 joergr 00688 * Replaced invocation of getCount() by member variable Count where possible. 00689 * 00690 * Revision 1.5 1999/01/11 09:34:28 joergr 00691 * Corrected bug in determing 'AbsMaximum' (removed '+ 1'). 00692 * 00693 * Revision 1.4 1998/12/22 14:23:16 joergr 00694 * Added calculation of member variables AbsMinimum/AbsMaximum. 00695 * Replaced method copyMem by for-loop copying each item. 00696 * Removed some '#ifdef DEBUG'. 00697 * 00698 * Revision 1.3 1998/12/16 16:30:34 joergr 00699 * Added methods to determine absolute minimum and maximum value for given 00700 * value representation. 00701 * 00702 * Revision 1.2 1998/12/14 17:18:23 joergr 00703 * Reformatted source code. 00704 * 00705 * Revision 1.1 1998/11/27 15:08:21 joergr 00706 * Added copyright message. 00707 * Introduced global debug level for dcmimage module to control error output. 00708 * Added support for new bit manipulation class. 00709 * 00710 * Revision 1.8 1998/07/01 08:39:21 joergr 00711 * Minor changes to avoid compiler warnings (gcc 2.8.1 with additional 00712 * options), e.g. add copy constructors. 00713 * 00714 * Revision 1.7 1998/05/11 14:53:17 joergr 00715 * Added CVS/RCS header to each file. 00716 * 00717 * 00718 */