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

typedef uint8_t BYTE;

int main(int argc, char *argv[])
    // ensure proper usage
    if (argc != 2)
        fprintf(stderr, "Usage: resize factor infile outfile\n");
        return 1;

    char filename[8];
    int jpeg_counter = 0;
    int *pjpeg_counter = &jpeg_counter;

    //remember filename
    char *rawfile = argv[1];

    BYTE buffer[512];

    //open forensic file
    FILE *rawptr = fopen(rawfile, "r");
    if (rawptr == NULL)
        fprintf(stderr, "Could not open %s.\n", rawfile);
        return 2;

    fseek(rawptr, 0, SEEK_END); // seek to end of file
    long int filesize = ftell(rawptr); // get current file pointer
    fseek(rawptr, 0, SEEK_SET); // seek back to beginning of file
    // proceed with allocating memory and reading the file

    //define number of blocks
    int blocks = filesize / sizeof(buffer);
    printf("File size is %li bits and it contains %i blocks\n", filesize, blocks);

    //read forensic file

for (int i = 0; i < blocks; i++)

        fread(buffer, sizeof(buffer), 1, rawptr);
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        sprintf(filename, "%03i.jpg", jpeg_counter);
        FILE *img = fopen(filename, "w");
        fwrite(buffer, sizeof(buffer), 1, img);
        fread(buffer, sizeof(buffer), 1, rawptr);
            while (buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3] & 0xf0) != 0xe0)
            fwrite(buffer, sizeof(buffer), 1, img);
            fread(buffer, sizeof(buffer), 1, rawptr);
        fseek(rawptr, -sizeof(buffer), SEEK_CUR);
        *pjpeg_counter = *pjpeg_counter + 1;



A large problem lies here:

        while (buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3] & 0xf0) != 0xe0)

While it might seem like this is the way to keep looping until a new signature is found, compound logic doesn't work that way. You can't just negate each part of the test. Think about it. If just one byte of the four matches, for instance, if the first byte was Oxff, then the test fails and the loop terminates. Random data in the first four bytes of certain blocks are triggering an early termination of the file. It looks like almost every file is being closed before being completed.

There's a very complex explanation on why this is so, and a semester of digital logic to explain it in detail, but there's a shortcut. Instead, when you have to take the negative of a complex logic test i.e., while ( a && b && c && d ), just negate the entire test as a whole, i.e., while ( !( a && b && c && d )). It's as simple as enclosing the test in parantheses and placing the not operator, ! in front of it!

As a side note, this code is more complex than it needs to be. While it will work when fixed, you should consider how it could be simplified. Hint: nearly identical code is usually a red flag that code can be rethought to remove some or all of the duplicated code.

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

  • Hi Cliff B, thank you for your help. The correction that you've suggested worked and not all images are complete and not corrupted, except for the last one. It doesn't pass check50 for 1st, middle and last images. My best guess is that 000 image that I recover is actually not the 1st image. – Sviatoslav Pechurytsia Aug 26 '19 at 11:31
  • It doesn't pass check50 due to “timing out while waiting for program to exit” – Sviatoslav Pechurytsia Aug 26 '19 at 11:53
  • OK, so the reason for timing out was that my program was running in a loop for the last image as it didn't check for the EOF. as a result, it stops only when the last file was 512 MB in size. Corrected that and now the checks are passed. Thank you again for your help. – Sviatoslav Pechurytsia Aug 26 '19 at 12:26

You must log in to answer this question.

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