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: DicomMonoOutputPixelTemplate (Header) 00023 * 00024 * Last Update: $Author: meichel $ 00025 * Update Date: $Date: 2005/12/08 16:47:54 $ 00026 * CVS/RCS Revision: $Revision: 1.46 $ 00027 * Status: $State: Exp $ 00028 * 00029 * CVS/RCS Log at end of file 00030 * 00031 */ 00032 00033 00034 #ifndef DIMOOPXT_H 00035 #define DIMOOPXT_H 00036 00037 #include "dcmtk/config/osconfig.h" 00038 #include "dcmtk/ofstd/ofconsol.h" 00039 #include "dcmtk/ofstd/ofcast.h" 00040 #include "dcmtk/dcmdata/dctypes.h" 00041 00042 #include "dcmtk/dcmimgle/dimoopx.h" 00043 #include "dcmtk/dcmimgle/diluptab.h" 00044 #include "dcmtk/dcmimgle/diovlay.h" 00045 #include "dcmtk/dcmimgle/dipxrept.h" 00046 #include "dcmtk/dcmimgle/diutils.h" 00047 #include "dcmtk/dcmimgle/didispfn.h" 00048 #include "dcmtk/dcmimgle/didislut.h" 00049 00050 #ifdef PASTEL_COLOR_OUTPUT 00051 #include "dimcopxt.h" 00052 #endif 00053 00054 #define INCLUDE_CMATH 00055 #include "dcmtk/ofstd/ofstdinc.h" 00056 00057 00058 /*---------------------* 00059 * class declaration * 00060 *---------------------*/ 00061 00064 template<class T1, class T2, class T3> 00065 class DiMonoOutputPixelTemplate 00066 : public DiMonoOutputPixel, 00067 public DiPixelRepresentationTemplate<T3> 00068 { 00069 00070 public: 00071 00090 DiMonoOutputPixelTemplate(void *buffer, 00091 const DiMonoPixel *pixel, 00092 DiOverlay *overlays[2], 00093 const DiLookupTable *vlut, 00094 const DiLookupTable *plut, 00095 DiDisplayFunction *disp, 00096 const double center, 00097 const double width, 00098 const Uint32 low, 00099 const Uint32 high, 00100 const Uint16 columns, 00101 const Uint16 rows, 00102 const unsigned long frame, 00103 #ifdef PASTEL_COLOR_OUTPUT 00104 const unsigned long frames, 00105 #else 00106 const unsigned long /*frames*/, 00107 #endif 00108 const int pastel = 0) 00109 : DiMonoOutputPixel(pixel, OFstatic_cast(unsigned long, columns) * OFstatic_cast(unsigned long, rows), frame, 00110 OFstatic_cast(unsigned long, fabs(OFstatic_cast(double, high - low)))), 00111 Data(NULL), 00112 DeleteData(buffer == NULL), 00113 ColorData(NULL) 00114 { 00115 if ((pixel != NULL) && (Count > 0) && (FrameSize >= Count)) 00116 { 00117 if (pastel) 00118 #ifdef PASTEL_COLOR_OUTPUT 00119 color(buffer, pixel, frame, frames); 00120 #else 00121 { 00122 ofConsole.lockCerr() << "WARNING: pastel color output not supported !" << endl; 00123 ofConsole.unlockCerr(); 00124 } 00125 #endif 00126 else 00127 { 00128 Data = OFstatic_cast(T3 *, buffer); 00129 if ((vlut != NULL) && (vlut->isValid())) // valid VOI LUT ? 00130 voilut(pixel, frame * FrameSize, vlut, plut, disp, OFstatic_cast(T3, low), OFstatic_cast(T3, high)); 00131 else 00132 { 00133 if (width < 1) // no valid window according to supplement 33 00134 nowindow(pixel, frame * FrameSize, plut, disp, OFstatic_cast(T3, low), OFstatic_cast(T3, high)); 00135 else 00136 window(pixel, frame * FrameSize, plut, disp, center, width, OFstatic_cast(T3, low), OFstatic_cast(T3, high)); 00137 } 00138 overlay(overlays, disp, columns, rows, frame); // add (visible) overlay planes to output bitmap 00139 } 00140 } 00141 } 00142 00145 virtual ~DiMonoOutputPixelTemplate() 00146 { 00147 if (DeleteData) 00148 delete[] Data; 00149 delete ColorData; 00150 } 00151 00156 inline EP_Representation getRepresentation() const 00157 { 00158 return DiPixelRepresentationTemplate<T3>::getRepresentation(); 00159 } 00160 00165 inline size_t getItemSize() const 00166 { 00167 return (ColorData != NULL) ? ColorData->getItemSize() : sizeof(T3); 00168 } 00169 00174 inline const void *getData() const 00175 { 00176 return (ColorData != NULL) ? ColorData->getData() : OFstatic_cast(const void *, Data); 00177 } 00178 00183 virtual void *getDataPtr() 00184 { 00185 return (ColorData != NULL) ? ColorData->getDataPtr() : OFstatic_cast(void *, Data); 00186 } 00187 00190 inline void removeDataReference() 00191 { 00192 Data = NULL; 00193 DeleteData = 0; 00194 } 00195 00202 inline int writePPM(ostream &stream) const 00203 { 00204 if (Data != NULL) 00205 { 00206 register unsigned long i; 00207 for (i = 0; i < FrameSize; ++i) 00208 stream << OFstatic_cast(unsigned long, Data[i]) << " "; // typecast to resolve problems with 'char' 00209 return 1; 00210 } 00211 if (ColorData != NULL) 00212 return ColorData->writePPM(stream); 00213 return 0; 00214 } 00215 00222 inline int writePPM(FILE *stream) const 00223 { 00224 if (Data != NULL) 00225 { 00226 register unsigned long i; 00227 for (i = 0; i < FrameSize; ++i) 00228 fprintf(stream, "%lu ", OFstatic_cast(unsigned long, Data[i])); 00229 return 1; 00230 } 00231 if (ColorData != NULL) 00232 return ColorData->writePPM(stream); 00233 return 0; 00234 } 00235 00236 00237 protected: 00238 00241 inline void determineUsedValues() 00242 { 00243 if ((UsedValues == NULL) && (MaxValue > 0) && (MaxValue < MAX_TABLE_ENTRY_COUNT)) 00244 { 00245 UsedValues = new Uint8[MaxValue + 1]; 00246 if (UsedValues != NULL) 00247 { 00248 OFBitmanipTemplate<Uint8>::zeroMem(UsedValues, MaxValue + 1); // initialize array 00249 register const T3 *p = Data; 00250 register Uint8 *q = UsedValues; 00251 register unsigned long i; 00252 for (i = Count; i != 0; --i) 00253 *(q + *(p++)) = 1; // mark used entries 00254 } 00255 } 00256 } 00257 00258 00259 private: 00260 00267 inline void createDisplayLUT(const DiDisplayLUT *&dlut, 00268 DiDisplayFunction *disp, 00269 const int bits) 00270 { 00271 if ((disp != NULL) && (disp->isValid())) 00272 { // create Display LUT 00273 dlut = disp->getLookupTable(bits); 00274 if ((dlut != NULL) && (dlut->isValid())) // LUT is valid 00275 { 00276 #ifdef DEBUG 00277 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00278 { 00279 ofConsole.lockCerr() << "INFO: using display transformation" << endl; 00280 ofConsole.unlockCerr(); 00281 } 00282 #endif 00283 } else { 00284 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Warnings)) 00285 { 00286 ofConsole.lockCerr() << "WARNING: can't create display LUT ... ignoring display transformation !" << endl; 00287 ofConsole.unlockCerr(); 00288 } 00289 dlut = NULL; 00290 } 00291 } 00292 } 00293 00299 inline int initOptimizationLUT(T3 *&lut, 00300 const unsigned long ocnt) 00301 { 00302 int result = 0; 00303 if ((sizeof(T1) <= 2) && (Count > 3 * ocnt)) // optimization criteria 00304 { // use LUT for optimization 00305 lut = new T3[ocnt]; 00306 if (lut != NULL) 00307 { 00308 #ifdef DEBUG 00309 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00310 { 00311 ofConsole.lockCerr() << "INFO: using optimized routine with additional LUT" << endl; 00312 ofConsole.unlockCerr(); 00313 } 00314 #endif 00315 result = 1; 00316 } 00317 } 00318 return result; 00319 } 00320 00321 #ifdef PASTEL_COLOR_OUTPUT 00322 void color(void *buffer, // create true color pastel image 00323 const DiMonoPixel *inter, 00324 const unsigned long frame, 00325 const unsigned long frames) 00326 { 00327 ColorData = new DiMonoColorOutputPixelTemplate<T1, T3>(buffer, inter, frame, frames); 00328 if (ColorData != NULL) 00329 { 00330 ofConsole.lockCout() << "COLOR" << endl; 00331 ofConsole.unlockCout(); 00332 } 00333 } 00334 #endif 00335 00346 void voilut(const DiMonoPixel *inter, 00347 const Uint32 start, 00348 const DiLookupTable *vlut, 00349 const DiLookupTable *plut, 00350 DiDisplayFunction *disp, 00351 const T3 low, 00352 const T3 high) 00353 { 00354 const T1 *pixel = OFstatic_cast(const T1 *, inter->getData()); 00355 if ((pixel != NULL) && (vlut != NULL)) 00356 { 00357 if (Data == NULL) 00358 Data = new T3[FrameSize]; 00359 if (Data != NULL) 00360 { 00361 #ifdef DEBUG 00362 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00363 { 00364 ofConsole.lockCerr() << "INFO: using VOI routine 'voilut()'" << endl; 00365 ofConsole.unlockCerr(); 00366 } 00367 #endif 00368 const DiDisplayLUT *dlut = NULL; 00369 const double minvalue = vlut->getMinValue(); 00370 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low) + 1; 00371 register unsigned long i; 00372 if (minvalue == vlut->getMaxValue()) // LUT has only one entry or all entries are equal 00373 { 00374 T3 value; 00375 if ((plut != NULL) && (plut->isValid())) // has presentation LUT 00376 { 00377 #ifdef DEBUG 00378 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00379 { 00380 ofConsole.lockCerr() << "INFO: using presentation LUT transformation" << endl; 00381 ofConsole.unlockCerr(); 00382 } 00383 #endif 00384 createDisplayLUT(dlut, disp, plut->getBits()); 00385 const Uint32 value2 = OFstatic_cast(Uint32, (minvalue / OFstatic_cast(double, vlut->getAbsMaxRange())) * plut->getCount()); 00386 if (dlut != NULL) // perform display transformation 00387 { 00388 /* UNTESTED !! */ 00389 if (low > high) // invers 00390 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, plut->getAbsMaxRange() - plut->getValue(value2) - 1))); 00391 else // normal 00392 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, plut->getValue(value2)))); 00393 } else { // don't use display: invalid or absent 00394 value = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * outrange / OFstatic_cast(double, plut->getAbsMaxRange())); 00395 } 00396 } else { // has no presentation LUT 00397 createDisplayLUT(dlut, disp, vlut->getBits()); 00398 if (dlut != NULL) // perform display transformation 00399 { 00400 /* UNTESTED !! */ 00401 if (low > high) // invers 00402 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, vlut->getAbsMaxRange() - minvalue - 1))); 00403 else // normal 00404 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, minvalue))); 00405 } else // don't use display: invalid or absent 00406 value = OFstatic_cast(T3, OFstatic_cast(double, low) + (minvalue / OFstatic_cast(double, vlut->getAbsMaxRange())) * outrange); 00407 } 00408 OFBitmanipTemplate<T3>::setMem(Data, value, Count); // set output pixels to LUT value 00409 } else { 00410 register T2 value = 0; 00411 const T2 absmin = OFstatic_cast(T2, inter->getAbsMinimum()); 00412 const T2 firstentry = vlut->getFirstEntry(value); // choose signed/unsigned method 00413 const T2 lastentry = vlut->getLastEntry(value); 00414 const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange()); // number of LUT entries 00415 register const T1 *p = pixel + start; 00416 register T3 *q = Data; 00417 T3 *lut = NULL; 00418 if ((plut != NULL) && (plut->isValid())) // has presentation LUT 00419 { 00420 #ifdef DEBUG 00421 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00422 { 00423 ofConsole.lockCerr() << "INFO: using presentation LUT transformation" << endl; 00424 ofConsole.unlockCerr(); 00425 } 00426 #endif 00427 createDisplayLUT(dlut, disp, plut->getBits()); 00428 register Uint32 value2; // presentation LUT is always unsigned 00429 const Uint32 pcnt = plut->getCount(); 00430 const double gradient1 = OFstatic_cast(double, pcnt) / OFstatic_cast(double, vlut->getAbsMaxRange()); 00431 const Uint32 firstvalue = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getFirstValue()) * gradient1); 00432 const Uint32 lastvalue = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getLastValue()) * gradient1); 00433 if (initOptimizationLUT(lut, ocnt)) 00434 { // use LUT for optimization 00435 q = lut; 00436 if (dlut != NULL) // perform display transformation 00437 { 00438 if (low > high) // inverse 00439 { 00440 const Uint16 maxvalue = OFstatic_cast(Uint16, plut->getAbsMaxRange() - 1); 00441 for (i = 0; i < ocnt; ++i) 00442 { 00443 value = OFstatic_cast(T2, i) + absmin; 00444 if (value <= firstentry) 00445 value2 = firstvalue; 00446 else if (value >= lastentry) 00447 value2 = lastvalue; 00448 else 00449 value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1); 00450 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->getValue(value2)))); 00451 } 00452 } else { // normal 00453 for (i = 0; i < ocnt; ++i) 00454 { 00455 value = OFstatic_cast(T2, i) + absmin; 00456 if (value <= firstentry) 00457 value2 = firstvalue; 00458 else if (value >= lastentry) 00459 value2 = lastvalue; 00460 else 00461 value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1); 00462 *(q++) = OFstatic_cast(T3, dlut->getValue(plut->getValue(value2))); 00463 } 00464 } 00465 } else { // don't use display: invalid or absent 00466 const double gradient2 = outrange / OFstatic_cast(double, plut->getAbsMaxRange()); 00467 for (i = 0; i < ocnt; ++i) 00468 { 00469 value = OFstatic_cast(T2, i) + absmin; 00470 if (value <= firstentry) 00471 value2 = firstvalue; 00472 else if (value >= lastentry) 00473 value2 = lastvalue; 00474 else 00475 value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1); 00476 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient2); 00477 } 00478 } 00479 const T3 *lut0 = lut - OFstatic_cast(T2, inter->getAbsMinimum()); // points to 'zero' entry 00480 q = Data; 00481 for (i = Count; i != 0; --i) // apply LUT 00482 *(q++) = *(lut0 + (*(p++))); 00483 } 00484 if (lut == NULL) // use "normal" transformation 00485 { 00486 if (dlut != NULL) // perform display transformation 00487 { 00488 if (low > high) // inverse 00489 { 00490 const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->getAbsMaxRange() - 1); 00491 for (i = Count; i != 0; --i) 00492 { 00493 value = OFstatic_cast(T2, *(p++)); // pixel value 00494 if (value <= firstentry) 00495 value2 = firstvalue; 00496 else if (value >= lastentry) 00497 value2 = lastvalue; 00498 else 00499 value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1); 00500 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->getValue(value2)))); 00501 } 00502 } else { // normal 00503 for (i = Count; i != 0; --i) 00504 { 00505 value = OFstatic_cast(T2, *(p++)); // pixel value 00506 if (value <= firstentry) 00507 value2 = firstvalue; 00508 else if (value >= lastentry) 00509 value2 = lastvalue; 00510 else 00511 value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1); 00512 *(q++) = OFstatic_cast(T3, dlut->getValue(plut->getValue(value2))); 00513 } 00514 } 00515 } else { // don't use display: invalid or absent 00516 const double gradient2 = outrange / OFstatic_cast(double, plut->getAbsMaxRange()); 00517 for (i = Count; i != 0; --i) 00518 { 00519 value = OFstatic_cast(T2, *(p++)); // pixel value 00520 if (value <= firstentry) 00521 value2 = firstvalue; 00522 else if (value >= lastentry) 00523 value2 = lastvalue; 00524 else 00525 value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1); 00526 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient2); 00527 } 00528 } 00529 } 00530 } else { // has no presentation LUT 00531 createDisplayLUT(dlut, disp, vlut->getBits()); 00532 const double gradient = outrange / OFstatic_cast(double, vlut->getAbsMaxRange()); 00533 const T3 firstvalue = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getFirstValue()) * gradient); 00534 const T3 lastvalue = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getLastValue()) * gradient); 00535 if (initOptimizationLUT(lut, ocnt)) 00536 { // use LUT for optimization 00537 q = lut; 00538 if (dlut != NULL) // perform display transformation 00539 { 00540 if (low > high) // inverse 00541 { 00542 const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->getAbsMaxRange() - 1); 00543 for (i = 0; i < ocnt; ++i) 00544 { 00545 value = OFstatic_cast(T2, i) + absmin; 00546 if (value < firstentry) 00547 value = firstentry; 00548 else if (value > lastentry) 00549 value = lastentry; 00550 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - vlut->getValue(value)))); 00551 } 00552 } else { // normal 00553 for (i = 0; i < ocnt; ++i) 00554 { 00555 value = OFstatic_cast(T2, i) + absmin; 00556 if (value < firstentry) 00557 value = firstentry; 00558 else if (value > lastentry) 00559 value = lastentry; 00560 *(q++) = OFstatic_cast(T3, dlut->getValue(vlut->getValue(value))); 00561 } 00562 } 00563 } else { // don't use display: invalid or absent 00564 for (i = 0; i < ocnt; ++i) // calculating LUT entries 00565 { 00566 value = OFstatic_cast(T2, i) + absmin; 00567 if (value <= firstentry) 00568 *(q++) = firstvalue; 00569 else if (value >= lastentry) 00570 *(q++) = lastvalue; 00571 else 00572 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getValue(value)) * gradient); 00573 } 00574 } 00575 const T3 *lut0 = lut - OFstatic_cast(T2, inter->getAbsMinimum()); // points to 'zero' entry 00576 q = Data; 00577 for (i = Count; i != 0; --i) // apply LUT 00578 *(q++) = *(lut0 + (*(p++))); 00579 } 00580 if (lut == NULL) // use "normal" transformation 00581 { 00582 if (dlut != NULL) // perform display transformation 00583 { 00584 if (low > high) // inverse 00585 { 00586 const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->getAbsMaxRange() - 1); 00587 for (i = Count; i != 0; --i) 00588 { 00589 value = OFstatic_cast(T2, *(p++)); 00590 if (value < firstentry) 00591 value = firstentry; 00592 else if (value > lastentry) 00593 value = lastentry; 00594 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - vlut->getValue(value)))); 00595 } 00596 } else { // normal 00597 for (i = Count; i != 0; --i) 00598 { 00599 value = OFstatic_cast(T2, *(p++)); 00600 if (value < firstentry) 00601 value = firstentry; 00602 else if (value > lastentry) 00603 value = lastentry; 00604 *(q++) = OFstatic_cast(T3, dlut->getValue(vlut->getValue(value))); 00605 } 00606 } 00607 } else { // don't use display: invalid or absent 00608 for (i = 0; i < Count; ++i) 00609 { 00610 value = OFstatic_cast(T2, *(p++)); 00611 if (value <= firstentry) 00612 *(q++) = firstvalue; 00613 else if (value >= lastentry) 00614 *(q++) = lastvalue; 00615 else 00616 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getValue(value)) * gradient); 00617 } 00618 } 00619 } 00620 } 00621 delete[] lut; 00622 } 00623 if (Count < FrameSize) 00624 OFBitmanipTemplate<T3>::zeroMem(Data + Count, FrameSize - Count); // set remaining pixels of frame to zero 00625 } 00626 } else 00627 Data = NULL; 00628 } 00629 00639 void nowindow(const DiMonoPixel *inter, 00640 const Uint32 start, 00641 const DiLookupTable *plut, 00642 DiDisplayFunction *disp, 00643 const T3 low, 00644 const T3 high) 00645 { 00646 const DiDisplayLUT *dlut = NULL; 00647 const T1 *pixel = OFstatic_cast(const T1 *, inter->getData()); 00648 if (pixel != NULL) 00649 { 00650 if (Data == NULL) // create new output buffer 00651 Data = new T3[FrameSize]; 00652 if (Data != NULL) 00653 { 00654 #ifdef DEBUG 00655 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00656 { 00657 ofConsole.lockCerr() << "INFO: using VOI routine 'nowindow()'" << endl; 00658 ofConsole.unlockCerr(); 00659 } 00660 #endif 00661 const double absmin = inter->getAbsMinimum(); 00662 const double absmax = inter->getAbsMaximum(); 00663 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low) + 1; 00664 const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange()); // number of LUT entries 00665 register const T1 *p = pixel + start; 00666 register T3 *q = Data; 00667 register unsigned long i; 00668 T3 *lut = NULL; 00669 if ((plut != NULL) && (plut->isValid())) // has presentation LUT 00670 { 00671 #ifdef DEBUG 00672 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00673 { 00674 ofConsole.lockCerr() << "INFO: using presentation LUT transformation" << endl; 00675 ofConsole.unlockCerr(); 00676 } 00677 #endif 00678 createDisplayLUT(dlut, disp, plut->getBits()); 00679 register Uint32 value; // presentation LUT is always unsigned 00680 const double gradient1 = OFstatic_cast(double, plut->getCount()) / inter->getAbsMaxRange(); 00681 const double gradient2 = outrange / OFstatic_cast(double, plut->getAbsMaxRange()); 00682 if (initOptimizationLUT(lut, ocnt)) 00683 { // use LUT for optimization 00684 q = lut; 00685 if (dlut != NULL) // perform display transformation 00686 { 00687 if (low > high) // inverse 00688 { 00689 const Uint16 maxvalue = OFstatic_cast(Uint16, plut->getAbsMaxRange() - 1); 00690 for (i = 0; i < ocnt; ++i) 00691 { 00692 value = OFstatic_cast(Uint32, OFstatic_cast(double, i) * gradient1); 00693 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->getValue(value)))); 00694 } 00695 } else { // normal 00696 for (i = 0; i < ocnt; ++i) 00697 { 00698 value = OFstatic_cast(Uint32, OFstatic_cast(double, i) * gradient1); 00699 *(q++) = OFstatic_cast(T3, dlut->getValue(plut->getValue(value))); 00700 } 00701 } 00702 } else { // don't use display: invalid or absent 00703 for (i = 0; i < ocnt; ++i) 00704 { 00705 value = OFstatic_cast(Uint32, OFstatic_cast(double, i) * gradient1); 00706 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value)) * gradient2); 00707 } 00708 } 00709 const T3 *lut0 = lut - OFstatic_cast(T2, inter->getAbsMinimum()); // points to 'zero' entry 00710 q = Data; 00711 for (i = Count; i != 0; --i) // apply LUT 00712 *(q++) = *(lut0 + (*(p++))); 00713 } 00714 if (lut == NULL) // use "normal" transformation 00715 { 00716 if (dlut != NULL) // perform display transformation 00717 { 00718 if (low > high) // inverse 00719 { 00720 const Uint16 maxvalue = OFstatic_cast(Uint16, plut->getAbsMaxRange() - 1); 00721 for (i = Count; i != 0; --i) 00722 { 00723 value = OFstatic_cast(Uint32, (OFstatic_cast(double, *(p++)) - absmin) * gradient1); 00724 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->getValue(value)))); 00725 } 00726 } else { // normal 00727 for (i = Count; i != 0; --i) 00728 { 00729 value = OFstatic_cast(Uint32, (OFstatic_cast(double, *(p++)) - absmin) * gradient1); 00730 *(q++) = OFstatic_cast(T3, dlut->getValue(plut->getValue(value))); 00731 } 00732 } 00733 } else { // don't use display: invalid or absent 00734 for (i = Count; i != 0; --i) 00735 { 00736 value = OFstatic_cast(Uint32, (OFstatic_cast(double, *(p++)) - absmin) * gradient1); 00737 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value)) * gradient2); 00738 } 00739 } 00740 } 00741 } else { // has no presentation LUT 00742 createDisplayLUT(dlut, disp, inter->getBits()); 00743 register const double gradient = outrange / (inter->getAbsMaxRange()); 00744 if (initOptimizationLUT(lut, ocnt)) 00745 { // use LUT for optimization 00746 q = lut; 00747 if (dlut != NULL) // perform display transformation 00748 { 00749 if (low > high) // inverse 00750 { 00751 for (i = ocnt; i != 0; --i) // calculating LUT entries 00752 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, i - 1))); 00753 } else { // normal 00754 for (i = 0; i < ocnt; ++i) // calculating LUT entries 00755 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, i))); 00756 } 00757 } else { // don't use display: invalid or absent 00758 for (i = 0; i < ocnt; ++i) // calculating LUT entries 00759 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, i) * gradient); 00760 } 00761 const T3 *lut0 = lut - OFstatic_cast(T2, inter->getAbsMinimum()); // points to 'zero' entry 00762 q = Data; 00763 for (i = Count; i != 0; --i) // apply LUT 00764 *(q++) = *(lut0 + (*(p++))); 00765 } 00766 if (lut == NULL) // use "normal" transformation 00767 { 00768 if (dlut != NULL) // perform display transformation 00769 { 00770 if (low > high) // inverse 00771 { 00772 for (i = Count; i != 0; --i) 00773 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, absmax - (OFstatic_cast(double, *(p++)) - absmin)))); 00774 } else { // normal 00775 for (i = Count; i != 0; --i) 00776 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, OFstatic_cast(double, *(p++)) - absmin))); 00777 } 00778 } else { // don't use display: invalid or absent 00779 for (i = Count; i != 0; --i) 00780 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + (OFstatic_cast(double, *(p++)) - absmin) * gradient); 00781 } 00782 } 00783 } 00784 delete[] lut; 00785 if (Count < FrameSize) 00786 OFBitmanipTemplate<T3>::zeroMem(Data + Count, FrameSize - Count); // set remaining pixels of frame to zero 00787 } 00788 } else 00789 Data = NULL; 00790 } 00791 00792 00804 void window(const DiMonoPixel *inter, 00805 const Uint32 start, 00806 const DiLookupTable *plut, 00807 DiDisplayFunction *disp, 00808 const double center, 00809 const double width, 00810 const T3 low, 00811 const T3 high) 00812 { 00813 const T1 *pixel = OFstatic_cast(const T1 *, inter->getData()); 00814 if (pixel != NULL) 00815 { 00816 if (Data == NULL) 00817 Data = new T3[FrameSize]; // create new output buffer 00818 if (Data != NULL) 00819 { 00820 #ifdef DEBUG 00821 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00822 { 00823 ofConsole.lockCerr() << "INFO: using VOI routine 'window()'" << endl; 00824 ofConsole.unlockCerr(); 00825 } 00826 #endif 00827 const DiDisplayLUT *dlut = NULL; 00828 const double absmin = inter->getAbsMinimum(); 00829 const double width_1 = width - 1; 00830 const double leftBorder = center - 0.5 - width_1 / 2; // window borders, according to supplement 33 00831 const double rightBorder = center - 0.5 + width_1 / 2; 00832 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low); // output range 00833 const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange()); // number of LUT entries 00834 register const T1 *p = pixel + start; 00835 register T3 *q = Data; 00836 register unsigned long i; 00837 register double value; 00838 T3 *lut = NULL; 00839 if ((plut != NULL) && (plut->isValid())) // has presentation LUT 00840 { 00841 #ifdef DEBUG 00842 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals)) 00843 { 00844 ofConsole.lockCerr() << "INFO: using presentation LUT transformation" << endl; 00845 ofConsole.unlockCerr(); 00846 } 00847 #endif 00848 createDisplayLUT(dlut, disp, plut->getBits()); 00849 register Uint32 value2; // presentation LUT is always unsigned 00850 const Uint32 pcnt = plut->getCount(); 00851 const double plutmax_1 = OFstatic_cast(double, plut->getAbsMaxRange()) - 1; 00852 const double gradient1 = (width_1 == 0) ? 0 : OFstatic_cast(double, pcnt - 1) / width_1; 00853 if (initOptimizationLUT(lut, ocnt)) 00854 { // use LUT for optimization 00855 q = lut; 00856 if (dlut != NULL) // perform display transformation 00857 { 00858 const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1); 00859 const double offset = (low > high) ? maxvalue : 0; 00860 const double gradient2 = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1); 00861 for (i = 0; i < ocnt; ++i) 00862 { 00863 value = OFstatic_cast(double, i) + absmin; // pixel value 00864 if (value <= leftBorder) 00865 value2 = 0; // first LUT index 00866 else if (value > rightBorder) 00867 value2 = pcnt - 1; // last LUT index 00868 else 00869 value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1); 00870 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(double, plut->getValue(value2)) * gradient2))); 00871 } 00872 } else { // don't use display: invalid or absent 00873 const double gradient2 = outrange / plutmax_1; 00874 for (i = 0; i < ocnt; ++i) 00875 { 00876 value = OFstatic_cast(double, i) + absmin; // pixel value 00877 if (value <= leftBorder) 00878 value2 = 0; // first LUT index 00879 else if (value > rightBorder) 00880 value2 = pcnt - 1; // last LUT index 00881 else 00882 value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1); 00883 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient2); 00884 } 00885 } 00886 const T3 *lut0 = lut - OFstatic_cast(T2, absmin); // points to 'zero' entry 00887 q = Data; 00888 for (i = Count; i != 0; --i) // apply LUT 00889 *(q++) = *(lut0 + (*(p++))); 00890 } 00891 if (lut == NULL) // use "normal" transformation 00892 { 00893 if (dlut != NULL) // perform display transformation 00894 { 00895 const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1); 00896 const double offset = (low > high) ? maxvalue : 0; 00897 const double gradient2 = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1); 00898 for (i = Count; i != 0; --i) 00899 { 00900 value = OFstatic_cast(double, *(p++)); // pixel value 00901 if (value <= leftBorder) 00902 value2 = 0; // first LUT index 00903 else if (value > rightBorder) 00904 value2 = pcnt - 1; // last LUT index 00905 else 00906 value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1); 00907 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(double, plut->getValue(value2)) * gradient2))); 00908 } 00909 } else { // don't use display: invalid or absent 00910 const double gradient2 = outrange / plutmax_1; 00911 for (i = Count; i != 0; --i) 00912 { 00913 value = OFstatic_cast(double, *(p++)); // pixel value 00914 if (value <= leftBorder) 00915 value2 = 0; // first LUT index 00916 else if (value > rightBorder) 00917 value2 = pcnt - 1; // last LUT index 00918 else 00919 value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1); 00920 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient2); 00921 } 00922 } 00923 } 00924 } else { // has no presentation LUT 00925 createDisplayLUT(dlut, disp, bitsof(T1)); 00926 if (initOptimizationLUT(lut, ocnt)) 00927 { // use LUT for optimization 00928 q = lut; 00929 if (dlut != NULL) // perform display transformation 00930 { 00931 const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1); 00932 const double offset = (low > high) ? maxvalue : 0; 00933 const double gradient = (width_1 == 0) ? 0 : ((low > high) ? (-maxvalue / width_1) : (maxvalue / width_1)); 00934 for (i = 0; i < ocnt; ++i) // calculating LUT entries 00935 { 00936 value = OFstatic_cast(double, i) + absmin - leftBorder; 00937 if (value < 0) // left border 00938 value = 0; 00939 else if (value > width_1) // right border 00940 value = width_1; 00941 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + value * gradient))); // calculate value 00942 } 00943 } else { // don't use display: invalid or absent 00944 const double offset = (width_1 == 0) ? 0 : (high - ((center - 0.5) / width_1 + 0.5) * outrange); 00945 const double gradient = (width_1 == 0) ? 0 : outrange / width_1; 00946 for (i = 0; i < ocnt; ++i) // calculating LUT entries 00947 { 00948 value = OFstatic_cast(double, i) + absmin; 00949 if (value <= leftBorder) 00950 *(q++) = low; // black/white 00951 else if (value > rightBorder) 00952 *(q++) = high; // white/black 00953 else 00954 *(q++) = OFstatic_cast(T3, offset + value * gradient); // gray value 00955 } 00956 } 00957 const T3 *lut0 = lut - OFstatic_cast(T2, absmin); // points to 'zero' entry 00958 q = Data; 00959 for (i = Count; i != 0; --i) // apply LUT 00960 *(q++) = *(lut0 + (*(p++))); 00961 } 00962 if (lut == NULL) // use "normal" transformation 00963 { 00964 if (dlut != NULL) // perform display transformation 00965 { 00966 const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1); 00967 const double offset = (low > high) ? maxvalue : 0; 00968 const double gradient = (width_1 == 0) ? 0 : ((low > high) ? (-maxvalue / width_1) : (maxvalue / width_1)); 00969 for (i = Count; i != 0; --i) // calculating LUT entries 00970 { 00971 value = OFstatic_cast(double, *(p++)) - leftBorder; 00972 if (value < 0) // left border 00973 value = 0; 00974 else if (value > width_1) // right border 00975 value = width_1; 00976 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + value * gradient))); // calculate value 00977 } 00978 } else { // don't use display: invalid or absent 00979 const double offset = (width_1 == 0) ? 0 : (high - ((center - 0.5) / width_1 + 0.5) * outrange); 00980 const double gradient = (width_1 == 0) ? 0 : outrange / width_1; 00981 for (i = Count; i != 0; --i) 00982 { 00983 value = OFstatic_cast(double, *(p++)); 00984 if (value <= leftBorder) 00985 *(q++) = low; // black/white 00986 else if (value > rightBorder) 00987 *(q++) = high; // white/black 00988 else 00989 *(q++) = OFstatic_cast(T3, offset + value * gradient); // gray value 00990 } 00991 } 00992 } 00993 } 00994 delete[] lut; 00995 if (Count < FrameSize) 00996 OFBitmanipTemplate<T3>::zeroMem(Data + Count, FrameSize - Count); // set remaining pixels of frame to zero 00997 } 00998 } else 00999 Data = NULL; 01000 } 01001 01002 01011 void overlay(DiOverlay *overlays[2], 01012 DiDisplayFunction *disp, 01013 const Uint16 columns, 01014 const Uint16 rows, 01015 const unsigned long frame) 01016 { 01017 if ((Data != NULL) && (overlays != NULL)) 01018 { 01019 for (unsigned int j = 0; j < 2; ++j) 01020 { 01021 if (overlays[j] != NULL) 01022 { 01023 const signed long left_pos = overlays[j]->getLeft(); 01024 const signed long top_pos = overlays[j]->getTop(); 01025 register DiOverlayPlane *plane; 01026 for (unsigned int i = 0; i < overlays[j]->getCount(); ++i) 01027 { 01028 plane = overlays[j]->getPlane(i); 01029 if ((plane != NULL) && plane->isVisible() && plane->reset(frame)) 01030 { 01031 register T3 *q; 01032 register Uint16 x; 01033 register Uint16 y; 01034 const Uint16 xmin = (plane->getLeft(left_pos) > 0) ? plane->getLeft(left_pos) : 0; 01035 const Uint16 ymin = (plane->getTop(top_pos) > 0) ? plane->getTop(top_pos) : 0; 01036 const Uint16 xmax = (plane->getRight(left_pos) < columns) ? plane->getRight(left_pos) : columns; 01037 const Uint16 ymax = (plane->getBottom(top_pos) < rows) ? plane->getBottom(top_pos) : rows; 01038 const T3 maxvalue = OFstatic_cast(T3, DicomImageClass::maxval(bitsof(T3))); 01039 switch (plane->getMode()) 01040 { 01041 case EMO_Replace: 01042 { 01043 const T3 fore = OFstatic_cast(T3, plane->getForeground() * maxvalue); 01044 for (y = ymin; y < ymax; ++y) 01045 { 01046 plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y)); 01047 q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin); 01048 for (x = xmin; x < xmax; ++x, ++q) 01049 { 01050 if (plane->getNextBit()) 01051 *q = fore; 01052 } 01053 } 01054 break; 01055 } 01056 case EMO_ThresholdReplace: 01057 { 01058 const T3 fore = OFstatic_cast(T3, plane->getForeground() * maxvalue); 01059 const T3 thresh = OFstatic_cast(T3, plane->getThreshold() * maxvalue); 01060 for (y = ymin; y < ymax; ++y) 01061 { 01062 plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y)); 01063 q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin); 01064 for (x = xmin; x < xmax; ++x, ++q) 01065 { 01066 if (plane->getNextBit()) 01067 *q = (*q <= thresh) ? fore : 1; 01068 } 01069 } 01070 break; 01071 } 01072 case EMO_Complement: 01073 { 01074 const T3 thresh = OFstatic_cast(T3, DicomImageClass::maxval(bitsof(T3) / 2)); 01075 for (y = ymin; y < ymax; ++y) 01076 { 01077 plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y)); 01078 q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin); 01079 for (x = xmin; x < xmax; ++x, ++q) 01080 { 01081 if (plane->getNextBit()) 01082 *q = (*q <= thresh) ? maxvalue : 0; 01083 } 01084 } 01085 break; 01086 } 01087 case EMO_InvertBitmap: 01088 { 01089 const T3 fore = OFstatic_cast(T3, plane->getForeground() * maxvalue); 01090 for (y = ymin; y < ymax; ++y) 01091 { 01092 plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y)); 01093 q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin); 01094 for (x = xmin; x < xmax; ++x, ++q) 01095 { 01096 if (!plane->getNextBit()) 01097 *q = fore; 01098 } 01099 } 01100 break; 01101 } 01102 case EMO_RegionOfInterest: 01103 { 01104 const int dim = bitsof(T3) / 2; 01105 for (y = ymin; y < ymax; ++y) 01106 { 01107 plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y)); 01108 q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin); 01109 for (x = xmin; x < xmax; ++x, ++q) 01110 { 01111 if (!plane->getNextBit()) 01112 *q = *q >> dim; 01113 } 01114 } 01115 break; 01116 } 01117 case EMO_BitmapShutter: 01118 { 01119 register T3 fore = OFstatic_cast(T3, OFstatic_cast(double, maxvalue) * OFstatic_cast(double, plane->getPValue()) / OFstatic_cast(double, DicomImageClass::maxval(WIDTH_OF_PVALUES))); 01120 if ((disp != NULL) && (disp->isValid())) 01121 { 01122 const DiDisplayLUT *dlut = disp->getLookupTable(WIDTH_OF_PVALUES); 01123 if ((dlut != NULL) && (dlut->isValid())) 01124 fore = OFstatic_cast(T3, dlut->getValue(plane->getPValue())); 01125 } 01126 for (y = ymin; y < ymax; ++y) 01127 { 01128 plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y)); 01129 q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin); 01130 for (x = xmin; x < xmax; ++x, ++q) 01131 { 01132 if (plane->getNextBit()) 01133 *q = fore; 01134 } 01135 } 01136 break; 01137 } 01138 default: /* e.g. EMO_Default */ 01139 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Warnings)) 01140 { 01141 ofConsole.lockCerr() << "WARNING: unhandled overlay mode (" << OFstatic_cast(int, plane->getMode()) << ") !" << endl; 01142 ofConsole.unlockCerr(); 01143 } 01144 } 01145 } 01146 } 01147 } 01148 } 01149 } 01150 } 01151 01152 01154 T3 *Data; 01156 int DeleteData; 01157 01158 #ifdef PASTEL_COLOR_OUTPUT 01159 DiMonoColorOutputPixelTemplate<T1, T3> *ColorData; 01160 #else 01161 // dummy variable 01162 DiMonoOutputPixel *ColorData; 01163 #endif 01164 01165 // --- declarations to avoid compiler warnings 01166 01167 DiMonoOutputPixelTemplate(const DiMonoOutputPixelTemplate<T1,T2,T3> &); 01168 DiMonoOutputPixelTemplate<T1,T2,T3> &operator=(const DiMonoOutputPixelTemplate<T1,T2,T3> &); 01169 }; 01170 01171 01172 #endif 01173 01174 01175 /* 01176 * 01177 * CVS/RCS Log: 01178 * $Log: dimoopxt.h,v $ 01179 * Revision 1.46 2005/12/08 16:47:54 meichel 01180 * Changed include path schema for all DCMTK header files 01181 * 01182 * Revision 1.45 2005/03/09 17:30:42 joergr 01183 * Added support for new overlay mode "invert bitmap". 01184 * 01185 * Revision 1.44 2004/02/06 11:07:50 joergr 01186 * Distinguish more clearly between const and non-const access to pixel data. 01187 * 01188 * Revision 1.43 2003/12/23 15:53:22 joergr 01189 * Replaced post-increment/decrement operators by pre-increment/decrement 01190 * operators where appropriate (e.g. 'i++' by '++i'). 01191 * 01192 * Revision 1.42 2003/12/23 10:51:52 joergr 01193 * Updated documentation to get rid of doxygen warnings. 01194 * 01195 * Revision 1.41 2003/12/09 16:49:11 joergr 01196 * Adapted type casts to new-style typecast operators defined in ofcast.h. 01197 * Removed leading underscore characters from preprocessor symbols (reserved 01198 * symbols). Updated copyright header. 01199 * 01200 * Revision 1.40 2003/06/12 15:08:34 joergr 01201 * Fixed inconsistent API documentation reported by Doxygen. 01202 * 01203 * Revision 1.39 2002/12/09 13:32:53 joergr 01204 * Renamed parameter/local variable to avoid name clashes with global 01205 * declaration left and/or right (used for as iostream manipulators). 01206 * 01207 * Revision 1.38 2002/11/27 14:08:06 meichel 01208 * Adapted module dcmimgle to use of new header file ofstdinc.h 01209 * 01210 * Revision 1.37 2002/06/19 08:12:01 meichel 01211 * Added typecasts to avoid ambiguity with built-in functions on gcc 3.2 01212 * 01213 * Revision 1.36 2001/06/01 15:49:46 meichel 01214 * Updated copyright header 01215 * 01216 * Revision 1.35 2000/05/03 09:46:28 joergr 01217 * Removed most informational and some warning messages from release built 01218 * (#ifndef DEBUG). 01219 * 01220 * Revision 1.34 2000/04/28 12:32:31 joergr 01221 * DebugLevel - global for the module - now derived from OFGlobal (MF-safe). 01222 * 01223 * Revision 1.33 2000/04/27 13:08:40 joergr 01224 * Dcmimgle library code now consistently uses ofConsole for error output. 01225 * 01226 * Revision 1.32 2000/03/08 16:24:20 meichel 01227 * Updated copyright header. 01228 * 01229 * Revision 1.31 2000/03/07 16:15:12 joergr 01230 * Added explicit type casts to make Sun CC 2.0.1 happy. 01231 * 01232 * Revision 1.30 2000/03/06 18:19:36 joergr 01233 * Moved get-method to base class, renamed method and made method virtual to 01234 * avoid hiding of methods (reported by Sun CC 4.2). 01235 * 01236 * Revision 1.29 2000/03/03 14:09:13 meichel 01237 * Implemented library support for redirecting error messages into memory 01238 * instead of printing them to stdout/stderr for GUI applications. 01239 * 01240 * Revision 1.28 2000/02/01 10:52:37 meichel 01241 * Avoiding to include <stdlib.h> as extern "C" on Borland C++ Builder 4, 01242 * workaround for bug in compiler header files. 01243 * 01244 * Revision 1.27 1999/10/11 20:14:14 joergr 01245 * Fixed bug in window() routine for cases where presentation LUT is active. 01246 * 01247 * Revision 1.26 1999/10/06 13:42:03 joergr 01248 * Added method to remove reference to (internally handled) pixel data. 01249 * 01250 * Revision 1.25 1999/09/17 12:40:45 joergr 01251 * Added/changed/completed DOC++ style comments in the header files. 01252 * Enhanced efficiency of some "for" loops. 01253 * 01254 * Revision 1.24 1999/09/10 08:45:19 joergr 01255 * Added support for CIELAB display function. 01256 * 01257 * Revision 1.23 1999/08/25 16:41:53 joergr 01258 * Added new feature: Allow clipping region to be outside the image 01259 * (overlapping). 01260 * 01261 * Revision 1.22 1999/08/17 10:26:08 joergr 01262 * Commented unused parameter names to avoid compiler warnings. 01263 * 01264 * Revision 1.21 1999/07/23 14:08:44 joergr 01265 * Changed implementation/interpretation of windows center/width (according to 01266 * new letter ballot of supplement 33). 01267 * Enhanced handling of corrupted pixel data (wrong length). 01268 * 01269 * Revision 1.20 1999/05/03 15:43:21 joergr 01270 * Replaced method applyOptimizationLUT by its contents (method body) to avoid 01271 * warnings (and possible errors) on Sun CC 2.0.1 :-/ 01272 * 01273 * Revision 1.18 1999/04/30 16:10:50 meichel 01274 * Minor code purifications to keep IBM xlC quiet 01275 * 01276 * Revision 1.17 1999/04/29 16:46:46 meichel 01277 * Minor code purifications to keep DEC cxx 6 quiet. 01278 * 01279 * Revision 1.16 1999/04/29 09:38:34 joergr 01280 * Changed position of "#ifdef" to avoid compiler warnings. 01281 * 01282 * Revision 1.15 1999/04/29 09:20:01 joergr 01283 * Removed color related image files from public toolkit part. 01284 * 01285 * Revision 1.14 1999/04/28 18:56:07 joergr 01286 * Removed support for pastel color output from public DCMTK part. 01287 * 01288 * Revision 1.13 1999/04/28 14:51:44 joergr 01289 * Added experimental support to create grayscale images with more than 256 01290 * shades of gray to be displayed on a consumer monitor (use pastel colors). 01291 * Introduced new scheme for the debug level variable: now each level can be 01292 * set separately (there is no "include" relationship). 01293 * 01294 * Revision 1.12 1999/03/24 17:20:14 joergr 01295 * Added/Modified comments and formatting. 01296 * 01297 * Revision 1.11 1999/03/02 12:03:52 joergr 01298 * Corrected bug in output routine of monochrome pixel data (wrong scaling when 01299 * Barten transformation and windowing are active). 01300 * 01301 * Revision 1.10 1999/02/28 16:41:01 joergr 01302 * Corrected bug: the output bits for bitmaps shutters were inverted (this was 01303 * done due to an error in the used test images). 01304 * 01305 * Revision 1.9 1999/02/11 16:40:19 joergr 01306 * Added routine to check whether particular grayscale values are unused in 01307 * the output data. 01308 * Removed two small memory leaks reported by dmalloc library. 01309 * 01310 * Revision 1.8 1999/02/05 16:44:52 joergr 01311 * Corrected calculation of DDL value for bitmaps shutters (overlays). 01312 * 01313 * Revision 1.7 1999/02/05 15:13:36 joergr 01314 * Added conversion P-Value to DDL when display function is absent. 01315 * 01316 * Revision 1.6 1999/02/03 17:32:43 joergr 01317 * Added optimization LUT to transform pixel data. 01318 * Added support for calibration according to Barten transformation (incl. 01319 * a DISPLAY file describing the monitor characteristic). 01320 * 01321 * Revision 1.5 1999/01/20 15:11:05 joergr 01322 * Replaced invocation of getCount() by member variable Count where possible. 01323 * Added new output method to fill external memory buffer with rendered pixel 01324 * data. 01325 * Added new overlay plane mode for bitmap shutters. 01326 * Added optimization to modality and VOI transformation (using additional 01327 * LUTs). 01328 * 01329 * Revision 1.4 1998/12/23 12:40:01 joergr 01330 * Removed unused parameter (BitsPerSample). 01331 * 01332 * Revision 1.3 1998/12/22 14:32:49 joergr 01333 * Improved implementation of presentation LUT application (and other gray 01334 * scale transformations). Tested with ECR test images from David Clunie. 01335 * 01336 * Revision 1.2 1998/12/14 17:25:55 joergr 01337 * Added support for correct scaling of input/output values for grayscale 01338 * transformations. 01339 * 01340 * Revision 1.1 1998/11/27 15:29:53 joergr 01341 * Added copyright message. 01342 * Introduced global debug level for dcmimage module to control error output. 01343 * Corrected bug in VOI LUT transformation method. 01344 * Changed behaviour: now window width of 0 is valid and negative width 01345 * is invalid. 01346 * 01347 * Revision 1.6 1998/07/01 08:39:24 joergr 01348 * Minor changes to avoid compiler warnings (gcc 2.8.1 with additional 01349 * options), e.g. add copy constructors. 01350 * 01351 * Revision 1.5 1998/05/11 14:53:22 joergr 01352 * Added CVS/RCS header to each file. 01353 * 01354 * 01355 */ 01356