Details
-
Bug
-
Resolution: Fixed
-
Major
-
None
-
None
-
Operating System: ReactOS
Platform: x86 Hardware
Description
ReactOS Win32k.sys (eng/surface.c:136 or there abouts) lacks a implementation
of RLE4/8 Bitmap support. This keeps us from being able to run our own
autorun.exe/explorer.exe or use any third party application that has RLE
encoded resources built in.
Here is example code on run-length decoding used in WINE. It shouldn't be very
hard to adapt to use in ReactOS.
enum Rle_EscapeCodes
{
RLE_EOL = 0, /* End of line */
RLE_END = 1, /* End of bitmap */
RLE_DELTA = 2 /* Delta */
};
/***********************************************************************
- X11DRV_DIB_SetImageBits_RLE4
* - SetDIBits for a 4-bit deep compressed DIB.
*/
static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
DWORD width, DWORD dstwidth,
int left, int *colors,
XImage *bmpImage )
{
int x = 0, y = lines - 1, c, length;
const BYTE *begin = bits;
while (y >= 0)
{
length = *bits++;
if (length) { /* encoded */
c = *bits++;
while (length--)
} else {
length = *bits++;
switch (length)
{
case RLE_EOL:
x = 0;
y--;
break;
case RLE_END:
return;
case RLE_DELTA:
x = *bits+;
y -= *bits++;
break;
default: /* absolute */
while (length--)
if ((bits - begin) & 1)
bits++;
}
}
}
}
/***********************************************************************
- X11DRV_DIB_SetImageBits_RLE8
* - SetDIBits for an 8-bit deep compressed DIB.
* - This function rewritten 941113 by James Youngman. WINE blew out when I
- first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
* - This was because the algorithm assumed that all RLE8 bitmaps end with the
- 'End of bitmap' escape code. This code is very much laxer in what it
- allows to end the expansion. Possibly too lax. See the note by
- case RleDelta. BTW, MS's documentation implies that a correct RLE8
- bitmap should end with RleEnd, but on the other hand, software exists
- that produces ones that don't and Windows 3.1 doesn't complain a bit
- about it.
* - (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
- James A. Youngman <mbcstjy@afs.man.ac.uk>
- [JAY]
*/
static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
DWORD width, DWORD dstwidth,
int left, int *colors,
XImage *bmpImage )
{
int x; /* X-positon on each line. Increases. */
int y; /* Line #. Starts at lines-1, decreases */
const BYTE pIn = bits; / Pointer to current position in bits */
BYTE length; /* The length pf a run */
BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
/*
- Note that the bitmap data is stored by Windows starting at the
- bottom line of the bitmap and going upwards. Within each line,
- the data is stored left-to-right. That's the reason why line
- goes from lines-1 to 0. [JAY]
*/
x = 0;
y = lines - 1;
while (y >= 0)
{
length = *pIn++;
/*
- If the length byte is not zero (which is the escape value),
- We have a run of length pixels all the same colour. The colour
- index is stored next.
* - If the length byte is zero, we need to read the next byte to
- know what to do. [JAY]
*/
if (length != 0) { /* * [Run-Length] Encoded mode */ int color = colors[*pIn++]; while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color); }else
{
/* - Escape codes (may be an absolute sequence though)
*/
escape_code = (*pIn++);
switch(escape_code)
{
case RLE_EOL:
x = 0;
y--;
break;
case RLE_END:
/* Not all RLE8 bitmaps end with this code. For
- example, Paint Shop Pro produces some that don't.
- That's (I think) what caused the previous
- implementation to fail. [JAY]
*/
return;
case RLE_DELTA:
x = (*pIn+);
y -= (*pIn++);
break;
default: /* switch to absolute mode */
length = escape_code;
while (length--)
{
int color = colors[*pIn++];
if (x >= dstwidth)
XPutPixel(bmpImage, x++, y, color);
}
/*
- If you think for a moment you'll realise that the
- only time we could ever possibly read an odd
- number of bytes is when there is a 0x00 (escape),
- a value >0x02 (absolute mode) and then an odd-
- length run. Therefore this is the only place we
- need to worry about it. Everywhere else the
- bytes are always read in pairs. [JAY]
*/
if (escape_code & 1) pIn++; /* Throw away the pad byte. */
break;
} /* switch (escape_code) : Escape sequence */
}
}
}