0

I cant understand why 049.jpg is not working

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

unsigned char bytes[512];

//counter for the jpg files
int jpgCount = 0;

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

    // Open file which was provided in the command line
    FILE *rawCard = fopen(argv[1], "r");
    if (!rawCard)
    {
        return 1;
    }

    //Create pointer to new file
    FILE *picFromCard = NULL;

    //do untill end of file
    while (!(feof(rawCard))) 
    {
        //read 512 bytes and look for JPEG in first 4 bytes
        fread(bytes, 512, 1, rawCard);
        // Check first four bytes
        if (bytes[0] == 0xff && 
            bytes[1] == 0xd8 && 
            bytes[2] == 0xff &&
            (bytes[3] & 0xf0) == 0xe0)
        {
            //close any file that may be open or being written
            if (picFromCard != NULL)
            {
                fclose(picFromCard);
            }

            //format the file name ###.jpg 
            char filename[3];
            sprintf(filename, "%03i.jpg", jpgCount);

            //open a new file for writting and check that it opened successfully
            //"w" Creates an empty file for writing. If a file with the same name already exists, 
            //its content is erased and the file is considered as a new empty file.
            //"w+" on the other hand creates an empty file for both reading and writing.
            picFromCard = fopen(filename, "w+");
            if (picFromCard == NULL)
            {
                fclose(rawCard);
                fprintf(stderr, "Could not create \n");
                return 1;
            }
            //write first block of 512 bytes to the file    
            fwrite(&bytes, 512, 1, picFromCard);              
            //Counter for the numbers of jpg files found and it will help in naming the file.
            jpgCount++;
        }
        //when jpgCount is greater then 0 that means we already have a file found and so write remaining blocks of memory to the file.
        else if (jpgCount > 0)
        {
            fwrite(&bytes, 512, 1, picFromCard);
        }
        else if (jpgCount > 0 && )
    }
    // Close files
    fclose(rawCard);
    fclose(picFromCard);
}

1 Answer 1

2

Your last file has one extra block of data. Look at this code:

//do untill end of file
while (!(feof(rawCard))) 
{
    //read 512 bytes and look for JPEG in first 4 bytes
    fread(bytes, 512, 1, rawCard);
...
}

The code checks for EOF, then reads the next block of data, processes it, and then checks again for EOF at the top of the loop.

You have to understand that the EOF test will only return true once the EOF has been processed. The code can read right up to and including the last byte in the file without setting the EOF flag. Only when an attempt is made to read past the end of the file will it set. It doesn't check the "next byte", only the current bytes read.

So, when this code reads the last 512 byte block in the file, it will process it, return to the top and test for EOF. Since it didn't set the EOF flag (the next read will), it continues to the fread and tries to read another 512 bytes. There's nothing to read, so the fread returns a 0, but not an error. The buffer remains unchanged and the remaining code writes the last block out to the file a second time. Now, the EOF flag is set. The code returns to the while statement, sees that EOF is set, and ends the loop.

The result is an extra 512 bytes in the file. That causes a fail.

Hint: look at the man page for fread, particularly the return codes.

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

1
  • Thank you i followed that you said and added if Eod is true then break just under the while statement and it worked Commented Mar 15, 2020 at 15:43

You must log in to answer this question.

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