0

I'm a bit stuck with my code. I guess the logic is correct, but the program doesn't give me any output and I have to kill it. Debug is showing me, that the problem is somewhere in checking, if the buffer is JPG's or not. Probably I've described the functions badly in the end?

Many thanks for any hint!

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

bool isJpg(int *buffer);
bool isEof(int *buffer);

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

    // remember filename
    char *file = argv[1];

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

    // declare the 512b chunk of memory
    int buffer[512];

    // declare the counter
    int counter = -1;

    // declare variable for the filenames
    char photo[3];

    // read infile until found a 1st JPEG
    do 
    {
        fread(&buffer, 512, 1, inptr);
    }
    while (!isJpg(buffer));

    // read infile's all 512b chunks until EoF
    do
    {
        // start the counter and increase it
        counter++;

        // create the outfile with a correct name
        sprintf(photo, "%03i.jpg", counter);
        FILE *outptr = fopen(photo, "w");

        // write the 1st chunk to outfile
        fwrite(&buffer, 512, 1, outptr);

        // write the chunks until we reach next jpg
        while (!isJpg(buffer))
        {
            fread(&buffer, 1, 512, inptr);
            fwrite(&buffer, 512, 1, outptr);
        }

        // when next jpg is reached, clouse the outfile
        fclose(outptr);

        if (isEof(buffer))
        {
            // if EoF reached, close the infile
            fclose(inptr);

            // if any outfile exists, write the remaining chunk and close it
            if (outptr != NULL)
            {
                fwrite(&buffer, sizeof(buffer), 1, outptr);
                fclose(outptr);
            }
        }
    }
    while (!isJpg(buffer));
}

// this function checks for first 4 bytes
bool isJpg (int *buffer)
{
    if (buffer[0] == 0xff && 
        buffer[1] == 0xd8 && 
        buffer[2] == 0xff && 
        (buffer[3] & 0xf0) == 0xe0)
    {
        return true;
    }
    else return false;
}

// this function checks, if the end of file is here
bool isEof (int *buffer)
{
    if (sizeof(buffer) < 512) return true;
    else return false;
}

2 Answers 2

1

Hint 1: This int buffer[512]; is not a "512b chunk of memory". An int is 4 bytes, so this is a 512 * 4 byte chunk of memory. The buffer should be a "byte" type. You can take a hint from bmp.h in resize.

Hint 2: sizeof(buffer) < 512 is never true. sizeof(buffer) is always the size it was declared (so 2048 if int, 512 if byte type). That explains the endless loop. To check if EOF has been reached, you need to test the result [return value] of fread (it will be 0 if eof is reached).

Hint 3: (a bug waiting to happen) char photo[3]; is not big enough to hold the output file name (and don't forget the null-byte!).

1
  • Many thanks, that helped a lot!
    – Fed
    Commented Apr 21, 2017 at 8:24
0

The immediate problem does lie in isJpg(). It is comparing 1-byte long values to the values in buffer. Unfortunately, buffer is declared as an int array. An int is 4 bytes and signed, so the results of the comparisons between 4 byte values and 1 byte values isn't what you're expecting, both for length and for the impact of two's complement notation. Maybe you should consider using a 1 byte unsigned type, like uint8_t?

There are more problems to follow, but those are for a different question. Here's a clue to one of them though. When you create your output file name, how many chars are you storing in that name variable, including the end of string marker? ;-)

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

1
  • Many thanks, that really helped to move on!
    – Fed
    Commented Apr 21, 2017 at 8:24

You must log in to answer this question.

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