Coverage Report

Created: 2026-03-04 06:14

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
94.7k
{
36
94.7k
  PIXEL xorPixel = 0;
37
94.7k
  BYTE mask = 0x01;
38
39
94.7k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
94.7k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
85
    return nullptr;
47
48
94.6k
  UNROLL(cBits, {
49
94.6k
    PIXEL data = 0;
50
94.6k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
94.6k
    if (bitmask & mask)
53
94.6k
      data = xorPixel ^ fgPel;
54
94.6k
    else
55
94.6k
      data = xorPixel;
56
57
94.6k
    DESTWRITEPIXEL(pbDest, data);
58
94.6k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
94.6k
  });
60
94.6k
  return pbDest;
61
94.7k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
35
26.0k
{
36
26.0k
  PIXEL xorPixel = 0;
37
26.0k
  BYTE mask = 0x01;
38
39
26.0k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
26.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
25
    return nullptr;
47
48
26.0k
  UNROLL(cBits, {
49
26.0k
    PIXEL data = 0;
50
26.0k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
26.0k
    if (bitmask & mask)
53
26.0k
      data = xorPixel ^ fgPel;
54
26.0k
    else
55
26.0k
      data = xorPixel;
56
57
26.0k
    DESTWRITEPIXEL(pbDest, data);
58
26.0k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
26.0k
  });
60
26.0k
  return pbDest;
61
26.0k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
35
68.6k
{
36
68.6k
  PIXEL xorPixel = 0;
37
68.6k
  BYTE mask = 0x01;
38
39
68.6k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
68.6k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
60
    return nullptr;
47
48
68.5k
  UNROLL(cBits, {
49
68.5k
    PIXEL data = 0;
50
68.5k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
68.5k
    if (bitmask & mask)
53
68.5k
      data = xorPixel ^ fgPel;
54
68.5k
    else
55
68.5k
      data = xorPixel;
56
57
68.5k
    DESTWRITEPIXEL(pbDest, data);
58
68.5k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
68.5k
  });
60
68.5k
  return pbDest;
61
68.6k
}
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
57.4k
{
72
57.4k
  BYTE mask = 0x01;
73
74
57.4k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
57.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
55
    return nullptr;
82
83
57.4k
  UNROLL(cBits, {
84
57.4k
    PIXEL data;
85
86
57.4k
    if (bitmask & mask)
87
57.4k
      data = fgPel;
88
57.4k
    else
89
57.4k
      data = BLACK_PIXEL;
90
91
57.4k
    DESTWRITEPIXEL(pbDest, data);
92
57.4k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
57.4k
  });
94
57.4k
  return pbDest;
95
57.4k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
71
18.8k
{
72
18.8k
  BYTE mask = 0x01;
73
74
18.8k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
18.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
15
    return nullptr;
82
83
18.8k
  UNROLL(cBits, {
84
18.8k
    PIXEL data;
85
86
18.8k
    if (bitmask & mask)
87
18.8k
      data = fgPel;
88
18.8k
    else
89
18.8k
      data = BLACK_PIXEL;
90
91
18.8k
    DESTWRITEPIXEL(pbDest, data);
92
18.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
18.8k
  });
94
18.8k
  return pbDest;
95
18.8k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
71
38.6k
{
72
38.6k
  BYTE mask = 0x01;
73
74
38.6k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
38.6k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
40
    return nullptr;
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.6k
}
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
17.0k
{
105
17.0k
  const BYTE* pbSrc = pbSrcBuffer;
106
17.0k
  BYTE* pbDest = pbDestBuffer;
107
17.0k
  PIXEL temp = 0;
108
17.0k
  PIXEL fgPel = WHITE_PIXEL;
109
17.0k
  BOOL fInsertFgPel = FALSE;
110
17.0k
  BOOL fFirstLine = TRUE;
111
17.0k
  BYTE bitmask = 0;
112
17.0k
  PIXEL pixelA = 0;
113
17.0k
  PIXEL pixelB = 0;
114
17.0k
  UINT32 runLength = 0;
115
17.0k
  UINT32 code = 0;
116
17.0k
  UINT32 advance = 0;
117
17.0k
  RLEEXTRA
118
119
17.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
17.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
17.0k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
17.0k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
509k
  while (pbSrc < pbEnd)
138
504k
  {
139
    /* Watch out for the end of the first scanline. */
140
504k
    if (fFirstLine)
141
82.8k
    {
142
82.8k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
12.3k
      {
144
12.3k
        fFirstLine = FALSE;
145
12.3k
        fInsertFgPel = FALSE;
146
12.3k
      }
147
82.8k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
504k
    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
504k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
348k
    {
162
348k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
348k
      if (advance == 0)
164
611
        return FALSE;
165
347k
      pbSrc = pbSrc + advance;
166
167
347k
      if (fFirstLine)
168
36.0k
      {
169
36.0k
        if (fInsertFgPel)
170
24.9k
        {
171
24.9k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
24.9k
          DESTWRITEPIXEL(pbDest, fgPel);
175
24.9k
          runLength = runLength - 1;
176
24.9k
        }
177
178
36.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
86
          return FALSE;
180
181
35.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
35.9k
      }
183
311k
      else
184
311k
      {
185
311k
        if (fInsertFgPel)
186
283k
        {
187
283k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
283k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
41
            return FALSE;
191
192
283k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
283k
          runLength--;
194
283k
        }
195
196
311k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
975
          return FALSE;
198
199
310k
        UNROLL(runLength, {
200
310k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
310k
          DESTWRITEPIXEL(pbDest, temp);
202
310k
        });
203
310k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
346k
      fInsertFgPel = TRUE;
207
346k
      continue;
208
347k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
156k
    fInsertFgPel = FALSE;
213
214
156k
    switch (code)
215
156k
    {
216
      /* Handle Foreground Run Orders. */
217
27.8k
      case REGULAR_FG_RUN:
218
29.7k
      case MEGA_MEGA_FG_RUN:
219
45.9k
      case LITE_SET_FG_FG_RUN:
220
46.9k
      case MEGA_MEGA_SET_FG_RUN:
221
46.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
46.9k
        if (advance == 0)
223
98
          return FALSE;
224
46.8k
        pbSrc = pbSrc + advance;
225
226
46.8k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
17.1k
        {
228
17.1k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
217
            return FALSE;
230
16.9k
          SRCREADPIXEL(fgPel, pbSrc);
231
16.9k
        }
232
233
46.6k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
322
          return FALSE;
235
236
46.3k
        if (fFirstLine)
237
10.6k
        {
238
10.6k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
10.6k
        }
240
35.6k
        else
241
35.6k
        {
242
35.6k
          UNROLL(runLength, {
243
35.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
35.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
35.6k
          });
246
35.6k
        }
247
248
46.3k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
11.8k
      case LITE_DITHERED_RUN:
252
13.1k
      case MEGA_MEGA_DITHERED_RUN:
253
13.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
13.1k
        if (advance == 0)
255
59
          return FALSE;
256
13.0k
        pbSrc = pbSrc + advance;
257
13.0k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
300
          return FALSE;
259
12.7k
        SRCREADPIXEL(pixelA, pbSrc);
260
12.7k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
520
          return FALSE;
262
12.2k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
12.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
157
          return FALSE;
266
267
12.0k
        UNROLL(runLength, {
268
12.0k
          DESTWRITEPIXEL(pbDest, pixelA);
269
12.0k
          DESTWRITEPIXEL(pbDest, pixelB);
270
12.0k
        });
271
12.0k
        break;
272
273
      /* Handle Color Run Orders. */
274
31.8k
      case REGULAR_COLOR_RUN:
275
33.1k
      case MEGA_MEGA_COLOR_RUN:
276
33.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
33.1k
        if (advance == 0)
278
45
          return FALSE;
279
33.1k
        pbSrc = pbSrc + advance;
280
33.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
299
          return FALSE;
282
32.8k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
32.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
193
          return FALSE;
286
287
32.6k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
32.6k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
14.1k
      case REGULAR_FGBG_IMAGE:
292
16.3k
      case MEGA_MEGA_FGBG_IMAGE:
293
20.2k
      case LITE_SET_FG_FGBG_IMAGE:
294
21.0k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
21.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
21.0k
        if (advance == 0)
297
127
          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
4.64k
        {
302
4.64k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
177
            return FALSE;
304
4.47k
          SRCREADPIXEL(fgPel, pbSrc);
305
4.47k
        }
306
307
20.7k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
901
          return FALSE;
309
19.8k
        if (fFirstLine)
310
5.19k
        {
311
59.0k
          while (runLength > 8)
312
53.8k
          {
313
53.8k
            bitmask = *pbSrc;
314
53.8k
            pbSrc = pbSrc + 1;
315
53.8k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
53.8k
            if (!pbDest)
318
52
              return FALSE;
319
320
53.8k
            runLength = runLength - 8;
321
53.8k
          }
322
5.19k
        }
323
14.6k
        else
324
14.6k
        {
325
90.4k
          while (runLength > 8)
326
75.9k
          {
327
75.9k
            bitmask = *pbSrc++;
328
329
75.9k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
75.9k
            if (!pbDest)
332
67
              return FALSE;
333
334
75.8k
            runLength = runLength - 8;
335
75.8k
          }
336
14.6k
        }
337
338
19.7k
        if (runLength > 0)
339
17.2k
        {
340
17.2k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
94
            return FALSE;
342
17.1k
          bitmask = *pbSrc++;
343
344
17.1k
          if (fFirstLine)
345
2.98k
          {
346
2.98k
            pbDest =
347
2.98k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
2.98k
          }
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
11
            return FALSE;
357
17.1k
        }
358
359
19.6k
        break;
360
361
      /* Handle Color Image Orders. */
362
21.4k
      case REGULAR_COLOR_IMAGE:
363
23.7k
      case MEGA_MEGA_COLOR_IMAGE:
364
23.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
23.7k
        if (advance == 0)
366
81
          return FALSE;
367
23.7k
        pbSrc = pbSrc + advance;
368
23.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
86
          return FALSE;
370
23.6k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
967
          return FALSE;
372
373
22.6k
        UNROLL(runLength, {
374
22.6k
          SRCREADPIXEL(temp, pbSrc);
375
22.6k
          DESTWRITEPIXEL(pbDest, temp);
376
22.6k
        });
377
22.6k
        break;
378
379
      /* Handle Special Order 1. */
380
2.59k
      case SPECIAL_FGBG_1:
381
2.59k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
2.59k
        pbSrc = pbSrc + 1;
384
385
2.59k
        if (fFirstLine)
386
257
        {
387
257
          pbDest =
388
257
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
257
        }
390
2.33k
        else
391
2.33k
        {
392
2.33k
          pbDest =
393
2.33k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
2.33k
        }
395
396
2.59k
        if (!pbDest)
397
5
          return FALSE;
398
399
2.58k
        break;
400
401
      /* Handle Special Order 2. */
402
2.59k
      case SPECIAL_FGBG_2:
403
2.59k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
2.59k
        pbSrc = pbSrc + 1;
406
407
2.59k
        if (fFirstLine)
408
349
        {
409
349
          pbDest =
410
349
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
349
        }
412
2.24k
        else
413
2.24k
        {
414
2.24k
          pbDest =
415
2.24k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
2.24k
        }
417
418
2.59k
        if (!pbDest)
419
5
          return FALSE;
420
421
2.59k
        break;
422
423
      /* Handle White Order. */
424
4.19k
      case SPECIAL_WHITE:
425
4.19k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
4.19k
        pbSrc = pbSrc + 1;
428
429
4.19k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
4
          return FALSE;
431
432
4.19k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
4.19k
        break;
434
435
      /* Handle Black Order. */
436
2.79k
      case SPECIAL_BLACK:
437
2.79k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
2.79k
        pbSrc = pbSrc + 1;
440
441
2.79k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
3
          return FALSE;
443
444
2.79k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
2.79k
        break;
446
447
6.18k
      default:
448
6.18k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
6.18k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
6.18k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
6.18k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
6.18k
        return FALSE;
453
156k
    }
454
156k
  }
455
456
4.39k
  return TRUE;
457
17.0k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
104
5.69k
{
105
5.69k
  const BYTE* pbSrc = pbSrcBuffer;
106
5.69k
  BYTE* pbDest = pbDestBuffer;
107
5.69k
  PIXEL temp = 0;
108
5.69k
  PIXEL fgPel = WHITE_PIXEL;
109
5.69k
  BOOL fInsertFgPel = FALSE;
110
5.69k
  BOOL fFirstLine = TRUE;
111
5.69k
  BYTE bitmask = 0;
112
5.69k
  PIXEL pixelA = 0;
113
5.69k
  PIXEL pixelB = 0;
114
5.69k
  UINT32 runLength = 0;
115
5.69k
  UINT32 code = 0;
116
5.69k
  UINT32 advance = 0;
117
5.69k
  RLEEXTRA
118
119
5.69k
  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.69k
  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.69k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
5.69k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
164k
  while (pbSrc < pbEnd)
138
163k
  {
139
    /* Watch out for the end of the first scanline. */
140
163k
    if (fFirstLine)
141
27.8k
    {
142
27.8k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
3.94k
      {
144
3.94k
        fFirstLine = FALSE;
145
3.94k
        fInsertFgPel = FALSE;
146
3.94k
      }
147
27.8k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
163k
    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
163k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
113k
    {
162
113k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
113k
      if (advance == 0)
164
155
        return FALSE;
165
112k
      pbSrc = pbSrc + advance;
166
167
112k
      if (fFirstLine)
168
12.1k
      {
169
12.1k
        if (fInsertFgPel)
170
8.27k
        {
171
8.27k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
8.27k
          DESTWRITEPIXEL(pbDest, fgPel);
175
8.27k
          runLength = runLength - 1;
176
8.27k
        }
177
178
12.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
30
          return FALSE;
180
181
12.1k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
12.1k
      }
183
100k
      else
184
100k
      {
185
100k
        if (fInsertFgPel)
186
92.4k
        {
187
92.4k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
92.4k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
17
            return FALSE;
191
192
92.3k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
92.3k
          runLength--;
194
92.3k
        }
195
196
100k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
305
          return FALSE;
198
199
100k
        UNROLL(runLength, {
200
100k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
100k
          DESTWRITEPIXEL(pbDest, temp);
202
100k
        });
203
100k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
112k
      fInsertFgPel = TRUE;
207
112k
      continue;
208
112k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
49.9k
    fInsertFgPel = FALSE;
213
214
49.9k
    switch (code)
215
49.9k
    {
216
      /* Handle Foreground Run Orders. */
217
8.70k
      case REGULAR_FG_RUN:
218
9.32k
      case MEGA_MEGA_FG_RUN:
219
14.5k
      case LITE_SET_FG_FG_RUN:
220
14.9k
      case MEGA_MEGA_SET_FG_RUN:
221
14.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
14.9k
        if (advance == 0)
223
30
          return FALSE;
224
14.9k
        pbSrc = pbSrc + advance;
225
226
14.9k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
5.59k
        {
228
5.59k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
85
            return FALSE;
230
5.51k
          SRCREADPIXEL(fgPel, pbSrc);
231
5.51k
        }
232
233
14.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
92
          return FALSE;
235
236
14.7k
        if (fFirstLine)
237
3.64k
        {
238
3.64k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
3.64k
        }
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.7k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
3.92k
      case LITE_DITHERED_RUN:
252
4.37k
      case MEGA_MEGA_DITHERED_RUN:
253
4.37k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
4.37k
        if (advance == 0)
255
17
          return FALSE;
256
4.35k
        pbSrc = pbSrc + advance;
257
4.35k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
132
          return FALSE;
259
4.22k
        SRCREADPIXEL(pixelA, pbSrc);
260
4.22k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
246
          return FALSE;
262
3.97k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
3.97k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
47
          return FALSE;
266
267
3.92k
        UNROLL(runLength, {
268
3.92k
          DESTWRITEPIXEL(pbDest, pixelA);
269
3.92k
          DESTWRITEPIXEL(pbDest, pixelB);
270
3.92k
        });
271
3.92k
        break;
272
273
      /* Handle Color Run Orders. */
274
10.5k
      case REGULAR_COLOR_RUN:
275
11.0k
      case MEGA_MEGA_COLOR_RUN:
276
11.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
11.0k
        if (advance == 0)
278
13
          return FALSE;
279
11.0k
        pbSrc = pbSrc + advance;
280
11.0k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
113
          return FALSE;
282
10.8k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
10.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
73
          return FALSE;
286
287
10.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
10.8k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
4.47k
      case REGULAR_FGBG_IMAGE:
292
5.18k
      case MEGA_MEGA_FGBG_IMAGE:
293
6.44k
      case LITE_SET_FG_FGBG_IMAGE:
294
6.69k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
6.69k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
6.69k
        if (advance == 0)
297
37
          return FALSE;
298
6.65k
        pbSrc = pbSrc + advance;
299
300
6.65k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
1.48k
        {
302
1.48k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
57
            return FALSE;
304
1.43k
          SRCREADPIXEL(fgPel, pbSrc);
305
1.43k
        }
306
307
6.60k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
279
          return FALSE;
309
6.32k
        if (fFirstLine)
310
1.87k
        {
311
19.3k
          while (runLength > 8)
312
17.5k
          {
313
17.5k
            bitmask = *pbSrc;
314
17.5k
            pbSrc = pbSrc + 1;
315
17.5k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
17.5k
            if (!pbDest)
318
14
              return FALSE;
319
320
17.4k
            runLength = runLength - 8;
321
17.4k
          }
322
1.87k
        }
323
4.44k
        else
324
4.44k
        {
325
24.6k
          while (runLength > 8)
326
20.2k
          {
327
20.2k
            bitmask = *pbSrc++;
328
329
20.2k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
20.2k
            if (!pbDest)
332
17
              return FALSE;
333
334
20.2k
            runLength = runLength - 8;
335
20.2k
          }
336
4.44k
        }
337
338
6.29k
        if (runLength > 0)
339
5.51k
        {
340
5.51k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
34
            return FALSE;
342
5.47k
          bitmask = *pbSrc++;
343
344
5.47k
          if (fFirstLine)
345
1.16k
          {
346
1.16k
            pbDest =
347
1.16k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1.16k
          }
349
4.31k
          else
350
4.31k
          {
351
4.31k
            pbDest =
352
4.31k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
4.31k
          }
354
355
5.47k
          if (!pbDest)
356
7
            return FALSE;
357
5.47k
        }
358
359
6.25k
        break;
360
361
      /* Handle Color Image Orders. */
362
6.25k
      case REGULAR_COLOR_IMAGE:
363
6.86k
      case MEGA_MEGA_COLOR_IMAGE:
364
6.86k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
6.86k
        if (advance == 0)
366
27
          return FALSE;
367
6.83k
        pbSrc = pbSrc + advance;
368
6.83k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
32
          return FALSE;
370
6.80k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
315
          return FALSE;
372
373
6.48k
        UNROLL(runLength, {
374
6.48k
          SRCREADPIXEL(temp, pbSrc);
375
6.48k
          DESTWRITEPIXEL(pbDest, temp);
376
6.48k
        });
377
6.48k
        break;
378
379
      /* Handle Special Order 1. */
380
849
      case SPECIAL_FGBG_1:
381
849
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
849
        pbSrc = pbSrc + 1;
384
385
849
        if (fFirstLine)
386
81
        {
387
81
          pbDest =
388
81
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
81
        }
390
768
        else
391
768
        {
392
768
          pbDest =
393
768
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
768
        }
395
396
849
        if (!pbDest)
397
1
          return FALSE;
398
399
848
        break;
400
401
      /* Handle Special Order 2. */
402
869
      case SPECIAL_FGBG_2:
403
869
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
869
        pbSrc = pbSrc + 1;
406
407
869
        if (fFirstLine)
408
121
        {
409
121
          pbDest =
410
121
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
121
        }
412
748
        else
413
748
        {
414
748
          pbDest =
415
748
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
748
        }
417
418
869
        if (!pbDest)
419
1
          return FALSE;
420
421
868
        break;
422
423
      /* Handle White Order. */
424
1.39k
      case SPECIAL_WHITE:
425
1.39k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
1.39k
        pbSrc = pbSrc + 1;
428
429
1.39k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
2
          return FALSE;
431
432
1.39k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
1.39k
        break;
434
435
      /* Handle Black Order. */
436
928
      case SPECIAL_BLACK:
437
928
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
928
        pbSrc = pbSrc + 1;
440
441
928
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
1
          return FALSE;
443
444
927
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
927
        break;
446
447
2.04k
      default:
448
2.04k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
2.04k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
2.04k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
2.04k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
2.04k
        return FALSE;
453
49.9k
    }
454
49.9k
  }
455
456
1.47k
  return TRUE;
457
5.69k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
104
11.3k
{
105
11.3k
  const BYTE* pbSrc = pbSrcBuffer;
106
11.3k
  BYTE* pbDest = pbDestBuffer;
107
11.3k
  PIXEL temp = 0;
108
11.3k
  PIXEL fgPel = WHITE_PIXEL;
109
11.3k
  BOOL fInsertFgPel = FALSE;
110
11.3k
  BOOL fFirstLine = TRUE;
111
11.3k
  BYTE bitmask = 0;
112
11.3k
  PIXEL pixelA = 0;
113
11.3k
  PIXEL pixelB = 0;
114
11.3k
  UINT32 runLength = 0;
115
11.3k
  UINT32 code = 0;
116
11.3k
  UINT32 advance = 0;
117
11.3k
  RLEEXTRA
118
119
11.3k
  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.3k
  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.3k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
11.3k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
344k
  while (pbSrc < pbEnd)
138
341k
  {
139
    /* Watch out for the end of the first scanline. */
140
341k
    if (fFirstLine)
141
54.9k
    {
142
54.9k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
8.45k
      {
144
8.45k
        fFirstLine = FALSE;
145
8.45k
        fInsertFgPel = FALSE;
146
8.45k
      }
147
54.9k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
341k
    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
341k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
235k
    {
162
235k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
235k
      if (advance == 0)
164
456
        return FALSE;
165
234k
      pbSrc = pbSrc + advance;
166
167
234k
      if (fFirstLine)
168
23.8k
      {
169
23.8k
        if (fInsertFgPel)
170
16.7k
        {
171
16.7k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
16.7k
          DESTWRITEPIXEL(pbDest, fgPel);
175
16.7k
          runLength = runLength - 1;
176
16.7k
        }
177
178
23.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
56
          return FALSE;
180
181
23.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
23.8k
      }
183
210k
      else
184
210k
      {
185
210k
        if (fInsertFgPel)
186
191k
        {
187
191k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
191k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
24
            return FALSE;
191
192
191k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
191k
          runLength--;
194
191k
        }
195
196
210k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
670
          return FALSE;
198
199
210k
        UNROLL(runLength, {
200
210k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
210k
          DESTWRITEPIXEL(pbDest, temp);
202
210k
        });
203
210k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
233k
      fInsertFgPel = TRUE;
207
233k
      continue;
208
234k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
106k
    fInsertFgPel = FALSE;
213
214
106k
    switch (code)
215
106k
    {
216
      /* Handle Foreground Run Orders. */
217
19.1k
      case REGULAR_FG_RUN:
218
20.3k
      case MEGA_MEGA_FG_RUN:
219
31.3k
      case LITE_SET_FG_FG_RUN:
220
32.0k
      case MEGA_MEGA_SET_FG_RUN:
221
32.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
32.0k
        if (advance == 0)
223
68
          return FALSE;
224
31.9k
        pbSrc = pbSrc + advance;
225
226
31.9k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
11.6k
        {
228
11.6k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
132
            return FALSE;
230
11.4k
          SRCREADPIXEL(fgPel, pbSrc);
231
11.4k
        }
232
233
31.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
230
          return FALSE;
235
236
31.5k
        if (fFirstLine)
237
6.99k
        {
238
6.99k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
6.99k
        }
240
24.6k
        else
241
24.6k
        {
242
24.6k
          UNROLL(runLength, {
243
24.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
24.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
24.6k
          });
246
24.6k
        }
247
248
31.5k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
7.88k
      case LITE_DITHERED_RUN:
252
8.75k
      case MEGA_MEGA_DITHERED_RUN:
253
8.75k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
8.75k
        if (advance == 0)
255
42
          return FALSE;
256
8.71k
        pbSrc = pbSrc + advance;
257
8.71k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
168
          return FALSE;
259
8.54k
        SRCREADPIXEL(pixelA, pbSrc);
260
8.54k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
274
          return FALSE;
262
8.27k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
8.27k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
110
          return FALSE;
266
267
8.16k
        UNROLL(runLength, {
268
8.16k
          DESTWRITEPIXEL(pbDest, pixelA);
269
8.16k
          DESTWRITEPIXEL(pbDest, pixelB);
270
8.16k
        });
271
8.16k
        break;
272
273
      /* Handle Color Run Orders. */
274
21.2k
      case REGULAR_COLOR_RUN:
275
22.1k
      case MEGA_MEGA_COLOR_RUN:
276
22.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
22.1k
        if (advance == 0)
278
32
          return FALSE;
279
22.1k
        pbSrc = pbSrc + advance;
280
22.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
186
          return FALSE;
282
21.9k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
21.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
120
          return FALSE;
286
287
21.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
21.8k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
9.69k
      case REGULAR_FGBG_IMAGE:
292
11.1k
      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
90
          return FALSE;
298
14.2k
        pbSrc = pbSrc + advance;
299
300
14.2k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
3.15k
        {
302
3.15k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
120
            return FALSE;
304
3.03k
          SRCREADPIXEL(fgPel, pbSrc);
305
3.03k
        }
306
307
14.1k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
622
          return FALSE;
309
13.5k
        if (fFirstLine)
310
3.32k
        {
311
39.6k
          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
38
              return FALSE;
319
320
36.3k
            runLength = runLength - 8;
321
36.3k
          }
322
3.32k
        }
323
10.2k
        else
324
10.2k
        {
325
65.7k
          while (runLength > 8)
326
55.6k
          {
327
55.6k
            bitmask = *pbSrc++;
328
329
55.6k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
55.6k
            if (!pbDest)
332
50
              return FALSE;
333
334
55.5k
            runLength = runLength - 8;
335
55.5k
          }
336
10.2k
        }
337
338
13.4k
        if (runLength > 0)
339
11.7k
        {
340
11.7k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
60
            return FALSE;
342
11.7k
          bitmask = *pbSrc++;
343
344
11.7k
          if (fFirstLine)
345
1.81k
          {
346
1.81k
            pbDest =
347
1.81k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1.81k
          }
349
9.90k
          else
350
9.90k
          {
351
9.90k
            pbDest =
352
9.90k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
9.90k
          }
354
355
11.7k
          if (!pbDest)
356
4
            return FALSE;
357
11.7k
        }
358
359
13.3k
        break;
360
361
      /* Handle Color Image Orders. */
362
15.3k
      case REGULAR_COLOR_IMAGE:
363
16.9k
      case MEGA_MEGA_COLOR_IMAGE:
364
16.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
16.9k
        if (advance == 0)
366
54
          return FALSE;
367
16.8k
        pbSrc = pbSrc + advance;
368
16.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
54
          return FALSE;
370
16.8k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
652
          return FALSE;
372
373
16.1k
        UNROLL(runLength, {
374
16.1k
          SRCREADPIXEL(temp, pbSrc);
375
16.1k
          DESTWRITEPIXEL(pbDest, temp);
376
16.1k
        });
377
16.1k
        break;
378
379
      /* Handle Special Order 1. */
380
1.74k
      case SPECIAL_FGBG_1:
381
1.74k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
1.74k
        pbSrc = pbSrc + 1;
384
385
1.74k
        if (fFirstLine)
386
176
        {
387
176
          pbDest =
388
176
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
176
        }
390
1.56k
        else
391
1.56k
        {
392
1.56k
          pbDest =
393
1.56k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
1.56k
        }
395
396
1.74k
        if (!pbDest)
397
4
          return FALSE;
398
399
1.74k
        break;
400
401
      /* Handle Special Order 2. */
402
1.74k
      case SPECIAL_FGBG_2:
403
1.72k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
1.72k
        pbSrc = pbSrc + 1;
406
407
1.72k
        if (fFirstLine)
408
228
        {
409
228
          pbDest =
410
228
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
228
        }
412
1.50k
        else
413
1.50k
        {
414
1.50k
          pbDest =
415
1.50k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
1.50k
        }
417
418
1.72k
        if (!pbDest)
419
4
          return FALSE;
420
421
1.72k
        break;
422
423
      /* Handle White Order. */
424
2.79k
      case SPECIAL_WHITE:
425
2.79k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
2.79k
        pbSrc = pbSrc + 1;
428
429
2.79k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
2
          return FALSE;
431
432
2.79k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
2.79k
        break;
434
435
      /* Handle Black Order. */
436
1.87k
      case SPECIAL_BLACK:
437
1.87k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
1.87k
        pbSrc = pbSrc + 1;
440
441
1.87k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
2
          return FALSE;
443
444
1.86k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
1.86k
        break;
446
447
4.14k
      default:
448
4.14k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
4.14k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
4.14k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
4.14k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
4.14k
        return FALSE;
453
106k
    }
454
106k
  }
455
456
2.92k
  return TRUE;
457
11.3k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8