ccs50recover

recover problem: file format not supported error


I'm trying to solve this problem which consists of reading data from a "memory card" and write it into new readable jpg files.

I'm getting 50 files named correctly as far as I can tell but their data is incorrect. to me it looks like it should be writing into each jpg the data read into the buffer from the card or argv[1] but I'm guessing I'm missing something and I can't figure out what. this is what I wrote so far:


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint8_t BYTE;

int is_jpg(BYTE(buffer[]))
{
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xe0) == 0xe0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main(int argc, char *argv[])
{
    BYTE buffer[512];

    //checks argument validity
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }

    FILE *file = fopen(argv[1], "r");
    //printf("continuing program\n");

    //checks if the file exists
    if (file == NULL)
    {
        printf("No file found\n");
        return 2;
    }

    int file_count = 0;
    char file_name[8];
    //sprintf(file_name,  "%03d.jpg", file_count);
    FILE *image;

    while (fread(buffer, 512, 1, file) == 1)
    {
        if (is_jpg(buffer) == 1)
        {
            if (file_count != 0)
            {
                fclose(image);
            }
            sprintf(file_name,  "%03d.jpg", file_count);
            image = fopen(file_name, "w");
            fread(&buffer, 512, 1 , file);
            fwrite(&buffer, 512, 1, image);
            file_count++;
        }
        else if (file_count > 0)
        {
               fwrite(buffer, 512, 1, image);
        }
        //fwrite(&buffer, 512, 1, image);
    }
}

Solution

  • When you detect the header, you do an extra fread [after the image = fopen(file_name, "w"); call].

    You want to write the header to the output file/stream. But, the extra fread trashes the header data and the first block of the file is data and not the header as you desire.

    You only want the fread at the top of the loop.