Coverage Report

Created: 2025-07-18 07:05

/src/FreeRDP/libfreerdp/codec/include/bitmap.h
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * RLE Compressed Bitmap Stream
4
 *
5
 * Copyright 2011 Jay Sorg <jay.sorg@gmail.com>
6
 * Copyright 2016 Armin Novak <armin.novak@thincast.com>
7
 * Copyright 2016 Thincast Technologies GmbH
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 *     http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
22
#include <winpr/assert.h>
23
#include <winpr/cast.h>
24
#include <winpr/wtypes.h>
25
26
/* do not compile the file directly */
27
28
/**
29
 * Write a foreground/background image to a destination buffer.
30
 */
31
static inline BYTE* WRITEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
32
                                   const BYTE* WINPR_RESTRICT pbDestEnd, UINT32 rowDelta,
33
                                   BYTE bitmask, PIXEL fgPel, UINT32 cBits)
34
103k
{
35
103k
  PIXEL xorPixel = 0;
36
103k
  BYTE mask = 0x01;
37
38
103k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
103k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
82
    return NULL;
46
47
103k
  UNROLL(cBits, {
48
103k
    PIXEL data = 0;
49
103k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
103k
    if (bitmask & mask)
52
103k
      data = xorPixel ^ fgPel;
53
103k
    else
54
103k
      data = xorPixel;
55
56
103k
    DESTWRITEPIXEL(pbDest, data);
57
103k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
103k
  });
59
103k
  return pbDest;
60
103k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
34
29.0k
{
35
29.0k
  PIXEL xorPixel = 0;
36
29.0k
  BYTE mask = 0x01;
37
38
29.0k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
29.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
24
    return NULL;
46
47
29.0k
  UNROLL(cBits, {
48
29.0k
    PIXEL data = 0;
49
29.0k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
29.0k
    if (bitmask & mask)
52
29.0k
      data = xorPixel ^ fgPel;
53
29.0k
    else
54
29.0k
      data = xorPixel;
55
56
29.0k
    DESTWRITEPIXEL(pbDest, data);
57
29.0k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
29.0k
  });
59
29.0k
  return pbDest;
60
29.0k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
34
74.0k
{
35
74.0k
  PIXEL xorPixel = 0;
36
74.0k
  BYTE mask = 0x01;
37
38
74.0k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
74.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
58
    return NULL;
46
47
73.9k
  UNROLL(cBits, {
48
73.9k
    PIXEL data = 0;
49
73.9k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
73.9k
    if (bitmask & mask)
52
73.9k
      data = xorPixel ^ fgPel;
53
73.9k
    else
54
73.9k
      data = xorPixel;
55
56
73.9k
    DESTWRITEPIXEL(pbDest, data);
57
73.9k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
73.9k
  });
59
73.9k
  return pbDest;
60
73.9k
}
Unexecuted instantiation: interleaved.c:WriteFgBgImage8to8
61
62
/**
63
 * Write a foreground/background image to a destination buffer
64
 * for the first line of compressed data.
65
 */
66
static inline BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
67
                                            const BYTE* WINPR_RESTRICT pbDestEnd, BYTE bitmask,
68
                                            PIXEL fgPel, UINT32 cBits)
69
59.1k
{
70
59.1k
  BYTE mask = 0x01;
71
72
59.1k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
59.1k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
70
    return NULL;
80
81
59.1k
  UNROLL(cBits, {
82
59.1k
    PIXEL data;
83
84
59.1k
    if (bitmask & mask)
85
59.1k
      data = fgPel;
86
59.1k
    else
87
59.1k
      data = BLACK_PIXEL;
88
89
59.1k
    DESTWRITEPIXEL(pbDest, data);
90
59.1k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
59.1k
  });
92
59.1k
  return pbDest;
93
59.1k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
69
23.3k
{
70
23.3k
  BYTE mask = 0x01;
71
72
23.3k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
23.3k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
26
    return NULL;
80
81
23.3k
  UNROLL(cBits, {
82
23.3k
    PIXEL data;
83
84
23.3k
    if (bitmask & mask)
85
23.3k
      data = fgPel;
86
23.3k
    else
87
23.3k
      data = BLACK_PIXEL;
88
89
23.3k
    DESTWRITEPIXEL(pbDest, data);
90
23.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
23.3k
  });
92
23.3k
  return pbDest;
93
23.3k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
69
35.8k
{
70
35.8k
  BYTE mask = 0x01;
71
72
35.8k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
35.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
44
    return NULL;
80
81
35.8k
  UNROLL(cBits, {
82
35.8k
    PIXEL data;
83
84
35.8k
    if (bitmask & mask)
85
35.8k
      data = fgPel;
86
35.8k
    else
87
35.8k
      data = BLACK_PIXEL;
88
89
35.8k
    DESTWRITEPIXEL(pbDest, data);
90
35.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
35.8k
  });
92
35.8k
  return pbDest;
93
35.8k
}
Unexecuted instantiation: interleaved.c:WriteFirstLineFgBgImage8to8
94
95
/**
96
 * Decompress an RLE compressed bitmap.
97
 */
98
static inline BOOL RLEDECOMPRESS(const BYTE* WINPR_RESTRICT pbSrcBuffer, UINT32 cbSrcBuffer,
99
                                 BYTE* WINPR_RESTRICT pbDestBuffer, UINT32 rowDelta, UINT32 width,
100
                                 UINT32 height)
101
17.9k
{
102
17.9k
  const BYTE* pbSrc = pbSrcBuffer;
103
17.9k
  BYTE* pbDest = pbDestBuffer;
104
17.9k
  PIXEL temp = 0;
105
17.9k
  PIXEL fgPel = WHITE_PIXEL;
106
17.9k
  BOOL fInsertFgPel = FALSE;
107
17.9k
  BOOL fFirstLine = TRUE;
108
17.9k
  BYTE bitmask = 0;
109
17.9k
  PIXEL pixelA = 0;
110
17.9k
  PIXEL pixelB = 0;
111
17.9k
  UINT32 runLength = 0;
112
17.9k
  UINT32 code = 0;
113
17.9k
  UINT32 advance = 0;
114
17.9k
  RLEEXTRA
115
116
17.9k
  if ((rowDelta == 0) || (rowDelta < width))
117
0
  {
118
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
119
0
             width);
120
0
    return FALSE;
121
0
  }
122
123
17.9k
  if (!pbSrcBuffer || !pbDestBuffer)
124
0
  {
125
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p", pbSrcBuffer,
126
0
             pbDestBuffer);
127
0
    return FALSE;
128
0
  }
129
130
17.9k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
17.9k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
524k
  while (pbSrc < pbEnd)
134
520k
  {
135
    /* Watch out for the end of the first scanline. */
136
520k
    if (fFirstLine)
137
87.0k
    {
138
87.0k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
13.3k
      {
140
13.3k
        fFirstLine = FALSE;
141
13.3k
        fInsertFgPel = FALSE;
142
13.3k
      }
143
87.0k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
520k
    code = ExtractCodeId(*pbSrc);
150
151
#if defined(WITH_DEBUG_CODECS)
152
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
153
#endif
154
155
    /* Handle Background Run Orders. */
156
520k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
344k
    {
158
344k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
344k
      if (advance == 0)
160
736
        return FALSE;
161
343k
      pbSrc = pbSrc + advance;
162
163
343k
      if (fFirstLine)
164
38.9k
      {
165
38.9k
        if (fInsertFgPel)
166
27.2k
        {
167
27.2k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
27.2k
          DESTWRITEPIXEL(pbDest, fgPel);
171
27.2k
          runLength = runLength - 1;
172
27.2k
        }
173
174
38.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
102
          return FALSE;
176
177
38.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
38.8k
      }
179
304k
      else
180
304k
      {
181
304k
        if (fInsertFgPel)
182
273k
        {
183
273k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
273k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
37
            return FALSE;
187
188
272k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
272k
          runLength--;
190
272k
        }
191
192
304k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
896
          return FALSE;
194
195
303k
        UNROLL(runLength, {
196
303k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
303k
          DESTWRITEPIXEL(pbDest, temp);
198
303k
        });
199
303k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
342k
      fInsertFgPel = TRUE;
203
342k
      continue;
204
343k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
176k
    fInsertFgPel = FALSE;
209
210
176k
    switch (code)
211
176k
    {
212
      /* Handle Foreground Run Orders. */
213
31.6k
      case REGULAR_FG_RUN:
214
33.9k
      case MEGA_MEGA_FG_RUN:
215
51.8k
      case LITE_SET_FG_FG_RUN:
216
52.8k
      case MEGA_MEGA_SET_FG_RUN:
217
52.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
52.8k
        if (advance == 0)
219
118
          return FALSE;
220
52.7k
        pbSrc = pbSrc + advance;
221
222
52.7k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
18.8k
        {
224
18.8k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
214
            return FALSE;
226
18.6k
          SRCREADPIXEL(fgPel, pbSrc);
227
18.6k
        }
228
229
52.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
439
          return FALSE;
231
232
52.1k
        if (fFirstLine)
233
11.0k
        {
234
11.0k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
11.0k
        }
236
41.0k
        else
237
41.0k
        {
238
41.0k
          UNROLL(runLength, {
239
41.0k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
41.0k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
41.0k
          });
242
41.0k
        }
243
244
52.1k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
11.5k
      case LITE_DITHERED_RUN:
248
12.7k
      case MEGA_MEGA_DITHERED_RUN:
249
12.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
12.7k
        if (advance == 0)
251
64
          return FALSE;
252
12.6k
        pbSrc = pbSrc + advance;
253
12.6k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
218
          return FALSE;
255
12.4k
        SRCREADPIXEL(pixelA, pbSrc);
256
12.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
497
          return FALSE;
258
11.9k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
11.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
127
          return FALSE;
262
263
11.8k
        UNROLL(runLength, {
264
11.8k
          DESTWRITEPIXEL(pbDest, pixelA);
265
11.8k
          DESTWRITEPIXEL(pbDest, pixelB);
266
11.8k
        });
267
11.8k
        break;
268
269
      /* Handle Color Run Orders. */
270
53.6k
      case REGULAR_COLOR_RUN:
271
55.1k
      case MEGA_MEGA_COLOR_RUN:
272
55.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
55.1k
        if (advance == 0)
274
71
          return FALSE;
275
55.1k
        pbSrc = pbSrc + advance;
276
55.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
358
          return FALSE;
278
54.7k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
54.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
245
          return FALSE;
282
283
54.5k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
54.5k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
15.5k
      case REGULAR_FGBG_IMAGE:
288
17.6k
      case MEGA_MEGA_FGBG_IMAGE:
289
21.7k
      case LITE_SET_FG_FGBG_IMAGE:
290
23.1k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
23.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
23.1k
        if (advance == 0)
293
151
          return FALSE;
294
22.9k
        pbSrc = pbSrc + advance;
295
296
22.9k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
5.37k
        {
298
5.37k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
188
            return FALSE;
300
5.18k
          SRCREADPIXEL(fgPel, pbSrc);
301
5.18k
        }
302
303
22.7k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
875
          return FALSE;
305
21.9k
        if (fFirstLine)
306
5.37k
        {
307
60.7k
          while (runLength > 8)
308
55.4k
          {
309
55.4k
            bitmask = *pbSrc;
310
55.4k
            pbSrc = pbSrc + 1;
311
55.4k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
55.4k
            if (!pbDest)
314
67
              return FALSE;
315
316
55.4k
            runLength = runLength - 8;
317
55.4k
          }
318
5.37k
        }
319
16.5k
        else
320
16.5k
        {
321
98.7k
          while (runLength > 8)
322
82.2k
          {
323
82.2k
            bitmask = *pbSrc++;
324
325
82.2k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
82.2k
            if (!pbDest)
328
48
              return FALSE;
329
330
82.2k
            runLength = runLength - 8;
331
82.2k
          }
332
16.5k
        }
333
334
21.7k
        if (runLength > 0)
335
18.8k
        {
336
18.8k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
105
            return FALSE;
338
18.7k
          bitmask = *pbSrc++;
339
340
18.7k
          if (fFirstLine)
341
3.04k
          {
342
3.04k
            pbDest =
343
3.04k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
3.04k
          }
345
15.6k
          else
346
15.6k
          {
347
15.6k
            pbDest =
348
15.6k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
15.6k
          }
350
351
18.7k
          if (!pbDest)
352
26
            return FALSE;
353
18.7k
        }
354
355
21.6k
        break;
356
357
      /* Handle Color Image Orders. */
358
21.6k
      case REGULAR_COLOR_IMAGE:
359
12.4k
      case MEGA_MEGA_COLOR_IMAGE:
360
12.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
12.4k
        if (advance == 0)
362
92
          return FALSE;
363
12.3k
        pbSrc = pbSrc + advance;
364
12.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
150
          return FALSE;
366
12.1k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
1.02k
          return FALSE;
368
369
11.1k
        UNROLL(runLength, {
370
3.41k
          SRCREADPIXEL(temp, pbSrc);
371
3.41k
          DESTWRITEPIXEL(pbDest, temp);
372
3.41k
        });
373
7.71k
        break;
374
375
      /* Handle Special Order 1. */
376
7.71k
      case SPECIAL_FGBG_1:
377
3.01k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
3.01k
        pbSrc = pbSrc + 1;
380
381
3.01k
        if (fFirstLine)
382
364
        {
383
364
          pbDest =
384
364
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
364
        }
386
2.64k
        else
387
2.64k
        {
388
2.64k
          pbDest =
389
2.64k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
2.64k
        }
391
392
3.01k
        if (!pbDest)
393
6
          return FALSE;
394
395
3.00k
        break;
396
397
      /* Handle Special Order 2. */
398
3.00k
      case SPECIAL_FGBG_2:
399
2.79k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
2.79k
        pbSrc = pbSrc + 1;
402
403
2.79k
        if (fFirstLine)
404
298
        {
405
298
          pbDest =
406
298
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
298
        }
408
2.49k
        else
409
2.49k
        {
410
2.49k
          pbDest =
411
2.49k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
2.49k
        }
413
414
2.79k
        if (!pbDest)
415
5
          return FALSE;
416
417
2.78k
        break;
418
419
      /* Handle White Order. */
420
4.98k
      case SPECIAL_WHITE:
421
4.98k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
4.98k
        pbSrc = pbSrc + 1;
424
425
4.98k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
6
          return FALSE;
427
428
4.98k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
4.98k
        break;
430
431
      /* Handle Black Order. */
432
2.47k
      case SPECIAL_BLACK:
433
2.47k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
2.47k
        pbSrc = pbSrc + 1;
436
437
2.47k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
4
          return FALSE;
439
440
2.46k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
2.46k
        break;
442
443
6.55k
      default:
444
6.55k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
6.55k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
6.55k
        return FALSE;
447
176k
    }
448
176k
  }
449
450
4.50k
  return TRUE;
451
17.9k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
101
5.97k
{
102
5.97k
  const BYTE* pbSrc = pbSrcBuffer;
103
5.97k
  BYTE* pbDest = pbDestBuffer;
104
5.97k
  PIXEL temp = 0;
105
5.97k
  PIXEL fgPel = WHITE_PIXEL;
106
5.97k
  BOOL fInsertFgPel = FALSE;
107
5.97k
  BOOL fFirstLine = TRUE;
108
5.97k
  BYTE bitmask = 0;
109
5.97k
  PIXEL pixelA = 0;
110
5.97k
  PIXEL pixelB = 0;
111
5.97k
  UINT32 runLength = 0;
112
5.97k
  UINT32 code = 0;
113
5.97k
  UINT32 advance = 0;
114
5.97k
  RLEEXTRA
115
116
5.97k
  if ((rowDelta == 0) || (rowDelta < width))
117
0
  {
118
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
119
0
             width);
120
0
    return FALSE;
121
0
  }
122
123
5.97k
  if (!pbSrcBuffer || !pbDestBuffer)
124
0
  {
125
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p", pbSrcBuffer,
126
0
             pbDestBuffer);
127
0
    return FALSE;
128
0
  }
129
130
5.97k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
5.97k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
171k
  while (pbSrc < pbEnd)
134
170k
  {
135
    /* Watch out for the end of the first scanline. */
136
170k
    if (fFirstLine)
137
29.2k
    {
138
29.2k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
4.24k
      {
140
4.24k
        fFirstLine = FALSE;
141
4.24k
        fInsertFgPel = FALSE;
142
4.24k
      }
143
29.2k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
170k
    code = ExtractCodeId(*pbSrc);
150
151
#if defined(WITH_DEBUG_CODECS)
152
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
153
#endif
154
155
    /* Handle Background Run Orders. */
156
170k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
112k
    {
158
112k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
112k
      if (advance == 0)
160
206
        return FALSE;
161
112k
      pbSrc = pbSrc + advance;
162
163
112k
      if (fFirstLine)
164
13.0k
      {
165
13.0k
        if (fInsertFgPel)
166
8.96k
        {
167
8.96k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
8.96k
          DESTWRITEPIXEL(pbDest, fgPel);
171
8.96k
          runLength = runLength - 1;
172
8.96k
        }
173
174
13.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
36
          return FALSE;
176
177
13.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
13.0k
      }
179
98.9k
      else
180
98.9k
      {
181
98.9k
        if (fInsertFgPel)
182
89.1k
        {
183
89.1k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
89.1k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
7
            return FALSE;
187
188
89.1k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
89.1k
          runLength--;
190
89.1k
        }
191
192
98.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
288
          return FALSE;
194
195
98.7k
        UNROLL(runLength, {
196
98.7k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
98.7k
          DESTWRITEPIXEL(pbDest, temp);
198
98.7k
        });
199
98.7k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
111k
      fInsertFgPel = TRUE;
203
111k
      continue;
204
112k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
57.9k
    fInsertFgPel = FALSE;
209
210
57.9k
    switch (code)
211
57.9k
    {
212
      /* Handle Foreground Run Orders. */
213
10.2k
      case REGULAR_FG_RUN:
214
11.0k
      case MEGA_MEGA_FG_RUN:
215
16.5k
      case LITE_SET_FG_FG_RUN:
216
16.9k
      case MEGA_MEGA_SET_FG_RUN:
217
16.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
16.9k
        if (advance == 0)
219
36
          return FALSE;
220
16.9k
        pbSrc = pbSrc + advance;
221
222
16.9k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
5.92k
        {
224
5.92k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
82
            return FALSE;
226
5.84k
          SRCREADPIXEL(fgPel, pbSrc);
227
5.84k
        }
228
229
16.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
117
          return FALSE;
231
232
16.7k
        if (fFirstLine)
233
3.83k
        {
234
3.83k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
3.83k
        }
236
12.8k
        else
237
12.8k
        {
238
12.8k
          UNROLL(runLength, {
239
12.8k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
12.8k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
12.8k
          });
242
12.8k
        }
243
244
16.7k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
3.92k
      case LITE_DITHERED_RUN:
248
4.36k
      case MEGA_MEGA_DITHERED_RUN:
249
4.36k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
4.36k
        if (advance == 0)
251
22
          return FALSE;
252
4.34k
        pbSrc = pbSrc + advance;
253
4.34k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
90
          return FALSE;
255
4.25k
        SRCREADPIXEL(pixelA, pbSrc);
256
4.25k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
257
          return FALSE;
258
3.99k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
3.99k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
37
          return FALSE;
262
263
3.95k
        UNROLL(runLength, {
264
3.95k
          DESTWRITEPIXEL(pbDest, pixelA);
265
3.95k
          DESTWRITEPIXEL(pbDest, pixelB);
266
3.95k
        });
267
3.95k
        break;
268
269
      /* Handle Color Run Orders. */
270
18.3k
      case REGULAR_COLOR_RUN:
271
18.9k
      case MEGA_MEGA_COLOR_RUN:
272
18.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
18.9k
        if (advance == 0)
274
17
          return FALSE;
275
18.9k
        pbSrc = pbSrc + advance;
276
18.9k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
134
          return FALSE;
278
18.7k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
18.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
83
          return FALSE;
282
283
18.6k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
18.6k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
4.84k
      case REGULAR_FGBG_IMAGE:
288
5.55k
      case MEGA_MEGA_FGBG_IMAGE:
289
6.89k
      case LITE_SET_FG_FGBG_IMAGE:
290
7.31k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
7.31k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
7.31k
        if (advance == 0)
293
47
          return FALSE;
294
7.26k
        pbSrc = pbSrc + advance;
295
296
7.26k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
1.73k
        {
298
1.73k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
68
            return FALSE;
300
1.66k
          SRCREADPIXEL(fgPel, pbSrc);
301
1.66k
        }
302
303
7.19k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
281
          return FALSE;
305
6.91k
        if (fFirstLine)
306
1.95k
        {
307
23.8k
          while (runLength > 8)
308
21.9k
          {
309
21.9k
            bitmask = *pbSrc;
310
21.9k
            pbSrc = pbSrc + 1;
311
21.9k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
21.9k
            if (!pbDest)
314
25
              return FALSE;
315
316
21.9k
            runLength = runLength - 8;
317
21.9k
          }
318
1.95k
        }
319
4.96k
        else
320
4.96k
        {
321
27.5k
          while (runLength > 8)
322
22.6k
          {
323
22.6k
            bitmask = *pbSrc++;
324
325
22.6k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
22.6k
            if (!pbDest)
328
14
              return FALSE;
329
330
22.5k
            runLength = runLength - 8;
331
22.5k
          }
332
4.96k
        }
333
334
6.87k
        if (runLength > 0)
335
5.94k
        {
336
5.94k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
41
            return FALSE;
338
5.90k
          bitmask = *pbSrc++;
339
340
5.90k
          if (fFirstLine)
341
1.20k
          {
342
1.20k
            pbDest =
343
1.20k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.20k
          }
345
4.70k
          else
346
4.70k
          {
347
4.70k
            pbDest =
348
4.70k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
4.70k
          }
350
351
5.90k
          if (!pbDest)
352
8
            return FALSE;
353
5.90k
        }
354
355
6.82k
        break;
356
357
      /* Handle Color Image Orders. */
358
6.82k
      case REGULAR_COLOR_IMAGE:
359
3.82k
      case MEGA_MEGA_COLOR_IMAGE:
360
3.82k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
3.82k
        if (advance == 0)
362
30
          return FALSE;
363
3.79k
        pbSrc = pbSrc + advance;
364
3.79k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
44
          return FALSE;
366
3.75k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
331
          return FALSE;
368
369
3.41k
        UNROLL(runLength, {
370
3.41k
          SRCREADPIXEL(temp, pbSrc);
371
3.41k
          DESTWRITEPIXEL(pbDest, temp);
372
3.41k
        });
373
3.41k
        break;
374
375
      /* Handle Special Order 1. */
376
1.03k
      case SPECIAL_FGBG_1:
377
1.03k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
1.03k
        pbSrc = pbSrc + 1;
380
381
1.03k
        if (fFirstLine)
382
106
        {
383
106
          pbDest =
384
106
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
106
        }
386
932
        else
387
932
        {
388
932
          pbDest =
389
932
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
932
        }
391
392
1.03k
        if (!pbDest)
393
2
          return FALSE;
394
395
1.03k
        break;
396
397
      /* Handle Special Order 2. */
398
1.03k
      case SPECIAL_FGBG_2:
399
908
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
908
        pbSrc = pbSrc + 1;
402
403
908
        if (fFirstLine)
404
96
        {
405
96
          pbDest =
406
96
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
96
        }
408
812
        else
409
812
        {
410
812
          pbDest =
411
812
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
812
        }
413
414
908
        if (!pbDest)
415
1
          return FALSE;
416
417
907
        break;
418
419
      /* Handle White Order. */
420
1.63k
      case SPECIAL_WHITE:
421
1.63k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
1.63k
        pbSrc = pbSrc + 1;
424
425
1.63k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
2
          return FALSE;
427
428
1.63k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
1.63k
        break;
430
431
      /* Handle Black Order. */
432
883
      case SPECIAL_BLACK:
433
883
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
883
        pbSrc = pbSrc + 1;
436
437
883
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
2
          return FALSE;
439
440
881
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
881
        break;
442
443
2.15k
      default:
444
2.15k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
2.15k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
2.15k
        return FALSE;
447
57.9k
    }
448
57.9k
  }
449
450
1.51k
  return TRUE;
451
5.97k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
101
11.9k
{
102
11.9k
  const BYTE* pbSrc = pbSrcBuffer;
103
11.9k
  BYTE* pbDest = pbDestBuffer;
104
11.9k
  PIXEL temp = 0;
105
11.9k
  PIXEL fgPel = WHITE_PIXEL;
106
11.9k
  BOOL fInsertFgPel = FALSE;
107
11.9k
  BOOL fFirstLine = TRUE;
108
11.9k
  BYTE bitmask = 0;
109
11.9k
  PIXEL pixelA = 0;
110
11.9k
  PIXEL pixelB = 0;
111
11.9k
  UINT32 runLength = 0;
112
11.9k
  UINT32 code = 0;
113
11.9k
  UINT32 advance = 0;
114
11.9k
  RLEEXTRA
115
116
11.9k
  if ((rowDelta == 0) || (rowDelta < width))
117
0
  {
118
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
119
0
             width);
120
0
    return FALSE;
121
0
  }
122
123
11.9k
  if (!pbSrcBuffer || !pbDestBuffer)
124
0
  {
125
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p", pbSrcBuffer,
126
0
             pbDestBuffer);
127
0
    return FALSE;
128
0
  }
129
130
11.9k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
11.9k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
353k
  while (pbSrc < pbEnd)
134
350k
  {
135
    /* Watch out for the end of the first scanline. */
136
350k
    if (fFirstLine)
137
57.8k
    {
138
57.8k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
9.11k
      {
140
9.11k
        fFirstLine = FALSE;
141
9.11k
        fInsertFgPel = FALSE;
142
9.11k
      }
143
57.8k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
350k
    code = ExtractCodeId(*pbSrc);
150
151
#if defined(WITH_DEBUG_CODECS)
152
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc, rle_code_str(code), pbEnd - pbSrc);
153
#endif
154
155
    /* Handle Background Run Orders. */
156
350k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
232k
    {
158
232k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
232k
      if (advance == 0)
160
530
        return FALSE;
161
231k
      pbSrc = pbSrc + advance;
162
163
231k
      if (fFirstLine)
164
25.9k
      {
165
25.9k
        if (fInsertFgPel)
166
18.2k
        {
167
18.2k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
18.2k
          DESTWRITEPIXEL(pbDest, fgPel);
171
18.2k
          runLength = runLength - 1;
172
18.2k
        }
173
174
25.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
66
          return FALSE;
176
177
25.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
25.8k
      }
179
205k
      else
180
205k
      {
181
205k
        if (fInsertFgPel)
182
183k
        {
183
183k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
183k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
30
            return FALSE;
187
188
183k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
183k
          runLength--;
190
183k
        }
191
192
205k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
608
          return FALSE;
194
195
204k
        UNROLL(runLength, {
196
204k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
204k
          DESTWRITEPIXEL(pbDest, temp);
198
204k
        });
199
204k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
230k
      fInsertFgPel = TRUE;
203
230k
      continue;
204
231k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
118k
    fInsertFgPel = FALSE;
209
210
118k
    switch (code)
211
118k
    {
212
      /* Handle Foreground Run Orders. */
213
21.4k
      case REGULAR_FG_RUN:
214
22.9k
      case MEGA_MEGA_FG_RUN:
215
35.2k
      case LITE_SET_FG_FG_RUN:
216
35.9k
      case MEGA_MEGA_SET_FG_RUN:
217
35.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
35.9k
        if (advance == 0)
219
82
          return FALSE;
220
35.8k
        pbSrc = pbSrc + advance;
221
222
35.8k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
12.9k
        {
224
12.9k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
132
            return FALSE;
226
12.7k
          SRCREADPIXEL(fgPel, pbSrc);
227
12.7k
        }
228
229
35.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
322
          return FALSE;
231
232
35.3k
        if (fFirstLine)
233
7.21k
        {
234
7.21k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
7.21k
        }
236
28.1k
        else
237
28.1k
        {
238
28.1k
          UNROLL(runLength, {
239
28.1k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
28.1k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
28.1k
          });
242
28.1k
        }
243
244
35.3k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
7.66k
      case LITE_DITHERED_RUN:
248
8.37k
      case MEGA_MEGA_DITHERED_RUN:
249
8.37k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
8.37k
        if (advance == 0)
251
42
          return FALSE;
252
8.33k
        pbSrc = pbSrc + advance;
253
8.33k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
128
          return FALSE;
255
8.20k
        SRCREADPIXEL(pixelA, pbSrc);
256
8.20k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
240
          return FALSE;
258
7.96k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
7.96k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
90
          return FALSE;
262
263
7.87k
        UNROLL(runLength, {
264
7.87k
          DESTWRITEPIXEL(pbDest, pixelA);
265
7.87k
          DESTWRITEPIXEL(pbDest, pixelB);
266
7.87k
        });
267
7.87k
        break;
268
269
      /* Handle Color Run Orders. */
270
35.2k
      case REGULAR_COLOR_RUN:
271
36.2k
      case MEGA_MEGA_COLOR_RUN:
272
36.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
36.2k
        if (advance == 0)
274
54
          return FALSE;
275
36.2k
        pbSrc = pbSrc + advance;
276
36.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
224
          return FALSE;
278
35.9k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
35.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
162
          return FALSE;
282
283
35.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
35.8k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
10.6k
      case REGULAR_FGBG_IMAGE:
288
12.1k
      case MEGA_MEGA_FGBG_IMAGE:
289
14.8k
      case LITE_SET_FG_FGBG_IMAGE:
290
15.8k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
15.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
15.8k
        if (advance == 0)
293
104
          return FALSE;
294
15.7k
        pbSrc = pbSrc + advance;
295
296
15.7k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
3.64k
        {
298
3.64k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
120
            return FALSE;
300
3.52k
          SRCREADPIXEL(fgPel, pbSrc);
301
3.52k
        }
302
303
15.5k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
594
          return FALSE;
305
14.9k
        if (fFirstLine)
306
3.41k
        {
307
36.9k
          while (runLength > 8)
308
33.5k
          {
309
33.5k
            bitmask = *pbSrc;
310
33.5k
            pbSrc = pbSrc + 1;
311
33.5k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
33.5k
            if (!pbDest)
314
42
              return FALSE;
315
316
33.5k
            runLength = runLength - 8;
317
33.5k
          }
318
3.41k
        }
319
11.5k
        else
320
11.5k
        {
321
71.2k
          while (runLength > 8)
322
59.6k
          {
323
59.6k
            bitmask = *pbSrc++;
324
325
59.6k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
59.6k
            if (!pbDest)
328
34
              return FALSE;
329
330
59.6k
            runLength = runLength - 8;
331
59.6k
          }
332
11.5k
        }
333
334
14.9k
        if (runLength > 0)
335
12.8k
        {
336
12.8k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
64
            return FALSE;
338
12.8k
          bitmask = *pbSrc++;
339
340
12.8k
          if (fFirstLine)
341
1.84k
          {
342
1.84k
            pbDest =
343
1.84k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.84k
          }
345
10.9k
          else
346
10.9k
          {
347
10.9k
            pbDest =
348
10.9k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
10.9k
          }
350
351
12.8k
          if (!pbDest)
352
18
            return FALSE;
353
12.8k
        }
354
355
14.8k
        break;
356
357
      /* Handle Color Image Orders. */
358
14.8k
      case REGULAR_COLOR_IMAGE:
359
8.58k
      case MEGA_MEGA_COLOR_IMAGE:
360
8.58k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
8.58k
        if (advance == 0)
362
62
          return FALSE;
363
8.52k
        pbSrc = pbSrc + advance;
364
8.52k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
106
          return FALSE;
366
8.41k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
698
          return FALSE;
368
369
7.71k
        UNROLL(runLength, {
370
7.71k
          SRCREADPIXEL(temp, pbSrc);
371
7.71k
          DESTWRITEPIXEL(pbDest, temp);
372
7.71k
        });
373
7.71k
        break;
374
375
      /* Handle Special Order 1. */
376
7.71k
      case SPECIAL_FGBG_1:
377
1.97k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
1.97k
        pbSrc = pbSrc + 1;
380
381
1.97k
        if (fFirstLine)
382
258
        {
383
258
          pbDest =
384
258
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
258
        }
386
1.71k
        else
387
1.71k
        {
388
1.71k
          pbDest =
389
1.71k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
1.71k
        }
391
392
1.97k
        if (!pbDest)
393
4
          return FALSE;
394
395
1.96k
        break;
396
397
      /* Handle Special Order 2. */
398
1.96k
      case SPECIAL_FGBG_2:
399
1.88k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
1.88k
        pbSrc = pbSrc + 1;
402
403
1.88k
        if (fFirstLine)
404
202
        {
405
202
          pbDest =
406
202
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
202
        }
408
1.68k
        else
409
1.68k
        {
410
1.68k
          pbDest =
411
1.68k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
1.68k
        }
413
414
1.88k
        if (!pbDest)
415
4
          return FALSE;
416
417
1.87k
        break;
418
419
      /* Handle White Order. */
420
3.35k
      case SPECIAL_WHITE:
421
3.35k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
3.35k
        pbSrc = pbSrc + 1;
424
425
3.35k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
4
          return FALSE;
427
428
3.34k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
3.34k
        break;
430
431
      /* Handle Black Order. */
432
1.58k
      case SPECIAL_BLACK:
433
1.58k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
1.58k
        pbSrc = pbSrc + 1;
436
437
1.58k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
2
          return FALSE;
439
440
1.58k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
1.58k
        break;
442
443
4.40k
      default:
444
4.40k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
4.40k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
4.40k
        return FALSE;
447
118k
    }
448
118k
  }
449
450
2.99k
  return TRUE;
451
11.9k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8