0

Can anybody tell why the code below does not produce 50 readable images? I used the debugger to run through it. From the outset it seemed to jump in and out the loops as I expected. However it i) produces only 25 jpegs and ii) the images are scrambled / do not make sense. For the first point I thought the problem would be that I only pick up 50% of jpegs by misstating half of the check for new images, but I cannot find any fault there. Any tips are much appreciated. Thanks! CB

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

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

int main(int argc, char* argv[])
{
    // open card file
    FILE* inptr = fopen("card.raw", "r");
    if (inptr == NULL)
    {
        printf("Could not open file\n");
        return 1;
    }

    // initialize jpeg counter at 0
    int jpg_no = 0;

    // initialize buffer
    uint8_t buffer[512];

    // initialize outfile
    FILE* img = NULL;

    // initialize title of image
    char title[8];

    // repeat until end of file
    do
    {    
        // read 512 byes into buffer
        fread(&buffer, 512, 1, inptr);

        // is it a new jpeg?
        if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff
        && (buffer[3] == 0xe0 || buffer[3] == 0xe1))
        {
            // if 1st file, then open 1st file
            if(jpg_no == 0)
            {
                sprintf(title, "%03d.jpg", jpg_no);
                img = fopen(title, "a");
            }

            // else close previous file and open new one
            else
            {
                fclose(img);
                sprintf(title, "%03d.jpg", jpg_no);
                img = fopen(title, "a");
            }

            // update the jpeg counter
            jpg_no++;
        }

        // already found a jpeg?
        if(jpg_no > 0)
        {
            // write to open jpeg
            fwrite(&buffer, sizeof(buffer), 1, img);
        }
    }

    // while sizeof buffer = 512
    while(fread(&buffer, 512, 1, inptr) == 1);

    // close remaining files
    fclose(img);
    fclose(inptr);

    // the end
    printf("recovery completed\n");
    return 0;
}
0

Simply put, the code is throwing away every other 512 byte block. The code has two sequential fread() calls, one at the top of the do/while loop and another in the while statement itself. Effectively, it processes the first fread inside the loop and processes the data. It then executes the fread at the while statement, and then immediately executes another fread at the top of the loop again without doing anything with the while statement's fread data. So while it looks like there's all that code between them, they are executing one right after the other. This is throwing away half of the image data and missing half of the signature blocks.

An fread() in a while statement isn't just a test for EOF. It will actually execute the fread() call!

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

1
  • Thanks Cliff! I now first tried an feof check. However that messed up the last jpeg. Now I figured out how to put the read statement in the while condition :). It works!
    – CB Nuji
    May 16 '16 at 20:42

You must log in to answer this question.

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