From: ian Date: Fri, 22 Oct 2004 19:04:46 +0000 (+0000) Subject: compiles and does little X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=89b45a700aaf4387e035f21a0500b1d3846703f4;p=trains.git compiles and does little --- diff --git a/layout/subseg2display.c b/layout/subseg2display.c index ebd9e7e..ae9a139 100644 --- a/layout/subseg2display.c +++ b/layout/subseg2display.c @@ -3,24 +3,204 @@ * subseg2display encoding.ppm [status-info ...] * * status-info args are: - * + * + * .. + * + * + * `..' group is for unspecified segments. * * is * for fixed track * . for part of a moveable feature - * where numbers are in strtoul format, movfeatpos is the + * where numbers are in strtoul base=0 format, movfeatpos is the * moveable feature and position as in segcmapassign and - * if is `.', spec is for unspecified segments. * * Resulting pixel is * [ red ] * (alpha * DIRECTION_COLOUR) + ((1-alpha) * [ green ] ) * [ blue ] - * - * status.bin has the following format: - * 16 bits number of segments - * 2 */ -int main(int argc, const char *const *argv) { +#include +#include +#include +#include +#include +#include + +#include +#include + +/*---------- lookup data structure ----------*/ + +struct idinfo { + double alpha, red, green, blue; +}; + +typedef unsigned char id; + +struct movperseg { + id *lookup; + int lookup_a; +}; + +#define NCHARS 256 +#define MAXSEGNUM ((1<<10)-1) +#define MAXMOVFEATPOS ((1<<6)-1) + +static struct idinfo idinfo[NCHARS]; + +static id *fixed; +static int fixed_a; + +static struct movperseg *moveable; +static int moveable_a; + +/*---------- arg parsing helper routines ----------*/ + +static char **argv; + +static void badusage(void) { + fprintf(stderr,"bad usage\n"); + exit(12); +} + +static const char *nextarg(void) { + if (!*argv) badusage(); + return *argv++; +} + +static double doublearg(void) { + const char *arg= nextarg(); + char *ep; + double v; + + errno= 0; + v= strtod(arg,&ep); + if (*ep) badusage(); + if (errno) badusage(); + if (!finite(v)) badusage(); + + return v; +} + +/*---------- specification args ----------*/ + +static void idgroupargs(id ix) { + struct idinfo *r; + + r= &idinfo[ix]; + + r->alpha = doublearg(); + r->red = doublearg(); + r->green = doublearg(); + r->blue = doublearg(); +} + +static void ensure_somethings(void **ary, int *allocd, int want, size_t item, + void zero(void *data, int count)) { + int new_allocd; + + if (*allocd > want) return; + new_allocd= (*allocd+1)*2; + *ary= xrealloc(*ary, new_allocd * item); + zero((char*)*ary + item * *allocd, new_allocd - *allocd); + *allocd= new_allocd; +} + +static void zero_ids(void *data, int count) { + memset(data,0, count*sizeof(id)); +} + +static void zero_mps(void *data_v, int count) { + struct movperseg *data= data_v; + for (count /= sizeof(*data); + count > 0; + count--, data++) { + data->lookup= 0; + data->lookup_a= 0; + } +} + +#define ENSURE_THINGS(sfx,type) \ + static void ensure_##sfx(type **ary_io, int *allocd, int want) { \ + void *ary= *ary_io; \ + ensure_somethings(ary,allocd,want,sizeof(**ary_io),zero_##sfx); \ + *ary_io= ary; \ + } \ + struct eat_semicolon + +ENSURE_THINGS(ids,id); +ENSURE_THINGS(mps,struct movperseg); + +static void subsegarg(id ix, const char *arg) { + struct idinfo *r; + struct movperseg *mps; + unsigned long segnum, movfeatpos; + char *ep; + + r= &idinfo[ix]; + + errno= 0; + segnum= strtoul(arg,&ep,0); + if (errno) badusage(); + if (segnum > MAXSEGNUM) badusage(); + + if (!*ep) { + ensure_ids(&fixed,&fixed_a,segnum); + fixed[segnum]= ix; + return; + } + + if (*ep != '.') badusage(); + + errno= 0; + movfeatpos= strtoul(ep+1,&ep,0); + if (*ep || errno) badusage(); + if (movfeatpos > MAXMOVFEATPOS) badusage(); + + ensure_mps(&moveable,&moveable_a,segnum); + mps= &moveable[ix]; + ensure_ids(&mps->lookup,&mps->lookup_a, movfeatpos ^ MAXMOVFEATPOS); + mps->lookup[movfeatpos ^ MAXMOVFEATPOS]= ix; +} + +/*---------- actual image processing ----------*/ + +static int cols, rows, informat; +static pixval maxval; +static FILE *encodingfile; + +static void badformat(const char *m) { + fprintf(stderr,"bad format: %s\n", m); + exit(12); +} + +static void process(void) { + ppm_readppminit(encodingfile, &cols, &rows, &maxval, &informat); + if (maxval != 255) badformat("bad maxval"); + if (informat != RPPM_FORMAT) badformat("bad format"); + ppm_writeppminit(stdout, cols, rows, 255, 0); +} + +int main(int argc_spec, char **argv_spec) { + const char *arg, *encodingfilename; + + ppm_init(&argc_spec,argv_spec); + + argv= argv_spec; + nextarg(); + encodingfilename= nextarg(); + while (*argv) { + arg= nextarg(); + if (!*arg) badusage(); + if (!arg[1]) idgroupargs(arg[0]); + else if (!strcmp(arg,"..")) idgroupargs(0); + else subsegarg(arg[0],arg+1); + } + + encodingfile= fopen(encodingfilename, "rb"); + if (!encodingfile) { perror(encodingfilename); exit(8); } + process(); + return 0; }