Coverage Report

Created: 2025-07-11 06:43

/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
104k
{
35
104k
  PIXEL xorPixel = 0;
36
104k
  BYTE mask = 0x01;
37
38
104k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
104k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
107
    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.8k
{
35
29.8k
  PIXEL xorPixel = 0;
36
29.8k
  BYTE mask = 0x01;
37
38
29.8k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
29.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
33
    return NULL;
46
47
29.7k
  UNROLL(cBits, {
48
29.7k
    PIXEL data = 0;
49
29.7k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
29.7k
    if (bitmask & mask)
52
29.7k
      data = xorPixel ^ fgPel;
53
29.7k
    else
54
29.7k
      data = xorPixel;
55
56
29.7k
    DESTWRITEPIXEL(pbDest, data);
57
29.7k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
29.7k
  });
59
29.7k
  return pbDest;
60
29.7k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
34
74.2k
{
35
74.2k
  PIXEL xorPixel = 0;
36
74.2k
  BYTE mask = 0x01;
37
38
74.2k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
74.2k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
74
    return NULL;
46
47
74.1k
  UNROLL(cBits, {
48
74.1k
    PIXEL data = 0;
49
74.1k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
74.1k
    if (bitmask & mask)
52
74.1k
      data = xorPixel ^ fgPel;
53
74.1k
    else
54
74.1k
      data = xorPixel;
55
56
74.1k
    DESTWRITEPIXEL(pbDest, data);
57
74.1k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
74.1k
  });
59
74.1k
  return pbDest;
60
74.1k
}
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
56.5k
{
70
56.5k
  BYTE mask = 0x01;
71
72
56.5k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
56.5k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
68
    return NULL;
80
81
56.4k
  UNROLL(cBits, {
82
56.4k
    PIXEL data;
83
84
56.4k
    if (bitmask & mask)
85
56.4k
      data = fgPel;
86
56.4k
    else
87
56.4k
      data = BLACK_PIXEL;
88
89
56.4k
    DESTWRITEPIXEL(pbDest, data);
90
56.4k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
56.4k
  });
92
56.4k
  return pbDest;
93
56.4k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
69
22.4k
{
70
22.4k
  BYTE mask = 0x01;
71
72
22.4k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
22.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
26
    return NULL;
80
81
22.4k
  UNROLL(cBits, {
82
22.4k
    PIXEL data;
83
84
22.4k
    if (bitmask & mask)
85
22.4k
      data = fgPel;
86
22.4k
    else
87
22.4k
      data = BLACK_PIXEL;
88
89
22.4k
    DESTWRITEPIXEL(pbDest, data);
90
22.4k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
22.4k
  });
92
22.4k
  return pbDest;
93
22.4k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
69
34.1k
{
70
34.1k
  BYTE mask = 0x01;
71
72
34.1k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
34.1k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
42
    return NULL;
80
81
34.0k
  UNROLL(cBits, {
82
34.0k
    PIXEL data;
83
84
34.0k
    if (bitmask & mask)
85
34.0k
      data = fgPel;
86
34.0k
    else
87
34.0k
      data = BLACK_PIXEL;
88
89
34.0k
    DESTWRITEPIXEL(pbDest, data);
90
34.0k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
34.0k
  });
92
34.0k
  return pbDest;
93
34.0k
}
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
16.6k
{
102
16.6k
  const BYTE* pbSrc = pbSrcBuffer;
103
16.6k
  BYTE* pbDest = pbDestBuffer;
104
16.6k
  PIXEL temp = 0;
105
16.6k
  PIXEL fgPel = WHITE_PIXEL;
106
16.6k
  BOOL fInsertFgPel = FALSE;
107
16.6k
  BOOL fFirstLine = TRUE;
108
16.6k
  BYTE bitmask = 0;
109
16.6k
  PIXEL pixelA = 0;
110
16.6k
  PIXEL pixelB = 0;
111
16.6k
  UINT32 runLength = 0;
112
16.6k
  UINT32 code = 0;
113
16.6k
  UINT32 advance = 0;
114
16.6k
  RLEEXTRA
115
116
16.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
16.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
16.6k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
16.6k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
502k
  while (pbSrc < pbEnd)
134
498k
  {
135
    /* Watch out for the end of the first scanline. */
136
498k
    if (fFirstLine)
137
82.1k
    {
138
82.1k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
12.4k
      {
140
12.4k
        fFirstLine = FALSE;
141
12.4k
        fInsertFgPel = FALSE;
142
12.4k
      }
143
82.1k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
498k
    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
498k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
327k
    {
158
327k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
327k
      if (advance == 0)
160
678
        return FALSE;
161
327k
      pbSrc = pbSrc + advance;
162
163
327k
      if (fFirstLine)
164
36.4k
      {
165
36.4k
        if (fInsertFgPel)
166
25.5k
        {
167
25.5k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
25.5k
          DESTWRITEPIXEL(pbDest, fgPel);
171
25.5k
          runLength = runLength - 1;
172
25.5k
        }
173
174
36.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
97
          return FALSE;
176
177
36.3k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
36.3k
      }
179
290k
      else
180
290k
      {
181
290k
        if (fInsertFgPel)
182
262k
        {
183
262k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
262k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
43
            return FALSE;
187
188
262k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
262k
          runLength--;
190
262k
        }
191
192
290k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
861
          return FALSE;
194
195
289k
        UNROLL(runLength, {
196
289k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
289k
          DESTWRITEPIXEL(pbDest, temp);
198
289k
        });
199
289k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
326k
      fInsertFgPel = TRUE;
203
326k
      continue;
204
327k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
170k
    fInsertFgPel = FALSE;
209
210
170k
    switch (code)
211
170k
    {
212
      /* Handle Foreground Run Orders. */
213
31.7k
      case REGULAR_FG_RUN:
214
33.9k
      case MEGA_MEGA_FG_RUN:
215
50.2k
      case LITE_SET_FG_FG_RUN:
216
51.2k
      case MEGA_MEGA_SET_FG_RUN:
217
51.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
51.2k
        if (advance == 0)
219
107
          return FALSE;
220
51.1k
        pbSrc = pbSrc + advance;
221
222
51.1k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
17.2k
        {
224
17.2k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
219
            return FALSE;
226
17.0k
          SRCREADPIXEL(fgPel, pbSrc);
227
17.0k
        }
228
229
50.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
422
          return FALSE;
231
232
50.5k
        if (fFirstLine)
233
10.3k
        {
234
10.3k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
10.3k
        }
236
40.2k
        else
237
40.2k
        {
238
40.2k
          UNROLL(runLength, {
239
40.2k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
40.2k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
40.2k
          });
242
40.2k
        }
243
244
50.5k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
12.4k
      case LITE_DITHERED_RUN:
248
13.5k
      case MEGA_MEGA_DITHERED_RUN:
249
13.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
13.5k
        if (advance == 0)
251
45
          return FALSE;
252
13.5k
        pbSrc = pbSrc + advance;
253
13.5k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
218
          return FALSE;
255
13.2k
        SRCREADPIXEL(pixelA, pbSrc);
256
13.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
492
          return FALSE;
258
12.7k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
12.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
106
          return FALSE;
262
263
12.6k
        UNROLL(runLength, {
264
12.6k
          DESTWRITEPIXEL(pbDest, pixelA);
265
12.6k
          DESTWRITEPIXEL(pbDest, pixelB);
266
12.6k
        });
267
12.6k
        break;
268
269
      /* Handle Color Run Orders. */
270
52.3k
      case REGULAR_COLOR_RUN:
271
53.6k
      case MEGA_MEGA_COLOR_RUN:
272
53.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
53.6k
        if (advance == 0)
274
64
          return FALSE;
275
53.5k
        pbSrc = pbSrc + advance;
276
53.5k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
306
          return FALSE;
278
53.2k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
53.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
221
          return FALSE;
282
283
53.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
53.0k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
15.2k
      case REGULAR_FGBG_IMAGE:
288
17.4k
      case MEGA_MEGA_FGBG_IMAGE:
289
21.2k
      case LITE_SET_FG_FGBG_IMAGE:
290
22.6k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
22.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
22.6k
        if (advance == 0)
293
128
          return FALSE;
294
22.4k
        pbSrc = pbSrc + advance;
295
296
22.4k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
5.13k
        {
298
5.13k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
184
            return FALSE;
300
4.94k
          SRCREADPIXEL(fgPel, pbSrc);
301
4.94k
        }
302
303
22.3k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
875
          return FALSE;
305
21.4k
        if (fFirstLine)
306
5.18k
        {
307
58.2k
          while (runLength > 8)
308
53.1k
          {
309
53.1k
            bitmask = *pbSrc;
310
53.1k
            pbSrc = pbSrc + 1;
311
53.1k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
53.1k
            if (!pbDest)
314
65
              return FALSE;
315
316
53.0k
            runLength = runLength - 8;
317
53.0k
          }
318
5.18k
        }
319
16.2k
        else
320
16.2k
        {
321
99.9k
          while (runLength > 8)
322
83.7k
          {
323
83.7k
            bitmask = *pbSrc++;
324
325
83.7k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
83.7k
            if (!pbDest)
328
68
              return FALSE;
329
330
83.7k
            runLength = runLength - 8;
331
83.7k
          }
332
16.2k
        }
333
334
21.3k
        if (runLength > 0)
335
18.2k
        {
336
18.2k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
80
            return FALSE;
338
18.1k
          bitmask = *pbSrc++;
339
340
18.1k
          if (fFirstLine)
341
2.86k
          {
342
2.86k
            pbDest =
343
2.86k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
2.86k
          }
345
15.3k
          else
346
15.3k
          {
347
15.3k
            pbDest =
348
15.3k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
15.3k
          }
350
351
18.1k
          if (!pbDest)
352
26
            return FALSE;
353
18.1k
        }
354
355
21.2k
        break;
356
357
      /* Handle Color Image Orders. */
358
21.2k
      case REGULAR_COLOR_IMAGE:
359
12.3k
      case MEGA_MEGA_COLOR_IMAGE:
360
12.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
12.3k
        if (advance == 0)
362
87
          return FALSE;
363
12.2k
        pbSrc = pbSrc + advance;
364
12.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
126
          return FALSE;
366
12.1k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
936
          return FALSE;
368
369
11.2k
        UNROLL(runLength, {
370
3.40k
          SRCREADPIXEL(temp, pbSrc);
371
3.40k
          DESTWRITEPIXEL(pbDest, temp);
372
3.40k
        });
373
7.80k
        break;
374
375
      /* Handle Special Order 1. */
376
7.80k
      case SPECIAL_FGBG_1:
377
2.82k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
2.82k
        pbSrc = pbSrc + 1;
380
381
2.82k
        if (fFirstLine)
382
334
        {
383
334
          pbDest =
384
334
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
334
        }
386
2.49k
        else
387
2.49k
        {
388
2.49k
          pbDest =
389
2.49k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
2.49k
        }
391
392
2.82k
        if (!pbDest)
393
8
          return FALSE;
394
395
2.81k
        break;
396
397
      /* Handle Special Order 2. */
398
2.81k
      case SPECIAL_FGBG_2:
399
2.71k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
2.71k
        pbSrc = pbSrc + 1;
402
403
2.71k
        if (fFirstLine)
404
205
        {
405
205
          pbDest =
406
205
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
205
        }
408
2.51k
        else
409
2.51k
        {
410
2.51k
          pbDest =
411
2.51k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
2.51k
        }
413
414
2.71k
        if (!pbDest)
415
8
          return FALSE;
416
417
2.70k
        break;
418
419
      /* Handle White Order. */
420
3.07k
      case SPECIAL_WHITE:
421
3.07k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
3.07k
        pbSrc = pbSrc + 1;
424
425
3.07k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
6
          return FALSE;
427
428
3.06k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
3.06k
        break;
430
431
      /* Handle Black Order. */
432
2.92k
      case SPECIAL_BLACK:
433
2.92k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
2.92k
        pbSrc = pbSrc + 1;
436
437
2.92k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
7
          return FALSE;
439
440
2.92k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
2.92k
        break;
442
443
6.02k
      default:
444
6.02k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
6.02k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
6.02k
        return FALSE;
447
170k
    }
448
170k
  }
449
450
4.12k
  return TRUE;
451
16.6k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
101
5.54k
{
102
5.54k
  const BYTE* pbSrc = pbSrcBuffer;
103
5.54k
  BYTE* pbDest = pbDestBuffer;
104
5.54k
  PIXEL temp = 0;
105
5.54k
  PIXEL fgPel = WHITE_PIXEL;
106
5.54k
  BOOL fInsertFgPel = FALSE;
107
5.54k
  BOOL fFirstLine = TRUE;
108
5.54k
  BYTE bitmask = 0;
109
5.54k
  PIXEL pixelA = 0;
110
5.54k
  PIXEL pixelB = 0;
111
5.54k
  UINT32 runLength = 0;
112
5.54k
  UINT32 code = 0;
113
5.54k
  UINT32 advance = 0;
114
5.54k
  RLEEXTRA
115
116
5.54k
  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.54k
  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.54k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
5.54k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
164k
  while (pbSrc < pbEnd)
134
163k
  {
135
    /* Watch out for the end of the first scanline. */
136
163k
    if (fFirstLine)
137
27.5k
    {
138
27.5k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
3.95k
      {
140
3.95k
        fFirstLine = FALSE;
141
3.95k
        fInsertFgPel = FALSE;
142
3.95k
      }
143
27.5k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
163k
    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
163k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
107k
    {
158
107k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
107k
      if (advance == 0)
160
186
        return FALSE;
161
107k
      pbSrc = pbSrc + advance;
162
163
107k
      if (fFirstLine)
164
12.2k
      {
165
12.2k
        if (fInsertFgPel)
166
8.40k
        {
167
8.40k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
8.40k
          DESTWRITEPIXEL(pbDest, fgPel);
171
8.40k
          runLength = runLength - 1;
172
8.40k
        }
173
174
12.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
33
          return FALSE;
176
177
12.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
12.2k
      }
179
94.8k
      else
180
94.8k
      {
181
94.8k
        if (fInsertFgPel)
182
85.9k
        {
183
85.9k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
85.9k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
9
            return FALSE;
187
188
85.9k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
85.9k
          runLength--;
190
85.9k
        }
191
192
94.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
279
          return FALSE;
194
195
94.5k
        UNROLL(runLength, {
196
94.5k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
94.5k
          DESTWRITEPIXEL(pbDest, temp);
198
94.5k
        });
199
94.5k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
106k
      fInsertFgPel = TRUE;
203
106k
      continue;
204
107k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
56.1k
    fInsertFgPel = FALSE;
209
210
56.1k
    switch (code)
211
56.1k
    {
212
      /* Handle Foreground Run Orders. */
213
10.1k
      case REGULAR_FG_RUN:
214
10.8k
      case MEGA_MEGA_FG_RUN:
215
16.1k
      case LITE_SET_FG_FG_RUN:
216
16.5k
      case MEGA_MEGA_SET_FG_RUN:
217
16.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
16.5k
        if (advance == 0)
219
31
          return FALSE;
220
16.5k
        pbSrc = pbSrc + advance;
221
222
16.5k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
5.67k
        {
224
5.67k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
77
            return FALSE;
226
5.59k
          SRCREADPIXEL(fgPel, pbSrc);
227
5.59k
        }
228
229
16.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
112
          return FALSE;
231
232
16.3k
        if (fFirstLine)
233
3.59k
        {
234
3.59k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
3.59k
        }
236
12.7k
        else
237
12.7k
        {
238
12.7k
          UNROLL(runLength, {
239
12.7k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
12.7k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
12.7k
          });
242
12.7k
        }
243
244
16.3k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
3.99k
      case LITE_DITHERED_RUN:
248
4.41k
      case MEGA_MEGA_DITHERED_RUN:
249
4.41k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
4.41k
        if (advance == 0)
251
13
          return FALSE;
252
4.40k
        pbSrc = pbSrc + advance;
253
4.40k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
84
          return FALSE;
255
4.32k
        SRCREADPIXEL(pixelA, pbSrc);
256
4.32k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
238
          return FALSE;
258
4.08k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
4.08k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
32
          return FALSE;
262
263
4.05k
        UNROLL(runLength, {
264
4.05k
          DESTWRITEPIXEL(pbDest, pixelA);
265
4.05k
          DESTWRITEPIXEL(pbDest, pixelB);
266
4.05k
        });
267
4.05k
        break;
268
269
      /* Handle Color Run Orders. */
270
17.8k
      case REGULAR_COLOR_RUN:
271
18.2k
      case MEGA_MEGA_COLOR_RUN:
272
18.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
18.2k
        if (advance == 0)
274
16
          return FALSE;
275
18.2k
        pbSrc = pbSrc + advance;
276
18.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
118
          return FALSE;
278
18.1k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
18.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
69
          return FALSE;
282
283
18.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
18.0k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
4.78k
      case REGULAR_FGBG_IMAGE:
288
5.52k
      case MEGA_MEGA_FGBG_IMAGE:
289
6.78k
      case LITE_SET_FG_FGBG_IMAGE:
290
7.22k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
7.22k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
7.22k
        if (advance == 0)
293
42
          return FALSE;
294
7.18k
        pbSrc = pbSrc + advance;
295
296
7.18k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
1.68k
        {
298
1.68k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
68
            return FALSE;
300
1.61k
          SRCREADPIXEL(fgPel, pbSrc);
301
1.61k
        }
302
303
7.11k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
289
          return FALSE;
305
6.83k
        if (fFirstLine)
306
1.84k
        {
307
23.0k
          while (runLength > 8)
308
21.1k
          {
309
21.1k
            bitmask = *pbSrc;
310
21.1k
            pbSrc = pbSrc + 1;
311
21.1k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
21.1k
            if (!pbDest)
314
25
              return FALSE;
315
316
21.1k
            runLength = runLength - 8;
317
21.1k
          }
318
1.84k
        }
319
4.99k
        else
320
4.99k
        {
321
28.4k
          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
22
              return FALSE;
329
330
23.4k
            runLength = runLength - 8;
331
23.4k
          }
332
4.99k
        }
333
334
6.78k
        if (runLength > 0)
335
5.77k
        {
336
5.77k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
30
            return FALSE;
338
5.74k
          bitmask = *pbSrc++;
339
340
5.74k
          if (fFirstLine)
341
1.09k
          {
342
1.09k
            pbDest =
343
1.09k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.09k
          }
345
4.65k
          else
346
4.65k
          {
347
4.65k
            pbDest =
348
4.65k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
4.65k
          }
350
351
5.74k
          if (!pbDest)
352
8
            return FALSE;
353
5.74k
        }
354
355
6.74k
        break;
356
357
      /* Handle Color Image Orders. */
358
6.74k
      case REGULAR_COLOR_IMAGE:
359
3.77k
      case MEGA_MEGA_COLOR_IMAGE:
360
3.77k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
3.77k
        if (advance == 0)
362
29
          return FALSE;
363
3.74k
        pbSrc = pbSrc + advance;
364
3.74k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
36
          return FALSE;
366
3.70k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
304
          return FALSE;
368
369
3.40k
        UNROLL(runLength, {
370
3.40k
          SRCREADPIXEL(temp, pbSrc);
371
3.40k
          DESTWRITEPIXEL(pbDest, temp);
372
3.40k
        });
373
3.40k
        break;
374
375
      /* Handle Special Order 1. */
376
975
      case SPECIAL_FGBG_1:
377
975
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
975
        pbSrc = pbSrc + 1;
380
381
975
        if (fFirstLine)
382
94
        {
383
94
          pbDest =
384
94
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
94
        }
386
881
        else
387
881
        {
388
881
          pbDest =
389
881
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
881
        }
391
392
975
        if (!pbDest)
393
2
          return FALSE;
394
395
973
        break;
396
397
      /* Handle Special Order 2. */
398
973
      case SPECIAL_FGBG_2:
399
895
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
895
        pbSrc = pbSrc + 1;
402
403
895
        if (fFirstLine)
404
69
        {
405
69
          pbDest =
406
69
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
69
        }
408
826
        else
409
826
        {
410
826
          pbDest =
411
826
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
826
        }
413
414
895
        if (!pbDest)
415
2
          return FALSE;
416
417
893
        break;
418
419
      /* Handle White Order. */
420
1.01k
      case SPECIAL_WHITE:
421
1.01k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
1.01k
        pbSrc = pbSrc + 1;
424
425
1.01k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
2
          return FALSE;
427
428
1.01k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
1.01k
        break;
430
431
      /* Handle Black Order. */
432
1.03k
      case SPECIAL_BLACK:
433
1.03k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
1.03k
        pbSrc = pbSrc + 1;
436
437
1.03k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
3
          return FALSE;
439
440
1.03k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
1.03k
        break;
442
443
1.98k
      default:
444
1.98k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
1.98k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
1.98k
        return FALSE;
447
56.1k
    }
448
56.1k
  }
449
450
1.40k
  return TRUE;
451
5.54k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
101
11.0k
{
102
11.0k
  const BYTE* pbSrc = pbSrcBuffer;
103
11.0k
  BYTE* pbDest = pbDestBuffer;
104
11.0k
  PIXEL temp = 0;
105
11.0k
  PIXEL fgPel = WHITE_PIXEL;
106
11.0k
  BOOL fInsertFgPel = FALSE;
107
11.0k
  BOOL fFirstLine = TRUE;
108
11.0k
  BYTE bitmask = 0;
109
11.0k
  PIXEL pixelA = 0;
110
11.0k
  PIXEL pixelB = 0;
111
11.0k
  UINT32 runLength = 0;
112
11.0k
  UINT32 code = 0;
113
11.0k
  UINT32 advance = 0;
114
11.0k
  RLEEXTRA
115
116
11.0k
  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.0k
  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.0k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
11.0k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
338k
  while (pbSrc < pbEnd)
134
335k
  {
135
    /* Watch out for the end of the first scanline. */
136
335k
    if (fFirstLine)
137
54.5k
    {
138
54.5k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
8.49k
      {
140
8.49k
        fFirstLine = FALSE;
141
8.49k
        fInsertFgPel = FALSE;
142
8.49k
      }
143
54.5k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
335k
    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
335k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
220k
    {
158
220k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
220k
      if (advance == 0)
160
492
        return FALSE;
161
220k
      pbSrc = pbSrc + advance;
162
163
220k
      if (fFirstLine)
164
24.2k
      {
165
24.2k
        if (fInsertFgPel)
166
17.1k
        {
167
17.1k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
17.1k
          DESTWRITEPIXEL(pbDest, fgPel);
171
17.1k
          runLength = runLength - 1;
172
17.1k
        }
173
174
24.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
64
          return FALSE;
176
177
24.1k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
24.1k
      }
179
195k
      else
180
195k
      {
181
195k
        if (fInsertFgPel)
182
176k
        {
183
176k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
176k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
34
            return FALSE;
187
188
176k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
176k
          runLength--;
190
176k
        }
191
192
195k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
582
          return FALSE;
194
195
195k
        UNROLL(runLength, {
196
195k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
195k
          DESTWRITEPIXEL(pbDest, temp);
198
195k
        });
199
195k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
219k
      fInsertFgPel = TRUE;
203
219k
      continue;
204
220k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
114k
    fInsertFgPel = FALSE;
209
210
114k
    switch (code)
211
114k
    {
212
      /* Handle Foreground Run Orders. */
213
21.6k
      case REGULAR_FG_RUN:
214
23.1k
      case MEGA_MEGA_FG_RUN:
215
34.0k
      case LITE_SET_FG_FG_RUN:
216
34.7k
      case MEGA_MEGA_SET_FG_RUN:
217
34.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
34.7k
        if (advance == 0)
219
76
          return FALSE;
220
34.6k
        pbSrc = pbSrc + advance;
221
222
34.6k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
11.5k
        {
224
11.5k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
142
            return FALSE;
226
11.4k
          SRCREADPIXEL(fgPel, pbSrc);
227
11.4k
        }
228
229
34.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
310
          return FALSE;
231
232
34.2k
        if (fFirstLine)
233
6.71k
        {
234
6.71k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
6.71k
        }
236
27.4k
        else
237
27.4k
        {
238
27.4k
          UNROLL(runLength, {
239
27.4k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
27.4k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
27.4k
          });
242
27.4k
        }
243
244
34.2k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
8.44k
      case LITE_DITHERED_RUN:
248
9.13k
      case MEGA_MEGA_DITHERED_RUN:
249
9.13k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
9.13k
        if (advance == 0)
251
32
          return FALSE;
252
9.10k
        pbSrc = pbSrc + advance;
253
9.10k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
134
          return FALSE;
255
8.96k
        SRCREADPIXEL(pixelA, pbSrc);
256
8.96k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
254
          return FALSE;
258
8.71k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
8.71k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
74
          return FALSE;
262
263
8.63k
        UNROLL(runLength, {
264
8.63k
          DESTWRITEPIXEL(pbDest, pixelA);
265
8.63k
          DESTWRITEPIXEL(pbDest, pixelB);
266
8.63k
        });
267
8.63k
        break;
268
269
      /* Handle Color Run Orders. */
270
34.5k
      case REGULAR_COLOR_RUN:
271
35.3k
      case MEGA_MEGA_COLOR_RUN:
272
35.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
35.3k
        if (advance == 0)
274
48
          return FALSE;
275
35.3k
        pbSrc = pbSrc + advance;
276
35.3k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
188
          return FALSE;
278
35.1k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
35.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
152
          return FALSE;
282
283
34.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
34.9k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
10.4k
      case REGULAR_FGBG_IMAGE:
288
11.9k
      case MEGA_MEGA_FGBG_IMAGE:
289
14.4k
      case LITE_SET_FG_FGBG_IMAGE:
290
15.3k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
15.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
15.3k
        if (advance == 0)
293
86
          return FALSE;
294
15.3k
        pbSrc = pbSrc + advance;
295
296
15.3k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
3.45k
        {
298
3.45k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
116
            return FALSE;
300
3.33k
          SRCREADPIXEL(fgPel, pbSrc);
301
3.33k
        }
302
303
15.1k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
586
          return FALSE;
305
14.6k
        if (fFirstLine)
306
3.34k
        {
307
35.2k
          while (runLength > 8)
308
31.9k
          {
309
31.9k
            bitmask = *pbSrc;
310
31.9k
            pbSrc = pbSrc + 1;
311
31.9k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
31.9k
            if (!pbDest)
314
40
              return FALSE;
315
316
31.9k
            runLength = runLength - 8;
317
31.9k
          }
318
3.34k
        }
319
11.2k
        else
320
11.2k
        {
321
71.5k
          while (runLength > 8)
322
60.3k
          {
323
60.3k
            bitmask = *pbSrc++;
324
325
60.3k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
60.3k
            if (!pbDest)
328
46
              return FALSE;
329
330
60.2k
            runLength = runLength - 8;
331
60.2k
          }
332
11.2k
        }
333
334
14.5k
        if (runLength > 0)
335
12.4k
        {
336
12.4k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
50
            return FALSE;
338
12.4k
          bitmask = *pbSrc++;
339
340
12.4k
          if (fFirstLine)
341
1.76k
          {
342
1.76k
            pbDest =
343
1.76k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.76k
          }
345
10.6k
          else
346
10.6k
          {
347
10.6k
            pbDest =
348
10.6k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
10.6k
          }
350
351
12.4k
          if (!pbDest)
352
18
            return FALSE;
353
12.4k
        }
354
355
14.4k
        break;
356
357
      /* Handle Color Image Orders. */
358
14.4k
      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
58
          return FALSE;
363
8.52k
        pbSrc = pbSrc + advance;
364
8.52k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
90
          return FALSE;
366
8.43k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
632
          return FALSE;
368
369
7.80k
        UNROLL(runLength, {
370
7.80k
          SRCREADPIXEL(temp, pbSrc);
371
7.80k
          DESTWRITEPIXEL(pbDest, temp);
372
7.80k
        });
373
7.80k
        break;
374
375
      /* Handle Special Order 1. */
376
7.80k
      case SPECIAL_FGBG_1:
377
1.85k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
1.85k
        pbSrc = pbSrc + 1;
380
381
1.85k
        if (fFirstLine)
382
240
        {
383
240
          pbDest =
384
240
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
240
        }
386
1.61k
        else
387
1.61k
        {
388
1.61k
          pbDest =
389
1.61k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
1.61k
        }
391
392
1.85k
        if (!pbDest)
393
6
          return FALSE;
394
395
1.84k
        break;
396
397
      /* Handle Special Order 2. */
398
1.84k
      case SPECIAL_FGBG_2:
399
1.82k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
1.82k
        pbSrc = pbSrc + 1;
402
403
1.82k
        if (fFirstLine)
404
136
        {
405
136
          pbDest =
406
136
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
136
        }
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.82k
        if (!pbDest)
415
6
          return FALSE;
416
417
1.81k
        break;
418
419
      /* Handle White Order. */
420
2.05k
      case SPECIAL_WHITE:
421
2.05k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
2.05k
        pbSrc = pbSrc + 1;
424
425
2.05k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
4
          return FALSE;
427
428
2.05k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
2.05k
        break;
430
431
      /* Handle Black Order. */
432
1.89k
      case SPECIAL_BLACK:
433
1.89k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
1.89k
        pbSrc = pbSrc + 1;
436
437
1.89k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
4
          return FALSE;
439
440
1.89k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
1.89k
        break;
442
443
4.04k
      default:
444
4.04k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
4.04k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
4.04k
        return FALSE;
447
114k
    }
448
114k
  }
449
450
2.72k
  return TRUE;
451
11.0k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8