MandelBrot - OpenLearning

Edward Lin

edward.lin
/*
 *  bmpServer.c
 *  1917 serve that 3x3 bmp from lab3 Image activity
 *
 *  Created by Tim Lambert on 02/04/12.
 *  Containing code created by Richard Buckland on 28/01/11.
 *  Copyright 2012 Licensed under Creative Commons SA-BY-NC 3.0. 
 *
 */

#include "pixelColor.h"
#include "mandelBrot.h"

// after serving this many pages the server will halt
 
int main(int argc, char *argv[]) {
      
   printf("************************************\n");
   printf("Starting simple server %f\n", SIMPLE_SERVER_VERSION);
   printf("Serving bmps since 2012\n");   
   
   int serverSocket = makeServerSocket (DEFAULT_PORT);   
   printf("Access this server at http://localhost:%d/\n", DEFAULT_PORT);
   printf("************************************\n");
   
   char request[REQUEST_BUFFER_SIZE] = {0};
   int numberServed = 0;

   while (numberServed < NUMBER_OF_PAGES_TO_SERVE) {
      
      printf("*** So far served %d pages ***\n", numberServed);
      
      int connectionSocket = waitForConnection(serverSocket);
      // wait for a request to be sent from a web browser, open a new
      // connection for this conversation
      
      // read the first line of the request sent by the browser  
      int bytesRead;
      bytesRead = read(connectionSocket, request, (sizeof request)-1);
      assert(bytesRead >= 0); 
      // were we able to read any data from the connection?
      
      double x1; 
      double y1;
      double zoom1;
     
      char header[REQUEST_BUFFER_SIZE];

      int position = 0;
      while (request[position] != 'b'){
         header[position] = request[position+5];
         position++;
      }

      // print entire request to the console 
      printf (" *** Received http request ***\n %s\n", request);      

      if (request[5] == ' ') {         //if string size = 0 
         serveHTML(connectionSocket);
         x1 = 0;
         y1 = 0;
         zoom1 = 0;
      } else {
         
         int counter1 = 1;
         char part_x[strlen(header)]; 
         while (header[counter1] != '_') {
             part_x[counter1-1] = header[counter1];
             counter1++;
         }
         part_x[counter1-1] = '\0'; //end string

         counter1 = counter1 +2; // jump two to start of Y

         int counter2 = 0;

         char part_y[strlen(header)];
     
         while(header[counter1] != '_') {
            part_y[counter2] = header[counter1];
            counter1++;
            counter2++;
         }
         part_y[counter2] = '\0';     //end string

         counter1 = counter1+2;     //jump two to start of Z

         char part_z[strlen(header)];

         int count3 =0;

         while (header[counter1] != '.') {
            part_z[count3] = header[counter1];
            count3++;
            counter1++;
         }

         part_z[count3] = '\0';      //end of string
    
         char * pointer_x = (part_x);
         char * pointer_y = (part_y);
         char * pointer_z = (part_z);
  
         x1 = run_strtod(pointer_x);
         y1 = run_strtod(pointer_y);
         zoom1 = run_strtod(pointer_z);

	//send the browser a simple html page using http
      	 printf (" *** Sending http response ***\n");
      	 serveBMP(connectionSocket, x1, y1, zoom1);
    }
      
      // close the connection after sending the page- keep aust beautiful
      close(connectionSocket);
      numberServed++;

   } 
   
   // close the server connection after we are done- keep aust beautiful
   printf("** shutting down the server **\n");
   close(serverSocket);
   
   return EXIT_SUCCESS; 
}


void serveBMP(int socket, double x1, double y1, double zoom1) {
   char* message;

   // (if you write stings one after another like this on separate
   // lines the c compiler kindly joins them togther for you into
   // one long string)

   message = "HTTP/1.0 200 OK\r\n"
             "Content-Type: image/bmp\r\n"
             "\r\n";
   // first send the http response header
   printf ("about to send=> %s\n", message);
   write (socket, message, strlen (message));
   
   // now send the BMP
   
   unsigned char bmp[BMP_FILE_SIZE] = {0};
   createBMP(bmp, x1, y1, zoom1);
   write (socket, bmp, sizeof(bmp));

}
 
// -------------------------------------------------------
// start the server listening on the specified port number
// -------------------------------------------------------

int makeServerSocket(int portNumber) { 
   
   // create socket
   int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
   assert(serverSocket >= 0);   
   // error opening socket
   
   // bind socket to listening port
   struct sockaddr_in serverAddress;
   bzero((char *) &serverAddress, sizeof(serverAddress));
   
   serverAddress.sin_family      = AF_INET;
   serverAddress.sin_addr.s_addr = INADDR_ANY;
   serverAddress.sin_port        = htons(portNumber);
   
   // let the server start immediately after a previous shutdown
   int optionValue = 1;
   setsockopt(
      serverSocket,
      SOL_SOCKET,
      SO_REUSEADDR,
      &optionValue, 
      sizeof(int)
   );
 
   int bindSuccess = 
      bind(
         serverSocket, 
         (struct sockaddr *) &serverAddress,
         sizeof (serverAddress)
      );
   
   assert(bindSuccess >= 0);
   // if this assert fails wait a short while to let the operating 
   // system clear the port before trying again
   return serverSocket;
}

// ------------------------------------------------------------
// wait for a browser to request a connection,
// returns the socket on which the conversation will take place
// ------------------------------------------------------------

int waitForConnection(int serverSocket) {
   // listen for a connection
   const int serverMaxBacklog = 10;
   listen(serverSocket, serverMaxBacklog);
   
   // accept the connection
   struct sockaddr_in clientAddress;
   socklen_t clientLen = sizeof (clientAddress);
   int connectionSocket = 
      accept(
         serverSocket, 
         (struct sockaddr *) &clientAddress, 
         &clientLen
      );

   assert(connectionSocket >= 0);
   // error on accept
   return (connectionSocket);
}

int createBMP(unsigned char bmp[BMP_FILE_SIZE], double x1, double y1, double zoom1) {

   double y = y1;
   double x = x1;
   double zoom = zoom1;

   zoom = configureZoom(zoom);

   unsigned char header[] = 
      {0x42,0x4d,0x5a,0x00,0x00,0x00,0x00,0x00,
       0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
       0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,
       0x00,0x00,
       0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,
       0x24,0x00,0x00,0x00,0x13,0x0b,0x00,0x00,
       0x13,0x0b,0x00,0x00,0x00,0x00,
       0x00,0x00,0x00,0x00,0x00,0x00,};

   unsigned char body[BMP_BODY_SIZE] = {0};
   int pixel_array = 0;
   double yposition = 0;

   while (yposition< bmpSize) {

      double xposition = 0;
      while (xposition < bmpSize) {
         int iterations = setCheck(yposition, xposition, x, y, zoom);
         if (setCheck(yposition, xposition, x, y, zoom) > minIterations && 
             setCheck(yposition, xposition, x, y, zoom) < maxIterations) {
            body[pixel_array] = stepsToBlue(iterations);
            body[pixel_array+1] = stepsToGreen(iterations); 
            body[pixel_array+2] = stepsToRed(iterations);
            pixel_array = pixel_array+3;
         } else {
            body[pixel_array] = 0x00;
            body[pixel_array+1] = 0x00;
            body[pixel_array+2] = 0x00;
            pixel_array = pixel_array+3;
         }
      xposition++;
        }
   yposition++;
}

   int count1 = 0;
   while (count1 <BMP_HEADER_SIZE) {
      bmp[count1] = header[count1];
      count1++;
   }

   int count2 = 0;
   while  (count2 < BMP_BODY_SIZE) {
      bmp[count2+BMP_HEADER_SIZE] = body[count2];             //these two loops just put 
      count2++;                                  //the header and the body together
   }

   return EXIT_SUCCESS;
}


int setCheck(double yposition, double xposition, double x, double y, double zoom) {

    double point_x = (xposition - maxIterations)/(zoom) +x;      //    the -2 just orientates it , and adding 
                                                //    x makes the new co ordinate the origin
    double point_y = (yposition - maxIterations)/(zoom) +y;
    int count = 0;
    double Re = 0;
    double Im = 0;
    double tempx = 0;
    
    while ((count < maxIterations) && ((Re*Re + Im*Im) <= 4)) {
       tempx = Re;
       Re = (Re)*(Re) - (Im)*(Im) + point_x;
       Im = (2*tempx*Im) + point_y;
       count++;
    } 

    return count;
}

double configureZoom(double zoom) {

   double number = 2;
   int counter = 0;
  
   while (counter != zoom) {
      number = 2*number;
      counter++;
   }
   number = number/2;

   return number;
}


void serveHTML(int socket) {
   char* message;
 
   // first send the http response header
   message =
      "HTTP/1.0 200 Found\n"
      "Content-Type: text/html\n"
      "\n";
   printf("about to send=> %s\n", message);
   write(socket, message, strlen(message));
 
   message =
      "<!DOCTYPE html>\n"
      "<html>\n"
      "<script src=\"https://almondbread.openlearning.com/tileviewer.js\"></script>\n"
      "</html>\n";
   write(socket, message, strlen(message));
}


double run_strtod(char * input) {
   double output;
   char * end;

   output = strtod(input, & end);
   return output;
}

Download file: mandelBrot.c (9.1 KB)

Comments

Chat