Coverage Report

Created: 2026-01-17 07:16

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
static inline BYTE* WRITEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
32
                                   const BYTE* WINPR_RESTRICT pbDestEnd, UINT32 rowDelta,
33
                                   BYTE bitmask, PIXEL fgPel, UINT32 cBits)
34
94.8k
{
35
94.8k
  PIXEL xorPixel = 0;
36
94.8k
  BYTE mask = 0x01;
37
38
94.8k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
94.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
95
    return NULL;
46
47
94.7k
  UNROLL(cBits, {
48
94.7k
    PIXEL data = 0;
49
94.7k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
94.7k
    if (bitmask & mask)
52
94.7k
      data = xorPixel ^ fgPel;
53
94.7k
    else
54
94.7k
      data = xorPixel;
55
56
94.7k
    DESTWRITEPIXEL(pbDest, data);
57
94.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
94.7k
  });
59
94.7k
  return pbDest;
60
94.7k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
34
27.3k
{
35
27.3k
  PIXEL xorPixel = 0;
36
27.3k
  BYTE mask = 0x01;
37
38
27.3k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
27.3k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
31
    return NULL;
46
47
27.3k
  UNROLL(cBits, {
48
27.3k
    PIXEL data = 0;
49
27.3k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
27.3k
    if (bitmask & mask)
52
27.3k
      data = xorPixel ^ fgPel;
53
27.3k
    else
54
27.3k
      data = xorPixel;
55
56
27.3k
    DESTWRITEPIXEL(pbDest, data);
57
27.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
27.3k
  });
59
27.3k
  return pbDest;
60
27.3k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
34
67.4k
{
35
67.4k
  PIXEL xorPixel = 0;
36
67.4k
  BYTE mask = 0x01;
37
38
67.4k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
67.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
64
    return NULL;
46
47
67.3k
  UNROLL(cBits, {
48
67.3k
    PIXEL data = 0;
49
67.3k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
67.3k
    if (bitmask & mask)
52
67.3k
      data = xorPixel ^ fgPel;
53
67.3k
    else
54
67.3k
      data = xorPixel;
55
56
67.3k
    DESTWRITEPIXEL(pbDest, data);
57
67.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
67.3k
  });
59
67.3k
  return pbDest;
60
67.3k
}
Unexecuted instantiation: interleaved.c:WriteFgBgImage8to8
61
62
/**
63
 * Write a foreground/background image to a destination buffer
64
 * for the first line of compressed data.
65
 */
66
static inline BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
67
                                            const BYTE* WINPR_RESTRICT pbDestEnd, BYTE bitmask,
68
                                            PIXEL fgPel, UINT32 cBits)
69
52.9k
{
70
52.9k
  BYTE mask = 0x01;
71
72
52.9k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
52.9k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
40
    return NULL;
80
81
52.8k
  UNROLL(cBits, {
82
52.8k
    PIXEL data;
83
84
52.8k
    if (bitmask & mask)
85
52.8k
      data = fgPel;
86
52.8k
    else
87
52.8k
      data = BLACK_PIXEL;
88
89
52.8k
    DESTWRITEPIXEL(pbDest, data);
90
52.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
52.8k
  });
92
52.8k
  return pbDest;
93
52.8k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
69
20.3k
{
70
20.3k
  BYTE mask = 0x01;
71
72
20.3k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
20.3k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
16
    return NULL;
80
81
20.2k
  UNROLL(cBits, {
82
20.2k
    PIXEL data;
83
84
20.2k
    if (bitmask & mask)
85
20.2k
      data = fgPel;
86
20.2k
    else
87
20.2k
      data = BLACK_PIXEL;
88
89
20.2k
    DESTWRITEPIXEL(pbDest, data);
90
20.2k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
20.2k
  });
92
20.2k
  return pbDest;
93
20.2k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
69
32.6k
{
70
32.6k
  BYTE mask = 0x01;
71
72
32.6k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
32.6k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
24
    return NULL;
80
81
32.5k
  UNROLL(cBits, {
82
32.5k
    PIXEL data;
83
84
32.5k
    if (bitmask & mask)
85
32.5k
      data = fgPel;
86
32.5k
    else
87
32.5k
      data = BLACK_PIXEL;
88
89
32.5k
    DESTWRITEPIXEL(pbDest, data);
90
32.5k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
32.5k
  });
92
32.5k
  return pbDest;
93
32.5k
}
Unexecuted instantiation: interleaved.c:WriteFirstLineFgBgImage8to8
94
95
/**
96
 * Decompress an RLE compressed bitmap.
97
 */
98
static inline BOOL RLEDECOMPRESS(const BYTE* WINPR_RESTRICT pbSrcBuffer, UINT32 cbSrcBuffer,
99
                                 BYTE* WINPR_RESTRICT pbDestBuffer, UINT32 rowDelta, UINT32 width,
100
                                 UINT32 height)
101
16.7k
{
102
16.7k
  const BYTE* pbSrc = pbSrcBuffer;
103
16.7k
  BYTE* pbDest = pbDestBuffer;
104
16.7k
  PIXEL temp = 0;
105
16.7k
  PIXEL fgPel = WHITE_PIXEL;
106
16.7k
  BOOL fInsertFgPel = FALSE;
107
16.7k
  BOOL fFirstLine = TRUE;
108
16.7k
  BYTE bitmask = 0;
109
16.7k
  PIXEL pixelA = 0;
110
16.7k
  PIXEL pixelB = 0;
111
16.7k
  UINT32 runLength = 0;
112
16.7k
  UINT32 code = 0;
113
16.7k
  UINT32 advance = 0;
114
16.7k
  RLEEXTRA
115
116
16.7k
  if ((rowDelta == 0) || (rowDelta < width))
117
0
  {
118
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
119
0
             width);
120
0
    return FALSE;
121
0
  }
122
123
16.7k
  if (!pbSrcBuffer || !pbDestBuffer)
124
0
  {
125
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p",
126
0
             WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
127
0
             WINPR_CXX_COMPAT_CAST(const void*, pbDestBuffer));
128
0
    return FALSE;
129
0
  }
130
131
16.7k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
132
16.7k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
133
134
505k
  while (pbSrc < pbEnd)
135
501k
  {
136
    /* Watch out for the end of the first scanline. */
137
501k
    if (fFirstLine)
138
79.8k
    {
139
79.8k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
140
12.2k
      {
141
12.2k
        fFirstLine = FALSE;
142
12.2k
        fInsertFgPel = FALSE;
143
12.2k
      }
144
79.8k
    }
145
146
    /*
147
       Extract the compression order code ID from the compression
148
       order header.
149
    */
150
501k
    code = ExtractCodeId(*pbSrc);
151
152
#if defined(WITH_DEBUG_CODECS)
153
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
154
#endif
155
156
    /* Handle Background Run Orders. */
157
501k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
158
335k
    {
159
335k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
160
335k
      if (advance == 0)
161
556
        return FALSE;
162
334k
      pbSrc = pbSrc + advance;
163
164
334k
      if (fFirstLine)
165
33.9k
      {
166
33.9k
        if (fInsertFgPel)
167
23.0k
        {
168
23.0k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
169
0
            return FALSE;
170
171
23.0k
          DESTWRITEPIXEL(pbDest, fgPel);
172
23.0k
          runLength = runLength - 1;
173
23.0k
        }
174
175
33.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
176
59
          return FALSE;
177
178
33.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
179
33.9k
      }
180
300k
      else
181
300k
      {
182
300k
        if (fInsertFgPel)
183
271k
        {
184
271k
          DESTREADPIXEL(temp, pbDest - rowDelta);
185
186
271k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
187
55
            return FALSE;
188
189
271k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
190
271k
          runLength--;
191
271k
        }
192
193
300k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
194
977
          return FALSE;
195
196
299k
        UNROLL(runLength, {
197
299k
          DESTREADPIXEL(temp, pbDest - rowDelta);
198
299k
          DESTWRITEPIXEL(pbDest, temp);
199
299k
        });
200
299k
      }
201
202
      /* A follow-on background run order will need a foreground pel inserted. */
203
333k
      fInsertFgPel = TRUE;
204
333k
      continue;
205
334k
    }
206
207
    /* For any of the other run-types a follow-on background run
208
        order does not need a foreground pel inserted. */
209
165k
    fInsertFgPel = FALSE;
210
211
165k
    switch (code)
212
165k
    {
213
      /* Handle Foreground Run Orders. */
214
24.2k
      case REGULAR_FG_RUN:
215
26.5k
      case MEGA_MEGA_FG_RUN:
216
43.3k
      case LITE_SET_FG_FG_RUN:
217
44.4k
      case MEGA_MEGA_SET_FG_RUN:
218
44.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
219
44.4k
        if (advance == 0)
220
112
          return FALSE;
221
44.3k
        pbSrc = pbSrc + advance;
222
223
44.3k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
224
17.8k
        {
225
17.8k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
226
204
            return FALSE;
227
17.6k
          SRCREADPIXEL(fgPel, pbSrc);
228
17.6k
        }
229
230
44.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
231
309
          return FALSE;
232
233
43.8k
        if (fFirstLine)
234
10.0k
        {
235
10.0k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
236
10.0k
        }
237
33.8k
        else
238
33.8k
        {
239
33.8k
          UNROLL(runLength, {
240
33.8k
            DESTREADPIXEL(temp, pbDest - rowDelta);
241
33.8k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
242
33.8k
          });
243
33.8k
        }
244
245
43.8k
        break;
246
247
      /* Handle Dithered Run Orders. */
248
11.3k
      case LITE_DITHERED_RUN:
249
12.5k
      case MEGA_MEGA_DITHERED_RUN:
250
12.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
251
12.5k
        if (advance == 0)
252
65
          return FALSE;
253
12.5k
        pbSrc = pbSrc + advance;
254
12.5k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
251
          return FALSE;
256
12.2k
        SRCREADPIXEL(pixelA, pbSrc);
257
12.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
522
          return FALSE;
259
11.7k
        SRCREADPIXEL(pixelB, pbSrc);
260
261
11.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
262
182
          return FALSE;
263
264
11.5k
        UNROLL(runLength, {
265
11.5k
          DESTWRITEPIXEL(pbDest, pixelA);
266
11.5k
          DESTWRITEPIXEL(pbDest, pixelB);
267
11.5k
        });
268
11.5k
        break;
269
270
      /* Handle Color Run Orders. */
271
48.5k
      case REGULAR_COLOR_RUN:
272
49.7k
      case MEGA_MEGA_COLOR_RUN:
273
49.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
274
49.7k
        if (advance == 0)
275
61
          return FALSE;
276
49.6k
        pbSrc = pbSrc + advance;
277
49.6k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
278
290
          return FALSE;
279
49.3k
        SRCREADPIXEL(pixelA, pbSrc);
280
281
49.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
282
150
          return FALSE;
283
284
49.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
285
49.2k
        break;
286
287
      /* Handle Foreground/Background Image Orders. */
288
14.3k
      case REGULAR_FGBG_IMAGE:
289
16.4k
      case MEGA_MEGA_FGBG_IMAGE:
290
20.9k
      case LITE_SET_FG_FGBG_IMAGE:
291
22.1k
      case MEGA_MEGA_SET_FGBG_IMAGE:
292
22.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
293
22.1k
        if (advance == 0)
294
134
          return FALSE;
295
21.9k
        pbSrc = pbSrc + advance;
296
297
21.9k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
298
5.56k
        {
299
5.56k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
300
176
            return FALSE;
301
5.39k
          SRCREADPIXEL(fgPel, pbSrc);
302
5.39k
        }
303
304
21.7k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
305
865
          return FALSE;
306
20.9k
        if (fFirstLine)
307
5.27k
        {
308
54.5k
          while (runLength > 8)
309
49.3k
          {
310
49.3k
            bitmask = *pbSrc;
311
49.3k
            pbSrc = pbSrc + 1;
312
49.3k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
313
314
49.3k
            if (!pbDest)
315
37
              return FALSE;
316
317
49.3k
            runLength = runLength - 8;
318
49.3k
          }
319
5.27k
        }
320
15.6k
        else
321
15.6k
        {
322
90.1k
          while (runLength > 8)
323
74.5k
          {
324
74.5k
            bitmask = *pbSrc++;
325
326
74.5k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
327
328
74.5k
            if (!pbDest)
329
73
              return FALSE;
330
331
74.4k
            runLength = runLength - 8;
332
74.4k
          }
333
15.6k
        }
334
335
20.8k
        if (runLength > 0)
336
18.1k
        {
337
18.1k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
338
107
            return FALSE;
339
18.0k
          bitmask = *pbSrc++;
340
341
18.0k
          if (fFirstLine)
342
2.93k
          {
343
2.93k
            pbDest =
344
2.93k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
345
2.93k
          }
346
15.0k
          else
347
15.0k
          {
348
15.0k
            pbDest =
349
15.0k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
350
15.0k
          }
351
352
18.0k
          if (!pbDest)
353
14
            return FALSE;
354
18.0k
        }
355
356
20.6k
        break;
357
358
      /* Handle Color Image Orders. */
359
20.6k
      case REGULAR_COLOR_IMAGE:
360
12.4k
      case MEGA_MEGA_COLOR_IMAGE:
361
12.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
362
12.4k
        if (advance == 0)
363
65
          return FALSE;
364
12.4k
        pbSrc = pbSrc + advance;
365
12.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
366
126
          return FALSE;
367
12.2k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
368
1.01k
          return FALSE;
369
370
11.2k
        UNROLL(runLength, {
371
3.49k
          SRCREADPIXEL(temp, pbSrc);
372
3.49k
          DESTWRITEPIXEL(pbDest, temp);
373
3.49k
        });
374
7.78k
        break;
375
376
      /* Handle Special Order 1. */
377
7.78k
      case SPECIAL_FGBG_1:
378
2.37k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
379
0
          return FALSE;
380
2.37k
        pbSrc = pbSrc + 1;
381
382
2.37k
        if (fFirstLine)
383
299
        {
384
299
          pbDest =
385
299
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
386
299
        }
387
2.07k
        else
388
2.07k
        {
389
2.07k
          pbDest =
390
2.07k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
391
2.07k
        }
392
393
2.37k
        if (!pbDest)
394
8
          return FALSE;
395
396
2.36k
        break;
397
398
      /* Handle Special Order 2. */
399
3.44k
      case SPECIAL_FGBG_2:
400
3.44k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
401
0
          return FALSE;
402
3.44k
        pbSrc = pbSrc + 1;
403
404
3.44k
        if (fFirstLine)
405
327
        {
406
327
          pbDest =
407
327
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
408
327
        }
409
3.11k
        else
410
3.11k
        {
411
3.11k
          pbDest =
412
3.11k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
413
3.11k
        }
414
415
3.44k
        if (!pbDest)
416
3
          return FALSE;
417
418
3.43k
        break;
419
420
      /* Handle White Order. */
421
7.01k
      case SPECIAL_WHITE:
422
7.01k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
423
0
          return FALSE;
424
7.01k
        pbSrc = pbSrc + 1;
425
426
7.01k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
427
3
          return FALSE;
428
429
7.01k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
430
7.01k
        break;
431
432
      /* Handle Black Order. */
433
5.34k
      case SPECIAL_BLACK:
434
5.34k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
435
0
          return FALSE;
436
5.34k
        pbSrc = pbSrc + 1;
437
438
5.34k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
439
3
          return FALSE;
440
441
5.34k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
442
5.34k
        break;
443
444
6.12k
      default:
445
6.12k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
446
6.12k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
447
6.12k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
448
6.12k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
449
6.12k
        return FALSE;
450
165k
    }
451
165k
  }
452
453
4.18k
  return TRUE;
454
16.7k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
101
5.57k
{
102
5.57k
  const BYTE* pbSrc = pbSrcBuffer;
103
5.57k
  BYTE* pbDest = pbDestBuffer;
104
5.57k
  PIXEL temp = 0;
105
5.57k
  PIXEL fgPel = WHITE_PIXEL;
106
5.57k
  BOOL fInsertFgPel = FALSE;
107
5.57k
  BOOL fFirstLine = TRUE;
108
5.57k
  BYTE bitmask = 0;
109
5.57k
  PIXEL pixelA = 0;
110
5.57k
  PIXEL pixelB = 0;
111
5.57k
  UINT32 runLength = 0;
112
5.57k
  UINT32 code = 0;
113
5.57k
  UINT32 advance = 0;
114
5.57k
  RLEEXTRA
115
116
5.57k
  if ((rowDelta == 0) || (rowDelta < width))
117
0
  {
118
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
119
0
             width);
120
0
    return FALSE;
121
0
  }
122
123
5.57k
  if (!pbSrcBuffer || !pbDestBuffer)
124
0
  {
125
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p",
126
0
             WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
127
0
             WINPR_CXX_COMPAT_CAST(const void*, pbDestBuffer));
128
0
    return FALSE;
129
0
  }
130
131
5.57k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
132
5.57k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
133
134
167k
  while (pbSrc < pbEnd)
135
165k
  {
136
    /* Watch out for the end of the first scanline. */
137
165k
    if (fFirstLine)
138
26.9k
    {
139
26.9k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
140
3.92k
      {
141
3.92k
        fFirstLine = FALSE;
142
3.92k
        fInsertFgPel = FALSE;
143
3.92k
      }
144
26.9k
    }
145
146
    /*
147
       Extract the compression order code ID from the compression
148
       order header.
149
    */
150
165k
    code = ExtractCodeId(*pbSrc);
151
152
#if defined(WITH_DEBUG_CODECS)
153
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
154
#endif
155
156
    /* Handle Background Run Orders. */
157
165k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
158
109k
    {
159
109k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
160
109k
      if (advance == 0)
161
144
        return FALSE;
162
109k
      pbSrc = pbSrc + advance;
163
164
109k
      if (fFirstLine)
165
11.5k
      {
166
11.5k
        if (fInsertFgPel)
167
7.68k
        {
168
7.68k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
169
0
            return FALSE;
170
171
7.68k
          DESTWRITEPIXEL(pbDest, fgPel);
172
7.68k
          runLength = runLength - 1;
173
7.68k
        }
174
175
11.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
176
21
          return FALSE;
177
178
11.5k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
179
11.5k
      }
180
97.8k
      else
181
97.8k
      {
182
97.8k
        if (fInsertFgPel)
183
88.4k
        {
184
88.4k
          DESTREADPIXEL(temp, pbDest - rowDelta);
185
186
88.4k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
187
19
            return FALSE;
188
189
88.4k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
190
88.4k
          runLength--;
191
88.4k
        }
192
193
97.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
194
305
          return FALSE;
195
196
97.5k
        UNROLL(runLength, {
197
97.5k
          DESTREADPIXEL(temp, pbDest - rowDelta);
198
97.5k
          DESTWRITEPIXEL(pbDest, temp);
199
97.5k
        });
200
97.5k
      }
201
202
      /* A follow-on background run order will need a foreground pel inserted. */
203
109k
      fInsertFgPel = TRUE;
204
109k
      continue;
205
109k
    }
206
207
    /* For any of the other run-types a follow-on background run
208
        order does not need a foreground pel inserted. */
209
56.1k
    fInsertFgPel = FALSE;
210
211
56.1k
    switch (code)
212
56.1k
    {
213
      /* Handle Foreground Run Orders. */
214
8.05k
      case REGULAR_FG_RUN:
215
8.81k
      case MEGA_MEGA_FG_RUN:
216
14.9k
      case LITE_SET_FG_FG_RUN:
217
15.3k
      case MEGA_MEGA_SET_FG_RUN:
218
15.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
219
15.3k
        if (advance == 0)
220
36
          return FALSE;
221
15.3k
        pbSrc = pbSrc + advance;
222
223
15.3k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
224
6.51k
        {
225
6.51k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
226
72
            return FALSE;
227
6.43k
          SRCREADPIXEL(fgPel, pbSrc);
228
6.43k
        }
229
230
15.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
231
75
          return FALSE;
232
233
15.1k
        if (fFirstLine)
234
3.51k
        {
235
3.51k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
236
3.51k
        }
237
11.6k
        else
238
11.6k
        {
239
11.6k
          UNROLL(runLength, {
240
11.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
241
11.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
242
11.6k
          });
243
11.6k
        }
244
245
15.1k
        break;
246
247
      /* Handle Dithered Run Orders. */
248
3.94k
      case LITE_DITHERED_RUN:
249
4.36k
      case MEGA_MEGA_DITHERED_RUN:
250
4.36k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
251
4.36k
        if (advance == 0)
252
15
          return FALSE;
253
4.34k
        pbSrc = pbSrc + advance;
254
4.34k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
111
          return FALSE;
256
4.23k
        SRCREADPIXEL(pixelA, pbSrc);
257
4.23k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
248
          return FALSE;
259
3.98k
        SRCREADPIXEL(pixelB, pbSrc);
260
261
3.98k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
262
52
          return FALSE;
263
264
3.93k
        UNROLL(runLength, {
265
3.93k
          DESTWRITEPIXEL(pbDest, pixelA);
266
3.93k
          DESTWRITEPIXEL(pbDest, pixelB);
267
3.93k
        });
268
3.93k
        break;
269
270
      /* Handle Color Run Orders. */
271
16.9k
      case REGULAR_COLOR_RUN:
272
17.3k
      case MEGA_MEGA_COLOR_RUN:
273
17.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
274
17.3k
        if (advance == 0)
275
17
          return FALSE;
276
17.3k
        pbSrc = pbSrc + advance;
277
17.3k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
278
128
          return FALSE;
279
17.1k
        SRCREADPIXEL(pixelA, pbSrc);
280
281
17.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
282
60
          return FALSE;
283
284
17.1k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
285
17.1k
        break;
286
287
      /* Handle Foreground/Background Image Orders. */
288
4.52k
      case REGULAR_FGBG_IMAGE:
289
5.22k
      case MEGA_MEGA_FGBG_IMAGE:
290
6.77k
      case LITE_SET_FG_FGBG_IMAGE:
291
7.17k
      case MEGA_MEGA_SET_FGBG_IMAGE:
292
7.17k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
293
7.17k
        if (advance == 0)
294
38
          return FALSE;
295
7.13k
        pbSrc = pbSrc + advance;
296
297
7.13k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
298
1.93k
        {
299
1.93k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
300
70
            return FALSE;
301
1.86k
          SRCREADPIXEL(fgPel, pbSrc);
302
1.86k
        }
303
304
7.06k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
305
269
          return FALSE;
306
6.79k
        if (fFirstLine)
307
1.85k
        {
308
20.7k
          while (runLength > 8)
309
18.9k
          {
310
18.9k
            bitmask = *pbSrc;
311
18.9k
            pbSrc = pbSrc + 1;
312
18.9k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
313
314
18.9k
            if (!pbDest)
315
15
              return FALSE;
316
317
18.9k
            runLength = runLength - 8;
318
18.9k
          }
319
1.85k
        }
320
4.94k
        else
321
4.94k
        {
322
25.9k
          while (runLength > 8)
323
20.9k
          {
324
20.9k
            bitmask = *pbSrc++;
325
326
20.9k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
327
328
20.9k
            if (!pbDest)
329
19
              return FALSE;
330
331
20.9k
            runLength = runLength - 8;
332
20.9k
          }
333
4.94k
        }
334
335
6.76k
        if (runLength > 0)
336
5.84k
        {
337
5.84k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
338
37
            return FALSE;
339
5.80k
          bitmask = *pbSrc++;
340
341
5.80k
          if (fFirstLine)
342
1.13k
          {
343
1.13k
            pbDest =
344
1.13k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
345
1.13k
          }
346
4.67k
          else
347
4.67k
          {
348
4.67k
            pbDest =
349
4.67k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
350
4.67k
          }
351
352
5.80k
          if (!pbDest)
353
10
            return FALSE;
354
5.80k
        }
355
356
6.71k
        break;
357
358
      /* Handle Color Image Orders. */
359
6.71k
      case REGULAR_COLOR_IMAGE:
360
3.87k
      case MEGA_MEGA_COLOR_IMAGE:
361
3.87k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
362
3.87k
        if (advance == 0)
363
21
          return FALSE;
364
3.85k
        pbSrc = pbSrc + advance;
365
3.85k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
366
38
          return FALSE;
367
3.81k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
368
327
          return FALSE;
369
370
3.49k
        UNROLL(runLength, {
371
3.49k
          SRCREADPIXEL(temp, pbSrc);
372
3.49k
          DESTWRITEPIXEL(pbDest, temp);
373
3.49k
        });
374
3.49k
        break;
375
376
      /* Handle Special Order 1. */
377
787
      case SPECIAL_FGBG_1:
378
787
        if (!buffer_within_range(pbSrc, 1, pbEnd))
379
0
          return FALSE;
380
787
        pbSrc = pbSrc + 1;
381
382
787
        if (fFirstLine)
383
97
        {
384
97
          pbDest =
385
97
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
386
97
        }
387
690
        else
388
690
        {
389
690
          pbDest =
390
690
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
391
690
        }
392
393
787
        if (!pbDest)
394
2
          return FALSE;
395
396
785
        break;
397
398
      /* Handle Special Order 2. */
399
1.14k
      case SPECIAL_FGBG_2:
400
1.14k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
401
0
          return FALSE;
402
1.14k
        pbSrc = pbSrc + 1;
403
404
1.14k
        if (fFirstLine)
405
117
        {
406
117
          pbDest =
407
117
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
408
117
        }
409
1.03k
        else
410
1.03k
        {
411
1.03k
          pbDest =
412
1.03k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
413
1.03k
        }
414
415
1.14k
        if (!pbDest)
416
1
          return FALSE;
417
418
1.14k
        break;
419
420
      /* Handle White Order. */
421
2.31k
      case SPECIAL_WHITE:
422
2.31k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
423
0
          return FALSE;
424
2.31k
        pbSrc = pbSrc + 1;
425
426
2.31k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
427
1
          return FALSE;
428
429
2.31k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
430
2.31k
        break;
431
432
      /* Handle Black Order. */
433
1.77k
      case SPECIAL_BLACK:
434
1.77k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
435
0
          return FALSE;
436
1.77k
        pbSrc = pbSrc + 1;
437
438
1.77k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
439
1
          return FALSE;
440
441
1.77k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
442
1.77k
        break;
443
444
2.01k
      default:
445
2.01k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
446
2.01k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
447
2.01k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
448
2.01k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
449
2.01k
        return FALSE;
450
56.1k
    }
451
56.1k
  }
452
453
1.41k
  return TRUE;
454
5.57k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
101
11.1k
{
102
11.1k
  const BYTE* pbSrc = pbSrcBuffer;
103
11.1k
  BYTE* pbDest = pbDestBuffer;
104
11.1k
  PIXEL temp = 0;
105
11.1k
  PIXEL fgPel = WHITE_PIXEL;
106
11.1k
  BOOL fInsertFgPel = FALSE;
107
11.1k
  BOOL fFirstLine = TRUE;
108
11.1k
  BYTE bitmask = 0;
109
11.1k
  PIXEL pixelA = 0;
110
11.1k
  PIXEL pixelB = 0;
111
11.1k
  UINT32 runLength = 0;
112
11.1k
  UINT32 code = 0;
113
11.1k
  UINT32 advance = 0;
114
11.1k
  RLEEXTRA
115
116
11.1k
  if ((rowDelta == 0) || (rowDelta < width))
117
0
  {
118
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
119
0
             width);
120
0
    return FALSE;
121
0
  }
122
123
11.1k
  if (!pbSrcBuffer || !pbDestBuffer)
124
0
  {
125
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p",
126
0
             WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
127
0
             WINPR_CXX_COMPAT_CAST(const void*, pbDestBuffer));
128
0
    return FALSE;
129
0
  }
130
131
11.1k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
132
11.1k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
133
134
338k
  while (pbSrc < pbEnd)
135
335k
  {
136
    /* Watch out for the end of the first scanline. */
137
335k
    if (fFirstLine)
138
52.9k
    {
139
52.9k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
140
8.34k
      {
141
8.34k
        fFirstLine = FALSE;
142
8.34k
        fInsertFgPel = FALSE;
143
8.34k
      }
144
52.9k
    }
145
146
    /*
147
       Extract the compression order code ID from the compression
148
       order header.
149
    */
150
335k
    code = ExtractCodeId(*pbSrc);
151
152
#if defined(WITH_DEBUG_CODECS)
153
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
154
#endif
155
156
    /* Handle Background Run Orders. */
157
335k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
158
225k
    {
159
225k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
160
225k
      if (advance == 0)
161
412
        return FALSE;
162
225k
      pbSrc = pbSrc + advance;
163
164
225k
      if (fFirstLine)
165
22.4k
      {
166
22.4k
        if (fInsertFgPel)
167
15.4k
        {
168
15.4k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
169
0
            return FALSE;
170
171
15.4k
          DESTWRITEPIXEL(pbDest, fgPel);
172
15.4k
          runLength = runLength - 1;
173
15.4k
        }
174
175
22.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
176
38
          return FALSE;
177
178
22.4k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
179
22.4k
      }
180
203k
      else
181
203k
      {
182
203k
        if (fInsertFgPel)
183
182k
        {
184
182k
          DESTREADPIXEL(temp, pbDest - rowDelta);
185
186
182k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
187
36
            return FALSE;
188
189
182k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
190
182k
          runLength--;
191
182k
        }
192
193
203k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
194
672
          return FALSE;
195
196
202k
        UNROLL(runLength, {
197
202k
          DESTREADPIXEL(temp, pbDest - rowDelta);
198
202k
          DESTWRITEPIXEL(pbDest, temp);
199
202k
        });
200
202k
      }
201
202
      /* A follow-on background run order will need a foreground pel inserted. */
203
224k
      fInsertFgPel = TRUE;
204
224k
      continue;
205
225k
    }
206
207
    /* For any of the other run-types a follow-on background run
208
        order does not need a foreground pel inserted. */
209
109k
    fInsertFgPel = FALSE;
210
211
109k
    switch (code)
212
109k
    {
213
      /* Handle Foreground Run Orders. */
214
16.2k
      case REGULAR_FG_RUN:
215
17.7k
      case MEGA_MEGA_FG_RUN:
216
28.4k
      case LITE_SET_FG_FG_RUN:
217
29.1k
      case MEGA_MEGA_SET_FG_RUN:
218
29.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
219
29.1k
        if (advance == 0)
220
76
          return FALSE;
221
29.0k
        pbSrc = pbSrc + advance;
222
223
29.0k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
224
11.3k
        {
225
11.3k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
226
132
            return FALSE;
227
11.2k
          SRCREADPIXEL(fgPel, pbSrc);
228
11.2k
        }
229
230
28.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
231
234
          return FALSE;
232
233
28.7k
        if (fFirstLine)
234
6.54k
        {
235
6.54k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
236
6.54k
        }
237
22.1k
        else
238
22.1k
        {
239
22.1k
          UNROLL(runLength, {
240
22.1k
            DESTREADPIXEL(temp, pbDest - rowDelta);
241
22.1k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
242
22.1k
          });
243
22.1k
        }
244
245
28.7k
        break;
246
247
      /* Handle Dithered Run Orders. */
248
7.37k
      case LITE_DITHERED_RUN:
249
8.20k
      case MEGA_MEGA_DITHERED_RUN:
250
8.20k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
251
8.20k
        if (advance == 0)
252
50
          return FALSE;
253
8.15k
        pbSrc = pbSrc + advance;
254
8.15k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
140
          return FALSE;
256
8.01k
        SRCREADPIXEL(pixelA, pbSrc);
257
8.01k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
274
          return FALSE;
259
7.74k
        SRCREADPIXEL(pixelB, pbSrc);
260
261
7.74k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
262
130
          return FALSE;
263
264
7.61k
        UNROLL(runLength, {
265
7.61k
          DESTWRITEPIXEL(pbDest, pixelA);
266
7.61k
          DESTWRITEPIXEL(pbDest, pixelB);
267
7.61k
        });
268
7.61k
        break;
269
270
      /* Handle Color Run Orders. */
271
31.5k
      case REGULAR_COLOR_RUN:
272
32.3k
      case MEGA_MEGA_COLOR_RUN:
273
32.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
274
32.3k
        if (advance == 0)
275
44
          return FALSE;
276
32.3k
        pbSrc = pbSrc + advance;
277
32.3k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
278
162
          return FALSE;
279
32.1k
        SRCREADPIXEL(pixelA, pbSrc);
280
281
32.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
282
90
          return FALSE;
283
284
32.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
285
32.0k
        break;
286
287
      /* Handle Foreground/Background Image Orders. */
288
9.81k
      case REGULAR_FGBG_IMAGE:
289
11.2k
      case MEGA_MEGA_FGBG_IMAGE:
290
14.1k
      case LITE_SET_FG_FGBG_IMAGE:
291
14.9k
      case MEGA_MEGA_SET_FGBG_IMAGE:
292
14.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
293
14.9k
        if (advance == 0)
294
96
          return FALSE;
295
14.8k
        pbSrc = pbSrc + advance;
296
297
14.8k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
298
3.63k
        {
299
3.63k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
300
106
            return FALSE;
301
3.53k
          SRCREADPIXEL(fgPel, pbSrc);
302
3.53k
        }
303
304
14.7k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
305
596
          return FALSE;
306
14.1k
        if (fFirstLine)
307
3.42k
        {
308
33.8k
          while (runLength > 8)
309
30.4k
          {
310
30.4k
            bitmask = *pbSrc;
311
30.4k
            pbSrc = pbSrc + 1;
312
30.4k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
313
314
30.4k
            if (!pbDest)
315
22
              return FALSE;
316
317
30.3k
            runLength = runLength - 8;
318
30.3k
          }
319
3.42k
        }
320
10.7k
        else
321
10.7k
        {
322
64.2k
          while (runLength > 8)
323
53.5k
          {
324
53.5k
            bitmask = *pbSrc++;
325
326
53.5k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
327
328
53.5k
            if (!pbDest)
329
54
              return FALSE;
330
331
53.5k
            runLength = runLength - 8;
332
53.5k
          }
333
10.7k
        }
334
335
14.0k
        if (runLength > 0)
336
12.2k
        {
337
12.2k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
338
70
            return FALSE;
339
12.1k
          bitmask = *pbSrc++;
340
341
12.1k
          if (fFirstLine)
342
1.80k
          {
343
1.80k
            pbDest =
344
1.80k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
345
1.80k
          }
346
10.3k
          else
347
10.3k
          {
348
10.3k
            pbDest =
349
10.3k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
350
10.3k
          }
351
352
12.1k
          if (!pbDest)
353
4
            return FALSE;
354
12.1k
        }
355
356
13.9k
        break;
357
358
      /* Handle Color Image Orders. */
359
13.9k
      case REGULAR_COLOR_IMAGE:
360
8.60k
      case MEGA_MEGA_COLOR_IMAGE:
361
8.60k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
362
8.60k
        if (advance == 0)
363
44
          return FALSE;
364
8.55k
        pbSrc = pbSrc + advance;
365
8.55k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
366
88
          return FALSE;
367
8.46k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
368
686
          return FALSE;
369
370
7.78k
        UNROLL(runLength, {
371
7.78k
          SRCREADPIXEL(temp, pbSrc);
372
7.78k
          DESTWRITEPIXEL(pbDest, temp);
373
7.78k
        });
374
7.78k
        break;
375
376
      /* Handle Special Order 1. */
377
7.78k
      case SPECIAL_FGBG_1:
378
1.58k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
379
0
          return FALSE;
380
1.58k
        pbSrc = pbSrc + 1;
381
382
1.58k
        if (fFirstLine)
383
202
        {
384
202
          pbDest =
385
202
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
386
202
        }
387
1.38k
        else
388
1.38k
        {
389
1.38k
          pbDest =
390
1.38k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
391
1.38k
        }
392
393
1.58k
        if (!pbDest)
394
6
          return FALSE;
395
396
1.58k
        break;
397
398
      /* Handle Special Order 2. */
399
2.29k
      case SPECIAL_FGBG_2:
400
2.29k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
401
0
          return FALSE;
402
2.29k
        pbSrc = pbSrc + 1;
403
404
2.29k
        if (fFirstLine)
405
210
        {
406
210
          pbDest =
407
210
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
408
210
        }
409
2.08k
        else
410
2.08k
        {
411
2.08k
          pbDest =
412
2.08k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
413
2.08k
        }
414
415
2.29k
        if (!pbDest)
416
2
          return FALSE;
417
418
2.29k
        break;
419
420
      /* Handle White Order. */
421
4.69k
      case SPECIAL_WHITE:
422
4.69k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
423
0
          return FALSE;
424
4.69k
        pbSrc = pbSrc + 1;
425
426
4.69k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
427
2
          return FALSE;
428
429
4.69k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
430
4.69k
        break;
431
432
      /* Handle Black Order. */
433
3.57k
      case SPECIAL_BLACK:
434
3.57k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
435
0
          return FALSE;
436
3.57k
        pbSrc = pbSrc + 1;
437
438
3.57k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
439
2
          return FALSE;
440
441
3.56k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
442
3.56k
        break;
443
444
4.11k
      default:
445
4.11k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
446
4.11k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
447
4.11k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
448
4.11k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
449
4.11k
        return FALSE;
450
109k
    }
451
109k
  }
452
453
2.77k
  return TRUE;
454
11.1k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8