[ros-kernel] Q2 Bug (210 in bugzilla) Fix or bigger bug?

Waldo Alvarez Cañizares wac at lab.matcom.uh.cu
Tue Mar 2 16:30:24 CET 2004


Hi guys:
 
I can't access bugzilla right now to report the fix, that's why I'm sending it here. So >> if this closes the bug <<, please somebody close it and apply.
 
It is a problem related with dibs, but probably the thing gets bigger!
 
This is quoting the sdk
 
"BITMAPINFOHEADER
The BITMAPINFOHEADER structure contains information about the dimensions and color format of a DIB. 
Windows 95, Windows NT 4.0: Applications can use the BITMAPV4HEADER structure for added functionality. 
Windows 98/Me, Windows 2000/XP: Applications can use the BITMAPV5HEADER structure for added functionality. However, these are used only in the CreateDIBitmap function.
typedef struct tagBITMAPINFOHEADER{
  DWORD  biSize; 
  LONG   biWidth; 
  LONG   biHeight; 
  WORD   biPlanes; 
  WORD   biBitCount; 
  DWORD  biCompression; 
  DWORD  biSizeImage; 
  LONG   biXPelsPerMeter; 
  LONG   biYPelsPerMeter; 
  DWORD  biClrUsed; 
  DWORD  biClrImportant; 
} BITMAPINFOHEADER, *PBITMAPINFOHEADER; 
Members
biSize 
Specifies the number of bytes required by the structure. 
biWidth 
Specifies the width of the bitmap, in pixels. 
Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, the biWidth member specifies the width of the decompressed JPEG or PNG image file, respectively. 
-------------------------------------------------------------------------------------------------
biHeight 
Specifies the height of the bitmap, in pixels. If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is a top-down 
DIB and its origin is the upper-left corner. 
If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or BI_BITFIELDS. Top-down DIBs cannot be compressed. 
-------------------------------------------------------------------------------------------------

Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, the biHeight member specifies the height of the decompressed JPEG or PNG image file, respectively. 
..."
 
 
 
Now a piece of Quake2 sources (one of the versions but should be very similar):
...

/*
** DIB_Init
**
** Builds our DIB section
*/
qboolean DIB_Init( unsigned char **ppbuffer, int *ppitch )
{
 dibinfo_t   dibheader;
 BITMAPINFO *pbmiDIB = ( BITMAPINFO * ) &dibheader;
 int i;
 memset( &dibheader, 0, sizeof( dibheader ) );
 /*
 ** grab a DC
 */
 if ( !sww_state.hDC )
 {
  if ( ( sww_state.hDC = GetDC( sww_state.hWnd ) ) == NULL )
   return false;
 }
 /*
 ** figure out if we're running in an 8-bit display mode
 */
  if ( GetDeviceCaps( sww_state.hDC, RASTERCAPS ) & RC_PALETTE )
 {
  sww_state.palettized = true;
  // save system colors
  if ( !s_systemcolors_saved )
  {
   DIB_SaveSystemColors();
   s_systemcolors_saved = true;
  }
 }
 else
 {
  sww_state.palettized = false;
 }
 /*
 ** fill in the BITMAPINFO struct
 */
 pbmiDIB->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
 pbmiDIB->bmiHeader.biWidth         = vid.width;
 pbmiDIB->bmiHeader.biHeight        = vid.height;
 pbmiDIB->bmiHeader.biPlanes        = 1;
 pbmiDIB->bmiHeader.biBitCount      = 8;
 pbmiDIB->bmiHeader.biCompression   = BI_RGB;
 pbmiDIB->bmiHeader.biSizeImage     = 0;
 pbmiDIB->bmiHeader.biXPelsPerMeter = 0;
 pbmiDIB->bmiHeader.biYPelsPerMeter = 0;
 pbmiDIB->bmiHeader.biClrUsed       = 256;
 pbmiDIB->bmiHeader.biClrImportant  = 256;
 /*
 ** fill in the palette
 */
 for ( i = 0; i < 256; i++ )
 {
  dibheader.acolors[i].rgbRed   = ( d_8to24table[i] >> 0 )  & 0xff;
  dibheader.acolors[i].rgbGreen = ( d_8to24table[i] >> 8 )  & 0xff;
  dibheader.acolors[i].rgbBlue  = ( d_8to24table[i] >> 16 ) & 0xff;
 }
 /*
 ** create the DIB section
 */
 sww_state.hDIBSection = CreateDIBSection( sww_state.hDC,
                                       pbmiDIB,
            DIB_RGB_COLORS,
            &sww_state.pDIBBase,
            NULL,
            0 );
 if ( sww_state.hDIBSection == NULL )
 {
  ri.Con_Printf( PRINT_ALL, "DIB_Init() - CreateDIBSection failed\n" );
  goto fail;
 }
 if ( pbmiDIB->bmiHeader.biHeight > 0 )                             <------------ Here
    {
  // bottom up
  *ppbuffer = sww_state.pDIBBase + ( vid.height - 1 ) * vid.width;
  *ppitch  = -vid.width;
    }
    else
    {
  // top down
  *ppbuffer = sww_state.pDIBBase;
  *ppitch  = vid.width;
    }

Now the piece of code in ReactOS:
HBITMAP STDCALL
DIB_CreateDIBSection(
  PDC dc, BITMAPINFO *bmi, UINT usage,
  LPVOID *bits, HANDLE section,
  DWORD offset, DWORD ovr_pitch)
{
  HBITMAP res = 0;
  BITMAPOBJ *bmp = NULL;
  DIBSECTION *dib = NULL;
  // Fill BITMAP32 structure with DIB data
  BITMAPINFOHEADER *bi = &bmi->bmiHeader;
  INT effHeight;
  ULONG totalSize;
  UINT Entries = 0;
  BITMAP bm;
  DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
  effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;  
  bm.bmType = 0;                                                                        
  bm.bmWidth = bi->biWidth;                                                            
  bm.bmHeight = effHeight;                                                   
  bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
  bm.bmPlanes = bi->biPlanes;
  bm.bmBitsPixel = bi->biBitCount;
  bm.bmBits = NULL;
...
 
The value in the section passed by the program is not modified in the rest of the code

Change by:

  HBITMAP STDCALL
DIB_CreateDIBSection(
  PDC dc, BITMAPINFO *bmi, UINT usage,
  LPVOID *bits, HANDLE section,
  DWORD offset, DWORD ovr_pitch)
{
  HBITMAP res = 0;
  BITMAPOBJ *bmp = NULL;
  DIBSECTION *dib = NULL;
  // Fill BITMAP32 structure with DIB data
  BITMAPINFOHEADER *bi = &bmi->bmiHeader;
  /* INT effHeight; */                    <------- - Delete this (not used)
  ULONG totalSize;
  UINT Entries = 0;
  BITMAP bm;
  DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
  /* effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight; */  <------- - and delete this too (equivalent to abs)
  bm.bmType = 0;
  bm.bmWidth = bi->biWidth;                                                             
  bm.bmHeight = abs(bi->biHeight);     <------- Change by this
  bi->biHeight = -bm.bmHeight;         <------- + add this to signal programs the way we render
  bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
  bm.bmPlanes = bi->biPlanes;
  bm.bmBitsPixel = bi->biBitCount;
  bm.bmBits = NULL;
 
However that signals how ReactOS GDI does the bitblt but maybe the driver would have to be checked
to give the correct way.
 
This puts my Quake II the way it is (well before crashing of course) but I can see that all functions in ReactOS's gdi work doing things one way.
 
Shouldn't they check if the video adapter does render images inverted? I mean what if some driver implements some functions one way and the other EngXX functions that does thing not done by hardware do it the other way. I think that could be caotic.
 
BTW As Quake is open source and having sources helped a lot, that makes me think that it could be a good strategy to make open source programs at the begining to make ROS reach some acceptable compatibility with existing applications.
 
Best Regards
Waldo Alvarez
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/ms-tnef
Size: 14684 bytes
Desc: not available
Url : http://reactos.com:8080/pipermail/ros-kernel/attachments/20040302/88cc6f14/attachment-0001.bin


More information about the Ros-kernel mailing list