In: Computer Science
Write a program that reads the messages contained in the file message_tx.txt into a 640x480 BMP file named bbc_packet.bmp. Each line in the text file should be treated as a separate message.
#include "dirtyd.h"
#include "GLOWWORM.h"
#include "MyBMP.h"
#define OUT_BMPFILENAME "HW06_PR01.bmp"
#include
#include
#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\n", (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)\n",
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\n", 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!\n");
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("\n");
}
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\n", 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.\n");
}
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("\n");
printf(" ");
for (int i = 0; i <
BBC_PACKET_LENGTH_BITS; i++)
printf("%c", '0'
+ i%10);
printf("\n");
}
printf("PKT: ");
for (int i = 0; i < BBC_PACKET_LENGTH_BITS;
i++)
{
printf("%c", packet[i]? 'X' :
'.');
if ((i > 0) && !(i %
64))
printf("\n
");
}
printf("\n");
}
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)\n",
marks, percentage(marks,
BBC_PACKET_LENGTH_BITS));
printf("Found %i messages in packet\n",
bbc_decode(packet));
MyBMP_save(bmp);
MyBMP_del(bmp);
return EXIT_SUCCESS;
}
#include "dirtyd.h"
#include "GLOWWORM.h"
#include "MyBMP.h"
#define OUT_BMPFILENAME "HW06_PR01.bmp"
#include
#include
#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\n", (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)\n",
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\n", 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!\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i <
BBC_PACKET_LENGTH_BITS; i++)
packet[i] =
0;
}