Search code examples
ccs50recover

jpg's are not proper, mix of multiple images. Can anyone tell me whats wrong?“RECOVER”


I am working on CS50's PSET3 recover. I have a "card.raw" file in which jpg's are arranged one after another after the first one.

The objectives of the exercise is "find first jpg by scanning 512 bytes each time and checking if it is the starting of a jpg then adding next bytes to the file until next jpg start is found, then opening another file and repeating until the END OF FILE".

The images are not getting produced properly and I'm not sure where my problem lies in the code below.

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

int main(int argc, char *argv[])
{
    //check if program argument count is correct
    if ( argc != 2)
    {
        fprintf(stderr,"Usage: ./recover image\n");
        return(1);
    }

    char *infile = argv[1];    //Remember file name

    //open file for reading
    FILE *inptr = fopen(infile,"r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return(2);
    }

    typedef uint8_t BYTE;      //new name BYTE

    BYTE buffer[512];          // temporary  storage

    int counter = 0;           // image counter

    while (fread(buffer, 512, 1, inptr) == 1)
    {
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            char filename[8];

            start:
            sprintf(filename,"%03i.jpg", counter);
            FILE *outptr = fopen(filename,"w");
            fwrite(buffer, 512, 1,outptr);

            //check next byte
             while (fread(buffer, 512, 1, inptr) == 1)
             {
                  if (buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3] & 0xf0) != 0xe0)
                  {
                      fwrite(buffer, 512, 1,outptr);
                      printf("%i",counter);
                  }

                  //if next file starts
                  if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
                  {
                      counter++;
                      printf("%i",counter);
                      fclose(outptr);
                      goto start;
                  }
             }
             if (counter > 1)
             {
                 fclose(outptr);
             }
        }
    }
    fclose(inptr);
}

Solution

  • Could have written better code, but if its just about logic then

    if (buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3] & 0xf0) != 0xe0)
                      {
                          fwrite(buffer, 512, 1,outptr);
                          printf("%i",counter);
                      }
    

    This is wrong, it should be

    if (!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0))
                      {
                          fwrite(buffer, 512, 1,outptr);
                          printf("%i",counter);
                      }
    

    As the previous also neglects any part of jpg that have one or more of first 4 bytes equal to start of IMG but not all. Thank you everyone for helping.