Search code examples
cimagejpegrecoverycs50

cs50 pset5 why does my image recovery program only recover 49 of 50 images?


So my recover.c program works well, except for the fact that it fails to recover ALL 50 images from the card.raw file.

I can only get it to recover 49 of the 50 images. I'm pretty sure the missing image is the very first image (a girl with in a snowy background) because I saw that image early on in the process of writing and testing but the final program doesnt seem to recover that image anymore.

Any help guys?

  /**
 * recover.c
 *
 * Computer Science 50
 * Problem Set 4
 *
 * Recovers JPEGs from a forensic image.
 */

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

typedef uint8_t  BYTE;
typedef uint32_t DWORD;
typedef int32_t  LONG;
typedef uint16_t WORD;

typedef struct
{
    BYTE  rgbtBlue;
    BYTE  rgbtGreen;
    BYTE  rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;



int main(void)
{
    // OPEN CARD FILE
    char* infile = "card.raw";

    FILE* card = fopen(infile, "r");
    if (card == NULL)
    {
        printf("Could not open %s.\n", "card.raw");
        return 2;
    }

    int f = 0, c = 0, imageno = 0;
    // c signals that a jpg is being written
    FILE* images;
    char title[25];
    BYTE buffer[512];

    /*repeat until end of card*/
    do
    {
        //read one block into buffer

        fread(buffer, 512, 1, card);

        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff)
        {
            if (imageno < 10)
            {
                sprintf(title, "00%d.jpg", imageno); //change jpg title
            }
            else
            {
                sprintf(title, "0%d.jpg", imageno); //change jpg title
            }

            if (f == 1) //close previous jpg
            {
                fclose(images);
                imageno++;
            }

            images = fopen(title, "w");
            f = 1; //very first jpg has been opened
            c = 1; //jpg open
        }
        //jpg already open?
        if (c == 1) fwrite(buffer, 512, 1, images);
    }    
    while (!feof(card));
    return 0;
        //close any remaining files
}

Solution

  • You create a file name based on the value of variable imageno. You later increment that variable, but only in the event that that your program opened another file previously. In particular, you do not increment it after opening the very first file, therefore the same name is computed for the second file as was computed for the first, and the first file extracted gets overwritten.

    You should unconditionally increment imageno each time you create a new file name, or maybe each time you open a file.