|
|
|
|
@@ -0,0 +1,411 @@
|
|
|
|
|
From fb4de6d353b62c60163317833375d7565287375f Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: Joerg Riesmeier <dicom@jriesmeier.com>
|
|
|
|
|
Date: Fri, 15 Aug 2025 13:35:40 +0200
|
|
|
|
|
Subject: [PATCH] Fixed issue with invalid "YBR_FULL" DICOM images.
|
|
|
|
|
|
|
|
|
|
Fixed an issue when processing an invalid DICOM image with a Photometric
|
|
|
|
|
Interpretation of "YBR_FULL" and a Planar Configuration of "1" where
|
|
|
|
|
the number of pixels stored does not match the expected number of pixels
|
|
|
|
|
(much too less). Now, the pixel data of such an image is not processed
|
|
|
|
|
at all, but an empty image (black pixels) is created instead. The user
|
|
|
|
|
is warned about this by an appropriate log message.
|
|
|
|
|
|
|
|
|
|
Thanks to Ding zhengzheng <xiaozheng.ding399@gmail.com> for the report
|
|
|
|
|
and the sample file (PoC).
|
|
|
|
|
---
|
|
|
|
|
dcmimage/include/dcmtk/dcmimage/dicopxt.h | 6 +-
|
|
|
|
|
dcmimage/include/dcmtk/dcmimage/diybrpxt.h | 295 +++++++++++----------
|
|
|
|
|
dcmimgle/libsrc/dcmimage.cc | 3 +-
|
|
|
|
|
3 files changed, 160 insertions(+), 144 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/dcmimage/include/dcmtk/dcmimage/dicopxt.h b/dcmimage/include/dcmtk/dcmimage/dicopxt.h
|
|
|
|
|
index d812d16..d0ce15d 100644
|
|
|
|
|
--- a/dcmimage/include/dcmtk/dcmimage/dicopxt.h
|
|
|
|
|
+++ b/dcmimage/include/dcmtk/dcmimage/dicopxt.h
|
|
|
|
|
@@ -574,7 +574,11 @@ class DiColorPixelTemplate
|
|
|
|
|
{
|
|
|
|
|
/* erase empty part of the buffer (=blacken the background) */
|
|
|
|
|
if (InputCount < Count)
|
|
|
|
|
- OFBitmanipTemplate<T>::zeroMem(Data[j] + InputCount, Count - InputCount);
|
|
|
|
|
+ {
|
|
|
|
|
+ const size_t count = (Count - InputCount);
|
|
|
|
|
+ DCMIMAGE_TRACE("filing empty part of the intermediate pixel data (" << count << " pixels) of plane " << j << " with value = 0");
|
|
|
|
|
+ OFBitmanipTemplate<T>::zeroMem(Data[j] + InputCount, count);
|
|
|
|
|
+ }
|
|
|
|
|
} else {
|
|
|
|
|
DCMIMAGE_DEBUG("cannot allocate memory buffer for 'Data[" << j << "]' in DiColorPixelTemplate::Init()");
|
|
|
|
|
result = 0; // at least one buffer could not be allocated!
|
|
|
|
|
diff --git a/dcmimage/include/dcmtk/dcmimage/diybrpxt.h b/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
|
|
|
|
|
index 9655729..c5415c1 100644
|
|
|
|
|
--- a/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
|
|
|
|
|
+++ b/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
|
|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
- * Copyright (C) 1998-2016, OFFIS e.V.
|
|
|
|
|
+ * Copyright (C) 1998-2025, OFFIS e.V.
|
|
|
|
|
* All rights reserved. See COPYRIGHT file for details.
|
|
|
|
|
*
|
|
|
|
|
* This software and supporting documentation were developed by
|
|
|
|
|
@@ -24,6 +24,7 @@
|
|
|
|
|
#define DIYBRPXT_H
|
|
|
|
|
|
|
|
|
|
#include "dcmtk/config/osconfig.h"
|
|
|
|
|
+#include "dcmtk/ofstd/ofbmanip.h"
|
|
|
|
|
|
|
|
|
|
#include "dcmtk/dcmimage/dicopxt.h"
|
|
|
|
|
#include "dcmtk/dcmimgle/diinpx.h" /* gcc 3.4 needs this */
|
|
|
|
|
@@ -90,179 +91,189 @@ class DiYBRPixelTemplate
|
|
|
|
|
// use the number of input pixels derived from the length of the 'PixelData'
|
|
|
|
|
// attribute), but not more than the size of the intermediate buffer
|
|
|
|
|
const unsigned long count = (this->InputCount < this->Count) ? this->InputCount : this->Count;
|
|
|
|
|
- if (rgb) /* convert to RGB model */
|
|
|
|
|
+ // make sure that there is sufficient input data (for planar pixel data)
|
|
|
|
|
+ if (!this->PlanarConfiguration || (count >= planeSize * 3 /* number of planes */))
|
|
|
|
|
{
|
|
|
|
|
- T2 *r = this->Data[0];
|
|
|
|
|
- T2 *g = this->Data[1];
|
|
|
|
|
- T2 *b = this->Data[2];
|
|
|
|
|
- const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits));
|
|
|
|
|
- DiPixelRepresentationTemplate<T1> rep;
|
|
|
|
|
- if (bits == 8 && !rep.isSigned()) // only for unsigned 8 bit
|
|
|
|
|
+ if (rgb) /* convert to RGB model */
|
|
|
|
|
{
|
|
|
|
|
- Sint16 rcr_tab[256];
|
|
|
|
|
- Sint16 gcb_tab[256];
|
|
|
|
|
- Sint16 gcr_tab[256];
|
|
|
|
|
- Sint16 bcb_tab[256];
|
|
|
|
|
- const double r_const = 0.7010 * OFstatic_cast(double, maxvalue);
|
|
|
|
|
- const double g_const = 0.5291 * OFstatic_cast(double, maxvalue);
|
|
|
|
|
- const double b_const = 0.8859 * OFstatic_cast(double, maxvalue);
|
|
|
|
|
- unsigned long l;
|
|
|
|
|
- for (l = 0; l < 256; ++l)
|
|
|
|
|
+ T2 *r = this->Data[0];
|
|
|
|
|
+ T2 *g = this->Data[1];
|
|
|
|
|
+ T2 *b = this->Data[2];
|
|
|
|
|
+ const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits));
|
|
|
|
|
+ DiPixelRepresentationTemplate<T1> rep;
|
|
|
|
|
+ if (bits == 8 && !rep.isSigned()) // only for unsigned 8 bit
|
|
|
|
|
{
|
|
|
|
|
- rcr_tab[l] = OFstatic_cast(Sint16, 1.4020 * OFstatic_cast(double, l) - r_const);
|
|
|
|
|
- gcb_tab[l] = OFstatic_cast(Sint16, 0.3441 * OFstatic_cast(double, l));
|
|
|
|
|
- gcr_tab[l] = OFstatic_cast(Sint16, 0.7141 * OFstatic_cast(double, l) - g_const);
|
|
|
|
|
- bcb_tab[l] = OFstatic_cast(Sint16, 1.7720 * OFstatic_cast(double, l) - b_const);
|
|
|
|
|
- }
|
|
|
|
|
- Sint32 sr;
|
|
|
|
|
- Sint32 sg;
|
|
|
|
|
- Sint32 sb;
|
|
|
|
|
- if (this->PlanarConfiguration)
|
|
|
|
|
- {
|
|
|
|
|
-/*
|
|
|
|
|
- const T1 *y = pixel;
|
|
|
|
|
- const T1 *cb = y + this->InputCount;
|
|
|
|
|
- const T1 *cr = cb + this->InputCount;
|
|
|
|
|
- for (i = count; i != 0; --i, ++y, ++cb, ++cr)
|
|
|
|
|
+ Sint16 rcr_tab[256];
|
|
|
|
|
+ Sint16 gcb_tab[256];
|
|
|
|
|
+ Sint16 gcr_tab[256];
|
|
|
|
|
+ Sint16 bcb_tab[256];
|
|
|
|
|
+ const double r_const = 0.7010 * OFstatic_cast(double, maxvalue);
|
|
|
|
|
+ const double g_const = 0.5291 * OFstatic_cast(double, maxvalue);
|
|
|
|
|
+ const double b_const = 0.8859 * OFstatic_cast(double, maxvalue);
|
|
|
|
|
+ unsigned long l;
|
|
|
|
|
+ for (l = 0; l < 256; ++l)
|
|
|
|
|
{
|
|
|
|
|
- sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
|
|
|
|
|
- sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
|
|
|
|
|
- sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
|
|
|
|
|
- *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
|
|
|
|
|
- *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
|
|
|
|
|
- *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
|
|
|
|
|
+ rcr_tab[l] = OFstatic_cast(Sint16, 1.4020 * OFstatic_cast(double, l) - r_const);
|
|
|
|
|
+ gcb_tab[l] = OFstatic_cast(Sint16, 0.3441 * OFstatic_cast(double, l));
|
|
|
|
|
+ gcr_tab[l] = OFstatic_cast(Sint16, 0.7141 * OFstatic_cast(double, l) - g_const);
|
|
|
|
|
+ bcb_tab[l] = OFstatic_cast(Sint16, 1.7720 * OFstatic_cast(double, l) - b_const);
|
|
|
|
|
}
|
|
|
|
|
+ Sint32 sr;
|
|
|
|
|
+ Sint32 sg;
|
|
|
|
|
+ Sint32 sb;
|
|
|
|
|
+ if (this->PlanarConfiguration)
|
|
|
|
|
+ {
|
|
|
|
|
+/*
|
|
|
|
|
+ const T1 *y = pixel;
|
|
|
|
|
+ const T1 *cb = y + this->InputCount;
|
|
|
|
|
+ const T1 *cr = cb + this->InputCount;
|
|
|
|
|
+ for (i = count; i != 0; --i, ++y, ++cb, ++cr)
|
|
|
|
|
+ {
|
|
|
|
|
+ sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
|
|
|
|
|
+ sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
|
|
|
|
|
+ sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
|
|
|
|
|
+ *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
|
|
|
|
|
+ *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
|
|
|
|
|
+ *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
|
|
|
|
|
+ }
|
|
|
|
|
*/
|
|
|
|
|
- const T1 *y = pixel;
|
|
|
|
|
- const T1 *cb = y + planeSize;
|
|
|
|
|
- const T1 *cr = cb + planeSize;
|
|
|
|
|
- unsigned long i = count;
|
|
|
|
|
- while (i != 0)
|
|
|
|
|
+ const T1 *y = pixel;
|
|
|
|
|
+ const T1 *cb = y + planeSize;
|
|
|
|
|
+ const T1 *cr = cb + planeSize;
|
|
|
|
|
+ unsigned long i = count;
|
|
|
|
|
+ while (i != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ /* convert a single frame */
|
|
|
|
|
+ for (l = planeSize; (l != 0) && (i != 0); --l, --i, ++y, ++cb, ++cr)
|
|
|
|
|
+ {
|
|
|
|
|
+ sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
|
|
|
|
|
+ sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
|
|
|
|
|
+ sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
|
|
|
|
|
+ *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
|
|
|
|
|
+ *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
|
|
|
|
|
+ *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
|
|
|
|
|
+ }
|
|
|
|
|
+ /* jump to next frame start (skip 2 planes) */
|
|
|
|
|
+ y += 2 * planeSize;
|
|
|
|
|
+ cb += 2 * planeSize;
|
|
|
|
|
+ cr += 2 * planeSize;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
{
|
|
|
|
|
- /* convert a single frame */
|
|
|
|
|
- for (l = planeSize; (l != 0) && (i != 0); --l, --i, ++y, ++cb, ++cr)
|
|
|
|
|
+ const T1 *p = pixel;
|
|
|
|
|
+ T1 y;
|
|
|
|
|
+ T1 cb;
|
|
|
|
|
+ T1 cr;
|
|
|
|
|
+ unsigned long i;
|
|
|
|
|
+ for (i = count; i != 0; --i)
|
|
|
|
|
{
|
|
|
|
|
- sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, *cr)]);
|
|
|
|
|
- sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, *cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, *cr)]);
|
|
|
|
|
- sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, *cb)]);
|
|
|
|
|
+ y = *(p++);
|
|
|
|
|
+ cb = *(p++);
|
|
|
|
|
+ cr = *(p++);
|
|
|
|
|
+ sr = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, rcr_tab[cr]);
|
|
|
|
|
+ sg = OFstatic_cast(Sint32, y) - OFstatic_cast(Sint32, gcb_tab[cb]) - OFstatic_cast(Sint32, gcr_tab[cr]);
|
|
|
|
|
+ sb = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, bcb_tab[cb]);
|
|
|
|
|
*(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
|
|
|
|
|
*(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
|
|
|
|
|
*(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
|
|
|
|
|
}
|
|
|
|
|
- /* jump to next frame start (skip 2 planes) */
|
|
|
|
|
- y += 2 * planeSize;
|
|
|
|
|
- cb += 2 * planeSize;
|
|
|
|
|
- cr += 2 * planeSize;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
- const T1 *p = pixel;
|
|
|
|
|
- T1 y;
|
|
|
|
|
- T1 cb;
|
|
|
|
|
- T1 cr;
|
|
|
|
|
- unsigned long i;
|
|
|
|
|
- for (i = count; i != 0; --i)
|
|
|
|
|
+ if (this->PlanarConfiguration)
|
|
|
|
|
+ {
|
|
|
|
|
+/*
|
|
|
|
|
+ const T1 *y = pixel;
|
|
|
|
|
+ const T1 *cb = y + this->InputCount;
|
|
|
|
|
+ const T1 *cr = cb + this->InputCount;
|
|
|
|
|
+ for (i = count; i != 0; --i)
|
|
|
|
|
+ convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
|
|
|
|
|
+ removeSign(*(cr++), offset), maxvalue);
|
|
|
|
|
+*/
|
|
|
|
|
+ unsigned long l;
|
|
|
|
|
+ unsigned long i = count;
|
|
|
|
|
+ const T1 *y = pixel;
|
|
|
|
|
+ const T1 *cb = y + planeSize;
|
|
|
|
|
+ const T1 *cr = cb + planeSize;
|
|
|
|
|
+ while (i != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ /* convert a single frame */
|
|
|
|
|
+ for (l = planeSize; (l != 0) && (i != 0); --l, --i)
|
|
|
|
|
+ {
|
|
|
|
|
+ convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
|
|
|
|
|
+ removeSign(*(cr++), offset), maxvalue);
|
|
|
|
|
+ }
|
|
|
|
|
+ /* jump to next frame start (skip 2 planes) */
|
|
|
|
|
+ y += 2 * planeSize;
|
|
|
|
|
+ cb += 2 * planeSize;
|
|
|
|
|
+ cr += 2 * planeSize;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
{
|
|
|
|
|
- y = *(p++);
|
|
|
|
|
- cb = *(p++);
|
|
|
|
|
- cr = *(p++);
|
|
|
|
|
- sr = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, cr)]);
|
|
|
|
|
- sg = OFstatic_cast(Sint32, y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, cr)]);
|
|
|
|
|
- sb = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, cb)]);
|
|
|
|
|
- *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
|
|
|
|
|
- *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
|
|
|
|
|
- *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
|
|
|
|
|
+ const T1 *p = pixel;
|
|
|
|
|
+ T2 y;
|
|
|
|
|
+ T2 cb;
|
|
|
|
|
+ T2 cr;
|
|
|
|
|
+ unsigned long i;
|
|
|
|
|
+ for (i = count; i != 0; --i)
|
|
|
|
|
+ {
|
|
|
|
|
+ y = removeSign(*(p++), offset);
|
|
|
|
|
+ cb = removeSign(*(p++), offset);
|
|
|
|
|
+ cr = removeSign(*(p++), offset);
|
|
|
|
|
+ convertValue(*(r++), *(g++), *(b++), y, cb, cr, maxvalue);
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
+ } else { /* retain YCbCr model */
|
|
|
|
|
+ const T1 *p = pixel;
|
|
|
|
|
if (this->PlanarConfiguration)
|
|
|
|
|
{
|
|
|
|
|
-/*
|
|
|
|
|
- const T1 *y = pixel;
|
|
|
|
|
- const T1 *cb = y + this->InputCount;
|
|
|
|
|
- const T1 *cr = cb + this->InputCount;
|
|
|
|
|
- for (i = count; i != 0; --i)
|
|
|
|
|
- convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
|
|
|
|
|
- removeSign(*(cr++), offset), maxvalue);
|
|
|
|
|
-*/
|
|
|
|
|
+ /*
|
|
|
|
|
+ T2 *q;
|
|
|
|
|
+ // number of pixels to be skipped (only applicable if 'PixelData' contains more
|
|
|
|
|
+ // pixels than expected)
|
|
|
|
|
+ const unsigned long skip = (this->InputCount > this->Count) ? (this->InputCount - this->Count) : 0;
|
|
|
|
|
+ for (int j = 0; j < 3; ++j)
|
|
|
|
|
+ {
|
|
|
|
|
+ q = this->Data[j];
|
|
|
|
|
+ for (i = count; i != 0; --i)
|
|
|
|
|
+ *(q++) = removeSign(*(p++), offset);
|
|
|
|
|
+ // skip to beginning of next plane
|
|
|
|
|
+ p += skip;
|
|
|
|
|
+ }
|
|
|
|
|
+ */
|
|
|
|
|
unsigned long l;
|
|
|
|
|
- unsigned long i = count;
|
|
|
|
|
- const T1 *y = pixel;
|
|
|
|
|
- const T1 *cb = y + planeSize;
|
|
|
|
|
- const T1 *cr = cb + planeSize;
|
|
|
|
|
- while (i != 0)
|
|
|
|
|
+ unsigned long i = 0;
|
|
|
|
|
+ while (i < count)
|
|
|
|
|
{
|
|
|
|
|
- /* convert a single frame */
|
|
|
|
|
- for (l = planeSize; (l != 0) && (i != 0); --l, --i)
|
|
|
|
|
+ /* store current pixel index */
|
|
|
|
|
+ const unsigned long iStart = i;
|
|
|
|
|
+ for (int j = 0; j < 3; ++j)
|
|
|
|
|
{
|
|
|
|
|
- convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
|
|
|
|
|
- removeSign(*(cr++), offset), maxvalue);
|
|
|
|
|
+ /* convert a single plane */
|
|
|
|
|
+ for (l = planeSize, i = iStart; (l != 0) && (i < count); --l, ++i)
|
|
|
|
|
+ this->Data[j][i] = removeSign(*(p++), offset);
|
|
|
|
|
}
|
|
|
|
|
- /* jump to next frame start (skip 2 planes) */
|
|
|
|
|
- y += 2 * planeSize;
|
|
|
|
|
- cb += 2 * planeSize;
|
|
|
|
|
- cr += 2 * planeSize;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
- const T1 *p = pixel;
|
|
|
|
|
- T2 y;
|
|
|
|
|
- T2 cb;
|
|
|
|
|
- T2 cr;
|
|
|
|
|
+ int j;
|
|
|
|
|
unsigned long i;
|
|
|
|
|
- for (i = count; i != 0; --i)
|
|
|
|
|
- {
|
|
|
|
|
- y = removeSign(*(p++), offset);
|
|
|
|
|
- cb = removeSign(*(p++), offset);
|
|
|
|
|
- cr = removeSign(*(p++), offset);
|
|
|
|
|
- convertValue(*(r++), *(g++), *(b++), y, cb, cr, maxvalue);
|
|
|
|
|
- }
|
|
|
|
|
+ for (i = 0; i < count; ++i) /* for all pixel ... */
|
|
|
|
|
+ for (j = 0; j < 3; ++j)
|
|
|
|
|
+ this->Data[j][i] = removeSign(*(p++), offset); /* ... copy planes */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
- } else { /* retain YCbCr model */
|
|
|
|
|
- const T1 *p = pixel;
|
|
|
|
|
- if (this->PlanarConfiguration)
|
|
|
|
|
- {
|
|
|
|
|
-/*
|
|
|
|
|
- T2 *q;
|
|
|
|
|
- // number of pixels to be skipped (only applicable if 'PixelData' contains more
|
|
|
|
|
- // pixels than expected)
|
|
|
|
|
- const unsigned long skip = (this->InputCount > this->Count) ? (this->InputCount - this->Count) : 0;
|
|
|
|
|
- for (int j = 0; j < 3; ++j)
|
|
|
|
|
- {
|
|
|
|
|
- q = this->Data[j];
|
|
|
|
|
- for (i = count; i != 0; --i)
|
|
|
|
|
- *(q++) = removeSign(*(p++), offset);
|
|
|
|
|
- // skip to beginning of next plane
|
|
|
|
|
- p += skip;
|
|
|
|
|
- }
|
|
|
|
|
-*/
|
|
|
|
|
- unsigned long l;
|
|
|
|
|
- unsigned long i = 0;
|
|
|
|
|
- while (i < count)
|
|
|
|
|
- {
|
|
|
|
|
- /* store current pixel index */
|
|
|
|
|
- const unsigned long iStart = i;
|
|
|
|
|
- for (int j = 0; j < 3; ++j)
|
|
|
|
|
- {
|
|
|
|
|
- /* convert a single plane */
|
|
|
|
|
- for (l = planeSize, i = iStart; (l != 0) && (i < count); --l, ++i)
|
|
|
|
|
- this->Data[j][i] = removeSign(*(p++), offset);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- int j;
|
|
|
|
|
- unsigned long i;
|
|
|
|
|
- for (i = 0; i < count; ++i) /* for all pixel ... */
|
|
|
|
|
- for (j = 0; j < 3; ++j)
|
|
|
|
|
- this->Data[j][i] = removeSign(*(p++), offset); /* ... copy planes */
|
|
|
|
|
- }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // do not process the input data, as it is too short
|
|
|
|
|
+ DCMIMAGE_WARN("input data is too short, filling the complete image with black pixels");
|
|
|
|
|
+ // erase empty part of the buffer (that has not been "blackened" yet)
|
|
|
|
|
+ for (int j = 0; j < 3; ++j)
|
|
|
|
|
+ OFBitmanipTemplate<T2>::zeroMem(this->Data[j], count);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
diff --git a/dcmimgle/libsrc/dcmimage.cc b/dcmimgle/libsrc/dcmimage.cc
|
|
|
|
|
index bc395a2..ed10726 100644
|
|
|
|
|
--- a/dcmimgle/libsrc/dcmimage.cc
|
|
|
|
|
+++ b/dcmimgle/libsrc/dcmimage.cc
|
|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
- * Copyright (C) 1996-2024, OFFIS e.V.
|
|
|
|
|
+ * Copyright (C) 1996-2025, OFFIS e.V.
|
|
|
|
|
* All rights reserved. See COPYRIGHT file for details.
|
|
|
|
|
*
|
|
|
|
|
* This software and supporting documentation were developed by
|
|
|
|
|
@@ -210,6 +210,7 @@ void DicomImage::Init()
|
|
|
|
|
*(q++) = c;
|
|
|
|
|
}
|
|
|
|
|
*q = '\0'; // end of C string
|
|
|
|
|
+ DCMIMGLE_DEBUG("filtered version of 'PhotometricInterpretation' = " << OFSTRING_GUARD(cstr));
|
|
|
|
|
while ((pin->Name != NULL) && (strcmp(pin->Name, cstr) != 0))
|
|
|
|
|
++pin;
|
|
|
|
|
delete[] cstr;
|
|
|
|
|
--
|
|
|
|
|
2.51.0
|
|
|
|
|
|