Carl
Carl

Reputation: 31

Trying to read bitmap file as hexadecimals

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

#define NBRCOLOURS 16
#define COLOURSIZE 8

typedef struct
{
    char colours[COLOURSIZE];

}BITMAP;



//Main Function
void main(void)
{
    int count, count2;
    char bm_file[] = "C:\\Coding\\Bitmap Program\\Sample.bmp";
    FILE *fptr;
    char ch;
    int i = 0;
    BITMAP bm_data[NBRCOLOURS];


    fptr = fopen(bm_file, "rb");
    if (fptr != NULL)
    {
        while ((ch = fgetc(fptr)) != EOF)
        {
            printf("%02X ", ch);
            if (!(++i % 16)) putc('\n', stdout);
        }
    }

    fclose(fptr);

    system("pause");
    return;
}

I am using this code which I found mostly online to try and read the contents of a bitmap file as its hexadecimal values. For some reason, this code stops right at the end of the header, and unfortunately ultimately I need to count the number of times each colour appears so that I can figure out which occurs most and which occurs least.

If anyone could tell me why this code stops at the end of the header for the bitmap, or lead me towards being able to pull the rest of the hexadecimal data out of the file, I would really appreciate it.

Here is the hex code:

42 4D C6 00 00 00 00 00 00 00 76 00 00 00 28 00 
00 00 0A 00 00 00 0A 00 00 00 01 00 04 00 00 00 
00 00 50 00 00 00 12 0B 00 00 12 0B 00 00 10 00 
00 00 10 00 00 00 FF 00 00 00 00 FF 00 00 00 00 
42 00 5A 5A 84 00 00 00 FF 00 FF 00 FF 00 00 FF 
FF 00 08 FF FF 00 5A FF FF 00 FF FF FF 00 FF FF 
FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF 
FF 00 FF FF FF 00 92 59 00 16 47 00 00 00 25 90 
01 64 61 00 00 00 59 90 11 64 61 00 00 00 99 00 
16 48 11 00 00 00 90 01 64 61 11 00 00 00 00 16 
64 61 00 00 00 00 01 16 46 10 09 00 00 00 11 64 
41 00 99 00 00 00 16 64 11 09 95 00 00 00 66 48 
10 09 53 00 00 00

And here is what prints:

42 4D FFFFFFC6 00 00 00 00 00 00 00 76 00 00 00 28 00 
00 00 0A 00 00 00 0A 00 00 00 01 00 04 00 00 00 
00 00 50 00 00 00 12 0B 00 00 12 0B 00 00 10 00 
00 00 10 00 00 00

Long post, I'm sorry. Any help is greatly appreciated.

Upvotes: 2

Views: 147

Answers (2)

Govind Parmar
Govind Parmar

Reputation: 21542

The number before a format specifier in printf, like %02X only guarantees a minimum number of characters outputted, not a maximum. fgetc returns an int, not a char. If the int is negative two's complement then the entire bitstring representing the int will get printed, including the FF bytes at the start. EOF is not representable as a char; only as an int.

In your case we know that the file we're working with is small enough that loading the entire file into a buffer will probably succeed, so we can just use malloc and free instead:

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


typedef unsigned char byte;

int main(int argc, char *argv[])
{
    FILE *fp = fopen("C:\\Coding\\Bitmap Program\\Sample.bmp", "rb");
    byte *buffer = NULL;
    size_t len;
    int i;

    fseek(fp, 0, SEEK_END);

    len = ftell(fp);
    rewind(fp);

    buffer = malloc(len);
    if(!buffer)
    {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    fread(buffer, 1, len, fp);
    fclose(fp);
    for(i = 0; i < len; i++)
    {
        if(i%16==0) putchar('\n');
        printf("%.2X ", buffer[i]&0xFF);

    }
    free(buffer);
    return 0;
}

Upvotes: 0

Jim B.
Jim B.

Reputation: 4704

fgetc returns an int, not a char. You can't represent EOF with a char, as all of the possible values of a char are valid. EOF is (I think) -1 represented as an int, or 0xfffffff, so if you read 0xff as a char it's the same as EOF.

Change this:

char ch;

to:

int ch;

Upvotes: 3

Related Questions