Search code examples
arrayscimageprintfcs50

My code prints a hex that is not valid for an image, it's not a value from the array that I am comparing. I don't understand where is coming from


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

int main() 
{
    // open image
    FILE *image = fopen("me.jpg", "r");
    // read image
    // check if file is NULL
    if(image == NULL) 
    {
        return 1;
    }
    // store char signature in array
    unsigned char signature[4];
    // store extra
    unsigned char extra[16] = 
    {
      0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
      0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef
    };
    // read signature
    fread(signature, 4, 1, image);
    // read extra
    char extrahex = fread(extra, 16, 1, image);
    // find extra in the image
    for (int i = 0; i < 16; i++) 
    {
        if(extra[i] == extrahex)
        {
            printf("%#04x\n", extrahex);
            return 0;
            char hexnum = extrahex;
            // condition for jpeg
            if(signature[0] == 0xff && signature[1] == 0xd8 && signature[2] == 0xff && signature[3] == hexnum) 
            {
                printf("valid jpeg format\n");
            } 
            else 
            {
                printf("not a valid jpeg format\n");
            }
            return 0;
        }
    }
    fclose(image);
}

the return value that is printed is: 0x01, this is not a value from the extra array that I am checking against the image. And of course, the result is "not a valid jpg format". I tried a different image, it prints the same 0x01 value.

enter image description here


Solution

  • You do not need to make another call to fread. Instead, you must check if signature[3] is one of the known values stored in extra.

    #include <stdio.h>
    
    int main(void)
    {
        FILE *image = fopen("me.jpg", "r");
    
        if (!image)
        {
            return 1;
        }
    
        unsigned char signature[4];
        unsigned char extra[16] = {
            0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
            0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef
        };
    
        fread(signature, 4, 1, image);
        fclose(image);
    
        if (signature[0] == 0xff && signature[1] == 0xd8 && signature[2] == 0xff)
        {
            for (size_t i = 0; i < 16; i++)
            {
                if (signature[3] == extra[i])
                {
                    puts("valid jpeg format");
                    return 0;
                }
            }
        }
    
        puts("not a valid jpeg format");
    }
    

    Alternatively, check that the first four bits of signature[3] are 1110 (0xe).

    #include <stdio.h>
    
    int main(void)
    {
        FILE *image = fopen("me.jpg", "r");
    
        if (!image)
        {
            return 1;
        }
    
        unsigned char signature[4];
    
        fread(signature, 4, 1, image);
        fclose(image);
    
        if (signature[0] == 0xff &&
            signature[1] == 0xd8 &&
            signature[2] == 0xff &&
            (signature[3] >> 4) == 0xe)
        {
            puts("valid jpeg format");
        }
        else
        {
            puts("not a valid jpeg format");
        }
    }