0

So it seems like I am almost done with recover. My code recover all the pictures except the fist one and last one.

On the first one it only recovers a small block on the top right corner.

Also the last one is missing a little bit in the bottom.

Why does the check say it didn't recover any of them?

// Iterate until end of memory card
    while (fread(buffer, 512, 1, infile) == 1)
    {

        // Check if it is a JPEG
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            // Check if its the first JPEG
            if (jpegfound == 0)
            {
                // Name the JPEG file name
                sprintf(filename, "%03i.jpeg", jpegfound);

                // Create outfile
                outfile = fopen(filename, "w");

                //Write first jpeg
                fwrite(buffer, 512, 1, outfile);

                // Increase counter
                jpegfound++;

            }

            // If not the first
            else
            {
                // Close last file
                fclose(outfile);

                // Name the JPEG file name
                sprintf(filename, "%03i.jpeg", jpegfound);

                // Create outfile
                outfile = fopen(filename, "w");

                // Increase counter
                jpegfound++;
            }
        }

        if (jpegfound > 0)
        {
            //Write first jpeg
            fwrite(buffer, 512, 1, outfile);
        }

    }

(Edited)

So I deleted the line that writes the first block twice and the images now seem to be correct but check 50 still says its all wrong.

Here is the rest of the code:

int main(int argc, char *argv[])
{
    // Insure proper usage of comand line
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }

    // Open memory card
    FILE *infile = fopen(argv[1], "r");

    // Declare outfile
    FILE *outfile = malloc(sizeof(FILE));

    // Create JPEG counter
    int jpegfound = 0;

    // Create variable
    typedef uint8_t BYTE;

    // Create buffer/temporary storage
    BYTE buffer[512];

    // Create a storage for the file name
    char *filename = malloc(sizeof(4));

And

    }
    // Close last file
    fclose(outfile);
    free(filename);
    fclose(infile);
}
0

For one thing, check50 checks that the correct file is recovered for each file name. So, if a file is recovered but doesn't have the right file name, check50 says it wasn't recovered. Not exactly sure if this is what's happening, but it seems likely.

So let's move on to things we can be sure about.

Look at how the while loop functions for the first file. It's going to find the first signature, open the file, write the first block out, and then move out of the if(buffer) code block for the signature. At that point, it moves into the if(jpegfound) test. At this point, the test passes because jpegfound has been incremented, so it writes that same, first code block again to the output file, without having first read the next block from the input file. That's why the first file is corrupted.

The second file doesn't write the signature block when the new file is opened in the first if code block, and instead writes it in the second block, correctly.

However, there may still be something else going on. Without seeing the full code, I can't tell if or what. I'm highly suspicious of the code that processes the end of file handling of the input file and the closure of the last output file restored.

IF you fix the first problem, it may correct other issues.

[EDIT] In addition to those issues, what did the spec say to name the files? Specifically, how is the file extension spelled? Sometimes problems hide in plain sight! ;-)

A perfect demonstration that the program spec must be followed EXACTLY AND PRECISELY! Close doesn't get the job done!

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

6
  • I corrected the mistake you mentioned and added the rest of my code. – Christopher Holder Feb 12 '20 at 18:20
  • See edited answer. – Cliff B Feb 12 '20 at 22:52
  • Thanks, I have no idea why I wrote jpeg instead of jpg. – Christopher Holder Feb 12 '20 at 22:59
  • Oh, here's something else to be aware of. Look at this: char *filename = malloc(sizeof(4)); What do you think sizeof(4) returns? What about sizeof(800)? Both will return 4. The sizeof() function will return the size of the object, not the value in the parentheses. Since an integer is 4 bytes, an integer number will always return 4. The correct malloc would have been char *filename = malloc(4); or char *filename = malloc(4 * sizeof(char)); The latter tells programmers that read it later that your intent is to allocate space for 4 chars and not 4 ints or something else. – Cliff B Feb 12 '20 at 23:14
  • 1
    AND YET, that was still wrong. char *filename = malloc(sizeof(4)); doesn't allocate enough space. In this pset, all the filenames are 7 chars. You needed to allocate space for the entire firename, including the End of String char, \0 at the end, meaning 8 chars. You got lucky that it works, assuming it does. When insufficient space is allocated and you write a string to that location, the system will overwrite the physical memory that follows. Usually, it shows up when all the recovered files are corrupted because the first one or more bytes of the buffer get overwritten. – Cliff B Feb 12 '20 at 23:21

You must log in to answer this question.

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