0
#include <stdio.h>      //call for sprintf()
#include <stdint.h>     //call for typedef uint8_t BYTE
#include <stdlib.h>     //call for sizeof() and NULL
typedef uint8_t BYTE;   //For declaring BYTE buffer[512]; or unsigned char buffer[512]; or uint8_t buffer[512];

int main(int argc, char *argv[])
{
    //ensuring 2 command line arguments, otherwise quit
    if (argc != 2)
    {
        printf("Usage; ./recover image\n");
        return 1;
    }

    //open file
    FILE*input = fopen(argv[1], "r");

    //check if is valid
    if (input == NULL)
    {
        printf("Could not open %s.\n", argv[1]);
        return 1;
    }

    BYTE buffer[512];       //create buffer array to store 512 bytes each block
    int count = 0;          //keep track of jpg file
    FILE*output = NULL;     //initialise file pointer to recover images
    char image_file[8];     //declare ###.jpg\0


    while (fread(buffer, sizeof(BYTE), 512, input))         //read 512 bytes into a buffer
    {
        //if block is beginned with jpg headers
        if (buffer[0]==0xff && buffer[1]==0xd8 && buffer[2]==0xff && (buffer[3] & 0xf0)==0xe0)  
        {
            sprintf(image_file, "%03i.jpg", count);         //should create jpg file in 000.jpg format
            count++;                                        //keep track of jpg file

            if (count == 1)                                 //if is first jpg file
            {
                output = fopen(image_file, "w");            //open file for writing
                fwrite(buffer, sizeof(BYTE), 512, output);  //start copy to output file
            }
            else
            {
                fclose(output);                             //if new jpg appeared, close current file
                output = fopen(image_file, "w");            //open file for writing
                fwrite(buffer, sizeof(BYTE), 512, output);  //start copy to output file
            }
        }
        //if block is not beginned with jpg headers
        else if (buffer[0]!=0xff || buffer[1]!=0xd8 || buffer[2]!=0xff || (buffer[3] & 0xf0)!=0xe0)     
        {
            if (count > 1)                                  //if is not first jpg file
            {
                fwrite(buffer, sizeof(BYTE), 512, output);  //keep writing to it and repeat multiple times
            }
        }
        fclose(input);                                      //close remaining files if end of file reached
        return 0;
    }
}
0

Are you sure about your diagnosis of the problem?

Once I moved the fclose and return statements outside the for loop, it produced the correct number of files. Further, it seems that only the first file was corrupted.

Perhaps you have been editing the source code but forgetting to recompile it?

I'll let you try again to fix it first, or to edit the question with a more accurate description of the problems.

1
  • When I run "ls", what to be listed out are 000.jpg to 026.jpg, so I tried to click one of the jpg files, opened with blank box at the end. After I posted this questions, I was continue trying different approach, at the end, I noticed that I missed one step right before fclose(output), which is else { jpg_found = 1;}, if(jpg_found == 1), and else if(jpg_found == 1). Then by accident, it worked. – Bon Dec 31 '20 at 13:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .