Coverage Report

Created: 2025-08-26 06:33

/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
105k
{
35
105k
  PIXEL xorPixel = 0;
36
105k
  BYTE mask = 0x01;
37
38
105k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
105k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
86
    return NULL;
46
47
105k
  UNROLL(cBits, {
48
105k
    PIXEL data = 0;
49
105k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
105k
    if (bitmask & mask)
52
105k
      data = xorPixel ^ fgPel;
53
105k
    else
54
105k
      data = xorPixel;
55
56
105k
    DESTWRITEPIXEL(pbDest, data);
57
105k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
105k
  });
59
105k
  return pbDest;
60
105k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
34
28.8k
{
35
28.8k
  PIXEL xorPixel = 0;
36
28.8k
  BYTE mask = 0x01;
37
38
28.8k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
28.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
26
    return NULL;
46
47
28.8k
  UNROLL(cBits, {
48
28.8k
    PIXEL data = 0;
49
28.8k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
28.8k
    if (bitmask & mask)
52
28.8k
      data = xorPixel ^ fgPel;
53
28.8k
    else
54
28.8k
      data = xorPixel;
55
56
28.8k
    DESTWRITEPIXEL(pbDest, data);
57
28.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
28.8k
  });
59
28.8k
  return pbDest;
60
28.8k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
34
77.0k
{
35
77.0k
  PIXEL xorPixel = 0;
36
77.0k
  BYTE mask = 0x01;
37
38
77.0k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
77.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
60
    return NULL;
46
47
76.9k
  UNROLL(cBits, {
48
76.9k
    PIXEL data = 0;
49
76.9k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
76.9k
    if (bitmask & mask)
52
76.9k
      data = xorPixel ^ fgPel;
53
76.9k
    else
54
76.9k
      data = xorPixel;
55
56
76.9k
    DESTWRITEPIXEL(pbDest, data);
57
76.9k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
76.9k
  });
59
76.9k
  return pbDest;
60
76.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
41.3k
{
70
41.3k
  BYTE mask = 0x01;
71
72
41.3k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
41.3k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
44
    return NULL;
80
81
41.3k
  UNROLL(cBits, {
82
41.3k
    PIXEL data;
83
84
41.3k
    if (bitmask & mask)
85
41.3k
      data = fgPel;
86
41.3k
    else
87
41.3k
      data = BLACK_PIXEL;
88
89
41.3k
    DESTWRITEPIXEL(pbDest, data);
90
41.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
41.3k
  });
92
41.3k
  return pbDest;
93
41.3k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
69
16.8k
{
70
16.8k
  BYTE mask = 0x01;
71
72
16.8k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
16.8k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
18
    return NULL;
80
81
16.8k
  UNROLL(cBits, {
82
16.8k
    PIXEL data;
83
84
16.8k
    if (bitmask & mask)
85
16.8k
      data = fgPel;
86
16.8k
    else
87
16.8k
      data = BLACK_PIXEL;
88
89
16.8k
    DESTWRITEPIXEL(pbDest, data);
90
16.8k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
16.8k
  });
92
16.8k
  return pbDest;
93
16.8k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
69
24.4k
{
70
24.4k
  BYTE mask = 0x01;
71
72
24.4k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
24.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
26
    return NULL;
80
81
24.4k
  UNROLL(cBits, {
82
24.4k
    PIXEL data;
83
84
24.4k
    if (bitmask & mask)
85
24.4k
      data = fgPel;
86
24.4k
    else
87
24.4k
      data = BLACK_PIXEL;
88
89
24.4k
    DESTWRITEPIXEL(pbDest, data);
90
24.4k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
24.4k
  });
92
24.4k
  return pbDest;
93
24.4k
}
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.8k
{
102
17.8k
  const BYTE* pbSrc = pbSrcBuffer;
103
17.8k
  BYTE* pbDest = pbDestBuffer;
104
17.8k
  PIXEL temp = 0;
105
17.8k
  PIXEL fgPel = WHITE_PIXEL;
106
17.8k
  BOOL fInsertFgPel = FALSE;
107
17.8k
  BOOL fFirstLine = TRUE;
108
17.8k
  BYTE bitmask = 0;
109
17.8k
  PIXEL pixelA = 0;
110
17.8k
  PIXEL pixelB = 0;
111
17.8k
  UINT32 runLength = 0;
112
17.8k
  UINT32 code = 0;
113
17.8k
  UINT32 advance = 0;
114
17.8k
  RLEEXTRA
115
116
17.8k
  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.8k
  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.8k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
17.8k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
532k
  while (pbSrc < pbEnd)
134
527k
  {
135
    /* Watch out for the end of the first scanline. */
136
527k
    if (fFirstLine)
137
86.6k
    {
138
86.6k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
13.2k
      {
140
13.2k
        fFirstLine = FALSE;
141
13.2k
        fInsertFgPel = FALSE;
142
13.2k
      }
143
86.6k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
527k
    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
527k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
353k
    {
158
353k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
353k
      if (advance == 0)
160
692
        return FALSE;
161
352k
      pbSrc = pbSrc + advance;
162
163
352k
      if (fFirstLine)
164
37.8k
      {
165
37.8k
        if (fInsertFgPel)
166
26.0k
        {
167
26.0k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
26.0k
          DESTWRITEPIXEL(pbDest, fgPel);
171
26.0k
          runLength = runLength - 1;
172
26.0k
        }
173
174
37.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
114
          return FALSE;
176
177
37.7k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
37.7k
      }
179
314k
      else
180
314k
      {
181
314k
        if (fInsertFgPel)
182
283k
        {
183
283k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
283k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
68
            return FALSE;
187
188
283k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
283k
          runLength--;
190
283k
        }
191
192
314k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
1.01k
          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
351k
      fInsertFgPel = TRUE;
203
351k
      continue;
204
352k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
174k
    fInsertFgPel = FALSE;
209
210
174k
    switch (code)
211
174k
    {
212
      /* Handle Foreground Run Orders. */
213
31.8k
      case REGULAR_FG_RUN:
214
34.4k
      case MEGA_MEGA_FG_RUN:
215
52.1k
      case LITE_SET_FG_FG_RUN:
216
53.2k
      case MEGA_MEGA_SET_FG_RUN:
217
53.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
53.2k
        if (advance == 0)
219
117
          return FALSE;
220
53.1k
        pbSrc = pbSrc + advance;
221
222
53.1k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
18.7k
        {
224
18.7k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
248
            return FALSE;
226
18.5k
          SRCREADPIXEL(fgPel, pbSrc);
227
18.5k
        }
228
229
52.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
392
          return FALSE;
231
232
52.4k
        if (fFirstLine)
233
11.8k
        {
234
11.8k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
11.8k
        }
236
40.6k
        else
237
40.6k
        {
238
40.6k
          UNROLL(runLength, {
239
40.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
40.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
40.6k
          });
242
40.6k
        }
243
244
52.4k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
10.7k
      case LITE_DITHERED_RUN:
248
11.8k
      case MEGA_MEGA_DITHERED_RUN:
249
11.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
11.8k
        if (advance == 0)
251
55
          return FALSE;
252
11.8k
        pbSrc = pbSrc + advance;
253
11.8k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
266
          return FALSE;
255
11.5k
        SRCREADPIXEL(pixelA, pbSrc);
256
11.5k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
530
          return FALSE;
258
11.0k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
11.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
162
          return FALSE;
262
263
10.8k
        UNROLL(runLength, {
264
10.8k
          DESTWRITEPIXEL(pbDest, pixelA);
265
10.8k
          DESTWRITEPIXEL(pbDest, pixelB);
266
10.8k
        });
267
10.8k
        break;
268
269
      /* Handle Color Run Orders. */
270
52.6k
      case REGULAR_COLOR_RUN:
271
54.3k
      case MEGA_MEGA_COLOR_RUN:
272
54.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
54.3k
        if (advance == 0)
274
78
          return FALSE;
275
54.3k
        pbSrc = pbSrc + advance;
276
54.3k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
345
          return FALSE;
278
53.9k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
53.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
243
          return FALSE;
282
283
53.7k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
53.7k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
15.0k
      case REGULAR_FGBG_IMAGE:
288
17.1k
      case MEGA_MEGA_FGBG_IMAGE:
289
21.0k
      case LITE_SET_FG_FGBG_IMAGE:
290
23.3k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
23.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
23.3k
        if (advance == 0)
293
132
          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
6.17k
        {
298
6.17k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
204
            return FALSE;
300
5.96k
          SRCREADPIXEL(fgPel, pbSrc);
301
5.96k
        }
302
303
23.0k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
894
          return FALSE;
305
22.1k
        if (fFirstLine)
306
5.26k
        {
307
43.0k
          while (runLength > 8)
308
37.7k
          {
309
37.7k
            bitmask = *pbSrc;
310
37.7k
            pbSrc = pbSrc + 1;
311
37.7k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
37.7k
            if (!pbDest)
314
44
              return FALSE;
315
316
37.7k
            runLength = runLength - 8;
317
37.7k
          }
318
5.26k
        }
319
16.8k
        else
320
16.8k
        {
321
102k
          while (runLength > 8)
322
85.8k
          {
323
85.8k
            bitmask = *pbSrc++;
324
325
85.8k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
85.8k
            if (!pbDest)
328
57
              return FALSE;
329
330
85.8k
            runLength = runLength - 8;
331
85.8k
          }
332
16.8k
        }
333
334
22.0k
        if (runLength > 0)
335
18.1k
        {
336
18.1k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
98
            return FALSE;
338
18.0k
          bitmask = *pbSrc++;
339
340
18.0k
          if (fFirstLine)
341
2.96k
          {
342
2.96k
            pbDest =
343
2.96k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
2.96k
          }
345
15.0k
          else
346
15.0k
          {
347
15.0k
            pbDest =
348
15.0k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
15.0k
          }
350
351
18.0k
          if (!pbDest)
352
17
            return FALSE;
353
18.0k
        }
354
355
21.9k
        break;
356
357
      /* Handle Color Image Orders. */
358
21.9k
      case REGULAR_COLOR_IMAGE:
359
12.9k
      case MEGA_MEGA_COLOR_IMAGE:
360
12.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
12.9k
        if (advance == 0)
362
72
          return FALSE;
363
12.9k
        pbSrc = pbSrc + advance;
364
12.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
146
          return FALSE;
366
12.7k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
974
          return FALSE;
368
369
11.7k
        UNROLL(runLength, {
370
3.76k
          SRCREADPIXEL(temp, pbSrc);
371
3.76k
          DESTWRITEPIXEL(pbDest, temp);
372
3.76k
        });
373
8.02k
        break;
374
375
      /* Handle Special Order 1. */
376
8.02k
      case SPECIAL_FGBG_1:
377
2.64k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
2.64k
        pbSrc = pbSrc + 1;
380
381
2.64k
        if (fFirstLine)
382
350
        {
383
350
          pbDest =
384
350
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
350
        }
386
2.29k
        else
387
2.29k
        {
388
2.29k
          pbDest =
389
2.29k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
2.29k
        }
391
392
2.64k
        if (!pbDest)
393
6
          return FALSE;
394
395
2.64k
        break;
396
397
      /* Handle Special Order 2. */
398
2.94k
      case SPECIAL_FGBG_2:
399
2.94k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
2.94k
        pbSrc = pbSrc + 1;
402
403
2.94k
        if (fFirstLine)
404
268
        {
405
268
          pbDest =
406
268
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
268
        }
408
2.67k
        else
409
2.67k
        {
410
2.67k
          pbDest =
411
2.67k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
2.67k
        }
413
414
2.94k
        if (!pbDest)
415
6
          return FALSE;
416
417
2.94k
        break;
418
419
      /* Handle White Order. */
420
4.15k
      case SPECIAL_WHITE:
421
4.15k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
4.15k
        pbSrc = pbSrc + 1;
424
425
4.15k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
3
          return FALSE;
427
428
4.15k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
4.15k
        break;
430
431
      /* Handle Black Order. */
432
2.35k
      case SPECIAL_BLACK:
433
2.35k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
2.35k
        pbSrc = pbSrc + 1;
436
437
2.35k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
3
          return FALSE;
439
440
2.35k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
2.35k
        break;
442
443
6.27k
      default:
444
6.27k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
6.27k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
6.27k
        return FALSE;
447
174k
    }
448
174k
  }
449
450
4.58k
  return TRUE;
451
17.8k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
101
5.94k
{
102
5.94k
  const BYTE* pbSrc = pbSrcBuffer;
103
5.94k
  BYTE* pbDest = pbDestBuffer;
104
5.94k
  PIXEL temp = 0;
105
5.94k
  PIXEL fgPel = WHITE_PIXEL;
106
5.94k
  BOOL fInsertFgPel = FALSE;
107
5.94k
  BOOL fFirstLine = TRUE;
108
5.94k
  BYTE bitmask = 0;
109
5.94k
  PIXEL pixelA = 0;
110
5.94k
  PIXEL pixelB = 0;
111
5.94k
  UINT32 runLength = 0;
112
5.94k
  UINT32 code = 0;
113
5.94k
  UINT32 advance = 0;
114
5.94k
  RLEEXTRA
115
116
5.94k
  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.94k
  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.94k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
5.94k
  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.0k
    {
138
29.0k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
4.20k
      {
140
4.20k
        fFirstLine = FALSE;
141
4.20k
        fInsertFgPel = FALSE;
142
4.20k
      }
143
29.0k
    }
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
114k
    {
158
114k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
114k
      if (advance == 0)
160
184
        return FALSE;
161
114k
      pbSrc = pbSrc + advance;
162
163
114k
      if (fFirstLine)
164
12.7k
      {
165
12.7k
        if (fInsertFgPel)
166
8.63k
        {
167
8.63k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
8.63k
          DESTWRITEPIXEL(pbDest, fgPel);
171
8.63k
          runLength = runLength - 1;
172
8.63k
        }
173
174
12.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
40
          return FALSE;
176
177
12.7k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
12.7k
      }
179
101k
      else
180
101k
      {
181
101k
        if (fInsertFgPel)
182
92.2k
        {
183
92.2k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
92.2k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
20
            return FALSE;
187
188
92.1k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
92.1k
          runLength--;
190
92.1k
        }
191
192
101k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
322
          return FALSE;
194
195
101k
        UNROLL(runLength, {
196
101k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
101k
          DESTWRITEPIXEL(pbDest, temp);
198
101k
        });
199
101k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
114k
      fInsertFgPel = TRUE;
203
114k
      continue;
204
114k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
55.6k
    fInsertFgPel = FALSE;
209
210
55.6k
    switch (code)
211
55.6k
    {
212
      /* Handle Foreground Run Orders. */
213
9.68k
      case REGULAR_FG_RUN:
214
10.5k
      case MEGA_MEGA_FG_RUN:
215
16.0k
      case LITE_SET_FG_FG_RUN:
216
16.4k
      case MEGA_MEGA_SET_FG_RUN:
217
16.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
16.4k
        if (advance == 0)
219
33
          return FALSE;
220
16.3k
        pbSrc = pbSrc + advance;
221
222
16.3k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
5.88k
        {
224
5.88k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
92
            return FALSE;
226
5.78k
          SRCREADPIXEL(fgPel, pbSrc);
227
5.78k
        }
228
229
16.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
102
          return FALSE;
231
232
16.1k
        if (fFirstLine)
233
4.02k
        {
234
4.02k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
4.02k
        }
236
12.1k
        else
237
12.1k
        {
238
12.1k
          UNROLL(runLength, {
239
12.1k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
12.1k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
12.1k
          });
242
12.1k
        }
243
244
16.1k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
3.48k
      case LITE_DITHERED_RUN:
248
3.91k
      case MEGA_MEGA_DITHERED_RUN:
249
3.91k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
3.91k
        if (advance == 0)
251
15
          return FALSE;
252
3.90k
        pbSrc = pbSrc + advance;
253
3.90k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
106
          return FALSE;
255
3.79k
        SRCREADPIXEL(pixelA, pbSrc);
256
3.79k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
256
          return FALSE;
258
3.53k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
3.53k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
46
          return FALSE;
262
263
3.49k
        UNROLL(runLength, {
264
3.49k
          DESTWRITEPIXEL(pbDest, pixelA);
265
3.49k
          DESTWRITEPIXEL(pbDest, pixelB);
266
3.49k
        });
267
3.49k
        break;
268
269
      /* Handle Color Run Orders. */
270
16.8k
      case REGULAR_COLOR_RUN:
271
17.4k
      case MEGA_MEGA_COLOR_RUN:
272
17.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
17.4k
        if (advance == 0)
274
20
          return FALSE;
275
17.3k
        pbSrc = pbSrc + advance;
276
17.3k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
139
          return FALSE;
278
17.2k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
17.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
91
          return FALSE;
282
283
17.1k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
17.1k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
4.76k
      case REGULAR_FGBG_IMAGE:
288
5.46k
      case MEGA_MEGA_FGBG_IMAGE:
289
6.74k
      case LITE_SET_FG_FGBG_IMAGE:
290
7.51k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
7.51k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
7.51k
        if (advance == 0)
293
38
          return FALSE;
294
7.48k
        pbSrc = pbSrc + advance;
295
296
7.48k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
2.03k
        {
298
2.03k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
72
            return FALSE;
300
1.96k
          SRCREADPIXEL(fgPel, pbSrc);
301
1.96k
        }
302
303
7.40k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
290
          return FALSE;
305
7.11k
        if (fFirstLine)
306
1.93k
        {
307
17.4k
          while (runLength > 8)
308
15.5k
          {
309
15.5k
            bitmask = *pbSrc;
310
15.5k
            pbSrc = pbSrc + 1;
311
15.5k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
15.5k
            if (!pbDest)
314
18
              return FALSE;
315
316
15.5k
            runLength = runLength - 8;
317
15.5k
          }
318
1.93k
        }
319
5.18k
        else
320
5.18k
        {
321
27.7k
          while (runLength > 8)
322
22.5k
          {
323
22.5k
            bitmask = *pbSrc++;
324
325
22.5k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
22.5k
            if (!pbDest)
328
15
              return FALSE;
329
330
22.5k
            runLength = runLength - 8;
331
22.5k
          }
332
5.18k
        }
333
334
7.08k
        if (runLength > 0)
335
5.78k
        {
336
5.78k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
38
            return FALSE;
338
5.74k
          bitmask = *pbSrc++;
339
340
5.74k
          if (fFirstLine)
341
1.16k
          {
342
1.16k
            pbDest =
343
1.16k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.16k
          }
345
4.58k
          else
346
4.58k
          {
347
4.58k
            pbDest =
348
4.58k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
4.58k
          }
350
351
5.74k
          if (!pbDest)
352
7
            return FALSE;
353
5.74k
        }
354
355
7.04k
        break;
356
357
      /* Handle Color Image Orders. */
358
7.04k
      case REGULAR_COLOR_IMAGE:
359
4.16k
      case MEGA_MEGA_COLOR_IMAGE:
360
4.16k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
4.16k
        if (advance == 0)
362
24
          return FALSE;
363
4.14k
        pbSrc = pbSrc + advance;
364
4.14k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
52
          return FALSE;
366
4.09k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
326
          return FALSE;
368
369
3.76k
        UNROLL(runLength, {
370
3.76k
          SRCREADPIXEL(temp, pbSrc);
371
3.76k
          DESTWRITEPIXEL(pbDest, temp);
372
3.76k
        });
373
3.76k
        break;
374
375
      /* Handle Special Order 1. */
376
918
      case SPECIAL_FGBG_1:
377
918
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
918
        pbSrc = pbSrc + 1;
380
381
918
        if (fFirstLine)
382
90
        {
383
90
          pbDest =
384
90
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
90
        }
386
828
        else
387
828
        {
388
828
          pbDest =
389
828
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
828
        }
391
392
918
        if (!pbDest)
393
2
          return FALSE;
394
395
916
        break;
396
397
      /* Handle Special Order 2. */
398
990
      case SPECIAL_FGBG_2:
399
990
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
990
        pbSrc = pbSrc + 1;
402
403
990
        if (fFirstLine)
404
88
        {
405
88
          pbDest =
406
88
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
88
        }
408
902
        else
409
902
        {
410
902
          pbDest =
411
902
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
902
        }
413
414
990
        if (!pbDest)
415
2
          return FALSE;
416
417
988
        break;
418
419
      /* Handle White Order. */
420
1.36k
      case SPECIAL_WHITE:
421
1.36k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
1.36k
        pbSrc = pbSrc + 1;
424
425
1.36k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
1
          return FALSE;
427
428
1.36k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
1.36k
        break;
430
431
      /* Handle Black Order. */
432
847
      case SPECIAL_BLACK:
433
847
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
847
        pbSrc = pbSrc + 1;
436
437
847
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
1
          return FALSE;
439
440
846
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
846
        break;
442
443
2.07k
      default:
444
2.07k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
2.07k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
2.07k
        return FALSE;
447
55.6k
    }
448
55.6k
  }
449
450
1.52k
  return TRUE;
451
5.94k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
101
11.8k
{
102
11.8k
  const BYTE* pbSrc = pbSrcBuffer;
103
11.8k
  BYTE* pbDest = pbDestBuffer;
104
11.8k
  PIXEL temp = 0;
105
11.8k
  PIXEL fgPel = WHITE_PIXEL;
106
11.8k
  BOOL fInsertFgPel = FALSE;
107
11.8k
  BOOL fFirstLine = TRUE;
108
11.8k
  BYTE bitmask = 0;
109
11.8k
  PIXEL pixelA = 0;
110
11.8k
  PIXEL pixelB = 0;
111
11.8k
  UINT32 runLength = 0;
112
11.8k
  UINT32 code = 0;
113
11.8k
  UINT32 advance = 0;
114
11.8k
  RLEEXTRA
115
116
11.8k
  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.8k
  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.8k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
11.8k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
360k
  while (pbSrc < pbEnd)
134
357k
  {
135
    /* Watch out for the end of the first scanline. */
136
357k
    if (fFirstLine)
137
57.6k
    {
138
57.6k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
9.07k
      {
140
9.07k
        fFirstLine = FALSE;
141
9.07k
        fInsertFgPel = FALSE;
142
9.07k
      }
143
57.6k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
357k
    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
357k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
157
238k
    {
158
238k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
238k
      if (advance == 0)
160
508
        return FALSE;
161
238k
      pbSrc = pbSrc + advance;
162
163
238k
      if (fFirstLine)
164
25.1k
      {
165
25.1k
        if (fInsertFgPel)
166
17.4k
        {
167
17.4k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
17.4k
          DESTWRITEPIXEL(pbDest, fgPel);
171
17.4k
          runLength = runLength - 1;
172
17.4k
        }
173
174
25.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
74
          return FALSE;
176
177
25.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
25.0k
      }
179
213k
      else
180
213k
      {
181
213k
        if (fInsertFgPel)
182
191k
        {
183
191k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
191k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
48
            return FALSE;
187
188
191k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
191k
          runLength--;
190
191k
        }
191
192
213k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
694
          return FALSE;
194
195
212k
        UNROLL(runLength, {
196
212k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
212k
          DESTWRITEPIXEL(pbDest, temp);
198
212k
        });
199
212k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
237k
      fInsertFgPel = TRUE;
203
237k
      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
118k
    fInsertFgPel = FALSE;
209
210
118k
    switch (code)
211
118k
    {
212
      /* Handle Foreground Run Orders. */
213
22.1k
      case REGULAR_FG_RUN:
214
23.8k
      case MEGA_MEGA_FG_RUN:
215
36.1k
      case LITE_SET_FG_FG_RUN:
216
36.8k
      case MEGA_MEGA_SET_FG_RUN:
217
36.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
36.8k
        if (advance == 0)
219
84
          return FALSE;
220
36.7k
        pbSrc = pbSrc + advance;
221
222
36.7k
        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
156
            return FALSE;
226
12.7k
          SRCREADPIXEL(fgPel, pbSrc);
227
12.7k
        }
228
229
36.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
290
          return FALSE;
231
232
36.3k
        if (fFirstLine)
233
7.81k
        {
234
7.81k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
7.81k
        }
236
28.4k
        else
237
28.4k
        {
238
28.4k
          UNROLL(runLength, {
239
28.4k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
28.4k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
28.4k
          });
242
28.4k
        }
243
244
36.3k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
7.29k
      case LITE_DITHERED_RUN:
248
7.97k
      case MEGA_MEGA_DITHERED_RUN:
249
7.97k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
7.97k
        if (advance == 0)
251
40
          return FALSE;
252
7.93k
        pbSrc = pbSrc + advance;
253
7.93k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
160
          return FALSE;
255
7.77k
        SRCREADPIXEL(pixelA, pbSrc);
256
7.77k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
274
          return FALSE;
258
7.50k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
7.50k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
116
          return FALSE;
262
263
7.38k
        UNROLL(runLength, {
264
7.38k
          DESTWRITEPIXEL(pbDest, pixelA);
265
7.38k
          DESTWRITEPIXEL(pbDest, pixelB);
266
7.38k
        });
267
7.38k
        break;
268
269
      /* Handle Color Run Orders. */
270
35.8k
      case REGULAR_COLOR_RUN:
271
36.9k
      case MEGA_MEGA_COLOR_RUN:
272
36.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
36.9k
        if (advance == 0)
274
58
          return FALSE;
275
36.9k
        pbSrc = pbSrc + advance;
276
36.9k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
206
          return FALSE;
278
36.7k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
36.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
152
          return FALSE;
282
283
36.5k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
36.5k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
10.2k
      case REGULAR_FGBG_IMAGE:
288
11.6k
      case MEGA_MEGA_FGBG_IMAGE:
289
14.2k
      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
94
          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
4.13k
        {
298
4.13k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
132
            return FALSE;
300
4.00k
          SRCREADPIXEL(fgPel, pbSrc);
301
4.00k
        }
302
303
15.6k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
604
          return FALSE;
305
15.0k
        if (fFirstLine)
306
3.33k
        {
307
25.5k
          while (runLength > 8)
308
22.2k
          {
309
22.2k
            bitmask = *pbSrc;
310
22.2k
            pbSrc = pbSrc + 1;
311
22.2k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
22.2k
            if (!pbDest)
314
26
              return FALSE;
315
316
22.2k
            runLength = runLength - 8;
317
22.2k
          }
318
3.33k
        }
319
11.6k
        else
320
11.6k
        {
321
74.9k
          while (runLength > 8)
322
63.3k
          {
323
63.3k
            bitmask = *pbSrc++;
324
325
63.3k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
63.3k
            if (!pbDest)
328
42
              return FALSE;
329
330
63.2k
            runLength = runLength - 8;
331
63.2k
          }
332
11.6k
        }
333
334
14.9k
        if (runLength > 0)
335
12.3k
        {
336
12.3k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
60
            return FALSE;
338
12.2k
          bitmask = *pbSrc++;
339
340
12.2k
          if (fFirstLine)
341
1.80k
          {
342
1.80k
            pbDest =
343
1.80k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.80k
          }
345
10.4k
          else
346
10.4k
          {
347
10.4k
            pbDest =
348
10.4k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
10.4k
          }
350
351
12.2k
          if (!pbDest)
352
10
            return FALSE;
353
12.2k
        }
354
355
14.8k
        break;
356
357
      /* Handle Color Image Orders. */
358
14.8k
      case REGULAR_COLOR_IMAGE:
359
8.81k
      case MEGA_MEGA_COLOR_IMAGE:
360
8.81k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
8.81k
        if (advance == 0)
362
48
          return FALSE;
363
8.76k
        pbSrc = pbSrc + advance;
364
8.76k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
94
          return FALSE;
366
8.67k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
648
          return FALSE;
368
369
8.02k
        UNROLL(runLength, {
370
8.02k
          SRCREADPIXEL(temp, pbSrc);
371
8.02k
          DESTWRITEPIXEL(pbDest, temp);
372
8.02k
        });
373
8.02k
        break;
374
375
      /* Handle Special Order 1. */
376
8.02k
      case SPECIAL_FGBG_1:
377
1.72k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
1.72k
        pbSrc = pbSrc + 1;
380
381
1.72k
        if (fFirstLine)
382
260
        {
383
260
          pbDest =
384
260
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
260
        }
386
1.46k
        else
387
1.46k
        {
388
1.46k
          pbDest =
389
1.46k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
1.46k
        }
391
392
1.72k
        if (!pbDest)
393
4
          return FALSE;
394
395
1.72k
        break;
396
397
      /* Handle Special Order 2. */
398
1.95k
      case SPECIAL_FGBG_2:
399
1.95k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
1.95k
        pbSrc = pbSrc + 1;
402
403
1.95k
        if (fFirstLine)
404
180
        {
405
180
          pbDest =
406
180
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
180
        }
408
1.77k
        else
409
1.77k
        {
410
1.77k
          pbDest =
411
1.77k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
1.77k
        }
413
414
1.95k
        if (!pbDest)
415
4
          return FALSE;
416
417
1.95k
        break;
418
419
      /* Handle White Order. */
420
2.79k
      case SPECIAL_WHITE:
421
2.79k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
2.79k
        pbSrc = pbSrc + 1;
424
425
2.79k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
2
          return FALSE;
427
428
2.78k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
2.78k
        break;
430
431
      /* Handle Black Order. */
432
1.51k
      case SPECIAL_BLACK:
433
1.51k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
1.51k
        pbSrc = pbSrc + 1;
436
437
1.51k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
2
          return FALSE;
439
440
1.51k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
1.51k
        break;
442
443
4.20k
      default:
444
4.20k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
4.20k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
4.20k
        return FALSE;
447
118k
    }
448
118k
  }
449
450
3.06k
  return TRUE;
451
11.8k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8