Thread: How change the bmp bits data?

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    71

    How change the bmp bits data?

    I wanna to change the bmp bits data,but i receive an-"don't send/send error report" wenn i save the bmp file.
    In my code i use this and this.


    Code:
    #include <windows.h>
    #include <stdlib.h>
     
    typedef struct tagRGBTriplet
    {
    	BYTE red;
    	BYTE green;
    	BYTE blue;
    } RGBTriplet;
    BYTE *bt;
    BYTE* ConvertBMPToRGBBuffer ( BYTE* Buffer, int width, int height )
    {
    	if ( ( NULL == Buffer ) || ( width == 0 ) || ( height == 0 ) )
    		return NULL;
    	unsigned int padding = 0;
    	unsigned int scanlinebytes = width * 3;
    	while ( ( scanlinebytes + padding ) % 4 != 0 )
    		padding++;
    	int psw = scanlinebytes + padding;
    	BYTE* newbuf =(BYTE*)malloc(width*height*3);
    	long bufpos = 0;   
    	long newpos = 0;
    	for ( int y = 0; y < height; y++ )
    		for ( int x = 0; x < 3 * width; x+=3 )
    		{
    			newpos = y * 3 * width + x;     
    			bufpos = ( height - y - 1 ) * psw + x;
    
    			newbuf[newpos] = Buffer[bufpos + 2];       
    			newbuf[newpos + 1] = Buffer[bufpos+1]; 
    			newbuf[newpos + 2] = Buffer[bufpos];     
    		}
    	return newbuf;
    }
    
    BYTE* ConvertRGBToBMPBuffer ( BYTE* Buffer, int width, int height, 
    	long* newsize )
    {
    	if ( ( NULL == Buffer ) || ( width == 0 ) || ( height == 0 ) )
    		return NULL;
    int padding = 0;
    	int scanlinebytes = width * 3;
    	while ( ( scanlinebytes + padding ) % 4 != 0 ) 
    		padding++;
    	int psw = scanlinebytes + padding;
    	*newsize = height * psw;
    	BYTE* newbuf =(BYTE*)malloc(*newsize);
    	memset ( newbuf, 0, *newsize );
    
    	long bufpos = 0;   
    	long newpos = 0;
    	for ( int y = 0; y < height; y++ )
    		for ( int x = 0; x < 3 * width; x+=3 )
    		{
    			bufpos = y * 3 * width + x;     // position in original buffer
    			newpos = ( height - y - 1 ) * psw + x; // position in padded buffer
    			newbuf[newpos] = Buffer[bufpos+2];       // swap r and b
    			newbuf[newpos + 1] = Buffer[bufpos + 1]; // g stays
    			newbuf[newpos + 2] = Buffer[bufpos];     // swap b and r
    		}
    	return newbuf;
    }
     
    PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp);
    void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, 
                      HBITMAP hBMP, HDC hDC);
     
    const char g_szClassName[] = "myWindowClass";
     
    #define DESEN_LINIE 2001
    #define DESEN_TRIUNGHI 2002
    #define DESEN_DREPTUNGHI 2003
    #define DESEN_PATRAT 2004
    #define DESEN_PUNCT 2005
     
    #define FILE_OPEN 3001
    #define FILE_SAVE 3002
    #define FILE_EXIT 3003
     
    int i=0,j=0;
    int cScreenX,cScreenY;
    POINTS ptsLinie;
     
    #include <windows.h>
    #include "abc.h"
     
    HINSTANCE hInst;
    LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
     
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASSEX  WndCls;
        static char szAppName[] = "BitmapIntro";
        MSG         Msg;
     
        hInst       = hInstance;
        WndCls.cbSize        = sizeof(WndCls);
        WndCls.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
        WndCls.lpfnWndProc   = WindProcedure;
        WndCls.cbClsExtra    = 0;
        WndCls.cbWndExtra    = 0;
        WndCls.hInstance     = hInst;
        WndCls.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        WndCls.hCursor       = LoadCursor(NULL, IDC_ARROW);
        WndCls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        WndCls.lpszMenuName  = NULL;
        WndCls.lpszClassName = szAppName;
        WndCls.hIconSm       = LoadIcon(hInstance, IDI_APPLICATION);
        RegisterClassEx(&WndCls);
     
        CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                              szAppName,
                              "Bitmaps Fundamentals",
                              WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              CW_USEDEFAULT,
                              NULL,
                              NULL,
                              hInstance,
                              NULL);
     
        while( GetMessage(&Msg, NULL, 0, 0) )
        {
            TranslateMessage(&Msg);
            DispatchMessage( &Msg);
        }
     
        return Msg.wParam;
    }
     
    LRESULT CALLBACK WindProcedure(HWND hwnd, UINT Msg,
                   WPARAM wParam, LPARAM lParam)
    {
        static HDC hdc,memDC;
        static PAINTSTRUCT ps;
        static HBITMAP hBmpOld;
        static HBITMAP hBmpImage;
        static PBITMAPINFO pBmpInfo;
        static POINTS ptsBegin;
        switch(Msg)
        {
            case WM_CREATE:
            {
                HMENU hMenu, hSubMenu;
                hMenu = CreateMenu();
     
                hSubMenu=CreatePopupMenu();
                AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
                AppendMenu(hSubMenu, MF_STRING,FILE_OPEN, "OPEN");      
                AppendMenu(hSubMenu, MF_STRING,FILE_SAVE, "SAVE");  
                AppendMenu(hSubMenu, MF_STRING,FILE_EXIT, "EXIT");
     
                SetMenu(hwnd, hMenu);
     
     
                hdc=GetDC(hwnd);
                hBmpImage=(HBITMAP)LoadImage(NULL,"abc.bmp",IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
                if (hBmpImage==NULL)
                    MessageBox(hwnd,"da","da",MB_OK);
                // Create a memory device compatible with the above DC variable
                memDC = CreateCompatibleDC(hdc);
                // Select the new bitmap
                hBmpOld=SelectObject(memDC,hBmpImage);
                cScreenX=GetSystemMetrics(SM_CXSCREEN);
                cScreenY=GetSystemMetrics(SM_CYSCREEN);
            }
            break;
            case WM_COMMAND:
            {
                switch(LOWORD(wParam))
                {
                    case FILE_SAVE:
                        pBmpInfo=CreateBitmapInfoStruct(hwnd,hBmpImage);
                        CreateBMPFile(hwnd,"blabla2.bmp",pBmpInfo,hBmpImage,hdc);
                    break;
                }
            }
            break;
            case WM_PAINT:
            {
                hdc = BeginPaint(hwnd, &ps);
                // Copy the bits from the memory DC into the current dc
                BitBlt(hdc, 0, 0,cScreenX,cScreenY,memDC, 0, 0, SRCCOPY);
                // Restore the old bitmap
                EndPaint(hwnd, &ps);
                ++i;
            }
            break;
            case WM_MOUSEMOVE:
            {
                ptsBegin=MAKEPOINTS(lParam);
                LineTo(memDC,ptsBegin.x,ptsBegin.y);
            }
            break;
            case WM_DESTROY:
            {
                SelectObject(memDC,hBmpOld);
                DeleteDC(memDC);
                DeleteObject(hBmpImage);
                PostQuitMessage(WM_QUIT);
            }
            break;
            default:
                return DefWindowProc(hwnd, Msg, wParam, lParam);
        }
        return 0;
     
     
    }
     
    PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)
    { 
        BITMAP bmp; 
        PBITMAPINFO pbmi; 
        WORD    cClrBits; 
     
        // Retrieve the bitmap color format, width, and height.  
        if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) 
            MessageBox(hwnd,"da","da",MB_OK);
    
        // Convert the color format to a count of bits.  
        cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); 
        if (cClrBits == 1) 
            cClrBits = 1; 
        else if (cClrBits <= 4) 
            cClrBits = 4; 
        else if (cClrBits <= 8) 
            cClrBits = 8; 
        else if (cClrBits <= 16) 
            cClrBits = 16; 
        else if (cClrBits <= 24) 
            cClrBits = 24; 
        else cClrBits = 32;
    
            // Allocate memory for the BITMAPINFO structure. (This structure  
        // contains a BITMAPINFOHEADER structure and an array of RGBQUAD  
        // data structures.)  
     
         if (cClrBits < 24) 
             pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 
                        sizeof(BITMAPINFOHEADER) + 
                        sizeof(RGBQUAD) * (1<< cClrBits)); 
     
         // There is no RGBQUAD array for these formats: 24-bit-per-pixel or 32-bit-per-pixel 
     
         else
             pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 
                        sizeof(BITMAPINFOHEADER)); 
     
        // Initialize the fields in the BITMAPINFO structure.  
     
        pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
        pbmi->bmiHeader.biWidth = bmp.bmWidth; 
        pbmi->bmiHeader.biHeight = bmp.bmHeight; 
        pbmi->bmiHeader.biPlanes = bmp.bmPlanes; 
        pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; 
        if (cClrBits < 24) 
            pbmi->bmiHeader.biClrUsed = (1<<cClrBits); 
        if(pbmi->bmiHeader.biCompression == BI_RGB)
    	{
    		MessageBox(hwnd,"da","nu",MB_OK);
    	} 
        // If the bitmap is not compressed, set the BI_RGB flag.  
        pbmi->bmiHeader.biCompression = BI_RGB; 
     
        // Compute the number of bytes in the array of color  
        // indices and store the result in biSizeImage.  
        // The width must be DWORD aligned unless the bitmap is RLE 
        // compressed. 
        pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
                                      * pbmi->bmiHeader.biHeight; 
        // Set biClrImportant to 0, indicating that all of the  
        // device colors are important.
    
    	
         pbmi->bmiHeader.biClrImportant = 0;
    	long *newsize=NULL;
    	RGBTriplet* buffer = (RGBTriplet*)ConvertBMPToRGBBuffer(bmp.bmBits,bmp.bmWidth,bmp.bmHeight);
    	int n=sizeof(buffer)/3;
    	int i;
    	for (i=0;i<n;++i)
    	{
    		buffer->blue=0x00;
    		buffer->green=0x00;
    		buffer->red=0x00;
    	}
        bmp.bmBits=ConvertRGBToBMPBuffer((BYTE*)buffer,bmp.bmWidth,bmp.bmHeight,newsize); 
    	return pbmi; 
    }
     
    void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, 
                      HBITMAP hBMP, HDC hDC) 
     { 
         HANDLE hf;                 // file handle  
        BITMAPFILEHEADER hdr;       // bitmap file-header  
        PBITMAPINFOHEADER pbih;     // bitmap info-header  
        LPBYTE lpBits;              // memory pointer  
        DWORD dwTotal;              // total count of bytes  
        DWORD cb;                   // incremental count of bytes  
        BYTE *hp;                   // byte pointer  
        DWORD dwTmp; 
     
        pbih = (PBITMAPINFOHEADER) pbi; 
        lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
     
        if (!lpBits) 
        {
            MessageBox(hwnd,"da","da",MB_OK);
        }
     
        // 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)) 
        {
            MessageBox(hwnd,"da","da",MB_OK); 
        }
     
        // 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) 
            MessageBox(hwnd,"da","da",MB_OK);
        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)) 
        {
            MessageBox(hwnd,"da","da",MB_OK);
        }
     
        // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.  
        if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
                      + pbih->biClrUsed * sizeof (RGBQUAD), 
                      (LPDWORD) &dwTmp, ( NULL)))
            MessageBox(hwnd,"da","da",MB_OK);
     
        // 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)) 
               MessageBox(hwnd,"da","da",MB_OK); 
     
        // Close the .BMP file.  
         if (!CloseHandle(hf)) 
               MessageBox(hwnd,"da","da",MB_OK); 
     
        // Free memory.  
        GlobalFree((HGLOBAL)lpBits);
    }
    sorry for my English

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    You need to narrow this down for us.

    Step through the code and find which line causes the issue or exception.

    My guess is....

    Is the size of a struct RGBTriplet actually 3 bytes? (I bet it is 4)

    You have a BYTE varaibale cast to a struct tagRGBTriplet array and back to byte, but the complier has probably padded the struct to a 4 byte boundry (ie added another byte so each tagRGBTriplet is 4 bytes wide).

    EDIT:
    First fix the memory leaks.
    ie CreateBitmapInfoStruct is leaking memory. ConvertRGBToBMPBuffer allocates a buffer which is never freed.
    PBITMAPINFO is a struct not a pointer so returning pbmi creates a dangling pointer.
    bmp.bmBits=ConvertRGBToBMPBuffer is another memory leak.
    Last edited by novacain; 09-26-2011 at 04:27 AM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to change Array Data type?
    By LennoZebra in forum C Programming
    Replies: 11
    Last Post: 10-02-2009, 03:46 PM
  2. Replies: 3
    Last Post: 04-04-2007, 07:34 PM
  3. Writing binary data to a file (bits).
    By OOPboredom in forum C Programming
    Replies: 2
    Last Post: 04-05-2004, 03:53 PM
  4. Replies: 2
    Last Post: 11-08-2002, 03:22 AM
  5. Change data format from CString to int
    By ooosawaddee3 in forum C++ Programming
    Replies: 5
    Last Post: 11-04-2002, 10:43 AM