home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
graphics
/
utility
/
mdl10
/
mdl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-25
|
12KB
|
566 lines
/*
* 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);
}