home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / vifs / bifs.c next >
Encoding:
C/C++ Source or Header  |  1989-09-03  |  10.7 KB  |  478 lines

  1. /*
  2.  *    bifs.c  --  make binary pixel file (sbif) from an ifs description.
  3.  *
  4.  *    24 jul 1989  Olle Olsson.
  5.  */
  6.  
  7. #include <stdlib.h>
  8. #include <fcntl.h>
  9. #include <conio.h>
  10. #include <string.h>
  11. #include <io.h>
  12. #include <process.h>
  13. #include <alloc.h>
  14. #include <dos.h>
  15. #include "ifs.h"
  16. #include "sbif.h"
  17.  
  18. /* default sizes */
  19. #define XLINES 512        /* x pixel count */
  20. #define YLINES 512        /* y pixel count */
  21.  
  22. /* max number of transforms */
  23. #define NTRANSF 50
  24.  
  25. /* max group index */
  26. #define MAXGROUP (NTRANSF/2)
  27.  
  28. /* globals */
  29. int max_x_coord, max_y_coord;    /* x and y coordinate limits */
  30.  
  31. /* local functions */
  32. int wsbif( FILE *ofile, unsigned char *pmat, unsigned char huge *fpmat,
  33.              char *outfile, int xlines, int xbytes, int ylines );
  34. void far wpixel( int x, int y, int color );
  35. void far wpixelq( int x, int y, int color );
  36. unsigned far rpixel( int x, int y );
  37. void far fwpixel( int x, int y, int color );
  38. void far fwpixelq( int x, int y, int color );
  39. unsigned far frpixel( int x, int y );
  40. int nostop( void );
  41.  
  42. static void usage( void )
  43. {
  44. fprintf( stderr, "Usage:\n" );
  45. fprintf( stderr, "\tbifs [options] ifs_data_file\n" );
  46. fprintf( stderr, "Options are:\n" );
  47. fprintf( stderr, "\t-o str\toutput file name (default standard output)\n" );
  48. fprintf( stderr, "\t-x num\tx size (default %d)\n", XLINES );
  49. fprintf( stderr, "\t-y num\ty size (default %d)\n", YLINES );
  50. fprintf( stderr, "\t-s num\t\x and y size (shorthand for square output)\n" );
  51. fprintf( stderr, "\t-r num\trelative density (multiplier for the file value)\n" );
  52. fprintf( stderr, "\t-i\t\don't reduce the density if im mode (1/im_levels)\n" );
  53. fprintf( stderr, "\t-q\tquiet mode, don't stop at keyboard input\n" );
  54. fprintf( stderr, "\n" );
  55. }
  56.  
  57. /* the transformations */
  58. static transform trf[NTRANSF];    /* (could have been a linked list...) */
  59.  
  60. /* the colors (palette) */
  61. static rgb colors[MAXCOLORS + 1];
  62.  
  63.  
  64. /* the pixel matrix */
  65. static unsigned char *pmat;        /* base address */
  66. static unsigned char huge *fpmat;    /* far base address */
  67. static int xbytes;            /* x matrix length */
  68. static long wpcount, wppcount;        /* pixel count */
  69.  
  70.  
  71. void main( argc, argv )
  72. int argc;
  73. char *argv[];
  74. {
  75. FILE *inf;            /* data file */
  76. FILE *outf;            /* output file */
  77. ifsdes dd;            /* ifs descriptor */
  78. int quiet;            /* flag */
  79. int xlines, ylines;        /* x and y pixel count */
  80. int imreduce;            /* im mode means density reduction flag */
  81. double densfact;        /* factor for relative density */
  82. int trace;            /* trace flag */
  83. int i, c;            /* tmp */
  84. char datafile[100];        /* data file name */
  85. char outfile[100];        /* output file name */
  86. char *ap, **p;            /* argument pointers */
  87.  
  88. /* initialize */
  89. dd.tp = trf;
  90. dd.maxsize = NTRANSF;
  91. dd.colors = colors;
  92. dd.clrsize = sizeof (colors) / sizeof (colors[0]);
  93. dd.textcolor = dd.clrsize - 1;
  94. dd.prrdens = 0;
  95. dd.maxgroup = MAXGROUP;
  96.  
  97. xlines = XLINES;
  98. ylines = YLINES;
  99.  
  100. /* read arguments */
  101. datafile[0] = outfile[0] = '\0';
  102. trace = 0;
  103. imreduce = 1;
  104. densfact = 1;
  105. quiet = 0;
  106. for (p = argv + 1, c = 1; c < argc; ++c)
  107.     {
  108.     if (trace) printf( "%s:\n", *p );
  109.     ap = *p++;
  110.  
  111.     if (*ap == '-')    for (i = 1; ap[i]; ++i) switch (ap[i])
  112.         {
  113.         case 'o':
  114.             if (++c >= argc)
  115.                 error( "-o: output file name missing");
  116.  
  117.             if (outfile[0])
  118.                 error( "-o: too many output files" );
  119.  
  120.             strcpy( outfile, *p++ );
  121.             continue;
  122.  
  123.         case 'r':
  124.             if (++c >= argc)
  125.                 error( "-r: value missing");
  126.  
  127.             densfact = atof( *p++ );
  128.  
  129.             if (densfact <= 0)
  130.                 error( "-r: factor <= 0" );
  131.  
  132.             continue;
  133.  
  134.         case 's':
  135.             if (++c >= argc)
  136.                 error( "-s: size missing");
  137.  
  138.             xlines = ylines = atoi( *p++ );
  139.  
  140.             if (xlines <= 0)
  141.                 error( "-s: size <= 0" );
  142.  
  143.             continue;
  144.  
  145.         case 'x':
  146.             if (++c >= argc)
  147.                 error( "-x: size missing");
  148.  
  149.             xlines = atoi( *p++ );
  150.  
  151.             if (xlines <= 0)
  152.                 error( "-x: size <= 0" );
  153.  
  154.             continue;
  155.  
  156.         case 'y':
  157.             if (++c >= argc)
  158.                 error( "-y: size missing");
  159.  
  160.             ylines = atoi( *p++ );
  161.  
  162.             if (ylines <= 0)
  163.                 error( "-y: size <= 0" );
  164.  
  165.             continue;
  166.  
  167.         case 'i':
  168.             imreduce = 0;
  169.             continue;
  170.  
  171.         case 't':
  172.             trace++;
  173.             continue;
  174.  
  175.         case 'q':
  176.             quiet++;
  177.             continue;
  178.  
  179.         default:
  180.             usage();
  181.             error( "don't understand flag '-%c'", ap[i] );
  182.         }
  183.     else if (!datafile[0])
  184.         {
  185.         strcpy( datafile, ap );
  186.         }
  187.     else
  188.         {
  189.         usage();
  190.         error( "too many data files specified" );
  191.         }
  192.     }
  193.  
  194. /* open the data file */
  195. if (!datafile[0])
  196.     error( "No IFS data file specified" );
  197.  
  198. if ((inf = fopen( datafile, "r" )) == NULL)
  199.     error( "Can't open input file '%s'", datafile );
  200.  
  201. /* write to stdout or a named file? */
  202. if (!outfile[0])
  203.     {
  204.     /* stdout, make it binary mode */
  205.     outf = stdout;
  206.     setmode( fileno( outf ), O_BINARY );
  207.     }
  208. else if ((outf = fopen( outfile, "wb" )) == NULL)
  209.     error( "Can't create output file '%s'", outfile );
  210.  
  211. /* read the description */
  212. rdescr( inf, &dd, trace );
  213. fclose( inf );
  214.  
  215. if (trace) printf( "(imeasm:%d)\n", dd.im );
  216.  
  217. /* get a pixel matrix */
  218. xbytes = XBYTES( xlines );
  219. /* (there isn't much speed difference between near and far) */
  220. if (pmat = (unsigned char *) calloc( xbytes, ylines ))
  221.     {
  222.     /* use near mem. */
  223.     fpmat = 0;
  224.     }
  225. else if (!(fpmat = (unsigned char huge*) farcalloc( xbytes, ylines )))
  226.     error( "out of memory for the pixel matrix" );
  227.  
  228. /* set the size */
  229. MAX_COL = xlines - 1;
  230. MAX_ROW = ylines - 1;
  231.  
  232. if (!quiet) fprintf( stderr, "\n" );
  233.  
  234. /* apply density factor */
  235. dd.density *= densfact;
  236.  
  237. /* im mode reduce? */
  238. if ((dd.im > 1) && imreduce)
  239.     {
  240.     dd.density /= dd.im;
  241.     if (!quiet)
  242.             fprintf( stderr, "(Density multiplied by 1/%d for im mode.)\n",
  243.                                  dd.im );
  244.     }
  245.  
  246. /* Since this is only black and white, im mode doesn't show anything
  247.  * but takes extra time (to read and increase the color).
  248. dd.im = 0;
  249.  
  250. /* set up for printout during ifsshow() */
  251. wppcount = DENS2ITER( dd.density );
  252. if (!quiet) fprintf( stderr, "Density is %g giving %.1e iterations.\n",
  253.              dd.density, (double) wppcount );
  254.  
  255. if (!quiet) fprintf( stderr, "\n (hit any key to stop and write the output file)\n\n" );
  256.  
  257. /* wpixel will print one star per 2% */
  258. wppcount /= 50;
  259. if (!quiet) fprintf( stderr,
  260.      "        20%       40%       60%       80%       100%\n" );
  261. if (!quiet) fprintf( stderr,
  262.      "    .    |    .    |    .    |    .    |    .    |\n" );
  263.  
  264. /* show the fractal */
  265. if (quiet)
  266.     {
  267.     if (pmat)
  268.         ifsshow( &dd, nostop, 0, wpixelq, rpixel );
  269.     else
  270.         ifsshow( &dd, nostop, 0, fwpixelq, frpixel );
  271.     }
  272. else
  273.     {
  274.     if (pmat)
  275.         ifsshow( &dd, kbhit, 0, wpixel, rpixel );
  276.     else
  277.         ifsshow( &dd, kbhit, 0, fwpixel, frpixel );
  278.     }
  279.  
  280. /* stopped before full density? */
  281. if (!quiet) if (kbhit()) getch();
  282.  
  283. /* show that the generation of the image has stopped */
  284. if (!quiet) fprintf( stderr, "\n" );
  285.  
  286. /* write the binary image */
  287. if (!wsbif( outf, pmat, fpmat, outfile, xlines, xbytes, ylines ))
  288.     error( "could not write to file '%s'", outfile );
  289. }
  290.  
  291.  
  292. /* offset and mask, near and far versions */
  293. #define maddr( xl, x, y ) ((xl) * (y) + ((x)>>3) )
  294. #define lmaddr( xl, x, y ) (((long) xl) * (y) + ((x)>>3) )
  295. #define bitmask( x )  (0x80 >> ((x)&7))
  296.  
  297. void far wpixel( int x, int y, int color )
  298. {
  299. register unsigned int offs = maddr( xbytes, x, y );
  300. register int mask = bitmask( x );
  301.  
  302. /* write the pixel */
  303. if (color)
  304.     pmat[offs] |= mask;
  305. else
  306.     pmat[offs] &= ~mask;
  307.  
  308. /* statistics */
  309. if (++wpcount >= wppcount)
  310.     {
  311.     wpcount = 0;
  312.     fprintf( stderr, "*" );
  313.     }
  314. }
  315.  
  316. void far wpixelq( int x, int y, int color )
  317. {
  318. register unsigned int offs = maddr( xbytes, x, y );
  319. register int mask = bitmask( x );
  320.  
  321. /* quiet version */
  322.  
  323. /* write the pixel */
  324. if (color)
  325.     pmat[offs] |= mask;
  326. else
  327.     pmat[offs] &= ~mask;
  328.  
  329. /* statistics */
  330. ++wpcount;
  331. }
  332.  
  333. unsigned far rpixel( int x, int y )
  334. {
  335. register unsigned int offs = maddr( xbytes, x, y );
  336. register int mask = bitmask( x );
  337.  
  338. /* read the pixel */
  339. return ((pmat[offs] & mask) != 0);
  340. }
  341.  
  342. void far fwpixel( int x, int y, int color )
  343. {
  344. register unsigned long offs = lmaddr( xbytes, x, y );
  345. register int mask = bitmask( x );
  346.  
  347. /* far matrix version */
  348.  
  349. /* write the pixel */
  350. if (color)
  351.     fpmat[offs] |= mask;
  352. else
  353.     fpmat[offs] &= ~mask;
  354.  
  355. /* statistics */
  356. if (++wpcount >= wppcount)
  357.     {
  358.     wpcount = 0;
  359.     fprintf( stderr, "*" );
  360.     }
  361. }
  362.  
  363. void far fwpixelq( int x, int y, int color )
  364. {
  365. register unsigned long offs = lmaddr( xbytes, x, y );
  366. register int mask = bitmask( x );
  367.  
  368. /* quiet far matrix version */
  369.  
  370. /* write the pixel */
  371. if (color)
  372.     fpmat[offs] |= mask;
  373. else
  374.     fpmat[offs] &= ~mask;
  375.  
  376. /* statistics */
  377. ++wpcount;
  378. }
  379.  
  380. unsigned far frpixel( int x, int y )
  381. {
  382. register unsigned long offs = lmaddr( xbytes, x, y );
  383. register int mask = bitmask( x );
  384.  
  385. /* far matrix version */
  386. /* read the pixel */
  387. return ((fpmat[offs] & mask) != 0);
  388. }
  389.  
  390. int nostop( void )
  391. {
  392. /* status function that always says that it isn't time to stop yet */
  393. return (0);
  394. }
  395.  
  396. int wsbif( of, pmat, fpmat, outfile, xlines, xbytes, ylines )
  397. FILE *of;            /* output file */
  398. unsigned char *pmat;        /* the pixel matrix */
  399. unsigned char huge *fpmat;    /* the far pixel matrix */
  400. char *outfile;            /* name of the output file (may be empty) */
  401. int xlines;            /* x pixel count */
  402. int xbytes;            /* x byte count */
  403. int ylines;            /* y pixel count */
  404. {
  405. char hbuf[SBHSIZE];        /* header */
  406.  
  407. /* write a file according to sbif.h */
  408.  
  409. /* make the header */
  410. memset( hbuf, '\0', sizeof (hbuf) );
  411. sprintf( hbuf, "%s %d %d\n", outfile[0] ? outfile : "no_file", xlines, ylines );
  412.  
  413. /* write the header */
  414. if (fwrite( (void *) hbuf, sizeof (hbuf), 1, of ) < 1)
  415.     return (0);
  416.  
  417. /* write the data */
  418. if (fpmat)
  419.     {
  420.     long tot = xbytes * (long) ylines;
  421.     unsigned int bufsz;
  422.  
  423.     /* the far matrix was used, copy it in chunks to near mem. and write */
  424.  
  425.     /* get a (near) buffer */
  426.     bufsz = coreleft();
  427.     bufsz -= bufsz % 1024;
  428.     if (!(pmat = (unsigned char *) calloc( bufsz, 1 )))
  429.         error(
  430.       "out of memory for writing the pixel matrix (coreleft() is lying)" );
  431.  
  432.     for (; tot > 0; tot -= bufsz, fpmat += bufsz)
  433.         {
  434.         /* a full buffer left? */
  435.         if (tot < bufsz)
  436.             bufsz = tot;
  437.  
  438.         /* get the far data nearer */
  439.         movedata( FP_SEG(fpmat), FP_OFF(fpmat),
  440.                      _DS, (int)pmat, bufsz );
  441.  
  442.         if (fwrite( (void *) pmat, bufsz, 1, of ) < 1)
  443.             return (0);
  444.         }
  445.     }
  446. else
  447.     {
  448.     /* near matrix, write it */
  449.     if (fwrite( (void *) pmat, xbytes, ylines, of ) < ylines)
  450.         return (0);
  451.     }
  452.  
  453. /* ok */
  454. return (1);
  455. }
  456.  
  457. void error( s, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 )
  458. char *s;
  459. int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10;
  460. {
  461. fprintf( stderr, "\nError:" );
  462. fprintf( stderr, s, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 );
  463. fprintf( stderr, "\n" );
  464.  
  465. exit( 2 );
  466. }
  467.  
  468. void warning( s, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 )
  469. char *s;
  470. int v1, v2, v3, v4, v5, v6, v7, v8, v9, v10;
  471. {
  472. fprintf( stderr, "\nWarning:" );
  473. fprintf( stderr, s, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 );
  474. fprintf( stderr, "\n" );
  475. }
  476.  
  477.  
  478.