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 DIINPXT_H
00031 #define DIINPXT_H
00032
00033 #include "dcmtk/config/osconfig.h"
00034 #include "dcmtk/dcmdata/dcpixel.h"
00035
00036 #include "dcmtk/ofstd/ofbmanip.h"
00037 #include "dcmtk/ofstd/ofcast.h"
00038
00039 #include "dcmtk/dcmimgle/diinpx.h"
00040 #include "dcmtk/dcmimgle/didocu.h"
00041 #include "dcmtk/dcmimgle/dipxrept.h"
00042
00043
00044
00045
00046
00047
00048 static inline Uint8 expandSign(const Uint8 Value,
00049 const Uint8,
00050 const Uint8)
00051 {
00052 return Value;
00053 }
00054
00055
00056 static inline Uint16 expandSign(const Uint16 Value,
00057 const Uint16,
00058 const Uint16)
00059 {
00060 return Value;
00061 }
00062
00063
00064 static inline Uint32 expandSign(const Uint32 Value,
00065 const Uint32,
00066 const Uint32)
00067 {
00068 return Value;
00069 }
00070
00071
00072 static inline Sint8 expandSign(const Sint8 Value,
00073 const Sint8 SignBit,
00074 const Sint8 SignMask)
00075 {
00076 return (Value & SignBit) ? (Value | SignMask) : Value;
00077 }
00078
00079
00080 static inline Sint16 expandSign(const Sint16 Value,
00081 const Sint16 SignBit,
00082 const Sint16 SignMask)
00083 {
00084 return (Value & SignBit) ? (Value | SignMask) : Value;
00085 }
00086
00087
00088 static inline Sint32 expandSign(const Sint32 Value,
00089 const Sint32 SignBit,
00090 const Sint32 SignMask)
00091 {
00092 return (Value & SignBit) ? (Value | SignMask) : Value;
00093 }
00094
00095
00096 static Uint32 getPixelData(DcmPixelData *PixelData,
00097 Uint8 *&pixel)
00098 {
00099 PixelData->getUint8Array(pixel);
00100 return PixelData->getLength();
00101 }
00102
00103
00104 static Uint32 getPixelData(DcmPixelData *PixelData,
00105 Uint16 *&pixel)
00106 {
00107 PixelData->getUint16Array(pixel);
00108 return PixelData->getLength();
00109 }
00110
00111
00112
00113
00114
00115
00118 template<class T1, class T2>
00119 class DiInputPixelTemplate
00120 : public DiInputPixel,
00121 public DiPixelRepresentationTemplate<T2>
00122 {
00123
00124 public:
00125
00138 DiInputPixelTemplate(const DiDocument *document,
00139 const Uint16 alloc,
00140 const Uint16 stored,
00141 const Uint16 high,
00142 const unsigned long first,
00143 const unsigned long number,
00144 const unsigned long fsize,
00145 DcmFileCache *fileCache,
00146 Uint32 &fragment)
00147 : DiInputPixel(stored, first, number, fsize),
00148 Data(NULL)
00149 {
00150 MinValue[0] = 0;
00151 MinValue[1] = 0;
00152 MaxValue[0] = 0;
00153 MaxValue[1] = 0;
00154 if (this->isSigned())
00155 {
00156 AbsMinimum = -OFstatic_cast(double, DicomImageClass::maxval(Bits - 1, 0));
00157 AbsMaximum = OFstatic_cast(double, DicomImageClass::maxval(Bits - 1));
00158 } else {
00159 AbsMinimum = 0;
00160 AbsMaximum = OFstatic_cast(double, DicomImageClass::maxval(Bits));
00161 }
00162 if ((document != NULL) && (document->getPixelData() != NULL))
00163 convert(document, alloc, stored, high, fileCache, fragment);
00164 if ((PixelCount == 0) || (PixelStart + PixelCount > Count))
00165 {
00166 PixelCount = Count - PixelStart;
00167 DCMIMGLE_DEBUG("setting number of pixels to be processed (PixelCount) to: " << PixelCount);
00168 }
00169 }
00170
00173 virtual ~DiInputPixelTemplate()
00174 {
00175 delete[] Data;
00176 }
00177
00182 int determineMinMax()
00183 {
00184 if (Data != NULL)
00185 {
00186 DCMIMGLE_DEBUG("determining minimum and maximum pixel values for input data");
00187 register T2 *p = Data;
00188 register unsigned long i;
00189 const unsigned long ocnt = OFstatic_cast(unsigned long, getAbsMaxRange());
00190 Uint8 *lut = NULL;
00191 if ((sizeof(T2) <= 2) && (Count > 3 * ocnt))
00192 {
00193 lut = new Uint8[ocnt];
00194 if (lut != NULL)
00195 {
00196 DCMIMGLE_DEBUG("using optimized routine with additional LUT");
00197 OFBitmanipTemplate<Uint8>::zeroMem(lut, ocnt);
00198 register Uint8 *q = lut - OFstatic_cast(T2, getAbsMinimum());
00199 for (i = Count; i != 0; --i)
00200 *(q + *(p++)) = 1;
00201 q = lut;
00202 for (i = 0; i < ocnt; ++i)
00203 {
00204 if (*(q++) != 0)
00205 {
00206 MinValue[0] = OFstatic_cast(T2, OFstatic_cast(double, i) + getAbsMinimum());
00207 break;
00208 }
00209 }
00210 q = lut + ocnt;
00211 for (i = ocnt; i != 0; --i)
00212 {
00213 if (*(--q) != 0)
00214 {
00215 MaxValue[0] = OFstatic_cast(T2, OFstatic_cast(double, i - 1) + getAbsMinimum());
00216 break;
00217 }
00218 }
00219 if (Count >= PixelCount)
00220 {
00221 MinValue[1] = MinValue[0];
00222 MaxValue[1] = MaxValue[0];
00223 } else {
00224 OFBitmanipTemplate<Uint8>::zeroMem(lut, ocnt);
00225 p = Data + PixelStart;
00226 q = lut - OFstatic_cast(T2, getAbsMinimum());
00227 for (i = PixelCount; i != 0; --i)
00228 *(q + *(p++)) = 1;
00229 q = lut;
00230 for (i = 0; i < ocnt; ++i)
00231 {
00232 if (*(q++) != 0)
00233 {
00234 MinValue[1] = OFstatic_cast(T2, OFstatic_cast(double, i) + getAbsMinimum());
00235 break;
00236 }
00237 }
00238 q = lut + ocnt;
00239 for (i = ocnt; i != 0; --i)
00240 {
00241 if (*(--q) != 0)
00242 {
00243 MaxValue[1] = OFstatic_cast(T2, OFstatic_cast(double, i - 1) + getAbsMinimum());
00244 break;
00245 }
00246 }
00247 }
00248 }
00249 }
00250 if (lut == NULL)
00251 {
00252 register T2 value = *p;
00253 MinValue[0] = value;
00254 MaxValue[0] = value;
00255 for (i = Count; i > 1; --i)
00256 {
00257 value = *(++p);
00258 if (value < MinValue[0])
00259 MinValue[0] = value;
00260 else if (value > MaxValue[0])
00261 MaxValue[0] = value;
00262 }
00263 if (Count <= PixelCount)
00264 {
00265 MinValue[1] = MinValue[0];
00266 MaxValue[1] = MaxValue[0];
00267 } else {
00268 p = Data + PixelStart;
00269 value = *p;
00270 MinValue[1] = value;
00271 MaxValue[1] = value;
00272 for (i = PixelCount; i > 1; --i)
00273 {
00274 value = *(++p);
00275 if (value < MinValue[1])
00276 MinValue[1] = value;
00277 else if (value > MaxValue[1])
00278 MaxValue[1] = value;
00279 }
00280 }
00281 }
00282 delete[] lut;
00283 return 1;
00284 }
00285 return 0;
00286 }
00287
00292 inline EP_Representation getRepresentation() const
00293 {
00294 return DiPixelRepresentationTemplate<T2>::getRepresentation();
00295 }
00296
00301 inline const void *getData() const
00302 {
00303 return OFstatic_cast(const void *, Data);
00304 }
00305
00310 virtual void *getDataPtr()
00311 {
00312 return OFstatic_cast(void *, Data);
00313 }
00314
00317 inline void removeDataReference()
00318 {
00319 Data = NULL;
00320 }
00321
00329 inline double getMinValue(const int idx) const
00330 {
00331 return (idx == 0) ? OFstatic_cast(double, MinValue[0]) : OFstatic_cast(double, MinValue[1]);
00332 }
00333
00341 inline double getMaxValue(const int idx) const
00342 {
00343 return (idx == 0) ? OFstatic_cast(double, MaxValue[0]) : OFstatic_cast(double, MaxValue[1]);
00344 }
00345
00346
00347 private:
00348
00358 void convert(const DiDocument *document,
00359 const Uint16 bitsAllocated,
00360 const Uint16 bitsStored,
00361 const Uint16 highBit,
00362 DcmFileCache *fileCache,
00363 Uint32 &fragment)
00364 {
00365 T1 *pixel = NULL;
00366 OFBool deletePixel = OFFalse;
00367 Uint32 lengthBytes = 0;
00368 DcmPixelData *pixelData = document->getPixelData();
00369 const Uint16 bitsof_T1 = bitsof(T1);
00370 const Uint16 bitsof_T2 = bitsof(T2);
00371 const OFBool uncompressed = pixelData->canWriteXfer(EXS_LittleEndianExplicit, EXS_Unknown);
00372
00373 if ((document->getFlags() & CIF_UsePartialAccessToPixelData) && (PixelCount > 0) &&
00374 (!uncompressed || !pixelData->valueLoaded()) && (bitsAllocated % 8 == 0))
00375 {
00376
00377 const Uint32 byteFactor = bitsAllocated / 8;
00378 const Uint32 bytes_T1 = bitsof_T1 / 8;
00379 const Uint32 count_T1 = (byteFactor == bytes_T1) ? PixelCount : (PixelCount * byteFactor + bytes_T1 - 1) / bytes_T1;
00380 #ifdef DEBUG
00381 DCMIMGLE_TRACE("PixelCount: " << PixelCount << ", byteFactor: " << byteFactor << ", bytes_T1: " << bytes_T1 << ", count_T1: " << count_T1);
00382 #endif
00383
00384 const Uint32 extraByte = ((sizeof(T1) == 1) && (count_T1 & 1)) ? 1 : 0;
00385 pixel = new T1[count_T1 + extraByte];
00386 if (pixel != NULL)
00387 {
00388 if (uncompressed)
00389 {
00390 DCMIMGLE_DEBUG("using partial read access to uncompressed pixel data");
00391 const Uint32 offset = PixelStart * byteFactor;
00392 const Uint32 bufSize = PixelCount * byteFactor;
00393 const OFCondition status = pixelData->getPartialValue(pixel, offset, bufSize, fileCache);
00394 if (status.good())
00395 {
00396 PixelStart = 0;
00397 lengthBytes = bufSize;
00398 } else {
00399 DCMIMGLE_ERROR("can't access partial value from byte offset " << offset << " to "
00400 << (offset + bufSize - 1) << ": " << status.text());
00401 }
00402 } else {
00403 DCMIMGLE_DEBUG("using partial read access to compressed pixel data");
00404 OFCondition status = EC_IllegalCall;
00405 OFString decompressedColorModel;
00406 const Uint32 fsize = FrameSize * byteFactor;
00407 for (Uint32 frame = 0; frame < NumberOfFrames; ++frame)
00408 {
00409
00410 const Uint32 bufSize = (fsize & 1) ? fsize + 1 : fsize;
00411 status = pixelData->getUncompressedFrame(document->getDataset(), FirstFrame + frame, fragment,
00412 OFreinterpret_cast(Uint8 *, pixel) + lengthBytes, bufSize, decompressedColorModel, fileCache);
00413 if (status.good())
00414 {
00415 DCMIMGLE_TRACE("successfully decompressed frame " << FirstFrame + frame);
00416 lengthBytes += fsize;
00417 } else {
00418 DCMIMGLE_ERROR("can't decompress frame " << FirstFrame + frame << ": " << status.text());
00419 break;
00420 }
00421 }
00422 if (status.good())
00423 PixelStart = 0;
00424
00425 if (!decompressedColorModel.empty() && (decompressedColorModel != document->getPhotometricInterpretation()))
00426 {
00427 DCMIMGLE_WARN("Photometric Interpretation of decompressed pixel data deviates from original image: "
00428 << decompressedColorModel);
00429 }
00430 }
00431 deletePixel = OFTrue;
00432 }
00433 } else {
00434 DCMIMGLE_DEBUG("reading uncompressed pixel data completely into memory");
00435
00436 lengthBytes = getPixelData(pixelData, pixel);
00437 }
00438 if ((pixel != NULL) && (lengthBytes > 0))
00439 {
00440 const Uint32 length_T1 = lengthBytes / sizeof(T1);
00441
00442 const Uint32 length_B1 = lengthBytes / bitsAllocated;
00443 const Uint32 length_B2 = lengthBytes % bitsAllocated;
00444
00445 Count = 8 * length_B1 + (8 * length_B2 + bitsAllocated - 1) / bitsAllocated;
00446 register unsigned long i;
00447 Data = new T2[Count];
00448 if (Data != NULL)
00449 {
00450 DCMIMGLE_TRACE("Input length: " << lengthBytes << " bytes, Pixel count: " << Count
00451 << " (" << PixelCount << "), In: " << bitsof_T1 << " bits, Out: " << bitsof_T2
00452 << " bits (" << (this->isSigned() ? "signed" : "unsigned") << ")");
00453 register const T1 *p = pixel;
00454 register T2 *q = Data;
00455 if (bitsof_T1 == bitsAllocated)
00456 {
00457 if (bitsStored == bitsAllocated)
00458 {
00459 DCMIMGLE_DEBUG("convert input pixel data: case 1a (single copy)");
00460 for (i = Count; i != 0; --i)
00461 *(q++) = OFstatic_cast(T2, *(p++));
00462 }
00463 else
00464 {
00465 register T1 mask = 0;
00466 for (i = 0; i < bitsStored; ++i)
00467 mask |= OFstatic_cast(T1, 1 << i);
00468 const T2 sign = 1 << (bitsStored - 1);
00469 T2 smask = 0;
00470 for (i = bitsStored; i < bitsof_T2; ++i)
00471 smask |= OFstatic_cast(T2, 1 << i);
00472 const Uint16 shift = highBit + 1 - bitsStored;
00473 if (shift == 0)
00474 {
00475 DCMIMGLE_DEBUG("convert input pixel data: case 1b (mask & sign)");
00476 for (i = length_T1; i != 0; --i)
00477 *(q++) = expandSign(OFstatic_cast(T2, *(p++) & mask), sign, smask);
00478 }
00479 else
00480 {
00481 DCMIMGLE_DEBUG("convert input pixel data: case 1c (shift & mask & sign)");
00482 for (i = length_T1; i != 0; --i)
00483 *(q++) = expandSign(OFstatic_cast(T2, (*(p++) >> shift) & mask), sign, smask);
00484 }
00485 }
00486 }
00487 else if ((bitsof_T1 > bitsAllocated) && (bitsof_T1 % bitsAllocated == 0))
00488 {
00489 const Uint16 times = bitsof_T1 / bitsAllocated;
00490 register T1 mask = 0;
00491 for (i = 0; i < bitsStored; ++i)
00492 mask |= OFstatic_cast(T1, 1 << i);
00493 register Uint16 j;
00494 register T1 value;
00495 if ((bitsStored == bitsAllocated) && (bitsStored == bitsof_T2))
00496 {
00497 if (times == 2)
00498 {
00499 DCMIMGLE_DEBUG("convert input pixel data: case 2a (simple mask)");
00500 for (i = length_T1; i != 0; --i, ++p)
00501 {
00502 *(q++) = OFstatic_cast(T2, *p & mask);
00503 *(q++) = OFstatic_cast(T2, *p >> bitsAllocated);
00504 }
00505 }
00506 else
00507 {
00508 DCMIMGLE_DEBUG("convert input pixel data: case 2b (mask)");
00509 for (i = length_T1; i != 0; --i)
00510 {
00511 value = *(p++);
00512 for (j = times; j != 0; --j)
00513 {
00514 *(q++) = OFstatic_cast(T2, value & mask);
00515 value >>= bitsAllocated;
00516 }
00517 }
00518 }
00519 }
00520 else
00521 {
00522 DCMIMGLE_DEBUG("convert input pixel data: case 2c (shift & mask & sign)");
00523 const T2 sign = 1 << (bitsStored - 1);
00524 T2 smask = 0;
00525 for (i = bitsStored; i < bitsof_T2; ++i)
00526 smask |= OFstatic_cast(T2, 1 << i);
00527 const Uint16 shift = highBit + 1 - bitsStored;
00528 for (i = length_T1; i != 0; --i)
00529 {
00530 value = *(p++) >> shift;
00531 for (j = times; j != 0; --j)
00532 {
00533 *(q++) = expandSign(OFstatic_cast(T2, value & mask), sign, smask);
00534 value >>= bitsAllocated;
00535 }
00536 }
00537 }
00538 }
00539 else if ((bitsof_T1 < bitsAllocated) && (bitsAllocated % bitsof_T1 == 0)
00540 && (bitsStored == bitsAllocated))
00541 {
00542 DCMIMGLE_DEBUG("convert input pixel data: case 3 (multi copy)");
00543 const Uint16 times = bitsAllocated / bitsof_T1;
00544 register Uint16 j;
00545 register Uint16 shift;
00546 register T2 value;
00547 for (i = length_T1; i != 0; --i)
00548 {
00549 shift = 0;
00550 value = OFstatic_cast(T2, *(p++));
00551 for (j = times; j > 1; --j, --i)
00552 {
00553 shift += bitsof_T1;
00554 value |= OFstatic_cast(T2, *(p++)) << shift;
00555 }
00556 *(q++) = value;
00557 }
00558 }
00559 else
00560 {
00561 DCMIMGLE_DEBUG("convert input pixel data: case 4 (general)");
00562 register T2 value = 0;
00563 register Uint16 bits = 0;
00564 register Uint32 skip = highBit + 1 - bitsStored;
00565 register Uint32 times;
00566 T1 mask[bitsof_T1];
00567 mask[0] = 1;
00568 for (i = 1; i < bitsof_T1; ++i)
00569 mask[i] = (mask[i - 1] << 1) | 1;
00570 T2 smask = 0;
00571 for (i = bitsStored; i < bitsof_T2; ++i)
00572 smask |= OFstatic_cast(T2, 1 << i);
00573 const T2 sign = 1 << (bitsStored - 1);
00574 const Uint32 gap = bitsAllocated - bitsStored;
00575 i = 0;
00576 while (i < length_T1)
00577 {
00578 if (skip < bitsof_T1)
00579 {
00580 if (skip + bitsStored - bits < bitsof_T1)
00581 {
00582 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsStored - bits - 1]) << bits);
00583 skip += bitsStored - bits + gap;
00584 bits = bitsStored;
00585 }
00586 else
00587 {
00588 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsof_T1 - skip - 1]) << bits);
00589 bits += bitsof_T1 - OFstatic_cast(Uint16, skip);
00590 skip = (bits == bitsStored) ? gap : 0;
00591 ++i;
00592 ++p;
00593 }
00594 if (bits == bitsStored)
00595 {
00596 *(q++) = expandSign(value, sign, smask);
00597 value = 0;
00598 bits = 0;
00599 }
00600 }
00601 else
00602 {
00603 times = skip / bitsof_T1;
00604 i += times;
00605 p += times;
00606 skip -= times * bitsof_T1;
00607 }
00608 }
00609 }
00610 }
00611 } else {
00612
00613 Count = 0;
00614 }
00615 if (deletePixel)
00616 {
00617
00618 delete[] pixel;
00619 }
00620 }
00621
00623 T2 *Data;
00624
00626 T2 MinValue[2];
00628 T2 MaxValue[2];
00629
00630
00631
00632 DiInputPixelTemplate(const DiInputPixelTemplate<T1,T2> &);
00633 DiInputPixelTemplate<T1,T2> &operator=(const DiInputPixelTemplate<T1,T2> &);
00634 };
00635
00636
00637 #endif
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
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802