Skip to content

Instantly share code, notes, and snippets.

@CraigRodrigues
Created July 7, 2016 16:50
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save CraigRodrigues/8f831e9ea1003d9ad14f608d24cc1ba3 to your computer and use it in GitHub Desktop.
Save CraigRodrigues/8f831e9ea1003d9ad14f608d24cc1ba3 to your computer and use it in GitHub Desktop.
CS50 pset4 - "Recover"
/**
* 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;
}
@ushiradineth
Copy link

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

@frjimbow
Copy link

frjimbow commented Dec 11, 2020

~/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");

@Student3153
Copy link

@frjimbow I’m already done with the entire course

@frjimbow
Copy link

@frjimbow I’m already done with the entire course

sounds great. Have you become a professional developer ?

@recepkrty
Copy link

why the &buffer ?

just buffer is ok

@Caroline-100
Copy link

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

@atifali10
Copy link

#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 :)

Copy link

ghost commented Apr 8, 2021

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!

@ShivangM
Copy link

ShivangM commented Oct 3, 2021

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

@Seif2005
Copy link

why the &buffer ?

it is useless since the buffer array is already a pointer holding the address of the first element in it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment