home *** CD-ROM | disk | FTP | other *** search
- /*
- * bifs.c -- make binary pixel file (sbif) from an ifs description.
- *
- * 24 jul 1989 Olle Olsson.
- */
-
- #include <stdlib.h>
- #include <fcntl.h>
- #include <conio.h>
- #include <string.h>
- #include <io.h>
- #include <process.h>
- #include <alloc.h>
- #include <dos.h>
- #include "ifs.h"
- #include "sbif.h"
-
- /* default sizes */
- #define XLINES 512 /* x pixel count */
- #define YLINES 512 /* y pixel count */
-
- /* max number of transforms */
- #define NTRANSF 50
-
- /* max group index */
- #define MAXGROUP (NTRANSF/2)
-
- /* globals */
- int max_x_coord, max_y_coord; /* x and y coordinate limits */
-
- /* local functions */
- int wsbif( FILE *ofile, unsigned char *pmat, unsigned char huge *fpmat,
- char *outfile, int xlines, int xbytes, int ylines );
- void far wpixel( int x, int y, int color );
- void far wpixelq( int x, int y, int color );
- unsigned far rpixel( int x, int y );
- void far fwpixel( int x, int y, int color );
- void far fwpixelq( int x, int y, int color );
- unsigned far frpixel( int x, int y );
- int nostop( void );
-
- static void usage( void )
- {
- fprintf( stderr, "Usage:\n" );
- fprintf( stderr, "\tbifs [options] ifs_data_file\n" );
- fprintf( stderr, "Options are:\n" );
- fprintf( stderr, "\t-o str\toutput file name (default standard output)\n" );
- fprintf( stderr, "\t-x num\tx size (default %d)\n", XLINES );
- fprintf( stderr, "\t-y num\ty size (default %d)\n", YLINES );
- fprintf( stderr, "\t-s num\t\x and y size (shorthand for square output)\n" );
- fprintf( stderr, "\t-r num\trelative density (multiplier for the file value)\n" );
- fprintf( stderr, "\t-i\t\don't reduce the density if im mode (1/im_levels)\n" );
- fprintf( stderr, "\t-q\tquiet mode, don't stop at keyboard input\n" );
- fprintf( stderr, "\n" );
- }
-
- /* the transformations */
- static transform trf[NTRANSF]; /* (could have been a linked list...) */
-
- /* the colors (palette) */
- static rgb colors[MAXCOLORS + 1];
-
-
- /* the pixel matrix */
- static unsigned char *pmat; /* base address */
- static unsigned char huge *fpmat; /* far base address */
- static int xbytes; /* x matrix length */
- static long wpcount, wppcount; /* pixel count */
-
-
- void main( argc, argv )
- int argc;
- char *argv[];
- {
- FILE *inf; /* data file */
- FILE *outf; /* output file */
- ifsdes dd; /* ifs descriptor */
- int quiet; /* flag */
- int xlines, ylines; /* x and y pixel count */
- int imreduce; /* im mode means density reduction flag */
- double densfact; /* factor for relative density */
- int trace; /* trace flag */
- int i, c; /* tmp */
- char datafile[100]; /* data file name */
- char outfile[100]; /* output file name */
- char *ap, **p; /* argument pointers */
-
- /* initialize */
- dd.tp = trf;
- dd.maxsize = NTRANSF;
- dd.colors = colors;
- dd.clrsize = sizeof (colors) / sizeof (colors[0]);
- dd.textcolor = dd.clrsize - 1;
- dd.prrdens = 0;
- dd.maxgroup = MAXGROUP;
-
- xlines = XLINES;
- ylines = YLINES;
-
- /* read arguments */
- datafile[0] = outfile[0] = '\0';
- trace = 0;
- imreduce = 1;
- densfact = 1;
- quiet = 0;
- for (p = argv + 1, c = 1; c < argc; ++c)
- {
- if (trace) printf( "%s:\n", *p );
- ap = *p++;
-
- if (*ap == '-') for (i = 1; ap[i]; ++i) switch (ap[i])
- {
- case 'o':
- if (++c >= argc)
- error( "-o: output file name missing");
-
- if (outfile[0])
- error( "-o: too many output files" );
-
- strcpy( outfile, *p++ );
- continue;
-
- case 'r':
- if (++c >= argc)
- error( "-r: value missing");
-
- densfact = atof( *p++ );
-
- if (densfact <= 0)
- error( "-r: factor <= 0" );
-
- continue;
-
- case 's':
- if (++c >= argc)
- error( "-s: size missing");
-
- xlines = ylines = atoi( *p++ );
-
- if (xlines <= 0)
- error( "-s: size <= 0" );
-
- continue;
-
- case 'x':
- if (++c >= argc)
- error( "-x: size missing");
-
- xlines = atoi( *p++ );
-
- if (xlines <= 0)
- error( "-x: size <= 0" );
-
- continue;
-
- case 'y':
- if (++c >= argc)
- error( "-y: size missing");
-
- ylines = atoi( *p++ );
-
- if (ylines <= 0)
- error( "-y: size <= 0" );
-
- continue;
-
- case 'i':
- imreduce = 0;
- continue;
-
- case 't':
- trace++;
- continue;
-
- case 'q':
- quiet++;
- continue;
-
- default:
- usage();
- error( "don't understand flag '-%c'", ap[i] );
- }
- else if (!datafile[0])
- {
- strcpy( datafile, ap );
- }
- else
- {
- usage();
- error( "too many data files specified" );
- }
- }
-
- /* open the data file */
- if (!datafile[0])
- error( "No IFS data file specified" );
-
- if ((inf = fopen( datafile, "r" )) == NULL)
- error( "Can't open input file '%s'", datafile );
-
- /* write to stdout or a named file? */
- if (!outfile[0])
- {
- /* stdout, make it binary mode */
- outf = stdout;
- setmode( fileno( outf ), O_BINARY );
- }
- else if ((outf = fopen( outfile, "wb" )) == NULL)
- error( "Can't create output file '%s'", outfile );
-
- /* read the description */
- rdescr( inf, &dd, trace );
- fclose( inf );
-
- if (trace) printf( "(imeasm:%d)\n", dd.im );
-
- /* get a pixel matrix */
- xbytes = XBYTES( xlines );
- /* (there isn't much speed difference between near and far) */
- if (pmat = (unsigned char *) calloc( xbytes, ylines ))
- {
- /* use near mem. */
- fpmat = 0;
- }
- else if (!(fpmat = (unsigned char huge*) farcalloc( xbytes, ylines )))
- error( "out of memory for the pixel matrix" );
-
- /* set the size */
- MAX_COL = xlines - 1;
- MAX_ROW = ylines - 1;
-
- if (!quiet) fprintf( stderr, "\n" );
-
- /* apply density factor */
- dd.density *= densfact;
-
- /* im mode reduce? */
- if ((dd.im > 1) && imreduce)
- {
- dd.density /= dd.im;
- if (!quiet)
- fprintf( stderr, "(Density multiplied by 1/%d for im mode.)\n",
- dd.im );
- }
-
- /* Since this is only black and white, im mode doesn't show anything
- * but takes extra time (to read and increase the color).
- dd.im = 0;
-
- /* set up for printout during ifsshow() */
- wppcount = DENS2ITER( dd.density );
- if (!quiet) fprintf( stderr, "Density is %g giving %.1e iterations.\n",
- dd.density, (double) wppcount );
-
- if (!quiet) fprintf( stderr, "\n (hit any key to stop and write the output file)\n\n" );
-
- /* wpixel will print one star per 2% */
- wppcount /= 50;
- if (!quiet) fprintf( stderr,
- " 20% 40% 60% 80% 100%\n" );
- if (!quiet) fprintf( stderr,
- " . | . | . | . | . |\n" );
-
- /* show the fractal */
- if (quiet)
- {
- if (pmat)
- ifsshow( &dd, nostop, 0, wpixelq, rpixel );
- else
- ifsshow( &dd, nostop, 0, fwpixelq, frpixel );
- }
- else
- {
- if (pmat)
- ifsshow( &dd, kbhit, 0, wpixel, rpixel );
- else
- ifsshow( &dd, kbhit, 0, fwpixel, frpixel );
- }
-
- /* stopped before full density? */
- if (!quiet) if (kbhit()) getch();
-
- /* show that the generation of the image has stopped */
- if (!quiet) fprintf( stderr, "\n" );
-
- /* write the binary image */
- if (!wsbif( outf, pmat, fpmat, outfile, xlines, xbytes, ylines ))
- error( "could not write to file '%s'", outfile );
- }
-
-
- /* offset and mask, near and far versions */
- #define maddr( xl, x, y ) ((xl) * (y) + ((x)>>3) )
- #define lmaddr( xl, x, y ) (((long) xl) * (y) + ((x)>>3) )
- #define bitmask( x ) (0x80 >> ((x)&7))
-
- void far wpixel( int x, int y, int color )
- {
- register unsigned int offs = maddr( xbytes, x, y );
- register int mask = bitmask( x );
-
- /* write the pixel */
- if (color)
- pmat[offs] |= mask;
- else
- pmat[offs] &= ~mask;
-
- /* statistics */
- if (++wpcount >= wppcount)
- {
- wpcount = 0;
- fprintf( stderr, "*" );
- }
- }
-
- void far wpixelq( int x, int y, int color )
- {
- register unsigned int offs = maddr( xbytes, x, y );
- register int mask = bitmask( x );
-
- /* quiet version */
-
- /* write the pixel */
- if (color)
- pmat[offs] |= mask;
- else
- pmat[offs] &= ~mask;
-
- /* statistics */
- ++wpcount;
- }
-
- unsigned far rpixel( int x, int y )
- {
- register unsigned int offs = maddr( xbytes, x, y );
- register int mask = bitmask( x );
-
- /* read the pixel */
- return ((pmat[offs] & mask) != 0);
- }
-
- void far fwpixel( int x, int y, int color )
- {
- register unsigned long offs = lmaddr( xbytes, x, y );
- register int mask = bitmask( x );
-
- /* far matrix version */
-
- /* write the pixel */
- if (color)
- fpmat[offs] |= mask;
- else
- fpmat[offs] &= ~mask;
-
- /* statistics */
- if (++wpcount >= wppcount)
- {
- wpcount = 0;
- fprintf( stderr, "*" );
- }
- }
-
- void far fwpixelq( int x, int y, int color )
- {
- register unsigned long offs = lmaddr( xbytes, x, y );
- register int mask = bitmask( x );
-
- /* quiet far matrix version */
-
- /* write the pixel */
- if (color)
- fpmat[offs] |= mask;
- else
- fpmat[offs] &= ~mask;
-
- /* statistics */
- ++wpcount;
- }
-
- unsigned far frpixel( int x, int y )
- {
- register unsigned long offs = lmaddr( xbytes, x, y );
- register int mask = bitmask( x );
-
- /* far matrix version */
- /* read the pixel */
- return ((fpmat[offs] & mask) != 0);
- }
-
- int nostop( void )
- {
- /* status function that always says that it isn't time to stop yet */
- return (0);
- }
-
- int wsbif( of, pmat, fpmat, outfile, xlines, xbytes, ylines )
- FILE *of; /* output file */
- unsigned char *pmat; /* the pixel matrix */
- unsigned char huge *fpmat; /* the far pixel matrix */
- char *outfile; /* name of the output file (may be empty) */
- int xlines; /* x pixel count */
- int xbytes; /* x byte count */
- int ylines; /* y pixel count */
- {
- char hbuf[SBHSIZE]; /* header */
-
- /* write a file according to sbif.h */
-
- /* make the header */
- memset( hbuf, '\0', sizeof (hbuf) );
- sprintf( hbuf, "%s %d %d\n", outfile[0] ? outfile : "no_file", xlines, ylines );
-
- /* write the header */
- if (fwrite( (void *) hbuf, sizeof (hbuf), 1, of ) < 1)
- return (0);
-
- /* write the data */
- if (fpmat)
- {
- long tot = xbytes * (long) ylines;
- unsigned int bufsz;
-
- /* the far matrix was used, copy it in chunks to near mem. and write */
-
- /* get a (near) buffer */
- bufsz = coreleft();
- bufsz -= bufsz % 1024;
- if (!(pmat = (unsigned char *) calloc( bufsz, 1 )))
- error(
- "out of memory for writing the pixel matrix (coreleft() is lying)" );
-
- for (; tot > 0; tot -= bufsz, fpmat += bufsz)
- {
- /* a full buffer left? */
- if (tot < bufsz)
- bufsz = tot;
-
- /* get the far data nearer */
- movedata( FP_SEG(fpmat), FP_OFF(fpmat),
- _DS, (int)pmat, bufsz );
-
- if (fwrite( (void *) pmat, bufsz, 1, of ) < 1)
- return (0);
- }
- }
- else
- {
- /* near matrix, write it */
- if (fwrite( (void *) pmat, xbytes, ylines, of ) < ylines)
- return (0);
- }
-
- /* ok */
- return (1);
- }
-
- void error( s, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 )
- char *s;
- int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10;
- {
- fprintf( stderr, "\nError:" );
- fprintf( stderr, s, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 );
- fprintf( stderr, "\n" );
-
- exit( 2 );
- }
-
- void warning( s, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 )
- char *s;
- int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10;
- {
- fprintf( stderr, "\nWarning:" );
- fprintf( stderr, s, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 );
- fprintf( stderr, "\n" );
- }
-
-
-