Coverage Report

Created: 2025-08-03 07:06

/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
107k
{
35
107k
  PIXEL xorPixel = 0;
36
107k
  BYTE mask = 0x01;
37
38
107k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
107k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
74
    return NULL;
46
47
107k
  UNROLL(cBits, {
48
107k
    PIXEL data = 0;
49
107k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
107k
    if (bitmask & mask)
52
107k
      data = xorPixel ^ fgPel;
53
107k
    else
54
107k
      data = xorPixel;
55
56
107k
    DESTWRITEPIXEL(pbDest, data);
57
107k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
107k
  });
59
107k
  return pbDest;
60
107k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
34
30.2k
{
35
30.2k
  PIXEL xorPixel = 0;
36
30.2k
  BYTE mask = 0x01;
37
38
30.2k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
30.2k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
26
    return NULL;
46
47
30.2k
  UNROLL(cBits, {
48
30.2k
    PIXEL data = 0;
49
30.2k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
30.2k
    if (bitmask & mask)
52
30.2k
      data = xorPixel ^ fgPel;
53
30.2k
    else
54
30.2k
      data = xorPixel;
55
56
30.2k
    DESTWRITEPIXEL(pbDest, data);
57
30.2k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
30.2k
  });
59
30.2k
  return pbDest;
60
30.2k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
34
77.4k
{
35
77.4k
  PIXEL xorPixel = 0;
36
77.4k
  BYTE mask = 0x01;
37
38
77.4k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
77.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
48
    return NULL;
46
47
77.3k
  UNROLL(cBits, {
48
77.3k
    PIXEL data = 0;
49
77.3k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
77.3k
    if (bitmask & mask)
52
77.3k
      data = xorPixel ^ fgPel;
53
77.3k
    else
54
77.3k
      data = xorPixel;
55
56
77.3k
    DESTWRITEPIXEL(pbDest, data);
57
77.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
77.3k
  });
59
77.3k
  return pbDest;
60
77.3k
}
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
58.8k
{
70
58.8k
  BYTE mask = 0x01;
71
72
58.8k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
58.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
71
    return NULL;
80
81
58.7k
  UNROLL(cBits, {
82
58.7k
    PIXEL data;
83
84
58.7k
    if (bitmask & mask)
85
58.7k
      data = fgPel;
86
58.7k
    else
87
58.7k
      data = BLACK_PIXEL;
88
89
58.7k
    DESTWRITEPIXEL(pbDest, data);
90
58.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
58.7k
  });
92
58.7k
  return pbDest;
93
58.7k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
69
22.6k
{
70
22.6k
  BYTE mask = 0x01;
71
72
22.6k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
22.6k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
25
    return NULL;
80
81
22.6k
  UNROLL(cBits, {
82
22.6k
    PIXEL data;
83
84
22.6k
    if (bitmask & mask)
85
22.6k
      data = fgPel;
86
22.6k
    else
87
22.6k
      data = BLACK_PIXEL;
88
89
22.6k
    DESTWRITEPIXEL(pbDest, data);
90
22.6k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
22.6k
  });
92
22.6k
  return pbDest;
93
22.6k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
69
36.1k
{
70
36.1k
  BYTE mask = 0x01;
71
72
36.1k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
36.1k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
46
    return NULL;
80
81
36.1k
  UNROLL(cBits, {
82
36.1k
    PIXEL data;
83
84
36.1k
    if (bitmask & mask)
85
36.1k
      data = fgPel;
86
36.1k
    else
87
36.1k
      data = BLACK_PIXEL;
88
89
36.1k
    DESTWRITEPIXEL(pbDest, data);
90
36.1k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
36.1k
  });
92
36.1k
  return pbDest;
93
36.1k
}
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
18.6k
{
102
18.6k
  const BYTE* pbSrc = pbSrcBuffer;
103
18.6k
  BYTE* pbDest = pbDestBuffer;
104
18.6k
  PIXEL temp = 0;
105
18.6k
  PIXEL fgPel = WHITE_PIXEL;
106
18.6k
  BOOL fInsertFgPel = FALSE;
107
18.6k
  BOOL fFirstLine = TRUE;
108
18.6k
  BYTE bitmask = 0;
109
18.6k
  PIXEL pixelA = 0;
110
18.6k
  PIXEL pixelB = 0;
111
18.6k
  UINT32 runLength = 0;
112
18.6k
  UINT32 code = 0;
113
18.6k
  UINT32 advance = 0;
114
18.6k
  RLEEXTRA
115
116
18.6k
  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
18.6k
  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
18.6k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
18.6k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
539k
  while (pbSrc < pbEnd)
134
534k
  {
135
    /* Watch out for the end of the first scanline. */
136
534k
    if (fFirstLine)
137
91.0k
    {
138
91.0k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
13.7k
      {
140
13.7k
        fFirstLine = FALSE;
141
13.7k
        fInsertFgPel = FALSE;
142
13.7k
      }
143
91.0k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
534k
    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
534k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
355k
    {
158
355k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
355k
      if (advance == 0)
160
727
        return FALSE;
161
355k
      pbSrc = pbSrc + advance;
162
163
355k
      if (fFirstLine)
164
40.9k
      {
165
40.9k
        if (fInsertFgPel)
166
28.6k
        {
167
28.6k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
28.6k
          DESTWRITEPIXEL(pbDest, fgPel);
171
28.6k
          runLength = runLength - 1;
172
28.6k
        }
173
174
40.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
128
          return FALSE;
176
177
40.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
40.8k
      }
179
314k
      else
180
314k
      {
181
314k
        if (fInsertFgPel)
182
282k
        {
183
282k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
282k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
49
            return FALSE;
187
188
282k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
282k
          runLength--;
190
282k
        }
191
192
314k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
988
          return FALSE;
194
195
313k
        UNROLL(runLength, {
196
313k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
313k
          DESTWRITEPIXEL(pbDest, temp);
198
313k
        });
199
313k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
353k
      fInsertFgPel = TRUE;
203
353k
      continue;
204
355k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
178k
    fInsertFgPel = FALSE;
209
210
178k
    switch (code)
211
178k
    {
212
      /* Handle Foreground Run Orders. */
213
31.2k
      case REGULAR_FG_RUN:
214
33.7k
      case MEGA_MEGA_FG_RUN:
215
52.9k
      case LITE_SET_FG_FG_RUN:
216
54.0k
      case MEGA_MEGA_SET_FG_RUN:
217
54.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
54.0k
        if (advance == 0)
219
116
          return FALSE;
220
53.9k
        pbSrc = pbSrc + advance;
221
222
53.9k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
20.2k
        {
224
20.2k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
223
            return FALSE;
226
20.0k
          SRCREADPIXEL(fgPel, pbSrc);
227
20.0k
        }
228
229
53.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
453
          return FALSE;
231
232
53.2k
        if (fFirstLine)
233
11.9k
        {
234
11.9k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
11.9k
        }
236
41.3k
        else
237
41.3k
        {
238
41.3k
          UNROLL(runLength, {
239
41.3k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
41.3k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
41.3k
          });
242
41.3k
        }
243
244
53.2k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
11.4k
      case LITE_DITHERED_RUN:
248
12.5k
      case MEGA_MEGA_DITHERED_RUN:
249
12.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
12.5k
        if (advance == 0)
251
75
          return FALSE;
252
12.4k
        pbSrc = pbSrc + advance;
253
12.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
269
          return FALSE;
255
12.2k
        SRCREADPIXEL(pixelA, pbSrc);
256
12.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
556
          return FALSE;
258
11.6k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
11.6k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
128
          return FALSE;
262
263
11.5k
        UNROLL(runLength, {
264
11.5k
          DESTWRITEPIXEL(pbDest, pixelA);
265
11.5k
          DESTWRITEPIXEL(pbDest, pixelB);
266
11.5k
        });
267
11.5k
        break;
268
269
      /* Handle Color Run Orders. */
270
53.9k
      case REGULAR_COLOR_RUN:
271
55.3k
      case MEGA_MEGA_COLOR_RUN:
272
55.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
55.3k
        if (advance == 0)
274
68
          return FALSE;
275
55.2k
        pbSrc = pbSrc + advance;
276
55.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
362
          return FALSE;
278
54.8k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
54.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
245
          return FALSE;
282
283
54.6k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
54.6k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
15.6k
      case REGULAR_FGBG_IMAGE:
288
17.8k
      case MEGA_MEGA_FGBG_IMAGE:
289
22.0k
      case LITE_SET_FG_FGBG_IMAGE:
290
23.4k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
23.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
23.4k
        if (advance == 0)
293
175
          return FALSE;
294
23.2k
        pbSrc = pbSrc + advance;
295
296
23.2k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
5.51k
        {
298
5.51k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
201
            return FALSE;
300
5.31k
          SRCREADPIXEL(fgPel, pbSrc);
301
5.31k
        }
302
303
23.0k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
934
          return FALSE;
305
22.1k
        if (fFirstLine)
306
5.37k
        {
307
60.4k
          while (runLength > 8)
308
55.1k
          {
309
55.1k
            bitmask = *pbSrc;
310
55.1k
            pbSrc = pbSrc + 1;
311
55.1k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
55.1k
            if (!pbDest)
314
68
              return FALSE;
315
316
55.0k
            runLength = runLength - 8;
317
55.0k
          }
318
5.37k
        }
319
16.7k
        else
320
16.7k
        {
321
102k
          while (runLength > 8)
322
85.7k
          {
323
85.7k
            bitmask = *pbSrc++;
324
325
85.7k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
85.7k
            if (!pbDest)
328
41
              return FALSE;
329
330
85.7k
            runLength = runLength - 8;
331
85.7k
          }
332
16.7k
        }
333
334
22.0k
        if (runLength > 0)
335
18.9k
        {
336
18.9k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
95
            return FALSE;
338
18.8k
          bitmask = *pbSrc++;
339
340
18.8k
          if (fFirstLine)
341
3.00k
          {
342
3.00k
            pbDest =
343
3.00k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
3.00k
          }
345
15.8k
          else
346
15.8k
          {
347
15.8k
            pbDest =
348
15.8k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
15.8k
          }
350
351
18.8k
          if (!pbDest)
352
23
            return FALSE;
353
18.8k
        }
354
355
21.9k
        break;
356
357
      /* Handle Color Image Orders. */
358
21.9k
      case REGULAR_COLOR_IMAGE:
359
12.7k
      case MEGA_MEGA_COLOR_IMAGE:
360
12.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
12.7k
        if (advance == 0)
362
76
          return FALSE;
363
12.7k
        pbSrc = pbSrc + advance;
364
12.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
164
          return FALSE;
366
12.5k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
1.09k
          return FALSE;
368
369
11.4k
        UNROLL(runLength, {
370
3.44k
          SRCREADPIXEL(temp, pbSrc);
371
3.44k
          DESTWRITEPIXEL(pbDest, temp);
372
3.44k
        });
373
8.00k
        break;
374
375
      /* Handle Special Order 1. */
376
8.00k
      case SPECIAL_FGBG_1:
377
3.49k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
3.49k
        pbSrc = pbSrc + 1;
380
381
3.49k
        if (fFirstLine)
382
404
        {
383
404
          pbDest =
384
404
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
404
        }
386
3.08k
        else
387
3.08k
        {
388
3.08k
          pbDest =
389
3.08k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
3.08k
        }
391
392
3.49k
        if (!pbDest)
393
10
          return FALSE;
394
395
3.48k
        break;
396
397
      /* Handle Special Order 2. */
398
3.48k
      case SPECIAL_FGBG_2:
399
3.26k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
3.26k
        pbSrc = pbSrc + 1;
402
403
3.26k
        if (fFirstLine)
404
267
        {
405
267
          pbDest =
406
267
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
267
        }
408
3.00k
        else
409
3.00k
        {
410
3.00k
          pbDest =
411
3.00k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
3.00k
        }
413
414
3.26k
        if (!pbDest)
415
3
          return FALSE;
416
417
3.26k
        break;
418
419
      /* Handle White Order. */
420
4.45k
      case SPECIAL_WHITE:
421
4.45k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
4.45k
        pbSrc = pbSrc + 1;
424
425
4.45k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
5
          return FALSE;
427
428
4.44k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
4.44k
        break;
430
431
      /* Handle Black Order. */
432
2.80k
      case SPECIAL_BLACK:
433
2.80k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
2.80k
        pbSrc = pbSrc + 1;
436
437
2.80k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
3
          return FALSE;
439
440
2.80k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
2.80k
        break;
442
443
6.61k
      default:
444
6.61k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
6.61k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
6.61k
        return FALSE;
447
178k
    }
448
178k
  }
449
450
4.76k
  return TRUE;
451
18.6k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
101
6.21k
{
102
6.21k
  const BYTE* pbSrc = pbSrcBuffer;
103
6.21k
  BYTE* pbDest = pbDestBuffer;
104
6.21k
  PIXEL temp = 0;
105
6.21k
  PIXEL fgPel = WHITE_PIXEL;
106
6.21k
  BOOL fInsertFgPel = FALSE;
107
6.21k
  BOOL fFirstLine = TRUE;
108
6.21k
  BYTE bitmask = 0;
109
6.21k
  PIXEL pixelA = 0;
110
6.21k
  PIXEL pixelB = 0;
111
6.21k
  UINT32 runLength = 0;
112
6.21k
  UINT32 code = 0;
113
6.21k
  UINT32 advance = 0;
114
6.21k
  RLEEXTRA
115
116
6.21k
  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
6.21k
  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
6.21k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
6.21k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
176k
  while (pbSrc < pbEnd)
134
174k
  {
135
    /* Watch out for the end of the first scanline. */
136
174k
    if (fFirstLine)
137
30.6k
    {
138
30.6k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
4.34k
      {
140
4.34k
        fFirstLine = FALSE;
141
4.34k
        fInsertFgPel = FALSE;
142
4.34k
      }
143
30.6k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
174k
    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
174k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
116k
    {
158
116k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
116k
      if (advance == 0)
160
203
        return FALSE;
161
116k
      pbSrc = pbSrc + advance;
162
163
116k
      if (fFirstLine)
164
13.8k
      {
165
13.8k
        if (fInsertFgPel)
166
9.48k
        {
167
9.48k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
9.48k
          DESTWRITEPIXEL(pbDest, fgPel);
171
9.48k
          runLength = runLength - 1;
172
9.48k
        }
173
174
13.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
42
          return FALSE;
176
177
13.7k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
13.7k
      }
179
102k
      else
180
102k
      {
181
102k
        if (fInsertFgPel)
182
92.5k
        {
183
92.5k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
92.5k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
13
            return FALSE;
187
188
92.5k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
92.5k
          runLength--;
190
92.5k
        }
191
192
102k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
318
          return FALSE;
194
195
102k
        UNROLL(runLength, {
196
102k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
102k
          DESTWRITEPIXEL(pbDest, temp);
198
102k
        });
199
102k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
115k
      fInsertFgPel = TRUE;
203
115k
      continue;
204
116k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
58.0k
    fInsertFgPel = FALSE;
209
210
58.0k
    switch (code)
211
58.0k
    {
212
      /* Handle Foreground Run Orders. */
213
10.1k
      case REGULAR_FG_RUN:
214
10.9k
      case MEGA_MEGA_FG_RUN:
215
17.0k
      case LITE_SET_FG_FG_RUN:
216
17.4k
      case MEGA_MEGA_SET_FG_RUN:
217
17.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
17.4k
        if (advance == 0)
219
36
          return FALSE;
220
17.4k
        pbSrc = pbSrc + advance;
221
222
17.4k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
6.46k
        {
224
6.46k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
91
            return FALSE;
226
6.37k
          SRCREADPIXEL(fgPel, pbSrc);
227
6.37k
        }
228
229
17.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
121
          return FALSE;
231
232
17.2k
        if (fFirstLine)
233
4.13k
        {
234
4.13k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
4.13k
        }
236
13.0k
        else
237
13.0k
        {
238
13.0k
          UNROLL(runLength, {
239
13.0k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
13.0k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
13.0k
          });
242
13.0k
        }
243
244
17.2k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
3.79k
      case LITE_DITHERED_RUN:
248
4.24k
      case MEGA_MEGA_DITHERED_RUN:
249
4.24k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
4.24k
        if (advance == 0)
251
23
          return FALSE;
252
4.21k
        pbSrc = pbSrc + advance;
253
4.21k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
115
          return FALSE;
255
4.10k
        SRCREADPIXEL(pixelA, pbSrc);
256
4.10k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
270
          return FALSE;
258
3.83k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
3.83k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
38
          return FALSE;
262
263
3.79k
        UNROLL(runLength, {
264
3.79k
          DESTWRITEPIXEL(pbDest, pixelA);
265
3.79k
          DESTWRITEPIXEL(pbDest, pixelB);
266
3.79k
        });
267
3.79k
        break;
268
269
      /* Handle Color Run Orders. */
270
17.6k
      case REGULAR_COLOR_RUN:
271
18.1k
      case MEGA_MEGA_COLOR_RUN:
272
18.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
18.1k
        if (advance == 0)
274
18
          return FALSE;
275
18.1k
        pbSrc = pbSrc + advance;
276
18.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
136
          return FALSE;
278
17.9k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
17.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
93
          return FALSE;
282
283
17.8k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
17.8k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
4.94k
      case REGULAR_FGBG_IMAGE:
288
5.66k
      case MEGA_MEGA_FGBG_IMAGE:
289
7.02k
      case LITE_SET_FG_FGBG_IMAGE:
290
7.45k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
7.45k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
7.45k
        if (advance == 0)
293
53
          return FALSE;
294
7.40k
        pbSrc = pbSrc + advance;
295
296
7.40k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
1.76k
        {
298
1.76k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
75
            return FALSE;
300
1.68k
          SRCREADPIXEL(fgPel, pbSrc);
301
1.68k
        }
302
303
7.33k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
308
          return FALSE;
305
7.02k
        if (fFirstLine)
306
1.95k
        {
307
23.2k
          while (runLength > 8)
308
21.2k
          {
309
21.2k
            bitmask = *pbSrc;
310
21.2k
            pbSrc = pbSrc + 1;
311
21.2k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
21.2k
            if (!pbDest)
314
24
              return FALSE;
315
316
21.2k
            runLength = runLength - 8;
317
21.2k
          }
318
1.95k
        }
319
5.06k
        else
320
5.06k
        {
321
28.5k
          while (runLength > 8)
322
23.4k
          {
323
23.4k
            bitmask = *pbSrc++;
324
325
23.4k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
23.4k
            if (!pbDest)
328
15
              return FALSE;
329
330
23.4k
            runLength = runLength - 8;
331
23.4k
          }
332
5.06k
        }
333
334
6.98k
        if (runLength > 0)
335
6.02k
        {
336
6.02k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
37
            return FALSE;
338
5.98k
          bitmask = *pbSrc++;
339
340
5.98k
          if (fFirstLine)
341
1.17k
          {
342
1.17k
            pbDest =
343
1.17k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.17k
          }
345
4.81k
          else
346
4.81k
          {
347
4.81k
            pbDest =
348
4.81k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
4.81k
          }
350
351
5.98k
          if (!pbDest)
352
7
            return FALSE;
353
5.98k
        }
354
355
6.94k
        break;
356
357
      /* Handle Color Image Orders. */
358
6.94k
      case REGULAR_COLOR_IMAGE:
359
3.87k
      case MEGA_MEGA_COLOR_IMAGE:
360
3.87k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
3.87k
        if (advance == 0)
362
26
          return FALSE;
363
3.84k
        pbSrc = pbSrc + advance;
364
3.84k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
52
          return FALSE;
366
3.79k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
348
          return FALSE;
368
369
3.44k
        UNROLL(runLength, {
370
3.44k
          SRCREADPIXEL(temp, pbSrc);
371
3.44k
          DESTWRITEPIXEL(pbDest, temp);
372
3.44k
        });
373
3.44k
        break;
374
375
      /* Handle Special Order 1. */
376
1.15k
      case SPECIAL_FGBG_1:
377
1.15k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
1.15k
        pbSrc = pbSrc + 1;
380
381
1.15k
        if (fFirstLine)
382
116
        {
383
116
          pbDest =
384
116
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
116
        }
386
1.03k
        else
387
1.03k
        {
388
1.03k
          pbDest =
389
1.03k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
1.03k
        }
391
392
1.15k
        if (!pbDest)
393
4
          return FALSE;
394
395
1.14k
        break;
396
397
      /* Handle Special Order 2. */
398
1.14k
      case SPECIAL_FGBG_2:
399
1.08k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
1.08k
        pbSrc = pbSrc + 1;
402
403
1.08k
        if (fFirstLine)
404
89
        {
405
89
          pbDest =
406
89
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
89
        }
408
993
        else
409
993
        {
410
993
          pbDest =
411
993
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
993
        }
413
414
1.08k
        if (!pbDest)
415
1
          return FALSE;
416
417
1.08k
        break;
418
419
      /* Handle White Order. */
420
1.49k
      case SPECIAL_WHITE:
421
1.49k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
1.49k
        pbSrc = pbSrc + 1;
424
425
1.49k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
1
          return FALSE;
427
428
1.49k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
1.49k
        break;
430
431
      /* Handle Black Order. */
432
999
      case SPECIAL_BLACK:
433
999
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
999
        pbSrc = pbSrc + 1;
436
437
999
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
1
          return FALSE;
439
440
998
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
998
        break;
442
443
2.17k
      default:
444
2.17k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
2.17k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
2.17k
        return FALSE;
447
58.0k
    }
448
58.0k
  }
449
450
1.57k
  return TRUE;
451
6.21k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
101
12.4k
{
102
12.4k
  const BYTE* pbSrc = pbSrcBuffer;
103
12.4k
  BYTE* pbDest = pbDestBuffer;
104
12.4k
  PIXEL temp = 0;
105
12.4k
  PIXEL fgPel = WHITE_PIXEL;
106
12.4k
  BOOL fInsertFgPel = FALSE;
107
12.4k
  BOOL fFirstLine = TRUE;
108
12.4k
  BYTE bitmask = 0;
109
12.4k
  PIXEL pixelA = 0;
110
12.4k
  PIXEL pixelB = 0;
111
12.4k
  UINT32 runLength = 0;
112
12.4k
  UINT32 code = 0;
113
12.4k
  UINT32 advance = 0;
114
12.4k
  RLEEXTRA
115
116
12.4k
  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
12.4k
  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
12.4k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
12.4k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
363k
  while (pbSrc < pbEnd)
134
360k
  {
135
    /* Watch out for the end of the first scanline. */
136
360k
    if (fFirstLine)
137
60.4k
    {
138
60.4k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
9.36k
      {
140
9.36k
        fFirstLine = FALSE;
141
9.36k
        fInsertFgPel = FALSE;
142
9.36k
      }
143
60.4k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
360k
    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
360k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
239k
    {
158
239k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
239k
      if (advance == 0)
160
524
        return FALSE;
161
238k
      pbSrc = pbSrc + advance;
162
163
238k
      if (fFirstLine)
164
27.1k
      {
165
27.1k
        if (fInsertFgPel)
166
19.1k
        {
167
19.1k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
19.1k
          DESTWRITEPIXEL(pbDest, fgPel);
171
19.1k
          runLength = runLength - 1;
172
19.1k
        }
173
174
27.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
86
          return FALSE;
176
177
27.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
27.0k
      }
179
211k
      else
180
211k
      {
181
211k
        if (fInsertFgPel)
182
190k
        {
183
190k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
190k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
36
            return FALSE;
187
188
190k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
190k
          runLength--;
190
190k
        }
191
192
211k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
670
          return FALSE;
194
195
211k
        UNROLL(runLength, {
196
211k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
211k
          DESTWRITEPIXEL(pbDest, temp);
198
211k
        });
199
211k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
238k
      fInsertFgPel = TRUE;
203
238k
      continue;
204
238k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
120k
    fInsertFgPel = FALSE;
209
210
120k
    switch (code)
211
120k
    {
212
      /* Handle Foreground Run Orders. */
213
21.1k
      case REGULAR_FG_RUN:
214
22.7k
      case MEGA_MEGA_FG_RUN:
215
35.9k
      case LITE_SET_FG_FG_RUN:
216
36.5k
      case MEGA_MEGA_SET_FG_RUN:
217
36.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
36.5k
        if (advance == 0)
219
80
          return FALSE;
220
36.5k
        pbSrc = pbSrc + advance;
221
222
36.5k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
13.7k
        {
224
13.7k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
132
            return FALSE;
226
13.6k
          SRCREADPIXEL(fgPel, pbSrc);
227
13.6k
        }
228
229
36.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
332
          return FALSE;
231
232
36.0k
        if (fFirstLine)
233
7.80k
        {
234
7.80k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
7.80k
        }
236
28.2k
        else
237
28.2k
        {
238
28.2k
          UNROLL(runLength, {
239
28.2k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
28.2k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
28.2k
          });
242
28.2k
        }
243
244
36.0k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
7.62k
      case LITE_DITHERED_RUN:
248
8.32k
      case MEGA_MEGA_DITHERED_RUN:
249
8.32k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
8.32k
        if (advance == 0)
251
52
          return FALSE;
252
8.27k
        pbSrc = pbSrc + advance;
253
8.27k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
154
          return FALSE;
255
8.12k
        SRCREADPIXEL(pixelA, pbSrc);
256
8.12k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
286
          return FALSE;
258
7.83k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
7.83k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
90
          return FALSE;
262
263
7.74k
        UNROLL(runLength, {
264
7.74k
          DESTWRITEPIXEL(pbDest, pixelA);
265
7.74k
          DESTWRITEPIXEL(pbDest, pixelB);
266
7.74k
        });
267
7.74k
        break;
268
269
      /* Handle Color Run Orders. */
270
36.2k
      case REGULAR_COLOR_RUN:
271
37.1k
      case MEGA_MEGA_COLOR_RUN:
272
37.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
37.1k
        if (advance == 0)
274
50
          return FALSE;
275
37.1k
        pbSrc = pbSrc + advance;
276
37.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
226
          return FALSE;
278
36.9k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
36.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
152
          return FALSE;
282
283
36.7k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
36.7k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
10.7k
      case REGULAR_FGBG_IMAGE:
288
12.1k
      case MEGA_MEGA_FGBG_IMAGE:
289
14.9k
      case LITE_SET_FG_FGBG_IMAGE:
290
15.9k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
15.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
15.9k
        if (advance == 0)
293
122
          return FALSE;
294
15.8k
        pbSrc = pbSrc + advance;
295
296
15.8k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
3.75k
        {
298
3.75k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
126
            return FALSE;
300
3.62k
          SRCREADPIXEL(fgPel, pbSrc);
301
3.62k
        }
302
303
15.7k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
626
          return FALSE;
305
15.1k
        if (fFirstLine)
306
3.41k
        {
307
37.2k
          while (runLength > 8)
308
33.8k
          {
309
33.8k
            bitmask = *pbSrc;
310
33.8k
            pbSrc = pbSrc + 1;
311
33.8k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
33.8k
            if (!pbDest)
314
44
              return FALSE;
315
316
33.8k
            runLength = runLength - 8;
317
33.8k
          }
318
3.41k
        }
319
11.6k
        else
320
11.6k
        {
321
73.9k
          while (runLength > 8)
322
62.2k
          {
323
62.2k
            bitmask = *pbSrc++;
324
325
62.2k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
62.2k
            if (!pbDest)
328
26
              return FALSE;
329
330
62.2k
            runLength = runLength - 8;
331
62.2k
          }
332
11.6k
        }
333
334
15.0k
        if (runLength > 0)
335
12.9k
        {
336
12.9k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
58
            return FALSE;
338
12.9k
          bitmask = *pbSrc++;
339
340
12.9k
          if (fFirstLine)
341
1.82k
          {
342
1.82k
            pbDest =
343
1.82k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.82k
          }
345
11.0k
          else
346
11.0k
          {
347
11.0k
            pbDest =
348
11.0k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
11.0k
          }
350
351
12.9k
          if (!pbDest)
352
16
            return FALSE;
353
12.9k
        }
354
355
14.9k
        break;
356
357
      /* Handle Color Image Orders. */
358
14.9k
      case REGULAR_COLOR_IMAGE:
359
8.91k
      case MEGA_MEGA_COLOR_IMAGE:
360
8.91k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
8.91k
        if (advance == 0)
362
50
          return FALSE;
363
8.86k
        pbSrc = pbSrc + advance;
364
8.86k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
112
          return FALSE;
366
8.75k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
748
          return FALSE;
368
369
8.00k
        UNROLL(runLength, {
370
8.00k
          SRCREADPIXEL(temp, pbSrc);
371
8.00k
          DESTWRITEPIXEL(pbDest, temp);
372
8.00k
        });
373
8.00k
        break;
374
375
      /* Handle Special Order 1. */
376
8.00k
      case SPECIAL_FGBG_1:
377
2.33k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
2.33k
        pbSrc = pbSrc + 1;
380
381
2.33k
        if (fFirstLine)
382
288
        {
383
288
          pbDest =
384
288
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
288
        }
386
2.05k
        else
387
2.05k
        {
388
2.05k
          pbDest =
389
2.05k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
2.05k
        }
391
392
2.33k
        if (!pbDest)
393
6
          return FALSE;
394
395
2.33k
        break;
396
397
      /* Handle Special Order 2. */
398
2.33k
      case SPECIAL_FGBG_2:
399
2.18k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
2.18k
        pbSrc = pbSrc + 1;
402
403
2.18k
        if (fFirstLine)
404
178
        {
405
178
          pbDest =
406
178
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
178
        }
408
2.00k
        else
409
2.00k
        {
410
2.00k
          pbDest =
411
2.00k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
2.00k
        }
413
414
2.18k
        if (!pbDest)
415
2
          return FALSE;
416
417
2.18k
        break;
418
419
      /* Handle White Order. */
420
2.95k
      case SPECIAL_WHITE:
421
2.95k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
2.95k
        pbSrc = pbSrc + 1;
424
425
2.95k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
4
          return FALSE;
427
428
2.95k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
2.95k
        break;
430
431
      /* Handle Black Order. */
432
1.80k
      case SPECIAL_BLACK:
433
1.80k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
1.80k
        pbSrc = pbSrc + 1;
436
437
1.80k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
2
          return FALSE;
439
440
1.80k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
1.80k
        break;
442
443
4.43k
      default:
444
4.43k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
4.43k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
4.43k
        return FALSE;
447
120k
    }
448
120k
  }
449
450
3.19k
  return TRUE;
451
12.4k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8