Xeen Wiki

RAW image files store a single static 320x200 image. No palette information is stored in the file, so a separate palette file must also be loaded before attempting to display the image.

Usage[]

RAW images are primarily used to store the background images for animation sequences throughout the games, as well as the background of the main interface.

File Format[]

The image is stored in an uncompressed format, with each byte in the file representing the palette index of one pixel in the finished image. The image is stored left-to-right, top-to-bottom, and the RAW file is always exactly 64,000 bytes in size (320 bytes wide * 200 bytes high).

The first byte in the file is the palette index for the pixel in the top left of the screen (0,0). The next byte represents the next pixel in the line (0,1), and so on. The 320th byte represents the pixel in the top right (0,319), with the next pixel being for the first pixel of the next line (1,0).

Converting RAW to RGB[]

// This function assumes the size of the raw image 320*200
//  * rawData    - pointer to the raw data as loaded from the .cc file
//  * palletData - pointer to the pallet data as loaded from the .cc file or NULL
//  * colorData  - pointer to a byte array that will contain the RGB conversion of the raw image
// Remarks:
//  * If palletData is NULL the index into the pallet will be the resulting RGB color
void rawToRgb32( BYTE *rawData, BYTE *palletData, BYTE *colorData )
{
  DWORD i;

  if( palletData != NULL )
  {
    for( i = 0 ; i < 320 * 200 ; i++ )
    {
      colorData[i*4+0] = palletData[rawData[i] * 3 + 2] << 2;
      colorData[i*4+1] = palletData[rawData[i] * 3 + 1] << 2;
      colorData[i*4+2] = palletData[rawData[i] * 3 + 0] << 2;
    }
  }
  else
  {
    for( i = 0 ; i < 320 * 200 ; i++ )
    {
      colorData[i*4+0] = colorData[i*4+1] = colorData[i*4+2] = rawData[i];
    }
  }
}

Creating Windows Bitmap from RAW[]

// This function loads a RAW image (assumed to be 320x200) and create a bitmap from it
//  * rawData      - pointer to the raw data as loaded from the .cc file
//  * palletData   - pointer to the pallet data as loaded from the .cc file or NULL
//  * Return value - A handle to a Bitmap that can be used to display the image
// Remarks:
//  * If palletData is NULL the index into the pallet will be the resulting RGB color
//    this will result in a grayscale image.
HBITMAP getImageFromRawEx( BYTE *rawData, BYTE *palletData )
{
  // Bitmap handle that will be returned
  HBITMAP hBmp = NULL;

  // Device context used to create the bitmap
  HDC hdc = GetDC( NULL );

  // Array to hold the color data of the image
  BYTE *raster = malloc( 320 * 200 * 4 );

  // The desired format for the bitmap that is created (24-bit image)
  BITMAPINFOHEADER newInfo = { sizeof( BITMAPINFOHEADER ), 320, 200, 1, 24, BI_RGB, 0, 0, 0, 0, 0 };

  // The format of the color data (raster) - the width is negative because
  // Windows bitmaps are always bottom-up, but the RAW images are top-down
  // Use a 32-bit color raster so that DWORD padding at the end of a scan
  // line is not an issue (image of this size don't need padding anyway,
  // but this will allow you to load other images of varying size).
  BITMAPINFO oldInfo = { { sizeof( BITMAPINFOHEADER ), 320, -200, 1, 32, BI_RGB, 0, 0, 0, 0, 0 }, NULL };

  if( raster && hdc )
  {
    // Convert the RAW data into a 32-bit RGB raster
    rawToRgb32( rawData, palletData, raster );

    // Create the bitmap
    hBmp = CreateDIBitmap( hdc, &newInfo, CBM_INIT, raster, &oldInfo, DIB_RGB_COLORS );
  }

  free( raster );
  ReleaseDC( NULL, hdc );

  return( hBmp );
}

You can now use the HBITMAP that is returned to BitBlt onto a device context.