                                                  Morrison.ls2



Listing 2


/* IFS_decoder.c  Version 1.0  4/15/91  */

#include "stdio.h"

#include "exec/types.h"

#include "exec/tasks.h"

#include "exec/execbase.h"

#include "exec/memory.h"

#include "libraries/dos.h"

#include "libraries/dosextens.h"

#include "graphics/gfx.h"

#include "graphics/gfxmacros.h"

#include "graphics/gfxbase.h"

#include "graphics/view.h"

#include "intuition/intuition.h"

#include "intuition/intuitionbase.h"

#include "exec/exec.h"

#include "math.h"


#define COLORSIZ  32L

#define MAXTRANS     32L

/* The number of transformations is theoretically unlimited */

#define DEPTH    4

#define WIDTH    640

#define HEIGHT   400

/* Arbitrary colors to save with the final image. */

USHORT cmap[] = {0x000,0xf00,0x00f,0x0f0,0xff0,0x0ff,0xf0f,0xfff,

                 0x345,0x900,0x009,0x090,0x990,0x099,0x909,0x444 };

extern struct Window *w;

extern struct Screen *scr;

/*  C Structures defining the screen and window to be opened later.

    The resolution is 640 by 400 with 16 colors.  The message system

    requires a window be opened as well as a screen.  The messages we

    want to receive are mouse-clicks, clicks on the close window gadget

    and key presses.  */


struct NewScreen newscr = {

   0,0,640,400,4,0,1,

   HIRES|LACE,

   CUSTOMSCREEN,

   NULL,

   "IFS_decoder Screen",

   NULL,NULL,

   };

struct Screen *scr;

struct NewWindow nw  = {

   0,0,640,400,0,1,

   MOUSEBUTTONS|CLOSEWINDOW|VANILLAKEY,

   WINDOWCLOSE|ACTIVATE|BORDERLESS|SUPER_BITMAP,

   NULL, NULL,NULL,

   NULL, NULL,

   0,0,100,80,

   CUSTOMSCREEN };

struct Window *w;

SHORT *cols;

extern struct RastPort *rp;

struct FileHandle *Open();

struct BitMap *bitm;

struct RastPort *rp;

struct ViewPort *vp;

struct IntuitionBase *IntuitionBase;

struct GfxBase *GfxBase;


/*  Arrays for the transformation coefficents.  Arrays

    are better than Lists which would allow for variable

    dimensions but complicate and slow the iterations later.   */


double a[MAXTRANS];

double b[MAXTRANS];

double c[MAXTRANS];

double d[MAXTRANS];

double e[MAXTRANS];

double f[MAXTRANS];

double x1, y1;

double x2, y2;


char outfile[80];

char filename[80];



main(argc, argv)

int argc;

char *argv[];

{

      LONG ofh;

      struct IntuiMessage *mess;

      int  success;

      ULONG class;

      USHORT code;

      SHORT  x, y;

      int xoffset, yoffset;

      LONG nextx, nexty, i;

      int count, cc, r, ntrans;

      float  xscale,yscale;

      FILE *fopen(),*pp, *tp;

      LONG nb, colorsize, planesize;

      colorsize = COLORSIZ;

/*  Compile int as a 32 bit integer. */

 
  IntuitionBase = (struct IntuitionBase *)

                                   OpenLibrary("intuition.library",0);

      if(IntuitionBase == NULL)

      {  printf("Couldn't open Intuition library\n");

         goto aborted;  }


  GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);

      if(GfxBase == NULL)

      {  printf("Couldn't open Graphics library\n");

         goto aborted; }


   printf("\n\n      IFS_DECODER Program Copyright 1991 \n");

   printf("               by Laura M. Morrison   \n");

   printf("                  80 North Moore Street, Apt 4J\n");

   printf("                  New York, N. Y. 10013  \n");

   printf("                  Telephone: 212-349-1818  \n");


   if (argc < 2 )

   { printf("  Need coefficient filename on the command line.\n");

      goto aborted; }


   if ( argc < 3 )

   {

     printf("  Need output image filename  on command line. \n");

     printf("  None given so using a default name. \n");

   }


   if (( pp = fopen(argv[1],"r")) == NULL)

   {  printf("Trouble opening the coefficient file.\n");

      goto aborted;

   }

  i=0;

readmore:;


  fscanf(pp," %f %f %f %f %f %f ",&a[i],&b[i],&c[i],&d[i],&e[i],&f[i]);

   if( a[i] < 998.0   )
   {
       i++;

       if( i > (MAXTRANS-1) )
       {

           printf("Too many transformations for allotted storage.\n");

           goto aborted;
        }

        goto readmore;

   }

   ntrans = (int)i;

  fscanf(pp," %f  %d  %f  %d  \n",&xscale,&xoffset,&yscale,&yoffset);

  fclose(pp);

  bitm = (struct BitMap *)AllocMem(sizeof(struct BitMap),MEMF_CHIP);

       if (bitm==NULL)

       {   printf("Couldn't allocate memory for bmap structure. \n");

             goto aborted;  }

      InitBitMap(bitm,DEPTH,WIDTH,HEIGHT);

      planesize = (LONG)(WIDTH/8)*HEIGHT;

      for (i=0; i < DEPTH; i++)

      {  bitm->Planes[i]=(PLANEPTR)AllocRaster(WIDTH,HEIGHT);

             if (bitm->Planes[i] == NULL)

             {   printf("bitmap planes were null\n");

                 goto aborted; }

         BltClear(bitm->Planes[i],planesize,1);   }

      scr = (struct Screen *)OpenScreen(&newscr);

         if (scr==NULL)

         {  printf("scr was null\n");

            goto aborted; }

      nw.Screen = scr;

      nw.BitMap = bitm;

      w = OpenWindow(&nw);

         if (w==NULL)   goto aborted;

      rp = w->RPort;

      vp = &w->WScreen->ViewPort;

/* Tiles are plotted different colors according to the

   transformations that define them. (modulo 15)  The SetRGB4()

   statements tell which register a color is in.

   SetRGB4(viewport,register number, %red , %green, %blue )  */


   SetRGB4(vp,0,0,0,0);

   SetRGB4(vp,1,15,0,0);

   SetRGB4(vp,2,0,0,15);

   SetRGB4(vp,3,0,15,0);

   SetRGB4(vp,4,15,15,0);

   SetRGB4(vp,5,0,15,15);

   SetRGB4(vp,6,15,0,15);

   SetRGB4(vp,7,5,9,11);

   SetRGB4(vp,8,8,4,5);

   SetRGB4(vp,9,9,2,0);

   SetRGB4(vp,10,0,4,8);

   SetRGB4(vp,11,0,9,3);

   SetRGB4(vp,12,8,8,2);

   SetRGB4(vp,13,3,5,10);

   SetRGB4(vp,14,3,12,7);

   SetRGB4(vp,15,13,5,8);


   SetRast(rp,0);


   x1 = 0;

   y1 = 0;

   count=0;

/* Open a file called  "points" to contain the first fifty points

   generated by the iteration.  In case no image appears on the

   screen check these points to see where they are going.

   Adjust scale and offset parameters so points plot on the display.*/


  tp = fopen("ram:points","w");

for (;;)

{    while(( mess=(struct IntuiMessage *)GetMsg(w->UserPort))!= NULL)

     {

               class = mess->Class;

               code = mess->Code;

               x = mess->MouseX;

               y = mess->MouseY;

               ReplyMsg(mess);


/* The program continues to plot points until stopped.

   When the image has a satisfactory density click the

   upper left corner where the CloseWindow gadget is hidden.

   Closing takes a long time because the program writes a raw

   file then converts it to an ILBM file.  It works in  ram

   rather than to disk because the raw file can be quite large.

   Copy the image file to disk to save it. */


               if (class == CLOSEWINDOW)  goto finish;

/*  Key 'a' to abort the program without saving the image. */


               if ((class== VANILLAKEY)&&(code=='a'))   goto aborted;

     }

/* By processing transformations randomly the program

   eventually gets all sequences of transformations and

   thereby all the points.  There is nothing magical or

   or necessary about random selection.  It is just the

   easiest way to exhaust the possibilities. */

            r = rand()  % ntrans;

/* Given the last point(x1,y1) calculate and plot the next

   point(x2,y2) */

            x2 = a[r]*x1   +  b[r]*y1  +  e[r];

            y2 = c[r]*x1   +  d[r]*y1  +  f[r];

                         x1 = x2;

                         y1 = y2;

     /* Calculate in double floating point, plot in integers */

                      nextx = (LONG)(xscale*x2 + xoffset);

                      nexty = (LONG)(yscale*y2 + yoffset);

                         cc = (r  % 14)  +  1;

                         SetAPen(rp,cc);

                         WritePixel(rp,nextx,nexty);

/* Save the first fify points.*/

        count++;

        if(count < 50)

          fprintf(tp,"  %d   %ld   %ld  \n",r,  nextx,nexty);

}

finish:;

         if(argc < 3)

         {    strcpy(filename,"ram:out");

              strcat(filename,argv[1]);

         }

        else

        {  strcpy(filename,"ram:");

            strcat(filename,argv[2]);

        }

         ofh = Open(filename,MODE_NEWFILE);

         if (ofh != NULL)

         {

            for ( i=0; i < DEPTH; i++)

            {

              nb = Write(ofh,w->RPort->BitMap->Planes[i],planesize);

            }

            cols = &cmap[0];

            nb = Write(ofh,cols,colorsize);

            Close(ofh);

         }

            strcpy(outfile," raw2ilbm  ");

            strcat(outfile,filename);

            strcat(outfile,"  ");

            strcat(outfile,filename);

            strcat(outfile,".pic  hi 4 ");

            success=Execute(outfile,0,0);

              if (success == 0)

                printf("error converting outfile to ilbm image\n");

            strcpy(outfile," delete  ");

            strcat(outfile,filename);

            success = Execute(outfile,0,0);

                 if (success == 0)

                     printf(" error while deleting raw outfile\n");

aborted:;

       if(tp)   fclose(tp);

       if (w)  CloseWindow(w);

       if (scr)  CloseScreen(scr);

       for ( i = 0; i < DEPTH; i++)

       {

         if( bitm->Planes[i] > 0)

         { 

              FreeRaster(bitm->Planes[i],WIDTH,HEIGHT);

         }

       }


       if (bitm) FreeMem(bitm,sizeof(struct BitMap));

       if (IntuitionBase)   CloseLibrary(IntuitionBase);

       if (GfxBase)         CloseLibrary(GfxBase);


}  /* end of main */

