1 /*
2  * This software is copyrighted as noted below.  It may be freely copied,
3  * modified, and redistributed, provided that the copyright notice is
4  * preserved on all copies.
5  *
6  * There is no warranty or other guarantee of fitness for this software,
7  * it is provided solely "as is".  Bug reports or fixes may be sent
8  * to the author, who may or may not act on them as he desires.
9  *
10  * You may not include this software in a program or other software product
11  * without supplying the source, or without informing the end-user that the
12  * source is available for no extra charge.
13  *
14  * If you modify this software, you should include a notice giving the
15  * name of the person performing the modification, the date of modification,
16  * and the reason for such modification.
17  */
18 /*
19  * cnv.c - select the read/write function using the file name ( !!! ).
20  *
21  * Author:      Raul Rivero
22  *              Mathematics Dept.
23  *              University of Oviedo
24  * Date:        Sat Feb 6 1993
25  * Copyright (c) 1993, Raul Rivero
26  *
27  */
28  /*
29   * The algorithm is not too acuratte, but this is to me a
30   * curiosity not a vital part of LUG.
31   *
32   * If u wanna fix the problems, please do it ( and thank u ).
33   */
34 
35 #include <lug.h>
36 #include <lugfnts.h>
37 
38 /*
39  * If we need reduce the number of colors, what is the
40  * default process ? ...
41  */
42 #define DITHER_INSTEAD_OF_QUANTIZE              FALSE
43 
44 extern int LUGverbose;
45 
46 /*
47  * Complete file format name.
48  */
49 static char *lug_ff_name[] = {
50                         "Compuserve's GIF",
51                         "Rayshade's heightfield",
52                         "Sun raster",
53                         "Portable Bitmap Map",
54                         "Portable Grey Map",
55                         "Portable Pix Map",
56                         "ZSoft's PCX",
57                         "Alias's 'pix'",
58                         "raw",
59                         "rgb",
60                         "Wavefront's RLA",
61                         "Wavefront's RLB",
62                         "Utah Raster Toolkit's RLE",
63                         "Silicon Graphics RGB",
64                         "True Vision's targa",
65                         "Aldus' TIFF",
66                         "Aldus' TIFF",
67                         "PostScript",
68                         "JPEG",
69                         "JPEG"
70 };
71 
72 /*
73  * Ok, we recognize these extensions ...
74  */
75 static char *lug_ff_ext[] = {
76                         ".gif",
77                         ".hf",
78                         ".im",
79                         ".pbm", ".pgm", ".ppm",
80                         ".pcx",
81                         ".pix",
82                         ".raw",
83                         ".rgb",
84                         ".rla", ".rlb",
85                         ".rle",
86                         ".sgi",
87                         ".tga",
88                         ".tif", ".tiff",
89                         ".ps",
90                         ".jpg", ".jpeg",
91                         NULL
92 };
93 
94 /*
95  * Read file functions.
96  */
97 static int (*read_lug_fnts[])() = {
98                         read_gif_file,
99                         NULL,
100                         NULL,
101                         read_pbm_file, read_pbm_file, read_pbm_file,
102                         read_pcx_file,
103                         read_alias_file,
104                         read_raw_file,
105                         read_rgb_i_file,
106                         read_rla_file,
107                         read_rla_file,
108 #ifdef iRLE
109                         read_rle_file,
110 #else
111                         NULL,
112 #endif  /* iRLE */
113 #ifdef iSGI
114                         read_sgi_file,
115 #else
116                         NULL,
117 #endif  /* iSGI */
118                         read_tga_file,
119 #ifdef iTIFF
120                         read_tiff_file, read_tiff_file,
121 #else
122                         NULL, NULL,
123 #endif
124                         NULL,
125 #if defined(iJPEG) || defined(iJPEGNEW)
126                         read_jpeg_file, read_jpeg_file,
127 #else
128                         NULL, NULL,
129 #endif
130                         NULL
131 };
132 
133 /*
134  * Write file functions.
135  */
136 static int (*write_lug_fnts[])() = {
137                         write_gif_file,
138                         write_hf_file,
139                         NULL,
140                         write_pbm_file, write_pbm_file, write_pbm_file,
141                         write_pcx_file,
142                         write_alias_file,
143                         write_raw_file,
144                         write_rgb_file,
145                         write_rla_file,
146                         write_rla_file,
147 #ifdef iRLE
148                         write_rle_file,
149 #else
150                         NULL,
151 #endif  /* iRLE */
152 #ifdef iSGI
153                         write_sgi_file,
154 #else
155                         NULL,
156 #endif  /* iSGI */
157                         write_tga_file,
158 #ifdef iTIFF
159                         write_tiff_file, write_tiff_file,
160 #else
161                         NULL, NULL,
162 #endif
163                         write_ps_file,
164 #if defined(iJPEG) || defined(iJPEGNEW)
165                         write_jpeg_file, write_jpeg_file,
166 #else
167                         NULL, NULL,
168 #endif
169                         NULL
170 };
171 
172 /*
173  * Each file formats allows these depths ...
174  */
175 static int write_depth_fnts[] = {
176                         ONLY_8_PLANES,
177                         ONLY_RAW_PLANES,
178                         ALL_PLANES,
179                         ONLY_BINARY_PLANES, ONLY_8_PLANES, ONLY_24_PLANES,
180                         ONLY_8_PLANES,
181                         ONLY_24_PLANES,
182                         ONLY_RAW_PLANES,
183                         ONLY_24_PLANES,
184                         ONLY_24_PLANES,
185                         ONLY_24_PLANES,
186                         ALL_PLANES,
187                         ONLY_24_PLANES,
188                         ONLY_24_PLANES,
189                         ALL_PLANES, ALL_PLANES,
190                         ONLY_RAW_PLANES,
191                         ALL_PLANES, ALL_PLANES
192 };
193 
194 
read_lug_file(name,bitmap)195 read_lug_file( name, bitmap )
196 char *name;
197 bitmap_hdr *bitmap;
198 {
199   ifunptr read_file;
200 
201   /*
202    * Get the correct funtion to read that file ( please, remember
203    * tha we use the file extension and this is not perfect ).
204    */
205   read_file = get_readlug_function( name );
206 
207   /* Ok, do it. */
208   read_file( name, bitmap );
209 }
210 
211 
write_lug_file(name,bitmap)212 write_lug_file( name, bitmap )
213 char *name;
214 bitmap_hdr *bitmap;
215 {
216   ifunptr write_file;
217   int new_depth;
218   int dither_flag = DITHER_INSTEAD_OF_QUANTIZE;
219 
220   /* Get the output file type */
221   new_depth = get_depth_writelug_function( name );
222 
223   /*
224    * If the target file format doesn't allow the number of planes
225    * we have then we need convert the source image.
226    */
227   if ( !new_depth || bitmap->depth == new_depth ) {
228     /* Ok, all right */
229     write_file = get_writelug_function( name );
230     write_file( name, bitmap );
231   }else{
232     /* Ooppss!, different # of colors */
233     bitmap_hdr out;
234 
235     switch ( new_depth ) {
236       case  ONLY_BINARY_PLANES:
237                 fprintf( stderr, "Converting to bi-level format.\n" );
238                 error( 99 );
239                 break;
240       case  ONLY_RAW_PLANES:
241                 to_raw_bw( bitmap, &out );
242                 write_file = get_writelug_function( name );
243                 write_file( name, &out );
244                 break;
245       case  ONLY_8_PLANES:
246                 if ( dither_flag ) {
247                   dither_image( bitmap, &out, 6, (double) 1.0 );
248                 }else {
249                   VPRINTF( stderr, "Quantizing\n" );
250                   quantize( bitmap, &out, 256 );
251                 }
252                 write_file = get_writelug_function( name );
253                 write_file( name, &out );
254                 break;
255       case ONLY_24_PLANES:
256                 to24( bitmap, &out );
257                 write_file = get_writelug_function( name );
258                 write_file( name, &out );
259                 break;
260       default:
261                 fprintf( stderr, "Conversion error, unkown target depth\n" );
262                 exit( 1 );
263     }
264     freebitmap( &out );
265   }
266 }
267 
get_readlug_function(str)268 ifunptr get_readlug_function( str )
269 char *str;
270 {
271   ifunptr ptr;
272   int value;
273 
274   /* Get the correct function for reading */
275   if ( !(ptr = read_lug_fnts[ value = get_index_function(str) ]) ) {
276     /* Ooops!, no reader */
277     fprintf( stderr, "%s reader not linked during the compilation process\n",
278                      lug_ff_name[ value ] );
279     error( 99 );
280   }
281 
282   VPRINTF( stderr, "Reading %s using the %s reader ...\n",
283            str, lug_ff_name[value] );
284 
285   return ptr;
286 }
287 
get_writelug_function(str)288 ifunptr get_writelug_function( str )
289 char *str;
290 {
291   ifunptr ptr;
292   int value;
293 
294   /* Get the correct function for writing */
295   if ( !(ptr = write_lug_fnts[ value = get_index_function(str) ]) ) {
296     /* Ooops !, no writer */
297     fprintf( stderr, "%s writer not linked during the compilation process\n",
298                      lug_ff_name[ value ] );
299     error( 99 );
300   }
301 
302   VPRINTF( stderr, "Writing %s using the %s writer ...\n",
303            str, lug_ff_name[value] );
304 
305   return ptr;
306 }
307 
get_depth_writelug_function(str)308 get_depth_writelug_function( str )
309 char *str;
310 {
311   /* Return the correct depth of that specific file format */
312   return write_depth_fnts[ get_index_function(str) ];
313 }
314 
get_index_function(str)315 get_index_function( str )
316 char *str;
317 {
318   char dup[132];
319   char *ptr;
320   int len = strlen( str );
321   int indexx;
322 
323   /* Duplicates the string */
324   strcpy( dup, str );
325 
326   /* Check if exists the '.Z' extension ( and discard it ) */
327   if ( dup[len-2] == '.' && dup[len-1] == 'Z' )
328     dup[len-2] = 0;
329 
330   while ( ptr = strrchr( dup, '.' ) ) {
331     /*
332      * If the extension exists then we return the index
333      * to the read/write function else continue ( and
334      * disard the extension ).
335      */
336     if ( (indexx = get_real_index_function( ptr )) != -1 )
337       return indexx;
338     else ptr[0] = 0;
339   }
340 
341   return DEFAULT_FORMAT;
342 }
343 
get_real_index_function(str)344 get_real_index_function( str )
345 char *str;
346 {
347   register int i = 0;
348 
349   while ( lug_ff_ext[i] ) {
350     if ( strstr( str, lug_ff_ext[i] ) )
351       return i;
352     i++;
353   }
354 
355   return -1;
356 }
357