0

I have a question regarding a else if statement for the PSET4 Recover

  while (fread(buffer, 512, 1, card_raw))
{
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && ((buffer[3]) & 0xf0) == 0xe0)
    {
        if (image_number > 0)
        {
            fclose(images);
            sprintf (filename, "%03i.jpg", image_number);
            image_number++;
            images = fopen (filename, "w");
            fwrite (buffer, 512, 1, images);

        }

        else if (image_number == 0)

        {
            sprintf (filename, "%03i.jpg", image_number);
            image_number++;
            images = fopen (filename, "w");
            fwrite (buffer, 512, 1, images);
        }

    }

    else if (image_number > 0)  ///  <== How does this else if statement connect? Am I right in 
                                ///       thinking this just writes to the images after the checks?
    {
        fwrite(buffer, 512, 1, images);


    }

I'm just a bit confused why the code falls apart with blank images if the else if statement is not inserted.

I am wondering if there is a better way to subtract the necessary if statements.

  • WHICH else if statement are you referring to? – Cliff B Sep 3 at 0:43
  • Hi @Cliff B, I marked it rather clearly in my comments, but it's the else if (image_number > 0) I'm referring to. – allemandi Sep 3 at 1:21
  • Missed that. My bad. – Cliff B Sep 3 at 1:31
0

It serves two purposes in this code.

First, the IF part of the "else if" will make sure that no write is attempted before the first file has been opened. Without it, you'd get a seg fault for trying to write to a file that hasn't been opened. This is absolutely necessary.

The second purpose relates to the ELSE. Since the code writes the signature blocks in the earlier code, it's necessary to bypass this write with the ELSE clause. It would be slightly more efficient to remove the first two fwrite statements and the ELSE clause and just have an IF here. All the writing to output files would be handled by this one statement.

Programming note: If you compare the first if/else if code blocks, they're almost identical. The only difference is that one of them closes an already open file. That should be a red flag that the code can be simplified more.

The code could be streamlined further by simply checking if an output file is open and, if so, close it. End of if code block. Then open a new file. Then, if a file is open, write to it.

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

| improve this answer | |
  • thanks for the suggestions, but your answer on the else if statement did not seem to explain the need to separate the initial jpg checking and a continual iteration of fwriting after the initial check. I've written my own answer after a bit of research below – allemandi Sep 3 at 14:40
0

Thanks to @Cliff B for optimization answers, but the if else statement question was not quite what I was looking for.

After watching the CS50 walkthrough on Recover again, I typed out a few more notes which now makes more sense.

        //find start of a new jpeg file
    //if we find a file that has the first four bytes in the buffer that is similar to a jpg file
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
    {
        //if the count is greater than 0, then close opened files
        if (image_number > 0)
        {
            fclose(images);
        }
            //create jpg file
            sprintf (filename, "%03i.jpg", image_number);
            image_number++;
            //open the image file
            images = fopen (filename, "w");
            //write to image file
            fwrite (buffer, 512, 1, images);
    }
    //if jpg already exists and we have already been writing to it, then we should keep writing to it
    //this is the next 512 byte block of current jpg we have been writing to.
    //This should be repeated multiple times because every jpeg takes up multiple blocks of memory inside the card.raw given
    else if (image_number > 0)
    {
        fwrite (buffer, 512, 1, images);
    }

I have slightly simplified the code according to @Cliff B's suggestions.

However, the short answer appears to be that without the else if statement, the code will compile and run, and it will recover the correct amount of images. However, these images will mostly be blank, as if only partially written.

In summary, the else if statement allows for multiple iterations of writing 512bye blocks, which fills out the formerly blank images that had been created but only partially written after detecting the first four bytes of a jpg file.

This is why some of my images after removing else if are not entirely blank, but may have partial colors, similar to corrupted files.

Happy to be corrected if I am wrong, but this appears to be the case.

| improve this answer | |

You must log in to answer this question.

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