0

Working on pset4 - recover. The program compiles and runs and upon opening the images, they look alright. Check50 returns:

:) recovers 000.jpg correctly
:( recovers middle images correctly
    recovered image does not match
:) recovers 049.jpg correctly

Here is my code:

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

typedef uint8_t BYTE;

// block size is 512 bytes
int BLOCK = 512;

int main(int argc, char *argv[])
{
    // check usage
    if (argc != 2)
    {
        fprintf(stderr, "Usage: ./recover image\n");
        return 1;
    }
    // open file to be read and exit if it does not exist
    FILE *inptr = fopen(argv[1], "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "file does not exist.\n");
        return 1;
    }
    // allocate 512 bytes of memory
    BYTE *chunk = malloc(BLOCK * sizeof(BYTE));
    if (chunk == NULL)
    {
        fprintf(stderr, "not enough memory. \n");
        return 2;
    }
    int i = 0;
    // allocate 8 bytes of memory for filename strings
    char *outname = (char *)malloc(sizeof(char) * 8);
    FILE *outptr;
    size_t read;
    while (1)
    {
        // read 512 bytes of data into chunk from infile
        read = fread(chunk, sizeof(BYTE), BLOCK, inptr);
        // exit loop if end of file
        if (read != BLOCK * sizeof(BYTE))
        {
            break;
        }
        // skip this iteration if the block (likely) contains all 0
        if (chunk[0] == 0 && chunk[BLOCK - 1] == 0)
        {
            continue;
        }
        // if a jpg header is found, open a new file and write 512 bytes to that file
        else if (chunk[0] == 0xff && chunk[1] == 0xd8 && chunk[2] == 0xff && chunk[3] >= 0xe0 && chunk[3] <= 0xef)
        {
            if (i > 0)
            {
                fclose(outptr);
            }
            sprintf(outname, "%.3i.jpg", i);
            outptr = fopen(outname, "w");
            fwrite(chunk, sizeof(BYTE), BLOCK, outptr);
            i++;
        }
        // continue writing to file if it isn't finished
        else
        {
            fwrite(chunk, sizeof(BYTE), BLOCK, outptr);
        }
        // reallocate memory
        chunk = realloc(chunk, BLOCK * sizeof(BYTE));
    } 
    free(outname);
    free(chunk);
    fclose(outptr);
    fclose(inptr);
    return 0;
}

I am super confused. Thanks in advance for your help!

0

The problem lies here. It will cause a block(s) of data to be deleted from an image.

    // skip this iteration if the block (likely) contains all 0
    if (chunk[0] == 0 && chunk[BLOCK - 1] == 0)
    {
        continue;
    }

What is the purpose of this code? The comment implies that it is supposed to check for a block that's all zeros and not copy it to the output file. If an image block were predominately black pixels, it could easily have a data block of all zeros.

Further, this only checks the first and last bytes of a block, which could easily be zeros. Because of this, several files have had data blocks deleted, so they are found to be bad.

There are other aspects of this code that can be improved, but I'll let you research that on your own.

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

1
  • Thanks for your help. I was trying to deal with the zeroes at the beginning of the memory card but the next if condition solves that issue. Thanks again! – John Yang Aug 31 '20 at 21:23

You must log in to answer this question.

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