33 #include "dcmtk/config/osconfig.h" 35 #include "dcmtk/ofstd/ofcast.h" 36 #include "dcmtk/ofstd/ofbmanip.h" 38 #include "dcmtk/dcmimgle/dimoopx.h" 39 #include "dcmtk/dcmimgle/dimopx.h" 40 #include "dcmtk/dcmimgle/diluptab.h" 41 #include "dcmtk/dcmimgle/diovlay.h" 42 #include "dcmtk/dcmimgle/dipxrept.h" 43 #include "dcmtk/dcmimgle/didispfn.h" 44 #include "dcmtk/dcmimgle/didislut.h" 46 #ifdef PASTEL_COLOR_OUTPUT 51 #include "dcmtk/ofstd/ofstdinc.h" 60 template<
class T1,
class T2,
class T3>
93 const EF_VoiLutFunction vfunc,
100 const unsigned long frame,
101 #ifdef PASTEL_COLOR_OUTPUT
102 const unsigned long frames,
104 const unsigned long ,
106 const int pastel = 0)
107 :
DiMonoOutputPixel(pixel, OFstatic_cast(unsigned long, columns) * OFstatic_cast(unsigned long, rows), frame,
108 OFstatic_cast(unsigned long, fabs(OFstatic_cast(double, high - low)))),
116 #ifdef PASTEL_COLOR_OUTPUT 117 color(buffer, pixel, frame, frames);
119 DCMIMGLE_ERROR(
"pastel color output not supported");
123 DCMIMGLE_TRACE(
"monochrome output image - columns: " << columns <<
", rows: " << rows <<
", frame: " << frame);
124 DCMIMGLE_TRACE(
"monochrome output values - low: " << OFstatic_cast(
unsigned long, low) <<
", high: " 125 << OFstatic_cast(
unsigned long, high) << ((low > high) ?
" (inverted)" :
""));
126 Data = OFstatic_cast(T3 *, buffer);
127 if ((vlut != NULL) && (vlut->
isValid()))
128 voilut(pixel, frame *
FrameSize, vlut, plut, disp, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
132 nowindow(pixel, frame * FrameSize, plut, disp, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
133 else if (vfunc == EFV_Sigmoid)
134 sigmoid(pixel, frame * FrameSize, plut, disp, center, width, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
136 window(pixel, frame * FrameSize, plut, disp, center, width, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
138 overlay(overlays, disp, columns, rows, frame);
167 return (ColorData != NULL) ? ColorData->
getItemSize() :
sizeof(T3);
176 return (ColorData != NULL) ? ColorData->
getData() : OFstatic_cast(
const void *,
Data);
185 return (ColorData != NULL) ? ColorData->
getDataPtr() : OFstatic_cast(
void *,
Data);
202 inline int writePPM(STD_NAMESPACE ostream& stream)
const 206 register unsigned long i;
208 stream << OFstatic_cast(
unsigned long,
Data[i]) <<
" ";
211 if (ColorData != NULL)
226 register unsigned long i;
228 fprintf(stream,
"%lu ", OFstatic_cast(
unsigned long,
Data[i]));
231 if (ColorData != NULL)
249 register const T3 *p =
Data;
251 register unsigned long i;
252 for (i =
Count; i != 0; --i)
271 if ((disp != NULL) && (disp->
isValid()))
274 if ((dlut != NULL) && (dlut->
isValid()))
276 DCMIMGLE_DEBUG(
"using display transformation");
278 DCMIMGLE_WARN(
"can't create display LUT ... ignoring display transformation");
290 const unsigned long ocnt)
293 if ((
sizeof(T1) <= 2) && (
Count > 3 * ocnt))
298 DCMIMGLE_DEBUG(
"using optimized routine with additional LUT (" << ocnt <<
" entries)");
305 #ifdef PASTEL_COLOR_OUTPUT 306 void color(
void *buffer,
308 const unsigned long frame,
309 const unsigned long frames)
311 ColorData =
new DiMonoColorOutputPixelTemplate<T1, T3>(buffer, inter, frame, frames);
312 if (ColorData != NULL)
313 DCMIMGLE_DEBUG(
">>> COLOR <<<");
335 const T1 *pixel = OFstatic_cast(
const T1 *, inter->
getData());
336 if ((pixel != NULL) && (vlut != NULL))
342 DCMIMGLE_DEBUG(
"applying VOI transformation with LUT (" << vlut->
getCount() <<
" entries)");
345 const double outrange = OFstatic_cast(
double, high) - OFstatic_cast(
double, low) + 1;
346 register unsigned long i;
350 if ((plut != NULL) && (plut->
isValid()))
352 DCMIMGLE_DEBUG(
"applying presentation LUT transformation");
354 const Uint32 value2 = OFstatic_cast(Uint32, (minvalue / OFstatic_cast(
double, vlut->
getAbsMaxRange())) * plut->
getCount());
357 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #1 - UNTESTED");
359 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, plut->
getAbsMaxRange() - plut->
getValue(value2) - 1)));
361 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, plut->
getValue(value2))));
363 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #2");
364 value = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value2)) * outrange / OFstatic_cast(
double, plut->
getAbsMaxRange()));
370 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #3 - UNTESTED");
372 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, vlut->
getAbsMaxRange() - minvalue - 1)));
374 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, minvalue)));
376 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #4");
377 value = OFstatic_cast(T3, OFstatic_cast(
double, low) + (minvalue / OFstatic_cast(
double, vlut->
getAbsMaxRange())) * outrange);
382 register T2 value = 0;
386 const unsigned long ocnt = OFstatic_cast(
unsigned long, inter->
getAbsMaxRange());
387 register const T1 *p = pixel + start;
388 register T3 *q =
Data;
390 if ((plut != NULL) && (plut->
isValid()))
392 DCMIMGLE_DEBUG(
"applying presentation LUT transformation");
394 register Uint32 value2;
395 const Uint32 pcnt = plut->
getCount();
396 const double gradient1 = OFstatic_cast(
double, pcnt) / OFstatic_cast(
double, vlut->
getAbsMaxRange());
397 const Uint32 firstvalue = OFstatic_cast(Uint32, OFstatic_cast(
double, vlut->
getFirstValue()) * gradient1);
398 const Uint32 lastvalue = OFstatic_cast(Uint32, OFstatic_cast(
double, vlut->
getLastValue()) * gradient1);
404 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #5");
407 const Uint16 maxvalue = OFstatic_cast(Uint16, plut->
getAbsMaxRange() - 1);
408 for (i = 0; i < ocnt; ++i)
410 value = OFstatic_cast(T2, i) + absmin;
411 if (value <= firstentry)
413 else if (value >= lastentry)
416 value2 = OFstatic_cast(Uint32, OFstatic_cast(
double, vlut->
getValue(value)) * gradient1);
417 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->
getValue(value2))));
420 for (i = 0; i < ocnt; ++i)
422 value = OFstatic_cast(T2, i) + absmin;
423 if (value <= firstentry)
425 else if (value >= lastentry)
428 value2 = OFstatic_cast(Uint32, OFstatic_cast(
double, vlut->
getValue(value)) * gradient1);
429 *(q++) = OFstatic_cast(T3, dlut->getValue(plut->
getValue(value2)));
433 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #6");
434 const double gradient2 = outrange / OFstatic_cast(
double, plut->
getAbsMaxRange());
435 for (i = 0; i < ocnt; ++i)
437 value = OFstatic_cast(T2, i) + absmin;
438 if (value <= firstentry)
440 else if (value >= lastentry)
443 value2 = OFstatic_cast(Uint32, OFstatic_cast(
double, vlut->
getValue(value)) * gradient1);
444 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value2)) * gradient2);
447 const T3 *lut0 = lut - OFstatic_cast(T2, inter->
getAbsMinimum());
449 for (i =
Count; i != 0; --i)
450 *(q++) = *(lut0 + (*(p++)));
456 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #7");
459 const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->
getAbsMaxRange() - 1);
460 for (i =
Count; i != 0; --i)
462 value = OFstatic_cast(T2, *(p++));
463 if (value <= firstentry)
465 else if (value >= lastentry)
468 value2 = OFstatic_cast(Uint32, OFstatic_cast(
double, vlut->
getValue(value)) * gradient1);
469 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->
getValue(value2))));
472 for (i =
Count; i != 0; --i)
474 value = OFstatic_cast(T2, *(p++));
475 if (value <= firstentry)
477 else if (value >= lastentry)
480 value2 = OFstatic_cast(Uint32, OFstatic_cast(
double, vlut->
getValue(value)) * gradient1);
481 *(q++) = OFstatic_cast(T3, dlut->getValue(plut->
getValue(value2)));
485 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #8");
486 const double gradient2 = outrange / OFstatic_cast(
double, plut->
getAbsMaxRange());
487 for (i =
Count; i != 0; --i)
489 value = OFstatic_cast(T2, *(p++));
490 if (value <= firstentry)
492 else if (value >= lastentry)
495 value2 = OFstatic_cast(Uint32, OFstatic_cast(
double, vlut->
getValue(value)) * gradient1);
496 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value2)) * gradient2);
502 const double gradient = outrange / OFstatic_cast(
double, vlut->
getAbsMaxRange());
503 const T3 firstvalue = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, vlut->
getFirstValue()) * gradient);
504 const T3 lastvalue = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, vlut->
getLastValue()) * gradient);
510 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #9");
513 const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->
getAbsMaxRange() - 1);
514 for (i = 0; i < ocnt; ++i)
516 value = OFstatic_cast(T2, i) + absmin;
517 if (value < firstentry)
519 else if (value > lastentry)
521 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - vlut->
getValue(value))));
524 for (i = 0; i < ocnt; ++i)
526 value = OFstatic_cast(T2, i) + absmin;
527 if (value < firstentry)
529 else if (value > lastentry)
531 *(q++) = OFstatic_cast(T3, dlut->getValue(vlut->
getValue(value)));
535 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #10");
536 for (i = 0; i < ocnt; ++i)
538 value = OFstatic_cast(T2, i) + absmin;
539 if (value <= firstentry)
541 else if (value >= lastentry)
544 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, vlut->
getValue(value)) * gradient);
547 const T3 *lut0 = lut - OFstatic_cast(T2, inter->
getAbsMinimum());
549 for (i =
Count; i != 0; --i)
550 *(q++) = *(lut0 + (*(p++)));
556 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #11");
559 const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->
getAbsMaxRange() - 1);
560 for (i =
Count; i != 0; --i)
562 value = OFstatic_cast(T2, *(p++));
563 if (value < firstentry)
565 else if (value > lastentry)
567 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - vlut->
getValue(value))));
570 for (i =
Count; i != 0; --i)
572 value = OFstatic_cast(T2, *(p++));
573 if (value < firstentry)
575 else if (value > lastentry)
577 *(q++) = OFstatic_cast(T3, dlut->getValue(vlut->
getValue(value)));
581 DCMIMGLE_TRACE(
"monochrome rendering: VOI LUT #12");
582 for (i = 0; i <
Count; ++i)
584 value = OFstatic_cast(T2, *(p++));
585 if (value <= firstentry)
587 else if (value >= lastentry)
590 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, vlut->
getValue(value)) * gradient);
621 const T1 *pixel = OFstatic_cast(
const T1 *, inter->
getData());
628 DCMIMGLE_DEBUG(
"applying no VOI transformation (linear scaling)");
631 const double outrange = OFstatic_cast(
double, high) - OFstatic_cast(
double, low) + 1;
632 const unsigned long ocnt = OFstatic_cast(
unsigned long, inter->
getAbsMaxRange());
633 register const T1 *p = pixel + start;
634 register T3 *q =
Data;
635 register unsigned long i;
637 if ((plut != NULL) && (plut->
isValid()))
639 DCMIMGLE_DEBUG(
"applying presentation LUT transformation");
641 register Uint32 value;
643 const double gradient2 = outrange / OFstatic_cast(
double, plut->
getAbsMaxRange());
649 DCMIMGLE_TRACE(
"monochrome rendering: VOI NONE #1");
652 const Uint16 maxvalue = OFstatic_cast(Uint16, plut->
getAbsMaxRange() - 1);
653 for (i = 0; i < ocnt; ++i)
655 value = OFstatic_cast(Uint32, OFstatic_cast(
double, i) * gradient1);
656 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, maxvalue - plut->
getValue(value))));
659 for (i = 0; i < ocnt; ++i)
661 value = OFstatic_cast(Uint32, OFstatic_cast(
double, i) * gradient1);
666 DCMIMGLE_TRACE(
"monochrome rendering: VOI NONE #2");
667 for (i = 0; i < ocnt; ++i)
669 value = OFstatic_cast(Uint32, OFstatic_cast(
double, i) * gradient1);
670 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value)) * gradient2);
673 const T3 *lut0 = lut - OFstatic_cast(T2, inter->
getAbsMinimum());
675 for (i =
Count; i != 0; --i)
676 *(q++) = *(lut0 + (*(p++)));
682 DCMIMGLE_TRACE(
"monochrome rendering: VOI NONE #3");
685 const Uint16 maxvalue = OFstatic_cast(Uint16, plut->
getAbsMaxRange() - 1);
686 for (i =
Count; i != 0; --i)
688 value = OFstatic_cast(Uint32, (OFstatic_cast(
double, *(p++)) - absmin) * gradient1);
689 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, maxvalue - plut->
getValue(value))));
692 for (i =
Count; i != 0; --i)
694 value = OFstatic_cast(Uint32, (OFstatic_cast(
double, *(p++)) - absmin) * gradient1);
699 DCMIMGLE_TRACE(
"monochrome rendering: VOI NONE #4");
700 for (i =
Count; i != 0; --i)
702 value = OFstatic_cast(Uint32, (OFstatic_cast(
double, *(p++)) - absmin) * gradient1);
703 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value)) * gradient2);
709 register const double gradient = outrange / (inter->
getAbsMaxRange());
715 DCMIMGLE_TRACE(
"monochrome rendering: VOI NONE #5");
718 for (i = ocnt; i != 0; --i)
719 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, i - 1)));
721 for (i = 0; i < ocnt; ++i)
722 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, i)));
725 DCMIMGLE_TRACE(
"monochrome rendering: VOI NONE #6");
726 for (i = 0; i < ocnt; ++i)
727 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, i) * gradient);
729 const T3 *lut0 = lut - OFstatic_cast(T2, inter->
getAbsMinimum());
731 for (i =
Count; i != 0; --i)
732 *(q++) = *(lut0 + (*(p++)));
738 DCMIMGLE_TRACE(
"monochrome rendering: VOI NONE #7");
741 for (i =
Count; i != 0; --i)
742 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, absmax - (OFstatic_cast(
double, *(p++)) - absmin))));
744 for (i =
Count; i != 0; --i)
745 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, OFstatic_cast(
double, *(p++)) - absmin)));
748 DCMIMGLE_TRACE(
"monochrome rendering: VOI NONE #8");
749 for (i =
Count; i != 0; --i)
750 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + (OFstatic_cast(
double, *(p++)) - absmin) * gradient);
782 const T1 *pixel = OFstatic_cast(
const T1 *, inter->
getData());
789 DCMIMGLE_DEBUG(
"applying sigmoid VOI transformation with window center = " << center <<
", width = " << width);
792 const double outrange = OFstatic_cast(
double, high) - OFstatic_cast(
double, low);
793 const unsigned long ocnt = OFstatic_cast(
unsigned long, inter->
getAbsMaxRange());
794 register const T1 *p = pixel + start;
795 register T3 *q =
Data;
796 register unsigned long i;
797 register double value;
799 if ((plut != NULL) && (plut->
isValid()))
801 DCMIMGLE_DEBUG(
"applying presentation LUT transformation");
803 register Uint32 value2;
804 const double plutcnt_1 = OFstatic_cast(
double, plut->
getCount() - 1);
805 const double plutmax_1 = OFstatic_cast(
double, plut->
getAbsMaxRange() - 1);
811 DCMIMGLE_TRACE(
"monochrome rendering: VOI SIGMOID #1");
812 const double maxvalue = OFstatic_cast(
double, dlut->
getCount() - 1);
813 const double offset = (low > high) ? maxvalue : 0;
814 const double gradient = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1);
815 for (i = 0; i < ocnt; ++i)
817 value = OFstatic_cast(
double, i) + absmin;
818 value2 = OFstatic_cast(Uint32, plutcnt_1 / (1 + exp(-4 * (value - center) / width)));
819 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(
double, plut->
getValue(value2)) * gradient)));
822 DCMIMGLE_TRACE(
"monochrome rendering: VOI SIGMOID #2");
823 const double gradient = outrange / plutmax_1;
824 for (i = 0; i < ocnt; ++i)
826 value = OFstatic_cast(
double, i) + absmin;
827 value2 = OFstatic_cast(Uint32, plutcnt_1 / (1 + exp(-4 * (value - center) / width)));
828 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value2)) * gradient);
831 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
833 for (i =
Count; i != 0; --i)
834 *(q++) = *(lut0 + (*(p++)));
840 DCMIMGLE_TRACE(
"monochrome rendering: VOI SIGMOID #3");
841 const double maxvalue = OFstatic_cast(
double, dlut->
getCount() - 1);
842 const double offset = (low > high) ? maxvalue : 0;
843 const double gradient = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1);
844 for (i =
Count; i != 0; --i)
846 value = OFstatic_cast(
double, *(p++));
847 value2 = OFstatic_cast(Uint32, plutcnt_1 / (1 + exp(-4 * (value - center) / width)));
848 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(
double, plut->
getValue(value2)) * gradient)));
851 DCMIMGLE_TRACE(
"monochrome rendering: VOI SIGMOID #4");
852 const double gradient = outrange / plutmax_1;
853 for (i =
Count; i != 0; --i)
855 value = OFstatic_cast(
double, *(p++));
856 value2 = OFstatic_cast(Uint32, plutcnt_1 / (1 + exp(-4 * (value - center) / width)));
857 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value2)) * gradient);
868 DCMIMGLE_TRACE(
"monochrome rendering: VOI SIGMOID #5");
869 const double maxvalue = OFstatic_cast(
double, dlut->
getCount() - 1);
870 const double outrange2 = (low > high) ? -maxvalue : maxvalue;
871 const double offset = (low > high) ? maxvalue : 0;
872 for (i = 0; i < ocnt; ++i)
874 value = OFstatic_cast(
double, i) + absmin;
875 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, offset + outrange2 / (1 + exp(-4 * (value - center) / width)))));
878 DCMIMGLE_TRACE(
"monochrome rendering: VOI SIGMOID #6");
879 for (i = 0; i < ocnt; ++i)
881 value = OFstatic_cast(
double, i) + absmin;
882 *(q++) = OFstatic_cast(T3, outrange / (1 + exp(-4 * (value - center) / width)));
885 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
887 for (i =
Count; i != 0; --i)
888 *(q++) = *(lut0 + (*(p++)));
894 DCMIMGLE_TRACE(
"monochrome rendering: VOI SIGMOID #7");
895 const double maxvalue = OFstatic_cast(
double, dlut->
getCount() - 1);
896 const double outrange2 = (low > high) ? -maxvalue : maxvalue;
897 const double offset = (low > high) ? maxvalue : 0;
898 for (i =
Count; i != 0; --i)
900 value = OFstatic_cast(
double, *(p++));
901 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, offset + outrange2 / (1 + exp(-4 * (value - center) / width)))));
904 DCMIMGLE_TRACE(
"monochrome rendering: VOI SIGMOID #8");
905 for (i =
Count; i != 0; --i)
907 value = OFstatic_cast(
double, *(p++));
908 *(q++) = OFstatic_cast(T3, outrange / (1 + exp(-4 * (value - center) / width)));
941 const T1 *pixel = OFstatic_cast(
const T1 *, inter->
getData());
948 DCMIMGLE_DEBUG(
"applying linear VOI transformation with window center = " << center <<
", width = " << width);
951 const double width_1 = width - 1;
952 const double leftBorder = center - 0.5 - width_1 / 2;
953 const double rightBorder = center - 0.5 + width_1 / 2;
954 const double outrange = OFstatic_cast(
double, high) - OFstatic_cast(
double, low);
955 const unsigned long ocnt = OFstatic_cast(
unsigned long, inter->
getAbsMaxRange());
956 register const T1 *p = pixel + start;
957 register T3 *q =
Data;
958 register unsigned long i;
959 register double value;
961 if ((plut != NULL) && (plut->
isValid()))
963 DCMIMGLE_DEBUG(
"applying presentation LUT transformation");
965 register Uint32 value2;
966 const Uint32 pcnt = plut->
getCount();
967 const double plutmax_1 = OFstatic_cast(
double, plut->
getAbsMaxRange()) - 1;
968 const double gradient1 = (width_1 == 0) ? 0 : OFstatic_cast(
double, pcnt - 1) / width_1;
974 DCMIMGLE_TRACE(
"monochrome rendering: VOI LINEAR #1");
975 const double maxvalue = OFstatic_cast(
double, dlut->
getCount() - 1);
976 const double offset = (low > high) ? maxvalue : 0;
977 const double gradient2 = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1);
978 for (i = 0; i < ocnt; ++i)
980 value = OFstatic_cast(
double, i) + absmin;
981 if (value <= leftBorder)
983 else if (value > rightBorder)
986 value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1);
987 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(
double, plut->
getValue(value2)) * gradient2)));
990 DCMIMGLE_TRACE(
"monochrome rendering: VOI LINEAR #2");
991 const double gradient2 = outrange / plutmax_1;
992 for (i = 0; i < ocnt; ++i)
994 value = OFstatic_cast(
double, i) + absmin;
995 if (value <= leftBorder)
997 else if (value > rightBorder)
1000 value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1);
1001 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value2)) * gradient2);
1004 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
1006 for (i =
Count; i != 0; --i)
1007 *(q++) = *(lut0 + (*(p++)));
1013 DCMIMGLE_TRACE(
"monochrome rendering: VOI LINEAR #3");
1014 const double maxvalue = OFstatic_cast(
double, dlut->
getCount() - 1);
1015 const double offset = (low > high) ? maxvalue : 0;
1016 const double gradient2 = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1);
1017 for (i =
Count; i != 0; --i)
1019 value = OFstatic_cast(
double, *(p++));
1020 if (value <= leftBorder)
1022 else if (value > rightBorder)
1025 value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1);
1026 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(
double, plut->
getValue(value2)) * gradient2)));
1029 DCMIMGLE_TRACE(
"monochrome rendering: VOI LINEAR #4");
1030 const double gradient2 = outrange / plutmax_1;
1031 for (i =
Count; i != 0; --i)
1033 value = OFstatic_cast(
double, *(p++));
1034 if (value <= leftBorder)
1036 else if (value > rightBorder)
1039 value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1);
1040 *(q++) = OFstatic_cast(T3, OFstatic_cast(
double, low) + OFstatic_cast(
double, plut->
getValue(value2)) * gradient2);
1051 DCMIMGLE_TRACE(
"monochrome rendering: VOI LINEAR #5");
1052 const double maxvalue = OFstatic_cast(
double, dlut->
getCount() - 1);
1053 const double offset = (low > high) ? maxvalue : 0;
1054 const double gradient = (width_1 == 0) ? 0 : ((low > high) ? (-maxvalue / width_1) : (maxvalue / width_1));
1055 for (i = 0; i < ocnt; ++i)
1057 value = OFstatic_cast(
double, i) + absmin - leftBorder;
1060 else if (value > width_1)
1062 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, offset + value * gradient)));
1065 DCMIMGLE_TRACE(
"monochrome rendering: VOI LINEAR #6");
1066 const double offset = (width_1 == 0) ? 0 : (high - ((center - 0.5) / width_1 + 0.5) * outrange);
1067 const double gradient = (width_1 == 0) ? 0 : outrange / width_1;
1068 for (i = 0; i < ocnt; ++i)
1070 value = OFstatic_cast(
double, i) + absmin;
1071 if (value <= leftBorder)
1073 else if (value > rightBorder)
1076 *(q++) = OFstatic_cast(T3, offset + value * gradient);
1079 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
1081 for (i =
Count; i != 0; --i)
1082 *(q++) = *(lut0 + (*(p++)));
1088 DCMIMGLE_TRACE(
"monochrome rendering: VOI LINEAR #7");
1089 const double maxvalue = OFstatic_cast(
double, dlut->
getCount() - 1);
1090 const double offset = (low > high) ? maxvalue : 0;
1091 const double gradient = (width_1 == 0) ? 0 : ((low > high) ? (-maxvalue / width_1) : (maxvalue / width_1));
1092 for (i =
Count; i != 0; --i)
1094 value = OFstatic_cast(
double, *(p++)) - leftBorder;
1097 else if (value > width_1)
1099 *(q++) = OFstatic_cast(T3, dlut->
getValue(OFstatic_cast(Uint16, offset + value * gradient)));
1102 DCMIMGLE_TRACE(
"monochrome rendering: VOI LINEAR #8");
1103 const double offset = (width_1 == 0) ? 0 : (high - ((center - 0.5) / width_1 + 0.5) * outrange);
1104 const double gradient = (width_1 == 0) ? 0 : outrange / width_1;
1105 for (i =
Count; i != 0; --i)
1107 value = OFstatic_cast(
double, *(p++));
1108 if (value <= leftBorder)
1110 else if (value > rightBorder)
1113 *(q++) = OFstatic_cast(T3, offset + value * gradient);
1137 const Uint16 columns,
1139 const unsigned long frame)
1141 if ((
Data != NULL) && (overlays != NULL))
1143 for (
unsigned int j = 0; j < 2; ++j)
1145 if (overlays[j] != NULL)
1148 DCMIMGLE_DEBUG(
"applying " << ((j == 0) ?
"built-in" :
"additional") <<
" overlay planes");
1149 const signed long left_pos = overlays[j]->
getLeft();
1150 const signed long top_pos = overlays[j]->
getTop();
1152 for (
unsigned int i = 0; i < overlays[j]->
getCount(); ++i)
1154 plane = overlays[j]->getPlane(i);
1155 if ((plane != NULL) && plane->
isVisible() && plane->
reset(frame))
1160 const Uint16 xmin = (plane->
getLeft(left_pos) > 0) ? plane->
getLeft(left_pos) : 0;
1161 const Uint16 ymin = (plane->
getTop(top_pos) > 0) ? plane->
getTop(top_pos) : 0;
1162 const Uint16 xmax = (plane->
getRight(left_pos) < columns) ? plane->
getRight(left_pos) : columns;
1163 const Uint16 ymax = (plane->
getBottom(top_pos) < rows) ? plane->
getBottom(top_pos) : rows;
1169 DCMIMGLE_DEBUG(
"applying overlay plane " << (i + 1) <<
" with 'replace' mode");
1170 const T3 fore = OFstatic_cast(T3, plane->
getForeground() * maxvalue);
1171 for (y = ymin; y < ymax; ++y)
1173 plane->
setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
1174 q =
Data + OFstatic_cast(
unsigned long, y) * OFstatic_cast(
unsigned long, columns) + OFstatic_cast(
unsigned long, xmin);
1175 for (x = xmin; x < xmax; ++x, ++q)
1183 case EMO_ThresholdReplace:
1185 DCMIMGLE_DEBUG(
"applying overlay plane " << (i + 1) <<
" with 'threshold replace' mode");
1186 const T3 fore = OFstatic_cast(T3, plane->
getForeground() * maxvalue);
1187 const T3 thresh = OFstatic_cast(T3, plane->
getThreshold() * maxvalue);
1188 for (y = ymin; y < ymax; ++y)
1190 plane->
setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
1191 q =
Data + OFstatic_cast(
unsigned long, y) * OFstatic_cast(
unsigned long, columns) + OFstatic_cast(
unsigned long, xmin);
1192 for (x = xmin; x < xmax; ++x, ++q)
1195 *q = (*q <= thresh) ? fore : 1;
1200 case EMO_Complement:
1202 DCMIMGLE_DEBUG(
"applying overlay plane " << (i + 1) <<
" with 'complement' mode");
1204 for (y = ymin; y < ymax; ++y)
1206 plane->
setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
1207 q =
Data + OFstatic_cast(
unsigned long, y) * OFstatic_cast(
unsigned long, columns) + OFstatic_cast(
unsigned long, xmin);
1208 for (x = xmin; x < xmax; ++x, ++q)
1211 *q = (*q <= thresh) ? maxvalue : 0;
1216 case EMO_InvertBitmap:
1218 DCMIMGLE_DEBUG(
"applying overlay plane " << (i + 1) <<
" with 'invert bitmap' mode");
1219 const T3 fore = OFstatic_cast(T3, plane->
getForeground() * maxvalue);
1220 for (y = ymin; y < ymax; ++y)
1222 plane->
setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
1223 q =
Data + OFstatic_cast(
unsigned long, y) * OFstatic_cast(
unsigned long, columns) + OFstatic_cast(
unsigned long, xmin);
1224 for (x = xmin; x < xmax; ++x, ++q)
1232 case EMO_RegionOfInterest:
1234 DCMIMGLE_DEBUG(
"applying overlay plane " << (i + 1) <<
" with 'region of interest' mode");
1235 const int dim = bitsof(T3) / 2;
1236 for (y = ymin; y < ymax; ++y)
1238 plane->
setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
1239 q =
Data + OFstatic_cast(
unsigned long, y) * OFstatic_cast(
unsigned long, columns) + OFstatic_cast(
unsigned long, xmin);
1240 for (x = xmin; x < xmax; ++x, ++q)
1248 case EMO_BitmapShutter:
1250 DCMIMGLE_DEBUG(
"applying overlay plane " << (i + 1) <<
" with 'bitmap shutter' mode");
1251 register T3 fore = OFstatic_cast(T3, OFstatic_cast(
double, maxvalue) * OFstatic_cast(
double, plane->
getPValue()) / OFstatic_cast(
double,
DicomImageClass::maxval(WIDTH_OF_PVALUES)));
1252 if ((disp != NULL) && (disp->
isValid()))
1255 if ((dlut != NULL) && (dlut->
isValid()))
1258 for (y = ymin; y < ymax; ++y)
1260 plane->
setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
1261 q =
Data + OFstatic_cast(
unsigned long, y) * OFstatic_cast(
unsigned long, columns) + OFstatic_cast(
unsigned long, xmin);
1262 for (x = xmin; x < xmax; ++x, ++q)
1271 DCMIMGLE_WARN(
"unhandled overlay mode (" << OFstatic_cast(
int, plane->
getMode()) <<
")");
1286 #ifdef PASTEL_COLOR_OUTPUT 1287 DiMonoColorOutputPixelTemplate<T1, T3> *ColorData;
int initOptimizationLUT(T3 *&lut, const unsigned long ocnt)
initialize an optimization LUT if the optimization criteria is fulfilled
virtual const void * getData() const =0
get pointer to output pixel data (abstract)
unsigned int getCount() const
get number of overlay planes
int writePPM(STD_NAMESPACE ostream &stream) const
write pixel data of selected frame to PPM/ASCII file
Uint16 getMinValue() const
get minimum value of the LUT.
Abstract base class to handle monochrome pixel data.
void window(const DiMonoPixel *inter, const Uint32 start, const DiLookupTable *plut, DiDisplayFunction *disp, const double center, const double width, const T3 low, const T3 high)
apply the currently active linear VOI window to the output data
EP_Representation getRepresentation() const
get integer representation of output data
void overlay(DiOverlay *overlays[2], DiDisplayFunction *disp, const Uint16 columns, const Uint16 rows, const unsigned long frame)
apply the currently active overlay planes to the output data
void removeDataReference()
remove reference to (internally handled) pixel data (abstract)
Abstract base class to create monochrome output data.
EM_Overlay getMode() const
get overlay plane mode
Uint16 getPValue() const
get p-value of the plane.
virtual int writePPM(STD_NAMESPACE ostream &stream) const =0
write pixel data of selected frame to PPM/ASCII file (abstract)
double getThreshold() const
get threshold value of the plane
void setStart(const Uint16 x, const Uint16 y)
set internal 'cursor' to a specific position
double getAbsMaximum() const
get absolute maximum pixel value.
unsigned int getBits() const
get number of bits per pixel
Uint32 getAbsMaxRange() const
get absolute value range of the LUT entries.
int isVisible() const
check whether overlay plane is visible
void nowindow(const DiMonoPixel *inter, const Uint32 start, const DiLookupTable *plut, DiDisplayFunction *disp, const T3 low, const T3 high)
perform linear scaling to the output data (no windowing)
int isValid() const
check whether DisplayFunction is valid
DiMonoOutputPixelTemplate(void *buffer, const DiMonoPixel *pixel, DiOverlay *overlays[2], const DiLookupTable *vlut, const DiLookupTable *plut, DiDisplayFunction *disp, const EF_VoiLutFunction vfunc, const double center, const double width, const Uint32 low, const Uint32 high, const Uint16 columns, const Uint16 rows, const unsigned long frame, const unsigned long, const int pastel=0)
constructor
Uint32 getCount() const
get number of LUT entries
signed long getLeft() const
get current x-coordinate of overlay origin.
Class to compute and store the Display lookup table.
signed long getTop() const
get current y-coordinate of overlay origin.
void createDisplayLUT(const DiDisplayLUT *&dlut, DiDisplayFunction *disp, const int bits)
create a display LUT with the specified number of input bits
static void setMem(T *dest, const T value, const unsigned long count)
sets specified number of elements in destination memory to a defined value
Sint16 getTop(const Sint32 top_pos=0) const
get y-coordinate of overlay plane origin
const DiDisplayLUT * getLookupTable(const int bits, unsigned long count=0)
create look-up table with specified number of entries
Uint16 getLastValue() const
get value of last LUT entry.
int DeleteData
flag indicating whether the output data buffer should be deleted in the destructor ...
virtual const void * getData() const =0
get pointer to pixel data (abstract).
Uint16 getFirstValue() const
get value of first LUT entry.
Uint16 getRight(const Sint32 left_pos=0) const
get right border of overlay plane origin
Template class to determine pixel representation.
unsigned long getCount() const
get number of pixel per frame
static void zeroMem(T *dest, const unsigned long count)
sets specified number of elements in destination memory to zero
unsigned long Count
number of pixels per frame (intermediate representation)
Uint8 * UsedValues
array of used pixel values
void sigmoid(const DiMonoPixel *inter, const Uint32 start, const DiLookupTable *plut, DiDisplayFunction *disp, const double center, const double width, const T3 low, const T3 high)
apply the currently active sigmoid VOI window to the output data
Class to handle color palette look-up tables.
Uint16 getBits() const
get number of bits per entry
const void * getData() const
get pointer to output pixel data
void determineUsedValues()
examine which pixel values are actually used
int reset(const unsigned long frame)
reset internal 'cursor' to the beginning of the specified frame
int getNextBit()
get value of the current overlay plane bit and move 'cursor' to the next position ...
int writePPM(FILE *stream) const
write pixel data of selected frame to PPM/ASCII file
Class to handle hardcopy and softcopy device characteristics file and manage display LUTs (for calibr...
static unsigned long maxval(const int mv_bits, const unsigned long mv_pos=1)
calculate maximum value which could be stored in the specified number of bits
Class to handle a single overlay plane.
virtual void * getDataPtr()=0
get pointer to output pixel data (abstract)
size_t getItemSize() const
get size of one pixel / item in the pixel array
virtual size_t getItemSize() const =0
get size of one pixel / item in the pixel array (abstract)
double getAbsMaxRange() const
get absolute pixel range
Uint16 getMaxValue() const
get maximum value of the LUT.
Class to handle a set of overlay planes.
virtual ~DiMonoOutputPixelTemplate()
destructor
Sint16 getLeft(const Sint32 left_pos=0) const
get x-coordinate of overlay plane origin
int isValid() const
check whether LUT is valid
double getForeground() const
get foreground color of the plane
virtual EP_Representation getRepresentation() const
determine integer representation for template type T
const unsigned long MaxValue
maximum output value
Uint16 getBottom(const Sint32 top_pos=0) const
get bottom border of overlay plane origin
Uint16 getValue(const Uint16 pos) const
get value of specified LUT entry
const unsigned long FrameSize
number of pixels per frame (memory buffer size)
virtual void * getDataPtr()
get pointer to output pixel data
double getAbsMinimum() const
get absolute minimum pixel value.
Uint32 getLastEntry(const Uint32=0) const
get index of last LUT entry.
Template class to create monochrome output data.
T3 * Data
pointer to the storage area where the output data should be stored
Uint32 getFirstEntry(const Uint32=0) const
get index of first LUT entry.
void voilut(const DiMonoPixel *inter, const Uint32 start, const DiLookupTable *vlut, const DiLookupTable *plut, DiDisplayFunction *disp, const T3 low, const T3 high)
apply the currently active VOI LUT to the output data