Coverage Report

Created: 2026-02-26 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/libfreerdp/codec/include/bitmap.h
Line
Count
Source
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * RLE Compressed Bitmap Stream
4
 *
5
 * Copyright 2011 Jay Sorg <jay.sorg@gmail.com>
6
 * Copyright 2016 Armin Novak <armin.novak@thincast.com>
7
 * Copyright 2016 Thincast Technologies GmbH
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 *     http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
22
#include <winpr/assert.h>
23
#include <winpr/cast.h>
24
#include <winpr/wtypes.h>
25
26
/* do not compile the file directly */
27
28
/**
29
 * Write a foreground/background image to a destination buffer.
30
 */
31
WINPR_ATTR_NODISCARD
32
static inline BYTE* WRITEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
33
                                   const BYTE* WINPR_RESTRICT pbDestEnd, UINT32 rowDelta,
34
                                   BYTE bitmask, PIXEL fgPel, UINT32 cBits)
35
104k
{
36
104k
  PIXEL xorPixel = 0;
37
104k
  BYTE mask = 0x01;
38
39
104k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return NULL;
43
0
  }
44
45
104k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
109
    return NULL;
47
48
104k
  UNROLL(cBits, {
49
104k
    PIXEL data = 0;
50
104k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
104k
    if (bitmask & mask)
53
104k
      data = xorPixel ^ fgPel;
54
104k
    else
55
104k
      data = xorPixel;
56
57
104k
    DESTWRITEPIXEL(pbDest, data);
58
104k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
104k
  });
60
104k
  return pbDest;
61
104k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
35
29.6k
{
36
29.6k
  PIXEL xorPixel = 0;
37
29.6k
  BYTE mask = 0x01;
38
39
29.6k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return NULL;
43
0
  }
44
45
29.6k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
33
    return NULL;
47
48
29.6k
  UNROLL(cBits, {
49
29.6k
    PIXEL data = 0;
50
29.6k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
29.6k
    if (bitmask & mask)
53
29.6k
      data = xorPixel ^ fgPel;
54
29.6k
    else
55
29.6k
      data = xorPixel;
56
57
29.6k
    DESTWRITEPIXEL(pbDest, data);
58
29.6k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
29.6k
  });
60
29.6k
  return pbDest;
61
29.6k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
35
75.1k
{
36
75.1k
  PIXEL xorPixel = 0;
37
75.1k
  BYTE mask = 0x01;
38
39
75.1k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return NULL;
43
0
  }
44
45
75.1k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
76
    return NULL;
47
48
75.0k
  UNROLL(cBits, {
49
75.0k
    PIXEL data = 0;
50
75.0k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
75.0k
    if (bitmask & mask)
53
75.0k
      data = xorPixel ^ fgPel;
54
75.0k
    else
55
75.0k
      data = xorPixel;
56
57
75.0k
    DESTWRITEPIXEL(pbDest, data);
58
75.0k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
75.0k
  });
60
75.0k
  return pbDest;
61
75.1k
}
Unexecuted instantiation: interleaved.c:WriteFgBgImage8to8
62
63
/**
64
 * Write a foreground/background image to a destination buffer
65
 * for the first line of compressed data.
66
 */
67
WINPR_ATTR_NODISCARD
68
static inline BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
69
                                            const BYTE* WINPR_RESTRICT pbDestEnd, BYTE bitmask,
70
                                            PIXEL fgPel, UINT32 cBits)
71
58.8k
{
72
58.8k
  BYTE mask = 0x01;
73
74
58.8k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return NULL;
78
0
  }
79
80
58.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
53
    return NULL;
82
83
58.7k
  UNROLL(cBits, {
84
58.7k
    PIXEL data;
85
86
58.7k
    if (bitmask & mask)
87
58.7k
      data = fgPel;
88
58.7k
    else
89
58.7k
      data = BLACK_PIXEL;
90
91
58.7k
    DESTWRITEPIXEL(pbDest, data);
92
58.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
58.7k
  });
94
58.7k
  return pbDest;
95
58.8k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
71
20.2k
{
72
20.2k
  BYTE mask = 0x01;
73
74
20.2k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return NULL;
78
0
  }
79
80
20.2k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
17
    return NULL;
82
83
20.2k
  UNROLL(cBits, {
84
20.2k
    PIXEL data;
85
86
20.2k
    if (bitmask & mask)
87
20.2k
      data = fgPel;
88
20.2k
    else
89
20.2k
      data = BLACK_PIXEL;
90
91
20.2k
    DESTWRITEPIXEL(pbDest, data);
92
20.2k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
20.2k
  });
94
20.2k
  return pbDest;
95
20.2k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
71
38.5k
{
72
38.5k
  BYTE mask = 0x01;
73
74
38.5k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return NULL;
78
0
  }
79
80
38.5k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
36
    return NULL;
82
83
38.5k
  UNROLL(cBits, {
84
38.5k
    PIXEL data;
85
86
38.5k
    if (bitmask & mask)
87
38.5k
      data = fgPel;
88
38.5k
    else
89
38.5k
      data = BLACK_PIXEL;
90
91
38.5k
    DESTWRITEPIXEL(pbDest, data);
92
38.5k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
38.5k
  });
94
38.5k
  return pbDest;
95
38.5k
}
Unexecuted instantiation: interleaved.c:WriteFirstLineFgBgImage8to8
96
97
/**
98
 * Decompress an RLE compressed bitmap.
99
 */
100
WINPR_ATTR_NODISCARD
101
static inline BOOL RLEDECOMPRESS(const BYTE* WINPR_RESTRICT pbSrcBuffer, UINT32 cbSrcBuffer,
102
                                 BYTE* WINPR_RESTRICT pbDestBuffer, UINT32 rowDelta, UINT32 width,
103
                                 UINT32 height)
104
16.5k
{
105
16.5k
  const BYTE* pbSrc = pbSrcBuffer;
106
16.5k
  BYTE* pbDest = pbDestBuffer;
107
16.5k
  PIXEL temp = 0;
108
16.5k
  PIXEL fgPel = WHITE_PIXEL;
109
16.5k
  BOOL fInsertFgPel = FALSE;
110
16.5k
  BOOL fFirstLine = TRUE;
111
16.5k
  BYTE bitmask = 0;
112
16.5k
  PIXEL pixelA = 0;
113
16.5k
  PIXEL pixelB = 0;
114
16.5k
  UINT32 runLength = 0;
115
16.5k
  UINT32 code = 0;
116
16.5k
  UINT32 advance = 0;
117
16.5k
  RLEEXTRA
118
119
16.5k
  if ((rowDelta == 0) || (rowDelta < width))
120
0
  {
121
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
122
0
             width);
123
0
    return FALSE;
124
0
  }
125
126
16.5k
  if (!pbSrcBuffer || !pbDestBuffer)
127
0
  {
128
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p",
129
0
             WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
130
0
             WINPR_CXX_COMPAT_CAST(const void*, pbDestBuffer));
131
0
    return FALSE;
132
0
  }
133
134
16.5k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
16.5k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
462k
  while (pbSrc < pbEnd)
138
458k
  {
139
    /* Watch out for the end of the first scanline. */
140
458k
    if (fFirstLine)
141
79.4k
    {
142
79.4k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
12.0k
      {
144
12.0k
        fFirstLine = FALSE;
145
12.0k
        fInsertFgPel = FALSE;
146
12.0k
      }
147
79.4k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
458k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
157
#endif
158
159
    /* Handle Background Run Orders. */
160
458k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
317k
    {
162
317k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
317k
      if (advance == 0)
164
650
        return FALSE;
165
316k
      pbSrc = pbSrc + advance;
166
167
316k
      if (fFirstLine)
168
34.0k
      {
169
34.0k
        if (fInsertFgPel)
170
23.4k
        {
171
23.4k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
23.4k
          DESTWRITEPIXEL(pbDest, fgPel);
175
23.4k
          runLength = runLength - 1;
176
23.4k
        }
177
178
34.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
71
          return FALSE;
180
181
33.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
33.9k
      }
183
282k
      else
184
282k
      {
185
282k
        if (fInsertFgPel)
186
256k
        {
187
256k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
256k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
50
            return FALSE;
191
192
256k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
256k
          runLength--;
194
256k
        }
195
196
282k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
865
          return FALSE;
198
199
281k
        UNROLL(runLength, {
200
281k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
281k
          DESTWRITEPIXEL(pbDest, temp);
202
281k
        });
203
281k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
315k
      fInsertFgPel = TRUE;
207
315k
      continue;
208
316k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
140k
    fInsertFgPel = FALSE;
213
214
140k
    switch (code)
215
140k
    {
216
      /* Handle Foreground Run Orders. */
217
28.1k
      case REGULAR_FG_RUN:
218
29.9k
      case MEGA_MEGA_FG_RUN:
219
45.1k
      case LITE_SET_FG_FG_RUN:
220
46.1k
      case MEGA_MEGA_SET_FG_RUN:
221
46.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
46.1k
        if (advance == 0)
223
83
          return FALSE;
224
46.0k
        pbSrc = pbSrc + advance;
225
226
46.0k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
16.1k
        {
228
16.1k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
211
            return FALSE;
230
15.9k
          SRCREADPIXEL(fgPel, pbSrc);
231
15.9k
        }
232
233
45.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
279
          return FALSE;
235
236
45.5k
        if (fFirstLine)
237
10.1k
        {
238
10.1k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
10.1k
        }
240
35.4k
        else
241
35.4k
        {
242
35.4k
          UNROLL(runLength, {
243
35.4k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
35.4k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
35.4k
          });
246
35.4k
        }
247
248
45.5k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
10.6k
      case LITE_DITHERED_RUN:
252
11.8k
      case MEGA_MEGA_DITHERED_RUN:
253
11.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
11.8k
        if (advance == 0)
255
45
          return FALSE;
256
11.8k
        pbSrc = pbSrc + advance;
257
11.8k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
281
          return FALSE;
259
11.5k
        SRCREADPIXEL(pixelA, pbSrc);
260
11.5k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
505
          return FALSE;
262
11.0k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
11.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
142
          return FALSE;
266
267
10.9k
        UNROLL(runLength, {
268
10.9k
          DESTWRITEPIXEL(pbDest, pixelA);
269
10.9k
          DESTWRITEPIXEL(pbDest, pixelB);
270
10.9k
        });
271
10.9k
        break;
272
273
      /* Handle Color Run Orders. */
274
30.6k
      case REGULAR_COLOR_RUN:
275
32.0k
      case MEGA_MEGA_COLOR_RUN:
276
32.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
32.0k
        if (advance == 0)
278
47
          return FALSE;
279
31.9k
        pbSrc = pbSrc + advance;
280
31.9k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
281
          return FALSE;
282
31.6k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
31.6k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
190
          return FALSE;
286
287
31.4k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
31.4k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
13.7k
      case REGULAR_FGBG_IMAGE:
292
15.8k
      case MEGA_MEGA_FGBG_IMAGE:
293
20.0k
      case LITE_SET_FG_FGBG_IMAGE:
294
21.1k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
21.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
21.1k
        if (advance == 0)
297
139
          return FALSE;
298
20.9k
        pbSrc = pbSrc + advance;
299
300
20.9k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
5.15k
        {
302
5.15k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
160
            return FALSE;
304
4.99k
          SRCREADPIXEL(fgPel, pbSrc);
305
4.99k
        }
306
307
20.8k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
774
          return FALSE;
309
20.0k
        if (fFirstLine)
310
5.20k
        {
311
60.4k
          while (runLength > 8)
312
55.3k
          {
313
55.3k
            bitmask = *pbSrc;
314
55.3k
            pbSrc = pbSrc + 1;
315
55.3k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
55.3k
            if (!pbDest)
318
50
              return FALSE;
319
320
55.2k
            runLength = runLength - 8;
321
55.2k
          }
322
5.20k
        }
323
14.8k
        else
324
14.8k
        {
325
101k
          while (runLength > 8)
326
86.2k
          {
327
86.2k
            bitmask = *pbSrc++;
328
329
86.2k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
86.2k
            if (!pbDest)
332
89
              return FALSE;
333
334
86.1k
            runLength = runLength - 8;
335
86.1k
          }
336
14.8k
        }
337
338
19.9k
        if (runLength > 0)
339
17.2k
        {
340
17.2k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
91
            return FALSE;
342
17.1k
          bitmask = *pbSrc++;
343
344
17.1k
          if (fFirstLine)
345
2.90k
          {
346
2.90k
            pbDest =
347
2.90k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
2.90k
          }
349
14.2k
          else
350
14.2k
          {
351
14.2k
            pbDest =
352
14.2k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
14.2k
          }
354
355
17.1k
          if (!pbDest)
356
12
            return FALSE;
357
17.1k
        }
358
359
19.8k
        break;
360
361
      /* Handle Color Image Orders. */
362
19.8k
      case REGULAR_COLOR_IMAGE:
363
12.2k
      case MEGA_MEGA_COLOR_IMAGE:
364
12.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
12.2k
        if (advance == 0)
366
76
          return FALSE;
367
12.1k
        pbSrc = pbSrc + advance;
368
12.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
106
          return FALSE;
370
12.0k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
933
          return FALSE;
372
373
11.1k
        UNROLL(runLength, {
374
11.1k
          SRCREADPIXEL(temp, pbSrc);
375
11.1k
          DESTWRITEPIXEL(pbDest, temp);
376
11.1k
        });
377
11.1k
        break;
378
379
      /* Handle Special Order 1. */
380
2.14k
      case SPECIAL_FGBG_1:
381
2.14k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
2.14k
        pbSrc = pbSrc + 1;
384
385
2.14k
        if (fFirstLine)
386
298
        {
387
298
          pbDest =
388
298
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
298
        }
390
1.85k
        else
391
1.85k
        {
392
1.85k
          pbDest =
393
1.85k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
1.85k
        }
395
396
2.14k
        if (!pbDest)
397
5
          return FALSE;
398
399
2.14k
        break;
400
401
      /* Handle Special Order 2. */
402
2.77k
      case SPECIAL_FGBG_2:
403
2.77k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
2.77k
        pbSrc = pbSrc + 1;
406
407
2.77k
        if (fFirstLine)
408
304
        {
409
304
          pbDest =
410
304
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
304
        }
412
2.47k
        else
413
2.47k
        {
414
2.47k
          pbDest =
415
2.47k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
2.47k
        }
417
418
2.77k
        if (!pbDest)
419
6
          return FALSE;
420
421
2.77k
        break;
422
423
      /* Handle White Order. */
424
3.69k
      case SPECIAL_WHITE:
425
3.69k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
3.69k
        pbSrc = pbSrc + 1;
428
429
3.69k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
3
          return FALSE;
431
432
3.69k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
3.69k
        break;
434
435
      /* Handle Black Order. */
436
2.81k
      case SPECIAL_BLACK:
437
2.81k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
2.81k
        pbSrc = pbSrc + 1;
440
441
2.81k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
6
          return FALSE;
443
444
2.80k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
2.80k
        break;
446
447
6.13k
      default:
448
6.13k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
6.13k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
6.13k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
6.13k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
6.13k
        return FALSE;
453
140k
    }
454
140k
  }
455
456
4.25k
  return TRUE;
457
16.5k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
104
5.51k
{
105
5.51k
  const BYTE* pbSrc = pbSrcBuffer;
106
5.51k
  BYTE* pbDest = pbDestBuffer;
107
5.51k
  PIXEL temp = 0;
108
5.51k
  PIXEL fgPel = WHITE_PIXEL;
109
5.51k
  BOOL fInsertFgPel = FALSE;
110
5.51k
  BOOL fFirstLine = TRUE;
111
5.51k
  BYTE bitmask = 0;
112
5.51k
  PIXEL pixelA = 0;
113
5.51k
  PIXEL pixelB = 0;
114
5.51k
  UINT32 runLength = 0;
115
5.51k
  UINT32 code = 0;
116
5.51k
  UINT32 advance = 0;
117
5.51k
  RLEEXTRA
118
119
5.51k
  if ((rowDelta == 0) || (rowDelta < width))
120
0
  {
121
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
122
0
             width);
123
0
    return FALSE;
124
0
  }
125
126
5.51k
  if (!pbSrcBuffer || !pbDestBuffer)
127
0
  {
128
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p",
129
0
             WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
130
0
             WINPR_CXX_COMPAT_CAST(const void*, pbDestBuffer));
131
0
    return FALSE;
132
0
  }
133
134
5.51k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
5.51k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
150k
  while (pbSrc < pbEnd)
138
148k
  {
139
    /* Watch out for the end of the first scanline. */
140
148k
    if (fFirstLine)
141
26.7k
    {
142
26.7k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
3.82k
      {
144
3.82k
        fFirstLine = FALSE;
145
3.82k
        fInsertFgPel = FALSE;
146
3.82k
      }
147
26.7k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
148k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
157
#endif
158
159
    /* Handle Background Run Orders. */
160
148k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
103k
    {
162
103k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
103k
      if (advance == 0)
164
168
        return FALSE;
165
103k
      pbSrc = pbSrc + advance;
166
167
103k
      if (fFirstLine)
168
11.5k
      {
169
11.5k
        if (fInsertFgPel)
170
7.80k
        {
171
7.80k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
7.80k
          DESTWRITEPIXEL(pbDest, fgPel);
175
7.80k
          runLength = runLength - 1;
176
7.80k
        }
177
178
11.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
25
          return FALSE;
180
181
11.5k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
11.5k
      }
183
91.6k
      else
184
91.6k
      {
185
91.6k
        if (fInsertFgPel)
186
83.6k
        {
187
83.6k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
83.6k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
20
            return FALSE;
191
192
83.5k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
83.5k
          runLength--;
194
83.5k
        }
195
196
91.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
263
          return FALSE;
198
199
91.3k
        UNROLL(runLength, {
200
91.3k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
91.3k
          DESTWRITEPIXEL(pbDest, temp);
202
91.3k
        });
203
91.3k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
102k
      fInsertFgPel = TRUE;
207
102k
      continue;
208
103k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
45.4k
    fInsertFgPel = FALSE;
213
214
45.4k
    switch (code)
215
45.4k
    {
216
      /* Handle Foreground Run Orders. */
217
8.96k
      case REGULAR_FG_RUN:
218
9.56k
      case MEGA_MEGA_FG_RUN:
219
14.3k
      case LITE_SET_FG_FG_RUN:
220
14.7k
      case MEGA_MEGA_SET_FG_RUN:
221
14.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
14.7k
        if (advance == 0)
223
25
          return FALSE;
224
14.7k
        pbSrc = pbSrc + advance;
225
226
14.7k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
5.16k
        {
228
5.16k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
73
            return FALSE;
230
5.09k
          SRCREADPIXEL(fgPel, pbSrc);
231
5.09k
        }
232
233
14.6k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
79
          return FALSE;
235
236
14.5k
        if (fFirstLine)
237
3.51k
        {
238
3.51k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
3.51k
        }
240
11.0k
        else
241
11.0k
        {
242
11.0k
          UNROLL(runLength, {
243
11.0k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
11.0k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
11.0k
          });
246
11.0k
        }
247
248
14.5k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
3.68k
      case LITE_DITHERED_RUN:
252
4.10k
      case MEGA_MEGA_DITHERED_RUN:
253
4.10k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
4.10k
        if (advance == 0)
255
15
          return FALSE;
256
4.08k
        pbSrc = pbSrc + advance;
257
4.08k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
123
          return FALSE;
259
3.96k
        SRCREADPIXEL(pixelA, pbSrc);
260
3.96k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
241
          return FALSE;
262
3.72k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
3.72k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
42
          return FALSE;
266
267
3.68k
        UNROLL(runLength, {
268
3.68k
          DESTWRITEPIXEL(pbDest, pixelA);
269
3.68k
          DESTWRITEPIXEL(pbDest, pixelB);
270
3.68k
        });
271
3.68k
        break;
272
273
      /* Handle Color Run Orders. */
274
9.96k
      case REGULAR_COLOR_RUN:
275
10.3k
      case MEGA_MEGA_COLOR_RUN:
276
10.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
10.3k
        if (advance == 0)
278
15
          return FALSE;
279
10.3k
        pbSrc = pbSrc + advance;
280
10.3k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
113
          return FALSE;
282
10.2k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
10.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
60
          return FALSE;
286
287
10.1k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
10.1k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
4.33k
      case REGULAR_FGBG_IMAGE:
292
5.04k
      case MEGA_MEGA_FGBG_IMAGE:
293
6.33k
      case LITE_SET_FG_FGBG_IMAGE:
294
6.71k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
6.71k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
6.71k
        if (advance == 0)
297
41
          return FALSE;
298
6.67k
        pbSrc = pbSrc + advance;
299
300
6.67k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
1.65k
        {
302
1.65k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
54
            return FALSE;
304
1.60k
          SRCREADPIXEL(fgPel, pbSrc);
305
1.60k
        }
306
307
6.62k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
236
          return FALSE;
309
6.38k
        if (fFirstLine)
310
1.85k
        {
311
20.7k
          while (runLength > 8)
312
18.9k
          {
313
18.9k
            bitmask = *pbSrc;
314
18.9k
            pbSrc = pbSrc + 1;
315
18.9k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
18.9k
            if (!pbDest)
318
16
              return FALSE;
319
320
18.9k
            runLength = runLength - 8;
321
18.9k
          }
322
1.85k
        }
323
4.53k
        else
324
4.53k
        {
325
28.4k
          while (runLength > 8)
326
23.9k
          {
327
23.9k
            bitmask = *pbSrc++;
328
329
23.9k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
23.9k
            if (!pbDest)
332
25
              return FALSE;
333
334
23.9k
            runLength = runLength - 8;
335
23.9k
          }
336
4.53k
        }
337
338
6.34k
        if (runLength > 0)
339
5.43k
        {
340
5.43k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
31
            return FALSE;
342
5.40k
          bitmask = *pbSrc++;
343
344
5.40k
          if (fFirstLine)
345
1.12k
          {
346
1.12k
            pbDest =
347
1.12k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1.12k
          }
349
4.27k
          else
350
4.27k
          {
351
4.27k
            pbDest =
352
4.27k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
4.27k
          }
354
355
5.40k
          if (!pbDest)
356
6
            return FALSE;
357
5.40k
        }
358
359
6.30k
        break;
360
361
      /* Handle Color Image Orders. */
362
6.30k
      case REGULAR_COLOR_IMAGE:
363
3.71k
      case MEGA_MEGA_COLOR_IMAGE:
364
3.71k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
3.71k
        if (advance == 0)
366
24
          return FALSE;
367
3.68k
        pbSrc = pbSrc + advance;
368
3.68k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
40
          return FALSE;
370
3.64k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
301
          return FALSE;
372
373
3.34k
        UNROLL(runLength, {
374
3.34k
          SRCREADPIXEL(temp, pbSrc);
375
3.34k
          DESTWRITEPIXEL(pbDest, temp);
376
3.34k
        });
377
3.34k
        break;
378
379
      /* Handle Special Order 1. */
380
707
      case SPECIAL_FGBG_1:
381
707
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
707
        pbSrc = pbSrc + 1;
384
385
707
        if (fFirstLine)
386
96
        {
387
96
          pbDest =
388
96
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
96
        }
390
611
        else
391
611
        {
392
611
          pbDest =
393
611
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
611
        }
395
396
707
        if (!pbDest)
397
1
          return FALSE;
398
399
706
        break;
400
401
      /* Handle Special Order 2. */
402
928
      case SPECIAL_FGBG_2:
403
928
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
928
        pbSrc = pbSrc + 1;
406
407
928
        if (fFirstLine)
408
108
        {
409
108
          pbDest =
410
108
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
108
        }
412
820
        else
413
820
        {
414
820
          pbDest =
415
820
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
820
        }
417
418
928
        if (!pbDest)
419
2
          return FALSE;
420
421
926
        break;
422
423
      /* Handle White Order. */
424
1.23k
      case SPECIAL_WHITE:
425
1.23k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
1.23k
        pbSrc = pbSrc + 1;
428
429
1.23k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
1
          return FALSE;
431
432
1.23k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
1.23k
        break;
434
435
      /* Handle Black Order. */
436
925
      case SPECIAL_BLACK:
437
925
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
925
        pbSrc = pbSrc + 1;
440
441
925
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
2
          return FALSE;
443
444
923
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
923
        break;
446
447
2.01k
      default:
448
2.01k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
2.01k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
2.01k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
2.01k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
2.01k
        return FALSE;
453
45.4k
    }
454
45.4k
  }
455
456
1.45k
  return TRUE;
457
5.51k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
104
11.0k
{
105
11.0k
  const BYTE* pbSrc = pbSrcBuffer;
106
11.0k
  BYTE* pbDest = pbDestBuffer;
107
11.0k
  PIXEL temp = 0;
108
11.0k
  PIXEL fgPel = WHITE_PIXEL;
109
11.0k
  BOOL fInsertFgPel = FALSE;
110
11.0k
  BOOL fFirstLine = TRUE;
111
11.0k
  BYTE bitmask = 0;
112
11.0k
  PIXEL pixelA = 0;
113
11.0k
  PIXEL pixelB = 0;
114
11.0k
  UINT32 runLength = 0;
115
11.0k
  UINT32 code = 0;
116
11.0k
  UINT32 advance = 0;
117
11.0k
  RLEEXTRA
118
119
11.0k
  if ((rowDelta == 0) || (rowDelta < width))
120
0
  {
121
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
122
0
             width);
123
0
    return FALSE;
124
0
  }
125
126
11.0k
  if (!pbSrcBuffer || !pbDestBuffer)
127
0
  {
128
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p",
129
0
             WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
130
0
             WINPR_CXX_COMPAT_CAST(const void*, pbDestBuffer));
131
0
    return FALSE;
132
0
  }
133
134
11.0k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
11.0k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
312k
  while (pbSrc < pbEnd)
138
309k
  {
139
    /* Watch out for the end of the first scanline. */
140
309k
    if (fFirstLine)
141
52.7k
    {
142
52.7k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
8.18k
      {
144
8.18k
        fFirstLine = FALSE;
145
8.18k
        fInsertFgPel = FALSE;
146
8.18k
      }
147
52.7k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
309k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
157
#endif
158
159
    /* Handle Background Run Orders. */
160
309k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
214k
    {
162
214k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
214k
      if (advance == 0)
164
482
        return FALSE;
165
213k
      pbSrc = pbSrc + advance;
166
167
213k
      if (fFirstLine)
168
22.5k
      {
169
22.5k
        if (fInsertFgPel)
170
15.6k
        {
171
15.6k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
15.6k
          DESTWRITEPIXEL(pbDest, fgPel);
175
15.6k
          runLength = runLength - 1;
176
15.6k
        }
177
178
22.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
46
          return FALSE;
180
181
22.4k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
22.4k
      }
183
191k
      else
184
191k
      {
185
191k
        if (fInsertFgPel)
186
172k
        {
187
172k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
172k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
30
            return FALSE;
191
192
172k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
172k
          runLength--;
194
172k
        }
195
196
191k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
602
          return FALSE;
198
199
190k
        UNROLL(runLength, {
200
190k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
190k
          DESTWRITEPIXEL(pbDest, temp);
202
190k
        });
203
190k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
212k
      fInsertFgPel = TRUE;
207
212k
      continue;
208
213k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
95.4k
    fInsertFgPel = FALSE;
213
214
95.4k
    switch (code)
215
95.4k
    {
216
      /* Handle Foreground Run Orders. */
217
19.2k
      case REGULAR_FG_RUN:
218
20.4k
      case MEGA_MEGA_FG_RUN:
219
30.7k
      case LITE_SET_FG_FG_RUN:
220
31.4k
      case MEGA_MEGA_SET_FG_RUN:
221
31.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
31.4k
        if (advance == 0)
223
58
          return FALSE;
224
31.3k
        pbSrc = pbSrc + advance;
225
226
31.3k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
10.9k
        {
228
10.9k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
138
            return FALSE;
230
10.8k
          SRCREADPIXEL(fgPel, pbSrc);
231
10.8k
        }
232
233
31.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
200
          return FALSE;
235
236
31.0k
        if (fFirstLine)
237
6.62k
        {
238
6.62k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
6.62k
        }
240
24.3k
        else
241
24.3k
        {
242
24.3k
          UNROLL(runLength, {
243
24.3k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
24.3k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
24.3k
          });
246
24.3k
        }
247
248
31.0k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
6.99k
      case LITE_DITHERED_RUN:
252
7.79k
      case MEGA_MEGA_DITHERED_RUN:
253
7.79k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
7.79k
        if (advance == 0)
255
30
          return FALSE;
256
7.76k
        pbSrc = pbSrc + advance;
257
7.76k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
158
          return FALSE;
259
7.60k
        SRCREADPIXEL(pixelA, pbSrc);
260
7.60k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
264
          return FALSE;
262
7.33k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
7.33k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
100
          return FALSE;
266
267
7.23k
        UNROLL(runLength, {
268
7.23k
          DESTWRITEPIXEL(pbDest, pixelA);
269
7.23k
          DESTWRITEPIXEL(pbDest, pixelB);
270
7.23k
        });
271
7.23k
        break;
272
273
      /* Handle Color Run Orders. */
274
20.6k
      case REGULAR_COLOR_RUN:
275
21.6k
      case MEGA_MEGA_COLOR_RUN:
276
21.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
21.6k
        if (advance == 0)
278
32
          return FALSE;
279
21.5k
        pbSrc = pbSrc + advance;
280
21.5k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
168
          return FALSE;
282
21.4k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
21.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
130
          return FALSE;
286
287
21.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
21.2k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
9.41k
      case REGULAR_FGBG_IMAGE:
292
10.8k
      case MEGA_MEGA_FGBG_IMAGE:
293
13.7k
      case LITE_SET_FG_FGBG_IMAGE:
294
14.3k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
14.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
14.3k
        if (advance == 0)
297
98
          return FALSE;
298
14.3k
        pbSrc = pbSrc + advance;
299
300
14.3k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
3.49k
        {
302
3.49k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
106
            return FALSE;
304
3.39k
          SRCREADPIXEL(fgPel, pbSrc);
305
3.39k
        }
306
307
14.1k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
538
          return FALSE;
309
13.6k
        if (fFirstLine)
310
3.34k
        {
311
39.7k
          while (runLength > 8)
312
36.3k
          {
313
36.3k
            bitmask = *pbSrc;
314
36.3k
            pbSrc = pbSrc + 1;
315
36.3k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
36.3k
            if (!pbDest)
318
34
              return FALSE;
319
320
36.3k
            runLength = runLength - 8;
321
36.3k
          }
322
3.34k
        }
323
10.3k
        else
324
10.3k
        {
325
72.5k
          while (runLength > 8)
326
62.2k
          {
327
62.2k
            bitmask = *pbSrc++;
328
329
62.2k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
62.2k
            if (!pbDest)
332
64
              return FALSE;
333
334
62.2k
            runLength = runLength - 8;
335
62.2k
          }
336
10.3k
        }
337
338
13.5k
        if (runLength > 0)
339
11.8k
        {
340
11.8k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
60
            return FALSE;
342
11.7k
          bitmask = *pbSrc++;
343
344
11.7k
          if (fFirstLine)
345
1.77k
          {
346
1.77k
            pbDest =
347
1.77k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1.77k
          }
349
9.96k
          else
350
9.96k
          {
351
9.96k
            pbDest =
352
9.96k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
9.96k
          }
354
355
11.7k
          if (!pbDest)
356
6
            return FALSE;
357
11.7k
        }
358
359
13.4k
        break;
360
361
      /* Handle Color Image Orders. */
362
13.4k
      case REGULAR_COLOR_IMAGE:
363
8.52k
      case MEGA_MEGA_COLOR_IMAGE:
364
8.52k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
8.52k
        if (advance == 0)
366
52
          return FALSE;
367
8.47k
        pbSrc = pbSrc + advance;
368
8.47k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
66
          return FALSE;
370
8.40k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
632
          return FALSE;
372
373
7.77k
        UNROLL(runLength, {
374
7.77k
          SRCREADPIXEL(temp, pbSrc);
375
7.77k
          DESTWRITEPIXEL(pbDest, temp);
376
7.77k
        });
377
7.77k
        break;
378
379
      /* Handle Special Order 1. */
380
1.44k
      case SPECIAL_FGBG_1:
381
1.44k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
1.44k
        pbSrc = pbSrc + 1;
384
385
1.44k
        if (fFirstLine)
386
202
        {
387
202
          pbDest =
388
202
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
202
        }
390
1.24k
        else
391
1.24k
        {
392
1.24k
          pbDest =
393
1.24k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
1.24k
        }
395
396
1.44k
        if (!pbDest)
397
4
          return FALSE;
398
399
1.43k
        break;
400
401
      /* Handle Special Order 2. */
402
1.85k
      case SPECIAL_FGBG_2:
403
1.85k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
1.85k
        pbSrc = pbSrc + 1;
406
407
1.85k
        if (fFirstLine)
408
196
        {
409
196
          pbDest =
410
196
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
196
        }
412
1.65k
        else
413
1.65k
        {
414
1.65k
          pbDest =
415
1.65k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
1.65k
        }
417
418
1.85k
        if (!pbDest)
419
4
          return FALSE;
420
421
1.84k
        break;
422
423
      /* Handle White Order. */
424
2.45k
      case SPECIAL_WHITE:
425
2.45k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
2.45k
        pbSrc = pbSrc + 1;
428
429
2.45k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
2
          return FALSE;
431
432
2.45k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
2.45k
        break;
434
435
      /* Handle Black Order. */
436
1.88k
      case SPECIAL_BLACK:
437
1.88k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
1.88k
        pbSrc = pbSrc + 1;
440
441
1.88k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
4
          return FALSE;
443
444
1.88k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
1.88k
        break;
446
447
4.11k
      default:
448
4.11k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
4.11k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
4.11k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
4.11k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
4.11k
        return FALSE;
453
95.4k
    }
454
95.4k
  }
455
456
2.80k
  return TRUE;
457
11.0k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8