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