33 #include "dcmtk/config/osconfig.h"
34 #include "dcmtk/dcmdata/dcpixel.h"
36 #include "dcmtk/ofstd/ofbmanip.h"
37 #include "dcmtk/ofstd/ofcast.h"
39 #include "dcmtk/dcmimgle/diinpx.h"
40 #include "dcmtk/dcmimgle/didocu.h"
41 #include "dcmtk/dcmimgle/dipxrept.h"
48 static inline Uint8 expandSign(
const Uint8 Value,
56 static inline Uint16 expandSign(
const Uint16 Value,
64 static inline Uint32 expandSign(
const Uint32 Value,
72 static inline Sint8 expandSign(
const Sint8 Value,
76 return (Value & SignBit) ? (Value | SignMask) : Value;
80 static inline Sint16 expandSign(
const Sint16 Value,
82 const Sint16 SignMask)
84 return (Value & SignBit) ? (Value | SignMask) : Value;
88 static inline Sint32 expandSign(
const Sint32 Value,
90 const Sint32 SignMask)
92 return (Value & SignBit) ? (Value | SignMask) : Value;
118 template<
class T1,
class T2>
142 const unsigned long first,
143 const unsigned long number,
144 const unsigned long fsize,
162 if ((document != NULL) && (document->
getPixelData() != NULL))
163 convert(document, alloc, stored, high, fileCache, fragment);
167 DCMIMGLE_DEBUG(
"setting number of pixels to be processed (PixelCount) to: " <<
PixelCount);
175 #if defined(HAVE_STD__NOTHROW) && defined(HAVE_NOTHROW_DELETE)
177 operator delete[] (
Data, std::nothrow);
191 DCMIMGLE_DEBUG(
"determining minimum and maximum pixel values for input data");
192 register T2 *p =
Data;
193 register unsigned long i;
194 const unsigned long ocnt = OFstatic_cast(
unsigned long,
getAbsMaxRange());
196 if ((
sizeof(T2) <= 2) && (
Count > 3 * ocnt))
198 lut =
new Uint8[ocnt];
201 DCMIMGLE_DEBUG(
"using optimized routine with additional LUT");
203 register Uint8 *q = lut - OFstatic_cast(T2,
getAbsMinimum());
204 for (i =
Count; i != 0; --i)
207 for (i = 0; i < ocnt; ++i)
216 for (i = ocnt; i != 0; --i)
235 for (i = 0; i < ocnt; ++i)
244 for (i = ocnt; i != 0; --i)
257 register T2 value = *p;
260 for (i =
Count; i > 1; --i)
308 return OFstatic_cast(
const void *,
Data);
317 return OFstatic_cast(
void *,
Data);
336 return (idx == 0) ? OFstatic_cast(
double,
MinValue[0]) : OFstatic_cast(
double,
MinValue[1]);
348 return (idx == 0) ? OFstatic_cast(
double,
MaxValue[0]) : OFstatic_cast(
double,
MaxValue[1]);
364 const Uint16 bitsAllocated,
365 const Uint16 bitsStored,
366 const Uint16 highBit,
371 OFBool deletePixel = OFFalse;
372 Uint32 lengthBytes = 0;
374 const Uint16 bitsof_T1 = bitsof(T1);
375 const Uint16 bitsof_T2 = bitsof(T2);
376 const OFBool uncompressed = pixelData->
canWriteXfer(EXS_LittleEndianExplicit, EXS_Unknown);
379 (!uncompressed || !pixelData->
valueLoaded()) && (bitsAllocated % 8 == 0))
382 const Uint32 byteFactor = bitsAllocated / 8;
383 const Uint32 bytes_T1 = bitsof_T1 / 8;
384 const Uint32 count_T1 = (byteFactor == bytes_T1) ?
PixelCount : (
PixelCount * byteFactor + bytes_T1 - 1) / bytes_T1;
386 DCMIMGLE_TRACE(
"PixelCount: " <<
PixelCount <<
", byteFactor: " << byteFactor <<
", bytes_T1: " << bytes_T1 <<
", count_T1: " << count_T1);
389 const Uint32 extraByte = ((
sizeof(T1) == 1) && (count_T1 & 1)) ? 1 : 0;
390 #ifdef HAVE_STD__NOTHROW
392 pixel =
new (std::nothrow) T1[count_T1 + extraByte];
394 pixel =
new T1[count_T1 + extraByte];
400 DCMIMGLE_DEBUG(
"using partial read access to uncompressed pixel data");
401 const Uint32 offset =
PixelStart * byteFactor;
402 const Uint32 bufSize =
PixelCount * byteFactor;
407 lengthBytes = bufSize;
409 DCMIMGLE_ERROR(
"can't access partial value from byte offset " << offset <<
" to "
410 << (offset + bufSize - 1) <<
": " << status.
text());
413 DCMIMGLE_DEBUG(
"using partial read access to compressed pixel data");
416 const Uint32 fsize =
FrameSize * byteFactor;
420 const Uint32 bufSize = (fsize & 1) ? fsize + 1 : fsize;
422 OFreinterpret_cast(Uint8 *, pixel) + lengthBytes, bufSize, decompressedColorModel, fileCache);
425 DCMIMGLE_TRACE(
"successfully decompressed frame " <<
FirstFrame + frame);
426 lengthBytes += fsize;
428 DCMIMGLE_ERROR(
"can't decompress frame " <<
FirstFrame + frame <<
": " << status.
text());
437 DCMIMGLE_WARN(
"Photometric Interpretation of decompressed pixel data deviates from original image: "
438 << decompressedColorModel);
441 deletePixel = OFTrue;
444 DCMIMGLE_DEBUG(
"reading uncompressed pixel data completely into memory");
446 lengthBytes = getPixelData(pixelData, pixel);
448 if ((pixel != NULL) && (lengthBytes > 0))
450 const Uint32 length_T1 = lengthBytes /
sizeof(T1);
452 const Uint32 length_B1 = lengthBytes / bitsAllocated;
453 const Uint32 length_B2 = lengthBytes % bitsAllocated;
455 Count = 8 * length_B1 + (8 * length_B2 + bitsAllocated - 1) / bitsAllocated;
456 register unsigned long i;
457 #ifdef HAVE_STD__NOTHROW
465 DCMIMGLE_TRACE(
"Input length: " << lengthBytes <<
" bytes, Pixel count: " <<
Count
466 <<
" (" <<
PixelCount <<
"), In: " << bitsof_T1 <<
" bits, Out: " << bitsof_T2
467 <<
" bits (" << (this->
isSigned() ?
"signed" :
"unsigned") <<
")");
468 register const T1 *p = pixel;
469 register T2 *q =
Data;
470 if (bitsof_T1 == bitsAllocated)
472 if (bitsStored == bitsAllocated)
474 DCMIMGLE_DEBUG(
"convert input pixel data: case 1a (single copy)");
475 for (i =
Count; i != 0; --i)
476 *(q++) = OFstatic_cast(T2, *(p++));
480 register T1 mask = 0;
481 for (i = 0; i < bitsStored; ++i)
482 mask |= OFstatic_cast(T1, 1 << i);
483 const T2 sign = 1 << (bitsStored - 1);
485 for (i = bitsStored; i < bitsof_T2; ++i)
486 smask |= OFstatic_cast(T2, 1 << i);
487 const Uint16 shift = highBit + 1 - bitsStored;
490 DCMIMGLE_DEBUG(
"convert input pixel data: case 1b (mask & sign)");
491 for (i = length_T1; i != 0; --i)
492 *(q++) = expandSign(OFstatic_cast(T2, *(p++) & mask), sign, smask);
496 DCMIMGLE_DEBUG(
"convert input pixel data: case 1c (shift & mask & sign)");
497 for (i = length_T1; i != 0; --i)
498 *(q++) = expandSign(OFstatic_cast(T2, (*(p++) >> shift) & mask), sign, smask);
502 else if ((bitsof_T1 > bitsAllocated) && (bitsof_T1 % bitsAllocated == 0))
504 const Uint16 times = bitsof_T1 / bitsAllocated;
505 register T1 mask = 0;
506 for (i = 0; i < bitsStored; ++i)
507 mask |= OFstatic_cast(T1, 1 << i);
510 if ((bitsStored == bitsAllocated) && (bitsStored == bitsof_T2))
514 DCMIMGLE_DEBUG(
"convert input pixel data: case 2a (simple mask)");
515 for (i = length_T1; i != 0; --i, ++p)
517 *(q++) = OFstatic_cast(T2, *p & mask);
518 *(q++) = OFstatic_cast(T2, *p >> bitsAllocated);
523 DCMIMGLE_DEBUG(
"convert input pixel data: case 2b (mask)");
524 for (i = length_T1; i != 0; --i)
527 for (j = times; j != 0; --j)
529 *(q++) = OFstatic_cast(T2, value & mask);
530 value >>= bitsAllocated;
537 DCMIMGLE_DEBUG(
"convert input pixel data: case 2c (shift & mask & sign)");
538 const T2 sign = 1 << (bitsStored - 1);
540 for (i = bitsStored; i < bitsof_T2; ++i)
541 smask |= OFstatic_cast(T2, 1 << i);
542 const Uint16 shift = highBit + 1 - bitsStored;
543 for (i = length_T1; i != 0; --i)
545 value = *(p++) >> shift;
546 for (j = times; j != 0; --j)
548 *(q++) = expandSign(OFstatic_cast(T2, value & mask), sign, smask);
549 value >>= bitsAllocated;
554 else if ((bitsof_T1 < bitsAllocated) && (bitsAllocated % bitsof_T1 == 0)
555 && (bitsStored == bitsAllocated))
557 DCMIMGLE_DEBUG(
"convert input pixel data: case 3 (multi copy)");
558 const Uint16 times = bitsAllocated / bitsof_T1;
560 register Uint16 shift;
562 for (i = length_T1; i != 0; --i)
565 value = OFstatic_cast(T2, *(p++));
566 for (j = times; j > 1; --j, --i)
569 value |= OFstatic_cast(T2, *(p++)) << shift;
576 DCMIMGLE_DEBUG(
"convert input pixel data: case 4 (general)");
577 register T2 value = 0;
578 register Uint16 bits = 0;
579 register Uint32 skip = highBit + 1 - bitsStored;
580 register Uint32 times;
583 for (i = 1; i < bitsof_T1; ++i)
584 mask[i] = (mask[i - 1] << 1) | 1;
586 for (i = bitsStored; i < bitsof_T2; ++i)
587 smask |= OFstatic_cast(T2, 1 << i);
588 const T2 sign = 1 << (bitsStored - 1);
589 const Uint32 gap = bitsAllocated - bitsStored;
591 while (i < length_T1)
593 if (skip < bitsof_T1)
595 if (skip + bitsStored - bits < bitsof_T1)
597 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsStored - bits - 1]) << bits);
598 skip += bitsStored - bits + gap;
603 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsof_T1 - skip - 1]) << bits);
604 bits += bitsof_T1 - OFstatic_cast(Uint16, skip);
605 skip = (bits == bitsStored) ? gap : 0;
609 if (bits == bitsStored)
611 *(q++) = expandSign(value, sign, smask);
618 times = skip / bitsof_T1;
621 skip -= times * bitsof_T1;
633 #if defined(HAVE_STD__NOTHROW) && defined(HAVE_NOTHROW_DELETE)
635 operator delete[] (pixel, std::nothrow);