Coverage Report

Created: 2026-03-07 07:03

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
97.8k
{
36
97.8k
  PIXEL xorPixel = 0;
37
97.8k
  BYTE mask = 0x01;
38
39
97.8k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
97.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
103
    return nullptr;
47
48
97.7k
  UNROLL(cBits, {
49
97.7k
    PIXEL data = 0;
50
97.7k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
97.7k
    if (bitmask & mask)
53
97.7k
      data = xorPixel ^ fgPel;
54
97.7k
    else
55
97.7k
      data = xorPixel;
56
57
97.7k
    DESTWRITEPIXEL(pbDest, data);
58
97.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
97.7k
  });
60
97.7k
  return pbDest;
61
97.8k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
35
26.0k
{
36
26.0k
  PIXEL xorPixel = 0;
37
26.0k
  BYTE mask = 0x01;
38
39
26.0k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
26.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
29
    return nullptr;
47
48
26.0k
  UNROLL(cBits, {
49
26.0k
    PIXEL data = 0;
50
26.0k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
26.0k
    if (bitmask & mask)
53
26.0k
      data = xorPixel ^ fgPel;
54
26.0k
    else
55
26.0k
      data = xorPixel;
56
57
26.0k
    DESTWRITEPIXEL(pbDest, data);
58
26.0k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
26.0k
  });
60
26.0k
  return pbDest;
61
26.0k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
35
71.8k
{
36
71.8k
  PIXEL xorPixel = 0;
37
71.8k
  BYTE mask = 0x01;
38
39
71.8k
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
71.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
74
    return nullptr;
47
48
71.7k
  UNROLL(cBits, {
49
71.7k
    PIXEL data = 0;
50
71.7k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
71.7k
    if (bitmask & mask)
53
71.7k
      data = xorPixel ^ fgPel;
54
71.7k
    else
55
71.7k
      data = xorPixel;
56
57
71.7k
    DESTWRITEPIXEL(pbDest, data);
58
71.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
71.7k
  });
60
71.7k
  return pbDest;
61
71.8k
}
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
60.9k
{
72
60.9k
  BYTE mask = 0x01;
73
74
60.9k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
60.9k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
56
    return nullptr;
82
83
60.8k
  UNROLL(cBits, {
84
60.8k
    PIXEL data;
85
86
60.8k
    if (bitmask & mask)
87
60.8k
      data = fgPel;
88
60.8k
    else
89
60.8k
      data = BLACK_PIXEL;
90
91
60.8k
    DESTWRITEPIXEL(pbDest, data);
92
60.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
60.8k
  });
94
60.8k
  return pbDest;
95
60.9k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
71
20.3k
{
72
20.3k
  BYTE mask = 0x01;
73
74
20.3k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
20.3k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
16
    return nullptr;
82
83
20.3k
  UNROLL(cBits, {
84
20.3k
    PIXEL data;
85
86
20.3k
    if (bitmask & mask)
87
20.3k
      data = fgPel;
88
20.3k
    else
89
20.3k
      data = BLACK_PIXEL;
90
91
20.3k
    DESTWRITEPIXEL(pbDest, data);
92
20.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
20.3k
  });
94
20.3k
  return pbDest;
95
20.3k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
71
40.5k
{
72
40.5k
  BYTE mask = 0x01;
73
74
40.5k
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
40.5k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
40
    return nullptr;
82
83
40.5k
  UNROLL(cBits, {
84
40.5k
    PIXEL data;
85
86
40.5k
    if (bitmask & mask)
87
40.5k
      data = fgPel;
88
40.5k
    else
89
40.5k
      data = BLACK_PIXEL;
90
91
40.5k
    DESTWRITEPIXEL(pbDest, data);
92
40.5k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
40.5k
  });
94
40.5k
  return pbDest;
95
40.5k
}
Unexecuted instantiation: interleaved.c:WriteFirstLineFgBgImage8to8
96
97
/**
98
 * Decompress an RLE compressed bitmap.
99
 */
100
WINPR_ATTR_NODISCARD
101
static inline BOOL RLEDECOMPRESS(const BYTE* WINPR_RESTRICT pbSrcBuffer, UINT32 cbSrcBuffer,
102
                                 BYTE* WINPR_RESTRICT pbDestBuffer, UINT32 rowDelta, UINT32 width,
103
                                 UINT32 height)
104
17.1k
{
105
17.1k
  const BYTE* pbSrc = pbSrcBuffer;
106
17.1k
  BYTE* pbDest = pbDestBuffer;
107
17.1k
  PIXEL temp = 0;
108
17.1k
  PIXEL fgPel = WHITE_PIXEL;
109
17.1k
  BOOL fInsertFgPel = FALSE;
110
17.1k
  BOOL fFirstLine = TRUE;
111
17.1k
  BYTE bitmask = 0;
112
17.1k
  PIXEL pixelA = 0;
113
17.1k
  PIXEL pixelB = 0;
114
17.1k
  UINT32 runLength = 0;
115
17.1k
  UINT32 code = 0;
116
17.1k
  UINT32 advance = 0;
117
17.1k
  RLEEXTRA
118
119
17.1k
  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.1k
  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.1k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
17.1k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
510k
  while (pbSrc < pbEnd)
138
505k
  {
139
    /* Watch out for the end of the first scanline. */
140
505k
    if (fFirstLine)
141
83.6k
    {
142
83.6k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
12.5k
      {
144
12.5k
        fFirstLine = FALSE;
145
12.5k
        fInsertFgPel = FALSE;
146
12.5k
      }
147
83.6k
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
505k
    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
505k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
359k
    {
162
359k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
359k
      if (advance == 0)
164
615
        return FALSE;
165
359k
      pbSrc = pbSrc + advance;
166
167
359k
      if (fFirstLine)
168
36.5k
      {
169
36.5k
        if (fInsertFgPel)
170
25.5k
        {
171
25.5k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
25.5k
          DESTWRITEPIXEL(pbDest, fgPel);
175
25.5k
          runLength = runLength - 1;
176
25.5k
        }
177
178
36.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
68
          return FALSE;
180
181
36.4k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
36.4k
      }
183
322k
      else
184
322k
      {
185
322k
        if (fInsertFgPel)
186
294k
        {
187
294k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
294k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
46
            return FALSE;
191
192
294k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
294k
          runLength--;
194
294k
        }
195
196
322k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
1.04k
          return FALSE;
198
199
321k
        UNROLL(runLength, {
200
321k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
321k
          DESTWRITEPIXEL(pbDest, temp);
202
321k
        });
203
321k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
358k
      fInsertFgPel = TRUE;
207
358k
      continue;
208
359k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
145k
    fInsertFgPel = FALSE;
213
214
145k
    switch (code)
215
145k
    {
216
      /* Handle Foreground Run Orders. */
217
26.7k
      case REGULAR_FG_RUN:
218
28.5k
      case MEGA_MEGA_FG_RUN:
219
46.2k
      case LITE_SET_FG_FG_RUN:
220
47.1k
      case MEGA_MEGA_SET_FG_RUN:
221
47.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
47.1k
        if (advance == 0)
223
89
          return FALSE;
224
47.0k
        pbSrc = pbSrc + advance;
225
226
47.0k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
18.5k
        {
228
18.5k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
225
            return FALSE;
230
18.3k
          SRCREADPIXEL(fgPel, pbSrc);
231
18.3k
        }
232
233
46.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
304
          return FALSE;
235
236
46.5k
        if (fFirstLine)
237
10.9k
        {
238
10.9k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
10.9k
        }
240
35.6k
        else
241
35.6k
        {
242
35.6k
          UNROLL(runLength, {
243
35.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
35.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
35.6k
          });
246
35.6k
        }
247
248
46.5k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
12.2k
      case LITE_DITHERED_RUN:
252
13.4k
      case MEGA_MEGA_DITHERED_RUN:
253
13.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
13.4k
        if (advance == 0)
255
47
          return FALSE;
256
13.4k
        pbSrc = pbSrc + advance;
257
13.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
280
          return FALSE;
259
13.1k
        SRCREADPIXEL(pixelA, pbSrc);
260
13.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
512
          return FALSE;
262
12.6k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
12.6k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
158
          return FALSE;
266
267
12.4k
        UNROLL(runLength, {
268
12.4k
          DESTWRITEPIXEL(pbDest, pixelA);
269
12.4k
          DESTWRITEPIXEL(pbDest, pixelB);
270
12.4k
        });
271
12.4k
        break;
272
273
      /* Handle Color Run Orders. */
274
19.9k
      case REGULAR_COLOR_RUN:
275
21.2k
      case MEGA_MEGA_COLOR_RUN:
276
21.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
21.2k
        if (advance == 0)
278
53
          return FALSE;
279
21.1k
        pbSrc = pbSrc + advance;
280
21.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
309
          return FALSE;
282
20.8k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
20.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
218
          return FALSE;
286
287
20.6k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
20.6k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
14.8k
      case REGULAR_FGBG_IMAGE:
292
16.9k
      case MEGA_MEGA_FGBG_IMAGE:
293
20.7k
      case LITE_SET_FG_FGBG_IMAGE:
294
21.6k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
21.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
21.6k
        if (advance == 0)
297
132
          return FALSE;
298
21.5k
        pbSrc = pbSrc + advance;
299
300
21.5k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
4.68k
        {
302
4.68k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
174
            return FALSE;
304
4.51k
          SRCREADPIXEL(fgPel, pbSrc);
305
4.51k
        }
306
307
21.3k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
848
          return FALSE;
309
20.5k
        if (fFirstLine)
310
5.21k
        {
311
62.5k
          while (runLength > 8)
312
57.3k
          {
313
57.3k
            bitmask = *pbSrc;
314
57.3k
            pbSrc = pbSrc + 1;
315
57.3k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
57.3k
            if (!pbDest)
318
53
              return FALSE;
319
320
57.2k
            runLength = runLength - 8;
321
57.2k
          }
322
5.21k
        }
323
15.3k
        else
324
15.3k
        {
325
93.3k
          while (runLength > 8)
326
78.0k
          {
327
78.0k
            bitmask = *pbSrc++;
328
329
78.0k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
78.0k
            if (!pbDest)
332
84
              return FALSE;
333
334
78.0k
            runLength = runLength - 8;
335
78.0k
          }
336
15.3k
        }
337
338
20.4k
        if (runLength > 0)
339
17.8k
        {
340
17.8k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
88
            return FALSE;
342
17.7k
          bitmask = *pbSrc++;
343
344
17.7k
          if (fFirstLine)
345
2.99k
          {
346
2.99k
            pbDest =
347
2.99k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
2.99k
          }
349
14.7k
          else
350
14.7k
          {
351
14.7k
            pbDest =
352
14.7k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
14.7k
          }
354
355
17.7k
          if (!pbDest)
356
14
            return FALSE;
357
17.7k
        }
358
359
20.3k
        break;
360
361
      /* Handle Color Image Orders. */
362
21.2k
      case REGULAR_COLOR_IMAGE:
363
23.6k
      case MEGA_MEGA_COLOR_IMAGE:
364
23.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
23.6k
        if (advance == 0)
366
72
          return FALSE;
367
23.5k
        pbSrc = pbSrc + advance;
368
23.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
100
          return FALSE;
370
23.4k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
1.02k
          return FALSE;
372
373
22.4k
        UNROLL(runLength, {
374
22.4k
          SRCREADPIXEL(temp, pbSrc);
375
22.4k
          DESTWRITEPIXEL(pbDest, temp);
376
22.4k
        });
377
22.4k
        break;
378
379
      /* Handle Special Order 1. */
380
2.54k
      case SPECIAL_FGBG_1:
381
2.54k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
2.54k
        pbSrc = pbSrc + 1;
384
385
2.54k
        if (fFirstLine)
386
334
        {
387
334
          pbDest =
388
334
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
334
        }
390
2.20k
        else
391
2.20k
        {
392
2.20k
          pbDest =
393
2.20k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
2.20k
        }
395
396
2.54k
        if (!pbDest)
397
3
          return FALSE;
398
399
2.53k
        break;
400
401
      /* Handle Special Order 2. */
402
3.08k
      case SPECIAL_FGBG_2:
403
3.08k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
3.08k
        pbSrc = pbSrc + 1;
406
407
3.08k
        if (fFirstLine)
408
266
        {
409
266
          pbDest =
410
266
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
266
        }
412
2.81k
        else
413
2.81k
        {
414
2.81k
          pbDest =
415
2.81k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
2.81k
        }
417
418
3.08k
        if (!pbDest)
419
5
          return FALSE;
420
421
3.08k
        break;
422
423
      /* Handle White Order. */
424
3.69k
      case SPECIAL_WHITE:
425
3.69k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
3.69k
        pbSrc = pbSrc + 1;
428
429
3.69k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
3
          return FALSE;
431
432
3.68k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
3.68k
        break;
434
435
      /* Handle Black Order. */
436
3.07k
      case SPECIAL_BLACK:
437
3.07k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
3.07k
        pbSrc = pbSrc + 1;
440
441
3.07k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
3
          return FALSE;
443
444
3.07k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
3.07k
        break;
446
447
6.19k
      default:
448
6.19k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
6.19k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
6.19k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
6.19k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
6.19k
        return FALSE;
453
145k
    }
454
145k
  }
455
456
4.42k
  return TRUE;
457
17.1k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
104
5.73k
{
105
5.73k
  const BYTE* pbSrc = pbSrcBuffer;
106
5.73k
  BYTE* pbDest = pbDestBuffer;
107
5.73k
  PIXEL temp = 0;
108
5.73k
  PIXEL fgPel = WHITE_PIXEL;
109
5.73k
  BOOL fInsertFgPel = FALSE;
110
5.73k
  BOOL fFirstLine = TRUE;
111
5.73k
  BYTE bitmask = 0;
112
5.73k
  PIXEL pixelA = 0;
113
5.73k
  PIXEL pixelB = 0;
114
5.73k
  UINT32 runLength = 0;
115
5.73k
  UINT32 code = 0;
116
5.73k
  UINT32 advance = 0;
117
5.73k
  RLEEXTRA
118
119
5.73k
  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.73k
  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.73k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
5.73k
  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.0k
    {
142
28.0k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
3.98k
      {
144
3.98k
        fFirstLine = FALSE;
145
3.98k
        fInsertFgPel = FALSE;
146
3.98k
      }
147
28.0k
    }
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
117k
    {
162
117k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
117k
      if (advance == 0)
164
161
        return FALSE;
165
117k
      pbSrc = pbSrc + advance;
166
167
117k
      if (fFirstLine)
168
12.3k
      {
169
12.3k
        if (fInsertFgPel)
170
8.45k
        {
171
8.45k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
8.45k
          DESTWRITEPIXEL(pbDest, fgPel);
175
8.45k
          runLength = runLength - 1;
176
8.45k
        }
177
178
12.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
24
          return FALSE;
180
181
12.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
12.2k
      }
183
104k
      else
184
104k
      {
185
104k
        if (fInsertFgPel)
186
96.1k
        {
187
96.1k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
96.1k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
18
            return FALSE;
191
192
96.1k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
96.1k
          runLength--;
194
96.1k
        }
195
196
104k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
327
          return FALSE;
198
199
104k
        UNROLL(runLength, {
200
104k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
104k
          DESTWRITEPIXEL(pbDest, temp);
202
104k
        });
203
104k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
116k
      fInsertFgPel = TRUE;
207
116k
      continue;
208
117k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
46.8k
    fInsertFgPel = FALSE;
213
214
46.8k
    switch (code)
215
46.8k
    {
216
      /* Handle Foreground Run Orders. */
217
8.35k
      case REGULAR_FG_RUN:
218
8.96k
      case MEGA_MEGA_FG_RUN:
219
14.7k
      case LITE_SET_FG_FG_RUN:
220
15.1k
      case MEGA_MEGA_SET_FG_RUN:
221
15.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
15.1k
        if (advance == 0)
223
27
          return FALSE;
224
15.1k
        pbSrc = pbSrc + advance;
225
226
15.1k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
6.15k
        {
228
6.15k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
89
            return FALSE;
230
6.06k
          SRCREADPIXEL(fgPel, pbSrc);
231
6.06k
        }
232
233
15.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
88
          return FALSE;
235
236
14.9k
        if (fFirstLine)
237
3.75k
        {
238
3.75k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
3.75k
        }
240
11.1k
        else
241
11.1k
        {
242
11.1k
          UNROLL(runLength, {
243
11.1k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
11.1k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
11.1k
          });
246
11.1k
        }
247
248
14.9k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
4.04k
      case LITE_DITHERED_RUN:
252
4.43k
      case MEGA_MEGA_DITHERED_RUN:
253
4.43k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
4.43k
        if (advance == 0)
255
13
          return FALSE;
256
4.42k
        pbSrc = pbSrc + advance;
257
4.42k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
122
          return FALSE;
259
4.30k
        SRCREADPIXEL(pixelA, pbSrc);
260
4.30k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
244
          return FALSE;
262
4.05k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
4.05k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
48
          return FALSE;
266
267
4.01k
        UNROLL(runLength, {
268
4.01k
          DESTWRITEPIXEL(pbDest, pixelA);
269
4.01k
          DESTWRITEPIXEL(pbDest, pixelB);
270
4.01k
        });
271
4.01k
        break;
272
273
      /* Handle Color Run Orders. */
274
7.17k
      case REGULAR_COLOR_RUN:
275
7.60k
      case MEGA_MEGA_COLOR_RUN:
276
7.60k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
7.60k
        if (advance == 0)
278
15
          return FALSE;
279
7.58k
        pbSrc = pbSrc + advance;
280
7.58k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
117
          return FALSE;
282
7.47k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
7.47k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
90
          return FALSE;
286
287
7.38k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
7.38k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
4.51k
      case REGULAR_FGBG_IMAGE:
292
5.22k
      case MEGA_MEGA_FGBG_IMAGE:
293
6.43k
      case LITE_SET_FG_FGBG_IMAGE:
294
6.71k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
6.71k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
6.71k
        if (advance == 0)
297
38
          return FALSE;
298
6.67k
        pbSrc = pbSrc + advance;
299
300
6.67k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
1.47k
        {
302
1.47k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
58
            return FALSE;
304
1.41k
          SRCREADPIXEL(fgPel, pbSrc);
305
1.41k
        }
306
307
6.62k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
260
          return FALSE;
309
6.36k
        if (fFirstLine)
310
1.87k
        {
311
20.8k
          while (runLength > 8)
312
19.0k
          {
313
19.0k
            bitmask = *pbSrc;
314
19.0k
            pbSrc = pbSrc + 1;
315
19.0k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
19.0k
            if (!pbDest)
318
15
              return FALSE;
319
320
19.0k
            runLength = runLength - 8;
321
19.0k
          }
322
1.87k
        }
323
4.48k
        else
324
4.48k
        {
325
24.5k
          while (runLength > 8)
326
20.0k
          {
327
20.0k
            bitmask = *pbSrc++;
328
329
20.0k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
20.0k
            if (!pbDest)
332
20
              return FALSE;
333
334
20.0k
            runLength = runLength - 8;
335
20.0k
          }
336
4.48k
        }
337
338
6.32k
        if (runLength > 0)
339
5.51k
        {
340
5.51k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
32
            return FALSE;
342
5.48k
          bitmask = *pbSrc++;
343
344
5.48k
          if (fFirstLine)
345
1.16k
          {
346
1.16k
            pbDest =
347
1.16k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1.16k
          }
349
4.31k
          else
350
4.31k
          {
351
4.31k
            pbDest =
352
4.31k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
4.31k
          }
354
355
5.48k
          if (!pbDest)
356
8
            return FALSE;
357
5.48k
        }
358
359
6.28k
        break;
360
361
      /* Handle Color Image Orders. */
362
6.28k
      case REGULAR_COLOR_IMAGE:
363
6.84k
      case MEGA_MEGA_COLOR_IMAGE:
364
6.84k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
6.84k
        if (advance == 0)
366
24
          return FALSE;
367
6.82k
        pbSrc = pbSrc + advance;
368
6.82k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
40
          return FALSE;
370
6.78k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
328
          return FALSE;
372
373
6.45k
        UNROLL(runLength, {
374
6.45k
          SRCREADPIXEL(temp, pbSrc);
375
6.45k
          DESTWRITEPIXEL(pbDest, temp);
376
6.45k
        });
377
6.45k
        break;
378
379
      /* Handle Special Order 1. */
380
805
      case SPECIAL_FGBG_1:
381
805
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
805
        pbSrc = pbSrc + 1;
384
385
805
        if (fFirstLine)
386
108
        {
387
108
          pbDest =
388
108
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
108
        }
390
697
        else
391
697
        {
392
697
          pbDest =
393
697
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
697
        }
395
396
805
        if (!pbDest)
397
1
          return FALSE;
398
399
804
        break;
400
401
      /* Handle Special Order 2. */
402
1.03k
      case SPECIAL_FGBG_2:
403
1.03k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
1.03k
        pbSrc = pbSrc + 1;
406
407
1.03k
        if (fFirstLine)
408
92
        {
409
92
          pbDest =
410
92
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
92
        }
412
939
        else
413
939
        {
414
939
          pbDest =
415
939
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
939
        }
417
418
1.03k
        if (!pbDest)
419
1
          return FALSE;
420
421
1.03k
        break;
422
423
      /* Handle White Order. */
424
1.21k
      case SPECIAL_WHITE:
425
1.21k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
1.21k
        pbSrc = pbSrc + 1;
428
429
1.21k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
1
          return FALSE;
431
432
1.21k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
1.21k
        break;
434
435
      /* Handle Black Order. */
436
1.02k
      case SPECIAL_BLACK:
437
1.02k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
1.02k
        pbSrc = pbSrc + 1;
440
441
1.02k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
1
          return FALSE;
443
444
1.02k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
1.02k
        break;
446
447
2.03k
      default:
448
2.03k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
2.03k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
2.03k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
2.03k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
2.03k
        return FALSE;
453
46.8k
    }
454
46.8k
  }
455
456
1.48k
  return TRUE;
457
5.73k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
104
11.4k
{
105
11.4k
  const BYTE* pbSrc = pbSrcBuffer;
106
11.4k
  BYTE* pbDest = pbDestBuffer;
107
11.4k
  PIXEL temp = 0;
108
11.4k
  PIXEL fgPel = WHITE_PIXEL;
109
11.4k
  BOOL fInsertFgPel = FALSE;
110
11.4k
  BOOL fFirstLine = TRUE;
111
11.4k
  BYTE bitmask = 0;
112
11.4k
  PIXEL pixelA = 0;
113
11.4k
  PIXEL pixelB = 0;
114
11.4k
  UINT32 runLength = 0;
115
11.4k
  UINT32 code = 0;
116
11.4k
  UINT32 advance = 0;
117
11.4k
  RLEEXTRA
118
119
11.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
11.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
11.4k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
11.4k
  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
55.5k
    {
142
55.5k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
8.59k
      {
144
8.59k
        fFirstLine = FALSE;
145
8.59k
        fInsertFgPel = FALSE;
146
8.59k
      }
147
55.5k
    }
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
242k
    {
162
242k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
242k
      if (advance == 0)
164
454
        return FALSE;
165
242k
      pbSrc = pbSrc + advance;
166
167
242k
      if (fFirstLine)
168
24.2k
      {
169
24.2k
        if (fInsertFgPel)
170
17.0k
        {
171
17.0k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
17.0k
          DESTWRITEPIXEL(pbDest, fgPel);
175
17.0k
          runLength = runLength - 1;
176
17.0k
        }
177
178
24.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
44
          return FALSE;
180
181
24.1k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
24.1k
      }
183
217k
      else
184
217k
      {
185
217k
        if (fInsertFgPel)
186
198k
        {
187
198k
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
198k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
28
            return FALSE;
191
192
197k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
197k
          runLength--;
194
197k
        }
195
196
217k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
716
          return FALSE;
198
199
217k
        UNROLL(runLength, {
200
217k
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
217k
          DESTWRITEPIXEL(pbDest, temp);
202
217k
        });
203
217k
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
241k
      fInsertFgPel = TRUE;
207
241k
      continue;
208
242k
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
98.9k
    fInsertFgPel = FALSE;
213
214
98.9k
    switch (code)
215
98.9k
    {
216
      /* Handle Foreground Run Orders. */
217
18.3k
      case REGULAR_FG_RUN:
218
19.6k
      case MEGA_MEGA_FG_RUN:
219
31.4k
      case LITE_SET_FG_FG_RUN:
220
32.0k
      case MEGA_MEGA_SET_FG_RUN:
221
32.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
32.0k
        if (advance == 0)
223
62
          return FALSE;
224
31.9k
        pbSrc = pbSrc + advance;
225
226
31.9k
        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
136
            return FALSE;
230
12.2k
          SRCREADPIXEL(fgPel, pbSrc);
231
12.2k
        }
232
233
31.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
216
          return FALSE;
235
236
31.6k
        if (fFirstLine)
237
7.15k
        {
238
7.15k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
7.15k
        }
240
24.4k
        else
241
24.4k
        {
242
24.4k
          UNROLL(runLength, {
243
24.4k
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
24.4k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
24.4k
          });
246
24.4k
        }
247
248
31.6k
        break;
249
250
      /* Handle Dithered Run Orders. */
251
8.24k
      case LITE_DITHERED_RUN:
252
9.02k
      case MEGA_MEGA_DITHERED_RUN:
253
9.02k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
9.02k
        if (advance == 0)
255
34
          return FALSE;
256
8.99k
        pbSrc = pbSrc + advance;
257
8.99k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
158
          return FALSE;
259
8.83k
        SRCREADPIXEL(pixelA, pbSrc);
260
8.83k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
268
          return FALSE;
262
8.56k
        SRCREADPIXEL(pixelB, pbSrc);
263
264
8.56k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
110
          return FALSE;
266
267
8.45k
        UNROLL(runLength, {
268
8.45k
          DESTWRITEPIXEL(pbDest, pixelA);
269
8.45k
          DESTWRITEPIXEL(pbDest, pixelB);
270
8.45k
        });
271
8.45k
        break;
272
273
      /* Handle Color Run Orders. */
274
12.7k
      case REGULAR_COLOR_RUN:
275
13.6k
      case MEGA_MEGA_COLOR_RUN:
276
13.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
13.6k
        if (advance == 0)
278
38
          return FALSE;
279
13.5k
        pbSrc = pbSrc + advance;
280
13.5k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
192
          return FALSE;
282
13.3k
        SRCREADPIXEL(pixelA, pbSrc);
283
284
13.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
128
          return FALSE;
286
287
13.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
13.2k
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
10.2k
      case REGULAR_FGBG_IMAGE:
292
11.7k
      case MEGA_MEGA_FGBG_IMAGE:
293
14.2k
      case LITE_SET_FG_FGBG_IMAGE:
294
14.9k
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
14.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
14.9k
        if (advance == 0)
297
94
          return FALSE;
298
14.8k
        pbSrc = pbSrc + advance;
299
300
14.8k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
3.21k
        {
302
3.21k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
116
            return FALSE;
304
3.09k
          SRCREADPIXEL(fgPel, pbSrc);
305
3.09k
        }
306
307
14.7k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
588
          return FALSE;
309
14.1k
        if (fFirstLine)
310
3.34k
        {
311
41.6k
          while (runLength > 8)
312
38.3k
          {
313
38.3k
            bitmask = *pbSrc;
314
38.3k
            pbSrc = pbSrc + 1;
315
38.3k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
38.3k
            if (!pbDest)
318
38
              return FALSE;
319
320
38.2k
            runLength = runLength - 8;
321
38.2k
          }
322
3.34k
        }
323
10.8k
        else
324
10.8k
        {
325
68.7k
          while (runLength > 8)
326
58.0k
          {
327
58.0k
            bitmask = *pbSrc++;
328
329
58.0k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
58.0k
            if (!pbDest)
332
64
              return FALSE;
333
334
57.9k
            runLength = runLength - 8;
335
57.9k
          }
336
10.8k
        }
337
338
14.0k
        if (runLength > 0)
339
12.2k
        {
340
12.2k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
56
            return FALSE;
342
12.2k
          bitmask = *pbSrc++;
343
344
12.2k
          if (fFirstLine)
345
1.83k
          {
346
1.83k
            pbDest =
347
1.83k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1.83k
          }
349
10.4k
          else
350
10.4k
          {
351
10.4k
            pbDest =
352
10.4k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
10.4k
          }
354
355
12.2k
          if (!pbDest)
356
6
            return FALSE;
357
12.2k
        }
358
359
14.0k
        break;
360
361
      /* Handle Color Image Orders. */
362
15.2k
      case REGULAR_COLOR_IMAGE:
363
16.7k
      case MEGA_MEGA_COLOR_IMAGE:
364
16.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
16.7k
        if (advance == 0)
366
48
          return FALSE;
367
16.7k
        pbSrc = pbSrc + advance;
368
16.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
60
          return FALSE;
370
16.6k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
696
          return FALSE;
372
373
15.9k
        UNROLL(runLength, {
374
15.9k
          SRCREADPIXEL(temp, pbSrc);
375
15.9k
          DESTWRITEPIXEL(pbDest, temp);
376
15.9k
        });
377
15.9k
        break;
378
379
      /* Handle Special Order 1. */
380
1.73k
      case SPECIAL_FGBG_1:
381
1.73k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
1.73k
        pbSrc = pbSrc + 1;
384
385
1.73k
        if (fFirstLine)
386
226
        {
387
226
          pbDest =
388
226
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
226
        }
390
1.51k
        else
391
1.51k
        {
392
1.51k
          pbDest =
393
1.51k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
1.51k
        }
395
396
1.73k
        if (!pbDest)
397
2
          return FALSE;
398
399
1.73k
        break;
400
401
      /* Handle Special Order 2. */
402
2.05k
      case SPECIAL_FGBG_2:
403
2.05k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
2.05k
        pbSrc = pbSrc + 1;
406
407
2.05k
        if (fFirstLine)
408
174
        {
409
174
          pbDest =
410
174
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
174
        }
412
1.88k
        else
413
1.88k
        {
414
1.88k
          pbDest =
415
1.88k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
1.88k
        }
417
418
2.05k
        if (!pbDest)
419
4
          return FALSE;
420
421
2.05k
        break;
422
423
      /* Handle White Order. */
424
2.47k
      case SPECIAL_WHITE:
425
2.47k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
2.47k
        pbSrc = pbSrc + 1;
428
429
2.47k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
2
          return FALSE;
431
432
2.47k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
2.47k
        break;
434
435
      /* Handle Black Order. */
436
2.04k
      case SPECIAL_BLACK:
437
2.04k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
2.04k
        pbSrc = pbSrc + 1;
440
441
2.04k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
2
          return FALSE;
443
444
2.04k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
2.04k
        break;
446
447
4.16k
      default:
448
4.16k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
4.16k
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
4.16k
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
4.16k
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
4.16k
        return FALSE;
453
98.9k
    }
454
98.9k
  }
455
456
2.94k
  return TRUE;
457
11.4k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8