                                                        Morrison.ls1

Listing 1


/* IFS_coder.c  V1.0  Copyright by Laura M. Morrison 1991 */

#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  32

#define BUFSIZE  32000L

#define MAXCOLOR   14

#define DEPTH    4

#define WIDTH    640

#define HEIGHT   400


extern struct Window *w;

extern struct RastPort *rp;

extern struct Window *w;

extern struct Screen *OpenScreen();

extern struct Window *OpenWindow();

struct FileHandle *Open();

USHORT cmap[] =   { 0x000,0xfff,0xc00,0x990,0x070,0x0f0,0xc0c,0x0ac,

                    0xf0d,0x909,0x753,0xfdb,0xff0,0xaaa,0x777,0x444

                   };

struct NewScreen newscr = {

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

   HIRES|LACE,

   CUSTOMSCREEN,

   NULL,

   "Coder Screen",

   NULL,NULL,

   };

struct Screen *scr;


struct NewWindow nw  = {

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

   MOUSEBUTTONS|SELECTUP|CLOSEWINDOW|VANILLAKEY,

   WINDOWCLOSE|ACTIVATE|BORDERLESS|SUPER_BITMAP,

   NULL, NULL,

   "IFS_CODER ",

   NULL, NULL,

   0,0,100,80,

   CUSTOMSCREEN

   };


struct Window *w;

SHORT *cols;

struct BitMap *bitm;

struct Window *w;

struct RastPort *rp;

struct ViewPort *vp;

SHORT *cols;

struct BitMap *bitm;

struct Window *w;

struct RastPort *rp;

struct ViewPort *vp;

struct IntuitionBase *IntuitionBase;

struct GfxBase *GfxBase;


static int colrs[MAXCOLOR];

static int p11,p12,p21,p22;


/* Collect user mouse-clicked points in these variables. */

double pt1x[4],pt1y[4],pt2x[4],pt2y[4];

/* Program computes and writes out coefficients for one

   transformation at a time. */

double a, b, c, d, e, f ;

/* these variables are used for Cramer's rule solution to

   simultaneous  equations */

double h1,h2,h3,x1,y1,x2,y2;

double a11,a12,a13,a21,a22,a23,a31,a32,a33;

double deta,deta11,deta12,deta13,deta21,deta22,deta23;


char outfile[80];

char infile[80];

char filename[80];

char str[80];

char transtr[80];



main(argc, argv)

int argc;

char *argv[];

{

      LONG  bfh;

      struct IntuiMessage *mess;

      int  success, i, j, ntrans, npoints;

      ULONG class;

      USHORT code;

      SHORT   xcol, yrow;

      int from=0,  start=0;

      int countt,countf, cc;

      float  xrat=1.0,yrat=-1.0;

      float  dm = 999.9;

      int dum = 999;

      int  xoff=0, yoff=400;

      LONG  planesize, nb = 0, nt, colorsize;

      FILE *fopen(), *zp,  *cp;

      colorsize = COLORSIZ;

      a=0;b=0;c=0;d=0;e=0;f=0;



   IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0);

      if(IntuitionBase == NULL)

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

         exit(1); }


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

      if(GfxBase == NULL)

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

         goto finish; }

/* Program quits if no raw image file is supplied. Note that this could

   be a blank screen. Its only function is to guide the user's mouse

   clicking. This file is not destroyed by the program.*/

   if ( argc < 2 )
   {

     printf("CLI Usage:Need name of raw input image file on command line.\n");

     printf("         (Use ilbm2raw to convert ILBM image file to raw)\n");

     goto finish;

   }

   /* If user forgets to name a coefficient file on the command line the

      program supplies one and continues. Look for your output

      transformation in a file called 'coefs'.  Be sure to rename this

      file more appropriately to save it. */


   if( argc < 3)

   {  printf(" No coefficient output filename on command line. \n");

      printf(" so using default 'coefs' name for coefficient file.\n");

   }


   printf("\n\n     IFS_CODER PROGRAM Version 4/15/91   \n\n");

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

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

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


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

   if (bitm==NULL)

         {   printf("Couldn't allocate bmap struct \n");

             goto finish; }

   InitBitMap(bitm,DEPTH,WIDTH,HEIGHT);

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

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

   {   bitm->Planes[i]=(PLANEPTR)AllocRaster(640,400);

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

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

                 goto finish; }

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

   }

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

   if (scr==NULL)

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

            goto finish;   }

   nw.Screen = scr;

   nw.BitMap = bitm;

   w = OpenWindow(&nw);

   if (w==NULL)   goto finish;

   rp = w->RPort;

   vp = &w->WScreen->ViewPort;

/* These colors are arbitrary.  They correspond to tutorial text. */

/* To find which transformation is responsible for a tile look up the

   tile's color below and note the register number.  That row in the

   coefficient file corresponds to the tile's transformation. (modulo 15)*/

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

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

   SetRGB4(vp,2,15,0,0);        /* red */

   SetRGB4(vp,3,15,7,0);       /* orange */

   SetRGB4(vp,4,0,10,0);       /* dark green */

   SetRGB4(vp,5,0,15,0);      /* light green */

   SetRGB4(vp,6,0,0,15);    /*  blue */

   SetRGB4(vp,7,0,13,15);  /* turquoise */

   SetRGB4(vp,8,15,0,13);      /* pink */

   SetRGB4(vp,9,8,0,15);        /* purple */

   SetRGB4(vp,10,7,5,3);      /*  brown */

   SetRGB4(vp,11,15,13,11);   /* beige */

   SetRGB4(vp,12,15,15,0);      /* yellow */

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

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

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


/*  This input click-guide image file must be raw.  Rather than waste

    time converting it over and over again in this program do it once

    before you start the program.  To convert from ILBM format image

    to raw format type in CLI    'ILBM2raw <guidefilename>'

    Use the raw file, called <guidefilename>.hi4 as input to this program */


   bfh = Open(argv[1],MODE_OLDFILE);

   if (bfh == NULL)

   {   printf("Can't open image input file \n");

            goto finish; }

   for ( i=0; i<DEPTH; i++)
   {
      nb = Read(bfh,w->RPort->BitMap->Planes[i],planesize);

   }

   Close(bfh);

   for(j=0; j < MAXCOLOR; j++)

        {    colrs[j] = j; }

   start=0;

   countt=0;  countf=0;

   if(argc < 3 )
   {

/*  Be sure to save old default coefficient files (named 'coefs')

   or they will be erased here.  Note that a coefficient file cannot

   be simply overwritten since it is opened in 'append' mode. We want

   append mode so transformations can be collected over several sessions

   in IFS_coder.*/

        strcpy(outfile," delete ");

        strcat(outfile,"coefs ");

        success=Execute(outfile,0,0);

                 if (success == 0)

                 printf("No old default coefficient file to erase.\n");

        strcpy(outfile,"coefs ");

   }

   else

   {   strcpy(outfile,argv[2]); }

   cp = fopen(outfile,"a");

   /* This is a list of points selected.  User  may ignore this file

      until with experience he knows what to do with it.  If you want

      to save it rename it and copy it to disk otherwise it will be

       overwritten. */

   strcpy(outfile,"ram:");

   strcat(outfile,argv[2]);

   strcat(outfile,"points");

   zp = fopen(outfile,"a");

   from = 0;

   npoints = 0;

   ntrans = 0;

for(;;)

{

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

     {
            class = mess->Class;

            code = mess->Code;

            xcol = mess->MouseX;

            yrow = mess->MouseY;

            ReplyMsg(mess);

/* Here the program collects the mouse-clicks. Note that they must

   be in order.  FROM a point on the whole TO its image on the tile. */

         if((class==MOUSEBUTTONS)&&(code==SELECTUP))
         {
            if(from==0)

            {  pt1x[countf] = (double)xcol;

               pt1y[countf] = (double)(400-yrow);

               cc = 2;

/* Write indicators to screen to give the user some idea of what

   the program thinks he is doing. */

               SetAPen(rp,cc);

               if( (xcol > 0)&&(xcol < 639)&&(yrow > 0)&&(yrow < 399) )
               {

                  RectFill(rp,xcol-1,yrow-1,xcol+1,yrow+1);

                }

                WritePixel(rp,xcol,yrow);

                countf++;

                from=1;

                cc = 2;

                SetAPen(rp,cc);

                Move(rp,30,360);

                Text(rp,"From Point",10);

            }

            else

            {  pt2x[countt]=(double)xcol;

               pt2y[countt]= (double)(400-yrow);

               cc = 5;

               SetAPen(rp,cc);

               if( (xcol > 0)&&(xcol < 639)&&(yrow > 0)&&(yrow < 399) )

               {

                  RectFill(rp,xcol-1,yrow-1,xcol+1,yrow+1);

               }

               WritePixel(rp,xcol,yrow);

               countt++;

               from=0;

               npoints++;

               cc = 5;

               SetAPen(rp,cc);

               Move(rp,30,360);

               Text(rp,"To  Point  ",10);

               cc = npoints;

               SetAPen(rp,cc);

               RectFill(rp,30,380,50,396);


               cc = npoints;

               SetAPen(rp,cc);

               strcpy(transtr,"Pairs = ");

               nt = (LONG)npoints;

               itoa(nt,str);

               strcat(transtr,str);

               Move(rp,60,390);

               Text(rp,transtr,strlen(transtr));

            }

         }

/* When finished click the upper left corner where  CloseGadget

   is hidden.  */

         if(class==CLOSEWINDOW) goto finish;

/* To clear a mix-up mid-transformation key 'c' to start

   that tile over. */

         if((class==VANILLAKEY)&&(code=='c'))

         {

            from=0;

            cc=9;

            SetAPen(rp,cc);

            Move(rp,60,390);

            Text(rp,"Pairs = 0 ",10);

            cc = 0;

            SetAPen(rp,cc);

            RectFill(rp,30,380,50,396);

            npoints=0;

         }

     }

/*  When the program finds it has three sets of FROM->TO

  points it calculates transformation coefficients.  Not just

  any sets define a transformation.  Sometimes the determinent,

   ac-bd, is zero.  This usually means something went wild.

  All properly defined sets will produce a transformation.

  This is Cramer's rule for solving six equations for six unknowns.

  No need for a general simultaneous equation solver. */

     if(npoints==3)
     {

        a11 = pt1x[0];

         a21 = pt1x[1];

         a31 = pt1x[2];

         a12 = pt1y[0];

         a22 = pt1y[1];

         a32 = pt1y[2];

         a13 = 1;

         a23 = 1;

         a33 = 1;

         h1 = pt2x[0];

         h2 = pt2x[1];

         h3 = pt2x[2];

   deta=a11*(a22*a33-a23*a32)-a12*(a21*a33-a23*a31)+a13*(a21*a32-a22*a31);

   if(deta==0)

   {  printf("determinant = 0\n");

      goto noequation;  }

   deta11=h1*(a22*a33-a23*a32)-h2*(a12*a33-a13*a32)+ h3*(a12*a23-a13*a22);

   deta12=a11*(h2*a33-a23*h3)-a21*(h1*a33-a13*h3) + a31*(h1*a23-a13*h2);

   deta13=a11*(a22*h3-h2*a32)-a21*(a12*h3-h1*a32) + a31*(a12*h2-h1*a22);

   a=deta11/deta;

   b=deta12/deta;

   e=deta13/deta;

   h1 = pt2y[0];

   h2 = pt2y[1];

   h3 = pt2y[2];

   deta21=h1*(a22*a33-a23*a32)-h2*(a12*a33-a13*a32)+ h3*(a12*a23-a13*a22);

   deta22=a11*(h2*a33-a23*h3)-a21*(h1*a33-a13*h3) + a31*(h1*a23-a13*h2);

   deta23=a11*(a22*h3-h2*a32)-a21*(a12*h3-h1*a32) + a31*(a12*h2-h1*a22);

   c=deta21/deta;

   d=deta22/deta;

   f=deta23/deta;

/*  Save a list of the points used to calculate the coefficients.*/

   p11 = (int)pt1x[0];   p12 = (int)pt1y[0];

   p21 = (int)pt2x[0];   p22 = (int)pt2y[0];

   fprintf(zp," %d  %d      %d  %d \n",p11,p12,p21,p22);

   p11 = (int)pt1x[1];   p12 = (int)pt1y[1];

   p21 = (int)pt2x[1];   p22 = (int)pt2y[1];

   fprintf(zp," %d  %d      %d  %d \n", p11,p12,p21,p22);

   p11 = (int)pt1x[2];   p12 = (int)pt1y[2];

   p21 = (int)pt2x[2];   p22 = (int)pt2y[2];

   fprintf(zp," %d  %d      %d  %d \n\n",p11,p12,p21,p22);

/*  Add the coefficients to the output file. */

 fprintf(cp,"%.5f  %.5f  %.5f   %.5f   %.0f   %.0f\n\n",a,b,c,d,e,f);

   npoints=0;

   ntrans++;

   countf=0;

   countt=0;

   cc = (ntrans % 14 ) + 1;

   SetAPen(rp,cc);

   strcpy(transtr,"Transformations = ");

   nt = (LONG)ntrans;

   itoa(nt,str);

   strcat(transtr,str);

   Move(rp,450,390);

   Text(rp,transtr,strlen(transtr));

   RectFill(rp,420,380,440,396);

   cc = 9;

   SetAPen(rp,cc);

   Move(rp,60,390);

   Text(rp,"Pairs = 0 ",10);

   cc = 0;

   SetAPen(rp,cc);

   RectFill(rp,30,380,50,396);

noequation:;

     }

}

finish:;

        if(cp)

        {

 fprintf(cp,"%.5f  %.5f  %.5f   %.5f  %.0f  %.0f\n\n",dm,dm,dm,dm,dm,dm);

           fprintf(cp," %f  %d  %f  %d \n",xrat,xoff,yrat,yoff);

           fclose(cp);

        }


        if(zp)

        {

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

           {

               fprintf(zp," %d  %d   %d  %d  \n",dum,dum,dum,dum);

           }

           fprintf(zp,"\n %f  %d  %f  %d \n",xrat,xoff,yrat,yoff);

           fclose(zp);

       }

       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 */

/* This function converts an integer to its string

   representation in case your compiler doesn't have such a

   function. It is from Kerrigan and  Richie's C Programming. */

itoa(nt,str)

char str[];

int  nt;

{

   int c, j, i, sign;

   if (( sign = nt) < 0)

      nt = -nt;

   i=0;

   do {

      str[i++] = nt % 10 + '0';

   } while ((nt /= 10) > 0);

   if (sign < 0)

      str[i++] = '-';

   str[i] = '\0';

   for ( i=0, j=strlen(str)-1; i<j; i++,j--)

   {

      c = str[i];

      str[i]=str[j];

      str[j] = c;

   }

   return(0);

}

