Thread: Dynamic Bitmap Display

  1. #1
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256

    Dynamic Bitmap Display

    Code:
    BITMAP CustomBMP;
    HBITMAP hCustomBMP;
    BITMAPINFO CustomBMPInfo;
    BYTE BitmapData[16];
    RGBQUAD* Palette;
    Code:
        case WM_CREATE:
         {
          Palette = malloc(16);
          Palette[0].rgbRed    = 0;
          Palette[0].rgbGreen  = 0;
          Palette[0].rgbBlue   = 0;
          Palette[1].rgbRed    = 255;
          Palette[1].rgbGreen  = 0;
          Palette[1].rgbBlue   = 0;
          Palette[2].rgbRed    = 0;
          Palette[2].rgbGreen  = 255;
          Palette[2].rgbBlue   = 0;
          Palette[3].rgbRed    = 0;
          Palette[3].rgbGreen  = 0;
          Palette[3].rgbBlue   = 255;
          Palette[4].rgbRed    = 255;
          Palette[4].rgbGreen  = 255;
          Palette[4].rgbBlue   = 0;
          Palette[5].rgbRed    = 255;
          Palette[5].rgbGreen  = 0;
          Palette[5].rgbBlue   = 255;
          Palette[6].rgbRed    = 0;
          Palette[6].rgbGreen  = 255;
          Palette[6].rgbBlue   = 255;
          Palette[7].rgbRed    = 128;
          Palette[7].rgbGreen  = 0;
          Palette[7].rgbBlue   = 0;
          Palette[8].rgbRed    = 0;
          Palette[8].rgbGreen  = 128;
          Palette[8].rgbBlue   = 0;
          Palette[9].rgbRed    = 0;
          Palette[9].rgbGreen  = 0;
          Palette[9].rgbBlue   = 128;
          Palette[10].rgbRed   = 128;
          Palette[10].rgbGreen = 128;
          Palette[10].rgbBlue  = 0;
          Palette[11].rgbRed   = 128;
          Palette[11].rgbGreen = 0;
          Palette[11].rgbBlue  = 128;
          Palette[12].rgbRed   = 0;
          Palette[12].rgbGreen = 128;
          Palette[12].rgbBlue  = 128;
          Palette[13].rgbRed   = 128;
          Palette[13].rgbGreen = 128;
          Palette[13].rgbBlue  = 128;
          Palette[14].rgbRed   = 255;
          Palette[14].rgbGreen = 255;
          Palette[14].rgbBlue  = 255;
          Palette[15].rgbRed   = 0;
          Palette[15].rgbGreen = 0; 
          Palette[15].rgbBlue  = 0;
    
          BitmapData[0] =  0x01;
          BitmapData[1] =  0x23;
          BitmapData[2] =  0x45;
          BitmapData[3] =  0x67;
          BitmapData[4] =  0x89;
          BitmapData[5] =  0xAB;
          BitmapData[6] =  0xCD;
          BitmapData[7] =  0xEF;
          BitmapData[8] =  0x01;
          BitmapData[9] =  0x23;
          BitmapData[10] = 0x45;
          BitmapData[11] = 0x67;
          BitmapData[12] = 0x89;
          BitmapData[13] = 0xAB;
          BitmapData[14] = 0xCD;
          BitmapData[15] = 0xEF;
    
          CustomBMPInfo.bmiHeader.biSize = 40; 
          CustomBMPInfo.bmiHeader.biWidth = 16; 
          CustomBMPInfo.bmiHeader.biHeight = 2; 
          CustomBMPInfo.bmiHeader.biPlanes = 1; 
          CustomBMPInfo.bmiHeader.biBitCount = 4; 
          CustomBMPInfo.bmiHeader.biCompression = 0; 
          CustomBMPInfo.bmiHeader.biSizeImage = 0; 
          CustomBMPInfo.bmiHeader.biXPelsPerMeter = 0; 
          CustomBMPInfo.bmiHeader.biYPelsPerMeter = 0; 
          CustomBMPInfo.bmiHeader.biClrUsed = 16; 
          CustomBMPInfo.bmiHeader.biClrImportant = 0;
          CustomBMPInfo.bmiColors = Palette;
         }
        break;
        case WM_PAINT:
         {
          PAINTSTRUCT ps;
    
          HDC hdc = BeginPaint(hwnd, &ps);
    
          hCustomBMP = CreateCompatibleBitmap(hdc,
                                              CustomBMPInfo.bmiHeader.biWidth,
                                              CustomBMPInfo.bmiHeader.biHeight);
          GetObject(hCustomBMP, sizeof(CustomBMP), &CustomBMP);
          SetDIBits(hdc, hCustomBMP, 0, CustomBMP.bmHeight, BitmapData, &CustomBMPInfo, DIB_RGB_COLORS);
    
          HDC hdcMem = CreateCompatibleDC(hdc);
          HBITMAP hbmOld = SelectObject(hdcMem, hCustomBMP);
    
          BitBlt(hdc, 0, 0, CustomBMP.bmWidth, CustomBMP.bmHeight, hdcMem, 0, 0, SRCCOPY);
    
          SelectObject(hdcMem, hbmOld);
          DeleteDC(hdcMem);
          DeleteObject(hCustomBMP);
    
          EndPaint(hwnd, &ps);
         }
        break;
        case WM_CLOSE:
         {
          free(Palette);
          DestroyWindow(hwnd);
         }
        break;
    I'm having problems trying to understand the SetDIBits, with a paletted bitmap, rather than a raw bitmap. I attached an image of the output, zoomed in by 800%, as well as an image of the output I was aiming for. Any ideas what I'm doing wrong?
    Code:
    void function(void)
     {
      function();
     }

  2. #2
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Code:
    Palette = malloc(sizeof(RGBQUAD) * 16);
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  3. #3
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Ahh. Thank you. That doesn't seem to be my problem, though. The output is the same.
    Code:
    void function(void)
     {
      function();
     }

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Your params are wrong.

    ie CustomBMPInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

    Have a look here...
    http://cboard.cprogramming.com/showt...ght=bmp+header
    "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

  5. #5
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Code:
          CustomBMPInfo.bmiColors = Palette;
    This should not compile. The BITMAPINFO structure has the following definition:
    Code:
    typedef struct tagBITMAPINFO { 
      BITMAPINFOHEADER bmiHeader; 
      RGBQUAD          bmiColors[1]; 
    } BITMAPINFO, *PBITMAPINFO;
    The bmiColors member is an array, and therefore can not be assigned to. BITMAPINFO consists of an BITMAPINFOHEADER followed by a variable sized array of palette entries. It is not a BITMAPINFOHEADER followed by a pointer to an array of palette entries, which your code attempts to create. Because the array may be of various sizes, it is defined with the placeholder size of 1, and the programmer is expected to allocate appropriate memory. This pattern is not uncommon in the Windows API.

    I have modified your code to demonstrate:
    Code:
    #include <windows.h>
    #include <stdio.h>
    
    #if defined(_MSC_VER)
    #pragma comment(lib, "gdi32.lib")
    #endif
    
    int main(void)
    {
    
          BITMAP      CustomBMP;
          HBITMAP     hCustomBMP;
          BYTE        BitmapData[16];
          BITMAPINFO* CustomBMPInfo;
          RGBQUAD*    Palette;
    
          /* Allocate space for a BITMAPINFO structure followed by an array of RGBQUADs */
          CustomBMPInfo = (BITMAPINFO*) malloc(sizeof(BITMAPINFO) + (sizeof(RGBQUAD) * 16));
          /* TODO: check malloc. */
    
          /* Convenience variable. We could use CustomBMPInfo->bmiColors directly. */
          Palette = CustomBMPInfo->bmiColors;
    
          Palette[0].rgbRed    = 0;
          Palette[0].rgbGreen  = 0;
          Palette[0].rgbBlue   = 0;
          Palette[1].rgbRed    = 255;
          Palette[1].rgbGreen  = 0;
          Palette[1].rgbBlue   = 0;
          Palette[2].rgbRed    = 0;
          Palette[2].rgbGreen  = 255;
          Palette[2].rgbBlue   = 0;
          Palette[3].rgbRed    = 0;
          Palette[3].rgbGreen  = 0;
          Palette[3].rgbBlue   = 255;
          Palette[4].rgbRed    = 255;
          Palette[4].rgbGreen  = 255;
          Palette[4].rgbBlue   = 0;
          Palette[5].rgbRed    = 255;
          Palette[5].rgbGreen  = 0;
          Palette[5].rgbBlue   = 255;
          Palette[6].rgbRed    = 0;
          Palette[6].rgbGreen  = 255;
          Palette[6].rgbBlue   = 255;
          Palette[7].rgbRed    = 128;
          Palette[7].rgbGreen  = 0;
          Palette[7].rgbBlue   = 0;
          Palette[8].rgbRed    = 0;
          Palette[8].rgbGreen  = 128;
          Palette[8].rgbBlue   = 0;
          Palette[9].rgbRed    = 0;
          Palette[9].rgbGreen  = 0;
          Palette[9].rgbBlue   = 128;
          Palette[10].rgbRed   = 128;
          Palette[10].rgbGreen = 128;
          Palette[10].rgbBlue  = 0;
          Palette[11].rgbRed   = 128;
          Palette[11].rgbGreen = 0;
          Palette[11].rgbBlue  = 128;
          Palette[12].rgbRed   = 0;
          Palette[12].rgbGreen = 128;
          Palette[12].rgbBlue  = 128;
          Palette[13].rgbRed   = 128;
          Palette[13].rgbGreen = 128;
          Palette[13].rgbBlue  = 128;
          Palette[14].rgbRed   = 255;
          Palette[14].rgbGreen = 255;
          Palette[14].rgbBlue  = 255;
          Palette[15].rgbRed   = 0;
          Palette[15].rgbGreen = 0; 
          Palette[15].rgbBlue  = 0;
    
          BitmapData[0] =  0x01;
          BitmapData[1] =  0x23;
          BitmapData[2] =  0x45;
          BitmapData[3] =  0x67;
          BitmapData[4] =  0x89;
          BitmapData[5] =  0xAB;
          BitmapData[6] =  0xCD;
          BitmapData[7] =  0xEF;
          BitmapData[8] =  0x01;
          BitmapData[9] =  0x23;
          BitmapData[10] = 0x45;
          BitmapData[11] = 0x67;
          BitmapData[12] = 0x89;
          BitmapData[13] = 0xAB;
          BitmapData[14] = 0xCD;
          BitmapData[15] = 0xEF;
    
          CustomBMPInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
          CustomBMPInfo->bmiHeader.biWidth = 16; 
          CustomBMPInfo->bmiHeader.biHeight = 2; 
          CustomBMPInfo->bmiHeader.biPlanes = 1; 
          CustomBMPInfo->bmiHeader.biBitCount = 4; 
          CustomBMPInfo->bmiHeader.biCompression = BI_RGB; 
          CustomBMPInfo->bmiHeader.biSizeImage = 0; 
          CustomBMPInfo->bmiHeader.biXPelsPerMeter = 0; 
          CustomBMPInfo->bmiHeader.biYPelsPerMeter = 0; 
          CustomBMPInfo->bmiHeader.biClrUsed = 16; 
          CustomBMPInfo->bmiHeader.biClrImportant = 0;
    
          HDC hdc = GetDC(NULL);
    
          hCustomBMP = CreateCompatibleBitmap(hdc,
                                              CustomBMPInfo->bmiHeader.biWidth,
                                              CustomBMPInfo->bmiHeader.biHeight);
          GetObject(hCustomBMP, sizeof(CustomBMP), &CustomBMP);
          SetDIBits(hdc, hCustomBMP, 0, CustomBMP.bmHeight, BitmapData, CustomBMPInfo, DIB_RGB_COLORS);
    
          HDC hdcMem = CreateCompatibleDC(hdc);
          HBITMAP hbmOld = (HBITMAP) SelectObject(hdcMem, hCustomBMP);
    
          BitBlt(hdc, 0, 0, CustomBMP.bmWidth, CustomBMP.bmHeight, hdcMem, 0, 0, SRCCOPY);
    
          SelectObject(hdcMem, hbmOld);
          DeleteDC(hdcMem);
          DeleteObject(hCustomBMP);
    
          ReleaseDC(NULL, hdc);
    
          getchar();
          return 0;
    }
    Last edited by anonytmouse; 07-03-2005 at 10:18 PM.

  6. #6
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    I've never seen anyone use that technique for allocation. Although, it does make sense. Thanks a lot. I wish MSDN would be a little clearer on how to use that structure.
    Code:
    void function(void)
     {
      function();
     }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OpenGL -- Bitmaps
    By HQSneaker in forum Game Programming
    Replies: 14
    Last Post: 09-06-2004, 04:04 PM
  2. Simple Ddraw question. Display bitmap on a screen.
    By tegwin in forum Game Programming
    Replies: 0
    Last Post: 05-22-2004, 05:50 PM
  3. How to create and display a bitmap programatically?
    By solar3147 in forum Windows Programming
    Replies: 4
    Last Post: 06-24-2003, 02:55 AM
  4. bitmap not going onto screen
    By stallion in forum Windows Programming
    Replies: 4
    Last Post: 02-22-2003, 10:07 AM
  5. Using BitBlt() to display only a portion of a big bitmap
    By Leeman_s in forum Windows Programming
    Replies: 4
    Last Post: 01-16-2003, 10:09 PM