1

I have figured out a solution to recover, but my first attempt did not work. I'd like to understand a couple of things from my original attempt so I don't repeat the same errors in future code.

First, I originally declared buffer as type int. While the code compiled and ran, it created no jpgs. Changing the type to unsigned char fixed this issue, but I don't understand why the IF statement to check the first four bytes of buffer did not work when buffer was type int.

Second, after my do-while loop (I have since researched why this was a bad idea) I have an fseek to offset inptr back 512 bytes for the while loop. I did this because it was my understanding that the do-while loop would have incremented inptr on the iteration of the do-while loop just prior to breaking out, and I'd need to offset back for the main while loop. However, the code (once fixed for buffer type) creates the same 50 (scrambled) jpgs regardless of whether or not I include the fseek. Why do I not fail to (partially) recover every other jpg when the fseek is excluded?

Here is my code:

#include <stdio.h>


int main (int argc, char *argv[])
    {
    if (argc != 2)
    {
        fprintf(stderr, "Usage: ./recover infile\n");
        return 1;
    }

    char *infile = argv[1];
    FILE *inptr = fopen(infile, "r");

    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    unsigned char buffer[512] = {0};  //was originally int buffer[512] = {0};
    int counter = 0;
    char filename[8];

    while (fread(buffer, 1, 512, inptr) == 512)
    {
        if ((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0))
        {
            sprintf(filename, "%03i.jpg", counter);
            FILE *outptr = fopen(filename, "w");
            if (outptr == NULL)
            {
                fclose(inptr);
                fprintf(stderr, "Could not create %s.\n", filename);
                return 3;
            }
            counter++;
            do
            {
                fwrite(buffer, 1, 512, outptr);
                fread(buffer, 1, 512, inptr);
            }
            while ((buffer[0] != 0xff) && (buffer[1] != 0xd8) && (buffer[2] != 0xff) && ((buffer[3] & 0xf0) != 0xe0)); //this doesn't work because you need all of these statements to evaluate as TRUE
            fclose(outptr);
            //fseek(inptr, -512, SEEK_CUR);
        }
    }
    fclose(inptr);
    return 0;
    }

Thank you for any help with this.

1

an int is 4 bytes an unsigned char is 1 byte so buffer[3] in char is the 4th byte but in int it is the 13-16 bytes. so when using int you are not actually checking the first 4 bytes, but the first 16.

| improve this answer | |
  • Ah - that makes sense. Thank you. A separate question on board etiquette: Should I have made two separate posts since I asked two questions? If so, I will post my second question separately so I can give this answer a check mark. – CodingNewb Mar 14 '17 at 14:37

You must log in to answer this question.

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