[Asm] Problem z zapisem bitmapy do pliku

0

Piszę program, w którym rysuję pewne rzeczy na bitmapie. Normalnie bitmapa jest tworzona za pomoca CreateCompatibleBitmap, jednakze nigdzie nie znalazlem sposobu zapisu takiej bitmapy do pliku (jesli ktos moze udostepnic, chocby w C++, bede wdzieczny). Dlatego gdy musialem dodac opcje generowania bitmapy tylko i wylacznie do zapisu do pliku, zrobilem to tak:

invoke GetDC,0				;pobierz DC ekranu
mov hTemp,eax
invoke CreateCompatibleDC,hTemp		;utworz wirtualny DC
mov hVirtDC,eax
invoke ReleaseDC,0,hTemp		;zwolnij DC ekranu
mov SaveBitmapInfo.biSize,SIZEOF(BITMAPINFOHEADER)
m2m SaveBitmapInfo.biWidth,tempwd
m2m SaveBitmapInfo.biHeight,temphgt
mov SaveBitmapInfo.biPlanes,1
mov SaveBitmapInfo.biBitCount,8
mov SaveBitmapInfo.biCompression,BI_RGB
fild tempwd
fimul temphgt
fimul SaveBitmapInfo.biBitCount
fistp SaveBitmapInfo.biSizeImage
mov SaveBitmapInfo.biClrUsed,0
mov SaveBitmapInfo.biClrImportant,0
invoke CreateDIBSection,0,ADDR SaveBitmapInfo,DIB_RGB_COLORS,ADDR SaveBuffer,NULL,0	;utworz wirtualna bitmape
mov hVirtBitmap,eax
invoke SelectObject,hVirtDC,hVirtBitmap ;powiarz wirtualna bitmape z wirtualnym DC
invoke DrawTriangle,hVirtDC,tempwd,temphgt,iterations	;wyrysuj trojkat na wirtualnym DC
invoke CreateFile,SADD("E:\test.bmp"),GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL
mov SaveFileHandle,eax
mov SaveBitmapHeader.bfType,04d42H
mov eax,1024
add eax,SIZEOF(BITMAPFILEHEADER)
mov SaveBitmapHeader.bfOffBits,eax
fild SaveBitmapHeader.bfOffBits
fiadd SaveBitmapInfo.biSize
fist SaveBitmapHeader.bfOffBits
fiadd SaveBitmapInfo.biSizeImage
fistp SaveBitmapHeader.bfSize
mov SaveBitmapHeader.bfReserved1,0
mov SaveBitmapHeader.bfReserved2,0
invoke WriteFile,SaveFileHandle,ADDR SaveBitmapHeader,SIZEOF(BITMAPFILEHEADER),ADDR WriteBuffer,NULL
invoke WriteFile,SaveFileHandle,ADDR SaveBitmapInfo,SIZEOF(BITMAPINFOHEADER),ADDR WriteBuffer,NULL
invoke WriteFile,SaveFileHandle,ADDR SaveRGBPalette,1024,ADDR WriteBuffer,NULL
invoke WriteFile,SaveFileHandle,SaveBuffer,SaveBitmapInfo.biSizeImage,ADDR WriteBuffer,NULL
invoke CloseHandle,SaveFileHandle

Niestety gdzies jest tu jakis dziwny blad. Rysunki na bitmapie wykonuja sie dobrze (sprawdzilem kopiujac jej zawartosc do okna), ale zapis jest mozliwy tylko dla bardzo malych bitmap (np. 20x20 pikseli) dla wiekszych zapisuja sie same naglowki (1072 bajty). Prosilbym o pomoc.

0

(jesli ktos moze udostepnic, chocby w C++, bede wdzieczny)

Z MSDN'u:

void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, 
                  HBITMAP hBMP, HDC hDC) 
 { 
     HANDLE hf;       
    BITMAPFILEHEADER hdr;
    PBITMAPINFOHEADER pbih;
    LPBYTE lpBits;              
    DWORD dwTotal;          
    DWORD cb;                  
    BYTE *hp;                  
    DWORD dwTmp; 

    pbih = (PBITMAPINFOHEADER) pbi; 
    lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

    if (!lpBits) 
         errhandler("GlobalAlloc", hwnd); 

    // Retrieve the color table (RGBQUAD array) and the bits 
    // (array of palette indices) from the DIB. 
    if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, 
        DIB_RGB_COLORS)) 
    {
        errhandler("GetDIBits", hwnd); 
    }

    // Create the .BMP file. 
    hf = CreateFile(pszFile, 
                   GENERIC_READ | GENERIC_WRITE, 
                   (DWORD) 0, 
                    NULL, 
                   CREATE_ALWAYS, 
                   FILE_ATTRIBUTE_NORMAL, 
                   (HANDLE) NULL); 
    if (hf == INVALID_HANDLE_VALUE) 
        errhandler("CreateFile", hwnd); 
    hdr.bfType = 0x4d42;        // 0x42 = "B" 0x4d = "M" 
    // Compute the size of the entire file. 
    hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + 
                 pbih->biSize + pbih->biClrUsed 
                 * sizeof(RGBQUAD) + pbih->biSizeImage); 
    hdr.bfReserved1 = 0; 
    hdr.bfReserved2 = 0; 

    // Compute the offset to the array of color indices. 
    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + 
                    pbih->biSize + pbih->biClrUsed 
                    * sizeof (RGBQUAD); 

    // Copy the BITMAPFILEHEADER into the .BMP file. 
    if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
        (LPDWORD) &dwTmp,  NULL)) 
    {
       errhandler("WriteFile", hwnd); 
    }

    // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
    if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
                  + pbih->biClrUsed * sizeof (RGBQUAD), 
                  (LPDWORD) &dwTmp, ( NULL)) 
        errhandler("WriteFile", hwnd); 

    // Copy the array of color indices into the .BMP file. 
    dwTotal = cb = pbih->biSizeImage; 
    hp = lpBits; 
    if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) 
           errhandler("WriteFile", hwnd); 

    // Close the .BMP file. 
     if (!CloseHandle(hf)) 
           errhandler("CloseHandle", hwnd); 

    // Free memory. 
    GlobalFree((HGLOBAL)lpBits);
}

0

Dziękuję, pomogło mi znaleŹć jeden błąd. Drugi wynikał z tego, że część zmiennych nie mogła byc lokalna.

1 użytkowników online, w tym zalogowanych: 0, gości: 1