1

In pset4, recover.c, my program finds the start of the jpegs at 1024 bytes. After that, it encounters a seg fault and I don't see why. Here's my code:

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

#include <stdint.h>


int icheck(FILE* pf, long long n); //this function returns 1 if jpeg headers are found, 0 if not.
uint8_t bytes[4];       //for reading 1 byte at a time

int main(void)
{
    FILE* raw = fopen("card.raw", "r");
    if (raw == NULL)
    {
        printf("Error: card.raw cannot be opened");
        return 2;
    }


    int reader;
    long long current = 0;  //for the position of fseek while reading from file for headers
    char buffer[50];        //buffer for sprintf
    int check_out;          //to check if the header file has been encountered
    int done = 0;           //to check if the end of the jpeg sequence has been reached
    FILE* recover = NULL;   //holding jpegs
    int y;                  //to check if EOF has been reached


    do
    {

        fseek(raw, current, SEEK_SET);
        check_out = icheck(raw, current);

        if (check_out == 1)
        {
            printf("found jpeg start @ byte no. %lld\n", current);
            check_out = 0;
            fseek(raw, current, SEEK_SET);   //'cause header files must also be read as a part of the jpeg.

            int a = 0; //for the file name
            int b = 0; //-do-
            int c = 0; //-do-

            while(fread(&reader, 512, 1, raw) == 1)
            {
                sprintf(buffer, "%d%d%d.jpg", a, b, c);
                recover = fopen(buffer, "w");

                if (recover == NULL)
                    printf("Failed to open file :(");


                while (check_out == 0)
                {

                    fwrite(&reader, 512, 1, recover);

                    current = current + 512;
                    check_out = icheck(raw, current);

                    fseek(raw, current, SEEK_SET);

                }

                fclose(recover);
                //to set the name for the next jpg file.
                c++;
                if (c > 9)
                {
                    c = 0;
                    b++;
                }
                if (b > 9)
                {
                    b = 0;
                    a++;
                }

            }
            done = 1;
        }
        current++;

        //to check if the next byte is the EOF marker
        int x = current - 1;
        fseek(raw, x, SEEK_SET);
        fread(&y, 1, 1, raw);

    }
    while (done != 1 && y != EOF);
    fclose(raw);
}

int icheck(FILE* pf, long long n)
{
    fseek(pf, n, SEEK_SET);
    fread(&bytes, 32 , 1, pf);
    if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff
            && bytes[3] >= 0xe0 && bytes[3] <= 0xef)
    {
        return 1;
    }
    else
    {
        return 0;
    }


    return 0;

}
2

I see two writes that are way off:

fread(&bytes, 32 , 1, pf);

reads 32 bytes into a uint8_t[4], a 4-byte buffer

fread(&reader, 512, 1, raw)

reads 512 bytes into an int, which is a 2 to 8 byte variable (depending on system, most likely 4 bytes)

Also, I'm not sure you close the last image you write to (you'd find that with valgrind once your program does not segfault any more).

  • Okay, I've corrected those and with a few more corrections, I've got the 50 images albeit they are a bit skewed; a part of the image on the right is instead printed on the left. So it doesn't pass check50. Also, valgrind returns no error. Thank you for your help! @Blauelf – RB1213 Nov 8 '16 at 14:11

You must log in to answer this question.

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