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 "osconfig.h"
00038
#include "dctypes.h"
00039
#include "dcpixel.h"
00040
00041
#include "ofbmanip.h"
00042
#include "ofcast.h"
00043
00044
#include "diinpx.h"
00045
#include "dipxrept.h"
00046
#include "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