Coverage Report

Created: 2026-04-12 06:59

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
98.0k
{
36
98.0k
  PIXEL xorPixel = 0;
37
98.0k
  BYTE mask = 0x01;
38
39
98.0k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
98.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
104
    return nullptr;
47
48
97.9k
  UNROLL(cBits, {
49
97.9k
    PIXEL data = 0;
50
97.9k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
97.9k
    if (bitmask & mask)
53
97.9k
      data = xorPixel ^ fgPel;
54
97.9k
    else
55
97.9k
      data = xorPixel;
56
57
97.9k
    DESTWRITEPIXEL(pbDest, data);
58
97.9k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
97.9k
  });
60
97.9k
  return pbDest;
61
98.0k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
35
24.8k
{
36
24.8k
  PIXEL xorPixel = 0;
37
24.8k
  BYTE mask = 0x01;
38
39
24.8k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
24.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
28
    return nullptr;
47
48
24.8k
  UNROLL(cBits, {
49
24.8k
    PIXEL data = 0;
50
24.8k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
24.8k
    if (bitmask & mask)
53
24.8k
      data = xorPixel ^ fgPel;
54
24.8k
    else
55
24.8k
      data = xorPixel;
56
57
24.8k
    DESTWRITEPIXEL(pbDest, data);
58
24.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
24.8k
  });
60
24.8k
  return pbDest;
61
24.8k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
35
73.1k
{
36
73.1k
  PIXEL xorPixel = 0;
37
73.1k
  BYTE mask = 0x01;
38
39
73.1k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
73.1k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
76
    return nullptr;
47
48
73.1k
  UNROLL(cBits, {
49
73.1k
    PIXEL data = 0;
50
73.1k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
73.1k
    if (bitmask & mask)
53
73.1k
      data = xorPixel ^ fgPel;
54
73.1k
    else
55
73.1k
      data = xorPixel;
56
57
73.1k
    DESTWRITEPIXEL(pbDest, data);
58
73.1k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
73.1k
  });
60
73.1k
  return pbDest;
61
73.1k
}
Unexecuted instantiation: interleaved.c:WriteFgBgImage8to8
62
63
/**
64
 * Write a foreground/background image to a destination buffer
65
 * for the first line of compressed data.
66
 */
67
WINPR_ATTR_NODISCARD
68
static inline BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
69
                                            const BYTE* WINPR_RESTRICT pbDestEnd, BYTE bitmask,
70
                                            PIXEL fgPel, UINT32 cBits)
71
56.4k
{
72
56.4k
  BYTE mask = 0x01;
73
74
56.4k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
56.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
43
    return nullptr;
82
83
56.3k
  UNROLL(cBits, {
84
56.3k
    PIXEL data;
85
86
56.3k
    if (bitmask & mask)
87
56.3k
      data = fgPel;
88
56.3k
    else
89
56.3k
      data = BLACK_PIXEL;
90
91
56.3k
    DESTWRITEPIXEL(pbDest, data);
92
56.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
56.3k
  });
94
56.3k
  return pbDest;
95
56.4k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
71
20.6k
{
72
20.6k
  BYTE mask = 0x01;
73
74
20.6k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
20.6k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
15
    return nullptr;
82
83
20.6k
  UNROLL(cBits, {
84
20.6k
    PIXEL data;
85
86
20.6k
    if (bitmask & mask)
87
20.6k
      data = fgPel;
88
20.6k
    else
89
20.6k
      data = BLACK_PIXEL;
90
91
20.6k
    DESTWRITEPIXEL(pbDest, data);
92
20.6k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
20.6k
  });
94
20.6k
  return pbDest;
95
20.6k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
71
35.7k
{
72
35.7k
  BYTE mask = 0x01;
73
74
35.7k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
35.7k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
28
    return nullptr;
82
83
35.7k
  UNROLL(cBits, {
84
35.7k
    PIXEL data;
85
86
35.7k
    if (bitmask & mask)
87
35.7k
      data = fgPel;
88
35.7k
    else
89
35.7k
      data = BLACK_PIXEL;
90
91
35.7k
    DESTWRITEPIXEL(pbDest, data);
92
35.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
35.7k
  });
94
35.7k
  return pbDest;
95
35.7k
}
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.6k
{
105
17.6k
  const BYTE* pbSrc = pbSrcBuffer;
106
17.6k
  BYTE* pbDest = pbDestBuffer;
107
17.6k
  PIXEL temp = 0;
108
17.6k
  PIXEL fgPel = WHITE_PIXEL;
109
17.6k
  BOOL fInsertFgPel = FALSE;
110
17.6k
  BOOL fFirstLine = TRUE;
111
17.6k
  BYTE bitmask = 0;
112
17.6k
  PIXEL pixelA = 0;
113
17.6k
  PIXEL pixelB = 0;
114
17.6k
  UINT32 runLength = 0;
115
17.6k
  UINT32 code = 0;
116
17.6k
  UINT32 advance = 0;
117
17.6k
  RLEEXTRA
118
119
17.6k
  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.6k
  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.6k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
17.6k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
510k
  while (pbSrc < pbEnd)
138
506k
  {
139
    /* Watch out for the end of the first scanline. */
140
506k
    if (fFirstLine)
141
85.5k
    {
142
85.5k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
13.0k
      {
144
13.0k
        fFirstLine = FALSE;
145
13.0k
        fInsertFgPel = FALSE;
146
13.0k
      }
147
85.5k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
506k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
157
#endif
158
159
    /* Handle Background Run Orders. */
160
506k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
369k
    {
162
369k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
369k
      if (advance == 0)
164
610
        return FALSE;
165
368k
      pbSrc = pbSrc + advance;
166
167
368k
      if (fFirstLine)
168
38.2k
      {
169
38.2k
        if (fInsertFgPel)
170
26.6k
        {
171
26.6k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
26.6k
          DESTWRITEPIXEL(pbDest, fgPel);
175
26.6k
          runLength = runLength - 1;
176
26.6k
        }
177
178
38.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
73
          return FALSE;
180
181
38.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
38.2k
      }
183
330k
      else
184
330k
      {
185
330k
        if (fInsertFgPel)
186
301k
        {
187
301k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
301k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
56
            return FALSE;
191
192
301k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
301k
          runLength--;
194
301k
        }
195
196
330k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
1.07k
          return FALSE;
198
199
329k
        UNROLL(runLength, {
200
329k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
329k
          DESTWRITEPIXEL(pbDest, temp);
202
329k
        });
203
329k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
367k
      fInsertFgPel = TRUE;
207
367k
      continue;
208
368k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
136k
    fInsertFgPel = FALSE;
213
214
136k
    switch (code)
215
136k
    {
216
      /* Handle Foreground Run Orders. */
217
27.8k
      case REGULAR_FG_RUN:
218
29.7k
      case MEGA_MEGA_FG_RUN:
219
47.1k
      case LITE_SET_FG_FG_RUN:
220
48.1k
      case MEGA_MEGA_SET_FG_RUN:
221
48.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
48.1k
        if (advance == 0)
223
97
          return FALSE;
224
48.0k
        pbSrc = pbSrc + advance;
225
226
48.0k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
18.3k
        {
228
18.3k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
238
            return FALSE;
230
18.1k
          SRCREADPIXEL(fgPel, pbSrc);
231
18.1k
        }
232
233
47.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
310
          return FALSE;
235
236
47.5k
        if (fFirstLine)
237
10.6k
        {
238
10.6k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
10.6k
        }
240
36.8k
        else
241
36.8k
        {
242
36.8k
          UNROLL(runLength, {
243
36.8k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
36.8k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
36.8k
          });
246
36.8k
        }
247
248
47.5k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
12.6k
      case LITE_DITHERED_RUN:
252
13.6k
      case MEGA_MEGA_DITHERED_RUN:
253
13.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
13.6k
        if (advance == 0)
255
53
          return FALSE;
256
13.6k
        pbSrc = pbSrc + advance;
257
13.6k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
256
          return FALSE;
259
13.3k
        SRCREADPIXEL(pixelA, pbSrc);
260
13.3k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
515
          return FALSE;
262
12.8k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
12.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
146
          return FALSE;
266
267
12.7k
        UNROLL(runLength, {
268
12.7k
          DESTWRITEPIXEL(pbDest, pixelA);
269
12.7k
          DESTWRITEPIXEL(pbDest, pixelB);
270
12.7k
        });
271
12.7k
        break;
272
273
      /* Handle Color Run Orders. */
274
23.0k
      case REGULAR_COLOR_RUN:
275
24.3k
      case MEGA_MEGA_COLOR_RUN:
276
24.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
24.3k
        if (advance == 0)
278
66
          return FALSE;
279
24.2k
        pbSrc = pbSrc + advance;
280
24.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
314
          return FALSE;
282
23.9k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
23.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
222
          return FALSE;
286
287
23.7k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
23.7k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
13.0k
      case REGULAR_FGBG_IMAGE:
292
15.1k
      case MEGA_MEGA_FGBG_IMAGE:
293
18.8k
      case LITE_SET_FG_FGBG_IMAGE:
294
19.8k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
19.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
19.8k
        if (advance == 0)
297
113
          return FALSE;
298
19.7k
        pbSrc = pbSrc + advance;
299
300
19.7k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
4.62k
        {
302
4.62k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
194
            return FALSE;
304
4.43k
          SRCREADPIXEL(fgPel, pbSrc);
305
4.43k
        }
306
307
19.5k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
850
          return FALSE;
309
18.6k
        if (fFirstLine)
310
5.20k
        {
311
57.9k
          while (runLength > 8)
312
52.7k
          {
313
52.7k
            bitmask = *pbSrc;
314
52.7k
            pbSrc = pbSrc + 1;
315
52.7k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
52.7k
            if (!pbDest)
318
40
              return FALSE;
319
320
52.7k
            runLength = runLength - 8;
321
52.7k
          }
322
5.20k
        }
323
13.4k
        else
324
13.4k
        {
325
93.7k
          while (runLength > 8)
326
80.3k
          {
327
80.3k
            bitmask = *pbSrc++;
328
329
80.3k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
80.3k
            if (!pbDest)
332
88
              return FALSE;
333
334
80.2k
            runLength = runLength - 8;
335
80.2k
          }
336
13.4k
        }
337
338
18.5k
        if (runLength > 0)
339
15.9k
        {
340
15.9k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
106
            return FALSE;
342
15.8k
          bitmask = *pbSrc++;
343
344
15.8k
          if (fFirstLine)
345
2.90k
          {
346
2.90k
            pbDest =
347
2.90k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
2.90k
          }
349
12.9k
          else
350
12.9k
          {
351
12.9k
            pbDest =
352
12.9k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
12.9k
          }
354
355
15.8k
          if (!pbDest)
356
8
            return FALSE;
357
15.8k
        }
358
359
18.4k
        break;
360
361
      /* Handle Color Image Orders. */
362
18.4k
      case REGULAR_COLOR_IMAGE:
363
12.8k
      case MEGA_MEGA_COLOR_IMAGE:
364
12.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
12.8k
        if (advance == 0)
366
67
          return FALSE;
367
12.7k
        pbSrc = pbSrc + advance;
368
12.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
103
          return FALSE;
370
12.6k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
1.05k
          return FALSE;
372
373
11.6k
        UNROLL(runLength, {
374
11.6k
          SRCREADPIXEL(temp, pbSrc);
375
11.6k
          DESTWRITEPIXEL(pbDest, temp);
376
11.6k
        });
377
11.6k
        break;
378
379
      /* Handle Special Order 1. */
380
2.37k
      case SPECIAL_FGBG_1:
381
2.37k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
2.37k
        pbSrc = pbSrc + 1;
384
385
2.37k
        if (fFirstLine)
386
382
        {
387
382
          pbDest =
388
382
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
382
        }
390
1.98k
        else
391
1.98k
        {
392
1.98k
          pbDest =
393
1.98k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
1.98k
        }
395
396
2.37k
        if (!pbDest)
397
3
          return FALSE;
398
399
2.36k
        break;
400
401
      /* Handle Special Order 2. */
402
3.10k
      case SPECIAL_FGBG_2:
403
3.10k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
3.10k
        pbSrc = pbSrc + 1;
406
407
3.10k
        if (fFirstLine)
408
330
        {
409
330
          pbDest =
410
330
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
330
        }
412
2.77k
        else
413
2.77k
        {
414
2.77k
          pbDest =
415
2.77k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
2.77k
        }
417
418
3.10k
        if (!pbDest)
419
8
          return FALSE;
420
421
3.09k
        break;
422
423
      /* Handle White Order. */
424
3.11k
      case SPECIAL_WHITE:
425
3.11k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
3.11k
        pbSrc = pbSrc + 1;
428
429
3.11k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
3
          return FALSE;
431
432
3.11k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
3.11k
        break;
434
435
      /* Handle Black Order. */
436
2.61k
      case SPECIAL_BLACK:
437
2.61k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
2.61k
        pbSrc = pbSrc + 1;
440
441
2.61k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
3
          return FALSE;
443
444
2.61k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
2.61k
        break;
446
447
6.63k
      default:
448
6.63k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
6.63k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
6.63k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
6.63k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
6.63k
        return FALSE;
453
136k
    }
454
136k
  }
455
456
4.35k
  return TRUE;
457
17.6k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
104
5.89k
{
105
5.89k
  const BYTE* pbSrc = pbSrcBuffer;
106
5.89k
  BYTE* pbDest = pbDestBuffer;
107
5.89k
  PIXEL temp = 0;
108
5.89k
  PIXEL fgPel = WHITE_PIXEL;
109
5.89k
  BOOL fInsertFgPel = FALSE;
110
5.89k
  BOOL fFirstLine = TRUE;
111
5.89k
  BYTE bitmask = 0;
112
5.89k
  PIXEL pixelA = 0;
113
5.89k
  PIXEL pixelB = 0;
114
5.89k
  UINT32 runLength = 0;
115
5.89k
  UINT32 code = 0;
116
5.89k
  UINT32 advance = 0;
117
5.89k
  RLEEXTRA
118
119
5.89k
  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.89k
  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.89k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
5.89k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
165k
  while (pbSrc < pbEnd)
138
164k
  {
139
    /* Watch out for the end of the first scanline. */
140
164k
    if (fFirstLine)
141
28.7k
    {
142
28.7k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
4.13k
      {
144
4.13k
        fFirstLine = FALSE;
145
4.13k
        fInsertFgPel = FALSE;
146
4.13k
      }
147
28.7k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
164k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
157
#endif
158
159
    /* Handle Background Run Orders. */
160
164k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
120k
    {
162
120k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
120k
      if (advance == 0)
164
166
        return FALSE;
165
120k
      pbSrc = pbSrc + advance;
166
167
120k
      if (fFirstLine)
168
12.9k
      {
169
12.9k
        if (fInsertFgPel)
170
8.85k
        {
171
8.85k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
8.85k
          DESTWRITEPIXEL(pbDest, fgPel);
175
8.85k
          runLength = runLength - 1;
176
8.85k
        }
177
178
12.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
25
          return FALSE;
180
181
12.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
12.9k
      }
183
107k
      else
184
107k
      {
185
107k
        if (fInsertFgPel)
186
98.5k
        {
187
98.5k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
98.5k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
16
            return FALSE;
191
192
98.5k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
98.5k
          runLength--;
194
98.5k
        }
195
196
107k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
356
          return FALSE;
198
199
107k
        UNROLL(runLength, {
200
107k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
107k
          DESTWRITEPIXEL(pbDest, temp);
202
107k
        });
203
107k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
120k
      fInsertFgPel = TRUE;
207
120k
      continue;
208
120k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
43.4k
    fInsertFgPel = FALSE;
213
214
43.4k
    switch (code)
215
43.4k
    {
216
      /* Handle Foreground Run Orders. */
217
8.81k
      case REGULAR_FG_RUN:
218
9.42k
      case MEGA_MEGA_FG_RUN:
219
15.1k
      case LITE_SET_FG_FG_RUN:
220
15.5k
      case MEGA_MEGA_SET_FG_RUN:
221
15.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
15.5k
        if (advance == 0)
223
29
          return FALSE;
224
15.4k
        pbSrc = pbSrc + advance;
225
226
15.4k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
6.07k
        {
228
6.07k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
86
            return FALSE;
230
5.98k
          SRCREADPIXEL(fgPel, pbSrc);
231
5.98k
        }
232
233
15.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
92
          return FALSE;
235
236
15.3k
        if (fFirstLine)
237
3.65k
        {
238
3.65k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
3.65k
        }
240
11.6k
        else
241
11.6k
        {
242
11.6k
          UNROLL(runLength, {
243
11.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
11.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
11.6k
          });
246
11.6k
        }
247
248
15.3k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
4.15k
      case LITE_DITHERED_RUN:
252
4.51k
      case MEGA_MEGA_DITHERED_RUN:
253
4.51k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
4.51k
        if (advance == 0)
255
17
          return FALSE;
256
4.49k
        pbSrc = pbSrc + advance;
257
4.49k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
110
          return FALSE;
259
4.38k
        SRCREADPIXEL(pixelA, pbSrc);
260
4.38k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
255
          return FALSE;
262
4.13k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
4.13k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
40
          return FALSE;
266
267
4.09k
        UNROLL(runLength, {
268
4.09k
          DESTWRITEPIXEL(pbDest, pixelA);
269
4.09k
          DESTWRITEPIXEL(pbDest, pixelB);
270
4.09k
        });
271
4.09k
        break;
272
273
      /* Handle Color Run Orders. */
274
7.08k
      case REGULAR_COLOR_RUN:
275
7.53k
      case MEGA_MEGA_COLOR_RUN:
276
7.53k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
7.53k
        if (advance == 0)
278
20
          return FALSE;
279
7.51k
        pbSrc = pbSrc + advance;
280
7.51k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
120
          return FALSE;
282
7.39k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
7.39k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
84
          return FALSE;
286
287
7.30k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
7.30k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
3.93k
      case REGULAR_FGBG_IMAGE:
292
4.63k
      case MEGA_MEGA_FGBG_IMAGE:
293
5.80k
      case LITE_SET_FG_FGBG_IMAGE:
294
6.09k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
6.09k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
6.09k
        if (advance == 0)
297
33
          return FALSE;
298
6.05k
        pbSrc = pbSrc + advance;
299
300
6.05k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
1.43k
        {
302
1.43k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
68
            return FALSE;
304
1.36k
          SRCREADPIXEL(fgPel, pbSrc);
305
1.36k
        }
306
307
5.99k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
260
          return FALSE;
309
5.73k
        if (fFirstLine)
310
1.86k
        {
311
21.1k
          while (runLength > 8)
312
19.2k
          {
313
19.2k
            bitmask = *pbSrc;
314
19.2k
            pbSrc = pbSrc + 1;
315
19.2k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
19.2k
            if (!pbDest)
318
14
              return FALSE;
319
320
19.2k
            runLength = runLength - 8;
321
19.2k
          }
322
1.86k
        }
323
3.86k
        else
324
3.86k
        {
325
23.3k
          while (runLength > 8)
326
19.5k
          {
327
19.5k
            bitmask = *pbSrc++;
328
329
19.5k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
19.5k
            if (!pbDest)
332
20
              return FALSE;
333
334
19.5k
            runLength = runLength - 8;
335
19.5k
          }
336
3.86k
        }
337
338
5.69k
        if (runLength > 0)
339
4.87k
        {
340
4.87k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
40
            return FALSE;
342
4.83k
          bitmask = *pbSrc++;
343
344
4.83k
          if (fFirstLine)
345
1.12k
          {
346
1.12k
            pbDest =
347
1.12k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1.12k
          }
349
3.70k
          else
350
3.70k
          {
351
3.70k
            pbDest =
352
3.70k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
3.70k
          }
354
355
4.83k
          if (!pbDest)
356
4
            return FALSE;
357
4.83k
        }
358
359
5.65k
        break;
360
361
      /* Handle Color Image Orders. */
362
5.65k
      case REGULAR_COLOR_IMAGE:
363
3.88k
      case MEGA_MEGA_COLOR_IMAGE:
364
3.88k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
3.88k
        if (advance == 0)
366
23
          return FALSE;
367
3.86k
        pbSrc = pbSrc + advance;
368
3.86k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
37
          return FALSE;
370
3.82k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
328
          return FALSE;
372
373
3.49k
        UNROLL(runLength, {
374
3.49k
          SRCREADPIXEL(temp, pbSrc);
375
3.49k
          DESTWRITEPIXEL(pbDest, temp);
376
3.49k
        });
377
3.49k
        break;
378
379
      /* Handle Special Order 1. */
380
766
      case SPECIAL_FGBG_1:
381
766
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
766
        pbSrc = pbSrc + 1;
384
385
766
        if (fFirstLine)
386
122
        {
387
122
          pbDest =
388
122
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
122
        }
390
644
        else
391
644
        {
392
644
          pbDest =
393
644
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
644
        }
395
396
766
        if (!pbDest)
397
1
          return FALSE;
398
399
765
        break;
400
401
      /* Handle Special Order 2. */
402
1.09k
      case SPECIAL_FGBG_2:
403
1.09k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
1.09k
        pbSrc = pbSrc + 1;
406
407
1.09k
        if (fFirstLine)
408
114
        {
409
114
          pbDest =
410
114
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
114
        }
412
983
        else
413
983
        {
414
983
          pbDest =
415
983
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
983
        }
417
418
1.09k
        if (!pbDest)
419
4
          return FALSE;
420
421
1.09k
        break;
422
423
      /* Handle White Order. */
424
1.09k
      case SPECIAL_WHITE:
425
1.06k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
1.06k
        pbSrc = pbSrc + 1;
428
429
1.06k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
1
          return FALSE;
431
432
1.06k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
1.06k
        break;
434
435
      /* Handle Black Order. */
436
867
      case SPECIAL_BLACK:
437
867
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
867
        pbSrc = pbSrc + 1;
440
441
867
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
1
          return FALSE;
443
444
866
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
866
        break;
446
447
2.17k
      default:
448
2.17k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
2.17k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
2.17k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
2.17k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
2.17k
        return FALSE;
453
43.4k
    }
454
43.4k
  }
455
456
1.46k
  return TRUE;
457
5.89k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
104
11.7k
{
105
11.7k
  const BYTE* pbSrc = pbSrcBuffer;
106
11.7k
  BYTE* pbDest = pbDestBuffer;
107
11.7k
  PIXEL temp = 0;
108
11.7k
  PIXEL fgPel = WHITE_PIXEL;
109
11.7k
  BOOL fInsertFgPel = FALSE;
110
11.7k
  BOOL fFirstLine = TRUE;
111
11.7k
  BYTE bitmask = 0;
112
11.7k
  PIXEL pixelA = 0;
113
11.7k
  PIXEL pixelB = 0;
114
11.7k
  UINT32 runLength = 0;
115
11.7k
  UINT32 code = 0;
116
11.7k
  UINT32 advance = 0;
117
11.7k
  RLEEXTRA
118
119
11.7k
  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.7k
  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.7k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
11.7k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
344k
  while (pbSrc < pbEnd)
138
341k
  {
139
    /* Watch out for the end of the first scanline. */
140
341k
    if (fFirstLine)
141
56.8k
    {
142
56.8k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
8.88k
      {
144
8.88k
        fFirstLine = FALSE;
145
8.88k
        fInsertFgPel = FALSE;
146
8.88k
      }
147
56.8k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
341k
    code = ExtractCodeId(*pbSrc);
154
155
#if defined(WITH_DEBUG_CODECS)
156
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
157
#endif
158
159
    /* Handle Background Run Orders. */
160
341k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
248k
    {
162
248k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
248k
      if (advance == 0)
164
444
        return FALSE;
165
248k
      pbSrc = pbSrc + advance;
166
167
248k
      if (fFirstLine)
168
25.3k
      {
169
25.3k
        if (fInsertFgPel)
170
17.8k
        {
171
17.8k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
17.8k
          DESTWRITEPIXEL(pbDest, fgPel);
175
17.8k
          runLength = runLength - 1;
176
17.8k
        }
177
178
25.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
48
          return FALSE;
180
181
25.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
25.2k
      }
183
222k
      else
184
222k
      {
185
222k
        if (fInsertFgPel)
186
202k
        {
187
202k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
202k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
40
            return FALSE;
191
192
202k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
202k
          runLength--;
194
202k
        }
195
196
222k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
722
          return FALSE;
198
199
222k
        UNROLL(runLength, {
200
222k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
222k
          DESTWRITEPIXEL(pbDest, temp);
202
222k
        });
203
222k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
247k
      fInsertFgPel = TRUE;
207
247k
      continue;
208
248k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
93.2k
    fInsertFgPel = FALSE;
213
214
93.2k
    switch (code)
215
93.2k
    {
216
      /* Handle Foreground Run Orders. */
217
19.0k
      case REGULAR_FG_RUN:
218
20.2k
      case MEGA_MEGA_FG_RUN:
219
32.0k
      case LITE_SET_FG_FG_RUN:
220
32.6k
      case MEGA_MEGA_SET_FG_RUN:
221
32.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
32.6k
        if (advance == 0)
223
68
          return FALSE;
224
32.5k
        pbSrc = pbSrc + advance;
225
226
32.5k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
12.3k
        {
228
12.3k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
152
            return FALSE;
230
12.1k
          SRCREADPIXEL(fgPel, pbSrc);
231
12.1k
        }
232
233
32.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
218
          return FALSE;
235
236
32.2k
        if (fFirstLine)
237
7.00k
        {
238
7.00k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
7.00k
        }
240
25.2k
        else
241
25.2k
        {
242
25.2k
          UNROLL(runLength, {
243
25.2k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
25.2k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
25.2k
          });
246
25.2k
        }
247
248
32.2k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
8.52k
      case LITE_DITHERED_RUN:
252
9.17k
      case MEGA_MEGA_DITHERED_RUN:
253
9.17k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
9.17k
        if (advance == 0)
255
36
          return FALSE;
256
9.14k
        pbSrc = pbSrc + advance;
257
9.14k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
146
          return FALSE;
259
8.99k
        SRCREADPIXEL(pixelA, pbSrc);
260
8.99k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
260
          return FALSE;
262
8.73k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
8.73k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
106
          return FALSE;
266
267
8.63k
        UNROLL(runLength, {
268
8.63k
          DESTWRITEPIXEL(pbDest, pixelA);
269
8.63k
          DESTWRITEPIXEL(pbDest, pixelB);
270
8.63k
        });
271
8.63k
        break;
272
273
      /* Handle Color Run Orders. */
274
15.9k
      case REGULAR_COLOR_RUN:
275
16.8k
      case MEGA_MEGA_COLOR_RUN:
276
16.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
16.8k
        if (advance == 0)
278
46
          return FALSE;
279
16.7k
        pbSrc = pbSrc + advance;
280
16.7k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
194
          return FALSE;
282
16.5k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
16.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
138
          return FALSE;
286
287
16.4k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
16.4k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
9.07k
      case REGULAR_FGBG_IMAGE:
292
10.5k
      case MEGA_MEGA_FGBG_IMAGE:
293
13.0k
      case LITE_SET_FG_FGBG_IMAGE:
294
13.7k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
13.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
13.7k
        if (advance == 0)
297
80
          return FALSE;
298
13.6k
        pbSrc = pbSrc + advance;
299
300
13.6k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
3.19k
        {
302
3.19k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
126
            return FALSE;
304
3.06k
          SRCREADPIXEL(fgPel, pbSrc);
305
3.06k
        }
306
307
13.5k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
590
          return FALSE;
309
12.9k
        if (fFirstLine)
310
3.33k
        {
311
36.8k
          while (runLength > 8)
312
33.5k
          {
313
33.5k
            bitmask = *pbSrc;
314
33.5k
            pbSrc = pbSrc + 1;
315
33.5k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
33.5k
            if (!pbDest)
318
26
              return FALSE;
319
320
33.5k
            runLength = runLength - 8;
321
33.5k
          }
322
3.33k
        }
323
9.62k
        else
324
9.62k
        {
325
70.3k
          while (runLength > 8)
326
60.8k
          {
327
60.8k
            bitmask = *pbSrc++;
328
329
60.8k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
60.8k
            if (!pbDest)
332
68
              return FALSE;
333
334
60.7k
            runLength = runLength - 8;
335
60.7k
          }
336
9.62k
        }
337
338
12.8k
        if (runLength > 0)
339
11.0k
        {
340
11.0k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
66
            return FALSE;
342
11.0k
          bitmask = *pbSrc++;
343
344
11.0k
          if (fFirstLine)
345
1.77k
          {
346
1.77k
            pbDest =
347
1.77k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1.77k
          }
349
9.22k
          else
350
9.22k
          {
351
9.22k
            pbDest =
352
9.22k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
9.22k
          }
354
355
11.0k
          if (!pbDest)
356
4
            return FALSE;
357
11.0k
        }
358
359
12.7k
        break;
360
361
      /* Handle Color Image Orders. */
362
12.7k
      case REGULAR_COLOR_IMAGE:
363
8.98k
      case MEGA_MEGA_COLOR_IMAGE:
364
8.98k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
8.98k
        if (advance == 0)
366
44
          return FALSE;
367
8.93k
        pbSrc = pbSrc + advance;
368
8.93k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
66
          return FALSE;
370
8.87k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
728
          return FALSE;
372
373
8.14k
        UNROLL(runLength, {
374
8.14k
          SRCREADPIXEL(temp, pbSrc);
375
8.14k
          DESTWRITEPIXEL(pbDest, temp);
376
8.14k
        });
377
8.14k
        break;
378
379
      /* Handle Special Order 1. */
380
1.60k
      case SPECIAL_FGBG_1:
381
1.60k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
1.60k
        pbSrc = pbSrc + 1;
384
385
1.60k
        if (fFirstLine)
386
260
        {
387
260
          pbDest =
388
260
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
260
        }
390
1.34k
        else
391
1.34k
        {
392
1.34k
          pbDest =
393
1.34k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
1.34k
        }
395
396
1.60k
        if (!pbDest)
397
2
          return FALSE;
398
399
1.60k
        break;
400
401
      /* Handle Special Order 2. */
402
2.01k
      case SPECIAL_FGBG_2:
403
2.01k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
2.01k
        pbSrc = pbSrc + 1;
406
407
2.01k
        if (fFirstLine)
408
216
        {
409
216
          pbDest =
410
216
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
216
        }
412
1.79k
        else
413
1.79k
        {
414
1.79k
          pbDest =
415
1.79k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
1.79k
        }
417
418
2.01k
        if (!pbDest)
419
4
          return FALSE;
420
421
2.00k
        break;
422
423
      /* Handle White Order. */
424
2.05k
      case SPECIAL_WHITE:
425
2.05k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
2.05k
        pbSrc = pbSrc + 1;
428
429
2.05k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
2
          return FALSE;
431
432
2.05k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
2.05k
        break;
434
435
      /* Handle Black Order. */
436
1.75k
      case SPECIAL_BLACK:
437
1.75k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
1.75k
        pbSrc = pbSrc + 1;
440
441
1.75k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
2
          return FALSE;
443
444
1.74k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
1.74k
        break;
446
447
4.46k
      default:
448
4.46k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
4.46k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
4.46k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
4.46k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
4.46k
        return FALSE;
453
93.2k
    }
454
93.2k
  }
455
456
2.89k
  return TRUE;
457
11.7k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8