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