Coverage Report

Created: 2026-10-28 06:54

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
90.8k
{
36
90.8k
  PIXEL xorPixel = 0;
37
90.8k
  BYTE mask = 0x01;
38
39
90.8k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
90.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
94
    return nullptr;
47
48
90.7k
  UNROLL(cBits, {
49
90.7k
    PIXEL data = 0;
50
90.7k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
90.7k
    if (bitmask & mask)
53
90.7k
      data = xorPixel ^ fgPel;
54
90.7k
    else
55
90.7k
      data = xorPixel;
56
57
90.7k
    DESTWRITEPIXEL(pbDest, data);
58
90.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
90.7k
  });
60
90.7k
  return pbDest;
61
90.8k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
35
25.7k
{
36
25.7k
  PIXEL xorPixel = 0;
37
25.7k
  BYTE mask = 0x01;
38
39
25.7k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
25.7k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
26
    return nullptr;
47
48
25.7k
  UNROLL(cBits, {
49
25.7k
    PIXEL data = 0;
50
25.7k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
25.7k
    if (bitmask & mask)
53
25.7k
      data = xorPixel ^ fgPel;
54
25.7k
    else
55
25.7k
      data = xorPixel;
56
57
25.7k
    DESTWRITEPIXEL(pbDest, data);
58
25.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
25.7k
  });
60
25.7k
  return pbDest;
61
25.7k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
35
65.0k
{
36
65.0k
  PIXEL xorPixel = 0;
37
65.0k
  BYTE mask = 0x01;
38
39
65.0k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
65.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
68
    return nullptr;
47
48
64.9k
  UNROLL(cBits, {
49
64.9k
    PIXEL data = 0;
50
64.9k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
64.9k
    if (bitmask & mask)
53
64.9k
      data = xorPixel ^ fgPel;
54
64.9k
    else
55
64.9k
      data = xorPixel;
56
57
64.9k
    DESTWRITEPIXEL(pbDest, data);
58
64.9k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
64.9k
  });
60
64.9k
  return pbDest;
61
65.0k
}
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
30.2k
{
72
30.2k
  BYTE mask = 0x01;
73
74
30.2k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
30.2k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
25
    return nullptr;
82
83
30.2k
  UNROLL(cBits, {
84
30.2k
    PIXEL data;
85
86
30.2k
    if (bitmask & mask)
87
30.2k
      data = fgPel;
88
30.2k
    else
89
30.2k
      data = BLACK_PIXEL;
90
91
30.2k
    DESTWRITEPIXEL(pbDest, data);
92
30.2k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
30.2k
  });
94
30.2k
  return pbDest;
95
30.2k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
71
11.2k
{
72
11.2k
  BYTE mask = 0x01;
73
74
11.2k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
11.2k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
7
    return nullptr;
82
83
11.2k
  UNROLL(cBits, {
84
11.2k
    PIXEL data;
85
86
11.2k
    if (bitmask & mask)
87
11.2k
      data = fgPel;
88
11.2k
    else
89
11.2k
      data = BLACK_PIXEL;
90
91
11.2k
    DESTWRITEPIXEL(pbDest, data);
92
11.2k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
11.2k
  });
94
11.2k
  return pbDest;
95
11.2k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
71
19.0k
{
72
19.0k
  BYTE mask = 0x01;
73
74
19.0k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
19.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
18
    return nullptr;
82
83
19.0k
  UNROLL(cBits, {
84
19.0k
    PIXEL data;
85
86
19.0k
    if (bitmask & mask)
87
19.0k
      data = fgPel;
88
19.0k
    else
89
19.0k
      data = BLACK_PIXEL;
90
91
19.0k
    DESTWRITEPIXEL(pbDest, data);
92
19.0k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
19.0k
  });
94
19.0k
  return pbDest;
95
19.0k
}
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.6k
{
105
18.6k
  const BYTE* pbSrc = pbSrcBuffer;
106
18.6k
  BYTE* pbDest = pbDestBuffer;
107
18.6k
  PIXEL temp = 0;
108
18.6k
  PIXEL fgPel = WHITE_PIXEL;
109
18.6k
  BOOL fInsertFgPel = FALSE;
110
18.6k
  BOOL fFirstLine = TRUE;
111
18.6k
  BYTE bitmask = 0;
112
18.6k
  PIXEL pixelA = 0;
113
18.6k
  PIXEL pixelB = 0;
114
18.6k
  UINT32 runLength = 0;
115
18.6k
  UINT32 code = 0;
116
18.6k
  UINT32 advance = 0;
117
18.6k
  RLEEXTRA
118
119
18.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
18.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
18.6k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
18.6k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
605k
  while (pbSrc < pbEnd)
138
600k
  {
139
    /* Watch out for the end of the first scanline. */
140
600k
    if (fFirstLine)
141
90.3k
    {
142
90.3k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
13.9k
      {
144
13.9k
        fFirstLine = FALSE;
145
13.9k
        fInsertFgPel = FALSE;
146
13.9k
      }
147
90.3k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
600k
    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
600k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
436k
    {
163
436k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
436k
      if (advance == 0)
165
740
        return FALSE;
166
435k
      pbSrc = pbSrc + advance;
167
168
435k
      if (fFirstLine)
169
40.7k
      {
170
40.7k
        if (fInsertFgPel)
171
28.3k
        {
172
28.3k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
28.3k
          DESTWRITEPIXEL(pbDest, fgPel);
176
28.3k
          runLength = runLength - 1;
177
28.3k
        }
178
179
40.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
96
          return FALSE;
181
182
40.6k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
40.6k
      }
184
394k
      else
185
394k
      {
186
394k
        if (fInsertFgPel)
187
363k
        {
188
363k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
363k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
49
            return FALSE;
192
193
363k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
363k
          runLength--;
195
363k
        }
196
197
394k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
1.43k
          return FALSE;
199
200
393k
        UNROLL(runLength, {
201
393k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
393k
          DESTWRITEPIXEL(pbDest, temp);
203
393k
        });
204
393k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
434k
      fInsertFgPel = TRUE;
208
434k
      continue;
209
435k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
164k
    fInsertFgPel = FALSE;
214
215
164k
    switch (code)
216
164k
    {
217
      /* Handle Foreground Run Orders. */
218
28.2k
      case REGULAR_FG_RUN:
219
30.6k
      case MEGA_MEGA_FG_RUN:
220
49.7k
      case LITE_SET_FG_FG_RUN:
221
50.6k
      case MEGA_MEGA_SET_FG_RUN:
222
50.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
50.6k
        if (advance == 0)
224
92
          return FALSE;
225
50.5k
        pbSrc = pbSrc + advance;
226
227
50.5k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
19.9k
        {
229
19.9k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
219
            return FALSE;
231
19.7k
          SRCREADPIXEL(fgPel, pbSrc);
232
19.7k
        }
233
234
50.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
210
          return FALSE;
236
237
50.1k
        if (fFirstLine)
238
11.0k
        {
239
11.0k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
11.0k
        }
241
39.0k
        else
242
39.0k
        {
243
39.0k
          UNROLL(runLength, {
244
39.0k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
39.0k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
39.0k
          });
247
39.0k
        }
248
249
50.1k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
13.4k
      case LITE_DITHERED_RUN:
253
15.0k
      case MEGA_MEGA_DITHERED_RUN:
254
15.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
15.0k
        if (advance == 0)
256
54
          return FALSE;
257
15.0k
        pbSrc = pbSrc + advance;
258
15.0k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
359
          return FALSE;
260
14.6k
        SRCREADPIXEL(pixelA, pbSrc);
261
14.6k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
606
          return FALSE;
263
14.0k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
14.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
141
          return FALSE;
267
268
13.9k
        UNROLL(runLength, {
269
13.9k
          DESTWRITEPIXEL(pbDest, pixelA);
270
13.9k
          DESTWRITEPIXEL(pbDest, pixelB);
271
13.9k
        });
272
13.9k
        break;
273
274
      /* Handle Color Run Orders. */
275
42.5k
      case REGULAR_COLOR_RUN:
276
43.8k
      case MEGA_MEGA_COLOR_RUN:
277
43.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
43.8k
        if (advance == 0)
279
62
          return FALSE;
280
43.8k
        pbSrc = pbSrc + advance;
281
43.8k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
334
          return FALSE;
283
43.4k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
43.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
237
          return FALSE;
287
288
43.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
43.2k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
13.9k
      case REGULAR_FGBG_IMAGE:
293
16.3k
      case MEGA_MEGA_FGBG_IMAGE:
294
21.1k
      case LITE_SET_FG_FGBG_IMAGE:
295
22.5k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
22.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
22.5k
        if (advance == 0)
298
140
          return FALSE;
299
22.3k
        pbSrc = pbSrc + advance;
300
301
22.3k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
6.07k
        {
303
6.07k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
209
            return FALSE;
305
5.86k
          SRCREADPIXEL(fgPel, pbSrc);
306
5.86k
        }
307
308
22.1k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
843
          return FALSE;
310
21.3k
        if (fFirstLine)
311
5.56k
        {
312
32.0k
          while (runLength > 8)
313
26.5k
          {
314
26.5k
            bitmask = *pbSrc;
315
26.5k
            pbSrc = pbSrc + 1;
316
26.5k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
26.5k
            if (!pbDest)
319
22
              return FALSE;
320
321
26.4k
            runLength = runLength - 8;
322
26.4k
          }
323
5.56k
        }
324
15.7k
        else
325
15.7k
        {
326
84.8k
          while (runLength > 8)
327
69.1k
          {
328
69.1k
            bitmask = *pbSrc++;
329
330
69.1k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
69.1k
            if (!pbDest)
333
59
              return FALSE;
334
335
69.0k
            runLength = runLength - 8;
336
69.0k
          }
337
15.7k
        }
338
339
21.2k
        if (runLength > 0)
340
17.9k
        {
341
17.9k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
98
            return FALSE;
343
17.8k
          bitmask = *pbSrc++;
344
345
17.8k
          if (fFirstLine)
346
3.08k
          {
347
3.08k
            pbDest =
348
3.08k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
3.08k
          }
350
14.8k
          else
351
14.8k
          {
352
14.8k
            pbDest =
353
14.8k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
354
14.8k
          }
355
356
17.8k
          if (!pbDest)
357
9
            return FALSE;
358
17.8k
        }
359
360
21.1k
        break;
361
362
      /* Handle Color Image Orders. */
363
21.1k
      case REGULAR_COLOR_IMAGE:
364
12.8k
      case MEGA_MEGA_COLOR_IMAGE:
365
12.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
12.8k
        if (advance == 0)
367
54
          return FALSE;
368
12.7k
        pbSrc = pbSrc + advance;
369
12.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
97
          return FALSE;
371
12.6k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
1.21k
          return FALSE;
373
374
11.4k
        UNROLL(runLength, {
375
11.4k
          SRCREADPIXEL(temp, pbSrc);
376
11.4k
          DESTWRITEPIXEL(pbDest, temp);
377
11.4k
        });
378
11.4k
        break;
379
380
      /* Handle Special Order 1. */
381
4.41k
      case SPECIAL_FGBG_1:
382
4.41k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
4.41k
        pbSrc = pbSrc + 1;
385
386
4.41k
        if (fFirstLine)
387
389
        {
388
389
          pbDest =
389
389
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
389
        }
391
4.03k
        else
392
4.03k
        {
393
4.03k
          pbDest =
394
4.03k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
4.03k
        }
396
397
4.41k
        if (!pbDest)
398
13
          return FALSE;
399
400
4.40k
        break;
401
402
      /* Handle Special Order 2. */
403
4.40k
      case SPECIAL_FGBG_2:
404
3.15k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
3.15k
        pbSrc = pbSrc + 1;
407
408
3.15k
        if (fFirstLine)
409
265
        {
410
265
          pbDest =
411
265
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
265
        }
413
2.88k
        else
414
2.88k
        {
415
2.88k
          pbDest =
416
2.88k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
2.88k
        }
418
419
3.15k
        if (!pbDest)
420
16
          return FALSE;
421
422
3.13k
        break;
423
424
      /* Handle White Order. */
425
3.13k
      case SPECIAL_WHITE:
426
2.71k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
2.71k
        pbSrc = pbSrc + 1;
429
430
2.71k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
6
          return FALSE;
432
433
2.70k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
2.70k
        break;
435
436
      /* Handle Black Order. */
437
2.47k
      case SPECIAL_BLACK:
438
2.47k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
2.47k
        pbSrc = pbSrc + 1;
441
442
2.47k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
3
          return FALSE;
444
445
2.47k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
2.47k
        break;
447
448
6.55k
      default:
449
6.55k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
6.55k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
6.55k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
6.55k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
6.55k
        return FALSE;
454
164k
    }
455
164k
  }
456
457
4.66k
  return TRUE;
458
18.6k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
104
6.21k
{
105
6.21k
  const BYTE* pbSrc = pbSrcBuffer;
106
6.21k
  BYTE* pbDest = pbDestBuffer;
107
6.21k
  PIXEL temp = 0;
108
6.21k
  PIXEL fgPel = WHITE_PIXEL;
109
6.21k
  BOOL fInsertFgPel = FALSE;
110
6.21k
  BOOL fFirstLine = TRUE;
111
6.21k
  BYTE bitmask = 0;
112
6.21k
  PIXEL pixelA = 0;
113
6.21k
  PIXEL pixelB = 0;
114
6.21k
  UINT32 runLength = 0;
115
6.21k
  UINT32 code = 0;
116
6.21k
  UINT32 advance = 0;
117
6.21k
  RLEEXTRA
118
119
6.21k
  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.21k
  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.21k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
6.21k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
197k
  while (pbSrc < pbEnd)
138
196k
  {
139
    /* Watch out for the end of the first scanline. */
140
196k
    if (fFirstLine)
141
30.4k
    {
142
30.4k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
4.44k
      {
144
4.44k
        fFirstLine = FALSE;
145
4.44k
        fInsertFgPel = FALSE;
146
4.44k
      }
147
30.4k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
196k
    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
196k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
143k
    {
163
143k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
143k
      if (advance == 0)
165
210
        return FALSE;
166
143k
      pbSrc = pbSrc + advance;
167
168
143k
      if (fFirstLine)
169
13.7k
      {
170
13.7k
        if (fInsertFgPel)
171
9.38k
        {
172
9.38k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
9.38k
          DESTWRITEPIXEL(pbDest, fgPel);
176
9.38k
          runLength = runLength - 1;
177
9.38k
        }
178
179
13.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
32
          return FALSE;
181
182
13.7k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
13.7k
      }
184
129k
      else
185
129k
      {
186
129k
        if (fInsertFgPel)
187
119k
        {
188
119k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
119k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
17
            return FALSE;
192
193
119k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
119k
          runLength--;
195
119k
        }
196
197
129k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
472
          return FALSE;
199
200
129k
        UNROLL(runLength, {
201
129k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
129k
          DESTWRITEPIXEL(pbDest, temp);
203
129k
        });
204
129k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
143k
      fInsertFgPel = TRUE;
208
143k
      continue;
209
143k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
52.1k
    fInsertFgPel = FALSE;
214
215
52.1k
    switch (code)
216
52.1k
    {
217
      /* Handle Foreground Run Orders. */
218
9.03k
      case REGULAR_FG_RUN:
219
9.81k
      case MEGA_MEGA_FG_RUN:
220
16.3k
      case LITE_SET_FG_FG_RUN:
221
16.6k
      case MEGA_MEGA_SET_FG_RUN:
222
16.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
16.6k
        if (advance == 0)
224
30
          return FALSE;
225
16.6k
        pbSrc = pbSrc + advance;
226
227
16.6k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
6.87k
        {
229
6.87k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
85
            return FALSE;
231
6.78k
          SRCREADPIXEL(fgPel, pbSrc);
232
6.78k
        }
233
234
16.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
58
          return FALSE;
236
237
16.5k
        if (fFirstLine)
238
3.83k
        {
239
3.83k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
3.83k
        }
241
12.6k
        else
242
12.6k
        {
243
12.6k
          UNROLL(runLength, {
244
12.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
12.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
12.6k
          });
247
12.6k
        }
248
249
16.5k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
4.23k
      case LITE_DITHERED_RUN:
253
4.83k
      case MEGA_MEGA_DITHERED_RUN:
254
4.83k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
4.83k
        if (advance == 0)
256
18
          return FALSE;
257
4.81k
        pbSrc = pbSrc + advance;
258
4.81k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
139
          return FALSE;
260
4.67k
        SRCREADPIXEL(pixelA, pbSrc);
261
4.67k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
294
          return FALSE;
263
4.38k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
4.38k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
41
          return FALSE;
267
268
4.34k
        UNROLL(runLength, {
269
4.34k
          DESTWRITEPIXEL(pbDest, pixelA);
270
4.34k
          DESTWRITEPIXEL(pbDest, pixelB);
271
4.34k
        });
272
4.34k
        break;
273
274
      /* Handle Color Run Orders. */
275
12.6k
      case REGULAR_COLOR_RUN:
276
13.1k
      case MEGA_MEGA_COLOR_RUN:
277
13.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
13.1k
        if (advance == 0)
279
18
          return FALSE;
280
13.0k
        pbSrc = pbSrc + advance;
281
13.0k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
134
          return FALSE;
283
12.9k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
12.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
79
          return FALSE;
287
288
12.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
12.8k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
4.36k
      case REGULAR_FGBG_IMAGE:
293
5.17k
      case MEGA_MEGA_FGBG_IMAGE:
294
6.76k
      case LITE_SET_FG_FGBG_IMAGE:
295
7.19k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
7.19k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
7.19k
        if (advance == 0)
298
48
          return FALSE;
299
7.14k
        pbSrc = pbSrc + advance;
300
301
7.14k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
1.99k
        {
303
1.99k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
81
            return FALSE;
305
1.91k
          SRCREADPIXEL(fgPel, pbSrc);
306
1.91k
        }
307
308
7.06k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
269
          return FALSE;
310
6.79k
        if (fFirstLine)
311
2.03k
        {
312
11.7k
          while (runLength > 8)
313
9.75k
          {
314
9.75k
            bitmask = *pbSrc;
315
9.75k
            pbSrc = pbSrc + 1;
316
9.75k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
9.75k
            if (!pbDest)
319
6
              return FALSE;
320
321
9.74k
            runLength = runLength - 8;
322
9.74k
          }
323
2.03k
        }
324
4.75k
        else
325
4.75k
        {
326
23.6k
          while (runLength > 8)
327
18.9k
          {
328
18.9k
            bitmask = *pbSrc++;
329
330
18.9k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
18.9k
            if (!pbDest)
333
15
              return FALSE;
334
335
18.9k
            runLength = runLength - 8;
336
18.9k
          }
337
4.75k
        }
338
339
6.77k
        if (runLength > 0)
340
5.71k
        {
341
5.71k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
32
            return FALSE;
343
5.68k
          bitmask = *pbSrc++;
344
345
5.68k
          if (fFirstLine)
346
1.24k
          {
347
1.24k
            pbDest =
348
1.24k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
1.24k
          }
350
4.44k
          else
351
4.44k
          {
352
4.44k
            pbDest =
353
4.44k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
354
4.44k
          }
355
356
5.68k
          if (!pbDest)
357
5
            return FALSE;
358
5.68k
        }
359
360
6.73k
        break;
361
362
      /* Handle Color Image Orders. */
363
6.73k
      case REGULAR_COLOR_IMAGE:
364
3.86k
      case MEGA_MEGA_COLOR_IMAGE:
365
3.86k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
3.86k
        if (advance == 0)
367
16
          return FALSE;
368
3.84k
        pbSrc = pbSrc + advance;
369
3.84k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
35
          return FALSE;
371
3.81k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
379
          return FALSE;
373
374
3.43k
        UNROLL(runLength, {
375
3.43k
          SRCREADPIXEL(temp, pbSrc);
376
3.43k
          DESTWRITEPIXEL(pbDest, temp);
377
3.43k
        });
378
3.43k
        break;
379
380
      /* Handle Special Order 1. */
381
1.46k
      case SPECIAL_FGBG_1:
382
1.46k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
1.46k
        pbSrc = pbSrc + 1;
385
386
1.46k
        if (fFirstLine)
387
127
        {
388
127
          pbDest =
389
127
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
127
        }
391
1.33k
        else
392
1.33k
        {
393
1.33k
          pbDest =
394
1.33k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
1.33k
        }
396
397
1.46k
        if (!pbDest)
398
3
          return FALSE;
399
400
1.46k
        break;
401
402
      /* Handle Special Order 2. */
403
1.46k
      case SPECIAL_FGBG_2:
404
1.16k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
1.16k
        pbSrc = pbSrc + 1;
407
408
1.16k
        if (fFirstLine)
409
91
        {
410
91
          pbDest =
411
91
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
91
        }
413
1.07k
        else
414
1.07k
        {
415
1.07k
          pbDest =
416
1.07k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
1.07k
        }
418
419
1.16k
        if (!pbDest)
420
4
          return FALSE;
421
422
1.16k
        break;
423
424
      /* Handle White Order. */
425
1.16k
      case SPECIAL_WHITE:
426
888
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
888
        pbSrc = pbSrc + 1;
429
430
888
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
2
          return FALSE;
432
433
886
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
886
        break;
435
436
      /* Handle Black Order. */
437
774
      case SPECIAL_BLACK:
438
774
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
774
        pbSrc = pbSrc + 1;
441
442
774
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
1
          return FALSE;
444
445
773
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
773
        break;
447
448
2.15k
      default:
449
2.15k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
2.15k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
2.15k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
2.15k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
2.15k
        return FALSE;
454
52.1k
    }
455
52.1k
  }
456
457
1.53k
  return TRUE;
458
6.21k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
104
12.4k
{
105
12.4k
  const BYTE* pbSrc = pbSrcBuffer;
106
12.4k
  BYTE* pbDest = pbDestBuffer;
107
12.4k
  PIXEL temp = 0;
108
12.4k
  PIXEL fgPel = WHITE_PIXEL;
109
12.4k
  BOOL fInsertFgPel = FALSE;
110
12.4k
  BOOL fFirstLine = TRUE;
111
12.4k
  BYTE bitmask = 0;
112
12.4k
  PIXEL pixelA = 0;
113
12.4k
  PIXEL pixelB = 0;
114
12.4k
  UINT32 runLength = 0;
115
12.4k
  UINT32 code = 0;
116
12.4k
  UINT32 advance = 0;
117
12.4k
  RLEEXTRA
118
119
12.4k
  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.4k
  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.4k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
12.4k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
407k
  while (pbSrc < pbEnd)
138
404k
  {
139
    /* Watch out for the end of the first scanline. */
140
404k
    if (fFirstLine)
141
59.8k
    {
142
59.8k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
9.49k
      {
144
9.49k
        fFirstLine = FALSE;
145
9.49k
        fInsertFgPel = FALSE;
146
9.49k
      }
147
59.8k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
404k
    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
404k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
162
292k
    {
163
292k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
164
292k
      if (advance == 0)
165
530
        return FALSE;
166
291k
      pbSrc = pbSrc + advance;
167
168
291k
      if (fFirstLine)
169
26.9k
      {
170
26.9k
        if (fInsertFgPel)
171
18.9k
        {
172
18.9k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
173
0
            return FALSE;
174
175
18.9k
          DESTWRITEPIXEL(pbDest, fgPel);
176
18.9k
          runLength = runLength - 1;
177
18.9k
        }
178
179
26.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
180
64
          return FALSE;
181
182
26.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
183
26.9k
      }
184
264k
      else
185
264k
      {
186
264k
        if (fInsertFgPel)
187
243k
        {
188
243k
          DESTREADPIXEL(temp, pbDest - rowDelta);
189
190
243k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
191
32
            return FALSE;
192
193
243k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
194
243k
          runLength--;
195
243k
        }
196
197
264k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
198
964
          return FALSE;
199
200
263k
        UNROLL(runLength, {
201
263k
          DESTREADPIXEL(temp, pbDest - rowDelta);
202
263k
          DESTWRITEPIXEL(pbDest, temp);
203
263k
        });
204
263k
      }
205
206
      /* A follow-on background run order will need a foreground pel inserted. */
207
290k
      fInsertFgPel = TRUE;
208
290k
      continue;
209
291k
    }
210
211
    /* For any of the other run-types a follow-on background run
212
        order does not need a foreground pel inserted. */
213
112k
    fInsertFgPel = FALSE;
214
215
112k
    switch (code)
216
112k
    {
217
      /* Handle Foreground Run Orders. */
218
19.2k
      case REGULAR_FG_RUN:
219
20.7k
      case MEGA_MEGA_FG_RUN:
220
33.3k
      case LITE_SET_FG_FG_RUN:
221
33.9k
      case MEGA_MEGA_SET_FG_RUN:
222
33.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
223
33.9k
        if (advance == 0)
224
62
          return FALSE;
225
33.8k
        pbSrc = pbSrc + advance;
226
227
33.8k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
228
13.1k
        {
229
13.1k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
230
134
            return FALSE;
231
12.9k
          SRCREADPIXEL(fgPel, pbSrc);
232
12.9k
        }
233
234
33.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
235
152
          return FALSE;
236
237
33.5k
        if (fFirstLine)
238
7.22k
        {
239
7.22k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
240
7.22k
        }
241
26.3k
        else
242
26.3k
        {
243
26.3k
          UNROLL(runLength, {
244
26.3k
            DESTREADPIXEL(temp, pbDest - rowDelta);
245
26.3k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
246
26.3k
          });
247
26.3k
        }
248
249
33.5k
        break;
250
251
      /* Handle Dithered Run Orders. */
252
9.19k
      case LITE_DITHERED_RUN:
253
10.2k
      case MEGA_MEGA_DITHERED_RUN:
254
10.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
255
10.2k
        if (advance == 0)
256
36
          return FALSE;
257
10.2k
        pbSrc = pbSrc + advance;
258
10.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
259
220
          return FALSE;
260
9.98k
        SRCREADPIXEL(pixelA, pbSrc);
261
9.98k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
262
312
          return FALSE;
263
9.67k
        SRCREADPIXEL(pixelB, pbSrc);
264
265
9.67k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
266
100
          return FALSE;
267
268
9.57k
        UNROLL(runLength, {
269
9.57k
          DESTWRITEPIXEL(pbDest, pixelA);
270
9.57k
          DESTWRITEPIXEL(pbDest, pixelB);
271
9.57k
        });
272
9.57k
        break;
273
274
      /* Handle Color Run Orders. */
275
29.8k
      case REGULAR_COLOR_RUN:
276
30.7k
      case MEGA_MEGA_COLOR_RUN:
277
30.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
278
30.7k
        if (advance == 0)
279
44
          return FALSE;
280
30.7k
        pbSrc = pbSrc + advance;
281
30.7k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
282
200
          return FALSE;
283
30.5k
        SRCREADPIXEL(pixelA, pbSrc);
284
285
30.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
286
158
          return FALSE;
287
288
30.3k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
289
30.3k
        break;
290
291
      /* Handle Foreground/Background Image Orders. */
292
9.54k
      case REGULAR_FGBG_IMAGE:
293
11.2k
      case MEGA_MEGA_FGBG_IMAGE:
294
14.4k
      case LITE_SET_FG_FGBG_IMAGE:
295
15.3k
      case MEGA_MEGA_SET_FGBG_IMAGE:
296
15.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
297
15.3k
        if (advance == 0)
298
92
          return FALSE;
299
15.2k
        pbSrc = pbSrc + advance;
300
301
15.2k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
302
4.08k
        {
303
4.08k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
304
128
            return FALSE;
305
3.95k
          SRCREADPIXEL(fgPel, pbSrc);
306
3.95k
        }
307
308
15.1k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
309
574
          return FALSE;
310
14.5k
        if (fFirstLine)
311
3.52k
        {
312
20.2k
          while (runLength > 8)
313
16.7k
          {
314
16.7k
            bitmask = *pbSrc;
315
16.7k
            pbSrc = pbSrc + 1;
316
16.7k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
317
318
16.7k
            if (!pbDest)
319
16
              return FALSE;
320
321
16.7k
            runLength = runLength - 8;
322
16.7k
          }
323
3.52k
        }
324
11.0k
        else
325
11.0k
        {
326
61.1k
          while (runLength > 8)
327
50.1k
          {
328
50.1k
            bitmask = *pbSrc++;
329
330
50.1k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
331
332
50.1k
            if (!pbDest)
333
44
              return FALSE;
334
335
50.1k
            runLength = runLength - 8;
336
50.1k
          }
337
11.0k
        }
338
339
14.4k
        if (runLength > 0)
340
12.2k
        {
341
12.2k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
342
66
            return FALSE;
343
12.2k
          bitmask = *pbSrc++;
344
345
12.2k
          if (fFirstLine)
346
1.84k
          {
347
1.84k
            pbDest =
348
1.84k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
349
1.84k
          }
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.3k
        break;
361
362
      /* Handle Color Image Orders. */
363
14.3k
      case REGULAR_COLOR_IMAGE:
364
8.94k
      case MEGA_MEGA_COLOR_IMAGE:
365
8.94k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
366
8.94k
        if (advance == 0)
367
38
          return FALSE;
368
8.90k
        pbSrc = pbSrc + advance;
369
8.90k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
370
62
          return FALSE;
371
8.84k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
372
836
          return FALSE;
373
374
8.00k
        UNROLL(runLength, {
375
8.00k
          SRCREADPIXEL(temp, pbSrc);
376
8.00k
          DESTWRITEPIXEL(pbDest, temp);
377
8.00k
        });
378
8.00k
        break;
379
380
      /* Handle Special Order 1. */
381
2.95k
      case SPECIAL_FGBG_1:
382
2.95k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
383
0
          return FALSE;
384
2.95k
        pbSrc = pbSrc + 1;
385
386
2.95k
        if (fFirstLine)
387
262
        {
388
262
          pbDest =
389
262
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
390
262
        }
391
2.69k
        else
392
2.69k
        {
393
2.69k
          pbDest =
394
2.69k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
395
2.69k
        }
396
397
2.95k
        if (!pbDest)
398
10
          return FALSE;
399
400
2.94k
        break;
401
402
      /* Handle Special Order 2. */
403
2.94k
      case SPECIAL_FGBG_2:
404
1.98k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
405
0
          return FALSE;
406
1.98k
        pbSrc = pbSrc + 1;
407
408
1.98k
        if (fFirstLine)
409
174
        {
410
174
          pbDest =
411
174
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
412
174
        }
413
1.81k
        else
414
1.81k
        {
415
1.81k
          pbDest =
416
1.81k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
417
1.81k
        }
418
419
1.98k
        if (!pbDest)
420
12
          return FALSE;
421
422
1.97k
        break;
423
424
      /* Handle White Order. */
425
1.97k
      case SPECIAL_WHITE:
426
1.82k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
427
0
          return FALSE;
428
1.82k
        pbSrc = pbSrc + 1;
429
430
1.82k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
431
4
          return FALSE;
432
433
1.82k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
434
1.82k
        break;
435
436
      /* Handle Black Order. */
437
1.70k
      case SPECIAL_BLACK:
438
1.70k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
439
0
          return FALSE;
440
1.70k
        pbSrc = pbSrc + 1;
441
442
1.70k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
443
2
          return FALSE;
444
445
1.70k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
446
1.70k
        break;
447
448
4.40k
      default:
449
4.40k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
450
4.40k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
451
4.40k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
452
4.40k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
453
4.40k
        return FALSE;
454
112k
    }
455
112k
  }
456
457
3.12k
  return TRUE;
458
12.4k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8