1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * filename: m-color.c *
3 * *
4 * UTIL C-source: Medical Image Conversion Utility *
5 * *
6 * purpose : make color palettes *
7 * *
8 * project : (X)MedCon by Erik Nolf *
9 * *
10 * Functions : MdcLoadLUT() - Load LUT file into RGB array *
11 * MdcGrayScale() - Make gray palette *
12 * MdcInvertedScale() - Make inverted gray palette *
13 * MdcRainbowScale() - Make rainbow palette *
14 * MdcCombinedScale() - Make combined palette *
15 * MdcHotmetalScale() - Make hotmetal palette *
16 * MdcGetColorMap() - Get the specified palette *
17 * MdcSetPresentMap() - Preserve colormap in colored file *
18 * *
19 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20 /*
21 */
22
23 /*
24 Copyright (C) 1997-2021 by Erik Nolf
25
26 This program is free software; you can redistribute it and/or modify it
27 under the terms of the GNU General Public License as published by the
28 Free Software Foundation; either version 2, or (at your option) any later
29 version.
30
31 This program is distributed in the hope that it will be useful, but
32 WITHOUT ANY WARRANTY; without even the implied warranty of
33 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
34 Public License for more details.
35
36 You should have received a copy of the GNU General Public License along
37 with this program; if not, write to the Free Software Foundation, Inc.,
38 59 Place - Suite 330, Boston, MA 02111-1307, USA. */
39
40 /****************************************************************************
41 H E A D E R S
42 ****************************************************************************/
43
44 #include "m-depend.h"
45
46 #include <stdio.h>
47 #ifdef HAVE_STRING_H
48 #include <string.h>
49 #endif
50 #ifdef HAVE_STRINGS_H
51 #ifndef _WIN32
52 #include <strings.h>
53 #endif
54 #endif
55 #include "m-defs.h"
56 #include "m-global.h"
57 #include "m-color.h"
58
59 /****************************************************************************
60 D E F I N E S
61 ****************************************************************************/
62
63 static Uint8 loaded_map[768], LOADED = MDC_NO;
64 static Uint8 present_map[768]; /* map from file */
65
66 /* cti source */
67 struct {int n,r,g,b,dr,dg,db; }
68 bitty[] = { {32,0,0,0,2,0,4}, /* violet to indigo */
69 {32,64,0,128,-2,0,4}, /* indigo to blue */
70 {32,0,0,255,0,8,-8}, /* blue to green */
71 {64,0,255,0,4,0,0}, /* green to yellow */
72 {32,255,255,0,0,-2,0}, /* yellow to orange */
73 {64,255,192,0,0,-3,0} }; /* orange to red */
74
75
76 /****************************************************************************
77 F U N C T I O N S
78 ****************************************************************************/
MdcLoadLUT(const char * lutname)79 int MdcLoadLUT(const char *lutname)
80 {
81 FILE *fp;
82 int s;
83
84 LOADED = MDC_NO;
85
86 if ((fp=fopen(lutname,"rb")) == NULL) return(MDC_NO);
87
88 LOADED = MDC_YES;
89
90 /* get red values */
91 for (s=0; s<768; s+=3) loaded_map[s] = (Uint8)fgetc(fp);
92 /* get green values */
93 for (s=1; s<768; s+=3) loaded_map[s] = (Uint8)fgetc(fp);
94 /* get blue values */
95 for (s=2; s<768; s+=3) loaded_map[s] = (Uint8)fgetc(fp);
96
97 fclose(fp);
98
99 return(MDC_YES);
100 }
101
MdcGrayScale(Uint8 * palette)102 void MdcGrayScale(Uint8 *palette)
103 {
104 int i;
105 Uint8 gray;
106
107 for (i=0; i<256; i++) {
108 gray = (Uint8)i;
109 palette[i*3]=palette[i*3+1]=palette[i*3+2]=gray;
110 }
111
112 }
113
MdcInvertedScale(Uint8 * palette)114 void MdcInvertedScale(Uint8 *palette)
115 {
116 int i;
117 Uint8 gray;
118
119
120 for (i=0; i<256; i++) {
121 gray = 255 - (Uint8)i;
122 palette[i*3]=palette[i*3+1]=palette[i*3+2]=gray;
123 }
124
125 }
126
MdcRainbowScale(Uint8 * palette)127 void MdcRainbowScale(Uint8 *palette)
128 {
129 int p=0,i,j,r,g,b;
130
131 for (j=0;j<6;j++) {
132 palette[p++]=r=bitty[j].r;
133 palette[p++]=g=bitty[j].g;
134 palette[p++]=b=bitty[j].b;
135 for (i=1;i<bitty[j].n;i++) {
136 r+=bitty[j].dr; palette[p++]=r;
137 g+=bitty[j].dg; palette[p++]=g;
138 b+=bitty[j].db; palette[p++]=b;
139 }
140 }
141 }
142
MdcCombinedScale(Uint8 * palette)143 void MdcCombinedScale(Uint8 *palette)
144 {
145 int t=0,p=0,i,j,r,g,b;
146
147 /* lower 128 = gray levels */
148 for (i=0; i<256; i+=2) {
149 palette[t*3]=palette[t*3+1]=palette[t*3+2]=(Uint8)i; t+=1;
150 }
151
152 /* upper 128 = rainbow levels */
153 for (j=0;j<6;j++) {
154 r=bitty[j].r;
155 g=bitty[j].g;
156 b=bitty[j].b;
157 if (p++ % 2 && p <= 256) {
158 palette[t*3] =(Uint8)r;
159 palette[t*3+1]=(Uint8)g;
160 palette[t*3+2]=(Uint8)b;
161 t+=1;
162 }
163 for (i=1;i<bitty[j].n;i++) {
164 r+=bitty[j].dr;
165 g+=bitty[j].dg;
166 b+=bitty[j].db;
167 if (p++ % 2 && p <= 256) {
168 palette[t*3] =(Uint8)r;
169 palette[t*3+1]=(Uint8)g;
170 palette[t*3+2]=(Uint8)b;
171 t+=1;
172 }
173 }
174 }
175 }
176
MdcHotmetalScale(Uint8 * palette)177 void MdcHotmetalScale(Uint8 *palette)
178 {
179 int i, p=0;
180 float intensity, delta_intensity;
181
182 intensity = 0.0;
183 delta_intensity = 1.0/182;
184 for (p=0, i=0;i<182;i++,p+=3) { /* red */
185 palette[p]=255*intensity;
186 intensity+=delta_intensity;
187 }
188 for (i=182;i<256;i++,p+=3) palette[p]=255;
189 for (i=0,p=1;i<128;i++,p+=3) palette[p]=0; /* green */
190 intensity = 0.0;
191 delta_intensity = 1.0/91;
192 for (i=128;i<219; i++,p+=3) {
193 palette[p]=255*intensity;
194 intensity+=delta_intensity;
195 }
196 for (i=219;i<256;i++,p+=3) palette[p]=255;
197 for (i=0,p=2;i<192;i++,p+=3) palette[p]=0; /* blue */
198 intensity=0.0;
199 delta_intensity = 1.0/64;
200 for (i=192;i<256;i++,p+=3) {
201 palette[p]=255*intensity;
202 intensity += delta_intensity;
203 }
204 }
205
MdcGetColorMap(int map,Uint8 palette[])206 void MdcGetColorMap(int map, Uint8 palette[])
207 {
208
209 switch (map) {
210 case MDC_MAP_PRESENT : memcpy(palette,present_map,768);
211 break;
212 case MDC_MAP_GRAY : MdcGrayScale(palette);
213 break;
214 case MDC_MAP_INVERTED: MdcInvertedScale(palette);
215 break;
216 case MDC_MAP_RAINBOW : MdcRainbowScale(palette);
217 break;
218 case MDC_MAP_COMBINED: MdcCombinedScale(palette);
219 break;
220 case MDC_MAP_HOTMETAL: MdcHotmetalScale(palette);
221 break;
222 case MDC_MAP_LOADED :
223 if (LOADED == MDC_YES) memcpy(palette,loaded_map,768);
224 break;
225 default: MdcGrayScale(palette);
226 }
227
228 }
229
MdcSetPresentMap(Uint8 palette[])230 int MdcSetPresentMap(Uint8 palette[])
231 {
232 memcpy(present_map,palette,768);
233
234 return(MDC_MAP_PRESENT);
235 }
236