Domanda

I am new to opengl. I am trying to load an image using opengl. But I am unable to do so. It gives me this error:

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

I don't know what I am doing wrong. My code has been given below. Actually it is not my code. I have seen it in another post in Stack Overflow by someone named 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;
}
È stato utile?

Soluzione

This code that you got from another answer on StackOverflow has some awkward issues.

  1. It checks to see if bitmapImage is 0 and if it is, it immediately calls free (...) on bitmapImage
  2. It needs to return on failure in order to prevent crashing.
  3. fread (...) does not change whether or not bitmapImage is NULL

Here are some minimum changes that you need to make:

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;
}

Altri suggerimenti

As mentioned in my comment, you should not be writing your own code to read in a .bmp file (unless it's for an assignment, or something like that). You say you're on mint linux, so you might try either FreeImage or ImageMagick. The code you're using doesn't handle index color images, for example, and probably a host of other things.

that's how I load a BMP file of 24 bits per pixel, not for indexed colour bitmaps, download winbgim from here: http://www.mediafire.com/file/z9wnl0c70tiacqn/winbgim_DevCpp.zip/file, is in dev-c++, you probably have to load a couple of parameters for the linker, the path is: project, project options, parameters, and write: -lbgi -lgdi32 -luser32 -lcomdlg32 -luuid -loleaut32 -lole32 -mwindows -lwinmm, one thing more, after installing winbgim, go to dev c and create new project as console graphics application, this item must be in the project list if winbgim is properly installed, I wrote "write to shared memory", because I wrote the file also in memory although I did not access the file this way, but from the same file

 #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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top