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 DIMOIPXT_H
00035 #define DIMOIPXT_H
00036
00037 #include "dcmtk/config/osconfig.h"
00038 #include "dcmtk/ofstd/ofconsol.h"
00039 #include "dcmtk/ofstd/ofbmanip.h"
00040 #include "dcmtk/ofstd/ofcast.h"
00041
00042 #include "dcmtk/dcmimgle/dimopxt.h"
00043
00044
00045
00046
00047
00048
00051 template<class T1, class T2, class T3>
00052 class DiMonoInputPixelTemplate
00053 : public DiMonoPixelTemplate<T3>
00054 {
00055
00056 public:
00057
00063 DiMonoInputPixelTemplate(DiInputPixel *pixel,
00064 DiMonoModality *modality)
00065 : DiMonoPixelTemplate<T3>(pixel, modality)
00066 {
00067
00068 if ((this->Data != NULL) && (this->InputCount < this->Count))
00069 OFBitmanipTemplate<T3>::zeroMem(this->Data + this->InputCount, this->Count - this->InputCount);
00070 if ((pixel != NULL) && (this->Count > 0))
00071 {
00072
00073 if ((this->Modality != NULL) && this->Modality->hasLookupTable() && (bitsof(T1) <= MAX_TABLE_ENTRY_SIZE))
00074 {
00075 modlut(pixel);
00076
00077 this->determineMinMax();
00078 }
00079 else if ((this->Modality != NULL) && this->Modality->hasRescaling())
00080 {
00081 rescale(pixel, this->Modality->getRescaleSlope(), this->Modality->getRescaleIntercept());
00082 determineMinMax(OFstatic_cast(T3, this->Modality->getMinValue()), OFstatic_cast(T3, this->Modality->getMaxValue()));
00083 } else {
00084 rescale(pixel);
00085 determineMinMax(OFstatic_cast(T3, this->Modality->getMinValue()), OFstatic_cast(T3, this->Modality->getMaxValue()));
00086 }
00087 }
00088 }
00089
00092 virtual ~DiMonoInputPixelTemplate()
00093 {
00094 }
00095
00096
00097 private:
00098
00106 inline int initOptimizationLUT(T3 *&lut,
00107 const unsigned long ocnt)
00108 {
00109 int result = 0;
00110 if ((sizeof(T1) <= 2) && (this->InputCount > 3 * ocnt))
00111 {
00112 lut = new T3[ocnt];
00113 if (lut != NULL)
00114 {
00115 #ifdef DEBUG
00116 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00117 {
00118 ofConsole.lockCerr() << "INFO: using optimized routine with additional LUT" << endl;
00119 ofConsole.unlockCerr();
00120 }
00121 #endif
00122 result = 1;
00123 }
00124 }
00125 return result;
00126 }
00127
00132 void modlut(DiInputPixel *input)
00133 {
00134 const T1 *pixel = OFstatic_cast(const T1 *, input->getData());
00135 if ((pixel != NULL) && (this->Modality != NULL))
00136 {
00137 const DiLookupTable *mlut = this->Modality->getTableData();
00138 if (mlut != NULL)
00139 {
00140 const int useInputBuffer = (sizeof(T1) == sizeof(T3)) && (this->Count <= input->getCount());
00141 if (useInputBuffer)
00142 {
00143 this->Data = OFstatic_cast(T3 *, input->getDataPtr());
00144 input->removeDataReference();
00145 } else
00146 this->Data = new T3[this->Count];
00147 if (this->Data != NULL)
00148 {
00149 #ifdef DEBUG
00150 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00151 {
00152 ofConsole.lockCerr() << "INFO: using modality routine 'modlut()'" << endl;
00153 ofConsole.unlockCerr();
00154 }
00155 #endif
00156 register T2 value = 0;
00157 const T2 firstentry = mlut->getFirstEntry(value);
00158 const T2 lastentry = mlut->getLastEntry(value);
00159 const T3 firstvalue = OFstatic_cast(T3, mlut->getFirstValue());
00160 const T3 lastvalue = OFstatic_cast(T3, mlut->getLastValue());
00161 register const T1 *p = pixel + input->getPixelStart();
00162 register T3 *q = this->Data;
00163 register unsigned long i;
00164 T3 *lut = NULL;
00165 const unsigned long ocnt = OFstatic_cast(unsigned long, input->getAbsMaxRange());
00166 if (initOptimizationLUT(lut, ocnt))
00167 {
00168 const T2 absmin = OFstatic_cast(T2, input->getAbsMinimum());
00169 q = lut;
00170 for (i = 0; i < ocnt; ++i)
00171 {
00172 value = OFstatic_cast(T2, i) + absmin;
00173 if (value <= firstentry)
00174 *(q++) = firstvalue;
00175 else if (value >= lastentry)
00176 *(q++) = lastvalue;
00177 else
00178 *(q++) = OFstatic_cast(T3, mlut->getValue(value));
00179 }
00180 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
00181 q = this->Data;
00182 for (i = this->InputCount; i != 0; --i)
00183 *(q++) = *(lut0 + (*(p++)));
00184 }
00185 if (lut == NULL)
00186 {
00187 for (i = this->InputCount; i != 0; --i)
00188 {
00189 value = OFstatic_cast(T2, *(p++));
00190 if (value <= firstentry)
00191 *(q++) = firstvalue;
00192 else if (value >= lastentry)
00193 *(q++) = lastvalue;
00194 else
00195 *(q++) = OFstatic_cast(T3, mlut->getValue(value));
00196 }
00197 }
00198 delete[] lut;
00199 }
00200 }
00201 }
00202 }
00203
00210 void rescale(DiInputPixel *input,
00211 const double slope = 1.0,
00212 const double intercept = 0.0)
00213 {
00214 const T1 *pixel = OFstatic_cast(const T1 *, input->getData());
00215 if (pixel != NULL)
00216 {
00217 const int useInputBuffer = (sizeof(T1) == sizeof(T3)) && (this->Count <= input->getCount()) && (input->getPixelStart() == 0);
00218 if (useInputBuffer)
00219 {
00220 this->Data = OFstatic_cast(T3 *, input->getDataPtr());
00221 input->removeDataReference();
00222 } else
00223 this->Data = new T3[this->Count];
00224 if (this->Data != NULL)
00225 {
00226 register T3 *q = this->Data;
00227 register unsigned long i;
00228 if ((slope == 1.0) && (intercept == 0.0))
00229 {
00230 if (!useInputBuffer)
00231 {
00232 register const T1 *p = pixel + input->getPixelStart();
00233 for (i = this->InputCount; i != 0; --i)
00234 *(q++) = OFstatic_cast(T3, *(p++));
00235 }
00236 } else {
00237 #ifdef DEBUG
00238 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00239 {
00240 ofConsole.lockCerr() << "INFO: using modality routine 'rescale()'" << endl;
00241 ofConsole.unlockCerr();
00242 }
00243 #endif
00244 T3 *lut = NULL;
00245 register const T1 *p = pixel + input->getPixelStart();
00246 const unsigned long ocnt = OFstatic_cast(unsigned long, input->getAbsMaxRange());
00247 if (initOptimizationLUT(lut, ocnt))
00248 {
00249 const double absmin = input->getAbsMinimum();
00250 q = lut;
00251 if (slope == 1.0)
00252 {
00253 for (i = 0; i < ocnt; ++i)
00254 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, i) + absmin + intercept);
00255 } else {
00256 if (intercept == 0.0)
00257 {
00258 for (i = 0; i < ocnt; ++i)
00259 *(q++) = OFstatic_cast(T3, (OFstatic_cast(double, i) + absmin) * slope);
00260 } else {
00261 for (i = 0; i < ocnt; ++i)
00262 *(q++) = OFstatic_cast(T3, (OFstatic_cast(double, i) + absmin) * slope + intercept);
00263 }
00264 }
00265 const T3 *lut0 = lut - OFstatic_cast(T2, absmin);
00266 q = this->Data;
00267 for (i = this->InputCount; i != 0; --i)
00268 *(q++) = *(lut0 + (*(p++)));
00269 }
00270 if (lut == NULL)
00271 {
00272 if (slope == 1.0)
00273 {
00274 for (i = this->Count; i != 0; --i)
00275 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, *(p++)) + intercept);
00276 } else {
00277 if (intercept == 0.0)
00278 {
00279 for (i = this->InputCount; i != 0; --i)
00280 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, *(p++)) * slope);
00281 } else {
00282 for (i = this->InputCount; i != 0; --i)
00283 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, *(p++)) * slope + intercept);
00284 }
00285 }
00286 }
00287 delete[] lut;
00288 }
00289 }
00290 }
00291 }
00292 };
00293
00294
00295 #endif
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