1 /*
2 * file color.c - color and image manipulation
3 *
4 * $Id: color.c,v 1.5 2006/02/09 21:21:23 fzago Exp $
5 *
6 * Program XBLAST
7 * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2; or (at your option)
12 * any later version
13 *
14 * This program is distributed in the hope that it will be entertaining,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "xblast.h"
25
26 /*
27 * global function: CchToPpm
28 * description: converts ppm pixel data interpreting them as color/color/highlight
29 * parameters: ppm - pixel data in ppm format
30 * width - image width
31 * height - image height
32 * fg - base color (black most of the time)
33 * bg - first color (for red pixels)
34 * add - seconed color (for green pixels)
35 */
36 void
CchToPpm(unsigned char * ppm,int width,int height,XBColor fg,XBColor bg,XBColor add)37 CchToPpm (unsigned char *ppm, int width, int height, XBColor fg, XBColor bg, XBColor add)
38 {
39 int x, y;
40 unsigned red, green, blue;
41 unsigned fgRgb[3];
42 unsigned bgRgb[3];
43 unsigned addRgb[3];
44
45 /* convert colors */
46 fgRgb[0] = GET_RED (fg);
47 fgRgb[1] = GET_GREEN (fg);
48 fgRgb[2] = GET_BLUE (fg);
49
50 bgRgb[0] = GET_RED (bg);
51 bgRgb[1] = GET_GREEN (bg);
52 bgRgb[2] = GET_BLUE (bg);
53
54 addRgb[0] = GET_RED (add);
55 addRgb[1] = GET_GREEN (add);
56 addRgb[2] = GET_BLUE (add);
57
58 /* convert pixels */
59 for (y = 0; y < height; y++) {
60 for (x = 0; x < width; x++) {
61 /* blue is highlight only */
62 ppm[0] -= ppm[2];
63 ppm[1] -= ppm[2];
64 /* calc 16bit colors */
65 red =
66 31 * ppm[2] + fgRgb[0] * 255 + bgRgb[0] * ppm[0] - fgRgb[0] * ppm[0] +
67 addRgb[0] * ppm[1];
68 green =
69 31 * ppm[2] + fgRgb[1] * 255 + bgRgb[1] * ppm[0] - fgRgb[1] * ppm[0] +
70 addRgb[1] * ppm[1];
71 blue =
72 31 * ppm[2] + fgRgb[2] * 255 + bgRgb[2] * ppm[0] - fgRgb[2] * ppm[0] +
73 addRgb[2] * ppm[1];
74 /* cut off */
75 if (red > 8191) {
76 red = 8191;
77 }
78 if (green > 8191) {
79 green = 65535;
80 }
81 /* blue */
82 if (blue > 8191) {
83 blue = 8191;
84 }
85 /* rgb values are 13bit here */
86 ppm[0] = red >> 5;
87 ppm[1] = green >> 5;
88 ppm[2] = blue >> 5;
89
90 ppm += 3;
91 }
92 }
93 } /* CchToPpm */
94
95 /*
96 * global function: EpmToPpm
97 * description: converts ppm pixel data interpreting them as color/color/highlight
98 * parameters: ppm - pixel data in ppm format
99 * width - image width
100 * height - image height
101 * fg - base color (black most of the time)
102 * bg - first color (for red pixels)
103 * add - seconed color (for green pixels)
104 */
105 void
EpmToPpm(unsigned char * epm,unsigned char * ppm,int width,int height,int ncolors,const XBColor * color)106 EpmToPpm (unsigned char *epm, unsigned char *ppm, int width, int height, int ncolors,
107 const XBColor * color)
108 {
109 int i, x, y;
110 unsigned red, green, blue;
111 unsigned *cRed, *cGreen, *cBlue;
112 unsigned char **cEpm;
113
114 assert (epm != NULL);
115 assert (ppm != NULL);
116 /* alloc temp color arrays */
117 cRed = malloc (ncolors * sizeof (unsigned));
118 assert (cRed != NULL);
119 cGreen = malloc (ncolors * sizeof (unsigned));
120 assert (cGreen != NULL);
121 cBlue = malloc (ncolors * sizeof (unsigned));
122 assert (cBlue != NULL);
123 cEpm = malloc (ncolors * sizeof (unsigned char *));
124 assert (cEpm != NULL);
125 /* convert colors */
126 for (i = 0; i < ncolors; i++) {
127 cRed[i] = GET_RED (color[i]);
128 cGreen[i] = GET_GREEN (color[i]);
129 cBlue[i] = GET_BLUE (color[i]);
130 cEpm[i] = epm + i * width * height;
131 }
132 /* convert pixels */
133 for (y = 0; y < height; y++) {
134 for (x = 0; x < width; x++) {
135 red = blue = green = 0;
136 for (i = 0; i < ncolors; i++) {
137 red += cEpm[i][0] * cRed[i];
138 green += cEpm[i][0] * cGreen[i];
139 blue += cEpm[i][0] * cBlue[i];
140 cEpm[i]++;
141 }
142 /* cut off */
143 if (red > 8191) {
144 red = 8191;
145 }
146 if (green > 8191) {
147 green = 8191;
148 }
149 /* blue */
150 if (blue > 8191) {
151 blue = 8191;
152 }
153 /* rgb values are 13bit here */
154 ppm[0] = red >> 5;
155 ppm[1] = green >> 5;
156 ppm[2] = blue >> 5;
157 ppm += 3;
158 }
159 }
160 free (cEpm);
161 free (cBlue);
162 free (cGreen);
163 free (cRed);
164 } /* EpmToPpm */
165
166 /*
167 * convert color to string
168 */
169 const char *
ColorToString(XBColor color)170 ColorToString (XBColor color)
171 {
172 static char string[32];
173
174 assert (color != COLOR_INVALID);
175 sprintf (string, "#%02x%02x%02x", GET_RED (color) << 3, GET_GREEN (color) << 3,
176 GET_BLUE (color) << 3);
177 return string;
178 } /* ColorToString */
179
180 /*
181 * parse color from string
182 */
183 XBColor
StringToColor(const char * string)184 StringToColor (const char *string)
185 {
186 char hash;
187 unsigned red, green, blue;
188
189 assert (string != NULL);
190 if (4 != sscanf (string, "%c%2x%2x%2x", &hash, &red, &green, &blue)) {
191 return COLOR_INVALID;
192 }
193 if ('#' != hash) {
194 return COLOR_INVALID;
195 }
196 return SET_COLOR (red >> 3, green >> 3, blue >> 3);
197 } /* StringToColor */
198
199 /*
200 * create lighter version of color
201 */
202 XBColor
LighterColor(XBColor color)203 LighterColor (XBColor color)
204 {
205 unsigned r, g, b;
206
207 /* read colors */
208 r = GET_RED (color);
209 g = GET_GREEN (color);
210 b = GET_BLUE (color);
211 /* convert */
212 r += r / 4 + XBCOLOR_DEPTH / 4;
213 g += g / 4 + XBCOLOR_DEPTH / 4;
214 b += b / 4 + XBCOLOR_DEPTH / 4;
215 /* that'S all */
216 return SET_COLOR (r, g, b);
217 } /* LighterColor */
218
219 /*
220 * create lighter version of color
221 */
222 XBColor
DarkerColor(XBColor color)223 DarkerColor (XBColor color)
224 {
225 unsigned r, g, b;
226
227 /* read colors */
228 r = GET_RED (color);
229 g = GET_GREEN (color);
230 b = GET_BLUE (color);
231 /* convert */
232 r -= r / 2;
233 g -= g / 2;
234 b -= b / 2;
235 /* that'S all */
236 return SET_COLOR (r, g, b);
237 } /* LighterColor */
238
239 /*
240 * create a random color
241 */
242 XBColor
RandomColor(void)243 RandomColor (void)
244 {
245 return SET_COLOR (OtherRandomNumber (3) * XBCOLOR_DEPTH / 2,
246 OtherRandomNumber (3) * XBCOLOR_DEPTH / 2,
247 OtherRandomNumber (3) * XBCOLOR_DEPTH / 2);
248 } /* RandomColor */
249
250 /*
251 * end of file color.c
252 */
253