Reputation: 19
I am working on the Recover assignment of the CS50 course.
Getting the error : The recovered image does not match (from the CS50 error checker). In other words, I successfully recover 50/50 JPGs, but they are all just blank white
Can't seem to figure out where the problem lies.
Tried refactoring the code a bit, but honestly im at a loss. I know it must have something to do with handling the multi-block files, but maybe im missing something even more fundamental. CS50 has been my first foray into C so I would appreciate as much elaboration as possible.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Please add exactly one command line argument!");
return 1;
}
FILE *card = fopen(argv[1], "r");
char *filename = malloc(8);
FILE *img = NULL;
int numOfImgs = 0;
if (card == NULL)
{
printf("Could not access memory card.\n");
return 1;
}
uint8_t buffer[512];
while (fread(buffer, 1, 512, card) == 512)
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0) {
if (img == NULL) {
sprintf(filename, "%03i.jpg", numOfImgs);
img = fopen(filename, "w");
fwrite(buffer, 1, 512, img);
}
else {
fclose(img);
sprintf(filename, "%03i.jpg", numOfImgs);
img = fopen(filename, "w");
fwrite(buffer, 1, 512, img);
}
numOfImgs++;
}
}
fclose(img);
fclose(card);
free(filename);
return 0;
}
Upvotes: 1
Views: 58
Reputation: 24726
The assignment states the following:
Realize, of course, that JPEGs can span contiguous blocks. Otherwise, no JPEG could be larger than 512 B.
It appears that you are incorrectly assuming that a JPEG file will never consist of more than a single 512-byte block.
You are only writing the first 512 byte block of every recovered file to the output JPEG files. You are discarding all subsequent blocks, which is wrong.
The "walkthrough video" of the assignment contains a description of the algorithm you can use so that the subsequent blocks also get written to the JPEG output files.
As a side note, I would also like to point out that the lines
if (img == NULL) {
sprintf(filename, "%03i.jpg", numOfImgs);
img = fopen(filename, "w");
fwrite(buffer, 1, 512, img);
}
else {
fclose(img);
sprintf(filename, "%03i.jpg", numOfImgs);
img = fopen(filename, "w");
fwrite(buffer, 1, 512, img);
}
can be changed to:
if (img != NULL) {
fclose(img);
}
sprintf(filename, "%03i.jpg", numOfImgs);
img = fopen(filename, "w");
fwrite(buffer, 1, 512, img);
Performing this code change won't change the behavior of your program, but it will get rid of three lines of unnecessary code duplication.
Upvotes: 1