Coverage Report

Created: 2024-09-08 06:18

/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
/* do not compile the file directly */
23
24
/**
25
 * Write a foreground/background image to a destination buffer.
26
 */
27
static INLINE BYTE* WRITEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
28
                                   const BYTE* WINPR_RESTRICT pbDestEnd, UINT32 rowDelta,
29
                                   BYTE bitmask, PIXEL fgPel, INT32 cBits)
30
96.2k
{
31
96.2k
  PIXEL xorPixel;
32
96.2k
  BYTE mask = 0x01;
33
34
96.2k
  if (cBits > 8)
35
0
  {
36
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
37
0
    return NULL;
38
0
  }
39
40
96.2k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
41
95
    return NULL;
42
43
96.1k
  UNROLL(cBits, {
44
96.1k
    UINT32 data;
45
96.1k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
46
47
96.1k
    if (bitmask & mask)
48
96.1k
      data = xorPixel ^ fgPel;
49
96.1k
    else
50
96.1k
      data = xorPixel;
51
52
96.1k
    DESTWRITEPIXEL(pbDest, data);
53
96.1k
    mask = mask << 1;
54
96.1k
  });
55
96.1k
  return pbDest;
56
96.2k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
30
27.7k
{
31
27.7k
  PIXEL xorPixel;
32
27.7k
  BYTE mask = 0x01;
33
34
27.7k
  if (cBits > 8)
35
0
  {
36
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
37
0
    return NULL;
38
0
  }
39
40
27.7k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
41
27
    return NULL;
42
43
27.7k
  UNROLL(cBits, {
44
27.7k
    UINT32 data;
45
27.7k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
46
47
27.7k
    if (bitmask & mask)
48
27.7k
      data = xorPixel ^ fgPel;
49
27.7k
    else
50
27.7k
      data = xorPixel;
51
52
27.7k
    DESTWRITEPIXEL(pbDest, data);
53
27.7k
    mask = mask << 1;
54
27.7k
  });
55
27.7k
  return pbDest;
56
27.7k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
30
68.4k
{
31
68.4k
  PIXEL xorPixel;
32
68.4k
  BYTE mask = 0x01;
33
34
68.4k
  if (cBits > 8)
35
0
  {
36
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
37
0
    return NULL;
38
0
  }
39
40
68.4k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
41
68
    return NULL;
42
43
68.4k
  UNROLL(cBits, {
44
68.4k
    UINT32 data;
45
68.4k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
46
47
68.4k
    if (bitmask & mask)
48
68.4k
      data = xorPixel ^ fgPel;
49
68.4k
    else
50
68.4k
      data = xorPixel;
51
52
68.4k
    DESTWRITEPIXEL(pbDest, data);
53
68.4k
    mask = mask << 1;
54
68.4k
  });
55
68.4k
  return pbDest;
56
68.4k
}
Unexecuted instantiation: interleaved.c:WriteFgBgImage8to8
57
58
/**
59
 * Write a foreground/background image to a destination buffer
60
 * for the first line of compressed data.
61
 */
62
static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* WINPR_RESTRICT pbDest,
63
                                            const BYTE* WINPR_RESTRICT pbDestEnd, BYTE bitmask,
64
                                            PIXEL fgPel, UINT32 cBits)
65
33.2k
{
66
33.2k
  BYTE mask = 0x01;
67
68
33.2k
  if (cBits > 8)
69
0
  {
70
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
71
0
    return NULL;
72
0
  }
73
74
33.2k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
75
26
    return NULL;
76
77
33.2k
  UNROLL(cBits, {
78
33.2k
    UINT32 data;
79
80
33.2k
    if (bitmask & mask)
81
33.2k
      data = fgPel;
82
33.2k
    else
83
33.2k
      data = BLACK_PIXEL;
84
85
33.2k
    DESTWRITEPIXEL(pbDest, data);
86
33.2k
    mask = mask << 1;
87
33.2k
  });
88
33.2k
  return pbDest;
89
33.2k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
65
10.7k
{
66
10.7k
  BYTE mask = 0x01;
67
68
10.7k
  if (cBits > 8)
69
0
  {
70
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
71
0
    return NULL;
72
0
  }
73
74
10.7k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
75
8
    return NULL;
76
77
10.6k
  UNROLL(cBits, {
78
10.6k
    UINT32 data;
79
80
10.6k
    if (bitmask & mask)
81
10.6k
      data = fgPel;
82
10.6k
    else
83
10.6k
      data = BLACK_PIXEL;
84
85
10.6k
    DESTWRITEPIXEL(pbDest, data);
86
10.6k
    mask = mask << 1;
87
10.6k
  });
88
10.6k
  return pbDest;
89
10.7k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
65
22.5k
{
66
22.5k
  BYTE mask = 0x01;
67
68
22.5k
  if (cBits > 8)
69
0
  {
70
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
71
0
    return NULL;
72
0
  }
73
74
22.5k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
75
18
    return NULL;
76
77
22.5k
  UNROLL(cBits, {
78
22.5k
    UINT32 data;
79
80
22.5k
    if (bitmask & mask)
81
22.5k
      data = fgPel;
82
22.5k
    else
83
22.5k
      data = BLACK_PIXEL;
84
85
22.5k
    DESTWRITEPIXEL(pbDest, data);
86
22.5k
    mask = mask << 1;
87
22.5k
  });
88
22.5k
  return pbDest;
89
22.5k
}
Unexecuted instantiation: interleaved.c:WriteFirstLineFgBgImage8to8
90
91
/**
92
 * Decompress an RLE compressed bitmap.
93
 */
94
static INLINE BOOL RLEDECOMPRESS(const BYTE* WINPR_RESTRICT pbSrcBuffer, UINT32 cbSrcBuffer,
95
                                 BYTE* WINPR_RESTRICT pbDestBuffer, UINT32 rowDelta, UINT32 width,
96
                                 UINT32 height)
97
16.2k
{
98
#if defined(WITH_DEBUG_CODECS)
99
  char sbuffer[128] = { 0 };
100
#endif
101
16.2k
  const BYTE* pbSrc = pbSrcBuffer;
102
16.2k
  const BYTE* pbEnd;
103
16.2k
  const BYTE* pbDestEnd;
104
16.2k
  BYTE* pbDest = pbDestBuffer;
105
16.2k
  PIXEL temp;
106
16.2k
  PIXEL fgPel = WHITE_PIXEL;
107
16.2k
  BOOL fInsertFgPel = FALSE;
108
16.2k
  BOOL fFirstLine = TRUE;
109
16.2k
  BYTE bitmask;
110
16.2k
  PIXEL pixelA, pixelB;
111
16.2k
  UINT32 runLength;
112
16.2k
  UINT32 code;
113
16.2k
  UINT32 advance = 0;
114
16.2k
  RLEEXTRA
115
116
16.2k
  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.2k
  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.2k
  pbEnd = pbSrcBuffer + cbSrcBuffer;
131
16.2k
  pbDestEnd = pbDestBuffer + rowDelta * height;
132
133
484k
  while (pbSrc < pbEnd)
134
480k
  {
135
    /* Watch out for the end of the first scanline. */
136
480k
    if (fFirstLine)
137
75.7k
    {
138
75.7k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
11.7k
      {
140
11.7k
        fFirstLine = FALSE;
141
11.7k
        fInsertFgPel = FALSE;
142
11.7k
      }
143
75.7k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
480k
    code = ExtractCodeId(*pbSrc);
150
151
#if defined(WITH_DEBUG_CODECS)
152
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc,
153
             rle_code_str_buffer(code, sbuffer, sizeof(sbuffer)), pbEnd - pbSrc);
154
#endif
155
156
    /* Handle Background Run Orders. */
157
480k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
158
266k
    {
159
266k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
160
266k
      if (advance == 0)
161
624
        return FALSE;
162
266k
      pbSrc = pbSrc + advance;
163
164
266k
      if (fFirstLine)
165
30.5k
      {
166
30.5k
        if (fInsertFgPel)
167
20.2k
        {
168
20.2k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
169
0
            return FALSE;
170
171
20.2k
          DESTWRITEPIXEL(pbDest, fgPel);
172
20.2k
          runLength = runLength - 1;
173
20.2k
        }
174
175
30.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
176
92
          return FALSE;
177
178
30.4k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
179
30.4k
      }
180
235k
      else
181
235k
      {
182
235k
        if (fInsertFgPel)
183
210k
        {
184
210k
          DESTREADPIXEL(temp, pbDest - rowDelta);
185
186
210k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
187
89
            return FALSE;
188
189
210k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
190
210k
          runLength--;
191
210k
        }
192
193
235k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
194
577
          return FALSE;
195
196
234k
        UNROLL(runLength, {
197
234k
          DESTREADPIXEL(temp, pbDest - rowDelta);
198
234k
          DESTWRITEPIXEL(pbDest, temp);
199
234k
        });
200
234k
      }
201
202
      /* A follow-on background run order will need a foreground pel inserted. */
203
265k
      fInsertFgPel = TRUE;
204
265k
      continue;
205
266k
    }
206
207
    /* For any of the other run-types a follow-on background run
208
        order does not need a foreground pel inserted. */
209
213k
    fInsertFgPel = FALSE;
210
211
213k
    switch (code)
212
213k
    {
213
      /* Handle Foreground Run Orders. */
214
40.9k
      case REGULAR_FG_RUN:
215
43.2k
      case MEGA_MEGA_FG_RUN:
216
58.5k
      case LITE_SET_FG_FG_RUN:
217
59.7k
      case MEGA_MEGA_SET_FG_RUN:
218
59.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
219
59.7k
        if (advance == 0)
220
113
          return FALSE;
221
59.6k
        pbSrc = pbSrc + advance;
222
223
59.6k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
224
16.3k
        {
225
16.3k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
226
208
            return FALSE;
227
16.1k
          SRCREADPIXEL(fgPel, pbSrc);
228
16.1k
        }
229
230
59.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
231
304
          return FALSE;
232
233
59.0k
        if (fFirstLine)
234
10.0k
        {
235
10.0k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
236
10.0k
        }
237
49.0k
        else
238
49.0k
        {
239
49.0k
          UNROLL(runLength, {
240
49.0k
            DESTREADPIXEL(temp, pbDest - rowDelta);
241
49.0k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
242
49.0k
          });
243
49.0k
        }
244
245
59.0k
        break;
246
247
      /* Handle Dithered Run Orders. */
248
12.5k
      case LITE_DITHERED_RUN:
249
13.5k
      case MEGA_MEGA_DITHERED_RUN:
250
13.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
251
13.5k
        if (advance == 0)
252
52
          return FALSE;
253
13.4k
        pbSrc = pbSrc + advance;
254
13.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
200
          return FALSE;
256
13.2k
        SRCREADPIXEL(pixelA, pbSrc);
257
13.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
547
          return FALSE;
259
12.7k
        SRCREADPIXEL(pixelB, pbSrc);
260
261
12.7k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
262
125
          return FALSE;
263
264
12.6k
        UNROLL(runLength, {
265
12.6k
          DESTWRITEPIXEL(pbDest, pixelA);
266
12.6k
          DESTWRITEPIXEL(pbDest, pixelB);
267
12.6k
        });
268
12.6k
        break;
269
270
      /* Handle Color Run Orders. */
271
89.2k
      case REGULAR_COLOR_RUN:
272
90.2k
      case MEGA_MEGA_COLOR_RUN:
273
90.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
274
90.2k
        if (advance == 0)
275
52
          return FALSE;
276
90.2k
        pbSrc = pbSrc + advance;
277
90.2k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
278
324
          return FALSE;
279
89.8k
        SRCREADPIXEL(pixelA, pbSrc);
280
281
89.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
282
298
          return FALSE;
283
284
89.5k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
285
89.5k
        break;
286
287
      /* Handle Foreground/Background Image Orders. */
288
13.9k
      case REGULAR_FGBG_IMAGE:
289
16.2k
      case MEGA_MEGA_FGBG_IMAGE:
290
20.0k
      case LITE_SET_FG_FGBG_IMAGE:
291
21.1k
      case MEGA_MEGA_SET_FGBG_IMAGE:
292
21.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
293
21.1k
        if (advance == 0)
294
154
          return FALSE;
295
20.9k
        pbSrc = pbSrc + advance;
296
297
20.9k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
298
4.80k
        {
299
4.80k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
300
228
            return FALSE;
301
4.57k
          SRCREADPIXEL(fgPel, pbSrc);
302
4.57k
        }
303
304
20.7k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
305
865
          return FALSE;
306
19.8k
        if (fFirstLine)
307
5.05k
        {
308
34.8k
          while (runLength > 8)
309
29.8k
          {
310
29.8k
            bitmask = *pbSrc;
311
29.8k
            pbSrc = pbSrc + 1;
312
29.8k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
313
314
29.8k
            if (!pbDest)
315
26
              return FALSE;
316
317
29.8k
            runLength = runLength - 8;
318
29.8k
          }
319
5.05k
        }
320
14.8k
        else
321
14.8k
        {
322
91.1k
          while (runLength > 8)
323
76.4k
          {
324
76.4k
            bitmask = *pbSrc++;
325
326
76.4k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
327
328
76.4k
            if (!pbDest)
329
78
              return FALSE;
330
331
76.3k
            runLength = runLength - 8;
332
76.3k
          }
333
14.8k
        }
334
335
19.7k
        if (runLength > 0)
336
16.9k
        {
337
16.9k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
338
91
            return FALSE;
339
16.8k
          bitmask = *pbSrc++;
340
341
16.8k
          if (fFirstLine)
342
2.84k
          {
343
2.84k
            pbDest =
344
2.84k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
345
2.84k
          }
346
13.9k
          else
347
13.9k
          {
348
13.9k
            pbDest =
349
13.9k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
350
13.9k
          }
351
352
16.8k
          if (!pbDest)
353
6
            return FALSE;
354
16.8k
        }
355
356
19.6k
        break;
357
358
      /* Handle Color Image Orders. */
359
19.6k
      case REGULAR_COLOR_IMAGE:
360
12.0k
      case MEGA_MEGA_COLOR_IMAGE:
361
12.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
362
12.0k
        if (advance == 0)
363
67
          return FALSE;
364
11.9k
        pbSrc = pbSrc + advance;
365
11.9k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
366
69
          return FALSE;
367
11.8k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
368
915
          return FALSE;
369
370
10.9k
        UNROLL(runLength, {
371
10.9k
          SRCREADPIXEL(temp, pbSrc);
372
10.9k
          DESTWRITEPIXEL(pbDest, temp);
373
10.9k
        });
374
10.9k
        break;
375
376
      /* Handle Special Order 1. */
377
2.69k
      case SPECIAL_FGBG_1:
378
2.69k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
379
0
          return FALSE;
380
2.69k
        pbSrc = pbSrc + 1;
381
382
2.69k
        if (fFirstLine)
383
258
        {
384
258
          pbDest =
385
258
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
386
258
        }
387
2.43k
        else
388
2.43k
        {
389
2.43k
          pbDest =
390
2.43k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
391
2.43k
        }
392
393
2.69k
        if (!pbDest)
394
3
          return FALSE;
395
396
2.69k
        break;
397
398
      /* Handle Special Order 2. */
399
3.69k
      case SPECIAL_FGBG_2:
400
3.69k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
401
0
          return FALSE;
402
3.69k
        pbSrc = pbSrc + 1;
403
404
3.69k
        if (fFirstLine)
405
297
        {
406
297
          pbDest =
407
297
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
408
297
        }
409
3.39k
        else
410
3.39k
        {
411
3.39k
          pbDest =
412
3.39k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
413
3.39k
        }
414
415
3.69k
        if (!pbDest)
416
8
          return FALSE;
417
418
3.68k
        break;
419
420
      /* Handle White Order. */
421
3.68k
      case SPECIAL_WHITE:
422
2.15k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
423
0
          return FALSE;
424
2.15k
        pbSrc = pbSrc + 1;
425
426
2.15k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
427
3
          return FALSE;
428
429
2.14k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
430
2.14k
        break;
431
432
      /* Handle Black Order. */
433
2.31k
      case SPECIAL_BLACK:
434
2.31k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
435
0
          return FALSE;
436
2.31k
        pbSrc = pbSrc + 1;
437
438
2.31k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
439
4
          return FALSE;
440
441
2.31k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
442
2.31k
        break;
443
444
6.05k
      default:
445
6.05k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
446
6.05k
                 code, pbSrcBuffer, pbSrc, pbEnd);
447
6.05k
        return FALSE;
448
213k
    }
449
213k
  }
450
451
4.03k
  return TRUE;
452
16.2k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
97
5.40k
{
98
#if defined(WITH_DEBUG_CODECS)
99
  char sbuffer[128] = { 0 };
100
#endif
101
5.40k
  const BYTE* pbSrc = pbSrcBuffer;
102
5.40k
  const BYTE* pbEnd;
103
5.40k
  const BYTE* pbDestEnd;
104
5.40k
  BYTE* pbDest = pbDestBuffer;
105
5.40k
  PIXEL temp;
106
5.40k
  PIXEL fgPel = WHITE_PIXEL;
107
5.40k
  BOOL fInsertFgPel = FALSE;
108
5.40k
  BOOL fFirstLine = TRUE;
109
5.40k
  BYTE bitmask;
110
5.40k
  PIXEL pixelA, pixelB;
111
5.40k
  UINT32 runLength;
112
5.40k
  UINT32 code;
113
5.40k
  UINT32 advance = 0;
114
5.40k
  RLEEXTRA
115
116
5.40k
  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.40k
  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.40k
  pbEnd = pbSrcBuffer + cbSrcBuffer;
131
5.40k
  pbDestEnd = pbDestBuffer + rowDelta * height;
132
133
156k
  while (pbSrc < pbEnd)
134
155k
  {
135
    /* Watch out for the end of the first scanline. */
136
155k
    if (fFirstLine)
137
25.5k
    {
138
25.5k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
3.77k
      {
140
3.77k
        fFirstLine = FALSE;
141
3.77k
        fInsertFgPel = FALSE;
142
3.77k
      }
143
25.5k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
155k
    code = ExtractCodeId(*pbSrc);
150
151
#if defined(WITH_DEBUG_CODECS)
152
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc,
153
             rle_code_str_buffer(code, sbuffer, sizeof(sbuffer)), pbEnd - pbSrc);
154
#endif
155
156
    /* Handle Background Run Orders. */
157
155k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
158
86.3k
    {
159
86.3k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
160
86.3k
      if (advance == 0)
161
182
        return FALSE;
162
86.1k
      pbSrc = pbSrc + advance;
163
164
86.1k
      if (fFirstLine)
165
10.4k
      {
166
10.4k
        if (fInsertFgPel)
167
6.87k
        {
168
6.87k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
169
0
            return FALSE;
170
171
6.87k
          DESTWRITEPIXEL(pbDest, fgPel);
172
6.87k
          runLength = runLength - 1;
173
6.87k
        }
174
175
10.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
176
30
          return FALSE;
177
178
10.4k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
179
10.4k
      }
180
75.6k
      else
181
75.6k
      {
182
75.6k
        if (fInsertFgPel)
183
68.1k
        {
184
68.1k
          DESTREADPIXEL(temp, pbDest - rowDelta);
185
186
68.1k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
187
29
            return FALSE;
188
189
68.0k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
190
68.0k
          runLength--;
191
68.0k
        }
192
193
75.6k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
194
173
          return FALSE;
195
196
75.4k
        UNROLL(runLength, {
197
75.4k
          DESTREADPIXEL(temp, pbDest - rowDelta);
198
75.4k
          DESTWRITEPIXEL(pbDest, temp);
199
75.4k
        });
200
75.4k
      }
201
202
      /* A follow-on background run order will need a foreground pel inserted. */
203
85.9k
      fInsertFgPel = TRUE;
204
85.9k
      continue;
205
86.1k
    }
206
207
    /* For any of the other run-types a follow-on background run
208
        order does not need a foreground pel inserted. */
209
68.7k
    fInsertFgPel = FALSE;
210
211
68.7k
    switch (code)
212
68.7k
    {
213
      /* Handle Foreground Run Orders. */
214
13.4k
      case REGULAR_FG_RUN:
215
14.1k
      case MEGA_MEGA_FG_RUN:
216
19.2k
      case LITE_SET_FG_FG_RUN:
217
19.6k
      case MEGA_MEGA_SET_FG_RUN:
218
19.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
219
19.6k
        if (advance == 0)
220
37
          return FALSE;
221
19.6k
        pbSrc = pbSrc + advance;
222
223
19.6k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
224
5.46k
        {
225
5.46k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
226
80
            return FALSE;
227
5.38k
          SRCREADPIXEL(fgPel, pbSrc);
228
5.38k
        }
229
230
19.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
231
96
          return FALSE;
232
233
19.4k
        if (fFirstLine)
234
3.47k
        {
235
3.47k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
236
3.47k
        }
237
15.9k
        else
238
15.9k
        {
239
15.9k
          UNROLL(runLength, {
240
15.9k
            DESTREADPIXEL(temp, pbDest - rowDelta);
241
15.9k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
242
15.9k
          });
243
15.9k
        }
244
245
19.4k
        break;
246
247
      /* Handle Dithered Run Orders. */
248
3.68k
      case LITE_DITHERED_RUN:
249
4.05k
      case MEGA_MEGA_DITHERED_RUN:
250
4.05k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
251
4.05k
        if (advance == 0)
252
18
          return FALSE;
253
4.03k
        pbSrc = pbSrc + advance;
254
4.03k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
94
          return FALSE;
256
3.94k
        SRCREADPIXEL(pixelA, pbSrc);
257
3.94k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
271
          return FALSE;
259
3.67k
        SRCREADPIXEL(pixelB, pbSrc);
260
261
3.67k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
262
33
          return FALSE;
263
264
3.64k
        UNROLL(runLength, {
265
3.64k
          DESTWRITEPIXEL(pbDest, pixelA);
266
3.64k
          DESTWRITEPIXEL(pbDest, pixelB);
267
3.64k
        });
268
3.64k
        break;
269
270
      /* Handle Color Run Orders. */
271
29.1k
      case REGULAR_COLOR_RUN:
272
29.5k
      case MEGA_MEGA_COLOR_RUN:
273
29.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
274
29.5k
        if (advance == 0)
275
16
          return FALSE;
276
29.4k
        pbSrc = pbSrc + advance;
277
29.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
278
124
          return FALSE;
279
29.3k
        SRCREADPIXEL(pixelA, pbSrc);
280
281
29.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
282
86
          return FALSE;
283
284
29.2k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
285
29.2k
        break;
286
287
      /* Handle Foreground/Background Image Orders. */
288
4.21k
      case REGULAR_FGBG_IMAGE:
289
4.96k
      case MEGA_MEGA_FGBG_IMAGE:
290
6.16k
      case LITE_SET_FG_FGBG_IMAGE:
291
6.55k
      case MEGA_MEGA_SET_FGBG_IMAGE:
292
6.55k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
293
6.55k
        if (advance == 0)
294
42
          return FALSE;
295
6.51k
        pbSrc = pbSrc + advance;
296
297
6.51k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
298
1.57k
        {
299
1.57k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
300
74
            return FALSE;
301
1.50k
          SRCREADPIXEL(fgPel, pbSrc);
302
1.50k
        }
303
304
6.44k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
305
277
          return FALSE;
306
6.16k
        if (fFirstLine)
307
1.80k
        {
308
11.3k
          while (runLength > 8)
309
9.52k
          {
310
9.52k
            bitmask = *pbSrc;
311
9.52k
            pbSrc = pbSrc + 1;
312
9.52k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
313
314
9.52k
            if (!pbDest)
315
8
              return FALSE;
316
317
9.52k
            runLength = runLength - 8;
318
9.52k
          }
319
1.80k
        }
320
4.36k
        else
321
4.36k
        {
322
26.0k
          while (runLength > 8)
323
21.6k
          {
324
21.6k
            bitmask = *pbSrc++;
325
326
21.6k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
327
328
21.6k
            if (!pbDest)
329
22
              return FALSE;
330
331
21.6k
            runLength = runLength - 8;
332
21.6k
          }
333
4.36k
        }
334
335
6.13k
        if (runLength > 0)
336
5.14k
        {
337
5.14k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
338
35
            return FALSE;
339
5.11k
          bitmask = *pbSrc++;
340
341
5.11k
          if (fFirstLine)
342
999
          {
343
999
            pbDest =
344
999
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
345
999
          }
346
4.11k
          else
347
4.11k
          {
348
4.11k
            pbDest =
349
4.11k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
350
4.11k
          }
351
352
5.11k
          if (!pbDest)
353
2
            return FALSE;
354
5.11k
        }
355
356
6.09k
        break;
357
358
      /* Handle Color Image Orders. */
359
6.09k
      case REGULAR_COLOR_IMAGE:
360
3.34k
      case MEGA_MEGA_COLOR_IMAGE:
361
3.34k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
362
3.34k
        if (advance == 0)
363
23
          return FALSE;
364
3.32k
        pbSrc = pbSrc + advance;
365
3.32k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
366
19
          return FALSE;
367
3.30k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
368
301
          return FALSE;
369
370
3.00k
        UNROLL(runLength, {
371
3.00k
          SRCREADPIXEL(temp, pbSrc);
372
3.00k
          DESTWRITEPIXEL(pbDest, temp);
373
3.00k
        });
374
3.00k
        break;
375
376
      /* Handle Special Order 1. */
377
865
      case SPECIAL_FGBG_1:
378
865
        if (!buffer_within_range(pbSrc, 1, pbEnd))
379
0
          return FALSE;
380
865
        pbSrc = pbSrc + 1;
381
382
865
        if (fFirstLine)
383
76
        {
384
76
          pbDest =
385
76
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
386
76
        }
387
789
        else
388
789
        {
389
789
          pbDest =
390
789
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
391
789
        }
392
393
865
        if (!pbDest)
394
1
          return FALSE;
395
396
864
        break;
397
398
      /* Handle Special Order 2. */
399
1.28k
      case SPECIAL_FGBG_2:
400
1.28k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
401
0
          return FALSE;
402
1.28k
        pbSrc = pbSrc + 1;
403
404
1.28k
        if (fFirstLine)
405
99
        {
406
99
          pbDest =
407
99
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
408
99
        }
409
1.18k
        else
410
1.18k
        {
411
1.18k
          pbDest =
412
1.18k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
413
1.18k
        }
414
415
1.28k
        if (!pbDest)
416
2
          return FALSE;
417
418
1.28k
        break;
419
420
      /* Handle White Order. */
421
1.28k
      case SPECIAL_WHITE:
422
701
        if (!buffer_within_range(pbSrc, 1, pbEnd))
423
0
          return FALSE;
424
701
        pbSrc = pbSrc + 1;
425
426
701
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
427
1
          return FALSE;
428
429
700
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
430
700
        break;
431
432
      /* Handle Black Order. */
433
753
      case SPECIAL_BLACK:
434
753
        if (!buffer_within_range(pbSrc, 1, pbEnd))
435
0
          return FALSE;
436
753
        pbSrc = pbSrc + 1;
437
438
753
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
439
2
          return FALSE;
440
441
751
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
442
751
        break;
443
444
1.99k
      default:
445
1.99k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
446
1.99k
                 code, pbSrcBuffer, pbSrc, pbEnd);
447
1.99k
        return FALSE;
448
68.7k
    }
449
68.7k
  }
450
451
1.33k
  return TRUE;
452
5.40k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
97
10.8k
{
98
#if defined(WITH_DEBUG_CODECS)
99
  char sbuffer[128] = { 0 };
100
#endif
101
10.8k
  const BYTE* pbSrc = pbSrcBuffer;
102
10.8k
  const BYTE* pbEnd;
103
10.8k
  const BYTE* pbDestEnd;
104
10.8k
  BYTE* pbDest = pbDestBuffer;
105
10.8k
  PIXEL temp;
106
10.8k
  PIXEL fgPel = WHITE_PIXEL;
107
10.8k
  BOOL fInsertFgPel = FALSE;
108
10.8k
  BOOL fFirstLine = TRUE;
109
10.8k
  BYTE bitmask;
110
10.8k
  PIXEL pixelA, pixelB;
111
10.8k
  UINT32 runLength;
112
10.8k
  UINT32 code;
113
10.8k
  UINT32 advance = 0;
114
10.8k
  RLEEXTRA
115
116
10.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
10.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
10.8k
  pbEnd = pbSrcBuffer + cbSrcBuffer;
131
10.8k
  pbDestEnd = pbDestBuffer + rowDelta * height;
132
133
328k
  while (pbSrc < pbEnd)
134
325k
  {
135
    /* Watch out for the end of the first scanline. */
136
325k
    if (fFirstLine)
137
50.1k
    {
138
50.1k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
139
8.00k
      {
140
8.00k
        fFirstLine = FALSE;
141
8.00k
        fInsertFgPel = FALSE;
142
8.00k
      }
143
50.1k
    }
144
145
    /*
146
       Extract the compression order code ID from the compression
147
       order header.
148
    */
149
325k
    code = ExtractCodeId(*pbSrc);
150
151
#if defined(WITH_DEBUG_CODECS)
152
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc,
153
             rle_code_str_buffer(code, sbuffer, sizeof(sbuffer)), pbEnd - pbSrc);
154
#endif
155
156
    /* Handle Background Run Orders. */
157
325k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
158
180k
    {
159
180k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
160
180k
      if (advance == 0)
161
442
        return FALSE;
162
180k
      pbSrc = pbSrc + advance;
163
164
180k
      if (fFirstLine)
165
20.0k
      {
166
20.0k
        if (fInsertFgPel)
167
13.4k
        {
168
13.4k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
169
0
            return FALSE;
170
171
13.4k
          DESTWRITEPIXEL(pbDest, fgPel);
172
13.4k
          runLength = runLength - 1;
173
13.4k
        }
174
175
20.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
176
62
          return FALSE;
177
178
19.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
179
19.9k
      }
180
159k
      else
181
159k
      {
182
159k
        if (fInsertFgPel)
183
142k
        {
184
142k
          DESTREADPIXEL(temp, pbDest - rowDelta);
185
186
142k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
187
60
            return FALSE;
188
189
142k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
190
142k
          runLength--;
191
142k
        }
192
193
159k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
194
404
          return FALSE;
195
196
159k
        UNROLL(runLength, {
197
159k
          DESTREADPIXEL(temp, pbDest - rowDelta);
198
159k
          DESTWRITEPIXEL(pbDest, temp);
199
159k
        });
200
159k
      }
201
202
      /* A follow-on background run order will need a foreground pel inserted. */
203
179k
      fInsertFgPel = TRUE;
204
179k
      continue;
205
180k
    }
206
207
    /* For any of the other run-types a follow-on background run
208
        order does not need a foreground pel inserted. */
209
144k
    fInsertFgPel = FALSE;
210
211
144k
    switch (code)
212
144k
    {
213
      /* Handle Foreground Run Orders. */
214
27.5k
      case REGULAR_FG_RUN:
215
29.0k
      case MEGA_MEGA_FG_RUN:
216
39.3k
      case LITE_SET_FG_FG_RUN:
217
40.0k
      case MEGA_MEGA_SET_FG_RUN:
218
40.0k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
219
40.0k
        if (advance == 0)
220
76
          return FALSE;
221
39.9k
        pbSrc = pbSrc + advance;
222
223
39.9k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
224
10.9k
        {
225
10.9k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
226
128
            return FALSE;
227
10.7k
          SRCREADPIXEL(fgPel, pbSrc);
228
10.7k
        }
229
230
39.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
231
208
          return FALSE;
232
233
39.6k
        if (fFirstLine)
234
6.54k
        {
235
6.54k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
236
6.54k
        }
237
33.0k
        else
238
33.0k
        {
239
33.0k
          UNROLL(runLength, {
240
33.0k
            DESTREADPIXEL(temp, pbDest - rowDelta);
241
33.0k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
242
33.0k
          });
243
33.0k
        }
244
245
39.6k
        break;
246
247
      /* Handle Dithered Run Orders. */
248
8.81k
      case LITE_DITHERED_RUN:
249
9.48k
      case MEGA_MEGA_DITHERED_RUN:
250
9.48k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
251
9.48k
        if (advance == 0)
252
34
          return FALSE;
253
9.45k
        pbSrc = pbSrc + advance;
254
9.45k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
106
          return FALSE;
256
9.34k
        SRCREADPIXEL(pixelA, pbSrc);
257
9.34k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
258
276
          return FALSE;
259
9.07k
        SRCREADPIXEL(pixelB, pbSrc);
260
261
9.07k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
262
92
          return FALSE;
263
264
8.97k
        UNROLL(runLength, {
265
8.97k
          DESTWRITEPIXEL(pbDest, pixelA);
266
8.97k
          DESTWRITEPIXEL(pbDest, pixelB);
267
8.97k
        });
268
8.97k
        break;
269
270
      /* Handle Color Run Orders. */
271
60.0k
      case REGULAR_COLOR_RUN:
272
60.7k
      case MEGA_MEGA_COLOR_RUN:
273
60.7k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
274
60.7k
        if (advance == 0)
275
36
          return FALSE;
276
60.7k
        pbSrc = pbSrc + advance;
277
60.7k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
278
200
          return FALSE;
279
60.5k
        SRCREADPIXEL(pixelA, pbSrc);
280
281
60.5k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
282
212
          return FALSE;
283
284
60.3k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
285
60.3k
        break;
286
287
      /* Handle Foreground/Background Image Orders. */
288
9.75k
      case REGULAR_FGBG_IMAGE:
289
11.2k
      case MEGA_MEGA_FGBG_IMAGE:
290
13.8k
      case LITE_SET_FG_FGBG_IMAGE:
291
14.5k
      case MEGA_MEGA_SET_FGBG_IMAGE:
292
14.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
293
14.5k
        if (advance == 0)
294
112
          return FALSE;
295
14.4k
        pbSrc = pbSrc + advance;
296
297
14.4k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
298
3.23k
        {
299
3.23k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
300
154
            return FALSE;
301
3.07k
          SRCREADPIXEL(fgPel, pbSrc);
302
3.07k
        }
303
304
14.2k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
305
588
          return FALSE;
306
13.7k
        if (fFirstLine)
307
3.25k
        {
308
23.5k
          while (runLength > 8)
309
20.3k
          {
310
20.3k
            bitmask = *pbSrc;
311
20.3k
            pbSrc = pbSrc + 1;
312
20.3k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
313
314
20.3k
            if (!pbDest)
315
18
              return FALSE;
316
317
20.2k
            runLength = runLength - 8;
318
20.2k
          }
319
3.25k
        }
320
10.4k
        else
321
10.4k
        {
322
65.1k
          while (runLength > 8)
323
54.7k
          {
324
54.7k
            bitmask = *pbSrc++;
325
326
54.7k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
327
328
54.7k
            if (!pbDest)
329
56
              return FALSE;
330
331
54.6k
            runLength = runLength - 8;
332
54.6k
          }
333
10.4k
        }
334
335
13.6k
        if (runLength > 0)
336
11.7k
        {
337
11.7k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
338
56
            return FALSE;
339
11.7k
          bitmask = *pbSrc++;
340
341
11.7k
          if (fFirstLine)
342
1.84k
          {
343
1.84k
            pbDest =
344
1.84k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
345
1.84k
          }
346
9.87k
          else
347
9.87k
          {
348
9.87k
            pbDest =
349
9.87k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
350
9.87k
          }
351
352
11.7k
          if (!pbDest)
353
4
            return FALSE;
354
11.7k
        }
355
356
13.5k
        break;
357
358
      /* Handle Color Image Orders. */
359
13.5k
      case REGULAR_COLOR_IMAGE:
360
8.69k
      case MEGA_MEGA_COLOR_IMAGE:
361
8.69k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
362
8.69k
        if (advance == 0)
363
44
          return FALSE;
364
8.64k
        pbSrc = pbSrc + advance;
365
8.64k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
366
50
          return FALSE;
367
8.59k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
368
614
          return FALSE;
369
370
7.98k
        UNROLL(runLength, {
371
7.98k
          SRCREADPIXEL(temp, pbSrc);
372
7.98k
          DESTWRITEPIXEL(pbDest, temp);
373
7.98k
        });
374
7.98k
        break;
375
376
      /* Handle Special Order 1. */
377
1.82k
      case SPECIAL_FGBG_1:
378
1.82k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
379
0
          return FALSE;
380
1.82k
        pbSrc = pbSrc + 1;
381
382
1.82k
        if (fFirstLine)
383
182
        {
384
182
          pbDest =
385
182
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
386
182
        }
387
1.64k
        else
388
1.64k
        {
389
1.64k
          pbDest =
390
1.64k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
391
1.64k
        }
392
393
1.82k
        if (!pbDest)
394
2
          return FALSE;
395
396
1.82k
        break;
397
398
      /* Handle Special Order 2. */
399
2.41k
      case SPECIAL_FGBG_2:
400
2.41k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
401
0
          return FALSE;
402
2.41k
        pbSrc = pbSrc + 1;
403
404
2.41k
        if (fFirstLine)
405
198
        {
406
198
          pbDest =
407
198
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
408
198
        }
409
2.21k
        else
410
2.21k
        {
411
2.21k
          pbDest =
412
2.21k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
413
2.21k
        }
414
415
2.41k
        if (!pbDest)
416
6
          return FALSE;
417
418
2.40k
        break;
419
420
      /* Handle White Order. */
421
2.40k
      case SPECIAL_WHITE:
422
1.45k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
423
0
          return FALSE;
424
1.45k
        pbSrc = pbSrc + 1;
425
426
1.45k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
427
2
          return FALSE;
428
429
1.44k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
430
1.44k
        break;
431
432
      /* Handle Black Order. */
433
1.56k
      case SPECIAL_BLACK:
434
1.56k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
435
0
          return FALSE;
436
1.56k
        pbSrc = pbSrc + 1;
437
438
1.56k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
439
2
          return FALSE;
440
441
1.56k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
442
1.56k
        break;
443
444
4.06k
      default:
445
4.06k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
446
4.06k
                 code, pbSrcBuffer, pbSrc, pbEnd);
447
4.06k
        return FALSE;
448
144k
    }
449
144k
  }
450
451
2.70k
  return TRUE;
452
10.8k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8