-
-
Save CraigRodrigues/8f831e9ea1003d9ad14f608d24cc1ba3 to your computer and use it in GitHub Desktop.
/** | |
* recover.c | |
* | |
* Computer Science 50 | |
* Problem Set 4 | |
* | |
* Recovers JPEGs from a forensic image. | |
*/ | |
#include <cs50.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define BUFFER_SIZE 512 | |
int main(void) | |
{ | |
// open memory card file | |
FILE* input = fopen("card.raw", "r"); | |
if (input == NULL) | |
{ | |
printf("Could not open card.raw.\n"); | |
return 2; | |
} | |
// create buffer | |
unsigned char buffer[BUFFER_SIZE]; | |
// filename counter | |
int filecount = 0; | |
FILE* picture = NULL; | |
// check if we've found a jpeg yet or not | |
int jpg_found = 0; //false | |
// go through cardfile until there aren't any blocks left | |
while (fread(buffer, BUFFER_SIZE, 1, input) == 1) | |
{ | |
// read first 4 bytes of buffer and see if jpg signature using bitwise on last byte | |
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xe0) == 0xe0) | |
{ | |
if (jpg_found == 1) | |
{ | |
// We found the start of a new pic so close out current picture | |
fclose(picture); | |
} | |
else | |
{ | |
// jpg discovered and now we have the green light to write | |
jpg_found = 1; | |
} | |
char filename[8]; | |
sprintf(filename, "%03d.jpg", filecount); | |
picture = fopen(filename, "a"); | |
filecount++; | |
} | |
if (jpg_found == 1) | |
{ | |
// write 512 bytes to file once we start finding jpgs | |
fwrite(&buffer, BUFFER_SIZE, 1, picture); | |
} | |
} | |
// close files | |
fclose(input); | |
fclose(picture); | |
return 0; | |
} |
It is to allocate enough characters to write "###.jpg". Since a string like this needs a null character, in the end, it is 8 along with 7 characters of ###.jpg.
hello! could you please explain why the first fread uses buffer while the next fread at the end uses &buffer instead? thank you!
Hey there! How are you using jpg_found? Cuz you have initialised it to ''0'' and haven't incremented it anywhere. Thanks!
Hey there! How are you using jpg_found? Cuz you have initialised it to ''0'' and haven't incremented it anywhere. Thanks!
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xe0) == 0xe0)
{
if (jpg_found == 1)
{
// We found the start of a new pic so close out current picture
fclose(picture);
}
else
{
// jpg discovered and now we have the green light to write
jpg_found = 1;
This else condition sets jpg_found = 1. In this problem, as all the jpegs are back-to-back we never expect a blank space where a different file might be so once we've found the first jpeg we can just carry on until the end of the file, writing a new file everytime we discover a new jpg.
why the &buffer ?
hello! could you please explain the thought process used to create the if else statements in your while loop
Could you please explain here why the 3 argument is 1, and why we have == 1?
while (fread(buffer, BUFFER_SIZE, 1, input) == 1)
Why can't I use fclose(picture) after fwrite?
jpg_found will always be = 1 after find the "magical numbers", isn't? So, can't I avoid if-else in any way?
PS: Oh, I got it, a picture only should be fclosed when another is found!
char filename[8];
Hi, could you please explain why it is '8'? Thanks in advance
to create memory space for the filename
why is while(........ = 1 ) for fread
why is while(........ = 1 ) for fread
to stop executing if it didn't find block of 512 bytes in the memory
why is while(........ = 1 ) for fread
to stop executing if it didn't find block of 512 bytes in the memory
Does this mean something like "while fread is true: ..." ?
Why do you need the cs50 library
hello! could you please explain why the first fread uses buffer while the next fread at the end uses &buffer instead? thank you!
Hey nice work! You could also avoid the boolean flag just by checking the image file! if it is NULL then you can start writing, otherwise you close the file and create a new image! just to simplify the code!
~/pset4/recover/ $ ./a.out
Could not open card.raw.
someone help!
@Student3153 Are you using this code?
Hey, thank you for sharing your solution. Can you please explain to me, why in line 60 another if statement is needed? I would have used else, however, that does not work and it is giving me segmentation faults.
Thank you.
Hey, thank you for sharing your solution. Can you please explain to me, why in line 60 another if statement is needed? I would have used else, however, that does not work and it is giving me segmentation faults.
The "if (jpg_found == 1)" in line 60 is used for writing the bytes on an already existing jpg file
the if condition in 43 checks if a new file was found so you cant use a else condition because the 43 and 60 works together
~/pset4/recover/ $ ./a.out
Could not open card.raw.
someone help!
you need to put your file's name as follow :
FILE* file = fopen("card.raw", "r");
@frjimbow I’m already done with the entire course
@frjimbow I’m already done with the entire course
sounds great. Have you become a professional developer ?
why the &buffer ?
just buffer is ok
hello,
if (jpg_found == 1) { // We found the start of a new pic so close out current picture fclose(picture); }
i delete and it s work,
why it s important these lines
i think we close already here
// close files
fclose(input);
fclose(picture);
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define BLK_SIZE 512
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not be opened %s\n", argv[1]);
return 1;
}
FILE *output = NULL;
int imgcount = 0;
BYTE bytes[BLK_SIZE];
while(fread(bytes, sizeof(BYTE), BLK_SIZE, input) || feof(input))
{
if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff && (bytes[3] & 0xf0) == 0xe0)
{
if (output != NULL)
{
fclose(output);
}
char filename[8];
sprintf(filename, "%03i.jpg", imgcount);
output = fopen(filename, "w");
imgcount++;
}
if(output!=NULL)
{
fwrite(bytes, sizeof(BYTE), 1, output);
}
}
if (input == NULL)
{
fclose(input);
}
if(output == NULL)
{
fclose(output);
}
return 0;
}
:) recover.c exists.
:) recover.c compiles.
:) handles lack of forensic image
:( recovers 000.jpg correctly
timed out while waiting for program to exit
:( recovers middle images correctly
timed out while waiting for program to exit
:( recovers 049.jpg correctly
timed out while waiting for program to exit
can someone help me understand whats going on?
Thank you :)
Hello,
The following code is not working, could you please help?
Results :
:) 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
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#define BLOCK 512
#define FILENAME_LENGTH 8
bool isJPEG(unsigned char buffer[]){
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
return true;
}
return false;
}
int main(int argc, char *argv[])
{
//argv[1]
FILE *inFile = fopen(argv[1], "rb");
if (argc != 2)
{
return 1;
}
if (argv[1] == NULL)
{
fprintf(stderr, "Usage: ./recover image");
return 1;
}
//each JPEG file start with a distinct header
//all first 3 bytes in JPEG files are the same : 0xff - 0xd8 - 0xff
// the fourth byte : 0xe0, 0xe1, 0xe2, ...., or 0xef
//the JPEG files are stored back to back in the memory card
//each block is 512 bytes
int count = 0;
unsigned char buffer[BLOCK];
bool found = false;
FILE *outFile;
//read until the end
while (fread(buffer, sizeof(buffer), 1, inFile) == 1)
{
if (isJPEG(buffer) == true)
{
if (found == true)
{
// Close outfile
fclose(outFile);
}
else
{
found = true;
}
char outFileName[FILENAME_LENGTH];
sprintf(outFileName, "%03i.jpg", count);
outFile = fopen(outFileName, "wb");
count++;
if (found == true)
{
if (fwrite(buffer, sizeof(buffer), 1, outFile) != 1)
{
fprintf(stderr, "error writing");
}
}
}
}
fclose(outFile);
fclose(inFile);
return 0;
}
Thanks!
hello! could you please explain why the first fread uses buffer while the next fread at the end uses &buffer instead? thank you!
Hi, I had the same doubt. i guess this will help you out, after a bit research i found this answer helpful.
https://stackoverflow.com/a/53471904
why the &buffer ?
it is useless since the buffer array is already a pointer holding the address of the first element in it
Thanks a lot!
char filename[8];
Hi, could you please explain why it is '8'? Thanks in advance