0

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

typedef uint8_t BYTE;

int main(int argc, char *argv[]) { //user didn't enter one argument or enters more than one if (argc <= 1) { printf("Usage: ./recover image \n"); return 1; }

//Opening the file the user wishes to recover
FILE *file = fopen(argv[1], "r");

//checking if pointer returns null this means there's error or no such file as user input
if (file == NULL)
{
    printf("Couldn't open file \n");
    return 1;
}

//crearing a buffer of size 512 bytes
BYTE *buffer = malloc(512);
char filename[7];
FILE *img = NULL;

//Initializing number of JPEGs in the memorycard inorder to rename the new files later
int numberOfJPEGs = 0;

//to loop over all the file
while(fread(buffer, sizeof(BYTE), 512, file) == 512)
{
    if (buffer[0] == 0xFF && buffer[1] == 0xd8 && buffer[2] == 0xFF && (buffer[3] & 0xF0) == 0xe0)
    {
        //this means this is a jpeg file so increment number of JPEGs
        numberOfJPEGs ++;

        //this is the first jpg image
        if (numberOfJPEGs == 1)
        {
            //creating a new jpg file with a unique name and the minus 1 because first image here will be 001 so to make it 000,jpg
            sprintf(filename, "%03i.jpg",numberOfJPEGs - 1);

            //creating a new jpeg file
            img = fopen(filename, "a");

            //writing to the new jpg file created the data i read before
            fwrite(buffer, 1, 512, img);
        }

        //not the first jpg file,second,third...etc.
        else
        {
            //close the image before it
            fclose(img);

            //creating a new jpg file with a unique name and the minus 1 because first image here will be 001 so to make it 000,jpg
            sprintf(filename, "%03i.jpg",numberOfJPEGs - 1);

            //creating a new jpeg file
            img = fopen(filename, "a");

            //writing to the new jpg file created the data i read before
            fwrite(buffer, 1, 512, img);
        }
    }
    
    //if not beginning of JPEG file but we found at least one jpeg file, this means this info belongs to the one we are writing
    //so continue writing, as JPEG are back to back
    else
    {
        if (img != NULL)
        {
            fwrite(buffer, 1, 512, img);
        }
    }
}
fclose(file);
fclose(img);
free(buffer);

}

1

So once you find a JPG file, you write the buffer out to a new image file, which is correct. But then you close the image - what if the JPG is longer than 512 bytes?

3
  • Thanks, i thought that all JPEGs will be of size 512 bytes i was wrong, Now it worked, i fixed it, yet i have 2 more problems. The First is: when i open the first JPEG 000.jpg it says " Invalid or Unsupported Image Format". The Second is when i use free(buffer) to free the memory i allocated it says "free(): invalid pointer Aborted", Do you know why this happens? – Mazen Nov 18 '20 at 23:43
  • I've updated my code after the modification i've done. – Mazen Nov 18 '20 at 23:54
  • Your problem is (in a sense) quite simple, but probably hard to spot because the errors that manifest aren't intuitively related to it. You declare filename as an array of 7 chars, but you need an 8th char for the null terminator. As a result, data is written outside of the char array (a classic "buffer overflow") with undefined results. – Sentox Nov 19 '20 at 1:59

You must log in to answer this question.

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