home *** CD-ROM | disk | FTP | other *** search
- /*
- * mdl -- display a DL animation (monochrome ST only)
- *
- * uses Setscreen flicker trick
- *
- *
- *
- * derived from xdl by:
- * Jonas Yngvesson <jonas-y@isy.liu.se>
- *
- * which was derived from dltogl.c by:
- * George Phillips <phillips@cs.ubc.ca>
- *
- * Support for user defined animation speed:
- * Per Beremark <per.beremark@telelogic.se>
- */
-
- #include <stdio.h>
- #include <stdlib.h> /* for malloc */
- #include <unistd.h> /* for getopt */
- #include <sys/types.h>
- #include <sys/time.h>
-
-
- #define isneg16(x) ((x) & 0x8000)
- #define neg16(x) ((~(x) + 1) & 0x7fff)
-
-
- typedef struct {
- int version;
- int format;
- int images_per_screen;
- char title[21];
- char author[21];
- int num_screen;
- int num_command;
- } DL_info;
-
-
- int __default_mode__ = _IOBIN; /* force stdin binary (gcc) */
-
- unsigned long pixels[256]; /* for colormap conversion */
- char *myname = "mdl";
-
- void usage (int);
- void colormap_setup (FILE *, int);
- extern int dl_flicker (unsigned char *, int, int, int, int, int, int, int, int *, int, int);
-
- /* pimg -> raster image sequence (intensities) */
- /* nframes number of frames in pimg */
- /* width width, pixels */
- /* hight height, pixels */
- /* beta for laplace filter */
- /* maxrandom for random noise */
- /* opt 0=no flicker, 1=flicker */
- /* delay ms delay between images */
- /* cmd -> commands (order to display frames) */
- /* numcmd number of commands */
- /* show print info to stdout if != 0 */
-
-
- extern char *optarg; /* getopt stuff */
- extern int optind;
-
-
-
- /*------------------------------*/
- /* main */
- /*------------------------------*/
- void main (int argc, char *argv[])
- {
- DL_info dlinfo; /* dl file info */
- char *filename;
- FILE *fp;
- unsigned char *image_data; /* space for 1 screen from file */
- unsigned char *img; /* space for all frames */
- unsigned char *pimg; /* ptr to img */
- long pimg_inc; /* increment to next frame in img */
- int nframes; /* num of individual frames */
- int ncommands; /* num of frames (= num frames in loop)*/
- short gray;
- int width,
- height;
- int *cmd; /* space for command list */
- int labelpos;
- int frame_freq; /* milliseconds per frame */
- int fps = 25; /* frames per second */
- int zoomflag = 0;
- int ival = 0;
- int errflg = 0;
- int do_flick = 1;
- int beta = 0;
- int noise = 0;
- int verbose = 0;
- int i, j;
-
-
-
- /*
- * parse command line...
- */
- while ((i = getopt(argc, argv, "vszhr:i:b:n:")) != -1)
- {
- switch (i)
- {
- case 'v': /* verbose */
- verbose++;
- break;
-
- case 's': /* single (no flicker)*/
- do_flick = 0;
- break;
-
- case 'b': /* beta */
- beta = atoi(optarg);
- if (beta < 0) beta = 0;
- break;
-
- case 'n': /* noise */
- noise = atoi(optarg);
- if (noise < 0) noise = 0;
- if (noise > 255) noise = 255;
- break;
-
- case 'i': /* intensity adjust */
- ival = atoi(optarg);
- if (ival < -254) ival = -254;
- if (ival > 254) ival = 254;
- break;
-
- case 'z': /* zoom */
- zoomflag = 1;
- break;
-
- case 'h': /* help */
- usage (0);
- break; /*NOTREACHED*/
-
- case 'r': /* rate (fps) */
- fps = atoi(optarg);
- if (fps < 1) fps = 1;
- if (fps > 100) fps = 100;
- break;
-
- case '?':
- default:
- errflg++;
- }
- }
- if (errflg)
- {
- usage(2);
- }
-
-
-
- /*
- * if no files, use stdin. otherwise open file
- */
- if (argv[optind] == NULL)
- {
- fp = stdin;
- filename = "stdin";
- }
- else if ((fp = fopen (argv[optind], "rb")) == NULL)
- {
- fprintf(stderr, "%s: can't open %s\n", myname, argv[1]);
- exit(1);
- }
- else
- {
- filename = argv[optind];
- }
-
-
-
- /*
- * Check the version number...
- */
- if ((dlinfo.version = fgetc(fp)) != 1 && dlinfo.version != 2)
- {
- fprintf(stderr, "%s: This file is in an unknown format.\n",
- myname);
- fprintf(stderr, "can only do .DL version 1 and 2 (this is %d).\n",
- dlinfo.version);
- exit(1);
- }
-
-
-
- /*
- * ...and the format.
- */
- if (dlinfo.version == 1)
- dlinfo.format = 1;
- else
- dlinfo.format = fgetc(fp);
-
- switch (dlinfo.format)
- {
- case 0: /* large */
- width = 320;
- height = 200;
- dlinfo.images_per_screen = 1;
- zoomflag = 0;
- break;
-
- case 1: /* medium */
- if (zoomflag)
- {
- width = 320;
- height = 200;
- }
- else
- {
- width = 160;
- height = 100;
- }
- dlinfo.images_per_screen = 4;
- break;
-
- default:
- fprintf(stderr,
- "%s: only large and medium formats are handled",
- myname);
- exit(1);
- break;
- }
-
-
-
- /*
- * Get title and author (if any). i don't know what this is used
- * for...
- */
- dlinfo.title[20] = dlinfo.author[20] = 0;
- for (i = 0; i < 20; i++)
- {
- dlinfo.title[i] = fgetc(fp) ^ 255;
- if ((unsigned char)dlinfo.title[i] == 255)
- dlinfo.title[i] = 0;
- }
- for (i = 0; i < 20; i++)
- {
- if (dlinfo.version == 2)
- {
- dlinfo.author[i] = fgetc(fp) ^ 255;
- if ((unsigned char)dlinfo.author[i] == 255)
- dlinfo.author[i] = 0;
- }
- else
- dlinfo.author[i] = 0;
- }
-
-
-
- /*
- * Read number of screens and commands.
- */
- dlinfo.num_screen = fgetc(fp);
- dlinfo.num_command = fgetc(fp);
-
-
-
- /*
- * Display what we know so far.
- */
- nframes = dlinfo.num_screen * dlinfo.images_per_screen;
- ncommands = dlinfo.num_command;
- if (verbose)
- {
- printf("%s is a %s sized version %d .DL file.\n",
- filename,
- (dlinfo.format == 0 ? "large" : "medium"),
- dlinfo.version);
- printf("It contains %d images (num_screen=%d * images_per_screen=%d)\n",
- dlinfo.num_screen * dlinfo.images_per_screen,
- dlinfo.num_screen,
- dlinfo.images_per_screen);
- printf("in a %d frame (num_command) loop.\n",
- dlinfo.num_command);
- if (dlinfo.format == 1 && zoomflag)
- {
- puts("Zooming images to 320x200.");
- }
- printf("Displaying animation at %d frames per second.\n",fps);
- }
-
-
-
- /*
- * do the color map
- */
- if (verbose)
- printf("Reading colormap...\n");
- colormap_setup(fp, dlinfo.version);
-
-
-
- /*
- * Allocate memory for the commands, the image data, etc
- */
- if (verbose)
- printf ("Allocating memory:\n");
-
- /* command list: */
- if (verbose)
- printf (" command list (%d bytes)\n",
- dlinfo.num_command * sizeof(int));
- if (!(cmd = (int *)malloc(dlinfo.num_command * sizeof(int))))
- {
- fprintf(stderr, "%s: out of memory (commands)", myname);
- exit(1);
- }
-
- /* one screen (file): */
- if (verbose)
- printf (" single screen from file (64000 bytes)\n");
- if (NULL == (image_data = (unsigned char *)malloc(320 * 200)))
- {
- fprintf(stderr, "%s: not enough memory (image data).", myname);
- exit(1);
- }
-
- /* all frames: */
- if(dlinfo.format == 0)
- {
- /* large */
- if (verbose)
- printf (" raster list, large (%ld bytes)\n",
- (long)(320L * 200L * dlinfo.num_screen));
- img = (unsigned char *)malloc(320 * 200 * dlinfo.num_screen);
- pimg_inc = 320 * 200;
- }
- else if (zoomflag)
- {
- /* medium->large */
- if (verbose)
- printf (" raster list, zoom (%ld bytes)\n",
- (long)(320L * 200L * dlinfo.num_screen * dlinfo.images_per_screen));
- img = (unsigned char *)malloc(320 * 200 *
- dlinfo.num_screen * dlinfo.images_per_screen);
- pimg_inc = 320 * 200;
- }
- else
- {
- /* medium */
- if (verbose)
- printf (" raster list, medium (%ld bytes)\n",
- (long)(160L * 100L * dlinfo.num_screen * dlinfo.images_per_screen));
- img = (unsigned char *)malloc(160 * 100 *
- dlinfo.num_screen * dlinfo.images_per_screen);
- pimg_inc = 160 * 100;
- }
- if (img == (unsigned char *) NULL)
- {
- fprintf(stderr, "%s: not enough memory (pimg).", myname);
- exit(1);
- }
- pimg = img;
-
-
-
- /*
- * Build the pixmaps for the animation.
- */
- if (verbose)
- {
- printf("Building pixmaps, wait..."); fflush(stdout);
- }
- for (j = 0; j < dlinfo.num_screen; j++)
- {
- unsigned char *src;
- int row;
- int col;
-
-
- /*
- * Read one screen of data.
- */
- fread(image_data, 1, 320 * 200, fp);
-
-
- /*
- * Each screen can hold several images.
- */
- for (i = 0; i < dlinfo.images_per_screen; i++)
- {
- /*
- * Get a pointer to the beginning of this image.
- * Put the pixels in the img raster. We do zooming
- * by reading the same data several times.
- */
- src = image_data + (i % 2) * 160 + (i / 2) * 100 * 320;
-
- for (row = 0; row < height; row++)
- {
- for (col = 0; col < width; col++)
- {
- /*
- * map raw data to colormap
- * intensity
- */
- gray = pixels[*src] + ival;
- if (gray > 255) gray = 255;
- if (gray < 0) gray = 0;
-
- /*
- * poke in our raster
- */
- pimg[width * row + col] = gray;
-
- src += (zoomflag) ? (col & 1) : 1;
- }
-
- if (dlinfo.format)
- {
- if (zoomflag)
- {
- src += (row & 1) ? 160 : -160;
- }
- else
- {
- src += 160;
- }
- }
- }
-
-
- /*
- * advance image pointer to next frame
- */
- pimg += pimg_inc;
- }
- }
- if (verbose)
- printf("done.\n"); fflush(stdout);
-
-
-
- /*
- * Read the commands.
- */
- if (verbose)
- printf("Number of commands is %d\n", dlinfo.num_command);
- for (i = 0; i < dlinfo.num_command; i++)
- {
- if (dlinfo.version == 2)
- {
- j = fgetc(fp);
- j += fgetc(fp) << 8;
- cmd[i] = j;
- }
- else
- {
- j = fgetc(fp);
- cmd[i] = (j % 10) - 1 + ((j / 10) - 1) * 4;
- }
- if (verbose)
- printf("command %3d: %d\n", i, cmd[i]);
- }
- if (verbose)
- fflush(stdout);
-
-
- /*
- * if last cmd is -ve, it contains the 'labelpos'. what is this?
- */
- labelpos = 0;
- if (isneg16(cmd[dlinfo.num_command - 1]))
- {
- labelpos = (neg16(cmd[dlinfo.num_command - 1])
- + 1); /* Correct? Why add 1 ?? */
- dlinfo.num_command--; /* ignore that last command */
- }
-
-
-
- /*
- * do it. first set delay per frame (milliseconds)
- */
- frame_freq = 1000/fps;
-
- dl_flicker (img, nframes, width, height, beta, noise, do_flick,
- frame_freq, cmd, ncommands, verbose);
-
-
- exit (0);
- }
-
-
-
-
-
- /*------------------------------*/
- /* colormap_setup */
- /*------------------------------*/
- void colormap_setup (FILE *fp, int version)
- {
-
- /*
- * Initialize the colormap. I use a private one for PseudoColor,
- * I was too tired to fiddle with allocating shared colors.
- */
-
- unsigned char pal[768];
- int i;
-
-
- /*
- * Is this the border colour? ignore this anyway...
- */
- if (version == 2)
- {
- for (i = 0; i < 3; i++)
- fgetc(fp);
- }
- else
- fgetc(fp);
-
-
-
- /*
- * Here comes the colormap. 3 bytes per each of 256 colors.
- */
- fread(pal, 1, 768, fp);
-
-
-
- /*
- * Set up for grayscale conversion on a monochrome display (NTSC
- * weights). flicker interprets 0 as black and 255 as white.
- *
- * TODO: consider histogram equalization here...
- */
- for (i = 0; i < 256; i++)
- {
- pixels[i] = (((unsigned long)pal[3*i ] << 2) * 300) / 1000
- + (((unsigned long)pal[3*i + 1] << 2) * 590) / 1000
- + (((unsigned long)pal[3*i + 2] << 2) * 110) / 1000;
- }
- return;
- }
-
-
-
- /*------------------------------*/
- /* usage */
- /*------------------------------*/
- void usage (int excode)
- {
- fprintf(stderr,"usage: %s [options] [file.dl]\n", myname);
- fprintf(stderr,"options:\n");
- fprintf(stderr,"-v verbose\n");
- fprintf(stderr,"-s single image (no flicker)\n");
- fprintf(stderr,"-b beta for laplace filter (0..10)\n");
- fprintf(stderr,"-n noise add random noise (0..255)\n");
- fprintf(stderr,"-z zoom (enlarge to 320x200)\n");
- fprintf(stderr,"-h help\n");
- fprintf(stderr,"-i val add value to pixel intensity (-255..255)\n");
- fprintf(stderr,"-r fps run at fps frames/second (default=25)\n");
-
- exit (excode);
- }
-
-