Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rleswap.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 /*
19  * rleswap.c - Swap the channels in an RLE file around
20  *
21  * Author: Spencer W. Thomas
22  * Computer Science Dept.
23  * University of Utah
24  * Date: Thu Jan 22 1987
25  * Copyright (c) 1987, University of Utah
26  */
27 #ifndef lint
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 $";
29 #endif
30 /*
31 rleswap() Tag the file.
32 */
33 
34 #include <stdio.h>
35 #include "rle.h"
36 #include "rle_raw.h"
37 
38 extern void scan_usage();
39 void setup_map(), print_map();
40 
41 /*****************************************************************
42  * TAG( main )
43  *
44  * Usage:
45  * rleswap [-mM] [-p channel-pairs,...] [-f from-channels,...]
46  * [-t to-channels,...] [-d delete-channels,...] [infile]
47  * Inputs:
48  * -m: Modify only the colormap. Image data is not
49  * affected.
50  * -M: Don't modify the colormap. Only the image
51  * data is affected.
52  *
53  * -p, -f, -t, -d: Only one of these may be specified, they indicate
54  * different ways of indicating the channel swapping
55  * from input to output.
56  *
57  * channel-pairs: A comma separated list of pairs of channel numbers
58  * The first channel of each pair indicates a channel
59  * in the input file that will be mapped to the
60  * the channel in the output file indicated by the
61  * second number in the pair. No output channel
62  * number may appear more than once. Any input channel
63  * not mentioned will not appear in the output file.
64  * Any output channel not mentioned will not receive
65  * image data.
66  *
67  * from-channels: A comma separated list of numbers indicating the
68  * input channel that maps to each output channel
69  * in sequence. I.e., the first number indicates
70  * the input channel mapping to output channel 0.
71  * The alpha channel will be passed through unchanged
72  * if present. Any input channels not mentioned
73  * in the list will not appear in the output.
74  *
75  * to-channels: A comma separated list of numbers indicating the
76  * output channel to which each input channel, in
77  * sequence, will map. I.e., the first number gives
78  * the output channel to which the first input channel
79  * will map. No number may be repeated in this list.
80  * The alpha channel will be passed through unchanged
81  * if present. Any output channel not mentioned in
82  * the list will not receive image data. If there
83  * are fewer numbers in the list than there are input
84  * channels, the excess input channels will be ignored.
85  * If there are more numbers than input channels, it
86  * is an error.
87  *
88  * delete-channels:A comma separated list of input channels that should
89  * not appear in the output. All other channels will
90  * be passed through unchanged.
91  *
92  * infile: Optional input file name specification.
93  * outfile: Optional output file name specification.
94  * Outputs:
95  * An RLE file similar to the input file, but with the color channels
96  * remapped as indicated, will be written to the output.
97  * Assumptions:
98  * [None]
99  * Algorithm:
100  * [None]
101  */
102 void
104 int argc;
105 char **argv;
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;
137  rle_hdr in_hdr, out_hdr;
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 }
356 
357 void
361 int fflag, tflag, dflag, pflag;
362 int *specs;
363 int nspec;
364 rle_hdr *in_hdr;
365 int ncolors, alpha;
366 char *where;
367 register int **outchan, *noutput, *outalpha;
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 }
572 
573 void
575 int outalpha, noutput;
576 int *outchan;
577 char *where;
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 }
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
char rcsid[]
Definition: rleswap.c:28
#define RLE_SET_BIT(glob, bit)
Definition: rle.h:122
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
void rle_freeraw(rle_hdr *the_hdr, scanraw, nraw)
Definition: rle_getraw.c:268
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
int rle_raw_alloc(rle_hdr *the_hdr, rle_op ***scanp, int **nrawp)
Definition: rle_raw_alc.c:60
#define RLE_EMPTY
Definition: rle.h:73
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
rle_map * cmap
Definition: rle.h:112
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: rleswap.c:358
void rle_putraw(rle_op **scanraw, int *nraw, rle_hdr *the_hdr)
Definition: rle_putraw.c:60
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
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
#define RLE_EOF
Definition: rle.h:74
#define CONST_DECL
Definition: rle_config.h:42
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
void rle_skiprow(rle_hdr *the_hdr, int nrow)
Definition: rle_putrow.c:393
int background
Definition: rle.h:100
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
int ncmap
Definition: rle.h:100
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
void print_map(int outalpha, int noutput, int *outchan, char *where)
Definition: rleswap.c:574
unsigned short rle_map
Definition: rle.h:57
void scan_usage()
void rle_raw_free(rle_hdr *the_hdr, rle_op **scanp, nrawp)
Definition: rle_raw_alc.c:131
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
FILE * rle_file
Definition: rle.h:114
unsigned int rle_getraw(rle_hdr *the_hdr, scanraw, nraw)
Definition: rle_getraw.c:78
int ncolors
Definition: rle.h:100
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86