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.