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

Go to the source code of this file.

Macros

#define MALLOC_ERR   RLE_CHECK_ALLOC( progname, 0, 0 )
 

Functions

rle_map ** allocmap ()
 
void filemap ()
 
void copymap ()
 
void shiftmap ()
 
void copy_into_shortrow ()
 
void edge_enhance ()
 
void fsdither ()
 
void find_closest ()
 
void main (int argc, argv)
 
void copy_into_shortrow (rle_hdr *in_hdr, rle_pixel **rlerow, short *shortrow)
 
void edge_enhance (rle_hdr *in_hdr, rle_pixel **row_b, rle_pixel **row_m, rle_pixel **row_t, rle_pixel **edge_row, int blend, int blend_divisor)
 
void fsdither (rle_hdr *in_hdr, rle_map **map, int maplen, short *row_bottom, short *row_top, rle_pixel **outrow)
 
void filemap (int tflag, char *mapfname, int nchan, int length, rle_map **amap)
 
rle_map ** allocmap (int nchan, int length, rle_map *cmap)
 
void shiftmap (rle_map **map, int nchan, int length, int bits)
 
void copymap (rle_map **inmap, int nchan, int length, rle_map **outmap)
 
void find_closest (rle_map **map, int nchan, int maplen, rle_pixel *pixel, strchr)
 

Variables

static char rcs_ident [] = "$Id: rledither.c,v 3.0.1.1 1992/01/23 16:42:22 spencer Exp $"
 
char * progname
 

Macro Definition Documentation

#define MALLOC_ERR   RLE_CHECK_ALLOC( progname, 0, 0 )

Definition at line 42 of file rledither.c.

Function Documentation

rle_map** allocmap ( )
rle_map** allocmap ( int  nchan,
int  length,
rle_map cmap 
)

Definition at line 484 of file rledither.c.

488 {
489  rle_map ** map;
490  register int i;
491 
492  map = (rle_map **)malloc( nchan * sizeof( rle_map * ) );
493  RLE_CHECK_ALLOC( progname, map, 0 );
494  if ( cmap == NULL )
495  {
496  map[0] = (rle_map *)malloc( nchan * length * sizeof( rle_map ) );
497  RLE_CHECK_ALLOC( progname, map[0], 0 );
498  }
499  else
500  map[0] = cmap;
501  for ( i = 1; i < nchan; i++ )
502  map[i] = &map[i-1][length];
503  return map;
504 }
short map[3][256]
Definition: getap.c:115
char * progname
Definition: rledither.c:48
void * malloc()
int i
Definition: rletorla.c:82
int nchan
Definition: fant.c:104
unsigned short rle_map
Definition: rle.h:57
rle_pixel ** cmap
Definition: get4d.c:47
#define RLE_CHECK_ALLOC(pgm, ptr, name)
Definition: rle.h:86
void copy_into_shortrow ( )
void copy_into_shortrow ( rle_hdr in_hdr,
rle_pixel **  rlerow,
short *  shortrow 
)

Definition at line 206 of file rledither.c.

210 {
211  int chan,i;
212 
213  for (i=0; i <= in_hdr->xmax; i++)
214  {
215  for (chan = 0; chan < in_hdr->ncolors; chan++)
216  {
217  *shortrow++ = rlerow[chan][i];
218  }
219  }
220 }
int xmax
Definition: rle.h:100
int i
Definition: rletorla.c:82
int ncolors
Definition: rle.h:100
void copymap ( )
void copymap ( rle_map **  inmap,
int  nchan,
int  length,
rle_map **  outmap 
)

Definition at line 540 of file rledither.c.

543 {
544  register rle_map *ie, *oe;
545  register int i;
546 
547  for ( i = nchan * length, ie = inmap[0], oe = outmap[0];
548  i > 0; i--, ie++, oe++ )
549  *oe = *ie;
550 }
int i
Definition: rletorla.c:82
int nchan
Definition: fant.c:104
unsigned short rle_map
Definition: rle.h:57
void edge_enhance ( )
void edge_enhance ( rle_hdr in_hdr,
rle_pixel **  row_b,
rle_pixel **  row_m,
rle_pixel **  row_t,
rle_pixel **  edge_row,
int  blend,
int  blend_divisor 
)

Definition at line 223 of file rledither.c.

227 {
228  int chan, i;
229  int total, diff, avg, result;
230  for (chan = 0; chan < in_hdr->ncolors; chan++)
231  {
232  /* i = 0 case, ignore left column of pixels */
233  total = row_b[chan][0] + row_b[chan][1] +
234  row_m[chan][1] +
235  row_t[chan][0] + row_t[chan][1];
236  avg = total / 5;
237  diff = avg - row_m[chan][0];
238  result = row_m[chan][0] - (diff * blend / blend_divisor);
239  if (result < 0)
240  edge_row[chan][0] = 0;
241  else if (result > 255)
242  edge_row[chan][0] = 255;
243  else
244  edge_row[chan][0] = result;
245 
246  /* all the nice cases */
247  for (i=1; i < in_hdr->xmax; i++)
248  {
249  total = row_b[chan][i-1] + row_b[chan][i] + row_b[chan][i+1] +
250  row_m[chan][i-1] + row_m[chan][i+1] +
251  row_t[chan][i-1] + row_t[chan][i] + row_t[chan][i+1];
252  avg = total >> 3; /* divide by 8 */
253  diff = avg - row_m[chan][i];
254  result = row_m[chan][i] - (diff * blend / blend_divisor);
255  if (result < 0)
256  edge_row[chan][i] = 0;
257  else if (result > 255)
258  edge_row[chan][i] = 255;
259  else
260  edge_row[chan][i] = result;
261  }
262  /* i = in_hdr.xmax case, ignore right column of pixels */
263  i = in_hdr->xmax;
264  total = row_b[chan][i-1] + row_b[chan][i] +
265  row_m[chan][i-1] +
266  row_t[chan][i-1] + row_t[chan][i];
267  avg = total / 5;
268  diff = avg - row_m[chan][i];
269  result = row_m[chan][i] - (diff * blend / blend_divisor);
270  if (result < 0)
271  edge_row[chan][i] = 0;
272  else if (result > 255)
273  edge_row[chan][i] = 255;
274  else
275  edge_row[chan][i] = result;
276  }
277 }
int xmax
Definition: rle.h:100
int i
Definition: rletorla.c:82
int ncolors
Definition: rle.h:100
void filemap ( )
void filemap ( int  tflag,
char *  mapfname,
int  nchan,
int  length,
rle_map **  amap 
)

Definition at line 391 of file rledither.c.

395 {
396  FILE * mapfile;
397  register int c, i;
398  int ent;
399 
400  if ( ( mapfile = fopen( mapfname, "r" ) ) == NULL )
401  {
402  fprintf( stderr, "%s: Couldn't open map file %s: ",
403  progname, mapfname );
404  perror("");
405  exit(-1);
406  }
407 
408  if ( tflag == 1 ) /* channel-major order */
409  for ( c = 0; c < nchan; c++ )
410  for ( i = 0; i < length; i++ )
411  switch ( fscanf( mapfile, "%d", &ent ) )
412  {
413  case EOF: /* EOF */
414  fprintf( stderr,
415  "%s: Premature end of file reading map %s at channel %d, entry %d\n",
416  progname, mapfname, c, i );
417  exit(-1);
418  /* NOTREACHED */
419  case 1: /* Got it */
420  amap[c][i] = ent;
421  break;
422  case 0: /* no conversion? */
423  fprintf( stderr,
424  "%s: Bad data in map %s at channel %d, entry %d\n",
425  progname, mapfname, c, i );
426  exit(-1);
427  /* NOTREACHED */
428  default: /* error */
429  fprintf( stderr,
430  "%s: Error reading map %s at channel %d, entry %d\n",
431  progname, mapfname, c, i );
432  exit(-1);
433  /* NOTREACHED */
434  }
435  else /* Entry-major order */
436  for ( i = 0; i < length; i++ )
437  for ( c = 0; c < nchan; c++ )
438  switch ( fscanf( mapfile, "%d", &ent ) )
439  {
440  case EOF: /* EOF */
441  fprintf( stderr,
442  "%s: Premature end of file reading map %s at entry %d, channel %d\n",
443  progname, mapfname, i, c );
444  exit(-1);
445  /* NOTREACHED */
446  case 1: /* Got it */
447  amap[c][i] = ent;
448  break;
449  case 0: /* no conversion? */
450  fprintf( stderr,
451  "%s: Bad data in map %s at entry %d, channel %d\n",
452  progname, mapfname, i, c );
453  exit(-1);
454  /* NOTREACHED */
455  default: /* error */
456  fprintf( stderr,
457  "%s: Error reading map %s at entry %d, channel %d: ",
458  progname, mapfname, i, c );
459  perror("");
460  exit(-1);
461  /* NOTREACHED */
462  }
463  fclose( mapfile );
464 }
char * progname
Definition: rledither.c:48
int i
Definition: rletorla.c:82
int nchan
Definition: fant.c:104
void find_closest ( )
void find_closest ( rle_map **  map,
int  nchan,
int  maplen,
rle_pixel pixel,
strchr   
)

Definition at line 553 of file rledither.c.

558 {
559  int i, closest, chan;
560  long bestdist, dist;
561 
562  closest = -1;
563  bestdist = 256*256*nchan + 1;
564  for (i=0; i < maplen; i++)
565  {
566  dist = 0L;
567  for (chan = 0; chan < nchan; chan++)
568  {
569  int tmp = map[chan][i] - pixel[chan];
570  dist += tmp * tmp;
571  }
572  if (dist < bestdist)
573  {
574  closest = i;
575  bestdist = dist;
576  }
577  }
578  *index = closest;
579 }
int maplen
Definition: rletoppm.c:61
short map[3][256]
Definition: getap.c:115
#define index
Definition: rle_config.h:96
int i
Definition: rletorla.c:82
int nchan
Definition: fant.c:104
void fsdither ( )
void fsdither ( rle_hdr in_hdr,
rle_map **  map,
int  maplen,
short *  row_bottom,
short *  row_top,
rle_pixel **  outrow 
)

Definition at line 280 of file rledither.c.

286 {
287  register rle_pixel *optr;
288  register int j;
289  register short *thisptr, *nextptr = NULL;
290  int chan;
291  static int numchan = 0;
292  int lastline = 0, lastpixel ;
293  static int *cval=0;
294  static rle_pixel *pixel=0;
295 
296  if ( numchan != in_hdr->ncolors )
297  if ( cval )
298  {
299  free( cval );
300  free( pixel );
301  }
302 
303  numchan = in_hdr->ncolors;
304  if (!cval) {
305  if ((cval = (int *) malloc( numchan * sizeof(int) )) == 0)
306  MALLOC_ERR;
307  if ((pixel = (rle_pixel *) malloc( numchan * sizeof(rle_pixel) )) == 0)
308  MALLOC_ERR;
309  }
310  optr = outrow[RLE_RED];
311 
312  thisptr = row_top;
313  if (row_bottom)
314  nextptr = row_bottom;
315  else
316  lastline = 1;
317 
318  for(j=0; j <= in_hdr->xmax ; j++)
319  {
320  int cmap_index=0;
321 
322  lastpixel = (j == in_hdr->xmax) ;
323 
324  for (chan = 0; chan < numchan; chan++)
325  {
326  cval[chan] = *thisptr++ ;
327 
328  /* Current channel value has been accumulating error, it could be
329  * out of range.
330  */
331  if( cval[chan] < 0 ) cval[chan] = 0 ;
332  else if( cval[chan] > 255 ) cval[chan] = 255 ;
333 
334  pixel[chan] = cval[chan];
335  }
336 
337  /* find closest color */
338  find_closest(map, numchan, maplen, pixel, &cmap_index);
339  *optr++ = cmap_index;
340 
341  /* thisptr is now looking at pixel to the right of current pixel
342  * nextptr is looking at pixel below current pixel
343  * So, increment thisptr as stuff gets stored. nextptr gets moved
344  * by one, and indexing is done +/- numchan.
345  */
346  for (chan = 0; chan < numchan; chan++)
347  {
348  cval[chan] -= map[chan][cmap_index];
349 
350  if( !lastpixel )
351  {
352  thisptr[chan] += cval[chan] * 7 / 16 ;
353  }
354  if( !lastline )
355  {
356  if( j != 0 )
357  {
358  nextptr[-numchan] += cval[chan] * 3 / 16 ;
359  }
360  nextptr[0] += cval[chan] * 5 / 16 ;
361  if( !lastpixel )
362  {
363  nextptr[numchan] += cval[chan] / 16 ;
364  }
365  nextptr ++;
366  }
367  }
368  }
369 }
int maplen
Definition: rletoppm.c:61
#define MALLOC_ERR
Definition: rledither.c:42
short map[3][256]
Definition: getap.c:115
#define RLE_RED
Definition: rle.h:62
int xmax
Definition: rle.h:100
void find_closest()
unsigned char rle_pixel
Definition: rle.h:56
void * malloc()
int ncolors
Definition: rle.h:100
void main ( int  argc,
argv   
)

Definition at line 51 of file rledither.c.

54 {
55  int i, temp, y;
56  int oflag = 0;
57  int blend, blend_divisor = 256;
58  float edge_factor = 0.0;
59  int top, middle, bottom, edgetop, edgebottom;
61  rle_pixel **cleanrows[3], **edgerows[2], **outrow;
62  short *shortrows[2];
63  char *infname = NULL, *outfname = NULL, *mapfname = NULL;
64  FILE *outfile = stdout;
65  int nchan = 3, length = 256, tflag = 0;
66  rle_map **amap, **map;
67  int rle_cnt, rle_err;
68  char cmap_comment[80];
69 
70  progname = cmd_name( argv );
71  in_hdr = *rle_hdr_init( NULL );
72  out_hdr = *rle_hdr_init( NULL );
73 
74 
75  if ( scanargs( argc, argv,
76  "% e%-edge_factor!f l%-nchan!dlength!d \n\
77 \ttf!-mapfile!s o%-outfile!s infile%s",
78  &i, &edge_factor, &i, &nchan, &length,
79  &tflag, &mapfname,
80  &oflag, &outfname, &infname ) == 0 )
81  exit( 1 );
82 
83  in_hdr.rle_file = rle_open_f( progname, infname, "r" );
84  rle_names( &in_hdr, progname, infname, 0 );
85  rle_names( &out_hdr, progname, outfname, 0 );
86 
87  /* Allocate space for the applied map */
88  amap = allocmap( nchan, 256, NULL );
89  map = allocmap( nchan, 256, NULL );
90  filemap( tflag, mapfname, nchan, length, amap );
91  copymap( amap, nchan, 256, map );
92  shiftmap( amap, nchan, 256, 8 );
93 
94  for ( rle_cnt = 0;
95  (rle_err = rle_get_setup( &in_hdr )) == RLE_SUCCESS;
96  rle_cnt++ )
97  {
98  (void)rle_hdr_cp( &in_hdr, &out_hdr );
99  if ( rle_cnt == 0 )
100  outfile = rle_open_f( cmd_name( argv ), outfname, "w" );
101  out_hdr.rle_file = outfile;
102 
103  rle_addhist( argv, &in_hdr, &out_hdr );
104 
105  /* alpha on dithered stuff is too weird... */
106  out_hdr.alpha = 0;
107  out_hdr.ncolors = 1; /* Just one chan, the cmap index */
108  for (i = 1; i < in_hdr.ncolors; i++)
109  RLE_CLR_BIT( out_hdr, i ); /* Kill extra output channels */
110  out_hdr.ncmap = nchan;
111  out_hdr.cmaplen = 8; /* == 256 entries */
112  out_hdr.cmap = (rle_map *) amap[0];
113  sprintf( cmap_comment, "color_map_length=%d", length );
114  rle_putcom( cmap_comment, &out_hdr );
115  rle_put_setup( &out_hdr );
116 
117  in_hdr.xmax -= in_hdr.xmin;
118  in_hdr.xmin = 0;
119 
120  /* Oink. */
121  for (i = 0; i < 3; i++)
122  if (rle_row_alloc( &in_hdr, &cleanrows[i] ) < 0)
123  MALLOC_ERR;
124 
125  if (rle_row_alloc( &in_hdr, &edgerows[0] ) < 0)
126  MALLOC_ERR;
127 
128  if (rle_row_alloc( &in_hdr, &edgerows[1] ) < 0)
129  MALLOC_ERR;
130 
131  if (rle_row_alloc( &out_hdr, &outrow ) < 0)
132  MALLOC_ERR;
133 
134  if ( (shortrows[0] = (short *)malloc(in_hdr.ncolors
135  * (in_hdr.xmax+1)
136  * sizeof(short) )) == 0 )
137  MALLOC_ERR;
138  if ( (shortrows[1] = (short *)malloc(in_hdr.ncolors
139  * (in_hdr.xmax+1)
140  * sizeof(short) )) == 0 )
141  MALLOC_ERR;
142 
143  if (edge_factor < 0.0)
144  blend = 0;
145  else
146  blend = (int) (edge_factor * (float) blend_divisor);
147 
148  rle_getrow(&in_hdr, cleanrows[2]);
149  rle_getrow(&in_hdr, cleanrows[1]);
150  bottom = 0;
151  middle = 1;
152  top = 2;
153  edgetop = 1;
154  edgebottom = 0;
155  /* just copy the top row, it gets no edge enhancement */
156  copy_into_shortrow( &in_hdr,
157  cleanrows[top], shortrows[edgetop] );
158 
159  for (y = in_hdr.ymin+2; y <= in_hdr.ymax; y++)
160  {
161  rle_getrow(&in_hdr, cleanrows[bottom]);
162  edge_enhance(&in_hdr,
163  cleanrows[bottom], cleanrows[middle], cleanrows[top],
164  edgerows[edgebottom],
165  blend, blend_divisor);
166  copy_into_shortrow( &in_hdr,
167  edgerows[edgebottom], shortrows[edgebottom] );
168  fsdither(&in_hdr, map, length,
169  shortrows[edgebottom], shortrows[edgetop], outrow);
170  rle_putrow( outrow, in_hdr.xmax+1, &out_hdr);
171  /* swap the row pointers */
172  temp = top; top = middle; middle = bottom; bottom = temp;
173  temp = edgetop; edgetop = edgebottom; edgebottom = temp;
174  }
175  fsdither(&in_hdr, map, length,
176  shortrows[edgebottom], shortrows[edgetop], outrow);
177  rle_putrow( outrow, in_hdr.xmax+1, &out_hdr);
178  /* just copy the middle row, it gets no edge enhancement */
179  copy_into_shortrow( &in_hdr,
180  cleanrows[middle], shortrows[edgetop] );
181  fsdither(&in_hdr, map, length, NULL, shortrows[edgetop], outrow);
182  rle_putrow( outrow, in_hdr.xmax+1, &out_hdr);
183 
184  rle_puteof( &out_hdr );
185 
186  /* Release storage. */
187  for (i = 0; i < 3; i++)
188  rle_row_free( &in_hdr, cleanrows[i] );
189  rle_row_free( &in_hdr, edgerows[0] );
190  rle_row_free( &in_hdr, edgerows[1] );
191  rle_row_free( &out_hdr, outrow );
192  free( shortrows[0] );
193  free( shortrows[1] );
194  }
195 
196  /* Check for an error. EOF or EMPTY is ok if at least one image
197  * has been read. Otherwise, print an error message.
198  */
199  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
200  rle_get_error( rle_err, cmd_name( argv ), infname );
201 
202  exit( 0 );
203 }
void rle_row_free(rle_hdr *the_hdr, rle_pixel **scanp)
Definition: rle_row_alc.c:114
int xmin
Definition: rle.h:100
void copymap()
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
static rle_hdr in_hdr
Definition: rletogif.c:37
void edge_enhance()
FILE * outfile
Definition: giftorle.c:61
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
Definition: rle_row_alc.c:56
#define MALLOC_ERR
Definition: rledither.c:42
#define RLE_EMPTY
Definition: rle.h:73
const char * rle_putcom(const char *value, rle_hdr *the_hdr)
rle_map * cmap
Definition: rle.h:112
void rle_putrow(rle_pixel *rows[], int rowlen, rle_hdr *the_hdr)
short map[3][256]
Definition: getap.c:115
void rle_addhist(char *argv[], rle_hdr *in_hdr, rle_hdr *out_hdr)
#define RLE_SUCCESS
Definition: rle.h:70
void filemap()
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
string infname
Definition: getbob.c:68
char * progname
Definition: rledither.c:48
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
Definition: rle.h:96
int xmax
Definition: rle.h:100
static char temp[]
Definition: into.c:45
int top
Definition: getap.c:94
short middle
Definition: getap.c:98
int rle_get_error(int code, const char *pgmname, const char *fname)
#define RLE_EOF
Definition: rle.h:74
int
Definition: getami.c:848
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
void fsdither()
int ncmap
Definition: rle.h:100
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
rle_map ** allocmap()
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
void copy_into_shortrow()
int alpha
Definition: rle.h:100
FILE * rle_open_f(const char *prog_name, const char *f_name, const char *mode)
int nchan
Definition: fant.c:104
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
unsigned short rle_map
Definition: rle.h:57
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void shiftmap()
int oflag
Definition: painttorle.c:45
int rle_getrow(rle_hdr *the_hdr, rle_pixel *scanline[])
FILE * rle_file
Definition: rle.h:114
rle_hdr out_hdr
Definition: dvirle2.c:89
int ncolors
Definition: rle.h:100
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
void shiftmap ( )
void shiftmap ( rle_map **  map,
int  nchan,
int  length,
int  bits 
)

Definition at line 524 of file rledither.c.

527 {
528  register rle_map * e;
529  register int i;
530 
531  bits = 16 - bits;
532  if ( bits == 0 )
533  return; /* no work! */
534 
535  for ( i = nchan * length, e = map[0]; i > 0; i--, e++ )
536  *e <<= bits;
537 }
short map[3][256]
Definition: getap.c:115
int i
Definition: rletorla.c:82
int nchan
Definition: fant.c:104
unsigned short rle_map
Definition: rle.h:57

Variable Documentation

char* progname

Definition at line 48 of file rledither.c.

char rcs_ident[] = "$Id: rledither.c,v 3.0.1.1 1992/01/23 16:42:22 spencer Exp $"
static

Definition at line 36 of file rledither.c.