Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rletogif.c
Go to the documentation of this file.
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 /* rletogif.c */
19 
20 /*************************************************************************
21  * rletogif - Main program for RLE to GIF graphics format conversion.
22  * Works only with 8-bit RLE files. Use to8 to convert
23  * from 24-bit files.
24  * Will detectect if mcut has been used to reduce the number of
25  * colors and act accordingly.
26  *
27  * Written by Bailey Brown, Jr. May 24, 1990.
28  *************************************************************************
29  */
30 
31 #include <stdio.h>
32 #include "rle.h"
33 #include "rletogif.h"
34 
35 CONST_DECL char *MY_NAME = "rletogif";
36 
37 static rle_hdr in_hdr;
38 static rle_pixel **scan;
39 static gif_pixel **scanbuf; /* needed to read all scanlines before
40  converting to gif (rle is upside down) */
41 static int pix_mask; /* To make sure pixels have specified #bits. */
42 
43 int get_scanlines();
44 int get_color_bits();
45 void GIFEncode();
46 
47 void
49 int argc;
50 char *argv[];
51 {
52  char *outfname = NULL,
53  *infname = NULL;
54  int oflag = 0;
55  int i, color_bits;
56 
57  MY_NAME = cmd_name( argv );
58 
59  if ( scanargs( argc, argv, "% o%-outfile.gif!s infile.rle%s",
60  &oflag, &outfname, &infname ) == 0 )
61  exit( 1 );
62 
63  in_hdr = *rle_hdr_init( (rle_hdr *)NULL );
64  rle_names( &in_hdr, MY_NAME, infname, 0 );
65  in_hdr.rle_file = rle_open_f( MY_NAME, infname, "r" );
66 
67  rle_get_setup_ok( &in_hdr, NULL, NULL);
69  in_hdr.xmin = 0;
70 
71  if (in_hdr.ncolors > 1) error("Input file should have only 1 channel.");
72 
73  get_scanlines();
74  color_bits = get_color_bits(in_hdr.comments);
75  if ( in_hdr.ncmap && color_bits > in_hdr.cmaplen )
76  color_bits = in_hdr.cmaplen;
77  else if ( in_hdr.ncmap == 0 )
78  {
79  in_hdr.cmap = (rle_map *)malloc( sizeof(rle_map) * (1 << color_bits) );
80  in_hdr.cmaplen = color_bits;
81  for ( i = 0; i < (1 << color_bits); i++ )
82  in_hdr.cmap[i] = i << (16 - color_bits);
83  }
84  pix_mask = (1 << color_bits) - 1;
85 
86  GIFEncode( outfname, in_hdr.xmax - in_hdr.xmin + 1,
87  in_hdr.ymax - in_hdr.ymin + 1, 0, 0,
88  color_bits, &in_hdr.cmap[0],
89  &in_hdr.cmap[in_hdr.ncmap > 1 ? 1 << in_hdr.cmaplen : 0],
90  &in_hdr.cmap[in_hdr.ncmap > 2 ? 2 << in_hdr.cmaplen : 0],
91  getpixel );
93  for (i = 0; i <= in_hdr.ymax - in_hdr.ymin; i++ ) free(scanbuf[i]);
94  free(scanbuf);
95 }
96 
97 /*
98  * get_scanlines() reads in all RLE raster data at once. This is
99  * necessary because of RLE stores images bottom to top and GIF stores
100  * them top to bottom.
101  */
102 int get_scanlines()
103 {
104  int i;
105  rle_pixel *save_scan_0;
106 
107 
108  if (sizeof(rle_pixel) != sizeof(gif_pixel))
109  error("rle pixel size not 8 bits");
110  if (rle_row_alloc(&in_hdr, &scan) < 0)
111  error("can't allocate scan");
112  save_scan_0 = scan[0];
113  scanbuf = (gif_pixel**)
114  malloc(sizeof(gif_pixel*)*(in_hdr.ymax-in_hdr.ymin+1));
115  if (scanbuf == NULL)
116  error("can't allocate scanbuf");
117  for (i = 0; i <= in_hdr.ymax - in_hdr.ymin; i++) {
118  scan[0] = (rle_pixel*)malloc(sizeof(rle_pixel)*(in_hdr.xmax+1));
119  if (scan[0] == NULL)
120  error("can't allocate current scanline");
123  }
124  scan[0] = save_scan_0;
125  return (1);
126 }
127 
128 /********************************************************************
129  * get_color_bits() searches the array of comment strings for the substring
130  * "color_map_length=" which is added by mcut if it has worked on the
131  * file. If it is found, it sets color_bits to the ceiling of log 2
132  * color_map_length. Otherwise it returns the default value 8.
133  ********************************************************************/
134 int get_color_bits(comments)
135 char **comments;
136 {
137  int i, color_bits, num_colors;
138 
139  color_bits = 8;
140  if (comments == NULL) return (color_bits);
141  for (i = 0; comments[i]; i++) {
142  if (!strncmp(comments[i],"color_map_length=",17)) {
143  num_colors = atoi(&(comments[i][17]));
144  for (color_bits = 1; num_colors >> color_bits; color_bits++);
145  if (num_colors == (1<<(color_bits-1))) color_bits--;
146  break;
147  }
148  }
149  if ((color_bits < 0) || (color_bits > 8))
150  error("invalid number of color bits");
151  return (color_bits);
152 }
153 
154 int getpixel( x, y )
155 int x, y;
156 {
157  return pix_mask & (int)scanbuf[y][x];
158 }
159 
160 void error(s)
161 char *s;
162 {
163  fprintf(stderr,"%s\n", s);
164  exit(2);
165 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
int xmin
Definition: rle.h:100
static rle_hdr in_hdr
Definition: rletogif.c:37
const char ** comments
Definition: rle.h:113
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
void rle_row_free(rle_hdr *the_hdr, rle_pixel **scanp)
Definition: rle_row_alc.c:114
unsigned char gif_pixel
Definition: rletogif.h:10
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
rle_map * cmap
Definition: rle.h:112
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
static gif_pixel ** scanbuf
Definition: rletogif.c:39
int ymin
Definition: rle.h:100
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
int xmax
Definition: rle.h:100
const char * MY_NAME
Definition: rletogif.c:35
static int pix_mask
Definition: rletogif.c:41
#define CONST_DECL
Definition: rle_config.h:42
void rle_get_setup_ok(rle_hdr *the_hdr, const char *prog_name, const char *file_name)
Definition: rle_getrow.c:254
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
int cmaplen
Definition: rle.h:100
unsigned short rle_map
Definition: rle.h:57
static rle_pixel ** scan
Definition: rletogif.c:38
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
FILE * rle_file
Definition: rle.h:114
int ncolors
Definition: rle.h:100