Coverage Report

Created: 2025-08-29 06:46

/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
90
    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.6k
{
35
28.6k
  PIXEL xorPixel = 0;
36
28.6k
  BYTE mask = 0x01;
37
38
28.6k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
28.6k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
24
    return NULL;
46
47
28.6k
  UNROLL(cBits, {
48
28.6k
    PIXEL data = 0;
49
28.6k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
50
51
28.6k
    if (bitmask & mask)
52
28.6k
      data = xorPixel ^ fgPel;
53
28.6k
    else
54
28.6k
      data = xorPixel;
55
56
28.6k
    DESTWRITEPIXEL(pbDest, data);
57
28.6k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
58
28.6k
  });
59
28.6k
  return pbDest;
60
28.6k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
34
76.9k
{
35
76.9k
  PIXEL xorPixel = 0;
36
76.9k
  BYTE mask = 0x01;
37
38
76.9k
  if (cBits > 8)
39
0
  {
40
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
41
0
    return NULL;
42
0
  }
43
44
76.9k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
45
66
    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
42.3k
{
70
42.3k
  BYTE mask = 0x01;
71
72
42.3k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
42.3k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
43
    return NULL;
80
81
42.3k
  UNROLL(cBits, {
82
42.3k
    PIXEL data;
83
84
42.3k
    if (bitmask & mask)
85
42.3k
      data = fgPel;
86
42.3k
    else
87
42.3k
      data = BLACK_PIXEL;
88
89
42.3k
    DESTWRITEPIXEL(pbDest, data);
90
42.3k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
42.3k
  });
92
42.3k
  return pbDest;
93
42.3k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
69
16.9k
{
70
16.9k
  BYTE mask = 0x01;
71
72
16.9k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
16.9k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
17
    return NULL;
80
81
16.9k
  UNROLL(cBits, {
82
16.9k
    PIXEL data;
83
84
16.9k
    if (bitmask & mask)
85
16.9k
      data = fgPel;
86
16.9k
    else
87
16.9k
      data = BLACK_PIXEL;
88
89
16.9k
    DESTWRITEPIXEL(pbDest, data);
90
16.9k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
16.9k
  });
92
16.9k
  return pbDest;
93
16.9k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
69
25.4k
{
70
25.4k
  BYTE mask = 0x01;
71
72
25.4k
  if (cBits > 8)
73
0
  {
74
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
75
0
    return NULL;
76
0
  }
77
78
25.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
79
26
    return NULL;
80
81
25.4k
  UNROLL(cBits, {
82
25.4k
    PIXEL data;
83
84
25.4k
    if (bitmask & mask)
85
25.4k
      data = fgPel;
86
25.4k
    else
87
25.4k
      data = BLACK_PIXEL;
88
89
25.4k
    DESTWRITEPIXEL(pbDest, data);
90
25.4k
    mask = WINPR_ASSERTING_INT_CAST(BYTE, (mask << 1) & 0xFF);
91
25.4k
  });
92
25.4k
  return pbDest;
93
25.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
18.0k
{
102
18.0k
  const BYTE* pbSrc = pbSrcBuffer;
103
18.0k
  BYTE* pbDest = pbDestBuffer;
104
18.0k
  PIXEL temp = 0;
105
18.0k
  PIXEL fgPel = WHITE_PIXEL;
106
18.0k
  BOOL fInsertFgPel = FALSE;
107
18.0k
  BOOL fFirstLine = TRUE;
108
18.0k
  BYTE bitmask = 0;
109
18.0k
  PIXEL pixelA = 0;
110
18.0k
  PIXEL pixelB = 0;
111
18.0k
  UINT32 runLength = 0;
112
18.0k
  UINT32 code = 0;
113
18.0k
  UINT32 advance = 0;
114
18.0k
  RLEEXTRA
115
116
18.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
18.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
18.0k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
18.0k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
538k
  while (pbSrc < pbEnd)
134
534k
  {
135
    /* Watch out for the end of the first scanline. */
136
534k
    if (fFirstLine)
137
87.4k
    {
138
87.4k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
13.4k
      {
140
13.4k
        fFirstLine = FALSE;
141
13.4k
        fInsertFgPel = FALSE;
142
13.4k
      }
143
87.4k
    }
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
358k
    {
158
358k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
358k
      if (advance == 0)
160
726
        return FALSE;
161
357k
      pbSrc = pbSrc + advance;
162
163
357k
      if (fFirstLine)
164
38.4k
      {
165
38.4k
        if (fInsertFgPel)
166
26.3k
        {
167
26.3k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
26.3k
          DESTWRITEPIXEL(pbDest, fgPel);
171
26.3k
          runLength = runLength - 1;
172
26.3k
        }
173
174
38.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
110
          return FALSE;
176
177
38.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
38.2k
      }
179
319k
      else
180
319k
      {
181
319k
        if (fInsertFgPel)
182
287k
        {
183
287k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
287k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
64
            return FALSE;
187
188
287k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
287k
          runLength--;
190
287k
        }
191
192
319k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
1.03k
          return FALSE;
194
195
318k
        UNROLL(runLength, {
196
318k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
318k
          DESTWRITEPIXEL(pbDest, temp);
198
318k
        });
199
318k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
356k
      fInsertFgPel = TRUE;
203
356k
      continue;
204
357k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
175k
    fInsertFgPel = FALSE;
209
210
175k
    switch (code)
211
175k
    {
212
      /* Handle Foreground Run Orders. */
213
32.2k
      case REGULAR_FG_RUN:
214
34.6k
      case MEGA_MEGA_FG_RUN:
215
52.4k
      case LITE_SET_FG_FG_RUN:
216
53.5k
      case MEGA_MEGA_SET_FG_RUN:
217
53.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
53.5k
        if (advance == 0)
219
124
          return FALSE;
220
53.3k
        pbSrc = pbSrc + advance;
221
222
53.3k
        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
234
            return FALSE;
226
18.5k
          SRCREADPIXEL(fgPel, pbSrc);
227
18.5k
        }
228
229
53.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
407
          return FALSE;
231
232
52.7k
        if (fFirstLine)
233
11.5k
        {
234
11.5k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
11.5k
        }
236
41.1k
        else
237
41.1k
        {
238
41.1k
          UNROLL(runLength, {
239
41.1k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
41.1k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
41.1k
          });
242
41.1k
        }
243
244
52.7k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
10.7k
      case LITE_DITHERED_RUN:
248
12.0k
      case MEGA_MEGA_DITHERED_RUN:
249
12.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
12.0k
        if (advance == 0)
251
62
          return FALSE;
252
11.9k
        pbSrc = pbSrc + advance;
253
11.9k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
302
          return FALSE;
255
11.6k
        SRCREADPIXEL(pixelA, pbSrc);
256
11.6k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
517
          return FALSE;
258
11.1k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
11.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
173
          return FALSE;
262
263
10.9k
        UNROLL(runLength, {
264
10.9k
          DESTWRITEPIXEL(pbDest, pixelA);
265
10.9k
          DESTWRITEPIXEL(pbDest, pixelB);
266
10.9k
        });
267
10.9k
        break;
268
269
      /* Handle Color Run Orders. */
270
53.0k
      case REGULAR_COLOR_RUN:
271
54.7k
      case MEGA_MEGA_COLOR_RUN:
272
54.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
54.7k
        if (advance == 0)
274
77
          return FALSE;
275
54.6k
        pbSrc = pbSrc + advance;
276
54.6k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
373
          return FALSE;
278
54.2k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
54.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
262
          return FALSE;
282
283
54.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
54.0k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
15.3k
      case REGULAR_FGBG_IMAGE:
288
17.4k
      case MEGA_MEGA_FGBG_IMAGE:
289
21.5k
      case LITE_SET_FG_FGBG_IMAGE:
290
23.8k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
23.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
23.8k
        if (advance == 0)
293
133
          return FALSE;
294
23.6k
        pbSrc = pbSrc + advance;
295
296
23.6k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
6.26k
        {
298
6.26k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
208
            return FALSE;
300
6.05k
          SRCREADPIXEL(fgPel, pbSrc);
301
6.05k
        }
302
303
23.4k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
936
          return FALSE;
305
22.5k
        if (fFirstLine)
306
5.51k
        {
307
44.0k
          while (runLength > 8)
308
38.5k
          {
309
38.5k
            bitmask = *pbSrc;
310
38.5k
            pbSrc = pbSrc + 1;
311
38.5k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
38.5k
            if (!pbDest)
314
43
              return FALSE;
315
316
38.5k
            runLength = runLength - 8;
317
38.5k
          }
318
5.51k
        }
319
17.0k
        else
320
17.0k
        {
321
102k
          while (runLength > 8)
322
85.2k
          {
323
85.2k
            bitmask = *pbSrc++;
324
325
85.2k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
85.2k
            if (!pbDest)
328
56
              return FALSE;
329
330
85.2k
            runLength = runLength - 8;
331
85.2k
          }
332
17.0k
        }
333
334
22.4k
        if (runLength > 0)
335
18.5k
        {
336
18.5k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
99
            return FALSE;
338
18.4k
          bitmask = *pbSrc++;
339
340
18.4k
          if (fFirstLine)
341
3.19k
          {
342
3.19k
            pbDest =
343
3.19k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
3.19k
          }
345
15.2k
          else
346
15.2k
          {
347
15.2k
            pbDest =
348
15.2k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
15.2k
          }
350
351
18.4k
          if (!pbDest)
352
19
            return FALSE;
353
18.4k
        }
354
355
22.3k
        break;
356
357
      /* Handle Color Image Orders. */
358
22.3k
      case REGULAR_COLOR_IMAGE:
359
13.1k
      case MEGA_MEGA_COLOR_IMAGE:
360
13.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
13.1k
        if (advance == 0)
362
82
          return FALSE;
363
13.0k
        pbSrc = pbSrc + advance;
364
13.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
154
          return FALSE;
366
12.8k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
1.00k
          return FALSE;
368
369
11.8k
        UNROLL(runLength, {
370
3.77k
          SRCREADPIXEL(temp, pbSrc);
371
3.77k
          DESTWRITEPIXEL(pbDest, temp);
372
3.77k
        });
373
8.11k
        break;
374
375
      /* Handle Special Order 1. */
376
8.11k
      case SPECIAL_FGBG_1:
377
2.80k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
2.80k
        pbSrc = pbSrc + 1;
380
381
2.80k
        if (fFirstLine)
382
398
        {
383
398
          pbDest =
384
398
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
398
        }
386
2.41k
        else
387
2.41k
        {
388
2.41k
          pbDest =
389
2.41k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
2.41k
        }
391
392
2.80k
        if (!pbDest)
393
6
          return FALSE;
394
395
2.80k
        break;
396
397
      /* Handle Special Order 2. */
398
2.91k
      case SPECIAL_FGBG_2:
399
2.91k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
2.91k
        pbSrc = pbSrc + 1;
402
403
2.91k
        if (fFirstLine)
404
220
        {
405
220
          pbDest =
406
220
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
220
        }
408
2.69k
        else
409
2.69k
        {
410
2.69k
          pbDest =
411
2.69k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
2.69k
        }
413
414
2.91k
        if (!pbDest)
415
9
          return FALSE;
416
417
2.90k
        break;
418
419
      /* Handle White Order. */
420
4.13k
      case SPECIAL_WHITE:
421
4.13k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
4.13k
        pbSrc = pbSrc + 1;
424
425
4.13k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
3
          return FALSE;
427
428
4.13k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
4.13k
        break;
430
431
      /* Handle Black Order. */
432
2.38k
      case SPECIAL_BLACK:
433
2.38k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
2.38k
        pbSrc = pbSrc + 1;
436
437
2.38k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
3
          return FALSE;
439
440
2.37k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
2.37k
        break;
442
443
6.32k
      default:
444
6.32k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
6.32k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
6.32k
        return FALSE;
447
175k
    }
448
175k
  }
449
450
4.55k
  return TRUE;
451
18.0k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
101
6.03k
{
102
6.03k
  const BYTE* pbSrc = pbSrcBuffer;
103
6.03k
  BYTE* pbDest = pbDestBuffer;
104
6.03k
  PIXEL temp = 0;
105
6.03k
  PIXEL fgPel = WHITE_PIXEL;
106
6.03k
  BOOL fInsertFgPel = FALSE;
107
6.03k
  BOOL fFirstLine = TRUE;
108
6.03k
  BYTE bitmask = 0;
109
6.03k
  PIXEL pixelA = 0;
110
6.03k
  PIXEL pixelB = 0;
111
6.03k
  UINT32 runLength = 0;
112
6.03k
  UINT32 code = 0;
113
6.03k
  UINT32 advance = 0;
114
6.03k
  RLEEXTRA
115
116
6.03k
  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.03k
  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.03k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
6.03k
  const BYTE* pbDestEnd = &pbDestBuffer[1ULL * rowDelta * height];
132
133
174k
  while (pbSrc < pbEnd)
134
173k
  {
135
    /* Watch out for the end of the first scanline. */
136
173k
    if (fFirstLine)
137
29.2k
    {
138
29.2k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
4.25k
      {
140
4.25k
        fFirstLine = FALSE;
141
4.25k
        fInsertFgPel = FALSE;
142
4.25k
      }
143
29.2k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
173k
    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
173k
    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
196
        return FALSE;
161
116k
      pbSrc = pbSrc + advance;
162
163
116k
      if (fFirstLine)
164
12.9k
      {
165
12.9k
        if (fInsertFgPel)
166
8.74k
        {
167
8.74k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
8.74k
          DESTWRITEPIXEL(pbDest, fgPel);
171
8.74k
          runLength = runLength - 1;
172
8.74k
        }
173
174
12.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
38
          return FALSE;
176
177
12.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
12.9k
      }
179
103k
      else
180
103k
      {
181
103k
        if (fInsertFgPel)
182
93.8k
        {
183
93.8k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
93.8k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
20
            return FALSE;
187
188
93.8k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
93.8k
          runLength--;
190
93.8k
        }
191
192
103k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
326
          return FALSE;
194
195
103k
        UNROLL(runLength, {
196
103k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
103k
          DESTWRITEPIXEL(pbDest, temp);
198
103k
        });
199
103k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
116k
      fInsertFgPel = TRUE;
203
116k
      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
56.5k
    fInsertFgPel = FALSE;
209
210
56.5k
    switch (code)
211
56.5k
    {
212
      /* Handle Foreground Run Orders. */
213
10.0k
      case REGULAR_FG_RUN:
214
10.8k
      case MEGA_MEGA_FG_RUN:
215
16.4k
      case LITE_SET_FG_FG_RUN:
216
16.8k
      case MEGA_MEGA_SET_FG_RUN:
217
16.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
16.8k
        if (advance == 0)
219
36
          return FALSE;
220
16.7k
        pbSrc = pbSrc + advance;
221
222
16.7k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
223
5.94k
        {
224
5.94k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
88
            return FALSE;
226
5.86k
          SRCREADPIXEL(fgPel, pbSrc);
227
5.86k
        }
228
229
16.6k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
111
          return FALSE;
231
232
16.5k
        if (fFirstLine)
233
3.92k
        {
234
3.92k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
3.92k
        }
236
12.6k
        else
237
12.6k
        {
238
12.6k
          UNROLL(runLength, {
239
12.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
12.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
12.6k
          });
242
12.6k
        }
243
244
16.5k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
3.47k
      case LITE_DITHERED_RUN:
248
3.95k
      case MEGA_MEGA_DITHERED_RUN:
249
3.95k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
3.95k
        if (advance == 0)
251
16
          return FALSE;
252
3.94k
        pbSrc = pbSrc + advance;
253
3.94k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
112
          return FALSE;
255
3.83k
        SRCREADPIXEL(pixelA, pbSrc);
256
3.83k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
251
          return FALSE;
258
3.57k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
3.57k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
51
          return FALSE;
262
263
3.52k
        UNROLL(runLength, {
264
3.52k
          DESTWRITEPIXEL(pbDest, pixelA);
265
3.52k
          DESTWRITEPIXEL(pbDest, pixelB);
266
3.52k
        });
267
3.52k
        break;
268
269
      /* Handle Color Run Orders. */
270
17.1k
      case REGULAR_COLOR_RUN:
271
17.7k
      case MEGA_MEGA_COLOR_RUN:
272
17.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
17.7k
        if (advance == 0)
274
19
          return FALSE;
275
17.6k
        pbSrc = pbSrc + advance;
276
17.6k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
277
145
          return FALSE;
278
17.5k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
17.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
100
          return FALSE;
282
283
17.4k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
17.4k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
4.82k
      case REGULAR_FGBG_IMAGE:
288
5.55k
      case MEGA_MEGA_FGBG_IMAGE:
289
6.89k
      case LITE_SET_FG_FGBG_IMAGE:
290
7.64k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
7.64k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
7.64k
        if (advance == 0)
293
39
          return FALSE;
294
7.60k
        pbSrc = pbSrc + advance;
295
296
7.60k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
2.07k
        {
298
2.07k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
74
            return FALSE;
300
2.00k
          SRCREADPIXEL(fgPel, pbSrc);
301
2.00k
        }
302
303
7.53k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
302
          return FALSE;
305
7.22k
        if (fFirstLine)
306
2.02k
        {
307
17.5k
          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
17
              return FALSE;
315
316
15.5k
            runLength = runLength - 8;
317
15.5k
          }
318
2.02k
        }
319
5.20k
        else
320
5.20k
        {
321
27.4k
          while (runLength > 8)
322
22.2k
          {
323
22.2k
            bitmask = *pbSrc++;
324
325
22.2k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
22.2k
            if (!pbDest)
328
12
              return FALSE;
329
330
22.2k
            runLength = runLength - 8;
331
22.2k
          }
332
5.20k
        }
333
334
7.19k
        if (runLength > 0)
335
5.90k
        {
336
5.90k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
37
            return FALSE;
338
5.86k
          bitmask = *pbSrc++;
339
340
5.86k
          if (fFirstLine)
341
1.24k
          {
342
1.24k
            pbDest =
343
1.24k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.24k
          }
345
4.62k
          else
346
4.62k
          {
347
4.62k
            pbDest =
348
4.62k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
349
4.62k
          }
350
351
5.86k
          if (!pbDest)
352
7
            return FALSE;
353
5.86k
        }
354
355
7.15k
        break;
356
357
      /* Handle Color Image Orders. */
358
7.15k
      case REGULAR_COLOR_IMAGE:
359
4.19k
      case MEGA_MEGA_COLOR_IMAGE:
360
4.19k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
4.19k
        if (advance == 0)
362
28
          return FALSE;
363
4.16k
        pbSrc = pbSrc + advance;
364
4.16k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
54
          return FALSE;
366
4.11k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
340
          return FALSE;
368
369
3.77k
        UNROLL(runLength, {
370
3.77k
          SRCREADPIXEL(temp, pbSrc);
371
3.77k
          DESTWRITEPIXEL(pbDest, temp);
372
3.77k
        });
373
3.77k
        break;
374
375
      /* Handle Special Order 1. */
376
962
      case SPECIAL_FGBG_1:
377
962
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
962
        pbSrc = pbSrc + 1;
380
381
962
        if (fFirstLine)
382
102
        {
383
102
          pbDest =
384
102
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
102
        }
386
860
        else
387
860
        {
388
860
          pbDest =
389
860
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
860
        }
391
392
962
        if (!pbDest)
393
2
          return FALSE;
394
395
960
        break;
396
397
      /* Handle Special Order 2. */
398
979
      case SPECIAL_FGBG_2:
399
979
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
979
        pbSrc = pbSrc + 1;
402
403
979
        if (fFirstLine)
404
70
        {
405
70
          pbDest =
406
70
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
70
        }
408
909
        else
409
909
        {
410
909
          pbDest =
411
909
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
909
        }
413
414
979
        if (!pbDest)
415
3
          return FALSE;
416
417
976
        break;
418
419
      /* Handle White Order. */
420
1.38k
      case SPECIAL_WHITE:
421
1.38k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
1.38k
        pbSrc = pbSrc + 1;
424
425
1.38k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
1
          return FALSE;
427
428
1.37k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
1.37k
        break;
430
431
      /* Handle Black Order. */
432
852
      case SPECIAL_BLACK:
433
852
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
852
        pbSrc = pbSrc + 1;
436
437
852
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
1
          return FALSE;
439
440
851
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
851
        break;
442
443
2.09k
      default:
444
2.09k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
2.09k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
2.09k
        return FALSE;
447
56.5k
    }
448
56.5k
  }
449
450
1.50k
  return TRUE;
451
6.03k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
101
12.0k
{
102
12.0k
  const BYTE* pbSrc = pbSrcBuffer;
103
12.0k
  BYTE* pbDest = pbDestBuffer;
104
12.0k
  PIXEL temp = 0;
105
12.0k
  PIXEL fgPel = WHITE_PIXEL;
106
12.0k
  BOOL fInsertFgPel = FALSE;
107
12.0k
  BOOL fFirstLine = TRUE;
108
12.0k
  BYTE bitmask = 0;
109
12.0k
  PIXEL pixelA = 0;
110
12.0k
  PIXEL pixelB = 0;
111
12.0k
  UINT32 runLength = 0;
112
12.0k
  UINT32 code = 0;
113
12.0k
  UINT32 advance = 0;
114
12.0k
  RLEEXTRA
115
116
12.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
12.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
12.0k
  const BYTE* pbEnd = &pbSrcBuffer[cbSrcBuffer];
131
12.0k
  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
58.2k
    {
138
58.2k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
9.17k
      {
140
9.17k
        fFirstLine = FALSE;
141
9.17k
        fInsertFgPel = FALSE;
142
9.17k
      }
143
58.2k
    }
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
241k
    {
158
241k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
159
241k
      if (advance == 0)
160
530
        return FALSE;
161
241k
      pbSrc = pbSrc + advance;
162
163
241k
      if (fFirstLine)
164
25.4k
      {
165
25.4k
        if (fInsertFgPel)
166
17.6k
        {
167
17.6k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
168
0
            return FALSE;
169
170
17.6k
          DESTWRITEPIXEL(pbDest, fgPel);
171
17.6k
          runLength = runLength - 1;
172
17.6k
        }
173
174
25.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
175
72
          return FALSE;
176
177
25.3k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
178
25.3k
      }
179
215k
      else
180
215k
      {
181
215k
        if (fInsertFgPel)
182
193k
        {
183
193k
          DESTREADPIXEL(temp, pbDest - rowDelta);
184
185
193k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
186
44
            return FALSE;
187
188
193k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
189
193k
          runLength--;
190
193k
        }
191
192
215k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
193
708
          return FALSE;
194
195
214k
        UNROLL(runLength, {
196
214k
          DESTREADPIXEL(temp, pbDest - rowDelta);
197
214k
          DESTWRITEPIXEL(pbDest, temp);
198
214k
        });
199
214k
      }
200
201
      /* A follow-on background run order will need a foreground pel inserted. */
202
240k
      fInsertFgPel = TRUE;
203
240k
      continue;
204
241k
    }
205
206
    /* For any of the other run-types a follow-on background run
207
        order does not need a foreground pel inserted. */
208
119k
    fInsertFgPel = FALSE;
209
210
119k
    switch (code)
211
119k
    {
212
      /* Handle Foreground Run Orders. */
213
22.1k
      case REGULAR_FG_RUN:
214
23.7k
      case MEGA_MEGA_FG_RUN:
215
36.0k
      case LITE_SET_FG_FG_RUN:
216
36.6k
      case MEGA_MEGA_SET_FG_RUN:
217
36.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
218
36.6k
        if (advance == 0)
219
88
          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
12.8k
        {
224
12.8k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
225
146
            return FALSE;
226
12.7k
          SRCREADPIXEL(fgPel, pbSrc);
227
12.7k
        }
228
229
36.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
230
296
          return FALSE;
231
232
36.1k
        if (fFirstLine)
233
7.64k
        {
234
7.64k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
235
7.64k
        }
236
28.5k
        else
237
28.5k
        {
238
28.5k
          UNROLL(runLength, {
239
28.5k
            DESTREADPIXEL(temp, pbDest - rowDelta);
240
28.5k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
241
28.5k
          });
242
28.5k
        }
243
244
36.1k
        break;
245
246
      /* Handle Dithered Run Orders. */
247
7.31k
      case LITE_DITHERED_RUN:
248
8.07k
      case MEGA_MEGA_DITHERED_RUN:
249
8.07k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
250
8.07k
        if (advance == 0)
251
46
          return FALSE;
252
8.02k
        pbSrc = pbSrc + advance;
253
8.02k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
254
190
          return FALSE;
255
7.83k
        SRCREADPIXEL(pixelA, pbSrc);
256
7.83k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
257
266
          return FALSE;
258
7.57k
        SRCREADPIXEL(pixelB, pbSrc);
259
260
7.57k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
261
122
          return FALSE;
262
263
7.44k
        UNROLL(runLength, {
264
7.44k
          DESTWRITEPIXEL(pbDest, pixelA);
265
7.44k
          DESTWRITEPIXEL(pbDest, pixelB);
266
7.44k
        });
267
7.44k
        break;
268
269
      /* Handle Color Run Orders. */
270
35.9k
      case REGULAR_COLOR_RUN:
271
37.0k
      case MEGA_MEGA_COLOR_RUN:
272
37.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
273
37.0k
        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
228
          return FALSE;
278
36.7k
        SRCREADPIXEL(pixelA, pbSrc);
279
280
36.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
281
162
          return FALSE;
282
283
36.5k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
284
36.5k
        break;
285
286
      /* Handle Foreground/Background Image Orders. */
287
10.5k
      case REGULAR_FGBG_IMAGE:
288
11.9k
      case MEGA_MEGA_FGBG_IMAGE:
289
14.6k
      case LITE_SET_FG_FGBG_IMAGE:
290
16.1k
      case MEGA_MEGA_SET_FGBG_IMAGE:
291
16.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
292
16.1k
        if (advance == 0)
293
94
          return FALSE;
294
16.0k
        pbSrc = pbSrc + advance;
295
296
16.0k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
297
4.19k
        {
298
4.19k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
299
134
            return FALSE;
300
4.05k
          SRCREADPIXEL(fgPel, pbSrc);
301
4.05k
        }
302
303
15.9k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
304
634
          return FALSE;
305
15.3k
        if (fFirstLine)
306
3.49k
        {
307
26.5k
          while (runLength > 8)
308
23.0k
          {
309
23.0k
            bitmask = *pbSrc;
310
23.0k
            pbSrc = pbSrc + 1;
311
23.0k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
312
313
23.0k
            if (!pbDest)
314
26
              return FALSE;
315
316
23.0k
            runLength = runLength - 8;
317
23.0k
          }
318
3.49k
        }
319
11.8k
        else
320
11.8k
        {
321
74.7k
          while (runLength > 8)
322
62.9k
          {
323
62.9k
            bitmask = *pbSrc++;
324
325
62.9k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
326
327
62.9k
            if (!pbDest)
328
44
              return FALSE;
329
330
62.9k
            runLength = runLength - 8;
331
62.9k
          }
332
11.8k
        }
333
334
15.2k
        if (runLength > 0)
335
12.6k
        {
336
12.6k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
337
62
            return FALSE;
338
12.5k
          bitmask = *pbSrc++;
339
340
12.5k
          if (fFirstLine)
341
1.95k
          {
342
1.95k
            pbDest =
343
1.95k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
344
1.95k
          }
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.5k
          if (!pbDest)
352
12
            return FALSE;
353
12.5k
        }
354
355
15.1k
        break;
356
357
      /* Handle Color Image Orders. */
358
15.1k
      case REGULAR_COLOR_IMAGE:
359
8.93k
      case MEGA_MEGA_COLOR_IMAGE:
360
8.93k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
361
8.93k
        if (advance == 0)
362
54
          return FALSE;
363
8.87k
        pbSrc = pbSrc + advance;
364
8.87k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
365
100
          return FALSE;
366
8.77k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
367
662
          return FALSE;
368
369
8.11k
        UNROLL(runLength, {
370
8.11k
          SRCREADPIXEL(temp, pbSrc);
371
8.11k
          DESTWRITEPIXEL(pbDest, temp);
372
8.11k
        });
373
8.11k
        break;
374
375
      /* Handle Special Order 1. */
376
8.11k
      case SPECIAL_FGBG_1:
377
1.84k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
378
0
          return FALSE;
379
1.84k
        pbSrc = pbSrc + 1;
380
381
1.84k
        if (fFirstLine)
382
296
        {
383
296
          pbDest =
384
296
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
385
296
        }
386
1.55k
        else
387
1.55k
        {
388
1.55k
          pbDest =
389
1.55k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
390
1.55k
        }
391
392
1.84k
        if (!pbDest)
393
4
          return FALSE;
394
395
1.84k
        break;
396
397
      /* Handle Special Order 2. */
398
1.93k
      case SPECIAL_FGBG_2:
399
1.93k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
400
0
          return FALSE;
401
1.93k
        pbSrc = pbSrc + 1;
402
403
1.93k
        if (fFirstLine)
404
150
        {
405
150
          pbDest =
406
150
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
407
150
        }
408
1.78k
        else
409
1.78k
        {
410
1.78k
          pbDest =
411
1.78k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
412
1.78k
        }
413
414
1.93k
        if (!pbDest)
415
6
          return FALSE;
416
417
1.92k
        break;
418
419
      /* Handle White Order. */
420
2.75k
      case SPECIAL_WHITE:
421
2.75k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
422
0
          return FALSE;
423
2.75k
        pbSrc = pbSrc + 1;
424
425
2.75k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
426
2
          return FALSE;
427
428
2.75k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
429
2.75k
        break;
430
431
      /* Handle Black Order. */
432
1.52k
      case SPECIAL_BLACK:
433
1.52k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
434
0
          return FALSE;
435
1.52k
        pbSrc = pbSrc + 1;
436
437
1.52k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
438
2
          return FALSE;
439
440
1.52k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
441
1.52k
        break;
442
443
4.22k
      default:
444
4.22k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
445
4.22k
                 code, pbSrcBuffer, pbSrc, pbEnd);
446
4.22k
        return FALSE;
447
119k
    }
448
119k
  }
449
450
3.04k
  return TRUE;
451
12.0k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8