1 /****************************************************************
2  * aimage.c
3  *
4  * Copyright (C) 1995-2002 Klaus Ehrenfried
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  *************************************************************************/
21 
22 #include <stdio.h>
23 #include <memory.h>
24 #include <stdlib.h>
25 
26 #include "apro.h"
27 
28 static void remap_image(UBYTE *pp, LONG color[], int len, int ncolor);
29 static void wobbel_image(PMS *image);
30 
31 /****************************************************************
32  * get_image
33  ****************************************************************/
34 
get_image(char * fname,UBYTE * data,LONG color_table[])35 void get_image(char *fname,UBYTE *data,LONG color_table[])
36 {
37   PMS image;					/* Image */
38   UBYTE *run_pp, *pdest, *psource, *raw_data;
39   LONG rgb_value;
40   int i, j, len, used_count, nhelp, image_width, ncolor;
41   int idstart, idend, jdstart, jdend, isstart, jsstart;
42   int x_origin, y_origin;
43   int histogram[FLI_MAX_COLORS];
44 
45   fprintf(stdout,"Load '%s'\n",fname);
46   image.pixels = (unsigned char *) NULL;
47   if (!read_image(&image, fname))
48     {
49       fprintf(stderr,"error reading '%s'\n",fname);
50       exitialise(1);
51       exit(1);
52     }
53 
54   if (individual_flag)
55     {
56       clear_octree();
57       add_to_large_octree(&image);
58       prepare_quantize();
59     }
60 
61   if (wobbel_flag)
62     {
63       wobbel_image(&image);
64     }
65 
66   raw_data=malloc(image.len);
67   if (raw_data == NULL)
68     {
69       fprintf(stderr,"error allocating %d bytes\n",image.len);
70       exitialise(1);
71       exit(1);
72     }
73 
74   ncolor=clr_quantize(&image, raw_data, color_table);
75 
76   image_width = image.width;
77   run_pp = raw_data;
78 
79   /* compute histogram */
80   for (j=0; j < FLI_MAX_COLORS; j++) histogram[j]=0;
81 
82   if (individual_flag)
83     remap_image(raw_data, color_table, image.len, ncolor);
84 
85   if (border_color == 0)
86     {
87       for (i=0; i < image.len; i++)
88 	histogram[*(run_pp++)]++;
89     }
90   else
91     {
92       rgb_value=color_table[0];
93       color_table[0]=color_table[border_color];
94       color_table[border_color]=rgb_value;
95 
96       for (i=0; i < image.len; i++)
97 	{
98 	  if (*run_pp == 0)
99 	    *run_pp = (UBYTE)  border_color;
100 	  else if (*run_pp == border_color)
101 	    *run_pp = (UBYTE) 0;
102 
103 	  histogram[*(run_pp++)]++;
104 	}
105     }
106 
107   used_count=0;
108   for (j=0; j < FLI_MAX_COLORS; j++)
109     {
110       if (histogram[j] > 0) used_count++;
111     }
112 
113   if (verbose_flag > 0)
114     {
115       fprintf(stdout," %d color(s) used\n",used_count);
116     }
117 
118   memset(data, 0, fli_size);
119 
120   if (Xorigin_flag == 1)
121     {
122       x_origin = Xorigin;
123     }
124   else if (Xorigin_flag == 2)
125     {
126       x_origin = fli_width - Xorigin - image.width;
127     }
128   else
129     {
130       nhelp=fli_width - image.width;
131       x_origin = nhelp/2;
132     }
133 
134   if (x_origin >= 0)
135     {
136       idstart = x_origin;
137       isstart = 0;
138     }
139   else
140     {
141       idstart = 0;
142       isstart = -x_origin;
143     }
144   nhelp = x_origin + image.width;
145   idend = (nhelp < fli_width) ? nhelp : fli_width;
146 
147   if (Yorigin_flag == 1)
148     {
149       y_origin = Yorigin;
150     }
151   else if (Yorigin_flag == 2)
152     {
153       y_origin = fli_height - Yorigin - image.height;
154     }
155   else
156     {
157       nhelp=fli_height - image.height;
158       y_origin = nhelp/2;
159     }
160 
161   if (y_origin >= 0)
162     {
163       jdstart = y_origin;
164       jsstart = 0;
165     }
166   else
167     {
168       jdstart = 0;
169       jsstart = -y_origin;
170     }
171   nhelp = y_origin + image.height;
172   jdend = (nhelp < fli_height) ? nhelp : fli_height;
173 
174   psource = raw_data + (jsstart * image_width + isstart);
175   pdest = data + (jdstart * fli_width + idstart);
176 
177   len = idend - idstart;
178 
179   if (len > 0)
180     {
181       for (j=jdstart; j < jdend; j++)
182 	{
183 	  memcpy(pdest, psource, len);
184 	  psource += image_width;
185 	  pdest += fli_width;
186 	}
187     }
188 
189   free_pms(&image);
190   free(raw_data);
191 }
192 
193 /****************************************************************
194  * remap_image
195  ****************************************************************/
196 
remap_image(UBYTE * pp,LONG color[],int len,int ncolor)197 static void remap_image(UBYTE *pp, LONG color[], int len, int ncolor)
198 {
199   int occ[FLI_MAX_COLORS];
200   int map[FLI_MAX_COLORS];
201   int i,j,bingo,free_max;
202 
203   for (j = 0; j < FLI_MAX_COLORS; j++) occ[j] = 0;
204 
205   /* check if in previous table */
206 
207   /* fprintf(stdout,"(1)\n"); */
208   for (i = 0; i < ncolor; i++)
209     {
210       map[i] = -1;
211       for (j = 0; j < FLI_MAX_COLORS; j++)
212 	{
213 	  if (color[i] == mem_color[j])
214 	    {
215 	      map[i] = j;
216 	      occ[j] = 1;
217 	      /* fprintf(stdout," %3d",j); */
218 	      break;
219 	    }
220 	}
221     }
222 
223   /* take the most free entry */
224 
225   /* fprintf(stdout,"\n(2)\n"); */
226   for (i = 0; i < ncolor; i++)
227     {
228       if (map[i] != -1) continue;
229       bingo = -1;
230       free_max = -1;
231       for (j = 0; j < FLI_MAX_COLORS; j++)
232 	{
233 	  if (occ[j] == 0)
234 	    {
235 	      if (free_count[j] > free_max)
236 		{
237 		  bingo = j;
238 		  free_max = free_count[j];
239 		}
240 	    }
241 	}
242       if (bingo == -1)
243 	{
244 	  fprintf(stderr,"Error remapping image\n");
245 	  exitialise(1);
246 	  exit(1);
247 	}
248       map[i] = bingo;
249       occ[bingo] = 1;
250       /* fprintf(stdout," %3d",bingo); */
251     }
252   /* fprintf(stdout,"\n"); */
253 
254   for (i=0; i < len; i++)
255     {
256       *pp = map[*pp];
257       pp++;
258     }
259 
260   for (j = 0; j < ncolor; j++) mem_color[map[j]] = color[j];
261 
262   for (j = 0; j < FLI_MAX_COLORS; j++)
263     {
264       color[j] = mem_color[j];
265       if (occ[j] == 0)
266 	{
267 	  free_count[j]++;
268 	}
269       else
270 	{
271 	  free_count[j] = 0;
272 	}
273     }
274 }
275 
276 /****************************************************************
277  * wobbel_image
278  ****************************************************************/
279 
wobbel_image(PMS * image)280 static void wobbel_image(PMS *image)
281 {
282   int w,h;
283   int red,green,blue;
284   int i,j;
285   int new_len;
286   UBYTE *b,*p1,*p2;
287 
288   w=image->width;
289   h=image->height;
290   new_len=4*w*h;
291 
292   b=malloc(3*new_len);
293   if (b == NULL)
294     {
295       fprintf(stderr,"error allocating %d bytes\n",new_len);
296       exitialise(1);
297       exit(1);
298     }
299 
300   p1=image->pixels;
301   p2=b;
302 
303   for (j=0; j < h; j++)
304     {
305       for (i=0; i < w; i++)
306 	{
307 	  red=*p1++;
308 	  green=*p1++;
309 	  blue=*p1++;
310 
311 	  *p2++=red;
312 	  *p2++=green;
313 	  *p2++=blue;
314 
315 	  *p2++=red;
316 	  *p2++=green;
317 	  *p2++=blue;
318 	}
319       for (i=0; i < 6*w; i++)
320 	{
321 	  *p2++=0;
322 	}
323     }
324   free(image->pixels);
325   image->pixels=b;
326   image->width=2*w;
327   image->height=2*h;
328   image->len=new_len;
329 }
330 
331 /* -- FIN -- */
332