我无法加载.BMP图像

时间:2014-05-11 23:16:20

标签: c++ graphics

我是opengl的新手。我正在尝试使用opengl加载图像。但我无法这样做。它给了我这个错误:

*** Error in `./lena': double free or corruption (top) : 0x0000000001353070 ***

我不知道自己做错了什么。我的代码已在下面给出。实际上这不是我的代码。我在Stack Overflow的另一篇文章中看到了它,名字叫Ollo。

#include <bits/stdc++.h>
#include <GL/glut.h>

using namespace std;

struct BITMAPFILEHEADER
{
    int bfType;  //specifies the file type
    long long bfSize;  //specifies the size in bytes of the bitmap file
    int bfReserved1;  //reserved; must be 0
    int bfReserved2;  //reserved; must be 0
    long long bOffBits;  //species the offset in bytes from the bitmapfileheader to the bitmap bits
};

struct BITMAPINFOHEADER
{
    long long biSize;  //specifies the number of bytes required by the struct
    long long biWidth;  //specifies width in pixels
    long long biHeight;  //species height in pixels
    int biPlanes; //specifies the number of color planes, must be 1
    int biBitCount; //specifies the number of bit per pixel
    long long biCompression;//spcifies the type of compression
    long long biSizeImage;  //size of image in bytes
    long long biXPelsPerMeter;  //number of pixels per meter in x axis
    long long biYPelsPerMeter;  //number of pixels per meter in y axis
    long long biClrUsed;  //number of colors used by th ebitmap
    long long biClrImportant;  //number of colors that are important
};

int main(void){
    FILE *filePtr;
    BITMAPFILEHEADER bitmapFileHeader;
    BITMAPINFOHEADER *bitmapInfoHeader = new BITMAPINFOHEADER;
    unsigned char *bitmapImage;  //store image data
    int imageIdx=0;  //image index counter
    unsigned char tempRGB;  //our swap variable

    filePtr = fopen("lena.bmp","rb");
    if (filePtr == NULL)
        cout << "ERROR!!! 1" << endl;
    fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER),1,filePtr);

    fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr); // small edit. forgot to add the closing bracket at sizeof

    //move file point to the begging of bitmap data
    fseek(filePtr, bitmapFileHeader.bOffBits, SEEK_SET);

    //allocate enough memory for the bitmap image data
    bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);

    //verify memory allocation
    if (!bitmapImage)
    {
        free(bitmapImage);
        fclose(filePtr);
    }

    //read in the bitmap image data
    fread(bitmapImage, bitmapInfoHeader->biSizeImage, 1, filePtr);

    //make sure bitmap image data was read
    if (bitmapImage == NULL)
    {
        fclose(filePtr);
    }

    //swap the r and b values to get RGB (bitmap is BGR)
    for (imageIdx = 0;imageIdx < bitmapInfoHeader->biSizeImage;imageIdx+=3)
    {
        tempRGB = bitmapImage[imageIdx];
        bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
        bitmapImage[imageIdx + 2] = tempRGB;
    }

    return 0;
}

3 个答案:

答案 0 :(得分:2)

您在StackOverflow上从another answer获得的代码存在一些棘手的问题。

  1. 检查bitmapImage是否 0 ,如果是,则会立即拨打free (...)上的bitmapImage
  2. 失败时需要 返回 以防止崩溃。
  3. fread (...)不会更改bitmapImageNULL
  4. 以下是您需要进行的一些最小更改:

    if (filePtr == NULL) {
        cout << "ERROR!!! 1" << endl;
        return -1; // FAILURE, so return!
    }
    
    [...]
    
    //allocate enough memory for the bitmap image data
    bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
    
    //verify memory allocation
    if (!bitmapImage)
    {
        //free(bitmapImage); // This does not belong here!
        fclose(filePtr);
        return -2; // FAILURE, so return!
    }
    
    //read in the bitmap image data
    fread(bitmapImage, bitmapInfoHeader->biSizeImage, 1, filePtr);
    
    // THIS IS POINTLESS TOO, fread (...) is not going to change the address of
    //                          bitmapImage.
    /*
    //make sure bitmap image data was read
    if (bitmapImage == NULL)
    {
        fclose(filePtr);
    }
    */
    
    //swap the r and b values to get RGB (bitmap is BGR)
    for (imageIdx = 0;imageIdx < bitmapInfoHeader->biSizeImage;imageIdx+=3)
    {
        tempRGB = bitmapImage[imageIdx];
        bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
        bitmapImage[imageIdx + 2] = tempRGB;
    }
    

答案 1 :(得分:0)

正如我在评论中所提到的,你不应该编写自己的代码来读取.bmp文件(除非是为了作业,或类似的东西)。你说你是关于模仿linux的,所以你可以试试FreeImageImageMagick。您使用的代码不会处理索引颜色图像,例如,可能还有许多其他东西。

答案 2 :(得分:0)

这就是我加载每个像素24位的BMP文件的方式,而不是索引颜色位图的加载方式,请从此处下载winbgim:http://www.mediafire.com/file/z9wnl0c70tiacqn/winbgim_DevCpp.zip/file,是在dev-c ++中,您可能必须加载几个参数链接器,路径为:项目,项目选项,参数,并编写:-lbgi -lgdi32 -luser32 -lcomdlg32 -luuid -loleaut32 -lole32 -mwindows -lwinmm,在安装winbgim之后,转到dev c并创建新的作为控制台图形应用程序的项目,如果正确安装了winbgim,则该项目必须在项目列表中, 我写了“写到共享内存”,因为虽然我不是用这种方式访问​​文件的,但也是从同一个文件访问的,所以我也在内存中写了文件

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

 const char *Filename;

 BITMAPFILEHEADER FileHeader;
 BITMAPINFOHEADER InfoHeader;
 int k;
 typedef struct{
 BYTE colorr;
 BYTE colorg;
 BYTE colorb;
 }cine;

 cine color;

 HANDLE hArch, hProy;
 LPSTR base,puntero;
 DWORD tam;
 int main()
 {
 int gdriver=9;
 int gmode=2;
 // initgraph(&gdriver,&gmode, "");
 cleardevice();

 UnmapViewOfFile(base);
 CloseHandle(hProy);
 CloseHandle(hArch);
 char *p;
 char *base;
 DWORD buf;
 Filename="D:\\music\\IMSLP00795-BWV0971\\01.bmp";
 int gd = DETECT, gm;
 int x = 320, y = 240, radius;
 k=0;

 int i;
 int j;




 FILE *File=NULL;
 if(!Filename)
 {
 MessageBox(NULL,"Konnte Filename nicht  finden!","Error",MB_OK|MB_ICONERROR);
 }
 else
 {
 File=fopen("D:\\music\\IMSLP00795-BWV0971\\01.bmp","rb");
 }

 fread(&FileHeader,sizeof(BITMAPFILEHEADER),1,File);
 if(FileHeader.bfType != 0x4D42)
 {
 MessageBox(NULL,"Ungültiges Bildformat!","Error",MB_OK|MB_ICONERROR);
 exit(1); 
 }
 printf("tamaño total del archivo %d\n",FileHeader.bfSize);
 printf("comienzo del mapa de bits (imagen en pixels) en bits         %d\n",FileHeader.bfOffBits);

 buf=FileHeader.bfOffBits/8; //offset from the begining of BMP file (pixel array)
 printf("comienzo del mapa de bits en bytes desde el origen del archivo      %d\n",buf);
 fread(&InfoHeader,sizeof(BITMAPINFOHEADER),1,File);

 printf("horizontal resolution in pixels por metro %li\n",InfoHeader.biWidth);
 printf("vertical resolution in pixels por metro %li\n",InfoHeader.biHeight);
 printf("numero de bits por pixel %d", InfoHeader.biBitCount);
 initwindow(InfoHeader.biWidth,InfoHeader.biHeight);


 hArch = CreateFile("D:\\music\\IMSLP00795-BWV0971\\01.bmp", /* file  name */
 GENERIC_ALL , /* read/write access */
 0, /* no sharing of the file */
 NULL, /* default security */
 OPEN_ALWAYS, /* open new or existing file */
 FILE_ATTRIBUTE_NORMAL, /* routine file attributes */
 NULL); /* no file template */
 if (hArch==INVALID_HANDLE_VALUE){

 fprintf(stderr,"no puede abrirse el archivo");

 }

 hProy = CreateFileMapping(hArch, /* file handle */
 NULL, /* default security */
 PAGE_READWRITE, /* read/write access to mapped pages */
 0, /* map entire file */
 0,
 TEXT("SharedObject")); /* named shared memory object */

 /* write to shared memory */
 base=(LPSTR)MapViewOfFile(hProy,FILE_MAP_ALL_ACCESS,0,0,0);
 tam=GetFileSize(hArch,NULL);
 int cont=0;
 puntero=base;
 p=base+FileHeader.bfOffBits;
 k=0;int t=0,v,l;
 fseek(File,FileHeader.bfOffBits,SEEK_SET );
 int read=0,read2=0;
 k=0;
 for( i=0; i<InfoHeader.biWidth; i++ ) {
       fread(&color,sizeof(cine),1,File);
        read += sizeof(cine);
        printf( "Pixel %d: %3d %3d %3d\n", i+1, int(color.colorb),         int(color.colorg), int(color.colorr) );
    }
    if( read % 4 != 0 ) {
        read2 = 4 - (read%4);
        printf( "Padding: %d bytes\n", read2 );
        //fread( &color, read2, 1, File );

    }
    fseek(File,FileHeader.bfOffBits,SEEK_SET );
    for (i=0;i<InfoHeader.biHeight;i++)
 for(j=0;j<InfoHeader.biWidth ;j++)

{
 fread(&color,sizeof(cine),1,File);

 putpixel(j,InfoHeader.biHeight-  i,COLOR(int(color.colorb),int(color.colorg),int(color.colorr)));
 if(j==InfoHeader.biWidth-1&&read2!=0)fseek(File,read2,SEEK_CUR);
} 
 fclose(File);

 UnmapViewOfFile(base);
 CloseHandle(hProy);
 CloseHandle(hArch);
 getch();
}