Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rlesplice.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 /* rlesplice.c - Splice two RLE files together horizontally or vertically.
19  * Pad smaller dimensioned image with its background color or
20  * black.
21  *
22  * Author: Martin R. Friedmann (martin@media-lab.media.mit.edu)
23  * Vision and Modeling Group
24  * Massachusetts Institute of Technology
25  * Date: Mon Apr 23 1990 (The Apocalypse)
26  * Copyright (c) 1990, Martin R. Friedmann
27  */
28 #include <stdio.h>
29 #include "rle.h"
30 
31 #define MALLOC_ERR RLE_CHECK_ALLOC( cmd_name( argv ), 0, 0 )
32 
33 #define VERT_FLAG 0x01 /* Command line flags */
34 #define HORIZ_FLAG 0x02 /* must match appearance in scanargs */
35 #define FOO_FLAG 0x04
36 
37 #define Max(x, y) (((x) > (y)) ? (x) : (y) )
38 #define Min(x, y) (((x) < (y)) ? (x) : (y) )
39 
40 static void bfill();
41 char *progname = NULL;
42 
43 
45 rle_hdr *hdr_1, *hdr_2;
46 {
47 #define Check(thing,printthing)
48  if (hdr_1->thing != hdr_2->thing)
49  {
50  fprintf( stderr, "%s: %s does not match\n", progname, printthing);
51  return 0;
52  }
53  Check(ncolors, "Number of color channels");
54  Check(alpha, "Existance of alpha channel");
55  Check(ncmap, "Number of colormap channels");
56  Check(cmaplen, "Colormap length");
57  return 1;
58 #undef Check
59 }
60 
61 void
63 rle_hdr * the_hdr;
64 rle_pixel *scanline[];
65 {
66  int nc;
67  rle_pixel bg_color[255];
68 
69  if ( the_hdr->alpha && RLE_BIT( *the_hdr, -1 ) )
70  bfill( (char *)scanline[-1], the_hdr->xmax + 1, 0 );
71 
72  /* Clear to background if specified */
73  for ( nc = 0; nc < the_hdr->ncolors; nc++ ) {
74  bg_color[nc] = (the_hdr->background == 2 ) ? the_hdr->bg_color[nc] : 0;
75  if ( RLE_BIT( *the_hdr, nc ) )
76  bfill( (char *)scanline[nc], the_hdr->xmax+1, bg_color[nc] );
77  }
78 }
79 
80 void
82 int argc;
83 char *argv[];
84 {
85  char *infname1 = NULL, *outfname = NULL;
86  char *infname2 = NULL;
87  int oflag = 0, hvflag = 0, cflag = 0;
88  int rle_cnt = 0;
89  FILE *outfile = stdout;
90  int j;
91  int new_xlen,
92  new_ylen;
93  int rle_err1, rle_err2 = 0;
94  rle_hdr in_hdr1, in_hdr2, out_hdr;
95  int xmin, ymin, width1, width2, height1, height2;
96 
97  progname = cmd_name( argv );
98  in_hdr1 = *rle_hdr_init( NULL );
99  in_hdr2 = *rle_hdr_init( NULL );
100  out_hdr = *rle_hdr_init( NULL );
101 
102  if ( scanargs( argc, argv, "% hv!- c%- o%-outfile!s infile1!s infile2!s",
103  &hvflag, &cflag, &oflag, &outfname,
104  &infname1, &infname2 ) == 0 )
105  exit( 1 );
106 
107  in_hdr1.rle_file = rle_open_f( progname, infname1, "r" );
108  in_hdr2.rle_file = rle_open_f( progname, infname2, "r" );
109  rle_names( &in_hdr1, progname, infname1, 0 );
110  rle_names( &in_hdr2, progname, infname2, 0 );
111  rle_names( &out_hdr, progname, outfname, 0 );
112 
113 
114  /* Both standard input? */
115  if ( in_hdr1.rle_file == in_hdr2.rle_file )
116  {
117  fprintf( stderr, "Both files can't be on standard input.\n" );
118  exit( -1 );
119  }
120 
121  for ( rle_cnt = 0;
122  (rle_err1 = rle_get_setup( &in_hdr1 )) == RLE_SUCCESS &&
123  (rle_err2 = rle_get_setup( &in_hdr2 )) == RLE_SUCCESS;
124  rle_cnt++ ) {
125  rle_pixel **rows1, **rows2, **rowsout;
126  rle_pixel *ptr1, *ptr2, *ptrout;
127  int start_scan1, start_scan2, pad1, pad2;
128  int chan;
129 
130  if ( rle_cnt == 0 )
131  outfile = rle_open_f( progname, outfname, "w" );
132 
133  if (!compatible_hdr(&in_hdr1, &in_hdr2)) {
134  fprintf(stderr, "%s: Non-compatible rle files: %s and %s\n",
135  progname, infname1, infname2);
136  exit(1);
137  }
138 
139  (void)rle_hdr_cp( &in_hdr1, &out_hdr );
140  rle_addhist( argv, &in_hdr1, &out_hdr );
141 
142  /* preserve xmin and ymin from in_hdr1 */
143  xmin = in_hdr1.xmin;
144  ymin = in_hdr1.ymin;
145  width1 = in_hdr1.xmax - in_hdr1.xmin + 1;
146  width2 = in_hdr2.xmax - in_hdr2.xmin + 1;
147  height1 = in_hdr1.ymax - in_hdr1.ymin + 1;
148  height2 = in_hdr2.ymax - in_hdr2.ymin + 1;
149 
150  if (hvflag == VERT_FLAG) {
151  new_xlen = Max( width1, width2 );
152  new_ylen = height1 + height2;
153  } else {
154  new_xlen = width1 + width2;
155  new_ylen = Max( height1, height2 );
156  }
157 
158  out_hdr.xmin = xmin;
159  out_hdr.ymin = ymin;
160  out_hdr.xmax = xmin + new_xlen - 1;
161  out_hdr.ymax = ymin + new_ylen - 1;
162 
163  out_hdr.rle_file = outfile;
164  rle_put_setup( &out_hdr );
165 
166  /* Oink. */
167  if ( rle_row_alloc( &in_hdr1, &rows1 ) < 0 ||
168  rle_row_alloc( &in_hdr2, &rows2 ) < 0 ||
169  rle_row_alloc( &out_hdr, &rowsout ) < 0 )
170  MALLOC_ERR;
171 
172  rle_row_clear( &in_hdr1, rows1 );
173  rle_row_clear( &in_hdr2, rows2 );
174  rle_row_clear( &out_hdr, rowsout );
175 
176  if ( hvflag == HORIZ_FLAG ) {
177  int diff = height1 - height2 ;
178  start_scan1 = start_scan2 = pad1 = pad2 = 0;
179  if ( height1 < height2 )
180  start_scan1 = (cflag) ? -diff/2 : new_ylen - height1;
181  else if ( height2 < height1 )
182  start_scan2 = (cflag) ? diff/2 : new_ylen - height2;
183  } else {
184  /* upside down remember */
185  start_scan2 = pad1 = pad2 = 0;
186  start_scan1 = height2;
187 
188  if ( width1 < width2 )
189  pad1 = (cflag) ? (width2 - width1)/2 : 0;
190  else if (width2 < width1 )
191  pad2 = (cflag) ? (width1 - width2)/2 : 0;
192  }
193 
194  for ( j = 0; j < new_ylen; j++ ) {
195  if ( start_scan1 <= j && hvflag == VERT_FLAG ) {
196  start_scan2 = new_ylen + 1; /* never again */
197  rle_row_clear( &out_hdr, rowsout );
198  }
199  if ( start_scan1 <= j )
200  rle_getrow(&in_hdr1, rows1 );
201  if ( start_scan2 <= j )
202  rle_getrow(&in_hdr2, rows2 );
203 
204  for (chan = RLE_ALPHA; chan < in_hdr1.ncolors; chan++)
205  {
206  if ((chan == RLE_ALPHA) && (!in_hdr1.alpha))
207  continue;
208  ptr1 = &(rows1[chan][in_hdr1.xmin]);
209  ptr2 = &(rows2[chan][in_hdr2.xmin]);
210  ptrout = rowsout[chan];
211 
212  if ( start_scan1 <= j )
213  bcopy( ptr1, ptrout + pad1, width1 );
214  if ( start_scan2 <= j )
215  bcopy( ptr2,((char *)ptrout) + pad2 +
216  ((hvflag == VERT_FLAG) ? 0 : width1), width2 );
217 
218  }
219  rle_putrow( rowsout, new_xlen, &out_hdr );
220  }
221  rle_puteof( &out_hdr );
222 
223  rle_row_free( &in_hdr1, rows1 );
224  rle_row_free( &in_hdr2, rows2 );
225  rle_row_free( &out_hdr, rowsout );
226  }
227 
228  if ( rle_cnt == 0 || (rle_err1 != RLE_EOF && rle_err1 != RLE_EMPTY &&
229  rle_err2 != RLE_EOF && rle_err2 != RLE_EMPTY ) ) {
230  if (rle_err1 != RLE_SUCCESS)
231  rle_get_error( rle_err1, progname, infname1 );
232  if (rle_err2 != RLE_SUCCESS)
233  rle_get_error( rle_err2, progname, infname2 );
234  }
235  exit( 0 );
236 }
237 
238 /* Fill buffer at s with n copies of character c. N must be <= 65535*/
239 /* ARGSUSED */
240 static void bfill( s, n, c )
241 char *s;
242 int n, c;
243 {
244 #ifdef vax
245  asm(" movc5 $0,*4(ap),12(ap),8(ap),*4(ap)");
246 #else
247  while ( n-- > 0 )
248  *s++ = c;
249 #endif
250 }
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 VERT_FLAG
Definition: rleflip.c:42
#define Max(x, y)
Definition: getx11.h:76
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
#define RLE_EMPTY
Definition: rle.h:73
int compatible_hdr(rle_hdr *hdr_1, rle_hdr *hdr_2)
Definition: rlesplice.c:44
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
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 * bg_color
Definition: rle.h:100
#define RLE_SUCCESS
Definition: rle.h:70
int ymin
Definition: rle.h:100
int rle_get_error(int code, const char *pgmname, const char *fname)
Definition: rle_error.c:76
char * progname
Definition: unslice.c:51
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
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 MALLOC_ERR
Definition: rlecomp.c:38
void rle_row_clear(rle_hdr *the_hdr, scanline)
Definition: rlesplice.c:62
#define RLE_EOF
Definition: rle.h:74
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
int background
Definition: rle.h:100
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
static void bfill(char *s, int n, int c)
Definition: rlesplice.c:240
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
#define RLE_ALPHA
Definition: rle.h:65
#define HORIZ_FLAG
Definition: rleflip.c:43
#define Check(thing, printthing)
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
#define RLE_BIT(glob, bit)
Definition: rle.h:126