Problem mit LoadImage/GetDIBits [gelöst]
-
Moin,
ich habe wieder das Vergnügen, mich mit der WinAPI beschäftigen zu dürfen.
Ich möchte eine simple Bitmapdatei laden und von dieser unabhängig von ihrer tatsächlichen Farbtiefe die Pixel auslesen.Das Problem: die Zeile 38 (delete[] pBits) führt bei bestimmten Dateien und Auflösungskombinationen zum Programmabsturz. Wenn der Debugger läuft, bekomme ich zweimal SIGTRAP. Wenn ich beidesmal continue wähle, läuft das Programm weiter und zeigt das Bitmap korrekt an (call stack sieht so aus).
Der auskommentierte Code ist für das Anzeigen des Bitmaps zuständig. Zusätzlich wird das Bitmap dort in eine Datei gespeichert; das funktioniert immer und die Datei enthält immer die korrekte Darstellung, unabhängig davon, ob das Programm wenige Zeilen später abstürzt oder nicht. Es macht ebenfalls keinen Unterschied, ob der Code zum Anzeigen auskommentiert ist oder nicht. Das Problem tritt sowohl im Release- wie auch im Debug-Build auf.
Ich habe auch schon versucht, 8 statt 4 bytes pro Pixel bereitzustellen, falls GetDIBits aus irgendeinem Grund mehr schreibt als es soll. Macht aber auch keinen Unterschied.
Wenn ich Zeile 38 auskommentiere, läuft natürlich alles wie am Schnürchen... aber der Speicher wird mit der Zeit vollgemüllt.Sieht vielleicht jemand einen Fehler im Code? Ich weiß nämlich gerade nicht mehr weiter

HANDLE h=LoadImage(NULL,FileName.c_str(),IMAGE_BITMAP,0,0,LR_LOADFROMFILE); if (!h)delete this; else { HBITMAP b=reinterpret_cast<HBITMAP>(h); HDC hdc=CreateCompatibleDC(GetDC(NULL)); assert(hdc); BITMAPINFO BitmapInfo; memset(&BitmapInfo,0,sizeof(BitmapInfo)); BitmapInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); if (GetDIBits(hdc,b,0,0,NULL,&BitmapInfo,DIB_RGB_COLORS)) { const int W=BitmapInfo.bmiHeader.biWidth,H=BitmapInfo.bmiHeader.biHeight; byte* pBits=new byte[W*H*4]; BitmapInfo.bmiHeader.biBitCount=32; if (GetDIBits(hdc,b,0,H,pBits,&BitmapInfo,DIB_RGB_COLORS)!=H) { delete[] pBits; delete this; return; } /*CreateWindow(CreateGenericBorder(W,H),true); TSprite Sprite; Sprite.CreateBitmap(W,H,32); for (int y=0;y<H;y++) { for (int x=0;x<W;x++) { Sprite.SetPixel(x,H-y-1,RGB(pBits[2],pBits[1],pBits[0])); pBits+=4; } } Sprite.SaveToFile(GetBasePath()+"\\dbgout.bmp"); CreateLabel(0,0,Sprite.GetBitmap());*/ DeleteObject(h); DeleteDC(0,hdc); delete[] pBits; } else delete this; }Edit: es ist bemerkenswert, was etwas Schlaf ausrichten kann.
Offensichtlicher geht es ja gar nicht mehr...