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 DIINPXT_H
00035 #define DIINPXT_H
00036
00037 #include "dcmtk/config/osconfig.h"
00038 #include "dcmtk/dcmdata/dctypes.h"
00039 #include "dcmtk/dcmdata/dcpixel.h"
00040
00041 #include "dcmtk/ofstd/ofbmanip.h"
00042 #include "dcmtk/ofstd/ofcast.h"
00043
00044 #include "dcmtk/dcmimgle/diinpx.h"
00045 #include "dcmtk/dcmimgle/dipxrept.h"
00046 #include "dcmtk/dcmimgle/diutils.h"
00047
00048
00049
00050
00051
00052
00053 static inline Uint8 expandSign(const Uint8 Value,
00054 const Uint8,
00055 const Uint8)
00056 {
00057 return Value;
00058 }
00059
00060
00061 static inline Uint16 expandSign(const Uint16 Value,
00062 const Uint16,
00063 const Uint16)
00064 {
00065 return Value;
00066 }
00067
00068
00069 static inline Uint32 expandSign(const Uint32 Value,
00070 const Uint32,
00071 const Uint32)
00072 {
00073 return Value;
00074 }
00075
00076
00077 static inline Sint8 expandSign(const Sint8 Value,
00078 const Sint8 SignBit,
00079 const Sint8 SignMask)
00080 {
00081 return (Value & SignBit) ? (Value | SignMask) : Value;
00082 }
00083
00084
00085 static inline Sint16 expandSign(const Sint16 Value,
00086 const Sint16 SignBit,
00087 const Sint16 SignMask)
00088 {
00089 return (Value & SignBit) ? (Value | SignMask) : Value;
00090 }
00091
00092
00093 static inline Sint32 expandSign(const Sint32 Value,
00094 const Sint32 SignBit,
00095 const Sint32 SignMask)
00096 {
00097 return (Value & SignBit) ? (Value | SignMask) : Value;
00098 }
00099
00100
00101 static Uint32 getPixelData(DcmPixelData *PixelData,
00102 Uint8 *&pixel)
00103 {
00104 PixelData->getUint8Array(pixel);
00105 return PixelData->getLength();
00106 }
00107
00108
00109 static Uint32 getPixelData(DcmPixelData *PixelData,
00110 Uint16 *&pixel)
00111 {
00112 PixelData->getUint16Array(pixel);
00113 return PixelData->getLength();
00114 }
00115
00116
00117
00118
00119
00120
00123 template<class T1, class T2>
00124 class DiInputPixelTemplate
00125 : public DiInputPixel,
00126 public DiPixelRepresentationTemplate<T2>
00127 {
00128
00129 public:
00130
00140 DiInputPixelTemplate( DcmPixelData *pixel,
00141 const Uint16 alloc,
00142 const Uint16 stored,
00143 const Uint16 high,
00144 const unsigned long start,
00145 const unsigned long count)
00146 : DiInputPixel(stored, start, count),
00147 Data(NULL)
00148 {
00149 MinValue[0] = 0;
00150 MinValue[1] = 0;
00151 MaxValue[0] = 0;
00152 MaxValue[1] = 0;
00153 if (this->isSigned())
00154 {
00155 AbsMinimum = -OFstatic_cast(double, DicomImageClass::maxval(Bits - 1, 0));
00156 AbsMaximum = OFstatic_cast(double, DicomImageClass::maxval(Bits - 1));
00157 } else {
00158 AbsMinimum = 0;
00159 AbsMaximum = OFstatic_cast(double, DicomImageClass::maxval(Bits));
00160 }
00161 if (pixel != NULL)
00162 convert(pixel, alloc, stored, high);
00163 if ((PixelCount == 0) || (PixelStart + PixelCount > Count))
00164 PixelCount = Count - PixelStart;
00165 }
00166
00169 virtual ~DiInputPixelTemplate()
00170 {
00171 delete[] Data;
00172 }
00173
00178 int determineMinMax()
00179 {
00180 if (Data != NULL)
00181 {
00182 register T2 *p = Data;
00183 register unsigned long i;
00184 const unsigned long ocnt = OFstatic_cast(unsigned long, getAbsMaxRange());
00185 Uint8 *lut = NULL;
00186 if ((sizeof(T2) <= 2) && (Count > 3 * ocnt))
00187 {
00188 lut = new Uint8[ocnt];
00189 if (lut != NULL)
00190 {
00191 OFBitmanipTemplate<Uint8>::zeroMem(lut, ocnt);
00192 register Uint8 *q = lut - OFstatic_cast(T2, getAbsMinimum());
00193 for (i = Count; i != 0; --i)
00194 *(q + *(p++)) = 1;
00195 q = lut;
00196 for (i = 0; i < ocnt; ++i)
00197 {
00198 if (*(q++) != 0)
00199 {
00200 MinValue[0] = OFstatic_cast(T2, OFstatic_cast(double, i) + getAbsMinimum());
00201 break;
00202 }
00203 }
00204 q = lut + ocnt;
00205 for (i = ocnt; i != 0; --i)
00206 {
00207 if (*(--q) != 0)
00208 {
00209 MaxValue[0] = OFstatic_cast(T2, OFstatic_cast(double, i - 1) + getAbsMinimum());
00210 break;
00211 }
00212 }
00213 if (Count >= PixelCount)
00214 {
00215 MinValue[1] = MinValue[0];
00216 MaxValue[1] = MaxValue[0];
00217 } else {
00218 OFBitmanipTemplate<Uint8>::zeroMem(lut, ocnt);
00219 p = Data + PixelStart;
00220 q = lut - OFstatic_cast(T2, getAbsMinimum());
00221 for (i = PixelCount; i != 0; --i)
00222 *(q + *(p++)) = 1;
00223 q = lut;
00224 for (i = 0; i < ocnt; ++i)
00225 {
00226 if (*(q++) != 0)
00227 {
00228 MinValue[1] = OFstatic_cast(T2, OFstatic_cast(double, i) + getAbsMinimum());
00229 break;
00230 }
00231 }
00232 q = lut + ocnt;
00233 for (i = ocnt; i != 0; --i)
00234 {
00235 if (*(--q) != 0)
00236 {
00237 MaxValue[1] = OFstatic_cast(T2, OFstatic_cast(double, i - 1) + getAbsMinimum());
00238 break;
00239 }
00240 }
00241 }
00242 }
00243 }
00244 if (lut == NULL)
00245 {
00246 register T2 value = *p;
00247 MinValue[0] = value;
00248 MaxValue[0] = value;
00249 for (i = Count; i > 1; --i)
00250 {
00251 value = *(++p);
00252 if (value < MinValue[0])
00253 MinValue[0] = value;
00254 else if (value > MaxValue[0])
00255 MaxValue[0] = value;
00256 }
00257 if (Count <= PixelCount)
00258 {
00259 MinValue[1] = MinValue[0];
00260 MaxValue[1] = MaxValue[0];
00261 } else {
00262 p = Data + PixelStart;
00263 value = *p;
00264 MinValue[1] = value;
00265 MaxValue[1] = value;
00266 for (i = PixelCount; i > 1; --i)
00267 {
00268 value = *(++p);
00269 if (value < MinValue[1])
00270 MinValue[1] = value;
00271 else if (value > MaxValue[1])
00272 MaxValue[1] = value;
00273 }
00274 }
00275 }
00276 delete[] lut;
00277 return 1;
00278 }
00279 return 0;
00280 }
00281
00286 inline EP_Representation getRepresentation() const
00287 {
00288 return DiPixelRepresentationTemplate<T2>::getRepresentation();
00289 }
00290
00295 inline const void *getData() const
00296 {
00297 return OFstatic_cast(const void *, Data);
00298 }
00299
00304 virtual void *getDataPtr()
00305 {
00306 return OFstatic_cast(void *, Data);
00307 }
00308
00311 inline void removeDataReference()
00312 {
00313 Data = NULL;
00314 }
00315
00323 inline double getMinValue(const int idx) const
00324 {
00325 return (idx == 0) ? OFstatic_cast(double, MinValue[0]) : OFstatic_cast(double, MinValue[1]);
00326 }
00327
00335 inline double getMaxValue(const int idx) const
00336 {
00337 return (idx == 0) ? OFstatic_cast(double, MaxValue[0]) : OFstatic_cast(double, MaxValue[1]);
00338 }
00339
00340
00341 private:
00342
00350 void convert( DcmPixelData *pixelData,
00351 const Uint16 bitsAllocated,
00352 const Uint16 bitsStored,
00353 const Uint16 highBit)
00354 {
00355 const Uint16 bitsof_T1 = bitsof(T1);
00356 const Uint16 bitsof_T2 = bitsof(T2);
00357 T1 *pixel;
00358 const Uint32 length_Bytes = getPixelData(pixelData, pixel);
00359 const Uint32 length_T1 = length_Bytes / sizeof(T1);
00360 Count = ((length_Bytes * 8) + bitsAllocated - 1) / bitsAllocated;
00361 register unsigned long i;
00362 Data = new T2[Count];
00363 if (Data != NULL)
00364 {
00365 #ifdef DEBUG
00366 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00367 {
00368 ofConsole.lockCerr() << bitsAllocated << " " << bitsStored << " " << highBit << " " << isSigned() << endl;
00369 ofConsole.unlockCerr();
00370 }
00371 #endif
00372 register const T1 *p = pixel;
00373 register T2 *q = Data;
00374 if (bitsof_T1 == bitsAllocated)
00375 {
00376 if (bitsStored == bitsAllocated)
00377 {
00378 #ifdef DEBUG
00379 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00380 {
00381 ofConsole.lockCerr() << "convert pixelData: case 1a (single copy)" << endl;
00382 ofConsole.unlockCerr();
00383 }
00384 #endif
00385 for (i = Count; i != 0; --i)
00386 *(q++) = OFstatic_cast(T2, *(p++));
00387 }
00388 else
00389 {
00390 register T1 mask = 0;
00391 for (i = 0; i < bitsStored; ++i)
00392 mask |= OFstatic_cast(T1, 1 << i);
00393 const T2 sign = 1 << (bitsStored - 1);
00394 T2 smask = 0;
00395 for (i = bitsStored; i < bitsof_T2; ++i)
00396 smask |= OFstatic_cast(T2, 1 << i);
00397 const Uint16 shift = highBit + 1 - bitsStored;
00398 if (shift == 0)
00399 {
00400 #ifdef DEBUG
00401 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00402 {
00403 ofConsole.lockCerr() << "convert pixelData: case 1b (mask & sign)" << endl;
00404 ofConsole.unlockCerr();
00405 }
00406 #endif
00407 for (i = length_T1; i != 0; --i)
00408 *(q++) = expandSign(OFstatic_cast(T2, *(p++) & mask), sign, smask);
00409 }
00410 else
00411 {
00412 #ifdef DEBUG
00413 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00414 {
00415 ofConsole.lockCerr() << "convert pixelData: case 1c (shift & mask & sign)" << endl;
00416 ofConsole.unlockCerr();
00417 }
00418 #endif
00419 for (i = length_T1; i != 0; --i)
00420 *(q++) = expandSign(OFstatic_cast(T2, (*(p++) >> shift) & mask), sign, smask);
00421 }
00422 }
00423 }
00424 else if ((bitsof_T1 > bitsAllocated) && (bitsof_T1 % bitsAllocated == 0))
00425 {
00426 const Uint16 times = bitsof_T1 / bitsAllocated;
00427 register T1 mask = 0;
00428 for (i = 0; i < bitsStored; ++i)
00429 mask |= OFstatic_cast(T1, 1 << i);
00430 register Uint16 j;
00431 register T1 value;
00432 if ((bitsStored == bitsAllocated) && (bitsStored == bitsof_T2))
00433 {
00434 if (times == 2)
00435 {
00436 #ifdef DEBUG
00437 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00438 {
00439 ofConsole.lockCerr() << "convert pixelData: case 2a (simple mask)" << endl;
00440 ofConsole.unlockCerr();
00441 }
00442 #endif
00443 for (i = length_T1; i != 0; --i, ++p)
00444 {
00445 *(q++) = OFstatic_cast(T2, *p & mask);
00446 *(q++) = OFstatic_cast(T2, *p >> bitsAllocated);
00447 }
00448 }
00449 else
00450 {
00451 #ifdef DEBUG
00452 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00453 {
00454 ofConsole.lockCerr() << "convert pixelData: case 2b (mask)" << endl;
00455 ofConsole.unlockCerr();
00456 }
00457 #endif
00458 for (i = length_T1; i != 0; --i)
00459 {
00460 value = *(p++);
00461 for (j = times; j != 0; --j)
00462 {
00463 *(q++) = OFstatic_cast(T2, value & mask);
00464 value >>= bitsAllocated;
00465 }
00466 }
00467 }
00468 }
00469 else
00470 {
00471 #ifdef DEBUG
00472 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00473 {
00474 ofConsole.lockCerr() << "convert pixelData: case 2c (shift & mask & sign)" << endl;
00475 ofConsole.unlockCerr();
00476 }
00477 #endif
00478 const T2 sign = 1 << (bitsStored - 1);
00479 T2 smask = 0;
00480 for (i = bitsStored; i < bitsof_T2; ++i)
00481 smask |= OFstatic_cast(T2, 1 << i);
00482 const Uint16 shift = highBit + 1 - bitsStored;
00483 for (i = length_T1; i != 0; --i)
00484 {
00485 value = *(p++) >> shift;
00486 for (j = times; j != 0; --j)
00487 {
00488 *(q++) = expandSign(OFstatic_cast(T2, value & mask), sign, smask);
00489 value >>= bitsAllocated;
00490 }
00491 }
00492 }
00493 }
00494 else if ((bitsof_T1 < bitsAllocated) && (bitsAllocated % bitsof_T1 == 0)
00495 && (bitsStored == bitsAllocated))
00496 {
00497 #ifdef DEBUG
00498 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00499 {
00500 ofConsole.lockCerr() << "convert pixelData: case 3 (multi copy)" << endl;
00501 ofConsole.unlockCerr();
00502 }
00503 #endif
00504 const Uint16 times = bitsAllocated / bitsof_T1;
00505 register Uint16 j;
00506 register Uint16 shift;
00507 register T2 value;
00508 for (i = length_T1; i != 0; --i)
00509 {
00510 shift = 0;
00511 value = OFstatic_cast(T2, *(p++));
00512 for (j = times; j > 1; --j, --i)
00513 {
00514 shift += bitsof_T1;
00515 value |= OFstatic_cast(T2, *(p++)) << shift;
00516 }
00517 *(q++) = value;
00518 }
00519 }
00520 else
00521 {
00522 #ifdef DEBUG
00523 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00524 {
00525 ofConsole.lockCerr() << "convert pixelData: case 4 (general)" << endl;
00526 ofConsole.unlockCerr();
00527 }
00528 #endif
00529 register T2 value = 0;
00530 register Uint16 bits = 0;
00531 register Uint32 skip = highBit + 1 - bitsStored;
00532 register Uint32 times;
00533 T1 mask[bitsof_T1];
00534 mask[0] = 1;
00535 for (i = 1; i < bitsof_T1; ++i)
00536 mask[i] = (mask[i - 1] << 1) | 1;
00537 T2 smask = 0;
00538 for (i = bitsStored; i < bitsof_T2; ++i)
00539 smask |= OFstatic_cast(T2, 1 << i);
00540 const T2 sign = 1 << (bitsStored - 1);
00541 const Uint32 gap = bitsAllocated - bitsStored;
00542 i = 0;
00543 while (i < length_T1)
00544 {
00545 if (skip < bitsof_T1)
00546 {
00547 if (skip + bitsStored - bits < bitsof_T1)
00548 {
00549 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsStored - bits - 1]) << bits);
00550 skip += bitsStored - bits + gap;
00551 bits = bitsStored;
00552 }
00553 else
00554 {
00555 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsof_T1 - skip - 1]) << bits);
00556 bits += bitsof_T1 - OFstatic_cast(Uint16, skip);
00557 skip = (bits == bitsStored) ? gap : 0;
00558 ++i;
00559 ++p;
00560 }
00561 if (bits == bitsStored)
00562 {
00563 *(q++) = expandSign(value, sign, smask);
00564 value = 0;
00565 bits = 0;
00566 }
00567 }
00568 else
00569 {
00570 times = skip / bitsof_T1;
00571 i += times;
00572 p += times;
00573 skip -= times * bitsof_T1;
00574 }
00575 }
00576 }
00577 }
00578 }
00579
00581 T2 *Data;
00582
00584 T2 MinValue[2];
00586 T2 MaxValue[2];
00587
00588
00589
00590 DiInputPixelTemplate(const DiInputPixelTemplate<T1,T2> &);
00591 DiInputPixelTemplate<T1,T2> &operator=(const DiInputPixelTemplate<T1,T2> &);
00592 };
00593
00594
00595 #endif
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718