1
2 /* ==================================================================
3 FILE: "/home/joze/pub/zimg/zimg/color.c"
4 LAST MODIFIED: "Wed, 02 Jul 2003 21:10:52 CEST (joze)"
5 (C) 1999 - 2003 by Johannes Zellner
6 johannes@zellner.org
7 $Id: color.c,v 1.19 2003/07/02 19:19:56 joze Exp $
8 ---
9 Copyright (c) 1999 - 2003, Johannes Zellner <johannes@zellner.org>
10 All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 * Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18 * Redistributions in binary form must reproduce the above copyright
19 notice, this list of conditions and the following disclaimer in the
20 documentation and/or other materials provided with the distribution.
21 * Neither the name of Johannes Zellner nor the names of contributors
22 to this software may be used to endorse or promote products derived
23 from this software without specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
29 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 ================================================================== */
37
38 #ifdef HAVE_CONFIG_H
39 # include "config.h"
40 #endif
41
42 #include "zimg_priv.h"
43 #include "zimg.h"
44 #include "path.h"
45
get_next_custom_entry(FILE * fp)46 int* get_next_custom_entry (FILE* fp)
47 {
48 static int itmp[3];
49 char buf[BUFSIZ];
50 while (fgets (buf, sizeof (buf), fp)) {
51 if (*buf == '#') {
52 /* skip lines which start with a # mark */
53 /* fprintf (stderr, "skipping |%s|\n", buf); */
54 continue;
55 }
56 if (sscanf (buf, "%i%i%i", itmp, itmp + 1, itmp + 2) != 3
57 || itmp[0] < 0 || itmp[0] > 0xff
58 || itmp[1] < 0 || itmp[1] > 0xff
59 || itmp[2] < 0 || itmp[2] > 0xff) {
60 char* ptr;
61 /* check if it's an empty line */
62 for (ptr = buf; ptr && *ptr; ptr++) {
63 if (!(' ' == *ptr || '\t' == *ptr || '\n' == *ptr)) {
64 fprintf (stderr, "bad line `%s' in colormap file\n", buf);
65 exit (1);
66 }
67 }
68 /* it's an empty line --> read the next line */
69 continue;
70 } else {
71 return (itmp);
72 }
73 }
74 return ((int *) NULL);
75 }
76
77 int
zimg_dump_color(gdImagePtr im,int r,int g,int b)78 zimg_dump_color(gdImagePtr im, int r, int g, int b)
79 {
80 printf("%3d %3d %3d\n", r, g, b);
81 return 0;
82 }
83
84 static void
invert_colormap(int gdcolor[0x100],int len)85 invert_colormap(int gdcolor[0x100], int len)
86 {
87 int* tmp;
88 int i, j;
89
90 assert(len > 0);
91
92 tmp = (int*)malloc(sizeof (int) * len);
93
94 if (!tmp) {
95 perror("invert_colormap->tmp");
96 exit(2);
97 }
98 memcpy(tmp, gdcolor, len * sizeof (int));
99
100 for (i = 0, j = len - 1; j >= 0; i++, j--) {
101 gdcolor[i] = tmp[j];
102 }
103
104 free(tmp);
105 }
106
107 int
getGdColorMap(gdImagePtr im,int gdcolor[0x100],const int color,int rgbformulae[3],char * colormapfile,const zimg_color_t * xor_color)108 getGdColorMap(gdImagePtr im, int gdcolor[0x100],
109 const int color, int rgbformulae[3], char *colormapfile,
110 const zimg_color_t* xor_color)
111 {
112 int i, j, len = ZIMG_MAP_COLORS;
113 double color_scaling = 0xff / ZIMG_MAP_COLORS;
114 int R = 0, G = 0, B = 0;
115 int (*allocColor)(gdImagePtr, int, int, int) = gdImageColorAllocate;
116
117 if (!im) {
118 printf("# zimg colormap\n");
119 if (color & RGBMAP) {
120 printf("# -m%d,%d,%d\n", rgbformulae[0],
121 rgbformulae[1], rgbformulae[2]);
122 } else if (color & REDMAP) {
123 printf("# --red\n");
124 } else if (color & BLUEMAP) {
125 printf("# --blue\n");
126 } else if (color & GRAYMAP) {
127 printf("# --gray\n");
128 } else if (colormapfile) {
129 printf("# -m%s\n", colormapfile);
130 }
131 allocColor = zimg_dump_color;
132 }
133
134 if (color & XOR_MAP) {
135 R = xor_color->red;
136 G = xor_color->green;
137 B = xor_color->blue;
138 }
139
140 if (color & RGBMAP) {
141 double dlen = (double) --len;
142 for (i = 0; i < len; i++) {
143 double gray = (double) i / dlen;
144 int red = (int) (GetColorValueFromFormula
145 (rgbformulae[0], gray) * dlen);
146 int green = (int) (GetColorValueFromFormula
147 (rgbformulae[1], gray) * dlen);
148 int blue = (int) (GetColorValueFromFormula
149 (rgbformulae[2], gray) * dlen);
150 gdcolor[i] = allocColor(im, red^R, green^G, blue^B);
151 #if 0
152 fprintf(stderr, "(getGdColorMap) %02x,%02x,%02x\n", red, green, blue);
153 #endif
154 }
155 } else if (color & REDMAP) {
156 for (j = 0, i = 0; j < len; i++, j += 3) {
157 gdcolor[i] = allocColor(im, ((int)((double)j * color_scaling))^R, 0^G, 0^B);
158 }
159 for (j = 0; j < len; i++, j += 3) {
160 gdcolor[i] = allocColor(im, 0xff^R, ((int)((double)j * color_scaling))^G, 0^B);
161 }
162 for (j = 0; i < len; i++, j += 3) {
163 gdcolor[i] = allocColor(im, 0xff^R, 0xff^G, ((int)((double)j * color_scaling))^B);
164 }
165 len = i; /* actually allocated colors */
166 } else if (color & BLUEMAP) {
167 for (j = 0, i = 0; j < len; i++, j += 3) {
168 gdcolor[i] = allocColor(im, 0^R, 0^G, ((int)((double)j * color_scaling))^B);
169 }
170 for (j = 0; j < len; i++, j += 3) {
171 gdcolor[i] = allocColor(im, ((int)((double)j * color_scaling))^R, 0^G, 0xff^B);
172 }
173 for (j = 0; i < len; i++, j += 3) {
174 gdcolor[i] = allocColor(im, 0xff^R, ((int)((double)j * color_scaling))^G, 0xff^B);
175 }
176 len = i; /* actually allocated colors */
177 } else if (color & GRAYMAP) {
178 for (i = 0; i < len; i++) {
179 int c = (int)((double)i * color_scaling);
180 gdcolor[i] = allocColor(im, c^R, c^G, c^B);
181 }
182 } else if (colormapfile) {
183 /* read custom colormap file */
184 int* itmp;
185 FILE* fp = (FILE*)0;
186 char* path_colormapfile = search_file(colormapfile, "cmap", PKGDATADIR, 0 /* relative */);
187 if (!path_colormapfile)
188 Fatal("unable to find colormap file ");
189 fp = fopen(path_colormapfile, "r");
190 len = 0;
191 if (!fp) {
192 perror(path_colormapfile);
193 exit(2);
194 }
195 while (len < ZIMG_MAP_COLORS && (itmp = get_next_custom_entry(fp))) {
196 gdcolor[len] = allocColor
197 (im, (itmp[0])^R, (itmp[1])^G, (itmp[2])^B);
198 len++;
199 }
200 fclose(fp);
201 free(path_colormapfile);
202 } else {
203 /* use default colormap */
204 int len1, len2, len3, len4;
205 len = ZIMG_MAP_COLORS;
206 len1 = len * 0.2;
207 len2 = len1 * 2;
208 len3 = len1 * 3;
209 len4 = len1 * 4;
210 #if 0
211 fprintf(stderr, "(getGdColorMap) len1 = %d\n", len1);
212 fprintf(stderr, "(getGdColorMap) len2 = %d\n", len2);
213 fprintf(stderr, "(getGdColorMap) len3 = %d\n", len3);
214 fprintf(stderr, "(getGdColorMap) len4 = %d\n", len4);
215 #endif
216 for (j = ZIMG_MAP_COLORS - 1, i = 0; i < len1; i++, j--) {
217 gdcolor[j] = allocColor(im,
218 ((int)((double)0xff))^R,
219 ((int)((double)0xff * (double)i / (double)len1))^G,
220 ((int)((double)0x00))^B);
221
222 }
223 for (; i < len2; i++, j--) {
224 gdcolor[j] = allocColor(im,
225 ((int)((double)0xff * (double)(len2 - i) / (double)len1))^R,
226 ((int)((double)0xff))^G,
227 ((int)((double)0x00))^B);
228
229 }
230 for (; i < len3; i++, j--) {
231 gdcolor[j] = allocColor(im,
232 ((int)((double)0x00))^R,
233 ((int)((double)0xff))^G,
234 ((int)((double)0xff * (double)(i - len2) / (double)len1))^B);
235
236 }
237 for (; i < len4; i++, j--) {
238 gdcolor[j] = allocColor(im,
239 ((int)((double)0x00))^R,
240 ((int)((double)0xff * (double)(len4 - i) / (double)len1))^G,
241 ((int)((double)0xff))^B);
242
243 }
244 for (; i < len; i++, j--) {
245 gdcolor[j] = allocColor(im,
246 ((int)((double)0xff * (double)(i - len4) / (double)len1))^R,
247 ((int)((double)0x00))^G,
248 ((int)((double)0xff))^B);
249
250 }
251 }
252
253 if (color & INVERT_MAP)
254 invert_colormap(gdcolor, len);
255
256 return len;
257 }
258
259 int
zimg_gdImageLineColorAllocate(gdImagePtr im,int red,int green,int blue)260 zimg_gdImageLineColorAllocate(gdImagePtr im,
261 int red, int green, int blue)
262 {
263 int color = gdImageColorExact(im, red, green, blue);
264 if (color < 0) {
265 color = gdImageColorAllocate(im, red, green, blue);
266 }
267 if (color < 0) {
268 color = gdImageColorClosest(im, red, green, blue);
269 }
270 return color;
271 }
272
273