Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
Functions | Variables
rleswap.c File Reference
#include <stdio.h>
#include "rle.h"
#include "rle_raw.h"
Include dependency graph for rleswap.c:

Go to the source code of this file.

Functions

void scan_usage ()
 
void setup_map ()
 
void print_map ()
 
void main (int argc, char **argv)
 
void setup_map (int fflag, int tflag, int dflag, int pflag, int *specs, int nspec, rle_hdr *in_hdr, int ncolors, int alpha, char *where, int **outchan, int *noutput, int *outalpha)
 
void print_map (int outalpha, int noutput, int *outchan, char *where)
 

Variables

char rcsid [] = "$Header: /tmp_mnt/n/itn/hendrix/u/spencer/RCS/rleswap.c,v 3.0.1.4 1992/04/30 14:14:20 spencer Exp spencer $"
 

Function Documentation

void main ( int  argc,
char **  argv 
)

Definition at line 103 of file rleswap.c.

106 {
107  int nspec, * specs;
108  int tflag = 0, fflag = 0, oflag = 0, dflag = 0, pflag = 0, verbose = 0;
109  int mflag = 0;
110  char * fname = NULL, *out_fname = NULL;
111  FILE *outfile = stdout;
112  static CONST_DECL char * argfmt =
113  "% v%- Mm%- f%-from-channels!,d t%-to-channels!,d \n\
114 \td%-delete-channels!,d p%-channel-pairs!,d o%-outfile!s infile%s\n(\
115 \tRearrange or delete channels in an image.\n\
116 \t-v\tVerbose: explain (sort of) what's happening.\n\
117 \t-m\tModify only the colormap, leave the image alone.\n\
118 \t-M\tDon't modify the colormap.\n\
119 \t-f\tComma separated list of channels to copy from. First goes to\n\
120 \t\toutput channel 0, second to output channel 1, etc. An input\n\
121 \t\tchannel can be copied to several output channels this way.\n\
122 \t\tThe alpha channel is always copied \"straight across\".\n\
123 \t-t\tList of channels to copy to. First specifies where input\n\
124 \t\tchannel 0 goes, second where input channel 1 goes, etc. It is\n\
125 \t\tan error to try to copy more than one input channel to the same\n\
126 \t\toutput. The alpha channel is always copied \"straight across\".\n\
127 \t-p\tSpecify input and output channels in pairs. The first number in\n\
128 \t\ta pair is the input channel, the second is the output channel it\n\
129 \t\twill be copied to. A given output channel should appear at most\n\
130 \t\tonce in the list. The alpha channel is copied only if it is\n\
131 \t\texplicitly specified.\n\
132 \t-d\tA list of channels to delete from the input.)";
133  register int i;
134  int j;
135  int * outchan = 0, noutput = 0, outalpha = -2;
136  int *mapoutchan = 0, mapnoutput = 0, mapoutalpha = -2;
138  rle_op ** scanraw, ** outraw;
139  int * nraw, * outnraw, y, nskip;
140  int rle_cnt, rle_err;
141 
142  in_hdr = *rle_hdr_init( NULL );
143  out_hdr = *rle_hdr_init( NULL );
144 
145  if ( scanargs( argc, argv, argfmt, &verbose, &mflag,
146  &fflag, &nspec, &specs,
147  &tflag, &nspec, &specs,
148  &dflag, &nspec, &specs,
149  &pflag, &nspec, &specs,
150  &oflag, &out_fname, &fname ) == 0 )
151  exit( 1 );
152 
153  /* Do some sanity checks */
154  if ( fflag + tflag + dflag + pflag != 1 )
155  {
156  fprintf( stderr,
157  "%s: You must specify exactly one of -d, -f, -t, or -p\n",
158  argv[0] );
159  /*
160  * Generate usage message.
161  */
162  scan_usage( argv, argfmt );
163  exit( 1 );
164  }
165 
166  if ( pflag && (nspec % 2) != 0 )
167  {
168  fprintf( stderr, "%s: You must specify pairs of channels with -p\n",
169  cmd_name( argv ) );
170  exit( 1 );
171  }
172  /* More later, after we have the RLE header in hand */
173 
174  /* Open input */
175  in_hdr.rle_file = rle_open_f(cmd_name( argv ), fname, "r");
176  rle_names( &in_hdr, cmd_name( argv ), fname, 0 );
177  rle_names( &out_hdr, in_hdr.cmd, out_fname, 0 );
178 
179  /* Read in header */
180  for ( rle_cnt = 0;
181  (rle_err = rle_get_setup( &in_hdr )) == RLE_SUCCESS;
182  rle_cnt++ )
183  {
184  /* Mflag == 1 means do color map only. */
185  if ( mflag != 1 )
186  setup_map( fflag, tflag, dflag, pflag, specs, nspec,
187  &in_hdr, in_hdr.ncolors, in_hdr.alpha, "image data",
188  &outchan, &noutput, &outalpha );
189  else
190  /* Make identity mapping. */
191  setup_map( 0, 0, 1, 0, (int *)0, 0,
192  &in_hdr, in_hdr.ncolors, in_hdr.alpha, "image data",
193  &outchan, &noutput, &outalpha );
194 
195  /* Mflag == 2 means don't touch color map. */
196  if ( mflag != 2 && in_hdr.ncmap > 0 )
197  setup_map( fflag, tflag, dflag, pflag, specs, nspec,
198  &in_hdr, in_hdr.ncmap, 1, "color map",
199  &mapoutchan, &mapnoutput, &mapoutalpha );
200 
201  /* Be verbose if requested */
202  if ( verbose )
203  {
204  int cmap_different = mflag != 2 &&
205  (mflag == 1 || mapnoutput != noutput);
206  if ( mflag != 1 )
207  print_map( outalpha, noutput, outchan,
208  cmap_different ? "image data " : "" );
209  if ( cmap_different )
210  print_map( -3, mapnoutput, mapoutchan, "color map " );
211  }
212 
213  /* Set up output the_hdr now */
214  (void)rle_hdr_cp( &in_hdr, &out_hdr );
215  /* Same as input, except for a few changes. */
216  if ( rle_cnt == 0 )
217  outfile = rle_open_f(out_hdr.cmd, out_fname, "w");
218  out_hdr.rle_file = outfile;
219  out_hdr.ncolors = noutput;
220 
221  rle_addhist( argv, &in_hdr, &out_hdr );
222 
223  if ( outalpha != -2 )
224  {
225  out_hdr.alpha = 1;
226  RLE_SET_BIT( out_hdr, RLE_ALPHA );
227  }
228  else
229  {
230  out_hdr.alpha = 0;
231  RLE_CLR_BIT( out_hdr, RLE_ALPHA );
232  }
233  for ( i = 0; i < noutput; i++ )
234  if ( outchan[i] != -2 )
235  RLE_SET_BIT( out_hdr, i );
236  else
237  RLE_CLR_BIT( out_hdr, i );
238 
239  /* Do background color */
240  if ( out_hdr.background && out_hdr.ncolors > 0 )
241  {
242  out_hdr.bg_color =
243  (int *)malloc( out_hdr.ncolors * sizeof(int) );
244  RLE_CHECK_ALLOC( out_hdr.cmd, out_hdr.bg_color,
245  "output background color" );
246 
247  for ( i = 0; i < noutput; i++ )
248  if ( outchan[i] < 0 )
249  out_hdr.bg_color[i] = 0; /* got to be something */
250  else
251  out_hdr.bg_color[i] = in_hdr.bg_color[outchan[i]];
252  }
253 
254  /* And color map!? */
255  if ( mflag != 2 && in_hdr.ncmap > 0 )
256  {
257  int cmaplen = 1 << out_hdr.cmaplen;
258  int cmapshift = 16 - out_hdr.cmaplen;
259 
260  if ( mapnoutput > 0 )
261  {
262  out_hdr.cmap = (rle_map *)malloc( mapnoutput * cmaplen *
263  sizeof(rle_map) );
264  RLE_CHECK_ALLOC( out_hdr.cmd, out_hdr.cmap,
265  "output color map" );
266  }
267  else
268  out_hdr.cmap = 0;
269  out_hdr.ncmap = mapnoutput;
270 
271  /* If input channel is in color map, copy it, else use identity? */
272  for ( i = 0; i < mapnoutput; i++ )
273  if ( mapoutchan[i] >= 0 && mapoutchan[i] < in_hdr.ncmap )
274  {
275  register rle_map * imap, * omap;
276 
277  imap = &in_hdr.cmap[mapoutchan[i] * cmaplen];
278  omap = &out_hdr.cmap[i * cmaplen];
279 
280  for ( j = 0; j < cmaplen; j++ )
281  *omap++ = *imap++;
282  }
283  else
284  {
285  register rle_map * omap;
286 
287  omap = &out_hdr.cmap[i * cmaplen];
288  for ( j = 0; j < cmaplen; j++ )
289  *omap++ = j << cmapshift;
290  }
291  }
292 
293  /* Write output header */
294  rle_put_setup( &out_hdr );
295 
296  /* Allocate raw buffers for input */
297  if ( rle_raw_alloc( &in_hdr, &scanraw, &nraw ) < 0 )
298  RLE_CHECK_ALLOC( in_hdr.cmd, 0, "scanline memory" );
299 
300 
301  /* Allocate buffer pointers for output */
302  if ( rle_raw_alloc( &out_hdr, &outraw, &outnraw ) < 0 )
303  RLE_CHECK_ALLOC( out_hdr.cmd, 0, "scanline pointers" );
304  for ( i = -out_hdr.alpha; i < out_hdr.ncolors; i++ )
305  if ( outraw[i] )
306  {
307  free( (char *)outraw[i] ); /* don't need these */
308  break;
309  };
310 
311  /* Finally, do the work */
312  y = in_hdr.ymin - 1;
313  while ( (nskip = rle_getraw( &in_hdr, scanraw, nraw )) != 32768 )
314  {
315  nskip -= y; /* difference from previous line */
316  y += nskip;
317  if ( nskip > 1 )
318  rle_skiprow( &out_hdr, nskip - 1 );
319 
320  if ( outalpha != -2 )
321  {
322  outraw[-1] = scanraw[outalpha];
323  outnraw[-1] = nraw[outalpha];
324  }
325 
326  for ( i = 0; i < noutput; i++ )
327  if ( outchan[i] != -2 )
328  {
329  outraw[i] = scanraw[outchan[i]];
330  outnraw[i] = nraw[outchan[i]];
331  }
332  else
333  outnraw[i] = 0;
334 
335  rle_putraw( outraw, outnraw, &out_hdr );
336 
337  rle_freeraw( &in_hdr, scanraw, nraw );
338  }
339 
340  rle_puteof( &out_hdr ); /* all done! */
341 
342  /* Release memory. */
343  if ( outchan != specs )
344  free( outchan );
345  rle_raw_free( &in_hdr, scanraw, nraw );
346  }
347 
348  /* Check for an error. EOF or EMPTY is ok if at least one image
349  * has been read. Otherwise, print an error message.
350  */
351  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
352  rle_get_error( rle_err, in_hdr.cmd, fname );
353 
354  exit( 0 );
355 }
#define RLE_SET_BIT(glob, bit)
Definition: rle.h:122
void rle_skiprow(rle_hdr *the_hdr, int nrow)
Definition: rle_putrow.c:393
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
void rle_freeraw(rle_hdr *the_hdr, scanraw, nraw)
Definition: rle_getraw.c:268
static rle_hdr in_hdr
Definition: rletogif.c:37
FILE * outfile
Definition: giftorle.c:61
#define RLE_EMPTY
Definition: rle.h:73
int rle_raw_alloc()
rle_map * cmap
Definition: rle.h:112
int * bg_color
Definition: rle.h:100
void rle_addhist(char *argv[], rle_hdr *in_hdr, rle_hdr *out_hdr)
#define RLE_SUCCESS
Definition: rle.h:70
void rle_raw_free()
char * fname[3]
Definition: show3.c:31
int ymin
Definition: rle.h:100
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
static int y
Definition: getami.c:691
int verbose
Definition: aliastorle.c:96
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
const char * cmd
Definition: rle.h:133
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
Definition: rle.h:96
void rle_putraw()
void print_map()
void setup_map()
int rle_get_error(int code, const char *pgmname, const char *fname)
#define RLE_EOF
Definition: rle.h:74
#define CONST_DECL
Definition: rle_config.h:42
int background
Definition: rle.h:100
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
int ncmap
Definition: rle.h:100
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
void * malloc()
int cmaplen
Definition: rle.h:100
int i
Definition: rletorla.c:82
int alpha
Definition: rle.h:100
#define RLE_ALPHA
Definition: rle.h:65
FILE * rle_open_f(const char *prog_name, const char *f_name, const char *mode)
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
unsigned short rle_map
Definition: rle.h:57
void scan_usage()
char * cmd_name(char **argv)
Definition: cmd_name.c:31
int oflag
Definition: painttorle.c:45
Definition: rle_raw.h:47
FILE * rle_file
Definition: rle.h:114
unsigned int rle_getraw(rle_hdr *the_hdr, scanraw, nraw)
Definition: rle_getraw.c:78
rle_hdr out_hdr
Definition: dvirle2.c:89
int ncolors
Definition: rle.h:100
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
void print_map ( )
void print_map ( int  outalpha,
int  noutput,
int outchan,
char *  where 
)

Definition at line 574 of file rleswap.c.

578 {
579  int i;
580 
581  fprintf( stderr, "Channel mapping %sfrom input to output:\n", where );
582  if ( outalpha > -2 )
583  if ( outalpha < 0 )
584  fprintf( stderr, "alpha\t-> alpha\n" );
585  else
586  fprintf( stderr, "%d\t-> alpha\n", outalpha );
587  else if ( outalpha == -2 )
588  fprintf( stderr, "No output alpha channel\n" );
589  for ( i = 0; i < noutput; i++ )
590  if ( outchan[i] == -2 )
591  fprintf( stderr, "nothing\t-> %d\n", i );
592  else if ( outchan[i] == -1 )
593  fprintf( stderr, "alpha\t-> %d\n", i );
594  else
595  fprintf( stderr, "%d\t-> %d\n", outchan[i], i );
596  if ( noutput == 0 && outalpha < -1 )
597  fprintf( stderr, "Deleting %s\n", where );
598 }
int i
Definition: rletorla.c:82
void scan_usage ( )
void setup_map ( )
void setup_map ( int  fflag,
int  tflag,
int  dflag,
int  pflag,
int specs,
int  nspec,
rle_hdr in_hdr,
int  ncolors,
int  alpha,
char *  where,
int **  outchan,
int noutput,
int outalpha 
)

Definition at line 358 of file rleswap.c.

368 {
369  int errs = 0;
370  register int i;
371 
372  /* Initialize output variables. */
373  *outchan = 0;
374  *noutput = -1;
375  *outalpha = -2;
376 
377  /* Set up mapping and sanity check simultaneously */
378  if ( fflag ) /* where does output come from? */
379  {
380  *outchan = (int *)malloc( nspec * sizeof(int) );
381  bcopy( (char *)specs, (char *)*outchan, nspec * sizeof(int) );
382  *noutput = nspec;
383  /* Sanity check */
384  for ( i = 0; i < *noutput; i++ )
385  if ( (*outchan)[i] >= ncolors ||
386  (*outchan)[i] < -1 ||
387  (*outchan)[i] < 0 && !alpha )
388  {
389  fprintf( stderr, "%s: No input channel %d in %s\n",
390  in_hdr->cmd, (*outchan)[i], where );
391  errs++;
392  }
393 
394  if ( alpha )
395  *outalpha = -1; /* pass alpha channel through */
396  }
397 
398  if ( tflag ) /* where does input go */
399  {
400  if ( nspec > ncolors )
401  {
402  fprintf( stderr,
403  "%s: Input %s has %d channels, can't swap %d channels\n",
404  where, in_hdr->cmd, ncolors, nspec );
405  errs++;
406  }
407  else
408  {
409  /* Find highest output channel */
410  *noutput = -1; /* assume none */
411  for ( i = 0; i < nspec; i++ )
412  if ( specs[i] > *noutput )
413  *noutput = specs[i];
414  (*noutput)++;
415 
416  /* Allocate space for output pointers */
417  if ( *noutput > 0 )
418  {
419  *outchan = (int *)malloc( *noutput * sizeof( int ) );
420  RLE_CHECK_ALLOC( in_hdr->cmd, *outchan,
421  "output scanline pointers" );
422  }
423 
424  /* Initialize to empty state */
425  for ( i = 0; i < *noutput; i++ )
426  (*outchan)[i] = -2;
427 
428  /* Fill it in */
429  for ( i = 0; i < nspec; i++ )
430  {
431  if ( specs[i] < -1 )
432  {
433  fprintf( stderr, "%s: No channel %d in output %s\n",
434  in_hdr->cmd, specs[i], where );
435  errs++;
436  }
437  else if ( specs[i] < 0 )
438  {
439  if ( *outalpha > -2 )
440  {
441  fprintf( stderr,
442  "%s: Output alpha channel can't come from both inputs %d and %d.\n",
443  in_hdr->cmd, *outalpha, i );
444  errs++;
445  }
446  else
447  *outalpha = i;
448  }
449  else
450  {
451  if ( (*outchan)[specs[i]] > -2 )
452  {
453  fprintf( stderr,
454  "%s: Output channel %d can't come from both inputs %d and %d.\n",
455  in_hdr->cmd, specs[i],
456  (*outchan)[specs[i]], i );
457  errs++;
458  }
459  else
460  (*outchan)[specs[i]] = i;
461  }
462  }
463  if ( *outalpha < -1 && alpha )
464  *outalpha = -1; /* map alpha channel through */
465  }
466  }
467 
468  if ( dflag ) /* Delete some input channels */
469  {
470  /* First, set up identity mapping from input to output */
471  *noutput = ncolors;
472 
473  /* Allocate space for output pointers */
474  *outchan = (int *)malloc( *noutput * sizeof( int ) );
475  RLE_CHECK_ALLOC( in_hdr->cmd, *outchan,
476  "output scanline pointers" );
477 
478  for ( i = 0; i < *noutput; i++ )
479  (*outchan)[i] = i;
480  if ( alpha )
481  *outalpha = -1;
482 
483  /* Now, delete indicated channels from mapping */
484  for ( i = 0; i < nspec; i++ )
485  if ( specs[i] < -alpha ||
486  specs[i] >= ncolors )
487  fprintf( stderr, "%s: Warning: No channel %d in input %s\n",
488  in_hdr->cmd, specs[i], where );
489  else if ( specs[i] == -1 && *outalpha == -2 ||
490  (*outchan)[specs[i]] == -2 )
491  fprintf( stderr, "%s: Warning: Deleted channel %d twice\n",
492  in_hdr->cmd, specs[i] );
493  else if ( specs[i] >= 0 )
494  (*outchan)[specs[i]] = -2; /* null it out */
495  else
496  *outalpha = -2;
497 
498  /* Figure out how many output channels we really have */
499  while ( (*outchan)[*noutput - 1] == -2 )
500  (*noutput)--;
501  }
502 
503  if ( pflag ) /* Do pairs of mappings */
504  {
505  /* Find highest output channel */
506  *noutput = -1; /* assume none */
507  for ( i = 1; i < nspec; i += 2 )
508  if ( specs[i] > *noutput )
509  *noutput = specs[i];
510  (*noutput)++;
511 
512  /* Allocate space for output pointers */
513  if ( *noutput > 0 )
514  {
515  *outchan = (int *)malloc( *noutput * sizeof( int ) );
516  RLE_CHECK_ALLOC( in_hdr->cmd, *outchan,
517  "output scanline pointers" );
518  }
519 
520  /* Initialize to empty state */
521  for ( i = 0; i < *noutput; i++ )
522  (*outchan)[i] = -2;
523 
524  /* Fill it in */
525  for ( i = 0; i < nspec; i += 2 )
526  {
527  if ( specs[i] < -alpha ||
528  specs[i] >= ncolors )
529  {
530  fprintf( stderr, "%s: No channel %d in input %s\n",
531  in_hdr->cmd, specs[i], where );
532  errs++;
533  }
534  if ( specs[i+1] < -1 )
535  {
536  fprintf( stderr, "%s: No channel %d in output %s\n",
537  in_hdr->cmd, specs[i+1], where );
538  errs++;
539  }
540  else if ( specs[i+1] < 0 )
541  {
542  if ( *outalpha > -2 )
543  {
544  fprintf( stderr,
545  "%s: Output alpha channel can't come from both inputs %d and %d.\n",
546  in_hdr->cmd, *outalpha, specs[i] );
547  errs++;
548  }
549  else
550  *outalpha = specs[i];
551  }
552  else
553  {
554  if ( (*outchan)[specs[i+1]] > -2 )
555  {
556  fprintf( stderr,
557  "%s: Output channel %d can't come from both inputs %d and %d.\n",
558  in_hdr->cmd, specs[i+1],
559  (*outchan)[specs[i+1]], specs[i] );
560  errs++;
561  }
562  else
563  (*outchan)[specs[i+1]] = specs[i];
564  }
565  }
566  }
567 
568  /* If errors, go away */
569  if ( errs )
570  exit( 1 );
571 }
const char * cmd
Definition: rle.h:133
void * malloc()
int i
Definition: rletorla.c:82
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86

Variable Documentation

char rcsid[] = "$Header: /tmp_mnt/n/itn/hendrix/u/spencer/RCS/rleswap.c,v 3.0.1.4 1992/04/30 14:14:20 spencer Exp spencer $"

Definition at line 28 of file rleswap.c.