0

I've been quite frustrated by trying to make progress in Recover. When I run my code, I am unable to make even the first JPEG file as the program continues running until the file size is exceeded. I can't find where the bug(s) are, but my poor understanding of file reading/writing doesn't help.

I have some questions:

  1. When we call fread, does the function just read off from where the so-called file position indicator last left off?

  2. In the walkthrough, Brian suggested that we use FILE *image = fopen(filename, "w");. However, I understand that writing to a file erases the data that was there prior while appending just adds on to the file's existing data. Thus, when we write buffer data that isn't headed by the JPEG signature (i.e. the last "else" in my code) into our outgoing JPEG file, why aren't we somehow using "a" instead of the default "w"? Wouldn't this overwrite the data that is already written to our opened JPEG file?

  3. Finally, what is causing my first JPEG file to keep on getting written (presumably) indefinitely? As you can see from my commented-out code, I've tried various things - using malloc and free, changing the size of my buffer variable (called "copy"), and changing my arguments to fwrite, but all these haven't worked.

The following is my code. I know there's lots to be improved about it, but I'd really appreciate any input. Thank you.

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

typedef uint8_t BYTE;


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

    // open file
    FILE *raw = fopen(argv[1], "r");
    if (raw == NULL)
    {
        printf("unable to open file for reading\n");
        fclose(raw);
        return 1;
    }

    int count = 0;
    int flag = 0;   // indicates if JPEG-copying has started

    char filename[8];
    sprintf(filename, "%03i.jpg", count);
    FILE *img = fopen(filename, "w");       // declare outside while loop to prevent undeclared identifier error. A OR W???

    while (feof(raw) == 0)
    {
        // allocate buffer space
        //BYTE *copy = malloc(512 * sizeof(BYTE));
        //BYTE copy[512 * sizeof(BYTE)];
        BYTE copy[512];

        // read a block to the buffer
        fread(&copy, sizeof(copy), 1, raw);

        // check if start of JPEG
        if (copy[0] == 0xff && copy[1] == 0xd8 && copy[2] == 0xff && (copy[3] >= 0xe0 && copy[3] <= 0xef))
        {
            if (count == 0) // if first JPEG
            {
                fwrite(&copy, sizeof(copy), 1, img); //or fwrite(&copy, sizeof(BYTE), 512, img);?
                flag = 1;
            }
            else            // if not first JPEG
            {
                count += 1;

                // close the current image
                fclose(img);

                // create a new image
                sprintf(filename, "%03i.jpg", count);
                img = fopen(filename, "w");
                fwrite(&copy, sizeof(copy), 1, img);
            }
        }

        // if not start of JPEG
        else
        {
            if (flag == 0)
            {
                continue;
            }
            fwrite(&copy, sizeof(copy), 1, img);
        }
        //free (copy);
    }
    fclose(img);
    fclose(raw);
}
0

I have some answers. ;-)

  1. Yes. The position is automatically updated by fread, fwrite and all it's cousins.

  2. The "w" and "a" settings determine what happens when the file is initially opened for writes. In "w" or write mode, it will empty or delete an existing file with that filename and create a new file from scratch. In "a" or append mode, if the file doesn't exist, it will open a new file, but if it already exists, the file will be opened, and the file pointer will be set to the end of the file so that any new data written will be appended.

    Once the file is opened, for "w" or "a" mode, anything that is written to the file will be written wherever the file pointer is set. Generally, that means that any new data written will continue to be appended to the end. The exception is if the code moves the pointer to somewhere else in the file. In that case, the new data will be written to that new location, likely overwriting whatever is there. (This is not common.)

  3. The code above is successfully disposing of the garbage data at the front of the file, and opening the first file. Interestingly, the size of the one file created plus the size of the discarded data equals the size of the card.raw file. Hmmm......

Does the code increment the file counter?

This should get you going, but there may or may not be other unrelated issues. ;-)

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

| improve this answer | |

You must log in to answer this question.

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