From 10d3ee131eccdfd30effabf5a0000e26fd39d7da Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 23 Oct 2018 10:33:45 +0200 Subject: [PATCH] Fixed #4954: Check destination buffer bounds. --- libfreerdp/codec/include/bitmap.c | 232 ++++++++++++++++++++++-------- libfreerdp/codec/interleaved.c | 52 ++++++- 2 files changed, 216 insertions(+), 68 deletions(-) diff --git a/libfreerdp/codec/include/bitmap.c b/libfreerdp/codec/include/bitmap.c index a594a1bd4..cba7c2778 100644 --- a/libfreerdp/codec/include/bitmap.c +++ b/libfreerdp/codec/include/bitmap.c @@ -24,7 +24,7 @@ /** * Write a foreground/background image to a destination buffer. */ -static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, +static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd, UINT32 rowDelta, BYTE bitmask, PIXEL fgPel, INT32 cBits) { PIXEL xorPixel; @@ -32,11 +32,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, if (bitmask & g_MaskBit0) { - DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, xorPixel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -48,11 +50,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, if (bitmask & g_MaskBit1) { - DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, xorPixel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -64,11 +68,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, if (bitmask & g_MaskBit2) { - DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, xorPixel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -80,11 +86,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, if (bitmask & g_MaskBit3) { - DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, xorPixel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -96,11 +104,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, if (bitmask & g_MaskBit4) { - DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, xorPixel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -112,11 +122,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, if (bitmask & g_MaskBit5) { - DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, xorPixel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -128,11 +140,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, if (bitmask & g_MaskBit6) { - DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, xorPixel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -144,11 +158,13 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, if (bitmask & g_MaskBit7) { - DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel ^ fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, xorPixel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, xorPixel)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -167,16 +183,18 @@ static INLINE BYTE* WRITEFGBGIMAGE(BYTE* pbDest, UINT32 rowDelta, * Write a foreground/background image to a destination buffer * for the first line of compressed data. */ -static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, +static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd, BYTE bitmask, PIXEL fgPel, UINT32 cBits) { if (bitmask & g_MaskBit0) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -186,11 +204,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, { if (bitmask & g_MaskBit1) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -200,11 +220,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, { if (bitmask & g_MaskBit2) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -214,11 +236,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, { if (bitmask & g_MaskBit3) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -228,11 +252,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, { if (bitmask & g_MaskBit4) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -242,11 +268,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, { if (bitmask & g_MaskBit5) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -256,11 +284,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, { if (bitmask & g_MaskBit6) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -270,11 +300,13 @@ static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, BYTE bitmask, { if (bitmask & g_MaskBit7) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return NULL; } else { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return NULL; } DESTNEXTPIXEL(pbDest); @@ -298,6 +330,7 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, { const BYTE* pbSrc = pbSrcBuffer; const BYTE* pbEnd = pbSrcBuffer + cbSrcBuffer; + const BYTE* pbDestEnd = pbDestBuffer + rowDelta * height; BYTE* pbDest = pbDestBuffer; PIXEL temp; PIXEL fgPel = WHITE_PIXEL; @@ -310,6 +343,9 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, UINT32 advance; RLEEXTRA + if ((rowDelta == 0) || (rowDelta < width)) + return FALSE; + if (!pbSrcBuffer || !pbDestBuffer) return FALSE; @@ -341,7 +377,9 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, { if (fInsertFgPel) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -349,14 +387,19 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, while (runLength >= UNROLL_COUNT) { UNROLL( - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return FALSE; DESTNEXTPIXEL(pbDest);); + runLength = runLength - UNROLL_COUNT; } while (runLength > 0) { - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -366,7 +409,10 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, if (fInsertFgPel) { DESTREADPIXEL(temp, pbDest - rowDelta); - DESTWRITEPIXEL(pbDest, temp ^ fgPel); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp ^ fgPel)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -375,15 +421,21 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, { UNROLL( DESTREADPIXEL(temp, pbDest - rowDelta); - DESTWRITEPIXEL(pbDest, temp); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp)) + return FALSE; DESTNEXTPIXEL(pbDest);); + runLength = runLength - UNROLL_COUNT; } while (runLength > 0) { DESTREADPIXEL(temp, pbDest - rowDelta); - DESTWRITEPIXEL(pbDest, temp); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -419,14 +471,19 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, while (runLength >= UNROLL_COUNT) { UNROLL( - DESTWRITEPIXEL(pbDest, fgPel); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return FALSE; DESTNEXTPIXEL(pbDest);); + runLength = runLength - UNROLL_COUNT; } while (runLength > 0) { - DESTWRITEPIXEL(pbDest, fgPel); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, fgPel)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -437,15 +494,21 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, { UNROLL( DESTREADPIXEL(temp, pbDest - rowDelta); - DESTWRITEPIXEL(pbDest, temp ^ fgPel); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp ^ fgPel)) + return FALSE; DESTNEXTPIXEL(pbDest);); + runLength = runLength - UNROLL_COUNT; } while (runLength > 0) { DESTREADPIXEL(temp, pbDest - rowDelta); - DESTWRITEPIXEL(pbDest, temp ^ fgPel); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp ^ fgPel)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -466,18 +529,27 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, while (runLength >= UNROLL_COUNT) { UNROLL( - DESTWRITEPIXEL(pbDest, pixelA); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelA)) + return FALSE; DESTNEXTPIXEL(pbDest); - DESTWRITEPIXEL(pbDest, pixelB); - DESTNEXTPIXEL(pbDest);); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelB)) + return FALSE; + DESTNEXTPIXEL(pbDest);); + runLength = runLength - UNROLL_COUNT; } while (runLength > 0) { - DESTWRITEPIXEL(pbDest, pixelA); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelA)) + return FALSE; + DESTNEXTPIXEL(pbDest); - DESTWRITEPIXEL(pbDest, pixelB); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelB)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -495,14 +567,19 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, while (runLength >= UNROLL_COUNT) { UNROLL( - DESTWRITEPIXEL(pbDest, pixelA); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelA)) + return FALSE; DESTNEXTPIXEL(pbDest);); + runLength = runLength - UNROLL_COUNT; } while (runLength > 0) { - DESTWRITEPIXEL(pbDest, pixelA); + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, pixelA)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -529,7 +606,11 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, { bitmask = *pbSrc; pbSrc = pbSrc + 1; - pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, bitmask, fgPel, 8); + pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8); + + if (!pbDest) + return FALSE; + runLength = runLength - 8; } } @@ -539,7 +620,11 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, { bitmask = *pbSrc; pbSrc = pbSrc + 1; - pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, bitmask, fgPel, 8); + pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8); + + if (!pbDest) + return FALSE; + runLength = runLength - 8; } } @@ -551,12 +636,15 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, if (fFirstLine) { - pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, bitmask, fgPel, runLength); + pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength); } else { - pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, bitmask, fgPel, runLength); + pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength); } + + if (!pbDest) + return FALSE; } break; @@ -572,8 +660,11 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, UNROLL( SRCREADPIXEL(temp, pbSrc); SRCNEXTPIXEL(pbSrc); - DESTWRITEPIXEL(pbDest, temp); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp)) + return FALSE; DESTNEXTPIXEL(pbDest);); + runLength = runLength - UNROLL_COUNT; } @@ -581,7 +672,10 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, { SRCREADPIXEL(temp, pbSrc); SRCNEXTPIXEL(pbSrc); - DESTWRITEPIXEL(pbDest, temp); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, temp)) + return FALSE; + DESTNEXTPIXEL(pbDest); runLength = runLength - 1; } @@ -594,13 +688,16 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, if (fFirstLine) { - pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, g_MaskSpecialFgBg1, fgPel, 8); + pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8); } else { - pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, g_MaskSpecialFgBg1, fgPel, 8); + pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8); } + if (!pbDest) + return FALSE; + break; /* Handle Special Order 2. */ @@ -609,26 +706,35 @@ static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, if (fFirstLine) { - pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, g_MaskSpecialFgBg2, fgPel, 8); + pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8); } else { - pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, g_MaskSpecialFgBg2, fgPel, 8); + pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8); } + if (!pbDest) + return FALSE; + break; /* Handle White Order. */ case SPECIAL_WHITE: pbSrc = pbSrc + 1; - DESTWRITEPIXEL(pbDest, WHITE_PIXEL); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, WHITE_PIXEL)) + return FALSE; + DESTNEXTPIXEL(pbDest); break; /* Handle Black Order. */ case SPECIAL_BLACK: pbSrc = pbSrc + 1; - DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + + if (!DESTWRITEPIXEL(pbDest, pbDestEnd, BLACK_PIXEL)) + return FALSE; + DESTNEXTPIXEL(pbDest); break; diff --git a/libfreerdp/codec/interleaved.c b/libfreerdp/codec/interleaved.c index 44bdde794..7adc481f0 100644 --- a/libfreerdp/codec/interleaved.c +++ b/libfreerdp/codec/interleaved.c @@ -59,7 +59,6 @@ #define SPECIAL_BLACK 0xFE #define BLACK_PIXEL 0x000000 -#define WHITE_PIXEL 0xFFFFFF typedef UINT32 PIXEL; @@ -193,6 +192,44 @@ static INLINE UINT32 ExtractRunLength(UINT32 code, const BYTE* pbOrderHdr, return runLength; } +static INLINE BOOL write_pixel_8(BYTE* _buf, const BYTE* _end, BYTE _pix) +{ + if (!_buf || !_end) + return FALSE; + + if ((_end - _buf) < 1) + return FALSE; + + *_buf = _pix; + return TRUE; +} + +static INLINE BOOL write_pixel_24(BYTE* _buf, const BYTE* _end, UINT32 _pix) +{ + if (!_buf || !_end) + return FALSE; + + if ((_end - _buf) < 3) + return FALSE; + + (_buf)[0] = (BYTE)(_pix); + (_buf)[1] = (BYTE)((_pix) >> 8); + (_buf)[2] = (BYTE)((_pix) >> 16); + return TRUE; +} + +static INLINE BOOL write_pixel_16(BYTE* _buf, const BYTE* _end, UINT16 _pix) +{ + if (!_buf || !_end) + return FALSE; + + if ((_end - _buf) < 2) + return FALSE; + + *(UINT16*)_buf = _pix; + return TRUE; +} + #define UNROLL_COUNT 4 #define UNROLL(_exp) do { _exp _exp _exp _exp } while (0) @@ -205,7 +242,9 @@ static INLINE UINT32 ExtractRunLength(UINT32 code, const BYTE* pbOrderHdr, #undef WRITEFIRSTLINEFGBGIMAGE #undef RLEDECOMPRESS #undef RLEEXTRA -#define DESTWRITEPIXEL(_buf, _pix) (_buf)[0] = (BYTE)(_pix) +#undef WHITE_PIXEL +#define WHITE_PIXEL 0xFF +#define DESTWRITEPIXEL(_buf, _end, _pix) write_pixel_8(_buf, _end, _pix) #define DESTREADPIXEL(_pix, _buf) _pix = (_buf)[0] #define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0] #define DESTNEXTPIXEL(_buf) _buf += 1 @@ -225,7 +264,9 @@ static INLINE UINT32 ExtractRunLength(UINT32 code, const BYTE* pbOrderHdr, #undef WRITEFIRSTLINEFGBGIMAGE #undef RLEDECOMPRESS #undef RLEEXTRA -#define DESTWRITEPIXEL(_buf, _pix) ((UINT16*)(_buf))[0] = (UINT16)(_pix) +#undef WHITE_PIXEL +#define WHITE_PIXEL 0xFFFF +#define DESTWRITEPIXEL(_buf, _end, _pix) write_pixel_16(_buf, _end, _pix) #define DESTREADPIXEL(_pix, _buf) _pix = ((UINT16*)(_buf))[0] #ifdef HAVE_ALIGNED_REQUIRED #define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8) @@ -249,8 +290,9 @@ static INLINE UINT32 ExtractRunLength(UINT32 code, const BYTE* pbOrderHdr, #undef WRITEFIRSTLINEFGBGIMAGE #undef RLEDECOMPRESS #undef RLEEXTRA -#define DESTWRITEPIXEL(_buf, _pix) do { (_buf)[0] = (BYTE)(_pix); \ - (_buf)[1] = (BYTE)((_pix) >> 8); (_buf)[2] = (BYTE)((_pix) >> 16); } while (0) +#undef WHITE_PIXEL +#define WHITE_PIXEL 0xFFFFFF +#define DESTWRITEPIXEL(_buf, _end, _pix) write_pixel_24(_buf, _end, _pix) #define DESTREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8) | \ ((_buf)[2] << 16) #define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8) | \