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