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

Write a program that reads a BMP file (formatted as specified in PR01) and decod

ID: 3820929 • Letter: W

Question

Write a program that reads a BMP file (formatted as specified in PR01) and decodes it. The output should be written to the file message_rx.txt with one message per line.

pic to decode

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

#include "MyBMP.h"

#define OUT_BMPFILENAME "HW06_PR01.bmp"

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

#define BBC_PACKET_LENGTH_BYTES (1024)
#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 WIDTH (640)
#define HEIGHT (480)

#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;
       if (!!bitValue == 1){
           MyBMP_drawPixel(bmp, chip/WIDTH, chip%WIDTH, 0, 0, 0);
       //   MyBMP_drawPixel(bmp, chip%WIDTH, chip%HEIGHT, 255, 255, 255);
       //   MyBMP_drawCircle(bmp, chip%WIDTH, chip%HEIGHT, 5,
// 0, 0, 0, 1);
           printf("%i and %i ", chip/WIDTH, chip%WIDTH);
       }else {
           MyBMP_drawPixel(bmp, chip/WIDTH, chip%WIDTH, 255, 255, 255);
       }
       //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)
{
  
   BMP *bmp = BMP_open("HW06_PR01.bmp");
  
   // Get demisions
   int width = BMP_getWidth(bmp);
   int height = BMP_getHeight(bmp);
  
   // Go through each point
   for (int row = 0; row < height; row++)
       for (int col = 0; col < width; col++)
       {
           printf("Found %i messages in packet ", bbc_decode(col*width+height));
       }
   }
  
//   uint8_t *packet = bbc_encode(NULL, (uint8_t *) "Hello World mand ajkdjafl adfkjals adjfoiasdj diafojsdal iodajfalsk jfoiadjfla i afjoad flak ioajdlfkeo adjflasdk jodafj lfjdioajflwkae f", bmp);
//   bbc_encode(packet, (uint8_t *) "JAMMER", bmp);
  
   // Encode a packet having the leading bit set (results of printing unknown)
//   uint8_t msg[5] = {255,0};
//   bbc_encode(packet, (uint8_t *) msg, 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));
  
   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 BBC_PACKET_LENGTH_BYTES (1024)
#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 WIDTH (640)
#define HEIGHT (480)

#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;
       if (!!bitValue == 1){
           MyBMP_drawPixel(bmp, chip/WIDTH, chip%WIDTH, 0, 0, 0);
       //   MyBMP_drawPixel(bmp, chip%WIDTH, chip%HEIGHT, 255, 255, 255);
       //   MyBMP_drawCircle(bmp, chip%WIDTH, chip%HEIGHT, 5,
// 0, 0, 0, 1);
           printf("%i and %i ", chip/WIDTH, chip%WIDTH);
       }else {
           MyBMP_drawPixel(bmp, chip/WIDTH, chip%WIDTH, 255, 255, 255);
       }
       //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)
{
  
   BMP *bmp = BMP_open("HW06_PR01.bmp");
  
   // Get demisions
   int width = BMP_getWidth(bmp);
   int height = BMP_getHeight(bmp);
  
   // Go through each point
   for (int row = 0; row < height; row++)
       for (int col = 0; col < width; col++)
       {
           printf("Found %i messages in packet ", bbc_decode(col*width+height));
       }
   }
  
   return EXIT_SUCCESS;
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote