0

My code creates 16 jpgs, with the correct naming as well, but they all start with the wrong bytes and I can't figure it out...;

int main(int argc, char* argv[])
{

// open card file
FILE* inptr = fopen("card.raw", "r");    

// check for error
if (inptr == NULL)
{
    fclose(inptr);
    printf("Couldn't open the file. \n");
    return 1;
}

// beginning of a jpg
char beg0[4] = {0xff, 0xd8, 0xff, 0xe0};
char beg1[4] = {0xff, 0xd8, 0xff, 0xe1};

int filenumber = 0;
char filename[8];
FILE* img;

// create buffer
char buffer[512];
char bufferstart[4];

bool foundfirst = false;

// find first jpg
while(foundfirst == false)
{ 
    // fill buffer
    for (int i = 0; i < 512; i++)
    {
        buffer[i] = fgetc(inptr);
    }

    // fill bufferstart
    for (int j = 0; j < 4; j++)
    {
        bufferstart[j] = buffer[j];
    }

    // is it a jpg?
    if (memcmp(bufferstart, beg0, 4) == 0 || memcmp(bufferstart, beg1, 4) == 0)
    {
        foundfirst = true;
    }
}

// create jpgs until EOF 
while(fread(buffer, sizeof(buffer), 1, inptr) == 1)   
{        
    // check for beginning of jpg
    if (memcmp(bufferstart, beg0, 4) == 0 || memcmp(bufferstart, beg1, 4) == 0)
    { 
        // Name and open new jpg
        sprintf(filename, "%03d.jpg", filenumber);
        filenumber++;          
        img = fopen(filename, "w");

        // check for errors
        if(img == NULL)
        {
            fclose(img);
            printf("Couldn't open the file. \n");
            return 1;
        }
        // write 512 bytes and close for now
        fwrite(buffer, sizeof(buffer), 1, img); 
        fclose(img);
    }
    else
    {
        fopen(filename, "a");
        fwrite(buffer, sizeof(buffer), 1, img); 
        fclose(img);
    } 
    // fill buffer for next run of the loop
    for (int m = 0; m < 512; m++)
    {
        buffer[m] = fgetc(inptr);
    }
    // fill bufferstart
    for (int k = 0; k < 4; k++)
    {
        bufferstart[k] = buffer[k];
    }
}         
fclose(inptr);
// that's all folks
return 0;
}
2

The code scans through the beginning of the file to find the first signature. Then, it scans the next block in the while loop setup statement, thus discarding the first 512 byte block of the first file.

Later, you have a block of code following the comment // fill buffer for next run of the loop that reads in a 512 byte block. The next thing that happens is that you read in another 512 byte block at the top of the while loop. This discards every other block of data without being processed.

A common error is that people don't understand that the following line:

while(fread(buffer, sizeof(buffer), 1, inptr) == 1) 

doesn't just check whether EOF has been detected. It actually executes an fread() call and loads 512 bytes into buffer.

It also looks like you haven't grasped that the fread will actually do a 512 byte read. You use fgetc() in two different places to read in one byte at a time * 512 reads. Every read has overhead at the hardware level, which includes accessing the file, setting up the read, positioning the read head on the drive, spinning around to the right byte on the drive, doing the read, and closing the read (different from opening and closing the file.) The fread() does the overhead once, while reading 512 bytes. The for loop/fgetc() call method does all the overhead and reads one byte, but it does all that a total of 512 times, a massive amount of unneeded overhead. Multiply that by a 20 megabyte file.

This is a case of overcomplicating things. I was able to get your program working by removing a fair amount of code and making a couple of minor changes. Something to think about. This should get you going.

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

1
  • I've rewritten my code, after your comment :) Dec 13 '15 at 20:50

You must log in to answer this question.

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