22 #include <winpr/assert.h>
23 #include <winpr/cast.h>
24 #include <winpr/wtypes.h>
31 static inline BYTE* WRITEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
32 const BYTE* WINPR_RESTRICT pbDestEnd, UINT32 rowDelta,
33 BYTE bitmask, PIXEL fgPel, UINT32 cBits)
40 WLog_ERR(TAG,
"cBits %d > 8", cBits);
44 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
49 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
52 data = xorPixel ^ fgPel;
56 DESTWRITEPIXEL(pbDest, data);
57 mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
66 static inline BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
67 const BYTE* WINPR_RESTRICT pbDestEnd, BYTE bitmask,
68 PIXEL fgPel, UINT32 cBits)
74 WLog_ERR(TAG,
"cBits %d > 8", cBits);
78 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
89 DESTWRITEPIXEL(pbDest, data);
90 mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
98 static inline BOOL RLEDECOMPRESS(
const BYTE* WINPR_RESTRICT pbSrcBuffer, UINT32 cbSrcBuffer,
99 BYTE* WINPR_RESTRICT pbDestBuffer, UINT32 rowDelta, UINT32 width,
102 #if defined(WITH_DEBUG_CODECS)
103 char sbuffer[128] = { 0 };
105 const BYTE* pbSrc = pbSrcBuffer;
106 BYTE* pbDest = pbDestBuffer;
108 PIXEL fgPel = WHITE_PIXEL;
109 BOOL fInsertFgPel = FALSE;
110 BOOL fFirstLine = TRUE;
114 UINT32 runLength = 0;
119 if ((rowDelta == 0) || (rowDelta < width))
121 WLog_ERR(TAG,
"Invalid arguments: rowDelta=%" PRIu32
" == 0 || < width=%" PRIu32, rowDelta,
126 if (!pbSrcBuffer || !pbDestBuffer)
128 WLog_ERR(TAG,
"Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p", pbSrcBuffer,
133 const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
134 const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136 while (pbSrc < pbEnd)
141 if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
144 fInsertFgPel = FALSE;
152 code = ExtractCodeId(*pbSrc);
154 #if defined(WITH_DEBUG_CODECS)
155 WLog_VRB(TAG,
"pbSrc=%p code=%s, rem=%" PRIuz, pbSrc,
156 rle_code_str_buffer(code, sbuffer,
sizeof(sbuffer)), pbEnd - pbSrc);
160 if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162 runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
165 pbSrc = pbSrc + advance;
171 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
174 DESTWRITEPIXEL(pbDest, fgPel);
175 runLength = runLength - 1;
178 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
181 UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
187 DESTREADPIXEL(temp, pbDest - rowDelta);
189 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
192 DESTWRITEPIXEL(pbDest, temp ^ fgPel);
196 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
200 DESTREADPIXEL(temp, pbDest - rowDelta);
201 DESTWRITEPIXEL(pbDest, temp);
212 fInsertFgPel = FALSE;
218 case MEGA_MEGA_FG_RUN:
219 case LITE_SET_FG_FG_RUN:
220 case MEGA_MEGA_SET_FG_RUN:
221 runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
224 pbSrc = pbSrc + advance;
226 if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228 if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230 SRCREADPIXEL(fgPel, pbSrc);
233 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
238 UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
243 DESTREADPIXEL(temp, pbDest - rowDelta);
244 DESTWRITEPIXEL(pbDest, temp ^ fgPel);
251 case LITE_DITHERED_RUN:
252 case MEGA_MEGA_DITHERED_RUN:
253 runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
256 pbSrc = pbSrc + advance;
257 if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259 SRCREADPIXEL(pixelA, pbSrc);
260 if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262 SRCREADPIXEL(pixelB, pbSrc);
264 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
268 DESTWRITEPIXEL(pbDest, pixelA);
269 DESTWRITEPIXEL(pbDest, pixelB);
274 case REGULAR_COLOR_RUN:
275 case MEGA_MEGA_COLOR_RUN:
276 runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
279 pbSrc = pbSrc + advance;
280 if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282 SRCREADPIXEL(pixelA, pbSrc);
284 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
287 UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
291 case REGULAR_FGBG_IMAGE:
292 case MEGA_MEGA_FGBG_IMAGE:
293 case LITE_SET_FG_FGBG_IMAGE:
294 case MEGA_MEGA_SET_FGBG_IMAGE:
295 runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
298 pbSrc = pbSrc + advance;
300 if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302 if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304 SRCREADPIXEL(fgPel, pbSrc);
307 if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
311 while (runLength > 8)
315 pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
320 runLength = runLength - 8;
325 while (runLength > 8)
329 pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
334 runLength = runLength - 8;
340 if (!buffer_within_range(pbSrc, 1, pbEnd))
347 WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
352 WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
362 case REGULAR_COLOR_IMAGE:
363 case MEGA_MEGA_COLOR_IMAGE:
364 runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
367 pbSrc = pbSrc + advance;
368 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370 if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
374 SRCREADPIXEL(temp, pbSrc);
375 DESTWRITEPIXEL(pbDest, temp);
381 if (!buffer_within_range(pbSrc, 1, pbEnd))
388 WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
393 WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
403 if (!buffer_within_range(pbSrc, 1, pbEnd))
410 WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
415 WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
425 if (!buffer_within_range(pbSrc, 1, pbEnd))
429 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
432 DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
437 if (!buffer_within_range(pbSrc, 1, pbEnd))
441 if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
444 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
448 WLog_ERR(TAG,
"invalid code 0x%08" PRIx32
", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449 code, pbSrcBuffer, pbSrc, pbEnd);