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 "osconfig.h"
00038
#include "ofconsol.h"
00039
#include "ofcast.h"
00040
#include "dctypes.h"
00041
00042
#include "dimoopx.h"
00043
#include "diluptab.h"
00044
#include "diovlay.h"
00045
#include "dipxrept.h"
00046
#include "diutils.h"
00047
#include "didispfn.h"
00048
#include "didislut.h"
00049
00050
#ifdef PASTEL_COLOR_OUTPUT
00051
#include "dimcopxt.h"
00052
#endif
00053
00054
#define INCLUDE_CMATH
00055
#include "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_RegionOfInterest:
01088 {
01089
const int dim = bitsof(T3) / 2;
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 = *q >> dim;
01098 }
01099 }
01100
break;
01101 }
01102
case EMO_BitmapShutter:
01103 {
01104
register T3 fore = OFstatic_cast(T3, OFstatic_cast(
double, maxvalue) * OFstatic_cast(
double, plane->
getPValue()) / OFstatic_cast(
double, DicomImageClass::maxval(WIDTH_OF_PVALUES)));
01105
if ((disp != NULL) && (disp->
isValid()))
01106 {
01107
const DiDisplayLUT *dlut = disp->
getLookupTable(WIDTH_OF_PVALUES);
01108
if ((dlut != NULL) && (dlut->
isValid()))
01109 fore = OFstatic_cast(T3, dlut->
getValue(plane->
getPValue()));
01110 }
01111
for (y = ymin; y < ymax; ++y)
01112 {
01113 plane->
setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
01114 q =
Data + OFstatic_cast(
unsigned long, y) * OFstatic_cast(
unsigned long, columns) + OFstatic_cast(
unsigned long, xmin);
01115
for (x = xmin; x < xmax; ++x, ++q)
01116 {
01117
if (plane->
getNextBit())
01118 *q = fore;
01119 }
01120 }
01121
break;
01122 }
01123
default:
01124
if (
DicomImageClass::checkDebugLevel(DicomImageClass::DL_Warnings))
01125 {
01126 ofConsole.lockCerr() <<
"WARNING: unhandled overlay mode (" << OFstatic_cast(
int, plane->
getMode()) <<
") !" << endl;
01127 ofConsole.unlockCerr();
01128 }
01129 }
01130 }
01131 }
01132 }
01133 }
01134 }
01135 }
01136
01137
01139 T3 *
Data;
01141 int DeleteData;
01142
01143
#ifdef PASTEL_COLOR_OUTPUT
01144
DiMonoColorOutputPixelTemplate<T1, T3> *ColorData;
01145
#else
01146
01147
DiMonoOutputPixel *ColorData;
01148
#endif
01149
01150
01151
01152
DiMonoOutputPixelTemplate(
const DiMonoOutputPixelTemplate<T1,T2,T3> &);
01153
DiMonoOutputPixelTemplate<T1,T2,T3> &operator=(
const DiMonoOutputPixelTemplate<T1,T2,T3> &);
01154 };
01155
01156
01157
#endif
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
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