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);
186 DCMIMGLE_DEBUG(
"determining minimum and maximum pixel values for input data");
187 register T2 *p =
Data;
188 register unsigned long i;
189 const unsigned long ocnt = OFstatic_cast(
unsigned long,
getAbsMaxRange());
191 if ((
sizeof(T2) <= 2) && (
Count > 3 * ocnt))
193 lut =
new Uint8[ocnt];
196 DCMIMGLE_DEBUG(
"using optimized routine with additional LUT");
198 register Uint8 *q = lut - OFstatic_cast(T2,
getAbsMinimum());
199 for (i =
Count; i != 0; --i)
202 for (i = 0; i < ocnt; ++i)
211 for (i = ocnt; i != 0; --i)
230 for (i = 0; i < ocnt; ++i)
239 for (i = ocnt; i != 0; --i)
252 register T2 value = *p;
255 for (i =
Count; i > 1; --i)
303 return OFstatic_cast(
const void *,
Data);
312 return OFstatic_cast(
void *,
Data);
331 return (idx == 0) ? OFstatic_cast(
double,
MinValue[0]) : OFstatic_cast(
double,
MinValue[1]);
343 return (idx == 0) ? OFstatic_cast(
double,
MaxValue[0]) : OFstatic_cast(
double,
MaxValue[1]);
359 const Uint16 bitsAllocated,
360 const Uint16 bitsStored,
361 const Uint16 highBit,
366 OFBool deletePixel = OFFalse;
367 Uint32 lengthBytes = 0;
369 const Uint16 bitsof_T1 = bitsof(T1);
370 const Uint16 bitsof_T2 = bitsof(T2);
371 const OFBool uncompressed = pixelData->
canWriteXfer(EXS_LittleEndianExplicit, EXS_Unknown);
374 (!uncompressed || !pixelData->
valueLoaded()) && (bitsAllocated % 8 == 0))
377 const Uint32 byteFactor = bitsAllocated / 8;
378 const Uint32 bytes_T1 = bitsof_T1 / 8;
379 const Uint32 count_T1 = (byteFactor == bytes_T1) ?
PixelCount : (
PixelCount * byteFactor + bytes_T1 - 1) / bytes_T1;
381 DCMIMGLE_TRACE(
"PixelCount: " <<
PixelCount <<
", byteFactor: " << byteFactor <<
", bytes_T1: " << bytes_T1 <<
", count_T1: " << count_T1);
384 const Uint32 extraByte = ((
sizeof(T1) == 1) && (count_T1 & 1)) ? 1 : 0;
385 pixel =
new T1[count_T1 + extraByte];
390 DCMIMGLE_DEBUG(
"using partial read access to uncompressed pixel data");
391 const Uint32 offset =
PixelStart * byteFactor;
392 const Uint32 bufSize =
PixelCount * byteFactor;
397 lengthBytes = bufSize;
399 DCMIMGLE_ERROR(
"can't access partial value from byte offset " << offset <<
" to "
400 << (offset + bufSize - 1) <<
": " << status.
text());
403 DCMIMGLE_DEBUG(
"using partial read access to compressed pixel data");
406 const Uint32 fsize =
FrameSize * byteFactor;
410 const Uint32 bufSize = (fsize & 1) ? fsize + 1 : fsize;
412 OFreinterpret_cast(Uint8 *, pixel) + lengthBytes, bufSize, decompressedColorModel, fileCache);
415 DCMIMGLE_TRACE(
"successfully decompressed frame " <<
FirstFrame + frame);
416 lengthBytes += fsize;
418 DCMIMGLE_ERROR(
"can't decompress frame " <<
FirstFrame + frame <<
": " << status.
text());
427 DCMIMGLE_WARN(
"Photometric Interpretation of decompressed pixel data deviates from original image: "
428 << decompressedColorModel);
431 deletePixel = OFTrue;
434 DCMIMGLE_DEBUG(
"reading uncompressed pixel data completely into memory");
436 lengthBytes = getPixelData(pixelData, pixel);
438 if ((pixel != NULL) && (lengthBytes > 0))
440 const Uint32 length_T1 = lengthBytes /
sizeof(T1);
442 const Uint32 length_B1 = lengthBytes / bitsAllocated;
443 const Uint32 length_B2 = lengthBytes % bitsAllocated;
445 Count = 8 * length_B1 + (8 * length_B2 + bitsAllocated - 1) / bitsAllocated;
446 register unsigned long i;
450 DCMIMGLE_TRACE(
"Input length: " << lengthBytes <<
" bytes, Pixel count: " <<
Count
451 <<
" (" <<
PixelCount <<
"), In: " << bitsof_T1 <<
" bits, Out: " << bitsof_T2
452 <<
" bits (" << (this->
isSigned() ?
"signed" :
"unsigned") <<
")");
453 register const T1 *p = pixel;
454 register T2 *q =
Data;
455 if (bitsof_T1 == bitsAllocated)
457 if (bitsStored == bitsAllocated)
459 DCMIMGLE_DEBUG(
"convert input pixel data: case 1a (single copy)");
460 for (i =
Count; i != 0; --i)
461 *(q++) = OFstatic_cast(T2, *(p++));
465 register T1 mask = 0;
466 for (i = 0; i < bitsStored; ++i)
467 mask |= OFstatic_cast(T1, 1 << i);
468 const T2 sign = 1 << (bitsStored - 1);
470 for (i = bitsStored; i < bitsof_T2; ++i)
471 smask |= OFstatic_cast(T2, 1 << i);
472 const Uint16 shift = highBit + 1 - bitsStored;
475 DCMIMGLE_DEBUG(
"convert input pixel data: case 1b (mask & sign)");
476 for (i = length_T1; i != 0; --i)
477 *(q++) = expandSign(OFstatic_cast(T2, *(p++) & mask), sign, smask);
481 DCMIMGLE_DEBUG(
"convert input pixel data: case 1c (shift & mask & sign)");
482 for (i = length_T1; i != 0; --i)
483 *(q++) = expandSign(OFstatic_cast(T2, (*(p++) >> shift) & mask), sign, smask);
487 else if ((bitsof_T1 > bitsAllocated) && (bitsof_T1 % bitsAllocated == 0))
489 const Uint16 times = bitsof_T1 / bitsAllocated;
490 register T1 mask = 0;
491 for (i = 0; i < bitsStored; ++i)
492 mask |= OFstatic_cast(T1, 1 << i);
495 if ((bitsStored == bitsAllocated) && (bitsStored == bitsof_T2))
499 DCMIMGLE_DEBUG(
"convert input pixel data: case 2a (simple mask)");
500 for (i = length_T1; i != 0; --i, ++p)
502 *(q++) = OFstatic_cast(T2, *p & mask);
503 *(q++) = OFstatic_cast(T2, *p >> bitsAllocated);
508 DCMIMGLE_DEBUG(
"convert input pixel data: case 2b (mask)");
509 for (i = length_T1; i != 0; --i)
512 for (j = times; j != 0; --j)
514 *(q++) = OFstatic_cast(T2, value & mask);
515 value >>= bitsAllocated;
522 DCMIMGLE_DEBUG(
"convert input pixel data: case 2c (shift & mask & sign)");
523 const T2 sign = 1 << (bitsStored - 1);
525 for (i = bitsStored; i < bitsof_T2; ++i)
526 smask |= OFstatic_cast(T2, 1 << i);
527 const Uint16 shift = highBit + 1 - bitsStored;
528 for (i = length_T1; i != 0; --i)
530 value = *(p++) >> shift;
531 for (j = times; j != 0; --j)
533 *(q++) = expandSign(OFstatic_cast(T2, value & mask), sign, smask);
534 value >>= bitsAllocated;
539 else if ((bitsof_T1 < bitsAllocated) && (bitsAllocated % bitsof_T1 == 0)
540 && (bitsStored == bitsAllocated))
542 DCMIMGLE_DEBUG(
"convert input pixel data: case 3 (multi copy)");
543 const Uint16 times = bitsAllocated / bitsof_T1;
545 register Uint16 shift;
547 for (i = length_T1; i != 0; --i)
550 value = OFstatic_cast(T2, *(p++));
551 for (j = times; j > 1; --j, --i)
554 value |= OFstatic_cast(T2, *(p++)) << shift;
561 DCMIMGLE_DEBUG(
"convert input pixel data: case 4 (general)");
562 register T2 value = 0;
563 register Uint16 bits = 0;
564 register Uint32 skip = highBit + 1 - bitsStored;
565 register Uint32 times;
568 for (i = 1; i < bitsof_T1; ++i)
569 mask[i] = (mask[i - 1] << 1) | 1;
571 for (i = bitsStored; i < bitsof_T2; ++i)
572 smask |= OFstatic_cast(T2, 1 << i);
573 const T2 sign = 1 << (bitsStored - 1);
574 const Uint32 gap = bitsAllocated - bitsStored;
576 while (i < length_T1)
578 if (skip < bitsof_T1)
580 if (skip + bitsStored - bits < bitsof_T1)
582 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsStored - bits - 1]) << bits);
583 skip += bitsStored - bits + gap;
588 value |= (OFstatic_cast(T2, (*p >> skip) & mask[bitsof_T1 - skip - 1]) << bits);
589 bits += bitsof_T1 - OFstatic_cast(Uint16, skip);
590 skip = (bits == bitsStored) ? gap : 0;
594 if (bits == bitsStored)
596 *(q++) = expandSign(value, sign, smask);
603 times = skip / bitsof_T1;
606 skip -= times * bitsof_T1;