Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rleinterp.c
Go to the documentation of this file.
1 /******************************************************
2  *
3  * rleintrp.c -
4  *
5  * Interpolation between UTAH_RLE images making nbimage files
6  * by linear interpolation between the values of the pixels in
7  * two input files or between 0 and the value of a file
8  * (or the standard input if filename = '-' ).
9  *
10  * We check the mapping of the characteristics of each
11  * image in input : size, number of channels, background color
12  * color map, alpha channel ...
13  *
14  * Input : - prefix of output files
15  * - name of files between which interpolation occurs.
16  * If no mame : error.
17  * If name = '-' : standard input. Only one file can be
18  * specified like this.
19  * - Number of images created (default 1).
20  *
21  * Usage : rleintrp [-n nbimage] [-o outfile] [infile1 [infile2]]
22  *
23  *
24  * Author: Michel GAUDET
25  * SLX Onera
26  * 29 Avenue Division Leclerc
27  * 92322 CHATILLON CEDEX
28  * France
29  * Date: Mon Jul 1 09:18:26 1991
30  */
31 
32 #include <stdio.h>
33 #include <rle.h>
34 #include <fcntl.h>
35 
36 int comp_hdr ();
37 
38 extern char *optarg;
39 extern int optind;
40 
42 int argc;
43 char **argv;
44 {
45  char *infname1 = NULL,
46  *infname2 = NULL,
47  *outfname = NULL,
48  nom_sortie[BUFSIZ],
49  extension[80] ,
50  *basenom, *rep ;
51  int i, ni, n, nbimage=1;
52  int rle_err, width, y, x ;
53  int iflag1 = 0 , iflag2 = 0, oflag = 0, fd ;
54  double alpha, beta ;
55  FILE * outfile;
56  rle_hdr in1_hdr, in2_hdr, *out_hdr; /* Headers for input and output. */
57  rle_pixel **rows1, ** rows2, **rowsout, *point1, *point2, *pointout, *tab0;
58  /* Will be used for scanline storage. */
59 
60  in1_hdr = *rle_hdr_init( (rle_hdr *)NULL );
61  in2_hdr = *rle_hdr_init( (rle_hdr *)NULL );
62 
63 #define ARG_FORMAT "% n%-nimage!d o%-outfile!s infile1%s infile2%s\n(\
64 \tInterpolate between two images or between one image and black.\n\
65 \t-n\tSpecify number of images to produce as output.\n\
66 \tIf neither input is specified, infile1 defaults to standard input.\n\
67 \tIf infile2 is not specified, fade from infile1 to black.\n\
68 \tTo fade from black to an image, specify infile1 as \"\" (empty string).\n\
69 \tBoth inputs cannot be standard input (-).)"
70 
71  if ( scanargs( argc, argv, ARG_FORMAT,
72  &nbimage, &nbimage, &oflag, &outfname,
73  &infname1, &infname2 ) == 0 )
74  exit( 1 );
75 
76  iflag1 = (infname1 && *infname1);
77  iflag2 = (infname2 && *infname2);
78 
79  /* Check if we have two arguments
80  * and if we have not two '-'
81  *
82  */
83  if ( ( infname1 && ! strcmp(infname1,"-") ) &&
84  ( infname2 && ! strcmp(infname2,"-") ) )
85  {
86  fprintf(stderr,"%s : At most one input can be standard input\n",
87  cmd_name( argv ) ) ;
88  scan_usage( argv, ARG_FORMAT ) ;
89  exit (1) ;
90  }
91 
92  if ( infname1 && *infname1 && ! outfname ) outfname = infname1 ;
93  else if ( infname2 && *infname2 && ! outfname ) outfname = infname2 ;
94 
95  /* If only one file and name is '-' and no output file name prefix
96  * arbitrary output file name : process Number and extension 'rle'.
97  * Memory allocation to store outfname (no area because no argument
98  * in command line)
99  */
100  if ( !outfname || ! strcmp(outfname,"-") )
101  {
102  outfname = ( char *) malloc(80*sizeof(char)) ;
103  sprintf(outfname,"i%-d.rle",getpid()) ;
104  }
105 
106  rle_names( &in1_hdr, cmd_name( argv ), infname1, 0 );
107  rle_names( &in2_hdr, cmd_name( argv ), infname2, 0 );
108 
109  /* limit number of images at 99 */
110  if ( nbimage > 99 )
111  {
112  fprintf(stderr,"%s : Number of images too big\n",argv[0] ) ;
113  exit (1) ;
114  }
115  out_hdr = (rle_hdr *) malloc ( nbimage * sizeof(rle_hdr) );
116  RLE_CHECK_ALLOC( in1_hdr.cmd, out_hdr, "output header array" );
117 
118  if ( iflag1 )
119  in1_hdr.rle_file = rle_open_f( cmd_name( argv ), infname1, "r" );
120  if ( iflag2 )
121  in2_hdr.rle_file = rle_open_f( cmd_name( argv ), infname2, "r" );
122 
123  /* Read images from the input file until the end of file is
124  * encountered or an error occurs.
125  */
126  if ( iflag1 )
127  rle_get_setup_ok( &in1_hdr, NULL, NULL );
128 
129  if ( iflag2 )
130  rle_get_setup_ok( &in2_hdr, NULL, NULL );
131 
132 
133  /* Comparison of header or creation if needed
134  */
135  if ( iflag1 && iflag2 )
136  {
137  if ( comp_hdr(&in1_hdr,&in2_hdr ) )
138  {
139  fprintf(stderr,"%s : Input files not compatibles\n",argv[0]) ;
140  exit (1) ;
141  }
142  }
143  else if ( iflag1 ) rle_hdr_cp( &in1_hdr, &in2_hdr );
144  else if ( iflag2 ) rle_hdr_cp( &in2_hdr, &in1_hdr );
145 
146  /* Creation of array of 0s */
147  tab0 = (rle_pixel *)
148  calloc ( in1_hdr.xmax - in1_hdr.xmin + 1, sizeof(rle_pixel) );
149 
150  /* Since rle_getrow and rle_putrow use different array origins,
151  * we will compensate by adjusting the xmin and xmax values in
152  * the input header. [rle_getrow assumes that the scanline
153  * array starts at pixel 0, while rle_putrow assumes that the
154  * scanline array starts at pixel xmin. This is a botch, but
155  * it's too late to change it now.]
156  */
157  in1_hdr.xmax -= in1_hdr.xmin;
158  in1_hdr.xmin = 0;
159  width = in1_hdr.xmax + 1; /* Width of a scanline. */
160 
161  /* If only one of input file is defined we interpolate between
162  * the values of this one and 0
163  * It is then necessary to have a pointer for an array of 0
164  *
165  * If the alpha channel exists it is numbered -1
166  */
167  if ( iflag1 && rle_row_alloc( &in1_hdr, &rows1 ) < 0)
168  RLE_CHECK_ALLOC( in1_hdr.cmd, 0, "image 1 scanline" );
169  else if ( ! iflag1 )
170  {
171  rows1 = (rle_pixel **)
172  malloc((in1_hdr.ncolors+in1_hdr.alpha)*sizeof(rle_pixel *));
173  RLE_CHECK_ALLOC( in1_hdr.cmd, rows1, "black scanline" );
174  if ( in1_hdr.alpha )
175  rows1++ ;
176  }
177  if ( iflag2 && rle_row_alloc( &in2_hdr, &rows2 ) < 0)
178  {
179  fprintf( stderr, "%s : Memory allocation error.\n",argv[0] );
180  exit( RLE_NO_SPACE );
181  }
182  else if ( ! iflag2 )
183  {
184  rows2 = (rle_pixel **)
185  malloc((in1_hdr.ncolors+in1_hdr.alpha)*sizeof(rle_pixel *));
186  RLE_CHECK_ALLOC( in1_hdr.cmd, rows2, "black scanline" );
187  if ( in2_hdr.alpha )
188  rows2++ ;
189  }
190 
191  /* File base-name reduction to 7 characters because
192  * may be limitations to 14 characters of final file name
193  */
194  basenom = (rep=strrchr(outfname,'/'))==NULL?outfname:rep+1 ;
195 
196  /* Save extension for making final name
197  */
198  if ( (rep=strrchr(basenom,'.')) == NULL )
199  extension[0]='\0' ;
200  else
201  {
202 #ifdef FILE_NAME_14_CHARS
203  strncpy(extension,rep,4);
204  extension[4] ='\0';
205 #else
206  strcpy(extension, rep);
207 #endif
208  *rep = '\0' ;
209  }
210 
211 #ifdef FILE_NAME_14_CHARS
212  if ( ( strlen(basenom) - (i=strlen(extension)) ) > 10 )
213  *(basenom+10-i) = '\0' ;
214 #endif
215 
216  for ( y = in1_hdr.ymin; y <= in1_hdr.ymax; y++ )
217  {
218  /* Read a scanline. */
219  if ( iflag1 ) rle_getrow( &in1_hdr, rows1 );
220  if ( iflag2 ) rle_getrow( &in2_hdr, rows2 );
221 
222  /* I create all the files in one pass to avoid to read many time
223  * the input files
224  */
225 
226  for ( i = 0 ; i < nbimage ; i++ )
227  {
228  if ( y == in1_hdr.ymin )
229  {
230  sprintf(nom_sortie , "%s_%03d%s",outfname,i,extension) ;
231 
232  if ( ( fd = open(nom_sortie, O_RDONLY ) ) != -1 )
233  {
234  close(fd) ;
235  fprintf(stderr,"%s : File %s exists\n",
236  in1_hdr.cmd, nom_sortie ) ;
237  exit (1) ;
238  }
239  else
240  {
241  fprintf(stderr,"Create image %s\n",nom_sortie) ;
242  outfile = rle_open_f(cmd_name(argv), nom_sortie, "w" ) ;
243  }
244  /* The output header is a copy of the input header. The only
245  * difference is the FILE pointer.
246  */
247  rle_hdr_cp( &in2_hdr, &out_hdr[i] );
248  rle_names( &out_hdr[i], in2_hdr.cmd, nom_sortie, 0 );
249  out_hdr[i].rle_file = outfile;
250 
251  /* Add to the history comment. */
252  rle_addhist( argv, (rle_hdr *) 0, &out_hdr[i] );
253 
254  /* Write the output image header. */
255  rle_put_setup( &out_hdr[i] );
256 
257  if ( rle_row_alloc(&out_hdr[i],&rowsout) < 0 )
258  RLE_CHECK_ALLOC( in1_hdr.cmd, 0, "output scanline" );
259  }
260  /* Only one input file : the other is '0' image
261  */
262  if ( ! iflag1 )
263  for (n = -in1_hdr.alpha; n<in1_hdr.ncolors; n++)
264  rows1[n] = tab0 ;
265  if ( ! iflag2 )
266  for (n = -in2_hdr.alpha; n<in2_hdr.ncolors; n++)
267  rows2[n] = tab0 ;
268  beta = (i+1) * 1.0/(nbimage + 1) ;
269  alpha = 1.0 - beta ;
270 
271  for ( (n = in1_hdr.alpha?-1:0) ; n < in1_hdr.ncolors ; n++ )
272  {
273  point1 = rows1[n] ;
274  point2 = rows2[n] ;
275  pointout = rowsout[n] ;
276 
277  for ( x = in1_hdr.xmin ; x <= in1_hdr.xmax ; x++ )
278  {
279  *pointout++ = (int) ( (*point1++) * alpha + beta * (*point2++) + 0.5 ) ;
280  }
281  }
282  /* Write the processed scanline. */
283  rle_putrow( rowsout, width, &out_hdr[i] );
284 
285  if ( y == in1_hdr.ymax )
286  {
287  /* Write an end-of-image code. */
288  rle_puteof( &out_hdr[i] );
289  fclose(out_hdr[i].rle_file) ;
290  }
291  }
292 
293  }
294  /* Free memory. */
295  if ( iflag1 ) rle_row_free( &in1_hdr, rows1 );
296  if ( iflag2 ) rle_row_free( &in2_hdr, rows2 );
297  rle_row_free( &out_hdr[0], rowsout ) ;
298 
299  exit( 0 );
300 }
301 
303 rle_hdr * hdr1 , * hdr2 ;
304 
305 {
306  int comp , i, j;
307  rle_map *point1, *point2 ;
308  int cmapsize, cmaplen1, cmaplen2;
309  char *v;
310 
311  comp = hdr1->ncolors != hdr2->ncolors ;
312  comp += hdr1->alpha != hdr2->alpha ;
313  comp += hdr1->background != hdr2->background ;
314  comp += hdr1->xmin != hdr2->xmin ;
315  comp += hdr1->xmax != hdr2->xmax ;
316  comp += hdr1->ymin != hdr2->ymin ;
317  comp += hdr1->ymax != hdr2->ymax ;
318  comp += hdr1->ncmap != hdr2->ncmap ;
319  comp += hdr1->cmaplen != hdr2->cmaplen ;
320  /* Color map length is complex. */
321  if ( !comp && hdr1->ncmap )
322  {
323  cmapsize = 1 << hdr1->cmaplen;
324  if ( (v = rle_getcom( "color_map_length", hdr1 )) != NULL )
325  cmaplen1 = atoi( v );
326  else
327  cmaplen1 = 1 << hdr1->cmaplen;
328  if ( (v = rle_getcom( "color_map_length", hdr2 )) != NULL )
329  cmaplen2 = atoi( v );
330  else
331  cmaplen2 = 1 << hdr2->cmaplen;
332  comp += cmaplen1 != cmaplen2;
333  if ( !comp )
334  for ( j=0; j<hdr1->ncmap; j++)
335  for ( i=0, point1 = hdr1->cmap+j*cmapsize,
336  point2 = hdr2->cmap+j*cmapsize;
337  i < cmaplen1 ; i++ )
338  comp += *point1++ != *point2++ ;
339  }
340  return comp ;
341 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
int xmin
Definition: rle.h:100
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
#define ARG_FORMAT
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
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
int ymin
Definition: rle.h:100
int optind
Definition: getopt.c:30
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
const char * cmd
Definition: rle.h:133
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
#define RLE_NO_SPACE
Definition: rle.h:72
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
void rle_get_setup_ok(rle_hdr *the_hdr, const char *prog_name, const char *file_name)
Definition: rle_getrow.c:254
char * rle_getcom(char *name, rle_hdr *the_hdr) const
Definition: rle_getcom.c:81
int background
Definition: rle.h:100
int comp_hdr(hdr1, rle_hdr *hdr1 *hdr2)
Definition: rleinterp.c:302
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
int cmaplen
Definition: rle.h:100
int alpha
Definition: rle.h:100
unsigned short rle_map
Definition: rle.h:57
char * optarg
Definition: getopt.c:29
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
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86