hey , I'm trying to read a 24 bit bmp file but after reading the first pixel something goes wrong, any ideas?

int i;
        FILE* f = fopen("Sample.bmp", "rb");
        unsigned char info[54];
        fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header

        // extract image height and width from header
        int width = *(int*)&info[18];
        int height = *(int*)&info[22];

        int size = 3 * width * height;

        unsigned char* data = new unsigned char[size]; // allocate 3 bytes per pixel
        fread(data, sizeof(unsigned char), size, f); // read the rest of the data at once
        fclose(f);

        for(int qq=0;qq<SCREEN_WIDTH;++qq)
            for (int kk=0;kk<SCREEN_HEIGHT;++kk)
            {
                PI[qq][kk][0] = data[kk * width + qq];
                PI[qq][kk][1] = data[kk * width + qq + 1];
                PI[qq][kk][2] = data[kk * width + qq + 2];
            }

So, what goes wrong? The main problem I see is your outer loop. You need to increment qq by 3, not 1, and the limit should be qq < (SCREEN_WIDTH * 3), not qq < SCREEN_WIDTH. IE: for (int qq = 0; qq < (SCREEN_WIDTH * 3); qq += 3) as you need 3 bytes for the 24 bit pixel. Also, properly bracket the contents of the outer loop as you do the inner one, otherwise you will likely be bit by the law of unintended consequences... :-)

Finally, to keep the system from recomputing the width on every outer loop, you can set a loop variable instead, as in for (int qq = 0, xx = (SCREEN_WIDTH * 3); qq < xx; qq += 3). Sometimes compilers will optimize the first example, and sometimes not...

Edited 2 Years Ago by rubberman

I think this is the guy from stack overflow that told me he could not change his code when I offered him code that reads a bitmap and finds it on screen :l

Again, you are missing the padding at the end of each bitmap scan line.

Here is how to read a 24-bit bitmap (without std::fstream):

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

typedef struct bitmap
{
    unsigned int width, height;
    unsigned char *pixels;
};

struct bitmap* bmp;

void FreeBmp()
{
    if (bmp && bmp->pixels)
    {
        bmp->width = 0;
        bmp->height = 0;
        free(bmp->pixels);
        free(bmp);
        bmp = NULL;
    }
}

bool LoadBmp(const char *filepath)
{
    bmp = NULL;
    FILE *f = fopen(filepath, "rb");

    if (f)
    {
        bmp = malloc(sizeof(bitmap));
        bmp->width = 0;
        bmp->height = 0;
        bmp->pixels = NULL;

        unsigned char info[54] = {0};
        fread(info, sizeof(unsigned char), 54, f);

        bmp->width = *(unsigned int *)&info[18];
        bmp->height = *(unsigned int *)&info[22];

        unsigned int size = ((((bmp->width * bmp->height) + 31) & ~31) / 8) * bmp->height;
        bmp->pixels = malloc(size);
        fread(bmp->pixels, sizeof(unsigned char), size, f);
        fclose(f);

        for(int i = 0; i < size; i += 3)
        {
            unsigned char tmp = bmp->pixels[i];
            bmp->pixels[i] = bmp->pixels[i + 2];
            bmp->pixels[i + 2] = tmp;
        }
        return true;
    }

    return false;
}

int main()
{
    LoadBmp("/users/Brandon/Desktop/t.bmp");
    //....
    FreeBmp();
}

Edited 2 Years Ago by triumphost

This article has been dead for over six months. Start a new discussion instead.