Coverage Report

Created: 2026-10-15 06:27

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
106k
{
36
106k
  PIXEL xorPixel = 0;
37
106k
  BYTE mask = 0x01;
38
39
106k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
106k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
115
    return nullptr;
47
48
106k
  UNROLL(cBits, {
49
106k
    PIXEL data = 0;
50
106k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
106k
    if (bitmask & mask)
53
106k
      data = xorPixel ^ fgPel;
54
106k
    else
55
106k
      data = xorPixel;
56
57
106k
    DESTWRITEPIXEL(pbDest, data);
58
106k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
106k
  });
60
106k
  return pbDest;
61
106k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
35
28.8k
{
36
28.8k
  PIXEL xorPixel = 0;
37
28.8k
  BYTE mask = 0x01;
38
39
28.8k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
28.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
31
    return nullptr;
47
48
28.8k
  UNROLL(cBits, {
49
28.8k
    PIXEL data = 0;
50
28.8k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
28.8k
    if (bitmask & mask)
53
28.8k
      data = xorPixel ^ fgPel;
54
28.8k
    else
55
28.8k
      data = xorPixel;
56
57
28.8k
    DESTWRITEPIXEL(pbDest, data);
58
28.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
28.8k
  });
60
28.8k
  return pbDest;
61
28.8k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
35
77.9k
{
36
77.9k
  PIXEL xorPixel = 0;
37
77.9k
  BYTE mask = 0x01;
38
39
77.9k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
77.9k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
84
    return nullptr;
47
48
77.8k
  UNROLL(cBits, {
49
77.8k
    PIXEL data = 0;
50
77.8k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
77.8k
    if (bitmask & mask)
53
77.8k
      data = xorPixel ^ fgPel;
54
77.8k
    else
55
77.8k
      data = xorPixel;
56
57
77.8k
    DESTWRITEPIXEL(pbDest, data);
58
77.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
77.8k
  });
60
77.8k
  return pbDest;
61
77.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
50.0k
{
72
50.0k
  BYTE mask = 0x01;
73
74
50.0k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
50.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
44
    return nullptr;
82
83
49.9k
  UNROLL(cBits, {
84
49.9k
    PIXEL data;
85
86
49.9k
    if (bitmask & mask)
87
49.9k
      data = fgPel;
88
49.9k
    else
89
49.9k
      data = BLACK_PIXEL;
90
91
49.9k
    DESTWRITEPIXEL(pbDest, data);
92
49.9k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
49.9k
  });
94
49.9k
  return pbDest;
95
50.0k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
71
18.4k
{
72
18.4k
  BYTE mask = 0x01;
73
74
18.4k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
18.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
16
    return nullptr;
82
83
18.4k
  UNROLL(cBits, {
84
18.4k
    PIXEL data;
85
86
18.4k
    if (bitmask & mask)
87
18.4k
      data = fgPel;
88
18.4k
    else
89
18.4k
      data = BLACK_PIXEL;
90
91
18.4k
    DESTWRITEPIXEL(pbDest, data);
92
18.4k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
18.4k
  });
94
18.4k
  return pbDest;
95
18.4k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
71
31.5k
{
72
31.5k
  BYTE mask = 0x01;
73
74
31.5k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
31.5k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
28
    return nullptr;
82
83
31.5k
  UNROLL(cBits, {
84
31.5k
    PIXEL data;
85
86
31.5k
    if (bitmask & mask)
87
31.5k
      data = fgPel;
88
31.5k
    else
89
31.5k
      data = BLACK_PIXEL;
90
91
31.5k
    DESTWRITEPIXEL(pbDest, data);
92
31.5k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
31.5k
  });
94
31.5k
  return pbDest;
95
31.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
18.0k
{
105
18.0k
  const BYTE* pbSrc = pbSrcBuffer;
106
18.0k
  BYTE* pbDest = pbDestBuffer;
107
18.0k
  PIXEL temp = 0;
108
18.0k
  PIXEL fgPel = WHITE_PIXEL;
109
18.0k
  BOOL fInsertFgPel = FALSE;
110
18.0k
  BOOL fFirstLine = TRUE;
111
18.0k
  BYTE bitmask = 0;
112
18.0k
  PIXEL pixelA = 0;
113
18.0k
  PIXEL pixelB = 0;
114
18.0k
  UINT32 runLength = 0;
115
18.0k
  UINT32 code = 0;
116
18.0k
  UINT32 advance = 0;
117
18.0k
  RLEEXTRA
118
119
18.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
18.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
18.0k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
18.0k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
563k
  while (pbSrc < pbEnd)
138
558k
  {
139
    /* Watch out for the end of the first scanline. */
140
558k
    if (fFirstLine)
141
87.5k
    {
142
87.5k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
13.3k
      {
144
13.3k
        fFirstLine = FALSE;
145
13.3k
        fInsertFgPel = FALSE;
146
13.3k
      }
147
87.5k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
558k
    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
558k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
400k
    {
163
400k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
400k
      if (advance == 0)
165
722
        return FALSE;
166
400k
      pbSrc = pbSrc + advance;
167
168
400k
      if (fFirstLine)
169
39.0k
      {
170
39.0k
        if (fInsertFgPel)
171
27.2k
        {
172
27.2k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
27.2k
          DESTWRITEPIXEL(pbDest, fgPel);
176
27.2k
          runLength = runLength - 1;
177
27.2k
        }
178
179
39.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
85
          return FALSE;
181
182
39.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
39.0k
      }
184
360k
      else
185
360k
      {
186
360k
        if (fInsertFgPel)
187
331k
        {
188
331k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
331k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
55
            return FALSE;
192
193
331k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
331k
          runLength--;
195
331k
        }
196
197
360k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
1.34k
          return FALSE;
199
200
359k
        UNROLL(runLength, {
201
359k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
359k
          DESTWRITEPIXEL(pbDest, temp);
203
359k
        });
204
359k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
398k
      fInsertFgPel = TRUE;
208
398k
      continue;
209
400k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
157k
    fInsertFgPel = FALSE;
214
215
157k
    switch (code)
216
157k
    {
217
      /* Handle Foreground Run Orders. */
218
26.1k
      case REGULAR_FG_RUN:
219
28.5k
      case MEGA_MEGA_FG_RUN:
220
45.9k
      case LITE_SET_FG_FG_RUN:
221
46.8k
      case MEGA_MEGA_SET_FG_RUN:
222
46.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
46.8k
        if (advance == 0)
224
97
          return FALSE;
225
46.7k
        pbSrc = pbSrc + advance;
226
227
46.7k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
18.2k
        {
229
18.2k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
245
            return FALSE;
231
18.0k
          SRCREADPIXEL(fgPel, pbSrc);
232
18.0k
        }
233
234
46.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
210
          return FALSE;
236
237
46.3k
        if (fFirstLine)
238
10.7k
        {
239
10.7k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
10.7k
        }
241
35.5k
        else
242
35.5k
        {
243
35.5k
          UNROLL(runLength, {
244
35.5k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
35.5k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
35.5k
          });
247
35.5k
        }
248
249
46.3k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
14.2k
      case LITE_DITHERED_RUN:
253
15.3k
      case MEGA_MEGA_DITHERED_RUN:
254
15.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
15.3k
        if (advance == 0)
256
65
          return FALSE;
257
15.3k
        pbSrc = pbSrc + advance;
258
15.3k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
315
          return FALSE;
260
15.0k
        SRCREADPIXEL(pixelA, pbSrc);
261
15.0k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
622
          return FALSE;
263
14.3k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
14.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
145
          return FALSE;
267
268
14.2k
        UNROLL(runLength, {
269
14.2k
          DESTWRITEPIXEL(pbDest, pixelA);
270
14.2k
          DESTWRITEPIXEL(pbDest, pixelB);
271
14.2k
        });
272
14.2k
        break;
273
274
      /* Handle Color Run Orders. */
275
40.1k
      case REGULAR_COLOR_RUN:
276
41.7k
      case MEGA_MEGA_COLOR_RUN:
277
41.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
41.7k
        if (advance == 0)
279
73
          return FALSE;
280
41.6k
        pbSrc = pbSrc + advance;
281
41.6k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
317
          return FALSE;
283
41.3k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
41.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
267
          return FALSE;
287
288
41.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
41.0k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
13.7k
      case REGULAR_FGBG_IMAGE:
293
16.3k
      case MEGA_MEGA_FGBG_IMAGE:
294
21.1k
      case LITE_SET_FG_FGBG_IMAGE:
295
22.9k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
22.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
22.9k
        if (advance == 0)
298
119
          return FALSE;
299
22.8k
        pbSrc = pbSrc + advance;
300
301
22.8k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
6.55k
        {
303
6.55k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
210
            return FALSE;
305
6.34k
          SRCREADPIXEL(fgPel, pbSrc);
306
6.34k
        }
307
308
22.5k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
826
          return FALSE;
310
21.7k
        if (fFirstLine)
311
5.79k
        {
312
52.0k
          while (runLength > 8)
313
46.2k
          {
314
46.2k
            bitmask = *pbSrc;
315
46.2k
            pbSrc = pbSrc + 1;
316
46.2k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
46.2k
            if (!pbDest)
319
41
              return FALSE;
320
321
46.2k
            runLength = runLength - 8;
322
46.2k
          }
323
5.79k
        }
324
15.9k
        else
325
15.9k
        {
326
101k
          while (runLength > 8)
327
85.1k
          {
328
85.1k
            bitmask = *pbSrc++;
329
330
85.1k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
85.1k
            if (!pbDest)
333
85
              return FALSE;
334
335
85.0k
            runLength = runLength - 8;
336
85.0k
          }
337
15.9k
        }
338
339
21.6k
        if (runLength > 0)
340
17.8k
        {
341
17.8k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
123
            return FALSE;
343
17.7k
          bitmask = *pbSrc++;
344
345
17.7k
          if (fFirstLine)
346
3.12k
          {
347
3.12k
            pbDest =
348
3.12k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
3.12k
          }
350
14.6k
          else
351
14.6k
          {
352
14.6k
            pbDest =
353
14.6k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
354
14.6k
          }
355
356
17.7k
          if (!pbDest)
357
12
            return FALSE;
358
17.7k
        }
359
360
21.5k
        break;
361
362
      /* Handle Color Image Orders. */
363
21.5k
      case REGULAR_COLOR_IMAGE:
364
12.1k
      case MEGA_MEGA_COLOR_IMAGE:
365
12.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
12.1k
        if (advance == 0)
367
56
          return FALSE;
368
12.1k
        pbSrc = pbSrc + advance;
369
12.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
106
          return FALSE;
371
12.0k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
1.10k
          return FALSE;
373
374
10.9k
        UNROLL(runLength, {
375
10.9k
          SRCREADPIXEL(temp, pbSrc);
376
10.9k
          DESTWRITEPIXEL(pbDest, temp);
377
10.9k
        });
378
10.9k
        break;
379
380
      /* Handle Special Order 1. */
381
4.71k
      case SPECIAL_FGBG_1:
382
4.71k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
4.71k
        pbSrc = pbSrc + 1;
385
386
4.71k
        if (fFirstLine)
387
367
        {
388
367
          pbDest =
389
367
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
367
        }
391
4.35k
        else
392
4.35k
        {
393
4.35k
          pbDest =
394
4.35k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
4.35k
        }
396
397
4.71k
        if (!pbDest)
398
10
          return FALSE;
399
400
4.70k
        break;
401
402
      /* Handle Special Order 2. */
403
4.70k
      case SPECIAL_FGBG_2:
404
2.90k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
2.90k
        pbSrc = pbSrc + 1;
407
408
2.90k
        if (fFirstLine)
409
236
        {
410
236
          pbDest =
411
236
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
236
        }
413
2.66k
        else
414
2.66k
        {
415
2.66k
          pbDest =
416
2.66k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
2.66k
        }
418
419
2.90k
        if (!pbDest)
420
11
          return FALSE;
421
422
2.89k
        break;
423
424
      /* Handle White Order. */
425
2.89k
      case SPECIAL_WHITE:
426
2.53k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
2.53k
        pbSrc = pbSrc + 1;
429
430
2.53k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
4
          return FALSE;
432
433
2.53k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
2.53k
        break;
435
436
      /* Handle Black Order. */
437
2.49k
      case SPECIAL_BLACK:
438
2.49k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
2.49k
        pbSrc = pbSrc + 1;
441
442
2.49k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
4
          return FALSE;
444
445
2.48k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
2.48k
        break;
447
448
6.11k
      default:
449
6.11k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
6.11k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
6.11k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
6.11k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
6.11k
        return FALSE;
454
157k
    }
455
157k
  }
456
457
4.63k
  return TRUE;
458
18.0k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
104
6.00k
{
105
6.00k
  const BYTE* pbSrc = pbSrcBuffer;
106
6.00k
  BYTE* pbDest = pbDestBuffer;
107
6.00k
  PIXEL temp = 0;
108
6.00k
  PIXEL fgPel = WHITE_PIXEL;
109
6.00k
  BOOL fInsertFgPel = FALSE;
110
6.00k
  BOOL fFirstLine = TRUE;
111
6.00k
  BYTE bitmask = 0;
112
6.00k
  PIXEL pixelA = 0;
113
6.00k
  PIXEL pixelB = 0;
114
6.00k
  UINT32 runLength = 0;
115
6.00k
  UINT32 code = 0;
116
6.00k
  UINT32 advance = 0;
117
6.00k
  RLEEXTRA
118
119
6.00k
  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
6.00k
  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
6.00k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
6.00k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
184k
  while (pbSrc < pbEnd)
138
182k
  {
139
    /* Watch out for the end of the first scanline. */
140
182k
    if (fFirstLine)
141
29.4k
    {
142
29.4k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
4.25k
      {
144
4.25k
        fFirstLine = FALSE;
145
4.25k
        fInsertFgPel = FALSE;
146
4.25k
      }
147
29.4k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
182k
    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
182k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
132k
    {
163
132k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
132k
      if (advance == 0)
165
208
        return FALSE;
166
131k
      pbSrc = pbSrc + advance;
167
168
131k
      if (fFirstLine)
169
13.2k
      {
170
13.2k
        if (fInsertFgPel)
171
8.98k
        {
172
8.98k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
8.98k
          DESTWRITEPIXEL(pbDest, fgPel);
176
8.98k
          runLength = runLength - 1;
177
8.98k
        }
178
179
13.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
27
          return FALSE;
181
182
13.1k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
13.1k
      }
184
118k
      else
185
118k
      {
186
118k
        if (fInsertFgPel)
187
109k
        {
188
109k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
109k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
19
            return FALSE;
192
193
109k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
109k
          runLength--;
195
109k
        }
196
197
118k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
441
          return FALSE;
199
200
118k
        UNROLL(runLength, {
201
118k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
118k
          DESTWRITEPIXEL(pbDest, temp);
203
118k
        });
204
118k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
131k
      fInsertFgPel = TRUE;
208
131k
      continue;
209
131k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
50.5k
    fInsertFgPel = FALSE;
214
215
50.5k
    switch (code)
216
50.5k
    {
217
      /* Handle Foreground Run Orders. */
218
8.20k
      case REGULAR_FG_RUN:
219
8.99k
      case MEGA_MEGA_FG_RUN:
220
14.8k
      case LITE_SET_FG_FG_RUN:
221
15.2k
      case MEGA_MEGA_SET_FG_RUN:
222
15.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
15.2k
        if (advance == 0)
224
29
          return FALSE;
225
15.1k
        pbSrc = pbSrc + advance;
226
227
15.1k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
6.21k
        {
229
6.21k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
93
            return FALSE;
231
6.12k
          SRCREADPIXEL(fgPel, pbSrc);
232
6.12k
        }
233
234
15.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
64
          return FALSE;
236
237
15.0k
        if (fFirstLine)
238
3.73k
        {
239
3.73k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
3.73k
        }
241
11.2k
        else
242
11.2k
        {
243
11.2k
          UNROLL(runLength, {
244
11.2k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
11.2k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
11.2k
          });
247
11.2k
        }
248
249
15.0k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
4.40k
      case LITE_DITHERED_RUN:
253
4.86k
      case MEGA_MEGA_DITHERED_RUN:
254
4.86k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
4.86k
        if (advance == 0)
256
17
          return FALSE;
257
4.84k
        pbSrc = pbSrc + advance;
258
4.84k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
125
          return FALSE;
260
4.72k
        SRCREADPIXEL(pixelA, pbSrc);
261
4.72k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
298
          return FALSE;
263
4.42k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
4.42k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
45
          return FALSE;
267
268
4.38k
        UNROLL(runLength, {
269
4.38k
          DESTWRITEPIXEL(pbDest, pixelA);
270
4.38k
          DESTWRITEPIXEL(pbDest, pixelB);
271
4.38k
        });
272
4.38k
        break;
273
274
      /* Handle Color Run Orders. */
275
12.9k
      case REGULAR_COLOR_RUN:
276
13.5k
      case MEGA_MEGA_COLOR_RUN:
277
13.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
13.5k
        if (advance == 0)
279
19
          return FALSE;
280
13.4k
        pbSrc = pbSrc + advance;
281
13.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
121
          return FALSE;
283
13.3k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
13.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
97
          return FALSE;
287
288
13.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
13.2k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
4.24k
      case REGULAR_FGBG_IMAGE:
293
5.10k
      case MEGA_MEGA_FGBG_IMAGE:
294
6.62k
      case LITE_SET_FG_FGBG_IMAGE:
295
7.25k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
7.25k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
7.25k
        if (advance == 0)
298
41
          return FALSE;
299
7.21k
        pbSrc = pbSrc + advance;
300
301
7.21k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
2.13k
        {
303
2.13k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
76
            return FALSE;
305
2.05k
          SRCREADPIXEL(fgPel, pbSrc);
306
2.05k
        }
307
308
7.13k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
258
          return FALSE;
310
6.87k
        if (fFirstLine)
311
2.10k
        {
312
19.0k
          while (runLength > 8)
313
16.9k
          {
314
16.9k
            bitmask = *pbSrc;
315
16.9k
            pbSrc = pbSrc + 1;
316
16.9k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
16.9k
            if (!pbDest)
319
15
              return FALSE;
320
321
16.9k
            runLength = runLength - 8;
322
16.9k
          }
323
2.10k
        }
324
4.77k
        else
325
4.77k
        {
326
27.0k
          while (runLength > 8)
327
22.2k
          {
328
22.2k
            bitmask = *pbSrc++;
329
330
22.2k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
22.2k
            if (!pbDest)
333
19
              return FALSE;
334
335
22.2k
            runLength = runLength - 8;
336
22.2k
          }
337
4.77k
        }
338
339
6.84k
        if (runLength > 0)
340
5.56k
        {
341
5.56k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
39
            return FALSE;
343
5.52k
          bitmask = *pbSrc++;
344
345
5.52k
          if (fFirstLine)
346
1.23k
          {
347
1.23k
            pbDest =
348
1.23k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
1.23k
          }
350
4.28k
          else
351
4.28k
          {
352
4.28k
            pbDest =
353
4.28k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
354
4.28k
          }
355
356
5.52k
          if (!pbDest)
357
8
            return FALSE;
358
5.52k
        }
359
360
6.79k
        break;
361
362
      /* Handle Color Image Orders. */
363
6.79k
      case REGULAR_COLOR_IMAGE:
364
3.63k
      case MEGA_MEGA_COLOR_IMAGE:
365
3.63k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
3.63k
        if (advance == 0)
367
18
          return FALSE;
368
3.61k
        pbSrc = pbSrc + advance;
369
3.61k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
38
          return FALSE;
371
3.58k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
343
          return FALSE;
373
374
3.23k
        UNROLL(runLength, {
375
3.23k
          SRCREADPIXEL(temp, pbSrc);
376
3.23k
          DESTWRITEPIXEL(pbDest, temp);
377
3.23k
        });
378
3.23k
        break;
379
380
      /* Handle Special Order 1. */
381
1.56k
      case SPECIAL_FGBG_1:
382
1.56k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
1.56k
        pbSrc = pbSrc + 1;
385
386
1.56k
        if (fFirstLine)
387
115
        {
388
115
          pbDest =
389
115
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
115
        }
391
1.45k
        else
392
1.45k
        {
393
1.45k
          pbDest =
394
1.45k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
1.45k
        }
396
397
1.56k
        if (!pbDest)
398
2
          return FALSE;
399
400
1.56k
        break;
401
402
      /* Handle Special Order 2. */
403
1.56k
      case SPECIAL_FGBG_2:
404
968
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
968
        pbSrc = pbSrc + 1;
407
408
968
        if (fFirstLine)
409
84
        {
410
84
          pbDest =
411
84
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
84
        }
413
884
        else
414
884
        {
415
884
          pbDest =
416
884
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
884
        }
418
419
968
        if (!pbDest)
420
3
          return FALSE;
421
422
965
        break;
423
424
      /* Handle White Order. */
425
965
      case SPECIAL_WHITE:
426
825
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
825
        pbSrc = pbSrc + 1;
429
430
825
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
2
          return FALSE;
432
433
823
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
823
        break;
435
436
      /* Handle Black Order. */
437
677
      case SPECIAL_BLACK:
438
677
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
677
        pbSrc = pbSrc + 1;
441
442
677
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
2
          return FALSE;
444
445
675
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
675
        break;
447
448
2.00k
      default:
449
2.00k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
2.00k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
2.00k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
2.00k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
2.00k
        return FALSE;
454
50.5k
    }
455
50.5k
  }
456
457
1.53k
  return TRUE;
458
6.00k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
104
12.0k
{
105
12.0k
  const BYTE* pbSrc = pbSrcBuffer;
106
12.0k
  BYTE* pbDest = pbDestBuffer;
107
12.0k
  PIXEL temp = 0;
108
12.0k
  PIXEL fgPel = WHITE_PIXEL;
109
12.0k
  BOOL fInsertFgPel = FALSE;
110
12.0k
  BOOL fFirstLine = TRUE;
111
12.0k
  BYTE bitmask = 0;
112
12.0k
  PIXEL pixelA = 0;
113
12.0k
  PIXEL pixelB = 0;
114
12.0k
  UINT32 runLength = 0;
115
12.0k
  UINT32 code = 0;
116
12.0k
  UINT32 advance = 0;
117
12.0k
  RLEEXTRA
118
119
12.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
12.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
12.0k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
12.0k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
379k
  while (pbSrc < pbEnd)
138
376k
  {
139
    /* Watch out for the end of the first scanline. */
140
376k
    if (fFirstLine)
141
58.0k
    {
142
58.0k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
9.11k
      {
144
9.11k
        fFirstLine = FALSE;
145
9.11k
        fInsertFgPel = FALSE;
146
9.11k
      }
147
58.0k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
376k
    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
376k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
268k
    {
163
268k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
268k
      if (advance == 0)
165
514
        return FALSE;
166
268k
      pbSrc = pbSrc + advance;
167
168
268k
      if (fFirstLine)
169
25.8k
      {
170
25.8k
        if (fInsertFgPel)
171
18.2k
        {
172
18.2k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
18.2k
          DESTWRITEPIXEL(pbDest, fgPel);
176
18.2k
          runLength = runLength - 1;
177
18.2k
        }
178
179
25.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
58
          return FALSE;
181
182
25.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
25.8k
      }
184
242k
      else
185
242k
      {
186
242k
        if (fInsertFgPel)
187
222k
        {
188
222k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
222k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
36
            return FALSE;
192
193
221k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
221k
          runLength--;
195
221k
        }
196
197
242k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
902
          return FALSE;
199
200
241k
        UNROLL(runLength, {
201
241k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
241k
          DESTWRITEPIXEL(pbDest, temp);
203
241k
        });
204
241k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
267k
      fInsertFgPel = TRUE;
208
267k
      continue;
209
268k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
107k
    fInsertFgPel = FALSE;
214
215
107k
    switch (code)
216
107k
    {
217
      /* Handle Foreground Run Orders. */
218
17.9k
      case REGULAR_FG_RUN:
219
19.5k
      case MEGA_MEGA_FG_RUN:
220
31.1k
      case LITE_SET_FG_FG_RUN:
221
31.6k
      case MEGA_MEGA_SET_FG_RUN:
222
31.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
31.6k
        if (advance == 0)
224
68
          return FALSE;
225
31.5k
        pbSrc = pbSrc + advance;
226
227
31.5k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
12.0k
        {
229
12.0k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
152
            return FALSE;
231
11.8k
          SRCREADPIXEL(fgPel, pbSrc);
232
11.8k
        }
233
234
31.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
146
          return FALSE;
236
237
31.2k
        if (fFirstLine)
238
7.03k
        {
239
7.03k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
7.03k
        }
241
24.2k
        else
242
24.2k
        {
243
24.2k
          UNROLL(runLength, {
244
24.2k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
24.2k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
24.2k
          });
247
24.2k
        }
248
249
31.2k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
9.82k
      case LITE_DITHERED_RUN:
253
10.5k
      case MEGA_MEGA_DITHERED_RUN:
254
10.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
10.5k
        if (advance == 0)
256
48
          return FALSE;
257
10.4k
        pbSrc = pbSrc + advance;
258
10.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
190
          return FALSE;
260
10.2k
        SRCREADPIXEL(pixelA, pbSrc);
261
10.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
324
          return FALSE;
263
9.96k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
9.96k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
100
          return FALSE;
267
268
9.86k
        UNROLL(runLength, {
269
9.86k
          DESTWRITEPIXEL(pbDest, pixelA);
270
9.86k
          DESTWRITEPIXEL(pbDest, pixelB);
271
9.86k
        });
272
9.86k
        break;
273
274
      /* Handle Color Run Orders. */
275
27.1k
      case REGULAR_COLOR_RUN:
276
28.2k
      case MEGA_MEGA_COLOR_RUN:
277
28.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
28.2k
        if (advance == 0)
279
54
          return FALSE;
280
28.1k
        pbSrc = pbSrc + advance;
281
28.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
196
          return FALSE;
283
27.9k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
27.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
170
          return FALSE;
287
288
27.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
27.8k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
9.46k
      case REGULAR_FGBG_IMAGE:
293
11.2k
      case MEGA_MEGA_FGBG_IMAGE:
294
14.5k
      case LITE_SET_FG_FGBG_IMAGE:
295
15.6k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
15.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
15.6k
        if (advance == 0)
298
78
          return FALSE;
299
15.5k
        pbSrc = pbSrc + advance;
300
301
15.5k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
4.42k
        {
303
4.42k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
134
            return FALSE;
305
4.29k
          SRCREADPIXEL(fgPel, pbSrc);
306
4.29k
        }
307
308
15.4k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
568
          return FALSE;
310
14.8k
        if (fFirstLine)
311
3.69k
        {
312
32.9k
          while (runLength > 8)
313
29.2k
          {
314
29.2k
            bitmask = *pbSrc;
315
29.2k
            pbSrc = pbSrc + 1;
316
29.2k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
29.2k
            if (!pbDest)
319
26
              return FALSE;
320
321
29.2k
            runLength = runLength - 8;
322
29.2k
          }
323
3.69k
        }
324
11.1k
        else
325
11.1k
        {
326
74.0k
          while (runLength > 8)
327
62.9k
          {
328
62.9k
            bitmask = *pbSrc++;
329
330
62.9k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
62.9k
            if (!pbDest)
333
66
              return FALSE;
334
335
62.8k
            runLength = runLength - 8;
336
62.8k
          }
337
11.1k
        }
338
339
14.7k
        if (runLength > 0)
340
12.3k
        {
341
12.3k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
84
            return FALSE;
343
12.2k
          bitmask = *pbSrc++;
344
345
12.2k
          if (fFirstLine)
346
1.89k
          {
347
1.89k
            pbDest =
348
1.89k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
1.89k
          }
350
10.3k
          else
351
10.3k
          {
352
10.3k
            pbDest =
353
10.3k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
354
10.3k
          }
355
356
12.2k
          if (!pbDest)
357
4
            return FALSE;
358
12.2k
        }
359
360
14.7k
        break;
361
362
      /* Handle Color Image Orders. */
363
14.7k
      case REGULAR_COLOR_IMAGE:
364
8.53k
      case MEGA_MEGA_COLOR_IMAGE:
365
8.53k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
8.53k
        if (advance == 0)
367
38
          return FALSE;
368
8.49k
        pbSrc = pbSrc + advance;
369
8.49k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
68
          return FALSE;
371
8.43k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
762
          return FALSE;
373
374
7.66k
        UNROLL(runLength, {
375
7.66k
          SRCREADPIXEL(temp, pbSrc);
376
7.66k
          DESTWRITEPIXEL(pbDest, temp);
377
7.66k
        });
378
7.66k
        break;
379
380
      /* Handle Special Order 1. */
381
3.15k
      case SPECIAL_FGBG_1:
382
3.15k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
3.15k
        pbSrc = pbSrc + 1;
385
386
3.15k
        if (fFirstLine)
387
252
        {
388
252
          pbDest =
389
252
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
252
        }
391
2.90k
        else
392
2.90k
        {
393
2.90k
          pbDest =
394
2.90k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
2.90k
        }
396
397
3.15k
        if (!pbDest)
398
8
          return FALSE;
399
400
3.14k
        break;
401
402
      /* Handle Special Order 2. */
403
3.14k
      case SPECIAL_FGBG_2:
404
1.93k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
1.93k
        pbSrc = pbSrc + 1;
407
408
1.93k
        if (fFirstLine)
409
152
        {
410
152
          pbDest =
411
152
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
152
        }
413
1.78k
        else
414
1.78k
        {
415
1.78k
          pbDest =
416
1.78k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
1.78k
        }
418
419
1.93k
        if (!pbDest)
420
8
          return FALSE;
421
422
1.92k
        break;
423
424
      /* Handle White Order. */
425
1.92k
      case SPECIAL_WHITE:
426
1.71k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
1.71k
        pbSrc = pbSrc + 1;
429
430
1.71k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
2
          return FALSE;
432
433
1.71k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
1.71k
        break;
435
436
      /* Handle Black Order. */
437
1.81k
      case SPECIAL_BLACK:
438
1.81k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
1.81k
        pbSrc = pbSrc + 1;
441
442
1.81k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
2
          return FALSE;
444
445
1.81k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
1.81k
        break;
447
448
4.11k
      default:
449
4.11k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
4.11k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
4.11k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
4.11k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
4.11k
        return FALSE;
454
107k
    }
455
107k
  }
456
457
3.09k
  return TRUE;
458
12.0k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8