Question: Complete the following code fill ALL THET ODO ========================================= #include #include #include #include /* The RGB values of a pixel. */ struct Pixel { int

Complete the following code fill ALL THET ODO

=========================================

#include

#include

#include

#include

/* The RGB values of a pixel. */

struct Pixel {

int red;

int green;

int blue;

};

/* An image loaded from a PPM file. */

struct PPM {

int width;

int height;

int max;

struct Pixel *pixels;

};

/* Reads an image from an open PPM file.

* Returns a new struct PPM, or NULL if the image cannot be read. */

struct PPM *getPPM(FILE * f)

{

int width, height, max;

if (fscanf(f, "P3 %d %d %d ", &width, &height, &max) != 3) {

fprintf(stderr, "Error reading PPM header ");

return NULL;

}

}

/* Write img to stdout in PPM format. */

void showPPM(const struct PPM *img)

{

printf("P3 %d %d %d ", img->width, img->height, img->max);

for (int i = 0; i < img->width * img->height; i++) {

printf("%d %d %d ", img->pixels[i].red, img->pixels[i].green, img->pixels[i].blue);

}

}

/* Opens and reads a PPM file, returning a pointer to a new struct PPM.

* On error, prints an error message and returns NULL. */

struct PPM *readPPM(const char *filename)

{

/* Open the file for reading */

FILE *f = fopen(filename, "r");

if (f == NULL) {

fprintf(stderr, "File %s could not be opened. ", filename);

return NULL;

}

/* Load the image using getPPM */

struct PPM *img = getPPM(f);

/* Close the file */

fclose(f);

if (img == NULL) {

fprintf(stderr, "File %s could not be read. ", filename);

return NULL;

}

return img;

}

/* Encode the string text into the red channel of image img.

* Returns a new struct PPM, or NULL on error. */

struct PPM *encode(const char *text, const struct PPM *img)

{

int text_len = strlen(text);

int pixels_per_char = (img->width * img->height) / (text_len + 1);

if (pixels_per_char < 3) { // at least 3 pixels per character to encode

fprintf(stderr, "Image too small to encode message ");

return NULL;

}

if (pixels_per_char * (text_len + 1) > img->width * img->height) { // message too long to encode

fprintf(stderr, "Message too long to encode in image ");

return NULL;

}

struct PPM *newimg = malloc(sizeof(struct PPM));

newimg->width = img->width;

newimg->height = img->height;

newimg->max = img->max;

newimg->pixels = malloc(newimg->width * newimg->height * sizeof(struct Pixel));

memcpy(newimg->pixels, img->pixels, newimg->width * newimg->height * sizeof(struct Pixel));

srand(time(NULL));

for (int i = 0; i < text_len; i++) {

int j = i * pixels_per_char + rand() % pixels_per_char;

newimg->pixels[j].red = (unsigned char)

text[i];

}

return newimg;

}

/* Extract the string encoded in the red channel of newimg, by comparing it

* with oldimg. The two images must have the same size.

* Returns a new C string, or NULL on error. */

char *decode(const struct PPM *oldimg, const struct PPM *newimg)

{

int pixels_per_char = (oldimg->width * oldimg->height) / (strlen(MESSAGE) + 1);

int max_msg_len = pixels_per_char - 1; // maximum length of message that can be encoded in one group of pixels

char *msg = malloc(max_msg_len * (strlen(MESSAGE) + 1) + 1); // allocate space for the decoded message

int msg_idx = 0;

for (int i = 0; i < strlen(MESSAGE); i++) {

int j = i * pixels_per_char + rand() % pixels_per_char;

char c = newimg->pixels[j].red ^ oldimg->pixels[j].red; // decode the character by XORing the red values

if (c == '\0') { // end of message reached

break;

}

if (msg_idx >= max_msg_len * (strlen(MESSAGE) + 1)) { // message too long to decode

fprintf(stderr, "Message too long to decode ");

free(msg);

return NULL;

}

msg[msg_idx++] = c;

}

msg[msg_idx] = '\0'; // null-terminate the message

return msg;

}

/* TODO: Question 3 */

int main(int argc, char *argv[])

{

/* Initialise the random number generator, using the time as the seed */

srand(time(NULL));

/* Parse command-line arguments */

if (argc == 3 && strcmp(argv[1], "t") == 0) {

/* Mode "t" - test PPM reading and writing */

struct PPM *img = readPPM(argv[2]);

showPPM(img);

} else if (argc == 3 && strcmp(argv[1], "e") == 0) {

/* Mode "e" - encode PPM */

struct PPM *oldimg = readPPM(argv[2]);

/* TODO: prompt for a message from the user, and read it into a string */

struct PPM *newimg;

/* TODO: encode the text into the image with encode, and assign to newimg */

/* TODO: write the image to stdout with showPPM */

} else if (argc == 4 && strcmp(argv[1], "d") == 0) {

/* Mode "d" - decode PPM */

struct PPM *oldimg;

/* TODO: get original file filename from argv, load it with

readPPM, then assign to oldimg */

struct PPM *newimg;

/* TODO: get encoded file filename from argv, load it with

readPPM, then assign to newimg */

char *message;

/* TODO: decode the encodedPPM with the comparisonPPM and assign to message */

/* TODO: print the decoded message to stdout */

} else {

fprintf(stderr, "Unrecognised or incomplete command line. ");

return 1;

}

return 0;

}

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!