Coverage Report

Created: 2026-08-31 06:26

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
95.3k
{
36
95.3k
  PIXEL xorPixel = 0;
37
95.3k
  BYTE mask = 0x01;
38
39
95.3k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
95.3k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
108
    return nullptr;
47
48
95.2k
  UNROLL(cBits, {
49
95.2k
    PIXEL data = 0;
50
95.2k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
95.2k
    if (bitmask & mask)
53
95.2k
      data = xorPixel ^ fgPel;
54
95.2k
    else
55
95.2k
      data = xorPixel;
56
57
95.2k
    DESTWRITEPIXEL(pbDest, data);
58
95.2k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
95.2k
  });
60
95.2k
  return pbDest;
61
95.3k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
35
26.3k
{
36
26.3k
  PIXEL xorPixel = 0;
37
26.3k
  BYTE mask = 0x01;
38
39
26.3k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
26.3k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
30
    return nullptr;
47
48
26.3k
  UNROLL(cBits, {
49
26.3k
    PIXEL data = 0;
50
26.3k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
26.3k
    if (bitmask & mask)
53
26.3k
      data = xorPixel ^ fgPel;
54
26.3k
    else
55
26.3k
      data = xorPixel;
56
57
26.3k
    DESTWRITEPIXEL(pbDest, data);
58
26.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
26.3k
  });
60
26.3k
  return pbDest;
61
26.3k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
35
68.9k
{
36
68.9k
  PIXEL xorPixel = 0;
37
68.9k
  BYTE mask = 0x01;
38
39
68.9k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
68.9k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
78
    return nullptr;
47
48
68.9k
  UNROLL(cBits, {
49
68.9k
    PIXEL data = 0;
50
68.9k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
68.9k
    if (bitmask & mask)
53
68.9k
      data = xorPixel ^ fgPel;
54
68.9k
    else
55
68.9k
      data = xorPixel;
56
57
68.9k
    DESTWRITEPIXEL(pbDest, data);
58
68.9k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
68.9k
  });
60
68.9k
  return pbDest;
61
68.9k
}
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
44.4k
{
72
44.4k
  BYTE mask = 0x01;
73
74
44.4k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
44.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
24
    return nullptr;
82
83
44.3k
  UNROLL(cBits, {
84
44.3k
    PIXEL data;
85
86
44.3k
    if (bitmask & mask)
87
44.3k
      data = fgPel;
88
44.3k
    else
89
44.3k
      data = BLACK_PIXEL;
90
91
44.3k
    DESTWRITEPIXEL(pbDest, data);
92
44.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
44.3k
  });
94
44.3k
  return pbDest;
95
44.4k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
71
16.8k
{
72
16.8k
  BYTE mask = 0x01;
73
74
16.8k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
16.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
10
    return nullptr;
82
83
16.8k
  UNROLL(cBits, {
84
16.8k
    PIXEL data;
85
86
16.8k
    if (bitmask & mask)
87
16.8k
      data = fgPel;
88
16.8k
    else
89
16.8k
      data = BLACK_PIXEL;
90
91
16.8k
    DESTWRITEPIXEL(pbDest, data);
92
16.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
16.8k
  });
94
16.8k
  return pbDest;
95
16.8k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
71
27.5k
{
72
27.5k
  BYTE mask = 0x01;
73
74
27.5k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
27.5k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
14
    return nullptr;
82
83
27.5k
  UNROLL(cBits, {
84
27.5k
    PIXEL data;
85
86
27.5k
    if (bitmask & mask)
87
27.5k
      data = fgPel;
88
27.5k
    else
89
27.5k
      data = BLACK_PIXEL;
90
91
27.5k
    DESTWRITEPIXEL(pbDest, data);
92
27.5k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
27.5k
  });
94
27.5k
  return pbDest;
95
27.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
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
468k
  while (pbSrc < pbEnd)
138
464k
  {
139
    /* Watch out for the end of the first scanline. */
140
464k
    if (fFirstLine)
141
77.9k
    {
142
77.9k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
12.3k
      {
144
12.3k
        fFirstLine = FALSE;
145
12.3k
        fInsertFgPel = FALSE;
146
12.3k
      }
147
77.9k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
464k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%ld", (const void*)pbSrc, rle_code_str(code),
157
             pbEnd - pbSrc);
158
#endif
159
160
    /* Handle Background Run Orders. */
161
464k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
320k
    {
163
320k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
320k
      if (advance == 0)
165
650
        return FALSE;
166
320k
      pbSrc = pbSrc + advance;
167
168
320k
      if (fFirstLine)
169
33.4k
      {
170
33.4k
        if (fInsertFgPel)
171
22.6k
        {
172
22.6k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
22.6k
          DESTWRITEPIXEL(pbDest, fgPel);
176
22.6k
          runLength = runLength - 1;
177
22.6k
        }
178
179
33.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
77
          return FALSE;
181
182
33.3k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
33.3k
      }
184
286k
      else
185
286k
      {
186
286k
        if (fInsertFgPel)
187
260k
        {
188
260k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
260k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
35
            return FALSE;
192
193
260k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
260k
          runLength--;
195
260k
        }
196
197
286k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
902
          return FALSE;
199
200
285k
        UNROLL(runLength, {
201
285k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
285k
          DESTWRITEPIXEL(pbDest, temp);
203
285k
        });
204
285k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
319k
      fInsertFgPel = TRUE;
208
319k
      continue;
209
320k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
143k
    fInsertFgPel = FALSE;
214
215
143k
    switch (code)
216
143k
    {
217
      /* Handle Foreground Run Orders. */
218
24.4k
      case REGULAR_FG_RUN:
219
25.9k
      case MEGA_MEGA_FG_RUN:
220
41.5k
      case LITE_SET_FG_FG_RUN:
221
42.3k
      case MEGA_MEGA_SET_FG_RUN:
222
42.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
42.3k
        if (advance == 0)
224
100
          return FALSE;
225
42.2k
        pbSrc = pbSrc + advance;
226
227
42.2k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
16.3k
        {
229
16.3k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
209
            return FALSE;
231
16.1k
          SRCREADPIXEL(fgPel, pbSrc);
232
16.1k
        }
233
234
42.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
240
          return FALSE;
236
237
41.8k
        if (fFirstLine)
238
9.75k
        {
239
9.75k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
9.75k
        }
241
32.0k
        else
242
32.0k
        {
243
32.0k
          UNROLL(runLength, {
244
32.0k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
32.0k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
32.0k
          });
247
32.0k
        }
248
249
41.8k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
12.0k
      case LITE_DITHERED_RUN:
253
13.1k
      case MEGA_MEGA_DITHERED_RUN:
254
13.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
13.1k
        if (advance == 0)
256
45
          return FALSE;
257
13.0k
        pbSrc = pbSrc + advance;
258
13.0k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
228
          return FALSE;
260
12.8k
        SRCREADPIXEL(pixelA, pbSrc);
261
12.8k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
525
          return FALSE;
263
12.3k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
12.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
171
          return FALSE;
267
268
12.1k
        UNROLL(runLength, {
269
12.1k
          DESTWRITEPIXEL(pbDest, pixelA);
270
12.1k
          DESTWRITEPIXEL(pbDest, pixelB);
271
12.1k
        });
272
12.1k
        break;
273
274
      /* Handle Color Run Orders. */
275
35.3k
      case REGULAR_COLOR_RUN:
276
36.4k
      case MEGA_MEGA_COLOR_RUN:
277
36.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
36.4k
        if (advance == 0)
279
43
          return FALSE;
280
36.4k
        pbSrc = pbSrc + advance;
281
36.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
360
          return FALSE;
283
36.0k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
36.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
247
          return FALSE;
287
288
35.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
35.8k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
12.2k
      case REGULAR_FGBG_IMAGE:
293
14.0k
      case MEGA_MEGA_FGBG_IMAGE:
294
18.0k
      case LITE_SET_FG_FGBG_IMAGE:
295
19.8k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
19.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
19.8k
        if (advance == 0)
298
120
          return FALSE;
299
19.7k
        pbSrc = pbSrc + advance;
300
301
19.7k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
5.75k
        {
303
5.75k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
216
            return FALSE;
305
5.54k
          SRCREADPIXEL(fgPel, pbSrc);
306
5.54k
        }
307
308
19.5k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
896
          return FALSE;
310
18.6k
        if (fFirstLine)
311
4.50k
        {
312
45.5k
          while (runLength > 8)
313
41.0k
          {
314
41.0k
            bitmask = *pbSrc;
315
41.0k
            pbSrc = pbSrc + 1;
316
41.0k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
41.0k
            if (!pbDest)
319
21
              return FALSE;
320
321
41.0k
            runLength = runLength - 8;
322
41.0k
          }
323
4.50k
        }
324
14.1k
        else
325
14.1k
        {
326
90.4k
          while (runLength > 8)
327
76.4k
          {
328
76.4k
            bitmask = *pbSrc++;
329
330
76.4k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
76.4k
            if (!pbDest)
333
82
              return FALSE;
334
335
76.3k
            runLength = runLength - 8;
336
76.3k
          }
337
14.1k
        }
338
339
18.5k
        if (runLength > 0)
340
15.4k
        {
341
15.4k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
78
            return FALSE;
343
15.3k
          bitmask = *pbSrc++;
344
345
15.3k
          if (fFirstLine)
346
2.67k
          {
347
2.67k
            pbDest =
348
2.67k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
2.67k
          }
350
12.7k
          else
351
12.7k
          {
352
12.7k
            pbDest =
353
12.7k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
354
12.7k
          }
355
356
15.3k
          if (!pbDest)
357
12
            return FALSE;
358
15.3k
        }
359
360
18.4k
        break;
361
362
      /* Handle Color Image Orders. */
363
18.4k
      case REGULAR_COLOR_IMAGE:
364
11.8k
      case MEGA_MEGA_COLOR_IMAGE:
365
11.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
11.8k
        if (advance == 0)
367
61
          return FALSE;
368
11.7k
        pbSrc = pbSrc + advance;
369
11.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
97
          return FALSE;
371
11.6k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
1.01k
          return FALSE;
373
374
10.6k
        UNROLL(runLength, {
375
10.6k
          SRCREADPIXEL(temp, pbSrc);
376
10.6k
          DESTWRITEPIXEL(pbDest, temp);
377
10.6k
        });
378
10.6k
        break;
379
380
      /* Handle Special Order 1. */
381
4.08k
      case SPECIAL_FGBG_1:
382
4.08k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
4.08k
        pbSrc = pbSrc + 1;
385
386
4.08k
        if (fFirstLine)
387
342
        {
388
342
          pbDest =
389
342
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
342
        }
391
3.74k
        else
392
3.74k
        {
393
3.74k
          pbDest =
394
3.74k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
3.74k
        }
396
397
4.08k
        if (!pbDest)
398
10
          return FALSE;
399
400
4.07k
        break;
401
402
      /* Handle Special Order 2. */
403
4.07k
      case SPECIAL_FGBG_2:
404
2.81k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
2.81k
        pbSrc = pbSrc + 1;
407
408
2.81k
        if (fFirstLine)
409
321
        {
410
321
          pbDest =
411
321
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
321
        }
413
2.49k
        else
414
2.49k
        {
415
2.49k
          pbDest =
416
2.49k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
2.49k
        }
418
419
2.81k
        if (!pbDest)
420
7
          return FALSE;
421
422
2.80k
        break;
423
424
      /* Handle White Order. */
425
3.36k
      case SPECIAL_WHITE:
426
3.36k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
3.36k
        pbSrc = pbSrc + 1;
429
430
3.36k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
3
          return FALSE;
432
433
3.35k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
3.35k
        break;
435
436
      /* Handle Black Order. */
437
2.86k
      case SPECIAL_BLACK:
438
2.86k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
2.86k
        pbSrc = pbSrc + 1;
441
442
2.86k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
4
          return FALSE;
444
445
2.86k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
2.86k
        break;
447
448
6.38k
      default:
449
6.38k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
6.38k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
6.38k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
6.38k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
6.38k
        return FALSE;
454
143k
    }
455
143k
  }
456
457
4.19k
  return TRUE;
458
17.0k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
104
5.67k
{
105
5.67k
  const BYTE* pbSrc = pbSrcBuffer;
106
5.67k
  BYTE* pbDest = pbDestBuffer;
107
5.67k
  PIXEL temp = 0;
108
5.67k
  PIXEL fgPel = WHITE_PIXEL;
109
5.67k
  BOOL fInsertFgPel = FALSE;
110
5.67k
  BOOL fFirstLine = TRUE;
111
5.67k
  BYTE bitmask = 0;
112
5.67k
  PIXEL pixelA = 0;
113
5.67k
  PIXEL pixelB = 0;
114
5.67k
  UINT32 runLength = 0;
115
5.67k
  UINT32 code = 0;
116
5.67k
  UINT32 advance = 0;
117
5.67k
  RLEEXTRA
118
119
5.67k
  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.67k
  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.67k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
5.67k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
150k
  while (pbSrc < pbEnd)
138
149k
  {
139
    /* Watch out for the end of the first scanline. */
140
149k
    if (fFirstLine)
141
26.2k
    {
142
26.2k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
3.91k
      {
144
3.91k
        fFirstLine = FALSE;
145
3.91k
        fInsertFgPel = FALSE;
146
3.91k
      }
147
26.2k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
149k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%ld", (const void*)pbSrc, rle_code_str(code),
157
             pbEnd - pbSrc);
158
#endif
159
160
    /* Handle Background Run Orders. */
161
149k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
104k
    {
163
104k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
104k
      if (advance == 0)
165
172
        return FALSE;
166
104k
      pbSrc = pbSrc + advance;
167
168
104k
      if (fFirstLine)
169
11.3k
      {
170
11.3k
        if (fInsertFgPel)
171
7.53k
        {
172
7.53k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
7.53k
          DESTWRITEPIXEL(pbDest, fgPel);
176
7.53k
          runLength = runLength - 1;
177
7.53k
        }
178
179
11.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
25
          return FALSE;
181
182
11.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
11.2k
      }
184
93.3k
      else
185
93.3k
      {
186
93.3k
        if (fInsertFgPel)
187
85.2k
        {
188
85.2k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
85.2k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
13
            return FALSE;
192
193
85.2k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
85.2k
          runLength--;
195
85.2k
        }
196
197
93.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
284
          return FALSE;
199
200
93.0k
        UNROLL(runLength, {
201
93.0k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
93.0k
          DESTWRITEPIXEL(pbDest, temp);
203
93.0k
        });
204
93.0k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
104k
      fInsertFgPel = TRUE;
208
104k
      continue;
209
104k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
44.3k
    fInsertFgPel = FALSE;
214
215
44.3k
    switch (code)
216
44.3k
    {
217
      /* Handle Foreground Run Orders. */
218
7.85k
      case REGULAR_FG_RUN:
219
8.32k
      case MEGA_MEGA_FG_RUN:
220
13.1k
      case LITE_SET_FG_FG_RUN:
221
13.4k
      case MEGA_MEGA_SET_FG_RUN:
222
13.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
13.4k
        if (advance == 0)
224
30
          return FALSE;
225
13.4k
        pbSrc = pbSrc + advance;
226
227
13.4k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
5.11k
        {
229
5.11k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
75
            return FALSE;
231
5.03k
          SRCREADPIXEL(fgPel, pbSrc);
232
5.03k
        }
233
234
13.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
72
          return FALSE;
236
237
13.2k
        if (fFirstLine)
238
3.36k
        {
239
3.36k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
3.36k
        }
241
9.90k
        else
242
9.90k
        {
243
9.90k
          UNROLL(runLength, {
244
9.90k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
9.90k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
9.90k
          });
247
9.90k
        }
248
249
13.2k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
3.96k
      case LITE_DITHERED_RUN:
253
4.29k
      case MEGA_MEGA_DITHERED_RUN:
254
4.29k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
4.29k
        if (advance == 0)
256
13
          return FALSE;
257
4.27k
        pbSrc = pbSrc + advance;
258
4.27k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
100
          return FALSE;
260
4.17k
        SRCREADPIXEL(pixelA, pbSrc);
261
4.17k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
251
          return FALSE;
263
3.92k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
3.92k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
53
          return FALSE;
267
268
3.87k
        UNROLL(runLength, {
269
3.87k
          DESTWRITEPIXEL(pbDest, pixelA);
270
3.87k
          DESTWRITEPIXEL(pbDest, pixelB);
271
3.87k
        });
272
3.87k
        break;
273
274
      /* Handle Color Run Orders. */
275
10.0k
      case REGULAR_COLOR_RUN:
276
10.4k
      case MEGA_MEGA_COLOR_RUN:
277
10.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
10.4k
        if (advance == 0)
279
11
          return FALSE;
280
10.4k
        pbSrc = pbSrc + advance;
281
10.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
134
          return FALSE;
283
10.2k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
10.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
91
          return FALSE;
287
288
10.1k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
10.1k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
3.76k
      case REGULAR_FGBG_IMAGE:
293
4.36k
      case MEGA_MEGA_FGBG_IMAGE:
294
5.67k
      case LITE_SET_FG_FGBG_IMAGE:
295
6.24k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
6.24k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
6.24k
        if (advance == 0)
298
40
          return FALSE;
299
6.20k
        pbSrc = pbSrc + advance;
300
301
6.20k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
1.86k
        {
303
1.86k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
82
            return FALSE;
305
1.77k
          SRCREADPIXEL(fgPel, pbSrc);
306
1.77k
        }
307
308
6.11k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
288
          return FALSE;
310
5.83k
        if (fFirstLine)
311
1.64k
        {
312
17.1k
          while (runLength > 8)
313
15.5k
          {
314
15.5k
            bitmask = *pbSrc;
315
15.5k
            pbSrc = pbSrc + 1;
316
15.5k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
15.5k
            if (!pbDest)
319
9
              return FALSE;
320
321
15.5k
            runLength = runLength - 8;
322
15.5k
          }
323
1.64k
        }
324
4.18k
        else
325
4.18k
        {
326
24.7k
          while (runLength > 8)
327
20.6k
          {
328
20.6k
            bitmask = *pbSrc++;
329
330
20.6k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
20.6k
            if (!pbDest)
333
20
              return FALSE;
334
335
20.5k
            runLength = runLength - 8;
336
20.5k
          }
337
4.18k
        }
338
339
5.80k
        if (runLength > 0)
340
4.83k
        {
341
4.83k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
24
            return FALSE;
343
4.81k
          bitmask = *pbSrc++;
344
345
4.81k
          if (fFirstLine)
346
1.06k
          {
347
1.06k
            pbDest =
348
1.06k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
1.06k
          }
350
3.74k
          else
351
3.74k
          {
352
3.74k
            pbDest =
353
3.74k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
354
3.74k
          }
355
356
4.81k
          if (!pbDest)
357
6
            return FALSE;
358
4.81k
        }
359
360
5.77k
        break;
361
362
      /* Handle Color Image Orders. */
363
5.77k
      case REGULAR_COLOR_IMAGE:
364
3.52k
      case MEGA_MEGA_COLOR_IMAGE:
365
3.52k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
3.52k
        if (advance == 0)
367
19
          return FALSE;
368
3.50k
        pbSrc = pbSrc + advance;
369
3.50k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
37
          return FALSE;
371
3.46k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
329
          return FALSE;
373
374
3.13k
        UNROLL(runLength, {
375
3.13k
          SRCREADPIXEL(temp, pbSrc);
376
3.13k
          DESTWRITEPIXEL(pbDest, temp);
377
3.13k
        });
378
3.13k
        break;
379
380
      /* Handle Special Order 1. */
381
1.30k
      case SPECIAL_FGBG_1:
382
1.30k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
1.30k
        pbSrc = pbSrc + 1;
385
386
1.30k
        if (fFirstLine)
387
102
        {
388
102
          pbDest =
389
102
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
102
        }
391
1.20k
        else
392
1.20k
        {
393
1.20k
          pbDest =
394
1.20k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
1.20k
        }
396
397
1.30k
        if (!pbDest)
398
2
          return FALSE;
399
400
1.30k
        break;
401
402
      /* Handle Special Order 2. */
403
1.30k
      case SPECIAL_FGBG_2:
404
931
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
931
        pbSrc = pbSrc + 1;
407
408
931
        if (fFirstLine)
409
107
        {
410
107
          pbDest =
411
107
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
107
        }
413
824
        else
414
824
        {
415
824
          pbDest =
416
824
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
824
        }
418
419
931
        if (!pbDest)
420
3
          return FALSE;
421
422
928
        break;
423
424
      /* Handle White Order. */
425
1.11k
      case SPECIAL_WHITE:
426
1.11k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
1.11k
        pbSrc = pbSrc + 1;
429
430
1.11k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
1
          return FALSE;
432
433
1.11k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
1.11k
        break;
435
436
      /* Handle Black Order. */
437
965
      case SPECIAL_BLACK:
438
965
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
965
        pbSrc = pbSrc + 1;
441
442
965
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
2
          return FALSE;
444
445
963
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
963
        break;
447
448
2.08k
      default:
449
2.08k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
2.08k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
2.08k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
2.08k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
2.08k
        return FALSE;
454
44.3k
    }
455
44.3k
  }
456
457
1.41k
  return TRUE;
458
5.67k
}
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
317k
  while (pbSrc < pbEnd)
138
315k
  {
139
    /* Watch out for the end of the first scanline. */
140
315k
    if (fFirstLine)
141
51.6k
    {
142
51.6k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
8.41k
      {
144
8.41k
        fFirstLine = FALSE;
145
8.41k
        fInsertFgPel = FALSE;
146
8.41k
      }
147
51.6k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
315k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%ld", (const void*)pbSrc, rle_code_str(code),
157
             pbEnd - pbSrc);
158
#endif
159
160
    /* Handle Background Run Orders. */
161
315k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
216k
    {
163
216k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
216k
      if (advance == 0)
165
478
        return FALSE;
166
215k
      pbSrc = pbSrc + advance;
167
168
215k
      if (fFirstLine)
169
22.1k
      {
170
22.1k
        if (fInsertFgPel)
171
15.1k
        {
172
15.1k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
15.1k
          DESTWRITEPIXEL(pbDest, fgPel);
176
15.1k
          runLength = runLength - 1;
177
15.1k
        }
178
179
22.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
52
          return FALSE;
181
182
22.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
22.0k
      }
184
193k
      else
185
193k
      {
186
193k
        if (fInsertFgPel)
187
174k
        {
188
174k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
174k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
22
            return FALSE;
192
193
174k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
174k
          runLength--;
195
174k
        }
196
197
193k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
618
          return FALSE;
199
200
192k
        UNROLL(runLength, {
201
192k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
192k
          DESTWRITEPIXEL(pbDest, temp);
203
192k
        });
204
192k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
214k
      fInsertFgPel = TRUE;
208
214k
      continue;
209
215k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
98.8k
    fInsertFgPel = FALSE;
214
215
98.8k
    switch (code)
216
98.8k
    {
217
      /* Handle Foreground Run Orders. */
218
16.6k
      case REGULAR_FG_RUN:
219
17.6k
      case MEGA_MEGA_FG_RUN:
220
28.3k
      case LITE_SET_FG_FG_RUN:
221
28.9k
      case MEGA_MEGA_SET_FG_RUN:
222
28.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
28.9k
        if (advance == 0)
224
70
          return FALSE;
225
28.8k
        pbSrc = pbSrc + advance;
226
227
28.8k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
11.2k
        {
229
11.2k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
134
            return FALSE;
231
11.1k
          SRCREADPIXEL(fgPel, pbSrc);
232
11.1k
        }
233
234
28.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
168
          return FALSE;
236
237
28.5k
        if (fFirstLine)
238
6.39k
        {
239
6.39k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
6.39k
        }
241
22.1k
        else
242
22.1k
        {
243
22.1k
          UNROLL(runLength, {
244
22.1k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
22.1k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
22.1k
          });
247
22.1k
        }
248
249
28.5k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
8.09k
      case LITE_DITHERED_RUN:
253
8.85k
      case MEGA_MEGA_DITHERED_RUN:
254
8.85k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
8.85k
        if (advance == 0)
256
32
          return FALSE;
257
8.82k
        pbSrc = pbSrc + advance;
258
8.82k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
128
          return FALSE;
260
8.69k
        SRCREADPIXEL(pixelA, pbSrc);
261
8.69k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
274
          return FALSE;
263
8.42k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
8.42k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
118
          return FALSE;
267
268
8.30k
        UNROLL(runLength, {
269
8.30k
          DESTWRITEPIXEL(pbDest, pixelA);
270
8.30k
          DESTWRITEPIXEL(pbDest, pixelB);
271
8.30k
        });
272
8.30k
        break;
273
274
      /* Handle Color Run Orders. */
275
25.3k
      case REGULAR_COLOR_RUN:
276
26.0k
      case MEGA_MEGA_COLOR_RUN:
277
26.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
26.0k
        if (advance == 0)
279
32
          return FALSE;
280
26.0k
        pbSrc = pbSrc + advance;
281
26.0k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
226
          return FALSE;
283
25.7k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
25.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
156
          return FALSE;
287
288
25.6k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
25.6k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
8.46k
      case REGULAR_FGBG_IMAGE:
293
9.69k
      case MEGA_MEGA_FGBG_IMAGE:
294
12.3k
      case LITE_SET_FG_FGBG_IMAGE:
295
13.6k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
13.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
13.6k
        if (advance == 0)
298
80
          return FALSE;
299
13.5k
        pbSrc = pbSrc + advance;
300
301
13.5k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
3.89k
        {
303
3.89k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
134
            return FALSE;
305
3.76k
          SRCREADPIXEL(fgPel, pbSrc);
306
3.76k
        }
307
308
13.4k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
608
          return FALSE;
310
12.8k
        if (fFirstLine)
311
2.85k
        {
312
28.3k
          while (runLength > 8)
313
25.5k
          {
314
25.5k
            bitmask = *pbSrc;
315
25.5k
            pbSrc = pbSrc + 1;
316
25.5k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
25.5k
            if (!pbDest)
319
12
              return FALSE;
320
321
25.5k
            runLength = runLength - 8;
322
25.5k
          }
323
2.85k
        }
324
9.95k
        else
325
9.95k
        {
326
65.7k
          while (runLength > 8)
327
55.8k
          {
328
55.8k
            bitmask = *pbSrc++;
329
330
55.8k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
55.8k
            if (!pbDest)
333
62
              return FALSE;
334
335
55.7k
            runLength = runLength - 8;
336
55.7k
          }
337
9.95k
        }
338
339
12.7k
        if (runLength > 0)
340
10.6k
        {
341
10.6k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
54
            return FALSE;
343
10.5k
          bitmask = *pbSrc++;
344
345
10.5k
          if (fFirstLine)
346
1.60k
          {
347
1.60k
            pbDest =
348
1.60k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
1.60k
          }
350
8.96k
          else
351
8.96k
          {
352
8.96k
            pbDest =
353
8.96k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
354
8.96k
          }
355
356
10.5k
          if (!pbDest)
357
6
            return FALSE;
358
10.5k
        }
359
360
12.6k
        break;
361
362
      /* Handle Color Image Orders. */
363
12.6k
      case REGULAR_COLOR_IMAGE:
364
8.32k
      case MEGA_MEGA_COLOR_IMAGE:
365
8.32k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
8.32k
        if (advance == 0)
367
42
          return FALSE;
368
8.28k
        pbSrc = pbSrc + advance;
369
8.28k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
60
          return FALSE;
371
8.22k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
688
          return FALSE;
373
374
7.53k
        UNROLL(runLength, {
375
7.53k
          SRCREADPIXEL(temp, pbSrc);
376
7.53k
          DESTWRITEPIXEL(pbDest, temp);
377
7.53k
        });
378
7.53k
        break;
379
380
      /* Handle Special Order 1. */
381
2.78k
      case SPECIAL_FGBG_1:
382
2.78k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
2.78k
        pbSrc = pbSrc + 1;
385
386
2.78k
        if (fFirstLine)
387
240
        {
388
240
          pbDest =
389
240
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
240
        }
391
2.54k
        else
392
2.54k
        {
393
2.54k
          pbDest =
394
2.54k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
2.54k
        }
396
397
2.78k
        if (!pbDest)
398
8
          return FALSE;
399
400
2.77k
        break;
401
402
      /* Handle Special Order 2. */
403
2.77k
      case SPECIAL_FGBG_2:
404
1.88k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
1.88k
        pbSrc = pbSrc + 1;
407
408
1.88k
        if (fFirstLine)
409
214
        {
410
214
          pbDest =
411
214
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
214
        }
413
1.66k
        else
414
1.66k
        {
415
1.66k
          pbDest =
416
1.66k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
1.66k
        }
418
419
1.88k
        if (!pbDest)
420
4
          return FALSE;
421
422
1.87k
        break;
423
424
      /* Handle White Order. */
425
2.25k
      case SPECIAL_WHITE:
426
2.25k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
2.25k
        pbSrc = pbSrc + 1;
429
430
2.25k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
2
          return FALSE;
432
433
2.24k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
2.24k
        break;
435
436
      /* Handle Black Order. */
437
1.90k
      case SPECIAL_BLACK:
438
1.90k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
1.90k
        pbSrc = pbSrc + 1;
441
442
1.90k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
2
          return FALSE;
444
445
1.90k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
1.90k
        break;
447
448
4.30k
      default:
449
4.30k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
4.30k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
4.30k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
4.30k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
4.30k
        return FALSE;
454
98.8k
    }
455
98.8k
  }
456
457
2.77k
  return TRUE;
458
11.3k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8