0

I finished recover.c and it recover all 50 photos but couldn't pass check50.

I checked with valgrind and it seemed that i have no errors of memory allocation.

I already searched for answers and haven't found if anyone had had the same problem.

Thanks for helping!!!

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

typedef uint8_t  BYTE;

int main(void)
{

    // open input file 
    FILE* inptr = fopen("card.raw", "r");
    if (inptr == NULL)
    {
        printf("Could not open card.raw");
        return 1;
    }


    // memory allocate, initial photo_temp to avoid the if condition to be used for junk uninitialized value
    BYTE* photo_reg = malloc(4);
    BYTE* photo_temp = malloc(512);
    *(photo_temp) = 0x00;
    *(photo_temp + 1) = 0x00;
    *(photo_temp + 2) = 0x00;
    *(photo_temp + 3) = 0x00;

    // end is for eof, first is for searching the starting point of file
    int end = 0;
    int i = 0;
    int first = 1;
    while (1)
    {   
        // if freads didn't return 512 in the former loop, break
        if (end == 1)
            break;

        // open output file
        char file_name[20];
        sprintf(file_name, "%03d.jpg", i);
        FILE* outptr = fopen(file_name, "w");
        if (outptr == NULL)
        {
            fclose(inptr);
            printf("Could not create photo.jpg");
            return 2;
        }


        if (first)
        {
            while (1)
            {   
                // reads one byte of data once a time, if it's 0xff ,then reads the following three. This is for searching the starting point of the forst jpeg
                fread(photo_reg, 1, 1, inptr);
                if (*photo_reg == 0xff)
                {
                    fread(photo_reg + 1, 1, 3, inptr);
                    if (*(photo_reg + 1) == 0xd8 && *(photo_reg + 2) == 0xff && (*(photo_reg + 3) >= 0xe0 && *(photo_reg + 3) <= 0xef))
                    {
                        //locate the first jpeg, so write the four signature bytes first and then the following 508 bytes                     
                        fwrite(photo_reg, 1, 4, outptr);
                        fread(photo_temp, 1, 508, inptr);
                        fwrite(photo_temp, 1, 508, outptr);
                        first = 0;
                        while(1)
                        {   
                            fread(photo_temp, 1, 512, inptr);
                            if (*photo_temp == 0xff && *(photo_temp + 1) == 0xd8 && *(photo_temp + 2) == 0xff && (*(photo_temp + 3) >= 0xe0 && *(photo_temp + 3) <= 0xef))
                                break;
                            else
                                fwrite(photo_temp, 1, 512, outptr);
                        }
                    }

                }
                if (*photo_temp == 0xff && *(photo_temp + 1) == 0xd8 && *(photo_temp + 2) == 0xff && (*(photo_temp + 3) >= 0xe0 && *(photo_temp + 3) <= 0xef))
                    break;
            }
        }
        else
        {
            fwrite(photo_temp, 1, 512, outptr);
            while(1)
            { 
                if (fread(photo_temp, 1, 512, inptr) == 512)
                {
                    if (*photo_temp == 0xff && *(photo_temp + 1) == 0xd8 && *(photo_temp + 2) == 0xff && (*(photo_temp + 3) >= 0xe0 && *(photo_temp + 3) <= 0xef))
                        break;
                    else
                        fwrite(photo_temp, 1, 512, outptr);
                }
                else
                {
                    end = 1;
                    break;
                }
            }
        }

        // close outfile
        i++;
        fclose(outptr);
    }

    // close infile
    fclose(inptr);
    free(photo_reg);
    free(photo_temp);

    return 0;


}
1

From the spec [emphasis added]:

Moreover, rather than read my CF card’s bytes one at a time, you can read 512 of them at a time into a buffer for efficiency’s sake. Thanks to FAT, you can trust that JPEGs' signatures will be "block-aligned." That is, you need only look for those signatures in a block’s first four bytes.

What does this program do if it happens to find 4 bytes that look like a jpg signature in the middle of a 512-byte block? By reading one byte here fread(photo_reg, 1, 1, inptr); you run the risk of finding a sequence of bytes that look like a jpg signature purely by chance.

It's quite likely (obvious?) that check50 is using a different card.raw than the one supplied by the pset for testing. One lesson of this pset set is that programs have to work on a whole range of potential inputs.

You will have to rework your program to make sure it stays "block-aligned".

| improve this answer | |

You must log in to answer this question.

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