c 读取 24 bmp

场景:C读取24位BMP图像,该怎么解决

C读取24位BMP图像
写了个程序读取24位的BMP图像,程序如下:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h>
#define A 256
int main()
{
    FILE *fp;
    int n,dis;
    int i,j,num=0,k=0;
    int width,height;
    unsigned char *r,*g,*b;
    unsigned char **R,**G,**B;
    unsigned char *temp;
    if((fp=fopen("t.bmp","rb"))==NULL)
    {
        printf("Can't open file: a.bmp");
        return 0;
    }
    fseek(fp,28,SEEK_SET);
    fread(&n,2,1,fp);
    printf("n=%d\n",n);
    fseek(fp,18,SEEK_SET);
    fread(&width,4,1,fp); /*图像宽*/
    fseek(fp,22,SEEK_SET);
    fread(&height,4,1,fp); /*图像高*/
    printf("width=%d\n",width);
    printf("height=%d\n",height);
    fseek(fp,10,SEEK_SET);
    fread(&dis,4,1,fp);    /*文件头到图像数据的偏移量*/
    printf("distance=%d\n",dis);
    fseek(fp,dis,SEEK_SET);
    if((r=(unsigned char *)malloc(width*height))==NULL)
    {
        printf("error \n");
        exit(0);
    }
    if( (g=(unsigned char *)malloc(width*height))==NULL  )
    {
        printf("error \n");
        exit(0);
    }
    if((b=(unsigned char *)malloc(width*height))==NULL)
    {
        printf("error \n");
        exit(0);
    }
     /*给R,G,B分配内存*/
     if((R=(unsigned char **)malloc(height))==NULL)
     {
        printf("error! \n");
        exit(0);
     }
     for(i=0;i<height;++i)
     {
        R[i]=(unsigned char *)malloc(width);
        if(R[i]==NULL)
        {
            printf("error! \n");
            exit(0);
        }
     }
     if((G=(unsigned char **)malloc(height))==NULL)
     {
        printf("error! \n");
        exit(0);
     }
     for(i=0;i<height;++i)
     {
        G[i]=(unsigned char *)malloc(width);
        if(G[i]==NULL)
        {
            printf("error! \n");
            exit(0);
        }
     }
     if((B=(unsigned char **)malloc(height))==NULL)
     {
        printf("error! \n");
        exit(0);
     }
     for(i=0;i<height;++i)
     {
        B[i]=(unsigned char *)malloc(width);
        if(B[i]==NULL)
        {
            printf("error! \n");
            exit(0);
        }
     }
    /*一次性读取正确*/
    if((temp=(unsigned char*)malloc(width*height*3))==NULL)
    {
        printf("error\n");
        exit(0);
    }

    fread(temp,1,width*height*3,fp);
    i=0;
    k=0;
    while(i<width*height*3)
    {
        b[k]=temp[i];
        ++i;
        g[k]=temp[i];
        ++i ;
        r[k]=temp[i];
        ++i;
        ++k;
    }

    k=0;

    for(i=0;i<=height-1;++i)
    {
        for(j=0;j<width;++j)
        {
            R[height-1-i][j]=r[k*width+j];
            G[height-1-i][j]=g[k*width+j];
            B[height-1-i][j]=b[k*width+j];
        }
        ++k;
    }


    printf("\n");
    printf("display r(1)\n");
    for(i=0;i<width*height;++i)
    {
        printf("%d ",r[i]);
        ++num;
        if(num%width==0)
            printf("\n");
    }

    printf("\n");
    printf("display r(2)\n");
    for(i=0;i<height;++i)
    {
        for(j=0;j<width;++j)
        {
            printf("%d ",R[i][j]);

        }
        printf("\n");
    }
    /*一个一个读取正确*/
   /* while(1)
    {
        b[num]=fgetc(fp);
        g[num]=fgetc(fp);
        r[num]=fgetc(fp);
        if(feof(fp))
        {
            break;
        }
       ++num;
    }
    */
    /*num=0;
    for(i=0;i<width*height;++i)
    {
        printf("%d ",r[i]);
        ++num;
        if(num%width==0)
            printf("\n");
    }
    */

    printf("k=%d",k);
    fclose(fp);
 
    free(r);
    free(g);
    free(b);
    free(R);
    free(G);
    free(B); 
free(temp);
    printf("\n");
    getch();
    return 0;
}
结果用不同的编译器会出现不同的错误,用VC编译会出现内存出错。 用WinTC不会报错但是显示会出错,我尝试在VC中把最后的几个free注释掉几个,注释掉free(b)及后面的free函数就不会报错。请问是不是我的指针内存分配有什么不妥,麻烦帮我看下我的各个指针定义以及内存分配是否合理,请指教!!!

------解决方案--------------------
最好自己写两个结构体
一个是信息头,一个文件头
然后malloc这两个结构体
------解决方案--------------------
位图数据长度计算错误
if((temp=(unsigned char*)malloc(width*height*3))==NULL)

你可以通过位图头信息来获取位图数据的长度,从而得到需要分配空间的长度
实际上应该是这样计算的:
每行所占的字节数:lineByte=(width * 24+31)/32*4;
位图数据所占字节数:height * lineByte
------解决方案--------------------
引用:
位图数据长度计算错误
if((temp=(unsigned char*)malloc(width*height*3))==NULL)

你可以通过位图头信息来获取位图数据的长度,从而得到需要分配空间的长度
实际上应该是这样计算的:
每行所占的字节数:lineByte=(width * 24+31)/32*4;
位图数据所占字节数:height * lineByte


是的,要考虑4字节对齐,而且也要考虑如果位图不是24位的格式。