Coverage Report

Created: 2026-06-15 06:57

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
731
{
36
731
  PIXEL xorPixel = 0;
37
731
  BYTE mask = 0x01;
38
39
731
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
731
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
3
    return nullptr;
47
48
728
  UNROLL(cBits, {
49
728
    PIXEL data = 0;
50
728
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
728
    if (bitmask & mask)
53
728
      data = xorPixel ^ fgPel;
54
728
    else
55
728
      data = xorPixel;
56
57
728
    DESTWRITEPIXEL(pbDest, data);
58
728
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
728
  });
60
728
  return pbDest;
61
731
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
35
249
{
36
249
  PIXEL xorPixel = 0;
37
249
  BYTE mask = 0x01;
38
39
249
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
249
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
1
    return nullptr;
47
48
248
  UNROLL(cBits, {
49
248
    PIXEL data = 0;
50
248
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
248
    if (bitmask & mask)
53
248
      data = xorPixel ^ fgPel;
54
248
    else
55
248
      data = xorPixel;
56
57
248
    DESTWRITEPIXEL(pbDest, data);
58
248
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
248
  });
60
248
  return pbDest;
61
249
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
35
482
{
36
482
  PIXEL xorPixel = 0;
37
482
  BYTE mask = 0x01;
38
39
482
  if (cBits > 8)
40
0
  {
41
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
42
0
    return nullptr;
43
0
  }
44
45
482
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
46
2
    return nullptr;
47
48
480
  UNROLL(cBits, {
49
480
    PIXEL data = 0;
50
480
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
51
52
480
    if (bitmask & mask)
53
480
      data = xorPixel ^ fgPel;
54
480
    else
55
480
      data = xorPixel;
56
57
480
    DESTWRITEPIXEL(pbDest, data);
58
480
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
59
480
  });
60
480
  return pbDest;
61
482
}
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
48
{
72
48
  BYTE mask = 0x01;
73
74
48
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
48
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
0
    return nullptr;
82
83
48
  UNROLL(cBits, {
84
48
    PIXEL data;
85
86
48
    if (bitmask & mask)
87
48
      data = fgPel;
88
48
    else
89
48
      data = BLACK_PIXEL;
90
91
48
    DESTWRITEPIXEL(pbDest, data);
92
48
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
48
  });
94
48
  return pbDest;
95
48
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
71
16
{
72
16
  BYTE mask = 0x01;
73
74
16
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
16
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
0
    return nullptr;
82
83
16
  UNROLL(cBits, {
84
16
    PIXEL data;
85
86
16
    if (bitmask & mask)
87
16
      data = fgPel;
88
16
    else
89
16
      data = BLACK_PIXEL;
90
91
16
    DESTWRITEPIXEL(pbDest, data);
92
16
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
16
  });
94
16
  return pbDest;
95
16
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
71
32
{
72
32
  BYTE mask = 0x01;
73
74
32
  if (cBits > 8)
75
0
  {
76
0
    WLog_ERR(TAG, "cBits %" PRIu32 " > 8", cBits);
77
0
    return nullptr;
78
0
  }
79
80
32
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
81
0
    return nullptr;
82
83
32
  UNROLL(cBits, {
84
32
    PIXEL data;
85
86
32
    if (bitmask & mask)
87
32
      data = fgPel;
88
32
    else
89
32
      data = BLACK_PIXEL;
90
91
32
    DESTWRITEPIXEL(pbDest, data);
92
32
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
93
32
  });
94
32
  return pbDest;
95
32
}
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
3
{
105
3
  const BYTE* pbSrc = pbSrcBuffer;
106
3
  BYTE* pbDest = pbDestBuffer;
107
3
  PIXEL temp = 0;
108
3
  PIXEL fgPel = WHITE_PIXEL;
109
3
  BOOL fInsertFgPel = FALSE;
110
3
  BOOL fFirstLine = TRUE;
111
3
  BYTE bitmask = 0;
112
3
  PIXEL pixelA = 0;
113
3
  PIXEL pixelB = 0;
114
3
  UINT32 runLength = 0;
115
3
  UINT32 code = 0;
116
3
  UINT32 advance = 0;
117
3
  RLEEXTRA
118
119
3
  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
3
  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
3
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
3
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
290
  while (pbSrc < pbEnd)
138
290
  {
139
    /* Watch out for the end of the first scanline. */
140
290
    if (fFirstLine)
141
9
    {
142
9
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
3
      {
144
3
        fFirstLine = FALSE;
145
3
        fInsertFgPel = FALSE;
146
3
      }
147
9
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
290
    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
290
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
0
    {
162
0
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
0
      if (advance == 0)
164
0
        return FALSE;
165
0
      pbSrc = pbSrc + advance;
166
167
0
      if (fFirstLine)
168
0
      {
169
0
        if (fInsertFgPel)
170
0
        {
171
0
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
0
          DESTWRITEPIXEL(pbDest, fgPel);
175
0
          runLength = runLength - 1;
176
0
        }
177
178
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
0
          return FALSE;
180
181
0
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
0
      }
183
0
      else
184
0
      {
185
0
        if (fInsertFgPel)
186
0
        {
187
0
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
0
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
0
            return FALSE;
191
192
0
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
0
          runLength--;
194
0
        }
195
196
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
0
          return FALSE;
198
199
0
        UNROLL(runLength, {
200
0
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
0
          DESTWRITEPIXEL(pbDest, temp);
202
0
        });
203
0
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
0
      fInsertFgPel = TRUE;
207
0
      continue;
208
0
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
290
    fInsertFgPel = FALSE;
213
214
290
    switch (code)
215
290
    {
216
      /* Handle Foreground Run Orders. */
217
178
      case REGULAR_FG_RUN:
218
178
      case MEGA_MEGA_FG_RUN:
219
181
      case LITE_SET_FG_FG_RUN:
220
181
      case MEGA_MEGA_SET_FG_RUN:
221
181
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
181
        if (advance == 0)
223
0
          return FALSE;
224
181
        pbSrc = pbSrc + advance;
225
226
181
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
3
        {
228
3
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
0
            return FALSE;
230
3
          SRCREADPIXEL(fgPel, pbSrc);
231
3
        }
232
233
181
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
0
          return FALSE;
235
236
181
        if (fFirstLine)
237
3
        {
238
3
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
3
        }
240
178
        else
241
178
        {
242
178
          UNROLL(runLength, {
243
178
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
178
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
178
          });
246
178
        }
247
248
181
        break;
249
250
      /* Handle Dithered Run Orders. */
251
0
      case LITE_DITHERED_RUN:
252
0
      case MEGA_MEGA_DITHERED_RUN:
253
0
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
0
        if (advance == 0)
255
0
          return FALSE;
256
0
        pbSrc = pbSrc + advance;
257
0
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
0
          return FALSE;
259
0
        SRCREADPIXEL(pixelA, pbSrc);
260
0
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
0
          return FALSE;
262
0
        SRCREADPIXEL(pixelB, pbSrc);
263
264
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
0
          return FALSE;
266
267
0
        UNROLL(runLength, {
268
0
          DESTWRITEPIXEL(pbDest, pixelA);
269
0
          DESTWRITEPIXEL(pbDest, pixelB);
270
0
        });
271
0
        break;
272
273
      /* Handle Color Run Orders. */
274
35
      case REGULAR_COLOR_RUN:
275
35
      case MEGA_MEGA_COLOR_RUN:
276
35
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
35
        if (advance == 0)
278
0
          return FALSE;
279
35
        pbSrc = pbSrc + advance;
280
35
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
0
          return FALSE;
282
35
        SRCREADPIXEL(pixelA, pbSrc);
283
284
35
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
0
          return FALSE;
286
287
35
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
35
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
72
      case REGULAR_FGBG_IMAGE:
292
72
      case MEGA_MEGA_FGBG_IMAGE:
293
74
      case LITE_SET_FG_FGBG_IMAGE:
294
74
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
74
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
74
        if (advance == 0)
297
0
          return FALSE;
298
74
        pbSrc = pbSrc + advance;
299
300
74
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
2
        {
302
2
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
0
            return FALSE;
304
2
          SRCREADPIXEL(fgPel, pbSrc);
305
2
        }
306
307
74
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
0
          return FALSE;
309
74
        if (fFirstLine)
310
3
        {
311
48
          while (runLength > 8)
312
45
          {
313
45
            bitmask = *pbSrc;
314
45
            pbSrc = pbSrc + 1;
315
45
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
45
            if (!pbDest)
318
0
              return FALSE;
319
320
45
            runLength = runLength - 8;
321
45
          }
322
3
        }
323
71
        else
324
71
        {
325
731
          while (runLength > 8)
326
663
          {
327
663
            bitmask = *pbSrc++;
328
329
663
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
663
            if (!pbDest)
332
3
              return FALSE;
333
334
660
            runLength = runLength - 8;
335
660
          }
336
71
        }
337
338
71
        if (runLength > 0)
339
71
        {
340
71
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
0
            return FALSE;
342
71
          bitmask = *pbSrc++;
343
344
71
          if (fFirstLine)
345
3
          {
346
3
            pbDest =
347
3
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
3
          }
349
68
          else
350
68
          {
351
68
            pbDest =
352
68
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
68
          }
354
355
71
          if (!pbDest)
356
0
            return FALSE;
357
71
        }
358
359
71
        break;
360
361
      /* Handle Color Image Orders. */
362
71
      case REGULAR_COLOR_IMAGE:
363
0
      case MEGA_MEGA_COLOR_IMAGE:
364
0
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
0
        if (advance == 0)
366
0
          return FALSE;
367
0
        pbSrc = pbSrc + advance;
368
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
0
          return FALSE;
370
0
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
0
          return FALSE;
372
373
0
        UNROLL(runLength, {
374
0
          SRCREADPIXEL(temp, pbSrc);
375
0
          DESTWRITEPIXEL(pbDest, temp);
376
0
        });
377
0
        break;
378
379
      /* Handle Special Order 1. */
380
0
      case SPECIAL_FGBG_1:
381
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
0
        pbSrc = pbSrc + 1;
384
385
0
        if (fFirstLine)
386
0
        {
387
0
          pbDest =
388
0
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
0
        }
390
0
        else
391
0
        {
392
0
          pbDest =
393
0
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
0
        }
395
396
0
        if (!pbDest)
397
0
          return FALSE;
398
399
0
        break;
400
401
      /* Handle Special Order 2. */
402
0
      case SPECIAL_FGBG_2:
403
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
0
        pbSrc = pbSrc + 1;
406
407
0
        if (fFirstLine)
408
0
        {
409
0
          pbDest =
410
0
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
0
        }
412
0
        else
413
0
        {
414
0
          pbDest =
415
0
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
0
        }
417
418
0
        if (!pbDest)
419
0
          return FALSE;
420
421
0
        break;
422
423
      /* Handle White Order. */
424
0
      case SPECIAL_WHITE:
425
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
0
        pbSrc = pbSrc + 1;
428
429
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
0
          return FALSE;
431
432
0
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
0
        break;
434
435
      /* Handle Black Order. */
436
0
      case SPECIAL_BLACK:
437
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
0
        pbSrc = pbSrc + 1;
440
441
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
0
          return FALSE;
443
444
0
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
0
        break;
446
447
0
      default:
448
0
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
0
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
0
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
0
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
0
        return FALSE;
453
290
    }
454
290
  }
455
456
0
  return TRUE;
457
3
}
interleaved.c:RleDecompress24to24
Line
Count
Source
104
1
{
105
1
  const BYTE* pbSrc = pbSrcBuffer;
106
1
  BYTE* pbDest = pbDestBuffer;
107
1
  PIXEL temp = 0;
108
1
  PIXEL fgPel = WHITE_PIXEL;
109
1
  BOOL fInsertFgPel = FALSE;
110
1
  BOOL fFirstLine = TRUE;
111
1
  BYTE bitmask = 0;
112
1
  PIXEL pixelA = 0;
113
1
  PIXEL pixelB = 0;
114
1
  UINT32 runLength = 0;
115
1
  UINT32 code = 0;
116
1
  UINT32 advance = 0;
117
1
  RLEEXTRA
118
119
1
  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
1
  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
1
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
1
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
94
  while (pbSrc < pbEnd)
138
94
  {
139
    /* Watch out for the end of the first scanline. */
140
94
    if (fFirstLine)
141
3
    {
142
3
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
1
      {
144
1
        fFirstLine = FALSE;
145
1
        fInsertFgPel = FALSE;
146
1
      }
147
3
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
94
    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
94
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
0
    {
162
0
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
0
      if (advance == 0)
164
0
        return FALSE;
165
0
      pbSrc = pbSrc + advance;
166
167
0
      if (fFirstLine)
168
0
      {
169
0
        if (fInsertFgPel)
170
0
        {
171
0
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
0
          DESTWRITEPIXEL(pbDest, fgPel);
175
0
          runLength = runLength - 1;
176
0
        }
177
178
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
0
          return FALSE;
180
181
0
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
0
      }
183
0
      else
184
0
      {
185
0
        if (fInsertFgPel)
186
0
        {
187
0
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
0
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
0
            return FALSE;
191
192
0
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
0
          runLength--;
194
0
        }
195
196
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
0
          return FALSE;
198
199
0
        UNROLL(runLength, {
200
0
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
0
          DESTWRITEPIXEL(pbDest, temp);
202
0
        });
203
0
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
0
      fInsertFgPel = TRUE;
207
0
      continue;
208
0
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
94
    fInsertFgPel = FALSE;
213
214
94
    switch (code)
215
94
    {
216
      /* Handle Foreground Run Orders. */
217
60
      case REGULAR_FG_RUN:
218
60
      case MEGA_MEGA_FG_RUN:
219
61
      case LITE_SET_FG_FG_RUN:
220
61
      case MEGA_MEGA_SET_FG_RUN:
221
61
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
61
        if (advance == 0)
223
0
          return FALSE;
224
61
        pbSrc = pbSrc + advance;
225
226
61
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
1
        {
228
1
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
0
            return FALSE;
230
1
          SRCREADPIXEL(fgPel, pbSrc);
231
1
        }
232
233
61
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
0
          return FALSE;
235
236
61
        if (fFirstLine)
237
1
        {
238
1
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
1
        }
240
60
        else
241
60
        {
242
60
          UNROLL(runLength, {
243
60
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
60
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
60
          });
246
60
        }
247
248
61
        break;
249
250
      /* Handle Dithered Run Orders. */
251
0
      case LITE_DITHERED_RUN:
252
0
      case MEGA_MEGA_DITHERED_RUN:
253
0
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
0
        if (advance == 0)
255
0
          return FALSE;
256
0
        pbSrc = pbSrc + advance;
257
0
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
0
          return FALSE;
259
0
        SRCREADPIXEL(pixelA, pbSrc);
260
0
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
0
          return FALSE;
262
0
        SRCREADPIXEL(pixelB, pbSrc);
263
264
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
0
          return FALSE;
266
267
0
        UNROLL(runLength, {
268
0
          DESTWRITEPIXEL(pbDest, pixelA);
269
0
          DESTWRITEPIXEL(pbDest, pixelB);
270
0
        });
271
0
        break;
272
273
      /* Handle Color Run Orders. */
274
9
      case REGULAR_COLOR_RUN:
275
9
      case MEGA_MEGA_COLOR_RUN:
276
9
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
9
        if (advance == 0)
278
0
          return FALSE;
279
9
        pbSrc = pbSrc + advance;
280
9
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
0
          return FALSE;
282
9
        SRCREADPIXEL(pixelA, pbSrc);
283
284
9
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
0
          return FALSE;
286
287
9
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
9
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
24
      case REGULAR_FGBG_IMAGE:
292
24
      case MEGA_MEGA_FGBG_IMAGE:
293
24
      case LITE_SET_FG_FGBG_IMAGE:
294
24
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
24
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
24
        if (advance == 0)
297
0
          return FALSE;
298
24
        pbSrc = pbSrc + advance;
299
300
24
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
0
        {
302
0
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
0
            return FALSE;
304
0
          SRCREADPIXEL(fgPel, pbSrc);
305
0
        }
306
307
24
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
0
          return FALSE;
309
24
        if (fFirstLine)
310
1
        {
311
16
          while (runLength > 8)
312
15
          {
313
15
            bitmask = *pbSrc;
314
15
            pbSrc = pbSrc + 1;
315
15
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
15
            if (!pbDest)
318
0
              return FALSE;
319
320
15
            runLength = runLength - 8;
321
15
          }
322
1
        }
323
23
        else
324
23
        {
325
249
          while (runLength > 8)
326
227
          {
327
227
            bitmask = *pbSrc++;
328
329
227
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
227
            if (!pbDest)
332
1
              return FALSE;
333
334
226
            runLength = runLength - 8;
335
226
          }
336
23
        }
337
338
23
        if (runLength > 0)
339
23
        {
340
23
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
0
            return FALSE;
342
23
          bitmask = *pbSrc++;
343
344
23
          if (fFirstLine)
345
1
          {
346
1
            pbDest =
347
1
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
1
          }
349
22
          else
350
22
          {
351
22
            pbDest =
352
22
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
22
          }
354
355
23
          if (!pbDest)
356
0
            return FALSE;
357
23
        }
358
359
23
        break;
360
361
      /* Handle Color Image Orders. */
362
23
      case REGULAR_COLOR_IMAGE:
363
0
      case MEGA_MEGA_COLOR_IMAGE:
364
0
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
0
        if (advance == 0)
366
0
          return FALSE;
367
0
        pbSrc = pbSrc + advance;
368
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
0
          return FALSE;
370
0
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
0
          return FALSE;
372
373
0
        UNROLL(runLength, {
374
0
          SRCREADPIXEL(temp, pbSrc);
375
0
          DESTWRITEPIXEL(pbDest, temp);
376
0
        });
377
0
        break;
378
379
      /* Handle Special Order 1. */
380
0
      case SPECIAL_FGBG_1:
381
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
0
        pbSrc = pbSrc + 1;
384
385
0
        if (fFirstLine)
386
0
        {
387
0
          pbDest =
388
0
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
0
        }
390
0
        else
391
0
        {
392
0
          pbDest =
393
0
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
0
        }
395
396
0
        if (!pbDest)
397
0
          return FALSE;
398
399
0
        break;
400
401
      /* Handle Special Order 2. */
402
0
      case SPECIAL_FGBG_2:
403
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
0
        pbSrc = pbSrc + 1;
406
407
0
        if (fFirstLine)
408
0
        {
409
0
          pbDest =
410
0
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
0
        }
412
0
        else
413
0
        {
414
0
          pbDest =
415
0
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
0
        }
417
418
0
        if (!pbDest)
419
0
          return FALSE;
420
421
0
        break;
422
423
      /* Handle White Order. */
424
0
      case SPECIAL_WHITE:
425
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
0
        pbSrc = pbSrc + 1;
428
429
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
0
          return FALSE;
431
432
0
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
0
        break;
434
435
      /* Handle Black Order. */
436
0
      case SPECIAL_BLACK:
437
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
0
        pbSrc = pbSrc + 1;
440
441
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
0
          return FALSE;
443
444
0
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
0
        break;
446
447
0
      default:
448
0
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
0
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
0
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
0
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
0
        return FALSE;
453
94
    }
454
94
  }
455
456
0
  return TRUE;
457
1
}
interleaved.c:RleDecompress16to16
Line
Count
Source
104
2
{
105
2
  const BYTE* pbSrc = pbSrcBuffer;
106
2
  BYTE* pbDest = pbDestBuffer;
107
2
  PIXEL temp = 0;
108
2
  PIXEL fgPel = WHITE_PIXEL;
109
2
  BOOL fInsertFgPel = FALSE;
110
2
  BOOL fFirstLine = TRUE;
111
2
  BYTE bitmask = 0;
112
2
  PIXEL pixelA = 0;
113
2
  PIXEL pixelB = 0;
114
2
  UINT32 runLength = 0;
115
2
  UINT32 code = 0;
116
2
  UINT32 advance = 0;
117
2
  RLEEXTRA
118
119
2
  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
2
  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
2
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
135
2
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
136
137
196
  while (pbSrc < pbEnd)
138
196
  {
139
    /* Watch out for the end of the first scanline. */
140
196
    if (fFirstLine)
141
6
    {
142
6
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
143
2
      {
144
2
        fFirstLine = FALSE;
145
2
        fInsertFgPel = FALSE;
146
2
      }
147
6
    }
148
149
    /*
150
       Extract the compression order code ID from the compression
151
       order header.
152
    */
153
196
    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
196
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
161
0
    {
162
0
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
163
0
      if (advance == 0)
164
0
        return FALSE;
165
0
      pbSrc = pbSrc + advance;
166
167
0
      if (fFirstLine)
168
0
      {
169
0
        if (fInsertFgPel)
170
0
        {
171
0
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
172
0
            return FALSE;
173
174
0
          DESTWRITEPIXEL(pbDest, fgPel);
175
0
          runLength = runLength - 1;
176
0
        }
177
178
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
179
0
          return FALSE;
180
181
0
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
182
0
      }
183
0
      else
184
0
      {
185
0
        if (fInsertFgPel)
186
0
        {
187
0
          DESTREADPIXEL(temp, pbDest - rowDelta);
188
189
0
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
190
0
            return FALSE;
191
192
0
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
193
0
          runLength--;
194
0
        }
195
196
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
197
0
          return FALSE;
198
199
0
        UNROLL(runLength, {
200
0
          DESTREADPIXEL(temp, pbDest - rowDelta);
201
0
          DESTWRITEPIXEL(pbDest, temp);
202
0
        });
203
0
      }
204
205
      /* A follow-on background run order will need a foreground pel inserted. */
206
0
      fInsertFgPel = TRUE;
207
0
      continue;
208
0
    }
209
210
    /* For any of the other run-types a follow-on background run
211
        order does not need a foreground pel inserted. */
212
196
    fInsertFgPel = FALSE;
213
214
196
    switch (code)
215
196
    {
216
      /* Handle Foreground Run Orders. */
217
118
      case REGULAR_FG_RUN:
218
118
      case MEGA_MEGA_FG_RUN:
219
120
      case LITE_SET_FG_FG_RUN:
220
120
      case MEGA_MEGA_SET_FG_RUN:
221
120
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
222
120
        if (advance == 0)
223
0
          return FALSE;
224
120
        pbSrc = pbSrc + advance;
225
226
120
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
227
2
        {
228
2
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
229
0
            return FALSE;
230
2
          SRCREADPIXEL(fgPel, pbSrc);
231
2
        }
232
233
120
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
234
0
          return FALSE;
235
236
120
        if (fFirstLine)
237
2
        {
238
2
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
239
2
        }
240
118
        else
241
118
        {
242
118
          UNROLL(runLength, {
243
118
            DESTREADPIXEL(temp, pbDest - rowDelta);
244
118
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
245
118
          });
246
118
        }
247
248
120
        break;
249
250
      /* Handle Dithered Run Orders. */
251
0
      case LITE_DITHERED_RUN:
252
0
      case MEGA_MEGA_DITHERED_RUN:
253
0
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
254
0
        if (advance == 0)
255
0
          return FALSE;
256
0
        pbSrc = pbSrc + advance;
257
0
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
0
          return FALSE;
259
0
        SRCREADPIXEL(pixelA, pbSrc);
260
0
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
261
0
          return FALSE;
262
0
        SRCREADPIXEL(pixelB, pbSrc);
263
264
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
265
0
          return FALSE;
266
267
0
        UNROLL(runLength, {
268
0
          DESTWRITEPIXEL(pbDest, pixelA);
269
0
          DESTWRITEPIXEL(pbDest, pixelB);
270
0
        });
271
0
        break;
272
273
      /* Handle Color Run Orders. */
274
26
      case REGULAR_COLOR_RUN:
275
26
      case MEGA_MEGA_COLOR_RUN:
276
26
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
277
26
        if (advance == 0)
278
0
          return FALSE;
279
26
        pbSrc = pbSrc + advance;
280
26
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
281
0
          return FALSE;
282
26
        SRCREADPIXEL(pixelA, pbSrc);
283
284
26
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
285
0
          return FALSE;
286
287
26
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
288
26
        break;
289
290
      /* Handle Foreground/Background Image Orders. */
291
48
      case REGULAR_FGBG_IMAGE:
292
48
      case MEGA_MEGA_FGBG_IMAGE:
293
50
      case LITE_SET_FG_FGBG_IMAGE:
294
50
      case MEGA_MEGA_SET_FGBG_IMAGE:
295
50
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
296
50
        if (advance == 0)
297
0
          return FALSE;
298
50
        pbSrc = pbSrc + advance;
299
300
50
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
301
2
        {
302
2
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
303
0
            return FALSE;
304
2
          SRCREADPIXEL(fgPel, pbSrc);
305
2
        }
306
307
50
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
308
0
          return FALSE;
309
50
        if (fFirstLine)
310
2
        {
311
32
          while (runLength > 8)
312
30
          {
313
30
            bitmask = *pbSrc;
314
30
            pbSrc = pbSrc + 1;
315
30
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
316
317
30
            if (!pbDest)
318
0
              return FALSE;
319
320
30
            runLength = runLength - 8;
321
30
          }
322
2
        }
323
48
        else
324
48
        {
325
482
          while (runLength > 8)
326
436
          {
327
436
            bitmask = *pbSrc++;
328
329
436
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
330
331
436
            if (!pbDest)
332
2
              return FALSE;
333
334
434
            runLength = runLength - 8;
335
434
          }
336
48
        }
337
338
48
        if (runLength > 0)
339
48
        {
340
48
          if (!buffer_within_range(pbSrc, 1, pbEnd))
341
0
            return FALSE;
342
48
          bitmask = *pbSrc++;
343
344
48
          if (fFirstLine)
345
2
          {
346
2
            pbDest =
347
2
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
348
2
          }
349
46
          else
350
46
          {
351
46
            pbDest =
352
46
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
353
46
          }
354
355
48
          if (!pbDest)
356
0
            return FALSE;
357
48
        }
358
359
48
        break;
360
361
      /* Handle Color Image Orders. */
362
48
      case REGULAR_COLOR_IMAGE:
363
0
      case MEGA_MEGA_COLOR_IMAGE:
364
0
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
365
0
        if (advance == 0)
366
0
          return FALSE;
367
0
        pbSrc = pbSrc + advance;
368
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
369
0
          return FALSE;
370
0
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
371
0
          return FALSE;
372
373
0
        UNROLL(runLength, {
374
0
          SRCREADPIXEL(temp, pbSrc);
375
0
          DESTWRITEPIXEL(pbDest, temp);
376
0
        });
377
0
        break;
378
379
      /* Handle Special Order 1. */
380
0
      case SPECIAL_FGBG_1:
381
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
382
0
          return FALSE;
383
0
        pbSrc = pbSrc + 1;
384
385
0
        if (fFirstLine)
386
0
        {
387
0
          pbDest =
388
0
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
389
0
        }
390
0
        else
391
0
        {
392
0
          pbDest =
393
0
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
394
0
        }
395
396
0
        if (!pbDest)
397
0
          return FALSE;
398
399
0
        break;
400
401
      /* Handle Special Order 2. */
402
0
      case SPECIAL_FGBG_2:
403
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
404
0
          return FALSE;
405
0
        pbSrc = pbSrc + 1;
406
407
0
        if (fFirstLine)
408
0
        {
409
0
          pbDest =
410
0
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
411
0
        }
412
0
        else
413
0
        {
414
0
          pbDest =
415
0
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
416
0
        }
417
418
0
        if (!pbDest)
419
0
          return FALSE;
420
421
0
        break;
422
423
      /* Handle White Order. */
424
0
      case SPECIAL_WHITE:
425
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
426
0
          return FALSE;
427
0
        pbSrc = pbSrc + 1;
428
429
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
430
0
          return FALSE;
431
432
0
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
433
0
        break;
434
435
      /* Handle Black Order. */
436
0
      case SPECIAL_BLACK:
437
0
        if (!buffer_within_range(pbSrc, 1, pbEnd))
438
0
          return FALSE;
439
0
        pbSrc = pbSrc + 1;
440
441
0
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
442
0
          return FALSE;
443
444
0
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
445
0
        break;
446
447
0
      default:
448
0
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
449
0
                 code, WINPR_CXX_COMPAT_CAST(const void*, pbSrcBuffer),
450
0
                 WINPR_CXX_COMPAT_CAST(const void*, pbSrc),
451
0
                 WINPR_CXX_COMPAT_CAST(const void*, pbEnd));
452
0
        return FALSE;
453
196
    }
454
196
  }
455
456
0
  return TRUE;
457
2
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8