简体   繁体   中英

CS50 PSET3 Recover segmentation fault, can't get code to output JPEG's

The program is supposed recover JPEG's from a raw file, I've checked similar problems, but can't seem to figure out the problem in my code that's causing the segmentation fault and failure to output images. The debugger in cs50 doesn't function.

Code:

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

typedef uint8_t  BYTE;

bool checkheader(BYTE buffer[512]);

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

    // save arguments
    char *infile = argv[1];

    // open input file
    FILE *inptr = fopen(infile, "r");
    if(inptr == NULL)
    {
        printf("File could not be read\n");
        return 2;
    }

    //open output file
    FILE* img = NULL;


    BYTE buffer[512];
    int block = 512;
    bool newJpeg = false;
    bool run = false;
    char filename[8];
    int filenameCnt = 0;


    // run until end of file
    while (fread(buffer, 512, 1, inptr) == 1)
    {

        // read 512 blocks UNTIL FIRST HEADER FOUND, checking to see if first four bytes indicate JPEG
        if (newJpeg == false)
        {
            for (int i = 0; i < block; i++)
            {
                fread(&buffer[i], 1, 512, inptr);
            }
        }

        // create jpeg file if jpeg header is found
        if(checkheader(buffer) == true)
        {
            sprintf(filename,"%03d.jpg", filenameCnt); // creating a new jpeg
            filenameCnt++;
            img = fopen(filename, "w"); // making the jpeg writable
            run = true;

            // write data of block after header
            for (int j = 0; j < block - 4; j++)
            {
                fwrite(&buffer[j+4], 1, 512, img);
            }
        }

        // read and write new blocks into jpeg until new header is found
        while (run == true)
        {

            // read new block
            for (int i = 0; i < block; i++)
            {
                fread(&buffer[i], 1, 512, inptr);
            }

            // check if new block has header
            if(checkheader(buffer) == true)
            {
                fclose(img); // close current jpeg so new one could be opened
                newJpeg = true;
                run = false;
            }
            else
                // if not, continue writing new blocks into the current jpeg.
                for (int j = 0; j < block; j++)
                {
                    fwrite(&buffer[j], 1, 512, img);
                }

        }
    }

return 0;

}

bool checkheader(BYTE buffer[512])
{
    if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        return true;
    else
        return false;
}

It's supposed to output 50 JPEG files. Any help or observations would be really appreciated. Thanks.

Does this "The debugger in cs50 doesn't function" mean debug50 ? Maybe you have set a breakpoint after the segfault. The segfault comes here fread(&buffer[i], 1, 512, inptr); (line 51). Basically, it cannot "fit" 512 bytes of data at the address of buffer[i] for some i.

Generally speaking the input file should be read in exactly one place, like here: while (fread(buffer, 512, 1, inptr) == 1)

What is this loop:

        for (int i = 0; i < block; i++)
        {
            fread(&buffer[i], 1, 512, inptr);
        }

going to do (if it didn't segfault!)? It is going to read 512 512-byte blocks from the infile. Wow, it will certainly miss some really important data, won't it?

The program needs to read inptr in one place, the while is appropriate, then decide what to do with each block read. There are three choices:

  • discard (have not found the first jpeg signature)
  • write to current jpeg
  • start a new jpeg (it is a signature block)

And remember, the signature block is an integral and necessary part of the output.

// write data of block after header
            for (int j = 0; j < block - 4; j++)
            {
                fwrite(&buffer[j+4], 1, 512, img);
            } 

is discarding the header, which will result in corrupt output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM