Search code examples
cfopenfreadbmp

C not reading entire BMP file - fopen


So I am trying to read a .bmp file in C. I am later going to encrypt the file using openssl libraries - but that's only background info.

I need to open the file in binary mode (obviously) but for whatever reason when I try to open the file, it only reads in 4 bytes. When I try to output this exact file I just opened (for error testing) it outputs the following - 88 24 AD FB.

In my troubleshooting I decided to try this on a text file (54 bytes) and I get the exact same result.

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>

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

int main(){

    char * fileName="pic_original.bmp";

    //read the file from given filename in binary mode
    printf("Start to read the .bmp file \n");

    FILE *image;
    image = fopen(fileName,"rb");

    //print the size of the image (4 bytes every damn time)
    printf("Size of image: %d\n",sizeof(image));

    //output the exact file that was read (error testing)
    FILE *test;
    test = fopen("./test.bin", "w");
    fwrite(image, sizeof(image), 1, test);

    fclose(test);
    fclose(image);


    return 1;
}

This is the image (uploaded as png for some reason)

image

Not exactly sure where I'm going wrong here but I'm not very seasoned in C.

Cheers, Liam

EDIT 1:

//allocate memory for the header and image
char *headerBuf = (char *)malloc(54);
char *imageBuf = (char *)malloc(sizeof(image)-54); //this line is wrong - thanks to user EOF

//allocate memory for the final ciphertext
char *imagecipherCBC = (char *)malloc(sizeof(image)); //wrong also

//read first 54 bytes (header)
rewind(image);
fread(headerBuf,54,1,image);

//read the bitmap image until the end of the file
fread(imageBuf,sizeof(image),1,image); //also wrong

Solution

  • Well, The size of the image is of course, 4 bytes which is a file pointer on a 32 bit machine.

    I think you have to prepare some image buffer of your bmp file as a simple example, then you can do encrypt and decrypt the contents of this image buffer if your file is not too big.

    static void read_from_image(char *imageBuf, int fileLength)
    {
        const char * outFileName="c:/DEV/temp/test.bin";
        char headerBuf[54];
        char *imagecipherCBC;
    
        FILE *test;
        test = fopen(outFileName, "wb");
    
        //allocate memory for the final ciphertext
        imagecipherCBC = (char *)malloc(fileLength *sizeof(char));
    
        //read first 54 bytes (header)
        //fread(headerBuf,54,1,image);
        memcpy(headerBuf, imageBuf, 54 * sizeof(char));
    
        //read the bitmap image until the end of the file
        //fread(imageBuf,sizeof(image),1,image); //also wrong
    
        fwrite(imageBuf, fileLength * sizeof(char), 1, test);
        fflush(test);
        fclose(test);
    
        free(imagecipherCBC),imagecipherCBC = NULL;
        free(imageBuf),imageBuf = NULL;
    
        return;
    }
    

    You can have a file length and an image buffer in a main function.

        int main(int argc, char *argv[])
    {
        const char * fileName="c:/DEV/temp/pic_original.bmp";
    
        int fileLength = 0;
    
        FILE *image;
        char *imageBuffer;
    
        imageBuffer = NULL;
        image = fopen(fileName,"rb");
    
        printf("read the file from given filename in binary mode \n");
        printf("Start to read the .bmp file \n");
    
        //try to get a file length;
        fseek(image, 0, SEEK_END);
        fileLength = ftell(image);
        fseek(image, 0, SEEK_SET);
        rewind(image);
    
        imageBuffer = (char*)malloc(fileLength * sizeof(char));
    
        //print the size of the image (4 bytes every damn time)
        printf("read the file from given filename in binary mode \n");
        printf("Size of image file pointer: %d\n",sizeof(image));
        printf("Size of image: %d\n",fileLength);
    
        //output the exact file that was read (error testing)
        fread(imageBuffer,sizeof(char),fileLength*sizeof(char), image);
    
        fclose(image);
    
        read_from_image(imageBuffer, fileLength);
    
        return 0;
    }
    

    good luck