1 /*
2 *
3 * Copyright (C) 1996-2010, OFFIS e.V.
4 * All rights reserved. See COPYRIGHT file for details.
5 *
6 * This software and supporting documentation were developed by
7 *
8 * OFFIS e.V.
9 * R&D Division Health
10 * Escherweg 2
11 * D-26121 Oldenburg, Germany
12 *
13 *
14 * Module: dcmimage
15 *
16 * Author: Joerg Riesmeier
17 *
18 * Purpose: DicomPaletteImage (Source)
19 *
20 */
21
22
23 #include "dcmtk/config/osconfig.h"
24
25 #include "dcmtk/dcmdata/dctypes.h"
26 #include "dcmtk/dcmdata/dcdeftag.h"
27 #include "dcmtk/dcmdata/dctag.h"
28
29 #include "dcmtk/dcmimgle/didocu.h"
30 #include "dcmtk/dcmimage/dipalimg.h"
31 #include "dcmtk/dcmimage/dipalpxt.h"
32 #include "dcmtk/dcmimage/diqttype.h"
33 #include "dcmtk/dcmimage/dilogger.h"
34 #include "dcmtk/dcmimgle/diluptab.h"
35 #include "dcmtk/dcmimgle/diinpx.h"
36
37
38 /*----------------*
39 * constructors *
40 *----------------*/
41
DiPaletteImage(const DiDocument * docu,const EI_Status status)42 DiPaletteImage::DiPaletteImage(const DiDocument *docu,
43 const EI_Status status)
44 : DiColorImage(docu, status, 1),
45 Palette() // initializes the three color palettes to NULL
46 {
47 if ((Document != NULL) && (InputData != NULL) && (ImageStatus == EIS_Normal))
48 {
49 if (BitsStored <= MAX_TABLE_ENTRY_SIZE)
50 {
51 const EL_BitsPerTableEntry descMode = (docu->getFlags() & CIF_CheckLutBitDepth) ? ELM_CheckValue : ELM_UseValue;
52 /* wrong palette attribute tags used */
53 if (Document->getFlags() & CIF_WrongPaletteAttributeTags)
54 {
55 Palette[0] = new DiLookupTable(Document, DCM_RETIRED_LargeRedPaletteColorLookupTableDescriptor,
56 DCM_RETIRED_LargeRedPaletteColorLookupTableData, DCM_UndefinedTagKey /*explanation*/, descMode, &ImageStatus);
57 Palette[1] = new DiLookupTable(Document, DCM_RETIRED_LargeGreenPaletteColorLookupTableDescriptor,
58 DCM_RETIRED_LargeGreenPaletteColorLookupTableData, DCM_UndefinedTagKey /*explanation*/, descMode, &ImageStatus);
59 Palette[2] = new DiLookupTable(Document, DCM_RETIRED_LargeBluePaletteColorLookupTableDescriptor,
60 DCM_RETIRED_LargeBluePaletteColorLookupTableData, DCM_UndefinedTagKey /*explanation*/, descMode, &ImageStatus);
61 } else {
62 const Uint16 *dummy = NULL;
63 /* check for (non-empty) segmented palette */
64 if ((Document->getValue(DCM_SegmentedRedPaletteColorLookupTableData, dummy) > 0) ||
65 (Document->getValue(DCM_SegmentedGreenPaletteColorLookupTableData, dummy) > 0) ||
66 (Document->getValue(DCM_SegmentedBluePaletteColorLookupTableData, dummy) > 0))
67 {
68 DCMIMAGE_WARN("segmented palettes not yet supported ... ignoring");
69 }
70 /* read data from non-segmented palettes (if present) */
71 Palette[0] = new DiLookupTable(Document, DCM_RedPaletteColorLookupTableDescriptor,
72 DCM_RedPaletteColorLookupTableData, DCM_UndefinedTagKey /*explanation*/, descMode, &ImageStatus);
73 Palette[1] = new DiLookupTable(Document, DCM_GreenPaletteColorLookupTableDescriptor,
74 DCM_GreenPaletteColorLookupTableData, DCM_UndefinedTagKey /*explanation*/, descMode, &ImageStatus);
75 Palette[2] = new DiLookupTable(Document, DCM_BluePaletteColorLookupTableDescriptor,
76 DCM_BluePaletteColorLookupTableData, DCM_UndefinedTagKey /*explanation*/, descMode, &ImageStatus);
77 }
78 if ((ImageStatus == EIS_Normal) && (Palette[0] != NULL) && (Palette[1] != NULL) && (Palette[2] != NULL))
79 {
80 BitsPerSample = 0;
81 /* determine the maximum value for bits stored of the three lookup tables */
82 for (int jj = 0; jj < 3; jj++)
83 {
84 if (Palette[jj]->getBits() > OFstatic_cast(Uint16, BitsPerSample))
85 BitsPerSample = Palette[jj]->getBits();
86 }
87 if ((BitsPerSample < 1) || (BitsPerSample > MAX_TABLE_ENTRY_SIZE))
88 {
89 DCMIMAGE_WARN("invalid value for 'BitsPerSample' (" << BitsPerSample
90 << ") computed from color palettes");
91 }
92 Init(); // create intermediate representation
93 }
94 }
95 else
96 {
97 ImageStatus = EIS_InvalidValue;
98 DCMIMAGE_ERROR("invalid value for 'BitsStored' (" << BitsStored << ") "
99 << "... exceeds maximum palette entry size of " << MAX_TABLE_ENTRY_SIZE << " bits");
100 }
101 }
102 }
103
104
105 /*--------------*
106 * destructor *
107 *--------------*/
108
~DiPaletteImage()109 DiPaletteImage::~DiPaletteImage()
110 {
111 delete Palette[0];
112 delete Palette[1];
113 delete Palette[2];
114 }
115
116
117 /*********************************************************************/
118
119
Init()120 void DiPaletteImage::Init()
121 {
122 switch (InputData->getRepresentation())
123 {
124 case EPR_Uint8:
125 if (BitsPerSample <= 8)
126 InterData = new DiPalettePixelTemplate<Uint8, Uint32, Uint8>(Document, InputData, Palette, ImageStatus);
127 else
128 InterData = new DiPalettePixelTemplate<Uint8, Uint32, Uint16>(Document, InputData, Palette, ImageStatus);
129 break;
130 case EPR_Sint8:
131 if (BitsPerSample <= 8)
132 InterData = new DiPalettePixelTemplate<Sint8, Sint32, Uint8>(Document, InputData, Palette, ImageStatus);
133 else
134 InterData = new DiPalettePixelTemplate<Sint8, Sint32, Uint16>(Document, InputData, Palette, ImageStatus);
135 break;
136 case EPR_Uint16:
137 if (BitsPerSample <= 8)
138 InterData = new DiPalettePixelTemplate<Uint16, Uint32, Uint8>(Document, InputData, Palette, ImageStatus);
139 else
140 InterData = new DiPalettePixelTemplate<Uint16, Uint32, Uint16>(Document, InputData, Palette, ImageStatus);
141 break;
142 case EPR_Sint16:
143 if (BitsPerSample <= 8)
144 InterData = new DiPalettePixelTemplate<Sint16, Sint32, Uint8>(Document, InputData, Palette, ImageStatus);
145 else
146 InterData = new DiPalettePixelTemplate<Sint16, Sint32, Uint16>(Document, InputData, Palette, ImageStatus);
147 break;
148 default:
149 DCMIMAGE_WARN("invalid value for inter-representation");
150 }
151 deleteInputData();
152 checkInterData();
153 }
154
155
156 /*********************************************************************/
157
158
processNextFrames(const unsigned long fcount)159 int DiPaletteImage::processNextFrames(const unsigned long fcount)
160 {
161 if (DiImage::processNextFrames(fcount))
162 {
163 delete InterData;
164 InterData = NULL;
165 Init();
166 return (ImageStatus == EIS_Normal);
167 }
168 return 0;
169 }
170