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