Search code examples
cfile-iojpeg

Matching JPEG signature


I am trying to scan a file looking for 1MB JPEGs that would be stored contiguously. My approach is create a structure to match the first 4 bytes with the JPEG signature and, if true, write the entire 512 buffer to a named file until I find another jpeg signature then I create a new file. The code below creates 2 files, neither of which are readable as the first few bytes are not part of the jpeg signature. Any ideas where I went wrong? I tried variations of my if statement where I test for the signature but no luck thus far.

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

typedef uint8_t  BYTE;

typedef struct
{
    BYTE first;
    BYTE second;
    BYTE third;
    BYTE fourth;
}
JPGTEST;

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

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

    if (inptr == NULL)

    {

        printf("Could not open file\n");

        return 2;

    }

    FILE* outptr;

    //initialize jpeg count and variable for filename
    int count = 0;
    char name[8];

    //allocate memory
    char buffer[512];
    JPGTEST myjpg;
    int is_open = 0;

    while (fread(&buffer, 512, 1, inptr) != 0)
    {

        //test first 4 bytes to see if jpeg
        fread(&myjpg, sizeof(JPGTEST), 1, inptr);

        //if match, name and write to file

        if (myjpg.first == 0xff && myjpg.second == 0xd8 && myjpg.third == 0xff && (myjpg.fourth == 0xe0 || myjpg.fourth == 0xe1))
        {
            sprintf(name, "%03d.jpg", count);
            if (is_open == 0)
            {          
                outptr = fopen(name, "w");
                fwrite(buffer, sizeof(buffer),1,outptr);
                is_open = 1;
            }
            if (is_open == 1)
            {          
                fclose(outptr);
                outptr = fopen(name, "w");
                fwrite(buffer, sizeof(buffer),1,outptr);
                count++;
            }  

        }
        else
        {
            if (is_open == 1)
            {
                fwrite(buffer, sizeof(buffer),1,outptr);
            }
        }
    }
    fclose(inptr);
    fclose(outptr);
    return 0;
}

Solution

  • Replace your second fread inside the loop with the below:

            memcpy((void *)&myjpg, (void *) buffer, sizeof(JPGTEST));
    

    And include string.h header file in your code for memcpy function.

    What you are doing wrong is that after reading first 512 you are not making any use of them rather you are again reading 4 bytes without checking first 4 bytes of previously read 512 bytes.