/* ******************** */

/* A DUMMY MAIN PROGRAM */

/* ******************** */

 

#include "raster.h"

#include <stdio.h>

main()

{

 

      raster myRaster;

 

/* open opens three files

      1) infile.bmp - for bmp input via the input method

      2) infile.out - for text output via the print method

      3) bmpfile.bmp - for bmp output via the output method

 

setframe generates a blank image.

draw draws a straight line

 

 

 input reads the data into the rastfile array and then divides it into a header and image array.

 rawdump outputs an "upside down text" print of the rastfile input to infile.out

 dump outputs a rightside up "text" print of the image array only to the standard output - terminal

 print outputs a rightside up "text" print of the image array only to infile.out

 output combine the header and image arrays into the rastfile array and outputs the bmp file, bmpfile.bmp

 

CAUTION: rawdump and print both output to the same infile.out file and should not be used simultaneously

*/

 

      if(!(myRaster.open("c:/courses/ai/raster/","tables","fee")))

      {printf("error on open\n");

       return 1 ;

      }

 

      myRaster.input();

//    myRaster.setFrame(60,60);

      myRaster.draw(5,5, 60,60);

 

     

     

       myRaster.rawdump();

       myRaster.dump();

//    myRaster.print();

      myRaster.output();

      return 1;

}

 

 

/* ******************** */

/* THE HEADER FILE      */

/* ******************** */

 

#ifndef RASTER_H

#define RASTER_H

 

#include <stdio.h>

#include <string.h>

 

#define MAXXSIZE  128

#define MAXYSIZE   128

#define HEADERSIZE  13

#define MAXIMAGESIZE  MAXXSIZE * MAXYSIZE

#define FILESIZE  MAXIMAGESIZE + HEADERSIZE

 

class raster

{public:

  int rastfile[FILESIZE];

  int image[MAXIMAGESIZE];

  int i,j;

  int size;

  int imagesize;

  int left, right;

  int wide, high;

  FILE *fin, *fout;

raster();

bool open(char *path, char * file);

void dump();

bool input();

void output();

void draw(int begx, int begy, int endx, int endy);

void setFrame(int myWide, int myHigh);

};

 

#endif;

 

/* ******************************* */

/* THE MEMBER FUNCTION (.CPP) FILE */

/* ******************************* */

 

#include "raster.h"

 

raster::raster()

{

}

 

/* Opens three files

      1) infile.bmp - for bmp input via the input method

      2) infile.out - for text output via the print method

      3) bmpfile.bmp - for bmp output via the output method

*/

bool raster::open(char *path, char * infile, char *bmpfile)

{

      char buffer[1000];

 

      strcpy(buffer,path);

      strcat(buffer,infile);

      strcat(buffer,".bmp");

    fin = fopen(buffer,"rb"); //"c:/courses/ai/raster/wdiag.bmp"

    if(fin == NULL)

      {

        printf("Error on open of file\n");

        return false;

      }

      else

            printf("Opened %s for input\n",buffer);

 

      strcpy(buffer,path);

      strcat(buffer,infile);

      strcat(buffer,".out");

      fout = fopen(buffer,"w"); //"c:/courses/ai/raster/raster.out"

    if(fout == NULL)

      {

        printf("Error on open of file\n");

        return false;

      }

      else

            printf("Opened %s for ascii output\n",buffer);

 

      strcpy(buffer,path);

      strcat(buffer,bmpfile);

      strcat(buffer,".bmp");

    fbmp = fopen(buffer,"wb"); //"c:/courses/ai/raster/foo.bmp"

    if(fin == NULL)

      {

        printf("Error on open of file\n");

        return false;

      }

      else

            printf("Opened %s for bmp output\n",buffer);

 

      return true;

}

 

 

 

 

bool raster::input()

{   int i,j,k;

    int left, right;

 

size = fread(rastfile, 4, FILESIZE, fin); //size is number of rastfile elements

//NOTE: the size in the header is header[1] + header[2] >> 16

//      the size in header[17] is header[17] + header[18] >> 16

 

j = 0;

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

{

      left = (rastfile[i] & 0xffff0000) >> 16;

      right = (rastfile[i] & 0xffff);

      header[j++] = right;

      header[j++] = left;

}

wide = header[9]; 

high = header[11];

if(wide > MAXXSIZE)

      printf("ERROR maximum x dimension of %d exceeded by %d\n",MAXXSIZE,wide);

if(high > MAXYSIZE)

      printf("ERROR maximum y dimension of %d exceeded by %d\n",MAXYSIZE,high);

jwide = (wide-1)/2;

if (jwide*2+1 == wide) // set a flag if width is odd - packing requires an extra word?

{

      oddWidth = true;

      printf("in open, oddWidth=true\n");

}

else

{

      oddWidth = false;

      printf("in open, oddWidth=false\n");

}

k = 0;

for(i=HEADERSIZE; i<size;) //does not seem quite right, but works the best

{

      if(oddWidth)

      {

            left = (rastfile[i] & 0xffff0000) >> 16;

            image[k++] = left;

            i++;

      }

      for(j=0; j<jwide; j++, i++)

      {

            left = (rastfile[i] & 0xffff0000) >> 16;

            right = (rastfile[i] & 0xffff);

            image[k++] = right;

            image[k++] = left;

      }

}

imagesize = wide * high;

return true;

}

 

 

 

 

/* generate the bmp file, bmpfile.bmp */

void raster::output()

{

int j,i,k;

 

for(i=0, j=0, k=0; i<HEADERSIZE; i++, j+=2, k++)

{

      rastfile[k] = header[j+1];

      rastfile[k] = (rastfile[k] << 16) | (header[j] & 0xffff);

}

k = 0;

for(i=HEADERSIZE; i<size;)

{

      if(oddWidth)

      {

            rastfile[i] = image[k++] << 16;

            i++;

      }

      for(j=0; j<jwide; j++, i++)

      {

      rastfile[i] = image[k+1];

      rastfile[i] = (rastfile[i] << 16) | (image[k] & 0xffff);

      k +=2;

      }

}

size = fwrite(rastfile, 4, size, fbmp);

}

 

/* create a blank image of myWide X myHigh size */

void raster::setFrame(int myWide, int myHigh)

{

int i;

     

for(i=0;  i<HEADERSIZE*2+1; i++)

      header[i] = 0;

wide = myWide;

jwide = (wide-1)/2;

high = myHigh;

imagesize = wide * high; //in 16 bit pixels

size = imagesize / 2; //in 32 bit words

header[0] = MB;

header[1] = (wide * high + HEADERSIZE*2+1)*2; //file size in bytes

//NOTE: the file size in the file is in header[1] + header[2] >> 16

header[5] = 54;   //size of header in bytes

header[7] = 40;   //don't know what this is

header[9] = wide;

header[11] = high;

header[13] = 1;   //don't know what this is

header[14] = 16;  //don't know what this is

header[17] = header[1] - header[5];  //image size in bytes

//NOTE: the size in header[17] is header[17] + header[18] >> 16

 

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

      image[i] = WHITE;

}

 

 

//outputs a "text" print to standard output - terminal

void raster::dump()

{

int i, j, k;

     

for(i=imagesize-wide+1;i>0;i-=wide)

{

      printf("%3d ",(i+1)/wide+1);

      for(k =0; k<wide; k++)

      {

            if (image[i+k] == 0)

                  printf("1");

            else

                  printf("0");

      }

      printf("\n");

}

printf("\n    ");

 

for(j=1; j <=wide; j++)

      printf("%1d",j%10);

printf("\n");

}

 

//outputs a "text" print of the image to standard output from the rastfile input

void raster::rawdump()

{

int i,j;

int left, right;

 

for(i=HEADERSIZE; i<size;)

{

      fprintf(fout,"%5d ",i);

      left = (rastfile[i] & 0xffff0000) >> 16;

      if (left == 0)

            fprintf(fout,"1");

      else

            fprintf(fout,"0");

      i++;

      for(j=0; j<jwide; j++, i++)

      {

            left = (rastfile[i] & 0xffff0000) >> 16;

            right = (rastfile[i] & 0xffff);

            if (right == 0)

                  fprintf(fout,"1");

            else

                  fprintf(fout,"0");

            if (left == 0)

                  fprintf(fout,"1");

            else

                  fprintf(fout,"0");

      }

      fprintf(fout,"\n");

}

fprintf(fout,"\n    ");

}

 

//outputs a "text" print to fout, the input file name with an .out extension - myinfile.out

void raster::print()

{

 

int i, j, k;

 

for(i=imagesize-wide+1;i>=0;i-=wide)

{

      fprintf(fout,"%3d ",(i+1)/wide+1);

      for(k =0; k<wide; k++)

      {

            if (image[i+k] == 0)

                  fprintf(fout,"1");

            else

                  fprintf(fout,"0");

      }

      fprintf(fout,"\n");

}

fprintf(fout,"\n    ");

 

for(j=1; j <=wide; j++)

      fprintf(fout,"%1d",j%10);

fprintf(fout,"\n");

}

 

 

 

// bresenham's algorithm - draws a line from (begx,begy) to (endx,endy)

void raster::draw(int begx, int begy, int endx, int endy)

{

int deltax, deltay, error, x,y, index, incx, incy, inc1, inc2;

 

deltax = endx - begx;

deltay = endy - begy;

if (deltax < 0) deltax = -deltax;

if (deltay < 0) deltay = - deltay;

incx = 1;

if(endx < begx) incx = -1;

incy = 1;

if(endy < begy) incy = -1;

x = begx;

y = begy;

 

if(deltax > deltay)

{

      index = (y-1)*wide  + x;

      image[index] =  BLACK;  // WHITE results in zero dump, BLACK results in 1

      error = 2*deltay - deltax;

      inc1 = 2*(deltay-deltax);

      inc2 = 2*deltay;

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

      {

            if(error >= 0)

            {

                  y += incy;

                  error += inc1;

            }

            else

                  error += inc2;

            x += incx;

            index = (y-1)*wide  + x;

            image[index] =  BLACK;  // WHITE results in zero dump, BLACK results in 1

      }

}

else

{

      index = (y-1)*wide  + x;

      image[index] =  BLACK;  // WHITE results in zero dump, BLACK results in 1

      error = 2*deltax - deltay;

      inc1 = 2*(deltax-deltay);

      inc2 = 2*deltax;

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

      {

            if(error >= 0)

            {

                  x += incx;

                  error += inc1;

            }

            else

                  error += inc2;

            y += incy;

            index = (y-1)*wide  + x;

            image[index] =  BLACK;  // WHITE results in zero dump, BLACK results in 1

} } }