How to use a windows BMP picture in VxWorks


When you want to use a windows BMP picture in VxWorks there is some basic knowledge about windows BMP pictures and Wind Rivers Media Library that have to be in place.

Windows BMP picture

The important thing to know about a windows BMP picture when using it in VxWorks is the following:

- Windows BMP pictures use a 54 bytes header. The header contains the information we need to interpret the windows BMP picture.
signature, must be 4D42 hex
size of BMP file in bytes (unreliable)
reserved, must be zero
reserved, must be zero
offset to start of image data in bytes
size of BITMAPINFOHEADER structure, must be 40
image width in pixels
image height in pixels
number of planes in the image, must be 1
number of bits per pixel (1, 4, 8, or 24)
compression type (0=none, 1=RLE-8, 2=RLE-4)
size of image data in bytes (including padding)
horizontal resolution in pixels per meter (unreliable)
vertical resolution in pixels per meter (unreliable)
number of colors in image, or zero
number of important colors, or zero

- A 24-bit BMP means that every pixel is represented by 24 bit, 1 byte pr. color.
- The color information is stored as RBG.
- A windows BMP picture uses (0, 0) as the bottom left corner. That means that a picture of an “L” is stored like the picture underneath

- All examples in How to use a windows BMP picture in VxWorks are based on using a 24-bit windows BMP picture.
- More information

Wind Rivers Media Library

The important thing to know about Wind Rivers Media Library (from now on referred to as ugl) is the following:
  • An ugl bitmap can be defined in a lot of ways. For other examples than the one explained in How to use a windows BMP picture in VxWorks see <installdir>\components\windml-4.2\samples\bitmaps
  • An ugl bitmap uses (0, 0) as the upper left corner. That means that a picture of an “L” is stored like the picture underneath.

Steps in using a windows BMP picture in VxWorks

  1. Open the picture.
    FILE* handle = NULL;
     handle = fopen( filename, "rb" );
  2. Get the information in the pictures header we need.
     fseek( handle, 18, SEEK_SET );
     fread( &_width, 4, 1, handle );
     fread( &_height, 4, 1, handle );
     fseek( handle, 28, SEEK_SET );
     fread( &_bitDepth, 2, 1, handle );
  3. Load the picture minus the header.
    fseek( handle, 0, SEEK_END );
     size = ftell( handle ) - 54;
     unsigned char* dataBMP;
     unsigned char* tempData;
     dataBMP = new unsigned char[size];
     tempData = new unsigned char[_width*3];
     fseek( handle, 54, SEEK_SET ); //image data//
     fread( dataBMP, size, 1, handle );
     fclose( handle );
  4. Because of the difference between windows BMP pictures (0, 0) and ugl bitmaps (0, 0) it’s necessary to “flip” the picture. This is done by taking the last line in the picture and copy it in a temp variable and copy the first line over the last line and then copy the temp over the first line, see the picture underneath. After this the same is done for the second line and second last line and so on and so on until the middle of the picture is reached.

    for ( int i = 0 ; i < _height / 2 ; ++ i )
     memcpy( tempData, &dataBMP[_width*3*(_height-(i+1))], _width*3 );
     memcpy( &dataBMP[_width*3*(_height-(i+1))], &dataBMP[_width*3*i], _width*3 );
     memcpy( &dataBMP[_width*3*i], tempData, _width*3 );
  5. Step 4 causes the color information pr. pixel to be inverted so it is BGR instead of RGB so the color information is inverted pr. pixel in the picture.
     char temp;
     for ( int i = 0 ; i < _width * _height * 3 ; i+3 )
     temp = dataBMP[i];
     dataBMP[i] = dataBMP[i+2];
     dataBMP[i+2] = temp;
  6. To create an ugl bitmap from a windows BMP picture it’s necessary to create an ugl device-independent bitmap (DIB) struct with information about the picture.
     UGL_DIB BMP_dip;

     BMP_dip.width = _width;
     BMP_dip.height = _height;
     BMP_dip.stride = _width;
     BMP_dip.imageFormat = UGL_DIRECT;
     BMP_dip.colorFormat = UGL_RGB888;
     BMP_dip.clutSize = NULL;
     BMP_dip.pClut = NULL;
     BMP_dip.pImage = dataBMP;

    width is the width of the picture.
    height is height of the picture.
    stride is the distance, in number of pixels, from the start of one row of image data to the start of the next row. Usually the pictures width.
    imageFormat it specifies the format of the color information in the image data in the DIB. When it’s a windows BMP picture there is specified in the struct it’s UGL_DIRECT this means that the color information is in a format specified by colorFormat.
    colorFormat specifi the format of the picture data for direct color format. UGL_RGB888 specifi 8 bit pr. color.
    clutSize not important.
    pClut not important.
    pImage a pointer to the picture data.

    For more information about the struct see Wind River Media Library for VxWorks 6 SDK PROGRAMMER’S GUIDE 4.1 page 50 and Wind River Media Library for VxWorks 6 API REFERENCE 4.1 page 38
  7. Create an ugl bitmap from the struct.
     UGL_DDB_ID ddbID;

     ddbID = uglBitmapCreate( devId, &BMP_dip, UGL_DIB_INIT_DATA, 0, UGL_DEFAULT_MEM );

    For more information about uglBitmapCreate see Wind River Media Library for VxWorks 6 API REFERENCE 4.1 page 36.
  8. Blitting the ugl bitmap to the screen. Blitting can only be done between bitmaps. When the GC is created it’s "default bitmap" is set to the screen bitmap, UGL_DISPLAY_ID. If this hasn't been changed, it is possible to blit to the screen by using UGL_DEFAULT_ID bitmap. To ensure that the blit operation will function, the GC's "default bitmap" is set to screen.
     uglBitmapBlt(*gc, ddbID,0,0,_width,_height, UGL_DEFAULT_ID, dstX, dstY);
     uglBitmapDestroy(devId, ddbID);

    Blitting is a computer graphics operation in which several bitmap patterns are combined into one using a "raster operator". For more information see
  9. Delete the arrays.
     delete [] tempData;
     delete [] dataBMP;

Known problems in using windows BMP’s in VxWorks

  • If the windows BMP picture size in MB is too large there have been recorded problems with the delete call on the arrays. The memory doesn’t get deallocated in ugl. Use Memscope to ensure that this problem isn’t present. The solution is simply just to split the windows BMP picture in to small pictures an load them one by one.
  • With some ratios between the windows BMP pictures width and height in pixels the picture is interpreted wrong. This shows by windows BMP pictures in VxWorks looking funny. Try making the picture width one pixel larger and load it again.