28 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 $";
108 int tflag = 0, fflag = 0, oflag = 0, dflag = 0, pflag = 0, verbose = 0;
110 char * fname = NULL, *out_fname = NULL;
111 FILE *outfile = stdout;
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.)";
135 int * outchan = 0, noutput = 0, outalpha = -2;
136 int *mapoutchan = 0, mapnoutput = 0, mapoutalpha = -2;
137 rle_hdr in_hdr, out_hdr;
138 rle_op ** scanraw, ** outraw;
139 int * nraw, * outnraw, y, nskip;
140 int rle_cnt, rle_err;
146 &fflag
, &nspec
, &specs
,
147 &tflag
, &nspec
, &specs
,
148 &dflag
, &nspec
, &specs
,
149 &pflag
, &nspec
, &specs
,
150 &oflag
, &out_fname
, &fname
) == 0 )
154 if ( fflag + tflag + dflag + pflag != 1 )
157 "%s: You must specify exactly one of -d, -f, -t, or -p\n",
166 if ( pflag && (nspec % 2) != 0 )
168 fprintf( stderr,
"%s: You must specify pairs of channels with -p\n",
188 &outchan
, &noutput
, &outalpha
);
193 &outchan
, &noutput
, &outalpha
);
196 if ( mflag != 2 && in_hdr
.ncmap > 0 )
199 &mapoutchan
, &mapnoutput
, &mapoutalpha
);
204 int cmap_different = mflag != 2 &&
205 (mflag == 1 || mapnoutput != noutput);
208 cmap_different ?
"image data " :
"" );
209 if ( cmap_different )
223 if ( outalpha != -2 )
233 for ( i = 0; i < noutput; i++ )
234 if ( outchan[i] != -2 )
243 (
int *)malloc( out_hdr
.ncolors *
sizeof(
int) );
245 "output background color" );
247 for ( i = 0; i < noutput; i++ )
248 if ( outchan[i] < 0 )
255 if ( mflag != 2 && in_hdr
.ncmap > 0 )
258 int cmapshift = 16 - out_hdr
.cmaplen;
260 if ( mapnoutput > 0 )
262 out_hdr
.cmap = (
rle_map *)malloc( mapnoutput * cmaplen *
265 "output color map" );
269 out_hdr
.ncmap = mapnoutput;
272 for ( i = 0; i < mapnoutput; i++ )
273 if ( mapoutchan[i] >= 0 && mapoutchan[i] < in_hdr
.ncmap )
275 register rle_map * imap, * omap;
277 imap = &in_hdr
.cmap[mapoutchan[i] * cmaplen];
278 omap = &out_hdr
.cmap[i * cmaplen];
280 for ( j = 0; j < cmaplen; j++ )
287 omap = &out_hdr
.cmap[i * cmaplen];
288 for ( j = 0; j < cmaplen; j++ )
289 *omap++ = j << cmapshift;
307 free( (
char *)outraw[i] );
320 if ( outalpha != -2 )
322 outraw[-1] = scanraw[outalpha];
323 outnraw[-1] = nraw[outalpha];
326 for ( i = 0; i < noutput; i++ )
327 if ( outchan[i] != -2 )
329 outraw[i] = scanraw[outchan[i]];
330 outnraw[i] = nraw[outchan[i]];
343 if ( outchan != specs )
361 int fflag, tflag, dflag, pflag;
367 register int **outchan, *noutput, *outalpha;
380 *outchan = (
int *)malloc( nspec *
sizeof(
int) );
381 bcopy( (
char *)specs, (
char *)*outchan, nspec *
sizeof(
int) );
384 for ( i = 0; i < *noutput; i++ )
385 if ( (*outchan)[i] >= ncolors ||
386 (*outchan)[i] < -1 ||
387 (*outchan)[i] < 0 && !alpha )
389 fprintf( stderr,
"%s: No input channel %d in %s\n",
390 in_hdr
->cmd, (*outchan)[i], where );
400 if ( nspec > ncolors )
403 "%s: Input %s has %d channels, can't swap %d channels\n",
404 where, in_hdr
->cmd, ncolors, nspec );
411 for ( i = 0; i < nspec; i++ )
412 if ( specs[i] > *noutput )
419 *outchan = (
int *)malloc( *noutput *
sizeof(
int ) );
421 "output scanline pointers" );
425 for ( i = 0; i < *noutput; i++ )
429 for ( i = 0; i < nspec; i++ )
433 fprintf( stderr,
"%s: No channel %d in output %s\n",
434 in_hdr
->cmd, specs[i], where );
437 else if ( specs[i] < 0 )
439 if ( *outalpha > -2 )
442 "%s: Output alpha channel can't come from both inputs %d and %d.\n",
443 in_hdr
->cmd, *outalpha, i );
451 if ( (*outchan)[specs[i]] > -2 )
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 );
460 (*outchan)[specs[i]] = i;
463 if ( *outalpha < -1 && alpha )
474 *outchan = (
int *)malloc( *noutput *
sizeof(
int ) );
476 "output scanline pointers" );
478 for ( i = 0; i < *noutput; i++ )
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;
499 while ( (*outchan)[*noutput - 1] == -2 )
507 for ( i = 1; i < nspec; i += 2 )
508 if ( specs[i] > *noutput )
515 *outchan = (
int *)malloc( *noutput *
sizeof(
int ) );
517 "output scanline pointers" );
521 for ( i = 0; i < *noutput; i++ )
525 for ( i = 0; i < nspec; i += 2 )
527 if ( specs[i] < -alpha ||
528 specs[i] >= ncolors )
530 fprintf( stderr,
"%s: No channel %d in input %s\n",
531 in_hdr
->cmd, specs[i], where );
534 if ( specs[i+1] < -1 )
536 fprintf( stderr,
"%s: No channel %d in output %s\n",
537 in_hdr
->cmd, specs[i+1], where );
540 else if ( specs[i+1] < 0 )
542 if ( *outalpha > -2 )
545 "%s: Output alpha channel can't come from both inputs %d and %d.\n",
546 in_hdr
->cmd, *outalpha, specs[i] );
550 *outalpha = specs[i];
554 if ( (*outchan)[specs[i+1]] > -2 )
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] );
563 (*outchan)[specs[i+1]] = specs[i];
575 int outalpha, noutput;
581 fprintf( stderr,
"Channel mapping %sfrom input to output:\n", where );
584 fprintf( stderr,
"alpha\t-> alpha\n" );
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 );
595 fprintf( stderr,
"%d\t-> %d\n", outchan[i], i );
596 if ( noutput == 0 && outalpha < -1 )
597 fprintf( stderr,
"Deleting %s\n", where );
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
#define RLE_SET_BIT(glob, bit)
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
void rle_freeraw(rle_hdr *the_hdr, scanraw, nraw)
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
int rle_raw_alloc(rle_hdr *the_hdr, rle_op ***scanp, int **nrawp)
char * cmd_name(char **argv)
void main(int argc, char **argv)
int rle_get_setup(rle_hdr *the_hdr)
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 rle_putraw(rle_op **scanraw, int *nraw, rle_hdr *the_hdr)
int rle_get_error(int code, const char *pgmname, const char *fname)
int scanargs(int argc, char **argv, const char *format,...)
void rle_puteof(rle_hdr *the_hdr)
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
void rle_skiprow(rle_hdr *the_hdr, int nrow)
#define RLE_CLR_BIT(glob, bit)
void rle_put_setup(rle_hdr *the_hdr)
void print_map(int outalpha, int noutput, int *outchan, char *where)
void rle_raw_free(rle_hdr *the_hdr, rle_op **scanp, nrawp)
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
unsigned int rle_getraw(rle_hdr *the_hdr, scanraw, nraw)
#define RLE_CHECK_ALLOC(pgm, ptr, name)