2 * FreeRDP: A Remote Desktop Protocol Client
3 * RLE Compressed Bitmap Stream
5 * Copyright 2011 Jay Sorg <jay.sorg@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 /* do not compile the file directly */
23 * Write a foreground/background image to a destination buffer.
25 static uint8* WRITEFGBGIMAGE(uint8* pbDest, uint32 rowDelta,
26 uint8 bitmask, PIXEL fgPel, uint32 cBits)
30 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
31 if (bitmask & g_MaskBit0)
33 DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
37 DESTWRITEPIXEL(pbDest, xorPixel);
39 DESTNEXTPIXEL(pbDest);
43 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
44 if (bitmask & g_MaskBit1)
46 DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
50 DESTWRITEPIXEL(pbDest, xorPixel);
52 DESTNEXTPIXEL(pbDest);
56 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
57 if (bitmask & g_MaskBit2)
59 DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
63 DESTWRITEPIXEL(pbDest, xorPixel);
65 DESTNEXTPIXEL(pbDest);
69 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
70 if (bitmask & g_MaskBit3)
72 DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
76 DESTWRITEPIXEL(pbDest, xorPixel);
78 DESTNEXTPIXEL(pbDest);
82 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
83 if (bitmask & g_MaskBit4)
85 DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
89 DESTWRITEPIXEL(pbDest, xorPixel);
91 DESTNEXTPIXEL(pbDest);
95 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
96 if (bitmask & g_MaskBit5)
98 DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
102 DESTWRITEPIXEL(pbDest, xorPixel);
104 DESTNEXTPIXEL(pbDest);
108 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
109 if (bitmask & g_MaskBit6)
111 DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
115 DESTWRITEPIXEL(pbDest, xorPixel);
117 DESTNEXTPIXEL(pbDest);
121 DESTREADPIXEL(xorPixel, pbDest - rowDelta);
122 if (bitmask & g_MaskBit7)
124 DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel);
128 DESTWRITEPIXEL(pbDest, xorPixel);
130 DESTNEXTPIXEL(pbDest);
142 * Write a foreground/background image to a destination buffer
143 * for the first line of compressed data.
145 static uint8* WRITEFIRSTLINEFGBGIMAGE(uint8* pbDest, uint8 bitmask,
146 PIXEL fgPel, uint32 cBits)
148 if (bitmask & g_MaskBit0)
150 DESTWRITEPIXEL(pbDest, fgPel);
154 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
156 DESTNEXTPIXEL(pbDest);
160 if (bitmask & g_MaskBit1)
162 DESTWRITEPIXEL(pbDest, fgPel);
166 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
168 DESTNEXTPIXEL(pbDest);
172 if (bitmask & g_MaskBit2)
174 DESTWRITEPIXEL(pbDest, fgPel);
178 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
180 DESTNEXTPIXEL(pbDest);
184 if (bitmask & g_MaskBit3)
186 DESTWRITEPIXEL(pbDest, fgPel);
190 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
192 DESTNEXTPIXEL(pbDest);
196 if (bitmask & g_MaskBit4)
198 DESTWRITEPIXEL(pbDest, fgPel);
202 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
204 DESTNEXTPIXEL(pbDest);
208 if (bitmask & g_MaskBit5)
210 DESTWRITEPIXEL(pbDest, fgPel);
214 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
216 DESTNEXTPIXEL(pbDest);
220 if (bitmask & g_MaskBit6)
222 DESTWRITEPIXEL(pbDest, fgPel);
226 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
228 DESTNEXTPIXEL(pbDest);
232 if (bitmask & g_MaskBit7)
234 DESTWRITEPIXEL(pbDest, fgPel);
238 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
240 DESTNEXTPIXEL(pbDest);
252 * Decompress an RLE compressed bitmap.
254 void RLEDECOMPRESS(uint8* pbSrcBuffer, uint32 cbSrcBuffer, uint8* pbDestBuffer,
255 uint32 rowDelta, uint32 width, uint32 height)
257 uint8* pbSrc = pbSrcBuffer;
258 uint8* pbEnd = pbSrcBuffer + cbSrcBuffer;
259 uint8* pbDest = pbDestBuffer;
262 PIXEL fgPel = WHITE_PIXEL;
263 boolean fInsertFgPel = false;
264 boolean fFirstLine = true;
267 PIXEL pixelA, pixelB;
276 while (pbSrc < pbEnd)
278 /* Watch out for the end of the first scanline. */
281 if ((uint32)(pbDest - pbDestBuffer) >= rowDelta)
284 fInsertFgPel = false;
289 Extract the compression order code ID from the compression
292 code = ExtractCodeId(*pbSrc);
294 /* Handle Background Run Orders. */
295 if (code == REGULAR_BG_RUN || code == MEGA_MEGA_BG_RUN)
297 runLength = ExtractRunLength(code, pbSrc, &advance);
298 pbSrc = pbSrc + advance;
303 DESTWRITEPIXEL(pbDest, fgPel);
304 DESTNEXTPIXEL(pbDest);
305 runLength = runLength - 1;
307 while (runLength >= UNROLL_COUNT)
310 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
311 DESTNEXTPIXEL(pbDest); );
312 runLength = runLength - UNROLL_COUNT;
314 while (runLength > 0)
316 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
317 DESTNEXTPIXEL(pbDest);
318 runLength = runLength - 1;
325 DESTREADPIXEL(temp, pbDest - rowDelta);
326 DESTWRITEPIXEL(pbDest, temp ^ fgPel);
327 DESTNEXTPIXEL(pbDest);
328 runLength = runLength - 1;
330 while (runLength >= UNROLL_COUNT)
333 DESTREADPIXEL(temp, pbDest - rowDelta);
334 DESTWRITEPIXEL(pbDest, temp);
335 DESTNEXTPIXEL(pbDest); );
336 runLength = runLength - UNROLL_COUNT;
338 while (runLength > 0)
340 DESTREADPIXEL(temp, pbDest - rowDelta);
341 DESTWRITEPIXEL(pbDest, temp);
342 DESTNEXTPIXEL(pbDest);
343 runLength = runLength - 1;
346 /* A follow-on background run order will need a foreground pel inserted. */
351 /* For any of the other run-types a follow-on background run
352 order does not need a foreground pel inserted. */
353 fInsertFgPel = false;
357 /* Handle Foreground Run Orders. */
359 case MEGA_MEGA_FG_RUN:
360 case LITE_SET_FG_FG_RUN:
361 case MEGA_MEGA_SET_FG_RUN:
362 runLength = ExtractRunLength(code, pbSrc, &advance);
363 pbSrc = pbSrc + advance;
364 if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
366 SRCREADPIXEL(fgPel, pbSrc);
371 while (runLength >= UNROLL_COUNT)
374 DESTWRITEPIXEL(pbDest, fgPel);
375 DESTNEXTPIXEL(pbDest); );
376 runLength = runLength - UNROLL_COUNT;
378 while (runLength > 0)
380 DESTWRITEPIXEL(pbDest, fgPel);
381 DESTNEXTPIXEL(pbDest);
382 runLength = runLength - 1;
387 while (runLength >= UNROLL_COUNT)
390 DESTREADPIXEL(temp, pbDest - rowDelta);
391 DESTWRITEPIXEL(pbDest, temp ^ fgPel);
392 DESTNEXTPIXEL(pbDest); );
393 runLength = runLength - UNROLL_COUNT;
395 while (runLength > 0)
397 DESTREADPIXEL(temp, pbDest - rowDelta);
398 DESTWRITEPIXEL(pbDest, temp ^ fgPel);
399 DESTNEXTPIXEL(pbDest);
400 runLength = runLength - 1;
405 /* Handle Dithered Run Orders. */
406 case LITE_DITHERED_RUN:
407 case MEGA_MEGA_DITHERED_RUN:
408 runLength = ExtractRunLength(code, pbSrc, &advance);
409 pbSrc = pbSrc + advance;
410 SRCREADPIXEL(pixelA, pbSrc);
412 SRCREADPIXEL(pixelB, pbSrc);
414 while (runLength >= UNROLL_COUNT)
417 DESTWRITEPIXEL(pbDest, pixelA);
418 DESTNEXTPIXEL(pbDest);
419 DESTWRITEPIXEL(pbDest, pixelB);
420 DESTNEXTPIXEL(pbDest); );
421 runLength = runLength - UNROLL_COUNT;
423 while (runLength > 0)
425 DESTWRITEPIXEL(pbDest, pixelA);
426 DESTNEXTPIXEL(pbDest);
427 DESTWRITEPIXEL(pbDest, pixelB);
428 DESTNEXTPIXEL(pbDest);
429 runLength = runLength - 1;
433 /* Handle Color Run Orders. */
434 case REGULAR_COLOR_RUN:
435 case MEGA_MEGA_COLOR_RUN:
436 runLength = ExtractRunLength(code, pbSrc, &advance);
437 pbSrc = pbSrc + advance;
438 SRCREADPIXEL(pixelA, pbSrc);
440 while (runLength >= UNROLL_COUNT)
443 DESTWRITEPIXEL(pbDest, pixelA);
444 DESTNEXTPIXEL(pbDest); );
445 runLength = runLength - UNROLL_COUNT;
447 while (runLength > 0)
449 DESTWRITEPIXEL(pbDest, pixelA);
450 DESTNEXTPIXEL(pbDest);
451 runLength = runLength - 1;
455 /* Handle Foreground/Background Image Orders. */
456 case REGULAR_FGBG_IMAGE:
457 case MEGA_MEGA_FGBG_IMAGE:
458 case LITE_SET_FG_FGBG_IMAGE:
459 case MEGA_MEGA_SET_FGBG_IMAGE:
460 runLength = ExtractRunLength(code, pbSrc, &advance);
461 pbSrc = pbSrc + advance;
462 if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
464 SRCREADPIXEL(fgPel, pbSrc);
469 while (runLength > 8)
473 pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, bitmask, fgPel, 8);
474 runLength = runLength - 8;
479 while (runLength > 8)
483 pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, bitmask, fgPel, 8);
484 runLength = runLength - 8;
493 pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, bitmask, fgPel, runLength);
497 pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, bitmask, fgPel, runLength);
502 /* Handle Color Image Orders. */
503 case REGULAR_COLOR_IMAGE:
504 case MEGA_MEGA_COLOR_IMAGE:
505 runLength = ExtractRunLength(code, pbSrc, &advance);
506 pbSrc = pbSrc + advance;
507 while (runLength >= UNROLL_COUNT)
510 SRCREADPIXEL(temp, pbSrc);
512 DESTWRITEPIXEL(pbDest, temp);
513 DESTNEXTPIXEL(pbDest); );
514 runLength = runLength - UNROLL_COUNT;
516 while (runLength > 0)
518 SRCREADPIXEL(temp, pbSrc);
520 DESTWRITEPIXEL(pbDest, temp);
521 DESTNEXTPIXEL(pbDest);
522 runLength = runLength - 1;
526 /* Handle Special Order 1. */
531 pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, g_MaskSpecialFgBg1, fgPel, 8);
535 pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
539 /* Handle Special Order 2. */
544 pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, g_MaskSpecialFgBg2, fgPel, 8);
548 pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
552 /* Handle White Order. */
555 DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
556 DESTNEXTPIXEL(pbDest);
559 /* Handle Black Order. */
562 DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
563 DESTNEXTPIXEL(pbDest);