0

I would appreciate some guidance on the below issue. I have seen the other threads with the same issue but haven't had any luck applying those fixes. I am getting the below error in my code and I can't work out why:

:) recover.c exists
:) recover.c compiles.:) handles lack of forensic image
:( recovers 000.jpg correctly
    failed to execute program due to segmentation fault
:( recovers middle images correctly
    failed to execute program due to segmentation fault
:( recovers 049.jpg correctly
    failed to execute program due to segmentation fault

See code below:

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

#define BUFFER_SIZE 512 // define size of buffer
typedef uint8_t BYTE;

int main(int argc, char *argv[])
{
    FILE * inputf = NULL;
    FILE * outputf = NULL;

    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }

    inputf = fopen(argv[1], "r"); // open memory card

    if (inputf == NULL)
    {
        printf("File cannot be read.\n");
        return 2;
    }

    int jpegcount = 0; // to write into file name in order

    char filename[8]; // store name of jpegs

    BYTE buffer[BUFFER_SIZE]; // create buffer

    while (fread(&buffer, BUFFER_SIZE, 1, inputf) == 1) // repeat until end of card
    {
        fread(&buffer, BUFFER_SIZE, 1, outputf); // (data, size, number, inptr) // read 512 bytes into a buffer

        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            if (jpegcount != 0) // if not first jpeg
            {
                fclose(outputf);
                sprintf(filename, "%03i.jpg", jpegcount); // create new file name
                outputf = fopen(filename, "w");
                jpegcount++;
                fwrite(&buffer, BUFFER_SIZE, 1, outputf);
            }
            else
            {
                sprintf(filename, "%03i.jpg", jpegcount); // create new file name
                outputf = fopen(filename, "w");
                jpegcount++;
                fwrite(&buffer, BUFFER_SIZE, 1, outputf);
            }

        }

        fclose(inputf);
        fclose(outputf);
    }

    return 0;
}
0
while (fread(&buffer, BUFFER_SIZE, 1, inputf) == 1) // repeat until end of card
    {
        fread(&buffer, BUFFER_SIZE, 1, outputf); // (data, size, number, inptr) // read 512 bytes into a buffer

Why are you trying to read from outputf into buffer??!! Clearly outputf is NULL pointer which results in segfault

if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
    if (jpegcount != 0) // if not first jpeg
    {
        fclose(outputf);
        sprintf(filename, "%03i.jpg", jpegcount); // create new file name
        outputf = fopen(filename, "w");
        jpegcount++;
        fwrite(&buffer, BUFFER_SIZE, 1, outputf);
    }
    else
    {
        sprintf(filename, "%03i.jpg", jpegcount); // create new file name
        outputf = fopen(filename, "w");
        jpegcount++;
        fwrite(&buffer, BUFFER_SIZE, 1, outputf);
    }

}

Here, you're trying to check if every 512 bytes is a jpeg header. But what if I have already read a jpeg header before, then subsequent 512 bytes should be written continuously until we encounter a new jpeg header again. You're code simply discards this data !! I've seen many people doing this mistake.

JPEG IMAGE = JPEG HEADER + (NUMEROUS PIXELS: THE REAL NECESSARY DATA DESCRIBING THE IMAGE)

Here's how you're supposed to do this:

  • Start a loop reading 512 bytes every time
    • If it's a jpeg header
      • If we had already seen a jpeg before, close the output file
      • Open a new output file and write into it
    • If it's not a jpeg header
      • If we have seen a jpeg before, then write this data into the output file(because this describes the image)
      • If we haven't seen a jpeg before, discard this information
  • Repeat until we have completely read the raw file
    fclose(inputf);
    fclose(outputf);
}

You still haven't completed reading the raw file !, and you have closed both input and output files immediately, resulting in abandoning the original process of reading 512 bytes again(another possibility of seg-fault since you will do read-operation next). You are supposed to do this outside the loop

You must log in to answer this question.

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