36 static char rcs_ident[] =
"$Id: rledither.c,v 3.0.1.1 1992/01/23 16:42:22 spencer Exp $";
57 int blend, blend_divisor = 256;
58 float edge_factor = 0.0;
59 int top, middle, bottom, edgetop, edgebottom;
60 rle_hdr in_hdr, out_hdr;
61 rle_pixel **cleanrows[3], **edgerows[2], **outrow;
63 char *infname = NULL, *outfname = NULL, *mapfname = NULL;
64 FILE *outfile = stdout;
65 int nchan = 3, length = 256, tflag = 0;
68 char cmap_comment[80];
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
,
80 &oflag
, &outfname
, &infname
) == 0 )
108 for (i = 1; i < in_hdr
.ncolors; i++)
113 sprintf( cmap_comment,
"color_map_length=%d", length );
121 for (i = 0; i < 3; i++)
134 if ( (shortrows[0] = (
short *)malloc(in_hdr
.ncolors
136 *
sizeof(
short) )) == 0 )
138 if ( (shortrows[1] = (
short *)malloc(in_hdr
.ncolors
140 *
sizeof(
short) )) == 0 )
143 if (edge_factor < 0.0)
146 blend = (
int) (edge_factor * (
float) blend_divisor);
157 cleanrows[top]
, shortrows[edgetop]
);
159 for (y = in_hdr
.ymin+2; y <= in_hdr
.ymax; y++)
163 cleanrows[bottom]
, cleanrows[middle]
, cleanrows[top]
,
164 edgerows[edgebottom]
,
165 blend
, blend_divisor
);
167 edgerows[edgebottom]
, shortrows[edgebottom]
);
169 shortrows[edgebottom]
, shortrows[edgetop]
, outrow
);
172 temp = top; top = middle; middle = bottom; bottom = temp;
173 temp = edgetop; edgetop = edgebottom; edgebottom = temp;
176 shortrows[edgebottom]
, shortrows[edgetop]
, outrow
);
180 cleanrows[middle]
, shortrows[edgetop]
);
187 for (i = 0; i < 3; i++)
192 free( shortrows[0] );
193 free( shortrows[1] );
213 for (i=0; i <= in_hdr
->xmax; i++)
215 for (chan = 0; chan < in_hdr
->ncolors; chan++)
217 *shortrow++ = rlerow[chan][i];
225 rle_pixel **row_b, **row_m, **row_t, **edge_row;
226 int blend_divisor, blend;
229 int total, diff, avg, result;
230 for (chan = 0; chan < in_hdr
->ncolors; chan++)
233 total = row_b[chan][0] + row_b[chan][1] +
235 row_t[chan][0] + row_t[chan][1];
237 diff = avg - row_m[chan][0];
238 result = row_m[chan][0] - (diff * blend / blend_divisor);
240 edge_row[chan][0] = 0;
241 else if (result > 255)
242 edge_row[chan][0] = 255;
244 edge_row[chan][0] = result;
247 for (i=1; i < in_hdr
->xmax; i++)
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];
253 diff = avg - row_m[chan][i];
254 result = row_m[chan][i] - (diff * blend / blend_divisor);
256 edge_row[chan][i] = 0;
257 else if (result > 255)
258 edge_row[chan][i] = 255;
260 edge_row[chan][i] = result;
264 total = row_b[chan][i-1] + row_b[chan][i] +
266 row_t[chan][i-1] + row_t[chan][i];
268 diff = avg - row_m[chan][i];
269 result = row_m[chan][i] - (diff * blend / blend_divisor);
271 edge_row[chan][i] = 0;
272 else if (result > 255)
273 edge_row[chan][i] = 255;
275 edge_row[chan][i] = result;
284 short *row_bottom, *row_top;
289 register short *thisptr, *nextptr = NULL;
291 static int numchan = 0;
292 int lastline = 0, lastpixel ;
305 if ((cval = (
int *) malloc( numchan *
sizeof(
int) )) == 0)
314 nextptr = row_bottom;
318 for(j=0; j <= in_hdr
->xmax ; j++)
322 lastpixel = (j == in_hdr
->xmax) ;
324 for (chan = 0; chan < numchan; chan++)
326 cval[chan] = *thisptr++ ;
331 if( cval[chan] < 0 ) cval[chan] = 0 ;
332 else if( cval[chan] > 255 ) cval[chan] = 255 ;
334 pixel[chan] = cval[chan];
339 *optr++ = cmap_index;
346 for (chan = 0; chan < numchan; chan++)
348 cval[chan] -= map[chan][cmap_index];
352 thisptr[chan] += cval[chan] * 7 / 16 ;
358 nextptr[-numchan] += cval[chan] * 3 / 16 ;
360 nextptr[0] += cval[chan] * 5 / 16 ;
363 nextptr[numchan] += cval[chan] / 16 ;
400 if ( ( mapfile = fopen( mapfname,
"r" ) ) == NULL )
402 fprintf( stderr,
"%s: Couldn't open map file %s: ",
409 for ( c = 0; c < nchan; c++ )
410 for ( i = 0; i < length; i++ )
411 switch ( fscanf( mapfile,
"%d", &ent ) )
415 "%s: Premature end of file reading map %s at channel %d, entry %d\n",
424 "%s: Bad data in map %s at channel %d, entry %d\n",
430 "%s: Error reading map %s at channel %d, entry %d\n",
436 for ( i = 0; i < length; i++ )
437 for ( c = 0; c < nchan; c++ )
438 switch ( fscanf( mapfile,
"%d", &ent ) )
442 "%s: Premature end of file reading map %s at entry %d, channel %d\n",
451 "%s: Bad data in map %s at entry %d, channel %d\n",
457 "%s: Error reading map %s at entry %d, channel %d: ",
501 for ( i = 1; i < nchan; i++ )
502 map[i] = &map[i-1][length];
535 for ( i = nchan * length, e = map[0]; i > 0; i--, e++ )
547 for ( i = nchan * length, ie = inmap[0], oe = outmap[0];
548 i > 0; i--, ie++, oe++ )
559 int i, closest, chan;
563 bestdist = 256*256*nchan + 1;
564 for (i=0; i < maplen; i++)
567 for (chan = 0; chan < nchan; chan++)
569 int tmp = map[chan][i] - pixel[chan];
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
void rle_row_free(rle_hdr *the_hdr, rle_pixel **scanp)
char * cmd_name(char **argv)
void main(int argc, char **argv)
int rle_get_setup(rle_hdr *the_hdr)
void copy_into_shortrow(rle_hdr *in_hdr, rle_pixel **rlerow, short *shortrow)
int rle_row_alloc(rle_hdr *the_hdr, rle_pixel ***scanp)
int rle_getrow(rle_hdr *the_hdr, scanline)
int rle_get_error(int code, const char *pgmname, const char *fname)
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)
int scanargs(int argc, char **argv, const char *format,...)
void rle_puteof(rle_hdr *the_hdr)
void find_closest(rle_map **map, int nchan, int maplen, rle_pixel *pixel, strchr)
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
void shiftmap(rle_map **map, int nchan, int length, int bits)
#define RLE_CLR_BIT(glob, bit)
void rle_put_setup(rle_hdr *the_hdr)
const char * rle_putcom(char *value, rle_hdr *the_hdr) const
void filemap(int tflag, char *mapfname, int nchan, int length, rle_map **amap)
rle_map ** allocmap(int nchan, int length, rle_map *cmap)
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
void fsdither(rle_hdr *in_hdr, rle_map **map, int maplen, short *row_bottom, short *row_top, rle_pixel **outrow)
#define RLE_CHECK_ALLOC(pgm, ptr, name)
void copymap(rle_map **inmap, int nchan, int length, rle_map **outmap)