[WIN32SS] Fix RLE4 bitmap decoding (#1188)

CORE-10553, CORE-11399
This commit is contained in:
Katayama Hirofumi MZ 2018-12-25 18:04:21 +09:00 committed by GitHub
parent 0a3f6f3b47
commit 968c8f37f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -18,40 +18,52 @@ enum Rle_EscapeCodes
RLE_DELTA = 2 /* Delta */ RLE_DELTA = 2 /* Delta */
}; };
VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format, ULONG cjSizeImage) VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits,
LONG Delta, ULONG Format, ULONG cjSizeImage)
{ {
INT x = 0; INT x = 0, y = Size.cy - 1;
INT y = Size.cy - 1; INT i, c, c2, length;
INT c; INT width = Size.cx, height = y;
INT length;
INT width;
INT height = y;
BYTE *begin = CompressedBits; BYTE *begin = CompressedBits;
BYTE *bits = CompressedBits; BYTE *bits = CompressedBits;
BYTE *temp; BYTE *temp;
INT shift = 0; BOOL is4bpp = FALSE;
if ((Format == BMF_4RLE) || (Format == BMF_4BPP)) if ((Format == BMF_4RLE) || (Format == BMF_4BPP))
shift = 1; is4bpp = TRUE;
else if ((Format != BMF_8RLE) && (Format != BMF_8BPP)) else if ((Format != BMF_8RLE) && (Format != BMF_8BPP))
return; return;
width = ((Size.cx + shift) >> shift);
_SEH2_TRY _SEH2_TRY
{ {
while (y >= 0 && (bits - begin) <= cjSizeImage) while (y >= 0 && (bits - begin) <= cjSizeImage)
{ {
length = (*bits++) >> shift; length = *bits++;
if (length) if (length)
{ {
c = *bits++; c = *bits++;
while (length--) for (i = 0; i < length; i++)
{ {
if (x >= width) break; if (x >= width) break;
temp = UncompressedBits + (((height - y) * Delta) + x); temp = UncompressedBits + (height - y) * Delta;
if (is4bpp)
{
temp += x / 2;
if (i & 1)
c2 = c & 0x0F;
else
c2 = c >> 4;
if (x & 1)
*temp |= c2;
else
*temp |= c2 << 4;
}
else
{
temp += x;
*temp = c;
}
x++; x++;
*temp = c;
} }
} }
else else
@ -66,19 +78,36 @@ VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits,
case RLE_END: case RLE_END:
_SEH2_YIELD(return); _SEH2_YIELD(return);
case RLE_DELTA: case RLE_DELTA:
x += (*bits++) >> shift; x += *bits++;
y -= (*bits++) >> shift; y -= *bits++;
break; break;
default: default:
length = length >> shift; for (i = 0; i < length; i++)
while (length--)
{ {
c = *bits++; if (!(is4bpp && i & 1))
c = *bits++;
if (x < width) if (x < width)
{ {
temp = UncompressedBits + (((height - y) * Delta) + x); temp = UncompressedBits + (height - y) * Delta;
if (is4bpp)
{
temp += x / 2;
if (i & 1)
c2 = c & 0x0F;
else
c2 = c >> 4;
if (x & 1)
*temp |= c2;
else
*temp |= c2 << 4;
}
else
{
temp += x;
*temp = c;
}
x++; x++;
*temp = c;
} }
} }
if ((bits - begin) & 1) if ((bits - begin) & 1)