Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

The following code does not work properly, please modify it. -------------------------------------------- #include #include #include #include /* The RGB values of a pixel. */ struct Pixel

The following code does not work properly, please modify it.

--------------------------------------------

#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;

struct Comment *comments;

};

struct Comment {

char *text;

struct Comment *next;

};

/* 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;

char buffer[256];

struct Comment *comments = NULL;

while (fgets(buffer, sizeof(buffer), f) != NULL) {

if (buffer[0] == '#') {

// add a new comment

struct Comment *comment = malloc(sizeof(struct Comment));

comment->text = strdup(buffer + 1); // skip the "#" character

comment->next = comments;

comments = comment;

} else {

// parse the header

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

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

return NULL;

}

break; // stop reading the header

}

}

if (comments != NULL) {

// reverse the linked list of comments to keep them in the original order

struct Comment *prev = NULL;

struct Comment *curr = comments;

while (curr != NULL) {

struct Comment *next = curr->next;

curr->next = prev;

prev = curr;

curr = next;

}

comments = prev;

}

// allocate memory for the PPM image data

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

img->width = width;

img->height = height;

img->max = max;

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

img->comments = comments;

// read the pixel data

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

if (fscanf(f, "%d %d %d", &img->pixels[i].red, &img->pixels[i].green, &img->pixels[i].blue) != 3) {

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

freePPM(img);

return NULL;

}

}

return img;

}

/* 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);

}

}

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;

}

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;

}

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]);

char message[256];

printf("Enter a message to encode: ");

scanf("%255[^ ]", message); // read up to 255 characters until a newline is encountered

/* Check that the message length is not too long */

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

if (pixels_per_char < 3) {

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

return 1;

}

if (pixels_per_char * (strlen(message) + 1) > oldimg->width * oldimg->height) {

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

return 1;

}

struct PPM *newimg = encode(message, oldimg);

if (newimg == NULL) {

fprintf(stderr, "Encoding failed ");

return 1;

}

free(newimg->pixels);

free(newimg);

free(oldimg->pixels);

free(oldimg);

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

/* Mode "d" - decode PPM */

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

struct PPM *newimg = readPPM(argv[3]);

char *message = decode(oldimg, newimg);

if (message == NULL) {

fprintf(stderr, "Decoding failed ");

return 1;

}

printf("Decoded message: %s ", message);

free(message);

free(newimg->pixels);

free(newimg);

free(oldimg->pixels);

free(oldimg);

} else {

fprintf(stderr, "Usage: %s t|e|d [filename2] ", argv[0]);

return 1;

}

void showPPMComments(const struct PPM *img)

{

struct Comment *comment = img->comments;

while (comment != NULL) {

printf("#%s", comment->text);

comment = comment->next;

}

}

return 0;

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Intelligent Information And Database Systems Asian Conference Aciids 2012 Kaohsiung Taiwan March 2012 Proceedings Part 2 Lnai 7197

Authors: Jeng-Shyang Pan ,Shyi-Ming Chen ,Ngoc-Thanh Nguyen

2012th Edition

3642284892, 978-3642284892

More Books

Students also viewed these Databases questions

Question

internationalization of business?

Answered: 1 week ago