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);
OFBool empty() const
return true if the string is empty, false otherwise.
This class implements a simple container that stores an input stream, the position of that input stre...
virtual Uint32 getLength(const E_TransferSyntax xfer=EXS_LittleEndianImplicit, const E_EncodingType enctype=EET_UndefinedLength)
returns length of representation value field conforming to given transfer syntax. ...
The class DcmPixelData stores different pixel representations identified by a type (the transfer synt...
Interface class to DICOM data management (dcmdata).
DcmPixelData * getPixelData() const
get pixel data object
DcmDataset * getDataset() const
get current DICOM dataset
OFBool good() const
returns true if status is OK
virtual OFCondition getUint16Array(Uint16 *&val)
get a pointer to the element value of the current element as type Uint16.
Template class to determine pixel representation.
static void zeroMem(T *dest, const unsigned long count)
sets specified number of elements in destination memory to zero
virtual OFCondition getUncompressedFrame(DcmItem *dataset, Uint32 frameNo, Uint32 &startFragment, void *buffer, Uint32 bufSize, OFString &decompressedColorModel, DcmFileCache *cache=NULL)
access single frame without decompressing or loading a complete multi-frame object.
const char * text() const
returns the error message text for this object.
virtual OFBool canWriteXfer(const E_TransferSyntax newXfer, const E_TransferSyntax oldXfer)
tests if it is possible to write a specific representation Only existing representations are consider...
OFBool valueLoaded() const
check if value of this element is loaded into main memory
static unsigned long maxval(const int mv_bits, const unsigned long mv_pos=1)
calculate maximum value which could be stored in the specified number of bits
const char * getPhotometricInterpretation() const
get photometric interpretation (color model).
a simple string class that implements a subset of std::string.
virtual EP_Representation getRepresentation() const
determine integer representation for template type T
virtual OFCondition getPartialValue(void *targetBuffer, const Uint32 offset, Uint32 numBytes, DcmFileCache *cache=NULL, E_ByteOrder byteOrder=gLocalByteOrder)
Copy numBytes bytes of data from the attribute value in byteOrder byte order to targetBuffer, starting at byte offset offset of the attribute value.
virtual OFCondition getUint8Array(Uint8 *&val)
get a pointer to the element value of the current element as type string.
int isSigned() const
check whether template type T is signed or not
General purpose class for condition codes.
unsigned long getFlags() const
get configuration flags