cs50 recover(pset4) doesn not recover correct images - c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc < 2 || argc > 2)
{
printf("Usage: ./recover IMAGE\n");
return 1;
}
FILE *file = fopen(argv[1], "r");
if (file == NULL)
{
printf("Could not open file.\n");
return 1;
}
char filename[8];
BYTE arr1[512];
int count = 0;
int i = 0;
FILE *img;
while (fread(arr1, sizeof(BYTE), 512, file) != 0)
{
if (arr1[0] == 0xff && arr1[1] == 0xd8 && arr1[2] == 0xff && (arr1[3] & 0xf0) == 0xe0 && count == 0)
{
sprintf(filename, "%03i.jpg", count);
count++;
img = fopen(filename, "w");
fwrite(arr1, sizeof(BYTE), 512, img);
}
else if (arr1[0] != 0xff && arr1[1] != 0xd8 && arr1[2] != 0xff && (arr1[3] & 0xf0) != 0xe0 && count != 0)
{
fwrite(arr1, sizeof(BYTE), 512, img);
}
else if (arr1[0] == 0xff && arr1[1] == 0xd8 && arr1[2] == 0xff && (arr1[3] & 0xf0) == 0xe0 && count != 0)
{
fclose(img);
sprintf(filename, "%03i.jpg", count);
count++;
img = fopen(filename, "w");
fwrite(arr1, sizeof(BYTE), 512, img);
}
else
{
continue;
}
}
fclose(file);
}
My code correctly compiles and finds 50 images but says that images didn't match and says program isn't free of memory problems, can somebody help me with debugging?
check50 says
:) recover.c exists.
:) recover.c compiles.
:) handles lack of forensic image
:( recovers 000.jpg correctly
recovered image does not match
:( recovers middle images correctly
recovered image does not match
:( recovers 049.jpg correctly
recovered image does not match
:| program is free of memory errors
can't check until a frown turns upside down

I could see two problems:
a) One reason for file content errors could be not opening the files in binary mode.
b) In this middle condition
else if (arr1[0] != 0xff && arr1[1] != 0xd8 && arr1[2] != 0xff && (arr1[3] & 0xf0) != 0xe0 && count != 0)
{
fwrite(arr1, sizeof(BYTE), 512, img);
}
you will refuse to write a data block if any of the signature bytes matches. They are allowed to: all must match for the signature block, but for a data block any of them can match: but not all them
This code simplifies the logic. There is absolutely no need to check for the header block three times, or write to the output in three different places.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define BLOCKSIZE 512 // don't repeat magic number
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{ // is simpler
printf("Usage: ./recover IMAGE\n");
return 1;
}
FILE *file = fopen(argv[1], "rb"); // use binary mode
if (file == NULL)
{
printf("Could not open input file.\n");
return 1;
}
char filename[8];
BYTE arr1[BLOCKSIZE];
int count = 0;
size_t bytes; // bytes read
FILE *img = NULL; // initialise
while ((bytes = fread(arr1, 1, BLOCKSIZE, file)) != 0)
{
if (arr1[0] == 0xff && arr1[1] == 0xd8 && arr1[2] == 0xff && (arr1[3] & 0xf0) == 0xe0 && count == 0)
{
// header block detected
if (img != NULL)
{
fclose(img);
}
sprintf(filename, "%03d.jpg", count);
count++;
img = fopen(filename, "wb"); // use binary mode
if (img == NULL)
{
printf("Could not open output file %s\n", filename);
return 1;
}
}
if (img != NULL) // first block might not be a header
{
fwrite(arr1, 1, bytes, img); // do this once per loop
}
}
if (img != NULL)
{ // tidy up
fclose(img);
}
fclose(file);
}

Related

CS50 recover Pset4 does not pass check50

This program is designed to recover images from a digital camera SD card. The program is not passing the last three checks when I run it through check50. The program does not recover 000.jpg, middle image, and image 049.jpg. The error message indicated the program timed out while waiting for program to exit. The debugging tool has not been able to help me with this. Thank you for your help.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Buffer to store card data
// recover deleter images
int main(int argc, char *argv[])
{
// count is 2
if(argc < 2)
{
printf("usage: ./recover image.raw\n");
return 1;
}
// Read file
char *file = argv[1];
FILE *card = fopen(file, "r");
unsigned char* buffer = malloc(512);
// Check that file is valid
if (fopen(file, "r") == NULL)
{
printf("could not open %s.\n", file);
return 1;
}
char* filename = malloc(3 * sizeof(int));
//JPGs created
int img_count = 0;
int test_counter = 0;
FILE *img nodd= NULL;
// Read 512 chars
while (test_counter == 0)
{
fread(buffer, sizeof(char), 512, card);
// Detect JPEG
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] && 0xf0 == 0xe0)
{
// Write JPEG
sprintf(filename, "%0x3i.jpg", img_count);
img = fopen(filename, "w");
img_count++;
while (true)
{
fread(buffer, sizeof(char), 512, card);
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] && 0xf0 == 0xe0)
{
sprintf(filename, "%0x3i.jpg", img_count);
img = fopen(filename, "a");
img_count++;
test_counter++;
fwrite(buffer, sizeof(char), 512, img);
break;
}
else
{
fwrite(buffer, sizeof(char), 512, img);
break;
}
}
while (fread(buffer, sizeof(char), 512, card)!= 0)
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] && 0xf0 == 0xe0)
{
// Pointer for JPG created
fclose(img);
sprintf(filename, "%0x3i.jpg", img_count);
img = fopen(filename, "a");
img_count++;
}
fwrite(buffer, sizeof(char), 512, img);
}
}
free(buffer);
fclose(img);
return 0;
}

CS50 Retrieving blank images when writing program to recover jpgs

I am having trouble identifying why I am getting blank images when recovering jps for an assignment in CS50. I read the entire file, write whenever the start of a jpg file is found, and close whenever the end of a jpg file is found. I create the total of 50 images, but all of them are blank. Could someone help push me in the right direction?
This is my code:
const int BLOCK = 512;
uint8_t buffer[BLOCK];
char filename[50][8] = { };
int counter = 0;
while (fread(buffer, BLOCK, 1, input) == 1)
{
sprintf(&filename[counter][0], "%03i.jpg", counter);
FILE *img = fopen(&filename[counter][0], "w");
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer [2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
if ((buffer[511] & 0xf0) != 0xe0)
{
fwrite(buffer, BLOCK, 1, img);
counter++;
}
else
{
fclose(img);
}
}
}
I made the update here:
while (fread(buffer, BLOCK, 1, input) == 1)
{
sprintf(filename, "%03i.jpg", counter);
FILE *img = fopen(filename, "w");
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer [2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
if ((buffer[511] & 0xf0) != 0xe0)
{
fwrite(buffer, BLOCK, 1, img);
}
else
{
fclose(img);
counter++;
}
}
}
This question is now solved. My whole logic was flawed and I wasnt writing anything, I was just opening files. Bellow is my reworked code, its funny how overnight everything just clicked and was able to write it in like 10 minutes!
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
const int BLOCK = 512;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover card.raw\n");
return 1;
}
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
uint8_t buffer[BLOCK];
char filename[8] = { };
int counter = 0;
FILE *img;
while (fread(buffer, BLOCK, 1, input) == 1)
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer [2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
if (counter == 0)
{
fwrite(buffer, BLOCK, 1, img);
counter++;
}
else
{
fclose(img);
img = fopen(filename, "w");
fwrite(buffer, BLOCK, 1, img);
counter++;
}
}
else if (counter != 0)
{
fwrite(buffer, BLOCK, 1, img);
}
}
fclose(input);
fclose(img);
}

Does "if" Interrupt a "while" function?

I'm trying to solve the problem sets of CS50.
Task is, to recover jpegs from data.
My code produces jpegs, but it seems to take just one chunk of 512 bytes instead of the whole picture.
Does my "if" interrupt my "while" condition.
Here my code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
const int FAT_SIZE = 512;
typedef uint8_t FAT [FAT_SIZE];
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover card.raw\n");
return 1;
}
// Open files and determine scaling factor
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
FAT fats;
int number = 0;
char filename[8];
FILE *jpg;
// Going through the input file
while (fread(&fats, 512, 1, input))
{
if (fats[0] == 0xff && fats[1] == 0xd8 && fats[2] == 0xff && (fats[3] & 0xf0) == 0xe0)
{
if (number == 0)
{
sprintf(filename, "%03i.jpg" , 0);
jpg = fopen(filename, "w");
number++;
fwrite(&fats,512, 1, jpg);
} else {
fclose(jpg);
sprintf(filename, "%03i.jpg" , number);
number++;
jpg = fopen(filename, "w");
fwrite(&fats,512, 1, jpg);
}
}
}
fclose(input);
fclose(jpg);
return 0;
}
I found a solution , but I want to understand, why my code is wrong
I didnt write following code. It's written by JosephR , it's just for comparision.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
else
{
// Open card.raw
char *input_file_name = argv[1];
FILE *input_pointer = fopen(input_file_name, "r");
if (input_pointer == NULL)
{
printf("Error: cannot open %s\n", input_file_name);
return 2;
}
// Initialise variables
BYTE buffer[512];
int count = 0;
FILE *img_pointer = NULL;
char filename[8];
// Repeat until end of card:
while (fread(&buffer, 512, 1, input_pointer) == 1)
{
// If start of a new JPEG (0xff 0xd8 0xff 0xe*):
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
// If not first JPEG, close previous
if (!(count == 0))
{
fclose(img_pointer);
}
// Initialise file
sprintf(filename, "%03i.jpg", count);
img_pointer = fopen(filename, "w");
count++;
}
// If JPEG has been found, write to file
if (!(count == 0))
{
fwrite(&buffer, 512, 1, img_pointer);
}
}
fclose(input_pointer);
fclose(img_pointer);
return 0;
}
}

Segfault cs50 pset4 recover

I'm always getting a segfault when trying to run the code.
I think it is caused by the last lines fclose(file) and fclose(img), but I don't really seem to understand why exactly.
If I delete both lines nothing happens.
Could someone please explain to me why segfault is called and why it is not creating new .jpg's?
(I have to implement a program that recovers JPEGs from a forensic image)
https://cs50.harvard.edu/college/2020/fall/psets/4/recover/
#include <stdlib.h>
#include <stdint.h>
#include <cs50.h>
int main(int argc, char *argv[])
{
//open file
FILE *file = fopen(argv[1], "r");
//promting user
if(argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
else if (file == NULL)
{
printf("Empty file.\n");
return 2;
}
int i = 0;
int found = 0;
unsigned char buffer[512];
FILE *img = NULL;
while (fread(buffer, 512, 1, file))
{
//start of new Jpeg?
if (buffer[0] == 0xff && buffer[1] == 0xff && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
//close file if found
if(found == 1)
{
fclose(img);
}
// open new one
else
{
found = 1;
}
char filename[8];
sprintf(filename, "%03i.jpg", i);
img = fopen(filename, "w");
i++;
}
if(found == 1)
{
fwrite(buffer, 512, 1, img);
}
}
fclose(file);
fclose(img);
return 0;
}

CS50 pset4 Recover, got a segmentation error

I got a segmentation fault with this code. Can anyone help? I have tried a couple of ways but still could not solve the problem. I tried replacing FILE *img = NULL by FILE *img, but it gives another error said variable 'img' is uninitialized when used in fwrite(buffer, 512, 1, img)
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
//Open memory card
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
FILE *file = fopen(argv[1], "r");
if (!file)
{
return 1;
}
//Read 512 bytes into a buffer
int counter = 0;
unsigned char buffer[512];
char filename[8];
FILE *img = NULL;
while (fread(buffer, 512, 1, file) == 1)
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] && 0xf0 == 0xe0))
{
//If first JPEG
if (counter == 0)
{
//open a new file
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
//write the array into the new file
fwrite(buffer, 512, 1, img);
counter++;
}
//if not first JPEG
else
{
//close the file
fclose(img);
//open a new file
sprintf(filename, "%03i.jpg", counter);
img = fopen(filename, "w");
//write the array into the new file
fwrite(buffer, 512, 1, img);
counter++;
}
}
//Else, if already found new JPEG
else
{
fwrite(buffer, 512, 1, img);
}
}
//Close any remaining files
fclose(img);
fclose(file);
return 0;
}
When this if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] && 0xf0 == 0xe0)) is not true (as with the first read), what does program do?
This comment //Else, if already found new JPEG needs to be put into code; ie the following write needs to be conditional.

Resources