0

Apologies for including all my (60 lines) of code, but I've been thoroughly confused by this for a while. I've written code to do Recover, and it's working fine and recovers images perfectly--it just puts all images in a name one number higher than they should be. That is, all the images are shifted up by one, and 000 is left empty (050 is the last image created, where it should be 049). I haven't found any logical reason for this to be given the code I've written, despite doing rubber-duck debugging several times. It must be an obvious error staring me in the face--any ideas?

Also, I was unsure why I didn't have to include:

fread(&buffer, 512, 1, rawFile)

after the while() statement, since I would imagine I would actually have to execute the read command at some point for the write command to work later on--but this turns out not to be the case, as you can see from the lack of fread after while(), and I still don't know why. I suspect it's because the fread inside of the while statement somehow automatically writes to buffer even though it's just a conditional being checked inside a while loop?

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


int main(int argc, char *argv[])
{
    // Takes input file that you want to recover images from and validates it is a meaningful input
    while (argc != 2)
    {
        fprintf(stderr, "Usage: ./recover image");
        return 1;
    }

    if (!(fopen(argv[1], "r")))
    {
        fprintf(stderr, "Image cannot be opened./n");
        return 2;
    }
    // creates pointer to access the input file in read mode readily by dereferencing this pointer
    FILE *rawFile = fopen(argv[1], "r");
   // creates a buffer array that will store values that are read throughout the program
    unsigned char buffer[512];
    // creates a counter that keeps track of how many JPEGs have already been made so you can
    //give an appropriate name to the most recent JPEG file created
    int counter = 0;
    // defines the string filename for use in sptrintf()
    char filename[8];
    // baseline global definition of outfile for each picture we create
    FILE *img = NULL;
    // checks for END OF FILE
    while (fread(&buffer, 512, 1, rawFile) == 1)
        {
            // checks if the block of data we just scanned is in fact the start of a JPEG file
            if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
                {
                    // checks the second conditional--have we already found a JPEG?
                    if (counter == 0)
                        {
                         // if yes->no, then just make a JPEG file img and write the block into it, nothing to close
                        sprintf(filename, "%03i.jpg", counter);
                        img = fopen(filename, "w");
                        counter++;
                        fwrite(&buffer, 512, 1, img);
                        // increment counter to reflect the fact that we just created a new JPEG file file the raw source
                        }
                    if (counter != 0)
                        {
                        // if yes->yes, then close the previous file before creating a new JPEG file
                        fclose(img);
                        sprintf(filename, "%03i.jpg", counter);
                        img = fopen(filename, "w");
                        counter++;
                        fwrite(&buffer, 512, 1, img);
                        }
                }

                    else
                    {
                        //if no->yes, then copy the info in this FAT block to the file currently open
                        if (counter != 0)
                            {
                            fwrite(&buffer, 512, 1, img);
                            }

                    }
        }
    // close any remaining files and exit the program because we've reached END OF FILE
    fclose(img);
    fclose(rawFile);
}

Thank you so much! Would appreciate commends/constructive criticism on my code more generally, too.

1

The problem is in the first jpg, that is, when the counter is zero, let's see what happens: When counter is zero, if we find a jpg we open a new image, with the title 000.jpg, we increase counter by one unit (counter == 1), and write a block of 512 bytes, and that's it, we don't write again In this image only one block, the rest of the 000.jpg image is incomplete. Following the logic of your program we find another IF condition, which will also be met, since now counter == 1, so that we close the previous image, open a new one, and write the same block, because fread () has not advanced. Basically we are writing the same jpg twice, once incompletely, and once completely. The rest of the iterations work correctly because the counter == 0 condition is no longer met. Therefore it seems that you should change the logic of your program for the case where counter == 0.

As for your question, I did not understand it very well, although fread is a condition of while, there is a real reading of 512 bytes, only when the reading is not 512, we leave the while loop. I hope this clarifies your doubts

You must log in to answer this question.

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