00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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 ,
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()))
00130 voilut(pixel, frame * FrameSize, vlut, plut, disp, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
00131 else
00132 {
00133 if (width < 1)
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);
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]) << " ";
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);
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;
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 {
00273 dlut = disp->getLookupTable(bits);
00274 if ((dlut != NULL) && (dlut->isValid()))
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))
00304 {
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,
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())
00373 {
00374 T3 value;
00375 if ((plut != NULL) && (plut->isValid()))
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)
00387 {
00388
00389 if (low > high)
00390 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, plut->getAbsMaxRange() - plut->getValue(value2) - 1)));
00391 else
00392 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, plut->getValue(value2))));
00393 } else {
00394 value = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * outrange / OFstatic_cast(double, plut->getAbsMaxRange()));
00395 }
00396 } else {
00397 createDisplayLUT(dlut, disp, vlut->getBits());
00398 if (dlut != NULL)
00399 {
00400
00401 if (low > high)
00402 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, vlut->getAbsMaxRange() - minvalue - 1)));
00403 else
00404 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, minvalue)));
00405 } else
00406 value = OFstatic_cast(T3, OFstatic_cast(double, low) + (minvalue / OFstatic_cast(double, vlut->getAbsMaxRange())) * outrange);
00407 }
00408 OFBitmanipTemplate<T3>::setMem(Data, value, Count);
00409 } else {
00410 register T2 value = 0;
00411 const T2 absmin = OFstatic_cast(T2, inter->getAbsMinimum());
00412 const T2 firstentry = vlut->getFirstEntry(value);
00413 const T2 lastentry = vlut->getLastEntry(value);
00414 const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());
00415 register const T1 *p = pixel + start;
00416 register T3 *q = Data;
00417 T3 *lut = NULL;
00418 if ((plut != NULL) && (plut->isValid()))
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;
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 {
00435 q = lut;
00436 if (dlut != NULL)
00437 {
00438 if (low > high)
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 {
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 {
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());
00480 q = Data;
00481 for (i = Count; i != 0; --i)
00482 *(q++) = *(lut0 + (*(p++)));
00483 }
00484 if (lut == NULL)
00485 {
00486 if (dlut != NULL)
00487 {
00488 if (low > high)
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++));
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 {
00503 for (i = Count; i != 0; --i)
00504 {
00505 value = OFstatic_cast(T2, *(p++));
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 {
00516 const double gradient2 = outrange / OFstatic_cast(double, plut->getAbsMaxRange());
00517 for (i = Count; i != 0; --i)
00518 {
00519 value = OFstatic_cast(T2, *(p++));
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 {
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 {
00537 q = lut;
00538 if (dlut != NULL)
00539 {
00540 if (low > high)
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 {
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 {
00564 for (i = 0; i < ocnt; ++i)
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());
00576 q = Data;
00577 for (i = Count; i != 0; --i)
00578 *(q++) = *(lut0 + (*(p++)));
00579 }
00580 if (lut == NULL)
00581 {
00582 if (dlut != NULL)
00583 {
00584 if (low > high)
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 {
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 {
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);
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)
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());
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()))
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;
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 {
00684 q = lut;
00685 if (dlut != NULL)
00686 {
00687 if (low > high)
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 {
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 {
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());
00710 q = Data;
00711 for (i = Count; i != 0; --i)
00712 *(q++) = *(lut0 + (*(p++)));
00713 }
00714 if (lut == NULL)
00715 {
00716 if (dlut != NULL)
00717 {
00718 if (low > high)
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 {
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 {
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 {
00742 createDisplayLUT(dlut, disp, inter->getBits());
00743 register const double gradient = outrange / (inter->getAbsMaxRange());
00744 if (initOptimizationLUT(lut, ocnt))
00745 {
00746 q = lut;
00747 if (dlut != NULL)
00748 {
00749 if (low > high)
00750 {
00751 for (i = ocnt; i != 0; --i)
00752 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, i - 1)));
00753 } else {
00754 for (i = 0; i < ocnt; ++i)
00755 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, i)));
00756 }
00757 } else {
00758 for (i = 0; i < ocnt; ++i)
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());
00762 q = Data;
00763 for (i = Count; i != 0; --i)
00764 *(q++) = *(lut0 + (*(p++)));
00765 }
00766 if (lut == NULL)
00767 {
00768 if (dlut != NULL)
00769 {
00770 if (low > high)
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 {
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 {
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);
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];
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;
00831 const double rightBorder = center - 0.5 + width_1 / 2;
00832 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low);
00833 const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());
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()))
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;
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 {
00855 q = lut;
00856 if (dlut != NULL)
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;
00864 if (value <= leftBorder)
00865 value2 = 0;
00866 else if (value > rightBorder)
00867 value2 = pcnt - 1;
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 {
00873 const double gradient2 = outrange / plutmax_1;
00874 for (i = 0; i < ocnt; ++i)
00875 {
00876 value = OFstatic_cast(double, i) + absmin;
00877 if (value <= leftBorder)
00878 value2 = 0;
00879 else if (value > rightBorder)
00880 value2 = pcnt - 1;
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);
00887 q = Data;
00888 for (i = Count; i != 0; --i)
00889 *(q++) = *(lut0 + (*(p++)));
00890 }
00891 if (lut == NULL)
00892 {
00893 if (dlut != NULL)
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++));
00901 if (value <= leftBorder)
00902 value2 = 0;
00903 else if (value > rightBorder)
00904 value2 = pcnt - 1;
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 {
00910 const double gradient2 = outrange / plutmax_1;
00911 for (i = Count; i != 0; --i)
00912 {
00913 value = OFstatic_cast(double, *(p++));
00914 if (value <= leftBorder)
00915 value2 = 0;
00916 else if (value > rightBorder)
00917 value2 = pcnt - 1;
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 {
00925 createDisplayLUT(dlut, disp, bitsof(T1));
00926 if (initOptimizationLUT(lut, ocnt))
00927 {
00928 q = lut;
00929 if (dlut != NULL)
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)
00935 {
00936 value = OFstatic_cast(double, i) + absmin - leftBorder;
00937 if (value < 0)
00938 value = 0;
00939 else if (value > width_1)
00940 value = width_1;
00941 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + value * gradient)));
00942 }
00943 } else {
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)
00947 {
00948 value = OFstatic_cast(double, i) + absmin;
00949 if (value <= leftBorder)
00950 *(q++) = low;
00951 else if (value > rightBorder)
00952 *(q++) = high;
00953 else
00954 *(q++) = OFstatic_cast(T3, offset + value * gradient);
00955 }
00956 }
00957 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
00958 q = Data;
00959 for (i = Count; i != 0; --i)
00960 *(q++) = *(lut0 + (*(p++)));
00961 }
00962 if (lut == NULL)
00963 {
00964 if (dlut != NULL)
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)
00970 {
00971 value = OFstatic_cast(double, *(p++)) - leftBorder;
00972 if (value < 0)
00973 value = 0;
00974 else if (value > width_1)
00975 value = width_1;
00976 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + value * gradient)));
00977 }
00978 } else {
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;
00986 else if (value > rightBorder)
00987 *(q++) = high;
00988 else
00989 *(q++) = OFstatic_cast(T3, offset + value * gradient);
00990 }
00991 }
00992 }
00993 }
00994 delete[] lut;
00995 if (Count < FrameSize)
00996 OFBitmanipTemplate<T3>::zeroMem(Data + Count, FrameSize - Count);
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:
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
01162 DiMonoOutputPixel *ColorData;
01163 #endif
01164
01165
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
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356