From 846de8d8d55fb0b5b20e9743d20f77c21b029f1f Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Thu, 25 Aug 2011 08:55:47 +0000 Subject: Tek ILDA --- tekilda.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 tekilda.c (limited to 'tekilda.c') diff --git a/tekilda.c b/tekilda.c new file mode 100644 index 0000000..2c6a984 --- /dev/null +++ b/tekilda.c @@ -0,0 +1,305 @@ +/* $Id$ */ +/* + * Copyright (c) 2010 Dimitri Sokolyuk + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include /* endian conversion */ +#include /* endian conversion */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "tekplot.h" + +struct tri { /* Format 0 (3D Coordinates) */ + int16_t x; + int16_t y; + int16_t z; + uint8_t color; /* Color Index */ + uint8_t state; /* State Byte */ +} tri; + +struct two { /* Format 1 (2D Coordinates) */ + int16_t x; + int16_t y; + uint8_t color; /* Color Index */ + uint8_t state; /* State Byte */ +} two; + +struct color { /* Format 2 (Color Index Palette) */ + uint8_t r; + uint8_t g; + uint8_t b; +} color; + +struct head { + int8_t magic[4]; /* Signature */ + int8_t zero[3]; /* Not used, must be zero */ + uint8_t format; /* Format Type */ + int8_t name[8]; /* Name */ + int8_t company[8]; /* Company Name */ + uint16_t npoints; /* Number of Entries in Data Section */ + uint16_t fnumner; /* Current Frame Number */ + uint16_t nframes; /* Total Number of Frames */ + uint8_t shead; /* Scanner Head */ + uint8_t future; /* Not used, must be zero */ +} head; + +struct coord { + int x; + int y; + int z; + int on; + int color; + struct coord *next; +}; + +struct ilda { + int format; + struct coord *coord; + struct ilda *next; +}; + +#ifndef __dead +#define __dead __attribute__((noreturn)) +#endif + +int dflag = 0; + +struct ilda *grab(FILE *); +void drop(struct ilda *); +void settimer(int); +void usage(void); + +struct ilda * +grab(FILE *fd) +{ + struct ilda *ilda, **pilda, *il; + struct coord *coord, **pcoord, *c; + int i, n; + int maxx, maxy, maxz, minx, miny, minz, tmp; + + ilda = NULL; + pilda = &ilda; + + maxx = maxy = maxz = 0; + minx = miny = minz = 1<<12; + +#define C(c) ((((htons(c)) + (1<<15)) % (1<<16)) >> 4) + +/* find min and max */ +#define R(p, c) \ + do { \ + if ((*p)->c > max##c) \ + max##c = (*p)->c; \ + if ((*p)->c < min##c) \ + min##c = (*p)->c; \ + } while (0) + + printf("Read Vectors\n"); + + while (fread(&head, sizeof(head), 1, fd) > 0) { + if (memcmp(head.magic, "ILDA", sizeof(head.magic))) + errx(-1, "miss magic"); + + *pilda = calloc(1, sizeof(*ilda)); + assert(*pilda); + (*pilda)->format = head.format; + + (*pilda)->coord = NULL; + pcoord = &(*pilda)->coord; + + n = ntohs(head.npoints); + + switch (head.format) { + case 0: + for (i = 0; i < n; i++) { + fread(&tri, sizeof(tri), 1, fd); + *pcoord = calloc(1, sizeof(*coord)); + assert(*pcoord); + (*pcoord)->x = C(tri.x); + R(pcoord, x); + (*pcoord)->y = C(tri.y); + R(pcoord, y); + (*pcoord)->z = C(tri.z); + R(pcoord, z); + (*pcoord)->on = tri.state; + (*pcoord)->color = tri.color; + pcoord = &(*pcoord)->next; + } + break; + case 1: + for (i = 0; i < n; i++) { + fread(&two, sizeof(two), 1, fd); + *pcoord = calloc(1, sizeof(*coord)); + assert(*pcoord); + (*pcoord)->x = C(tri.x); + R(pcoord, x); + (*pcoord)->y = C(tri.y); + R(pcoord, y); + (*pcoord)->on = tri.state; + pcoord = &(*pcoord)->next; + } + break; + case 2: + for (i = 0; i < head.npoints; i++) { + fread(&color, sizeof(color), 1, fd); + /* do nothing, just read ahead */ + } + break; + } + + pilda = &(*pilda)->next; + } + +#undef C +#undef R + +/* normalize */ +#define N(p, c, r, m) \ + do { \ + r = max##c - min##c; \ + if (r) \ + p->c = (p->c - min##c) * (m - 1) / r; \ + } while (0) + + printf("Normalize Points\n"); + + for (il = ilda; il; il = il->next) { + for (c = il->coord; c; c = c->next) { + N(c, x, tmp, 4096); + N(c, y, tmp, 3120); + N(c, z, tmp, 1024); + } + } +#undef N + printf("Ready to Play\n"); + + return ilda; +} + +void +drop(struct ilda *ilda) +{ + struct ilda *nilda; + struct coord *coord, *ncoord; + + for (; ilda; ilda = nilda) { + nilda = ilda->next; + for (coord = ilda->coord; coord; coord = ncoord) { + ncoord = coord->next; + free(coord); + } + free(ilda); + } +} + +void +catch(int signo) +{ + if (signo != SIGALRM) + dflag = 1; + return; +} + +int +main(int argc, char **argv) +{ + struct sigaction sa; + struct ilda *ilda, *i; + struct coord *c; + int on, ch; + int delay = 40000; /* 25 fps */ + FILE *input; + + while ((ch = getopt(argc, argv, "d:h")) != -1) + switch (ch) { + case 'd': + delay = 1000 * atoi(optarg); + break; + case 'h': + default: + usage(); + /* NOTREACHED */ + } + + argc -= optind; + argv += optind; + + if (!argc) + usage(); + + input = fopen(*argv, "r"); + if(!input) + err(-1, "%s", *argv); + + ilda = grab(input); + assert(ilda); + + fclose(input); + + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = catch; + sigaction(SIGALRM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGHUP, &sa, NULL); + + settimer(delay); + + inittek(); + for (i = ilda; !dflag && i; i = i->next) { + page(); + on = 0; /* first vector is always blank */ + for (c = i->coord; c; c = c->next) { + iplot(on, c->x, c->y); + on = !c->color; + } + fflush(stdout); + sigsuspend(&sa.sa_mask); + } + endtek(); + + drop(ilda); + + return 0; +} + +void +settimer(int usec) +{ + struct itimerval itv; + + itv.it_value.tv_sec = 0; + itv.it_value.tv_usec = usec; + itv.it_interval = itv.it_value; + + setitimer(ITIMER_REAL, &itv, NULL); +} + +__dead void +usage(void) +{ + extern char *__progname; + + (void)fprintf(stderr, "usage: %s [-d msec] [ILDA]\n", __progname); + + exit(1); +} -- cgit v1.2.3