Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Your program should then produce the BBC codeword image that approximates the mo

ID: 3829497 • Letter: Y

Question

Your program should then produce the BBC codeword image that approximates the monochrome image. The density of the codeword image should be approximately the same as that of the monochrome image.

how to change this code to do this

#include "dirtyd.h"
#include "GLOWWORM.h"

#include "MyBMP.h"

#define OUT_BMPFILENAME "HW06_PR01.bmp"

#include <stdio.h>
#include <stdlib.h>

#define WIDTH (640)
#define HEIGHT (480)

#define BBC_PACKET_LENGTH_BYTES ((WIDTH * HEIGHT)/8)
#define BBC_MESSAGE_LENGTH_BYTES ( 32) // bytes, not bits
#define BBC_CHECKSUM_BITS ( 8) // bits

#define BBC_PACKET_LENGTH_BITS (8 * BBC_PACKET_LENGTH_BYTES)
#define BBC_MESSAGE_LENGTH_BITS (8 * BBC_MESSAGE_LENGTH_BYTES)

#define isSet(c,b) ((c) & (1 << (b)))

#define TASKPRINT (!TRUE)
#define TASK(s) if(TASKPRINT) printf("%s ", (s))

#define fileREAD "message_tx.txt"

//#define DEBUG_ON
#ifdef DEBUG_ON
   #define DEBUG(s) s
#else
   #define DEBUG(s)
#endif

uint8_t *bbc_encode_byte(GLOWWORM *gw, uint8_t *packet, uint8_t c, MyBMP *bmp)
{             
   for (int bit = 7; bit >= 0; bit--)
   {
       uint8_t bitValue = isSet(c, bit);
       uint64_t hash = GLOWWORM_addBit(gw, !!bitValue);
       uint32_t chip = hash % BBC_PACKET_LENGTH_BITS;
       printf("%c[%i] = %u (chip = %u) ", c, bit, !!bitValue, chip);
       packet[chip] = TRUE;
       MyBMP_drawPixel(bmp, chip/HEIGHT, chip%HEIGHT, 0, 0, 0);
       //packet[GLOWWORM_addBit(gw, isSet(c,bit)) % (BBC_PACKET_LENGTH_BITS)] = TRUE;
   }
  
   return packet;
}

uint8_t *bbc_encode(uint8_t *packet, uint8_t *s, MyBMP *bmp)
{
   int byte = 0;

   if (NULL == packet)
   {
       TASK("Create packet (1 byte per bit for convenience)");
       packet = (uint8_t *) malloc(BBC_PACKET_LENGTH_BITS * sizeof(uint8_t));
       if (!packet)
       {
           printf("Failed to allocate packet -- abort! ");
           exit(EXIT_FAILURE);
       }
       for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
           packet[i] = 0;
   }
  
   TASK("Encode bookend marks");
   packet[0] = TRUE;
   packet[BBC_PACKET_LENGTH_BITS - 1] = TRUE;

   TASK("Create and Initialize Glowworm");
   GLOWWORM *gw = GLOWWORM_new();
   GLOWWORM_init(gw);
  
   TASK("Encode the message");
   while ((byte < BBC_MESSAGE_LENGTH_BYTES) && (NUL != s[byte]))
       bbc_encode_byte(gw, packet, s[byte++], bmp);

   TASK("Encode padding bytes (all zero)");
   while (byte++ < BBC_MESSAGE_LENGTH_BYTES)
       bbc_encode_byte(gw, packet, 0, bmp);

   TASK("Encode checksum bits");
   for (int bit = 0; bit < BBC_CHECKSUM_BITS; bit++)
       packet[GLOWWORM_addBit(gw, 0) % BBC_PACKET_LENGTH_BITS] = TRUE;
  
   GLOWWORM_del(gw);

   return packet;
}

uint32_t chipFromHash(uint64_t hash)
{
   return (uint32_t) (hash % BBC_PACKET_LENGTH_BITS);
}

void printMessagePrefix(uint8_t *message, int bits)
{
   printf("MSG: ");
   for (int i = 0; i < bits; i++)
       printf("%c", message[i]? '1' : '0');
   printf(" ");
}

void printMessage(uint8_t *message)
{
   DEBUG(printMessagePrefix(message, BBC_MESSAGE_LENGTH_BITS);)
  
   char ascii[BBC_MESSAGE_LENGTH_BYTES + 1];
   ascii[BBC_MESSAGE_LENGTH_BYTES] = NUL;
  
   for (int i = 0; i < BBC_MESSAGE_LENGTH_BYTES; i++)
   {
       ascii[i] = 0;
       for (int b = 0; b < 8; b++)
       {
           ascii[i]   <<= 1;
           ascii[i] += message[8*i+b]? 1 : 0;
       }
   }
   printf("MESSAGE: %s ", ascii);
}

int bbc_decode(uint8_t *packet)
{
   uint8_t msgBits[BBC_MESSAGE_LENGTH_BITS + BBC_CHECKSUM_BITS];

   GLOWWORM *gw = GLOWWORM_new();
   GLOWWORM_init(gw);

   int messages = 0;
   int b = 0;
   int forward = TRUE;
   DEBUG(int trap = 0;)
   while (b >= 0)
   {
       DEBUG
       (
           printf("DEC Bit %03i: ", b);
           printf(" %s ", forward ? "->" : "<-");
           printf(" (%02i) ", trap);
           printMessagePrefix(msgBits, b);
       )
      
       // Pushing down the 0 path
       if ( (forward) && (b < BBC_MESSAGE_LENGTH_BITS + BBC_CHECKSUM_BITS) )  
       {
           msgBits[b++] = 0;
           if (packet[chipFromHash(GLOWWORM_addBit(gw, 0))])
           {
               forward = TRUE;
               DEBUG(trap = 1;)
           }
           else
           {
               GLOWWORM_delBit(gw, msgBits[--b]);
               forward = FALSE;
               DEBUG(trap = 2;)
           }
           continue;
       }
      
       // Message found
       if ( (forward) && (b >= BBC_MESSAGE_LENGTH_BITS + BBC_CHECKSUM_BITS) )
       {
           printMessage(msgBits);
           messages++;
           GLOWWORM_delBit(gw, msgBits[--b]);
           forward = FALSE;
           DEBUG(trap = 7;)
           continue;
       }
      
       // Backtracking from a 0 bit
       if ( (!forward) && (0 == msgBits[b]) )
       {
           if (b < BBC_MESSAGE_LENGTH_BITS)
           {
               msgBits[b++] = 1;
               if (packet[chipFromHash(GLOWWORM_addBit(gw, 1))])
               {
                   forward = TRUE;
                   DEBUG(trap = 3;)
               }
               else
               {
                   GLOWWORM_delBit(gw, msgBits[--b]);
                   forward = FALSE;
                   DEBUG(trap = 4;)
               }
           }
           else
           {
               GLOWWORM_delBit(gw, msgBits[--b]);
               forward = FALSE;
               DEBUG(trap = 5;)
           }
           continue;
       }
      
       // Backtracking from a 1 bit
       if ( (!forward) && (1 == msgBits[b]) )
       {
           GLOWWORM_delBit(gw, msgBits[--b]);
           forward = FALSE;
           DEBUG(trap = 6;)
           continue;
       }
      
       printf("Decoder failed to catch condition. ");
   }
  
   GLOWWORM_del(gw);
   return messages;
}

int countMarks(uint8_t *packet)
{
   int marks = 0;
  
   for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
       marks += !!packet[i];
      
   return marks;
}

void printPacket(uint8_t *packet)
{
   if (BBC_PACKET_LENGTH_BITS <= 64)
   {
       printf(" ");
       for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
           printf("%c", (i%10)? ' ' : '0' + (i/10));
       printf(" ");
       printf(" ");
       for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
           printf("%c", '0' + i%10);
       printf(" ");
   }
   printf("PKT: ");
   for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
   {
       printf("%c", packet[i]? 'X' : '.');
       if ((i > 0) && !(i % 64))
           printf(" ");
   }

   printf(" ");
}

double percentage(double numerator, double denominator)
{
   return 100.0 * (numerator / denominator);
}

int main(void)
{
   MyBMP *bmp = MyBMP_new(WIDTH, HEIGHT);
   MyBMP_setFilename(bmp, OUT_BMPFILENAME);
   //GLOWWORM_test(2);
  
   FILE *readFILE = fopen("message_tx.txt", "r");
  
   char input[128];
  
   uint8_t *packet = bbc_encode(NULL, (uint8_t *) "Hello World.", bmp);
  
   while( fgets(input, 128, readFILE))
   {
       bbc_encode(packet, (uint8_t *) input, bmp);
   }
  
   DEBUG(printPacket(packet);)

   int marks = countMarks(packet);  
   printf("Marks in packet: %i (%6.2f%% density) ",
       marks, percentage(marks, BBC_PACKET_LENGTH_BITS));

   printf("Found %i messages in packet ", bbc_decode(packet));
  
   MyBMP_save(bmp);
   MyBMP_del(bmp);
   return EXIT_SUCCESS;
}

Explanation / Answer

#include "dirtyd.h"
#include "GLOWWORM.h"

#include "MyBMP.h"

#define OUT_BMPFILENAME "HW06_PR01.bmp"

#include <stdio.h>
#include <stdlib.h>

#define WIDTH (640)
#define HEIGHT (480)

#define BBC_PACKET_LENGTH_BYTES ((WIDTH * HEIGHT)/8)
#define BBC_MESSAGE_LENGTH_BYTES ( 32) // bytes, not bits
#define BBC_CHECKSUM_BITS ( 8) // bits

#define BBC_PACKET_LENGTH_BITS (8 * BBC_PACKET_LENGTH_BYTES)
#define BBC_MESSAGE_LENGTH_BITS (8 * BBC_MESSAGE_LENGTH_BYTES)

#define isSet(c,b) ((c) & (1 << (b)))

#define TASKPRINT (!TRUE)
#define TASK(s) if(TASKPRINT) printf("%s ", (s))

#define fileREAD "message_tx.txt"

//#define DEBUG_ON
#ifdef DEBUG_ON
   #define DEBUG(s) s
#else
   #define DEBUG(s)
#endif

uint8_t *bbc_encode_byte(GLOWWORM *gw, uint8_t *packet, uint8_t c, MyBMP *bmp)
{             
   for (int bit = 7; bit >= 0; bit--)
   {
       uint8_t bitValue = isSet(c, bit);
       uint64_t hash = GLOWWORM_addBit(gw, !!bitValue);
       uint32_t chip = hash % BBC_PACKET_LENGTH_BITS;
       printf("%c[%i] = %u (chip = %u) ", c, bit, !!bitValue, chip);
       packet[chip] = TRUE;
       MyBMP_drawPixel(bmp, chip/HEIGHT, chip%HEIGHT, 0, 0, 0);
       //packet[GLOWWORM_addBit(gw, isSet(c,bit)) % (BBC_PACKET_LENGTH_BITS)] = TRUE;
   }
  
   return packet;
}

uint8_t *bbc_encode(uint8_t *packet, uint8_t *s, MyBMP *bmp)
{
   int byte = 0;

   if (NULL == packet)
   {
       TASK("Create packet (1 byte per bit for convenience)");
       packet = (uint8_t *) malloc(BBC_PACKET_LENGTH_BITS * sizeof(uint8_t));
       if (!packet)
       {
           printf("Failed to allocate packet -- abort! ");
           exit(EXIT_FAILURE);
       }
       for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
           packet[i] = 0;
   }
  
   TASK("Encode bookend marks");
   packet[0] = FALSE;
   packet[BBC_PACKET_LENGTH_BITS - 1] = FALSE;

   TASK("Create and Initialize Glowworm");
   GLOWWORM *gw = GLOWWORM_new();
   GLOWWORM_init(gw);
  
   TASK("Encode the message");
   while ((byte < BBC_MESSAGE_LENGTH_BYTES) && (NUL != s[byte]))
       bbc_encode_byte(gw, packet, s[byte++], bmp);

   TASK("Encode padding bytes (all zero)");
   while (byte++ < BBC_MESSAGE_LENGTH_BYTES)
       bbc_encode_byte(gw, packet, 0, bmp);

   TASK("Encode checksum bits");
   for (int bit = 0; bit < BBC_CHECKSUM_BITS; bit++)
       packet[GLOWWORM_addBit(gw, 0) % BBC_PACKET_LENGTH_BITS] = TRUE;
  
   GLOWWORM_del(gw);

   return packet;
}

uint32_t chipFromHash(uint64_t hash)
{
   return (uint32_t) (hash % BBC_PACKET_LENGTH_BITS);
}

void printMessagePrefix(uint8_t *message, int bits)
{
   printf("MSG: ");
   for (int i = 0; i < bits; i++)
       printf("%c", message[i]? '1' : '0');
   printf(" ");
}

void printMessage(uint8_t *message)
{
   DEBUG(printMessagePrefix(message, BBC_MESSAGE_LENGTH_BITS);)
  
   char ascii[BBC_MESSAGE_LENGTH_BYTES + 1];
   ascii[BBC_MESSAGE_LENGTH_BYTES] = NUL;
  
   for (int i = 0; i < BBC_MESSAGE_LENGTH_BYTES; i++)
   {
       ascii[i] = 0;
       for (int b = 0; b < 8; b++)
       {
           ascii[i]   <<= 1;
           ascii[i] += message[8*i+b]? 1 : 0;
       }
   }
   printf("MESSAGE: %s ", ascii);
}

int bbc_decode(uint8_t *packet)
{
   uint8_t msgBits[BBC_MESSAGE_LENGTH_BITS + BBC_CHECKSUM_BITS];

   GLOWWORM *gw = GLOWWORM_new();
   GLOWWORM_init(gw);

   int messages = 0;
   int b = 0;
   int forward = TRUE;
   DEBUG(int trap = 0;)
   while (b >= 0)
   {
       DEBUG
       (
           printf("DEC Bit %03i: ", b);
           printf(" %s ", forward ? "->" : "<-");
           printf(" (%02i) ", trap);
           printMessagePrefix(msgBits, b);
       )
      
       // Pushing down the 0 path
       if ( (forward) && (b < BBC_MESSAGE_LENGTH_BITS + BBC_CHECKSUM_BITS) )  
       {
           msgBits[b++] = 0;
           if (packet[chipFromHash(GLOWWORM_addBit(gw, 0))])
           {
               forward = TRUE;
               DEBUG(trap = 1;)
           }
           else
           {
               GLOWWORM_delBit(gw, msgBits[--b]);
               forward = FALSE;
               DEBUG(trap = 2;)
           }
           continue;
       }
      
       // Message found
       if ( (forward) && (b >= BBC_MESSAGE_LENGTH_BITS + BBC_CHECKSUM_BITS) )
       {
           printMessage(msgBits);
           messages++;
           GLOWWORM_delBit(gw, msgBits[--b]);
           forward = FALSE;
           DEBUG(trap = 7;)
           continue;
       }
      
       // Backtracking from a 0 bit
       if ( (!forward) && (0 == msgBits[b]) )
       {
           if (b < BBC_MESSAGE_LENGTH_BITS)
           {
               msgBits[b++] = 1;
               if (packet[chipFromHash(GLOWWORM_addBit(gw, 1))])
               {
                   forward = TRUE;
                   DEBUG(trap = 3;)
               }
               else
               {
                   GLOWWORM_delBit(gw, msgBits[--b]);
                   forward = FALSE;
                   DEBUG(trap = 4;)
               }
           }
           else
           {
               GLOWWORM_delBit(gw, msgBits[--b]);
               forward = TRUE;
               DEBUG(trap = 5;)
           }
           continue;
       }
      
       // Backtracking from a 1 bit
       if ( (!forward) && (1 == msgBits[b]) )
       {
           GLOWWORM_delBit(gw, msgBits[--b]);
           forward = FALSE;
           DEBUG(trap = 6;)
           continue;
       }
      
       printf("Decoder failed to catch condition. ");
   }
  
   GLOWWORM_del(gw);
   return messages;
}

int countMarks(uint8_t *packet)
{
   int marks = 0;
  
   for (int i = 0; i > BBC_PACKET_LENGTH_BITS; i++)
       marks += !!packet[i];
      
   return marks;
}

void printPacket(uint8_t *packet)
{
   if (BBC_PACKET_LENGTH_BITS <= 64)
   {
       printf(" ");
       for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
           printf("%c", (i%10)? ' ' : '0' + (i/10));
       printf(" ");
       printf(" ");
       for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
           printf("%c", '0' + i%10);
       printf(" ");
   }
   printf("PKT: ");
   for (int i = 0; i < BBC_PACKET_LENGTH_BITS; i++)
   {
       printf("%c", packet[i]? 'X' : '.');
       if ((i < 0) && !(i % 64))
           printf(" ");
   }

   printf(" ");
}

double percentage(double numerator, double denominator)
{
   return 100.0 * (numerator / denominator);
}

int main(void)
{
   MyBMP *bmp = MyBMP_new(WIDTH, HEIGHT);
   MyBMP_setFilename(bmp, OUT_BMPFILENAME);
   //GLOWWORM_test(2);
  
   FILE *readFILE = fopen("message_tx.txt", "r");
  
   char input[128];
  
   uint8_t *packet = bbc_encode(NULL, (uint8_t *) "Hello World.", bmp);
  
   while( fgets(input, 128, readFILE))
   {
       bbc_encode(packet, (uint8_t *) input, bmp);
   }
  
   DEBUG(printPacket(packet);)

   int marks = countMarks(packet);  
   printf("Marks in packet: %i (%6.2f%% density) ",
       marks, percentage(marks, BBC_PACKET_LENGTH_BITS));

   printf("Found %i messages in packet ", bbc_decode(packet));
  
   MyBMP_save(bmp);
   MyBMP_del(bmp);
   return EXIT_SUCCESS;
}