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 #ifndef DIMOIPXT_H
00031 #define DIMOIPXT_H
00032
00033 #include "dcmtk/config/osconfig.h"
00034
00035 #include "dcmtk/ofstd/ofbmanip.h"
00036 #include "dcmtk/ofstd/ofcast.h"
00037
00038 #include "dcmtk/dcmimgle/dimopxt.h"
00039 #include "dcmtk/dcmimgle/diinpx.h"
00040
00041
00042
00043
00044
00045
00048 template<class T1, class T2, class T3>
00049 class DiMonoInputPixelTemplate
00050 : public DiMonoPixelTemplate<T3>
00051 {
00052
00053 public:
00054
00060 DiMonoInputPixelTemplate(DiInputPixel *pixel,
00061 DiMonoModality *modality)
00062 : DiMonoPixelTemplate<T3>(pixel, modality)
00063 {
00064
00065 if ((this->Data != NULL) && (this->InputCount < this->Count))
00066 OFBitmanipTemplate<T3>::zeroMem(this->Data + this->InputCount, this->Count - this->InputCount);
00067 if ((pixel != NULL) && (this->Count > 0))
00068 {
00069
00070 if ((this->Modality != NULL) && this->Modality->hasLookupTable() && (bitsof(T1) <= MAX_TABLE_ENTRY_SIZE))
00071 {
00072 modlut(pixel);
00073
00074 this->determineMinMax();
00075 }
00076 else if ((this->Modality != NULL) && this->Modality->hasRescaling())
00077 {
00078 rescale(pixel, this->Modality->getRescaleSlope(), this->Modality->getRescaleIntercept());
00079 determineMinMax(OFstatic_cast(T3, this->Modality->getMinValue()), OFstatic_cast(T3, this->Modality->getMaxValue()));
00080 } else {
00081 rescale(pixel);
00082 determineMinMax(OFstatic_cast(T3, this->Modality->getMinValue()), OFstatic_cast(T3, this->Modality->getMaxValue()));
00083 }
00084 }
00085 }
00086
00089 virtual ~DiMonoInputPixelTemplate()
00090 {
00091 }
00092
00093
00094 private:
00095
00103 inline int initOptimizationLUT(T3 *&lut,
00104 const unsigned long ocnt)
00105 {
00106 int result = 0;
00107 if ((sizeof(T1) <= 2) && (this->InputCount > 3 * ocnt))
00108 {
00109 lut = new T3[ocnt];
00110 if (lut != NULL)
00111 {
00112 DCMIMGLE_DEBUG("using optimized routine with additional LUT");
00113 result = 1;
00114 }
00115 }
00116 return result;
00117 }
00118
00123 void modlut(DiInputPixel *input)
00124 {
00125 const T1 *pixel = OFstatic_cast(const T1 *, input->getData());
00126 if ((pixel != NULL) && (this->Modality != NULL))
00127 {
00128 const DiLookupTable *mlut = this->Modality->getTableData();
00129 if (mlut != NULL)
00130 {
00131 const int useInputBuffer = (sizeof(T1) == sizeof(T3)) && (this->Count <= input->getCount());
00132 if (useInputBuffer)
00133 {
00134 DCMIMGLE_DEBUG("re-using input buffer, do not copy pixel data");
00135 this->Data = OFstatic_cast(T3 *, input->getDataPtr());
00136 input->removeDataReference();
00137 } else
00138 this->Data = new T3[this->Count];
00139 if (this->Data != NULL)
00140 {
00141 DCMIMGLE_DEBUG("applying modality tranformation with LUT (" << mlut->getCount() << " entries)");
00142 register T2 value = 0;
00143 const T2 firstentry = mlut->getFirstEntry(value);
00144 const T2 lastentry = mlut->getLastEntry(value);
00145 const T3 firstvalue = OFstatic_cast(T3, mlut->getFirstValue());
00146 const T3 lastvalue = OFstatic_cast(T3, mlut->getLastValue());
00147 register const T1 *p = pixel + input->getPixelStart();
00148 register T3 *q = this->Data;
00149 register unsigned long i;
00150 T3 *lut = NULL;
00151 const unsigned long ocnt = OFstatic_cast(unsigned long, input->getAbsMaxRange());
00152 if (initOptimizationLUT(lut, ocnt))
00153 {
00154 const T2 absmin = OFstatic_cast(T2, input->getAbsMinimum());
00155 q = lut;
00156 for (i = 0; i < ocnt; ++i)
00157 {
00158 value = OFstatic_cast(T2, i) + absmin;
00159 if (value <= firstentry)
00160 *(q++) = firstvalue;
00161 else if (value >= lastentry)
00162 *(q++) = lastvalue;
00163 else
00164 *(q++) = OFstatic_cast(T3, mlut->getValue(value));
00165 }
00166 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
00167 q = this->Data;
00168 for (i = this->InputCount; i != 0; --i)
00169 *(q++) = *(lut0 + (*(p++)));
00170 }
00171 if (lut == NULL)
00172 {
00173 for (i = this->InputCount; i != 0; --i)
00174 {
00175 value = OFstatic_cast(T2, *(p++));
00176 if (value <= firstentry)
00177 *(q++) = firstvalue;
00178 else if (value >= lastentry)
00179 *(q++) = lastvalue;
00180 else
00181 *(q++) = OFstatic_cast(T3, mlut->getValue(value));
00182 }
00183 }
00184 delete[] lut;
00185 }
00186 }
00187 }
00188 }
00189
00196 void rescale(DiInputPixel *input,
00197 const double slope = 1.0,
00198 const double intercept = 0.0)
00199 {
00200 const T1 *pixel = OFstatic_cast(const T1 *, input->getData());
00201 if (pixel != NULL)
00202 {
00203 const int useInputBuffer = (sizeof(T1) == sizeof(T3)) && (this->Count <= input->getCount()) && (input->getPixelStart() == 0);
00204 if (useInputBuffer)
00205 {
00206 DCMIMGLE_DEBUG("re-using input buffer, do not copy pixel data");
00207 this->Data = OFstatic_cast(T3 *, input->getDataPtr());
00208 input->removeDataReference();
00209 } else
00210 this->Data = new T3[this->Count];
00211 if (this->Data != NULL)
00212 {
00213 register T3 *q = this->Data;
00214 register unsigned long i;
00215 if ((slope == 1.0) && (intercept == 0.0))
00216 {
00217 if (!useInputBuffer)
00218 {
00219 register const T1 *p = pixel + input->getPixelStart();
00220 for (i = this->InputCount; i != 0; --i)
00221 *(q++) = OFstatic_cast(T3, *(p++));
00222 }
00223 } else {
00224 DCMIMGLE_DEBUG("applying modality transformation with rescale slope = " << slope << ", intercept = " << intercept);
00225 T3 *lut = NULL;
00226 register const T1 *p = pixel + input->getPixelStart();
00227 const unsigned long ocnt = OFstatic_cast(unsigned long, input->getAbsMaxRange());
00228 if (initOptimizationLUT(lut, ocnt))
00229 {
00230 const double absmin = input->getAbsMinimum();
00231 q = lut;
00232 if (slope == 1.0)
00233 {
00234 for (i = 0; i < ocnt; ++i)
00235 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, i) + absmin + intercept);
00236 } else {
00237 if (intercept == 0.0)
00238 {
00239 for (i = 0; i < ocnt; ++i)
00240 *(q++) = OFstatic_cast(T3, (OFstatic_cast(double, i) + absmin) * slope);
00241 } else {
00242 for (i = 0; i < ocnt; ++i)
00243 *(q++) = OFstatic_cast(T3, (OFstatic_cast(double, i) + absmin) * slope + intercept);
00244 }
00245 }
00246 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
00247 q = this->Data;
00248 for (i = this->InputCount; i != 0; --i)
00249 *(q++) = *(lut0 + (*(p++)));
00250 }
00251 if (lut == NULL)
00252 {
00253 if (slope == 1.0)
00254 {
00255 for (i = this->InputCount; i != 0; --i)
00256 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, *(p++)) + intercept);
00257 } else {
00258 if (intercept == 0.0)
00259 {
00260 for (i = this->InputCount; i != 0; --i)
00261 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, *(p++)) * slope);
00262 } else {
00263 for (i = this->InputCount; i != 0; --i)
00264 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, *(p++)) * slope + intercept);
00265 }
00266 }
00267 }
00268 delete[] lut;
00269 }
00270 }
00271 }
00272 }
00273 };
00274
00275
00276 #endif
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436