Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/libfreerdp/codec/include/bitmap.c
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* pbDest, const BYTE* pbDestEnd, UINT32 rowDelta,
28
                                   BYTE bitmask, PIXEL fgPel, INT32 cBits)
29
100k
{
30
100k
  PIXEL xorPixel;
31
100k
  BYTE mask = 0x01;
32
33
100k
  if (cBits > 8)
34
0
  {
35
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
36
0
    return NULL;
37
0
  }
38
39
100k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
40
133
    return NULL;
41
42
100k
  UNROLL(cBits, {
43
100k
    UINT32 data;
44
100k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
45
46
100k
    if (bitmask & mask)
47
100k
      data = xorPixel ^ fgPel;
48
100k
    else
49
100k
      data = xorPixel;
50
51
100k
    DESTWRITEPIXEL(pbDest, data);
52
100k
    mask = mask << 1;
53
100k
  });
54
100k
  return pbDest;
55
100k
}
interleaved.c:WriteFgBgImage24to24
Line
Count
Source
29
29.1k
{
30
29.1k
  PIXEL xorPixel;
31
29.1k
  BYTE mask = 0x01;
32
33
29.1k
  if (cBits > 8)
34
0
  {
35
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
36
0
    return NULL;
37
0
  }
38
39
29.1k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
40
35
    return NULL;
41
42
29.1k
  UNROLL(cBits, {
43
29.1k
    UINT32 data;
44
29.1k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
45
46
29.1k
    if (bitmask & mask)
47
29.1k
      data = xorPixel ^ fgPel;
48
29.1k
    else
49
29.1k
      data = xorPixel;
50
51
29.1k
    DESTWRITEPIXEL(pbDest, data);
52
29.1k
    mask = mask << 1;
53
29.1k
  });
54
29.1k
  return pbDest;
55
29.1k
}
interleaved.c:WriteFgBgImage16to16
Line
Count
Source
29
71.6k
{
30
71.6k
  PIXEL xorPixel;
31
71.6k
  BYTE mask = 0x01;
32
33
71.6k
  if (cBits > 8)
34
0
  {
35
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
36
0
    return NULL;
37
0
  }
38
39
71.6k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
40
98
    return NULL;
41
42
71.5k
  UNROLL(cBits, {
43
71.5k
    UINT32 data;
44
71.5k
    DESTREADPIXEL(xorPixel, pbDest - rowDelta);
45
46
71.5k
    if (bitmask & mask)
47
71.5k
      data = xorPixel ^ fgPel;
48
71.5k
    else
49
71.5k
      data = xorPixel;
50
51
71.5k
    DESTWRITEPIXEL(pbDest, data);
52
71.5k
    mask = mask << 1;
53
71.5k
  });
54
71.5k
  return pbDest;
55
71.6k
}
Unexecuted instantiation: interleaved.c:WriteFgBgImage8to8
56
57
/**
58
 * Write a foreground/background image to a destination buffer
59
 * for the first line of compressed data.
60
 */
61
static INLINE BYTE* WRITEFIRSTLINEFGBGIMAGE(BYTE* pbDest, const BYTE* pbDestEnd, BYTE bitmask,
62
                                            PIXEL fgPel, UINT32 cBits)
63
29.0k
{
64
29.0k
  BYTE mask = 0x01;
65
66
29.0k
  if (cBits > 8)
67
0
  {
68
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
69
0
    return NULL;
70
0
  }
71
72
29.0k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
73
24
    return NULL;
74
75
29.0k
  UNROLL(cBits, {
76
29.0k
    UINT32 data;
77
78
29.0k
    if (bitmask & mask)
79
29.0k
      data = fgPel;
80
29.0k
    else
81
29.0k
      data = BLACK_PIXEL;
82
83
29.0k
    DESTWRITEPIXEL(pbDest, data);
84
29.0k
    mask = mask << 1;
85
29.0k
  });
86
29.0k
  return pbDest;
87
29.0k
}
interleaved.c:WriteFirstLineFgBgImage24to24
Line
Count
Source
63
10.9k
{
64
10.9k
  BYTE mask = 0x01;
65
66
10.9k
  if (cBits > 8)
67
0
  {
68
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
69
0
    return NULL;
70
0
  }
71
72
10.9k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
73
10
    return NULL;
74
75
10.9k
  UNROLL(cBits, {
76
10.9k
    UINT32 data;
77
78
10.9k
    if (bitmask & mask)
79
10.9k
      data = fgPel;
80
10.9k
    else
81
10.9k
      data = BLACK_PIXEL;
82
83
10.9k
    DESTWRITEPIXEL(pbDest, data);
84
10.9k
    mask = mask << 1;
85
10.9k
  });
86
10.9k
  return pbDest;
87
10.9k
}
interleaved.c:WriteFirstLineFgBgImage16to16
Line
Count
Source
63
18.1k
{
64
18.1k
  BYTE mask = 0x01;
65
66
18.1k
  if (cBits > 8)
67
0
  {
68
0
    WLog_ERR(TAG, "cBits %d > 8", cBits);
69
0
    return NULL;
70
0
  }
71
72
18.1k
  if (!ENSURE_CAPACITY(pbDest, pbDestEnd, cBits))
73
14
    return NULL;
74
75
18.1k
  UNROLL(cBits, {
76
18.1k
    UINT32 data;
77
78
18.1k
    if (bitmask & mask)
79
18.1k
      data = fgPel;
80
18.1k
    else
81
18.1k
      data = BLACK_PIXEL;
82
83
18.1k
    DESTWRITEPIXEL(pbDest, data);
84
18.1k
    mask = mask << 1;
85
18.1k
  });
86
18.1k
  return pbDest;
87
18.1k
}
Unexecuted instantiation: interleaved.c:WriteFirstLineFgBgImage8to8
88
89
/**
90
 * Decompress an RLE compressed bitmap.
91
 */
92
static INLINE BOOL RLEDECOMPRESS(const BYTE* pbSrcBuffer, UINT32 cbSrcBuffer, BYTE* pbDestBuffer,
93
                                 UINT32 rowDelta, UINT32 width, UINT32 height)
94
17.1k
{
95
#if defined(WITH_DEBUG_CODECS)
96
  char sbuffer[128] = { 0 };
97
#endif
98
17.1k
  const BYTE* pbSrc = pbSrcBuffer;
99
17.1k
  const BYTE* pbEnd;
100
17.1k
  const BYTE* pbDestEnd;
101
17.1k
  BYTE* pbDest = pbDestBuffer;
102
17.1k
  PIXEL temp;
103
17.1k
  PIXEL fgPel = WHITE_PIXEL;
104
17.1k
  BOOL fInsertFgPel = FALSE;
105
17.1k
  BOOL fFirstLine = TRUE;
106
17.1k
  BYTE bitmask;
107
17.1k
  PIXEL pixelA, pixelB;
108
17.1k
  UINT32 runLength;
109
17.1k
  UINT32 code;
110
17.1k
  UINT32 advance = 0;
111
17.1k
  RLEEXTRA
112
113
17.1k
  if ((rowDelta == 0) || (rowDelta < width))
114
0
  {
115
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
116
0
             width);
117
0
    return FALSE;
118
0
  }
119
120
17.1k
  if (!pbSrcBuffer || !pbDestBuffer)
121
0
  {
122
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p", pbSrcBuffer,
123
0
             pbDestBuffer);
124
0
    return FALSE;
125
0
  }
126
127
17.1k
  pbEnd = pbSrcBuffer + cbSrcBuffer;
128
17.1k
  pbDestEnd = pbDestBuffer + rowDelta * height;
129
130
505k
  while (pbSrc < pbEnd)
131
501k
  {
132
    /* Watch out for the end of the first scanline. */
133
501k
    if (fFirstLine)
134
73.7k
    {
135
73.7k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
136
12.2k
      {
137
12.2k
        fFirstLine = FALSE;
138
12.2k
        fInsertFgPel = FALSE;
139
12.2k
      }
140
73.7k
    }
141
142
    /*
143
       Extract the compression order code ID from the compression
144
       order header.
145
    */
146
501k
    code = ExtractCodeId(*pbSrc);
147
148
#if defined(WITH_DEBUG_CODECS)
149
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc,
150
             rle_code_str_buffer(code, sbuffer, sizeof(sbuffer)), pbEnd - pbSrc);
151
#endif
152
153
    /* Handle Background Run Orders. */
154
501k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
155
273k
    {
156
273k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
157
273k
      if (advance == 0)
158
599
        return FALSE;
159
273k
      pbSrc = pbSrc + advance;
160
161
273k
      if (fFirstLine)
162
29.1k
      {
163
29.1k
        if (fInsertFgPel)
164
18.4k
        {
165
18.4k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
166
0
            return FALSE;
167
168
18.4k
          DESTWRITEPIXEL(pbDest, fgPel);
169
18.4k
          runLength = runLength - 1;
170
18.4k
        }
171
172
29.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
173
151
          return FALSE;
174
175
29.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
176
29.0k
      }
177
244k
      else
178
244k
      {
179
244k
        if (fInsertFgPel)
180
218k
        {
181
218k
          DESTREADPIXEL(temp, pbDest - rowDelta);
182
183
218k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
184
50
            return FALSE;
185
186
218k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
187
218k
          runLength--;
188
218k
        }
189
190
244k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
191
499
          return FALSE;
192
193
243k
        UNROLL(runLength, {
194
243k
          DESTREADPIXEL(temp, pbDest - rowDelta);
195
243k
          DESTWRITEPIXEL(pbDest, temp);
196
243k
        });
197
243k
      }
198
199
      /* A follow-on background run order will need a foreground pel inserted. */
200
272k
      fInsertFgPel = TRUE;
201
272k
      continue;
202
273k
    }
203
204
    /* For any of the other run-types a follow-on background run
205
        order does not need a foreground pel inserted. */
206
227k
    fInsertFgPel = FALSE;
207
208
227k
    switch (code)
209
227k
    {
210
      /* Handle Foreground Run Orders. */
211
46.8k
      case REGULAR_FG_RUN:
212
49.0k
      case MEGA_MEGA_FG_RUN:
213
60.9k
      case LITE_SET_FG_FG_RUN:
214
62.2k
      case MEGA_MEGA_SET_FG_RUN:
215
62.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
216
62.2k
        if (advance == 0)
217
162
          return FALSE;
218
62.0k
        pbSrc = pbSrc + advance;
219
220
62.0k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
221
13.0k
        {
222
13.0k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
223
237
            return FALSE;
224
12.8k
          SRCREADPIXEL(fgPel, pbSrc);
225
12.8k
        }
226
227
61.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
228
437
          return FALSE;
229
230
61.4k
        if (fFirstLine)
231
9.23k
        {
232
9.23k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
233
9.23k
        }
234
52.1k
        else
235
52.1k
        {
236
52.1k
          UNROLL(runLength, {
237
52.1k
            DESTREADPIXEL(temp, pbDest - rowDelta);
238
52.1k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
239
52.1k
          });
240
52.1k
        }
241
242
61.4k
        break;
243
244
      /* Handle Dithered Run Orders. */
245
13.0k
      case LITE_DITHERED_RUN:
246
14.2k
      case MEGA_MEGA_DITHERED_RUN:
247
14.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
248
14.2k
        if (advance == 0)
249
66
          return FALSE;
250
14.1k
        pbSrc = pbSrc + advance;
251
14.1k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
252
273
          return FALSE;
253
13.8k
        SRCREADPIXEL(pixelA, pbSrc);
254
13.8k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
571
          return FALSE;
256
13.3k
        SRCREADPIXEL(pixelB, pbSrc);
257
258
13.3k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
259
105
          return FALSE;
260
261
13.2k
        UNROLL(runLength, {
262
13.2k
          DESTWRITEPIXEL(pbDest, pixelA);
263
13.2k
          DESTWRITEPIXEL(pbDest, pixelB);
264
13.2k
        });
265
13.2k
        break;
266
267
      /* Handle Color Run Orders. */
268
96.3k
      case REGULAR_COLOR_RUN:
269
97.4k
      case MEGA_MEGA_COLOR_RUN:
270
97.4k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
271
97.4k
        if (advance == 0)
272
73
          return FALSE;
273
97.4k
        pbSrc = pbSrc + advance;
274
97.4k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
275
356
          return FALSE;
276
97.0k
        SRCREADPIXEL(pixelA, pbSrc);
277
278
97.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
279
347
          return FALSE;
280
281
96.7k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
282
96.7k
        break;
283
284
      /* Handle Foreground/Background Image Orders. */
285
14.0k
      case REGULAR_FGBG_IMAGE:
286
15.9k
      case MEGA_MEGA_FGBG_IMAGE:
287
20.5k
      case LITE_SET_FG_FGBG_IMAGE:
288
21.5k
      case MEGA_MEGA_SET_FGBG_IMAGE:
289
21.5k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
290
21.5k
        if (advance == 0)
291
138
          return FALSE;
292
21.4k
        pbSrc = pbSrc + advance;
293
294
21.4k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
295
5.56k
        {
296
5.56k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
297
203
            return FALSE;
298
5.36k
          SRCREADPIXEL(fgPel, pbSrc);
299
5.36k
        }
300
301
21.2k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
302
918
          return FALSE;
303
20.3k
        if (fFirstLine)
304
4.30k
        {
305
29.9k
          while (runLength > 8)
306
25.6k
          {
307
25.6k
            bitmask = *pbSrc;
308
25.6k
            pbSrc = pbSrc + 1;
309
25.6k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
310
311
25.6k
            if (!pbDest)
312
24
              return FALSE;
313
314
25.6k
            runLength = runLength - 8;
315
25.6k
          }
316
4.30k
        }
317
16.0k
        else
318
16.0k
        {
319
96.4k
          while (runLength > 8)
320
80.5k
          {
321
80.5k
            bitmask = *pbSrc++;
322
323
80.5k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
324
325
80.5k
            if (!pbDest)
326
116
              return FALSE;
327
328
80.4k
            runLength = runLength - 8;
329
80.4k
          }
330
16.0k
        }
331
332
20.1k
        if (runLength > 0)
333
17.7k
        {
334
17.7k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
335
105
            return FALSE;
336
17.5k
          bitmask = *pbSrc++;
337
338
17.5k
          if (fFirstLine)
339
2.80k
          {
340
2.80k
            pbDest =
341
2.80k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
342
2.80k
          }
343
14.7k
          else
344
14.7k
          {
345
14.7k
            pbDest =
346
14.7k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
347
14.7k
          }
348
349
17.5k
          if (!pbDest)
350
7
            return FALSE;
351
17.5k
        }
352
353
20.0k
        break;
354
355
      /* Handle Color Image Orders. */
356
20.0k
      case REGULAR_COLOR_IMAGE:
357
14.3k
      case MEGA_MEGA_COLOR_IMAGE:
358
14.3k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
359
14.3k
        if (advance == 0)
360
61
          return FALSE;
361
14.2k
        pbSrc = pbSrc + advance;
362
14.2k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
363
202
          return FALSE;
364
14.0k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
365
783
          return FALSE;
366
367
13.2k
        UNROLL(runLength, {
368
13.2k
          SRCREADPIXEL(temp, pbSrc);
369
13.2k
          DESTWRITEPIXEL(pbDest, temp);
370
13.2k
        });
371
13.2k
        break;
372
373
      /* Handle Special Order 1. */
374
2.31k
      case SPECIAL_FGBG_1:
375
2.31k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
376
0
          return FALSE;
377
2.31k
        pbSrc = pbSrc + 1;
378
379
2.31k
        if (fFirstLine)
380
267
        {
381
267
          pbDest =
382
267
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
383
267
        }
384
2.04k
        else
385
2.04k
        {
386
2.04k
          pbDest =
387
2.04k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
388
2.04k
        }
389
390
2.31k
        if (!pbDest)
391
3
          return FALSE;
392
393
2.31k
        break;
394
395
      /* Handle Special Order 2. */
396
3.75k
      case SPECIAL_FGBG_2:
397
3.75k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
398
0
          return FALSE;
399
3.75k
        pbSrc = pbSrc + 1;
400
401
3.75k
        if (fFirstLine)
402
348
        {
403
348
          pbDest =
404
348
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
405
348
        }
406
3.40k
        else
407
3.40k
        {
408
3.40k
          pbDest =
409
3.40k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
410
3.40k
        }
411
412
3.75k
        if (!pbDest)
413
7
          return FALSE;
414
415
3.74k
        break;
416
417
      /* Handle White Order. */
418
3.74k
      case SPECIAL_WHITE:
419
2.14k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
420
0
          return FALSE;
421
2.14k
        pbSrc = pbSrc + 1;
422
423
2.14k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
424
3
          return FALSE;
425
426
2.14k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
427
2.14k
        break;
428
429
      /* Handle Black Order. */
430
2.88k
      case SPECIAL_BLACK:
431
2.88k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
432
0
          return FALSE;
433
2.88k
        pbSrc = pbSrc + 1;
434
435
2.88k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
436
5
          return FALSE;
437
438
2.87k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
439
2.87k
        break;
440
441
6.45k
      default:
442
6.45k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
443
6.45k
                 code, pbSrcBuffer, pbSrc, pbEnd);
444
6.45k
        return FALSE;
445
227k
    }
446
227k
  }
447
448
4.18k
  return TRUE;
449
17.1k
}
interleaved.c:RleDecompress24to24
Line
Count
Source
94
5.71k
{
95
#if defined(WITH_DEBUG_CODECS)
96
  char sbuffer[128] = { 0 };
97
#endif
98
5.71k
  const BYTE* pbSrc = pbSrcBuffer;
99
5.71k
  const BYTE* pbEnd;
100
5.71k
  const BYTE* pbDestEnd;
101
5.71k
  BYTE* pbDest = pbDestBuffer;
102
5.71k
  PIXEL temp;
103
5.71k
  PIXEL fgPel = WHITE_PIXEL;
104
5.71k
  BOOL fInsertFgPel = FALSE;
105
5.71k
  BOOL fFirstLine = TRUE;
106
5.71k
  BYTE bitmask;
107
5.71k
  PIXEL pixelA, pixelB;
108
5.71k
  UINT32 runLength;
109
5.71k
  UINT32 code;
110
5.71k
  UINT32 advance = 0;
111
5.71k
  RLEEXTRA
112
113
5.71k
  if ((rowDelta == 0) || (rowDelta < width))
114
0
  {
115
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
116
0
             width);
117
0
    return FALSE;
118
0
  }
119
120
5.71k
  if (!pbSrcBuffer || !pbDestBuffer)
121
0
  {
122
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p", pbSrcBuffer,
123
0
             pbDestBuffer);
124
0
    return FALSE;
125
0
  }
126
127
5.71k
  pbEnd = pbSrcBuffer + cbSrcBuffer;
128
5.71k
  pbDestEnd = pbDestBuffer + rowDelta * height;
129
130
161k
  while (pbSrc < pbEnd)
131
160k
  {
132
    /* Watch out for the end of the first scanline. */
133
160k
    if (fFirstLine)
134
24.8k
    {
135
24.8k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
136
3.90k
      {
137
3.90k
        fFirstLine = FALSE;
138
3.90k
        fInsertFgPel = FALSE;
139
3.90k
      }
140
24.8k
    }
141
142
    /*
143
       Extract the compression order code ID from the compression
144
       order header.
145
    */
146
160k
    code = ExtractCodeId(*pbSrc);
147
148
#if defined(WITH_DEBUG_CODECS)
149
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc,
150
             rle_code_str_buffer(code, sbuffer, sizeof(sbuffer)), pbEnd - pbSrc);
151
#endif
152
153
    /* Handle Background Run Orders. */
154
160k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
155
88.4k
    {
156
88.4k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
157
88.4k
      if (advance == 0)
158
167
        return FALSE;
159
88.2k
      pbSrc = pbSrc + advance;
160
161
88.2k
      if (fFirstLine)
162
10.1k
      {
163
10.1k
        if (fInsertFgPel)
164
6.42k
        {
165
6.42k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
166
0
            return FALSE;
167
168
6.42k
          DESTWRITEPIXEL(pbDest, fgPel);
169
6.42k
          runLength = runLength - 1;
170
6.42k
        }
171
172
10.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
173
49
          return FALSE;
174
175
10.0k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
176
10.0k
      }
177
78.1k
      else
178
78.1k
      {
179
78.1k
        if (fInsertFgPel)
180
71.4k
        {
181
71.4k
          DESTREADPIXEL(temp, pbDest - rowDelta);
182
183
71.4k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
184
14
            return FALSE;
185
186
71.3k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
187
71.3k
          runLength--;
188
71.3k
        }
189
190
78.1k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
191
149
          return FALSE;
192
193
77.9k
        UNROLL(runLength, {
194
77.9k
          DESTREADPIXEL(temp, pbDest - rowDelta);
195
77.9k
          DESTWRITEPIXEL(pbDest, temp);
196
77.9k
        });
197
77.9k
      }
198
199
      /* A follow-on background run order will need a foreground pel inserted. */
200
88.0k
      fInsertFgPel = TRUE;
201
88.0k
      continue;
202
88.2k
    }
203
204
    /* For any of the other run-types a follow-on background run
205
        order does not need a foreground pel inserted. */
206
71.5k
    fInsertFgPel = FALSE;
207
208
71.5k
    switch (code)
209
71.5k
    {
210
      /* Handle Foreground Run Orders. */
211
15.2k
      case REGULAR_FG_RUN:
212
16.0k
      case MEGA_MEGA_FG_RUN:
213
19.5k
      case LITE_SET_FG_FG_RUN:
214
19.9k
      case MEGA_MEGA_SET_FG_RUN:
215
19.9k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
216
19.9k
        if (advance == 0)
217
48
          return FALSE;
218
19.9k
        pbSrc = pbSrc + advance;
219
220
19.9k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
221
3.90k
        {
222
3.90k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
223
83
            return FALSE;
224
3.82k
          SRCREADPIXEL(fgPel, pbSrc);
225
3.82k
        }
226
227
19.8k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
228
123
          return FALSE;
229
230
19.6k
        if (fFirstLine)
231
3.18k
        {
232
3.18k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
233
3.18k
        }
234
16.5k
        else
235
16.5k
        {
236
16.5k
          UNROLL(runLength, {
237
16.5k
            DESTREADPIXEL(temp, pbDest - rowDelta);
238
16.5k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
239
16.5k
          });
240
16.5k
        }
241
242
19.6k
        break;
243
244
      /* Handle Dithered Run Orders. */
245
3.69k
      case LITE_DITHERED_RUN:
246
4.10k
      case MEGA_MEGA_DITHERED_RUN:
247
4.10k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
248
4.10k
        if (advance == 0)
249
20
          return FALSE;
250
4.08k
        pbSrc = pbSrc + advance;
251
4.08k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
252
111
          return FALSE;
253
3.96k
        SRCREADPIXEL(pixelA, pbSrc);
254
3.96k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
279
          return FALSE;
256
3.69k
        SRCREADPIXEL(pixelB, pbSrc);
257
258
3.69k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
259
27
          return FALSE;
260
261
3.66k
        UNROLL(runLength, {
262
3.66k
          DESTWRITEPIXEL(pbDest, pixelA);
263
3.66k
          DESTWRITEPIXEL(pbDest, pixelB);
264
3.66k
        });
265
3.66k
        break;
266
267
      /* Handle Color Run Orders. */
268
30.1k
      case REGULAR_COLOR_RUN:
269
30.6k
      case MEGA_MEGA_COLOR_RUN:
270
30.6k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
271
30.6k
        if (advance == 0)
272
21
          return FALSE;
273
30.5k
        pbSrc = pbSrc + advance;
274
30.5k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
275
138
          return FALSE;
276
30.4k
        SRCREADPIXEL(pixelA, pbSrc);
277
278
30.4k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
279
101
          return FALSE;
280
281
30.3k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
282
30.3k
        break;
283
284
      /* Handle Foreground/Background Image Orders. */
285
4.34k
      case REGULAR_FGBG_IMAGE:
286
4.96k
      case MEGA_MEGA_FGBG_IMAGE:
287
6.34k
      case LITE_SET_FG_FGBG_IMAGE:
288
6.72k
      case MEGA_MEGA_SET_FGBG_IMAGE:
289
6.72k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
290
6.72k
        if (advance == 0)
291
46
          return FALSE;
292
6.68k
        pbSrc = pbSrc + advance;
293
294
6.68k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
295
1.74k
        {
296
1.74k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
297
75
            return FALSE;
298
1.67k
          SRCREADPIXEL(fgPel, pbSrc);
299
1.67k
        }
300
301
6.60k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
302
272
          return FALSE;
303
6.33k
        if (fFirstLine)
304
1.50k
        {
305
11.2k
          while (runLength > 8)
306
9.72k
          {
307
9.72k
            bitmask = *pbSrc;
308
9.72k
            pbSrc = pbSrc + 1;
309
9.72k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
310
311
9.72k
            if (!pbDest)
312
10
              return FALSE;
313
314
9.71k
            runLength = runLength - 8;
315
9.71k
          }
316
1.50k
        }
317
4.83k
        else
318
4.83k
        {
319
27.6k
          while (runLength > 8)
320
22.8k
          {
321
22.8k
            bitmask = *pbSrc++;
322
323
22.8k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
324
325
22.8k
            if (!pbDest)
326
28
              return FALSE;
327
328
22.8k
            runLength = runLength - 8;
329
22.8k
          }
330
4.83k
        }
331
332
6.29k
        if (runLength > 0)
333
5.45k
        {
334
5.45k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
335
39
            return FALSE;
336
5.41k
          bitmask = *pbSrc++;
337
338
5.41k
          if (fFirstLine)
339
988
          {
340
988
            pbDest =
341
988
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
342
988
          }
343
4.42k
          else
344
4.42k
          {
345
4.42k
            pbDest =
346
4.42k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
347
4.42k
          }
348
349
5.41k
          if (!pbDest)
350
3
            return FALSE;
351
5.41k
        }
352
353
6.25k
        break;
354
355
      /* Handle Color Image Orders. */
356
6.25k
      case REGULAR_COLOR_IMAGE:
357
4.37k
      case MEGA_MEGA_COLOR_IMAGE:
358
4.37k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
359
4.37k
        if (advance == 0)
360
19
          return FALSE;
361
4.36k
        pbSrc = pbSrc + advance;
362
4.36k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
363
64
          return FALSE;
364
4.29k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
365
269
          return FALSE;
366
367
4.02k
        UNROLL(runLength, {
368
4.02k
          SRCREADPIXEL(temp, pbSrc);
369
4.02k
          DESTWRITEPIXEL(pbDest, temp);
370
4.02k
        });
371
4.02k
        break;
372
373
      /* Handle Special Order 1. */
374
747
      case SPECIAL_FGBG_1:
375
747
        if (!buffer_within_range(pbSrc, 1, pbEnd))
376
0
          return FALSE;
377
747
        pbSrc = pbSrc + 1;
378
379
747
        if (fFirstLine)
380
81
        {
381
81
          pbDest =
382
81
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
383
81
        }
384
666
        else
385
666
        {
386
666
          pbDest =
387
666
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
388
666
        }
389
390
747
        if (!pbDest)
391
1
          return FALSE;
392
393
746
        break;
394
395
      /* Handle Special Order 2. */
396
1.35k
      case SPECIAL_FGBG_2:
397
1.35k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
398
0
          return FALSE;
399
1.35k
        pbSrc = pbSrc + 1;
400
401
1.35k
        if (fFirstLine)
402
122
        {
403
122
          pbDest =
404
122
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
405
122
        }
406
1.22k
        else
407
1.22k
        {
408
1.22k
          pbDest =
409
1.22k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
410
1.22k
        }
411
412
1.35k
        if (!pbDest)
413
3
          return FALSE;
414
415
1.34k
        break;
416
417
      /* Handle White Order. */
418
1.34k
      case SPECIAL_WHITE:
419
637
        if (!buffer_within_range(pbSrc, 1, pbEnd))
420
0
          return FALSE;
421
637
        pbSrc = pbSrc + 1;
422
423
637
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
424
1
          return FALSE;
425
426
636
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
427
636
        break;
428
429
      /* Handle Black Order. */
430
926
      case SPECIAL_BLACK:
431
926
        if (!buffer_within_range(pbSrc, 1, pbEnd))
432
0
          return FALSE;
433
926
        pbSrc = pbSrc + 1;
434
435
926
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
436
1
          return FALSE;
437
438
925
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
439
925
        break;
440
441
2.13k
      default:
442
2.13k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
443
2.13k
                 code, pbSrcBuffer, pbSrc, pbEnd);
444
2.13k
        return FALSE;
445
71.5k
    }
446
71.5k
  }
447
448
1.41k
  return TRUE;
449
5.71k
}
interleaved.c:RleDecompress16to16
Line
Count
Source
94
11.4k
{
95
#if defined(WITH_DEBUG_CODECS)
96
  char sbuffer[128] = { 0 };
97
#endif
98
11.4k
  const BYTE* pbSrc = pbSrcBuffer;
99
11.4k
  const BYTE* pbEnd;
100
11.4k
  const BYTE* pbDestEnd;
101
11.4k
  BYTE* pbDest = pbDestBuffer;
102
11.4k
  PIXEL temp;
103
11.4k
  PIXEL fgPel = WHITE_PIXEL;
104
11.4k
  BOOL fInsertFgPel = FALSE;
105
11.4k
  BOOL fFirstLine = TRUE;
106
11.4k
  BYTE bitmask;
107
11.4k
  PIXEL pixelA, pixelB;
108
11.4k
  UINT32 runLength;
109
11.4k
  UINT32 code;
110
11.4k
  UINT32 advance = 0;
111
11.4k
  RLEEXTRA
112
113
11.4k
  if ((rowDelta == 0) || (rowDelta < width))
114
0
  {
115
0
    WLog_ERR(TAG, "Invalid arguments: rowDelta=%" PRIu32 " == 0 || < width=%" PRIu32, rowDelta,
116
0
             width);
117
0
    return FALSE;
118
0
  }
119
120
11.4k
  if (!pbSrcBuffer || !pbDestBuffer)
121
0
  {
122
0
    WLog_ERR(TAG, "Invalid arguments: pbSrcBuffer=%p, pbDestBuffer=%p", pbSrcBuffer,
123
0
             pbDestBuffer);
124
0
    return FALSE;
125
0
  }
126
127
11.4k
  pbEnd = pbSrcBuffer + cbSrcBuffer;
128
11.4k
  pbDestEnd = pbDestBuffer + rowDelta * height;
129
130
344k
  while (pbSrc < pbEnd)
131
341k
  {
132
    /* Watch out for the end of the first scanline. */
133
341k
    if (fFirstLine)
134
48.9k
    {
135
48.9k
      if ((UINT32)(pbDest - pbDestBuffer) >= rowDelta)
136
8.34k
      {
137
8.34k
        fFirstLine = FALSE;
138
8.34k
        fInsertFgPel = FALSE;
139
8.34k
      }
140
48.9k
    }
141
142
    /*
143
       Extract the compression order code ID from the compression
144
       order header.
145
    */
146
341k
    code = ExtractCodeId(*pbSrc);
147
148
#if defined(WITH_DEBUG_CODECS)
149
    WLog_VRB(TAG, "pbSrc=%p code=%s, rem=%" PRIuz, pbSrc,
150
             rle_code_str_buffer(code, sbuffer, sizeof(sbuffer)), pbEnd - pbSrc);
151
#endif
152
153
    /* Handle Background Run Orders. */
154
341k
    if ((code == REGULAR_BG_RUN) || (code == MEGA_MEGA_BG_RUN))
155
185k
    {
156
185k
      runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
157
185k
      if (advance == 0)
158
432
        return FALSE;
159
185k
      pbSrc = pbSrc + advance;
160
161
185k
      if (fFirstLine)
162
19.0k
      {
163
19.0k
        if (fInsertFgPel)
164
12.0k
        {
165
12.0k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
166
0
            return FALSE;
167
168
12.0k
          DESTWRITEPIXEL(pbDest, fgPel);
169
12.0k
          runLength = runLength - 1;
170
12.0k
        }
171
172
19.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
173
102
          return FALSE;
174
175
18.9k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, BLACK_PIXEL); });
176
18.9k
      }
177
166k
      else
178
166k
      {
179
166k
        if (fInsertFgPel)
180
147k
        {
181
147k
          DESTREADPIXEL(temp, pbDest - rowDelta);
182
183
147k
          if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
184
36
            return FALSE;
185
186
147k
          DESTWRITEPIXEL(pbDest, temp ^ fgPel);
187
147k
          runLength--;
188
147k
        }
189
190
165k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
191
350
          return FALSE;
192
193
165k
        UNROLL(runLength, {
194
165k
          DESTREADPIXEL(temp, pbDest - rowDelta);
195
165k
          DESTWRITEPIXEL(pbDest, temp);
196
165k
        });
197
165k
      }
198
199
      /* A follow-on background run order will need a foreground pel inserted. */
200
184k
      fInsertFgPel = TRUE;
201
184k
      continue;
202
185k
    }
203
204
    /* For any of the other run-types a follow-on background run
205
        order does not need a foreground pel inserted. */
206
155k
    fInsertFgPel = FALSE;
207
208
155k
    switch (code)
209
155k
    {
210
      /* Handle Foreground Run Orders. */
211
31.5k
      case REGULAR_FG_RUN:
212
33.0k
      case MEGA_MEGA_FG_RUN:
213
41.3k
      case LITE_SET_FG_FG_RUN:
214
42.2k
      case MEGA_MEGA_SET_FG_RUN:
215
42.2k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
216
42.2k
        if (advance == 0)
217
114
          return FALSE;
218
42.1k
        pbSrc = pbSrc + advance;
219
220
42.1k
        if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN)
221
9.18k
        {
222
9.18k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
223
154
            return FALSE;
224
9.03k
          SRCREADPIXEL(fgPel, pbSrc);
225
9.03k
        }
226
227
42.0k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
228
314
          return FALSE;
229
230
41.7k
        if (fFirstLine)
231
6.05k
        {
232
6.05k
          UNROLL(runLength, { DESTWRITEPIXEL(pbDest, fgPel); });
233
6.05k
        }
234
35.6k
        else
235
35.6k
        {
236
35.6k
          UNROLL(runLength, {
237
35.6k
            DESTREADPIXEL(temp, pbDest - rowDelta);
238
35.6k
            DESTWRITEPIXEL(pbDest, temp ^ fgPel);
239
35.6k
          });
240
35.6k
        }
241
242
41.7k
        break;
243
244
      /* Handle Dithered Run Orders. */
245
9.35k
      case LITE_DITHERED_RUN:
246
10.1k
      case MEGA_MEGA_DITHERED_RUN:
247
10.1k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
248
10.1k
        if (advance == 0)
249
46
          return FALSE;
250
10.0k
        pbSrc = pbSrc + advance;
251
10.0k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
252
162
          return FALSE;
253
9.91k
        SRCREADPIXEL(pixelA, pbSrc);
254
9.91k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
255
292
          return FALSE;
256
9.62k
        SRCREADPIXEL(pixelB, pbSrc);
257
258
9.62k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength * 2))
259
78
          return FALSE;
260
261
9.54k
        UNROLL(runLength, {
262
9.54k
          DESTWRITEPIXEL(pbDest, pixelA);
263
9.54k
          DESTWRITEPIXEL(pbDest, pixelB);
264
9.54k
        });
265
9.54k
        break;
266
267
      /* Handle Color Run Orders. */
268
66.1k
      case REGULAR_COLOR_RUN:
269
66.8k
      case MEGA_MEGA_COLOR_RUN:
270
66.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
271
66.8k
        if (advance == 0)
272
52
          return FALSE;
273
66.8k
        pbSrc = pbSrc + advance;
274
66.8k
        if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
275
218
          return FALSE;
276
66.6k
        SRCREADPIXEL(pixelA, pbSrc);
277
278
66.6k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
279
246
          return FALSE;
280
281
66.3k
        UNROLL(runLength, { DESTWRITEPIXEL(pbDest, pixelA); });
282
66.3k
        break;
283
284
      /* Handle Foreground/Background Image Orders. */
285
9.71k
      case REGULAR_FGBG_IMAGE:
286
10.9k
      case MEGA_MEGA_FGBG_IMAGE:
287
14.2k
      case LITE_SET_FG_FGBG_IMAGE:
288
14.8k
      case MEGA_MEGA_SET_FGBG_IMAGE:
289
14.8k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
290
14.8k
        if (advance == 0)
291
92
          return FALSE;
292
14.7k
        pbSrc = pbSrc + advance;
293
294
14.7k
        if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE)
295
3.82k
        {
296
3.82k
          if (!buffer_within_range(pbSrc, PIXEL_SIZE, pbEnd))
297
128
            return FALSE;
298
3.69k
          SRCREADPIXEL(fgPel, pbSrc);
299
3.69k
        }
300
301
14.6k
        if (!buffer_within_range(pbSrc, runLength / 8, pbEnd))
302
646
          return FALSE;
303
13.9k
        if (fFirstLine)
304
2.80k
        {
305
18.7k
          while (runLength > 8)
306
15.9k
          {
307
15.9k
            bitmask = *pbSrc;
308
15.9k
            pbSrc = pbSrc + 1;
309
15.9k
            pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, 8);
310
311
15.9k
            if (!pbDest)
312
14
              return FALSE;
313
314
15.9k
            runLength = runLength - 8;
315
15.9k
          }
316
2.80k
        }
317
11.1k
        else
318
11.1k
        {
319
68.8k
          while (runLength > 8)
320
57.7k
          {
321
57.7k
            bitmask = *pbSrc++;
322
323
57.7k
            pbDest = WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, 8);
324
325
57.7k
            if (!pbDest)
326
88
              return FALSE;
327
328
57.6k
            runLength = runLength - 8;
329
57.6k
          }
330
11.1k
        }
331
332
13.8k
        if (runLength > 0)
333
12.2k
        {
334
12.2k
          if (!buffer_within_range(pbSrc, 1, pbEnd))
335
66
            return FALSE;
336
12.1k
          bitmask = *pbSrc++;
337
338
12.1k
          if (fFirstLine)
339
1.81k
          {
340
1.81k
            pbDest =
341
1.81k
                WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, bitmask, fgPel, runLength);
342
1.81k
          }
343
10.3k
          else
344
10.3k
          {
345
10.3k
            pbDest =
346
10.3k
                WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, bitmask, fgPel, runLength);
347
10.3k
          }
348
349
12.1k
          if (!pbDest)
350
4
            return FALSE;
351
12.1k
        }
352
353
13.8k
        break;
354
355
      /* Handle Color Image Orders. */
356
13.8k
      case REGULAR_COLOR_IMAGE:
357
9.95k
      case MEGA_MEGA_COLOR_IMAGE:
358
9.95k
        runLength = ExtractRunLength(code, pbSrc, pbEnd, &advance);
359
9.95k
        if (advance == 0)
360
42
          return FALSE;
361
9.91k
        pbSrc = pbSrc + advance;
362
9.91k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, runLength))
363
138
          return FALSE;
364
9.77k
        if (!ENSURE_CAPACITY(pbSrc, pbEnd, runLength))
365
514
          return FALSE;
366
367
9.26k
        UNROLL(runLength, {
368
9.26k
          SRCREADPIXEL(temp, pbSrc);
369
9.26k
          DESTWRITEPIXEL(pbDest, temp);
370
9.26k
        });
371
9.26k
        break;
372
373
      /* Handle Special Order 1. */
374
1.56k
      case SPECIAL_FGBG_1:
375
1.56k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
376
0
          return FALSE;
377
1.56k
        pbSrc = pbSrc + 1;
378
379
1.56k
        if (fFirstLine)
380
186
        {
381
186
          pbDest =
382
186
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg1, fgPel, 8);
383
186
        }
384
1.38k
        else
385
1.38k
        {
386
1.38k
          pbDest =
387
1.38k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg1, fgPel, 8);
388
1.38k
        }
389
390
1.56k
        if (!pbDest)
391
2
          return FALSE;
392
393
1.56k
        break;
394
395
      /* Handle Special Order 2. */
396
2.40k
      case SPECIAL_FGBG_2:
397
2.40k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
398
0
          return FALSE;
399
2.40k
        pbSrc = pbSrc + 1;
400
401
2.40k
        if (fFirstLine)
402
226
        {
403
226
          pbDest =
404
226
              WRITEFIRSTLINEFGBGIMAGE(pbDest, pbDestEnd, g_MaskSpecialFgBg2, fgPel, 8);
405
226
        }
406
2.17k
        else
407
2.17k
        {
408
2.17k
          pbDest =
409
2.17k
              WRITEFGBGIMAGE(pbDest, pbDestEnd, rowDelta, g_MaskSpecialFgBg2, fgPel, 8);
410
2.17k
        }
411
412
2.40k
        if (!pbDest)
413
4
          return FALSE;
414
415
2.39k
        break;
416
417
      /* Handle White Order. */
418
2.39k
      case SPECIAL_WHITE:
419
1.50k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
420
0
          return FALSE;
421
1.50k
        pbSrc = pbSrc + 1;
422
423
1.50k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
424
2
          return FALSE;
425
426
1.50k
        DESTWRITEPIXEL(pbDest, WHITE_PIXEL);
427
1.50k
        break;
428
429
      /* Handle Black Order. */
430
1.95k
      case SPECIAL_BLACK:
431
1.95k
        if (!buffer_within_range(pbSrc, 1, pbEnd))
432
0
          return FALSE;
433
1.95k
        pbSrc = pbSrc + 1;
434
435
1.95k
        if (!ENSURE_CAPACITY(pbDest, pbDestEnd, 1))
436
4
          return FALSE;
437
438
1.95k
        DESTWRITEPIXEL(pbDest, BLACK_PIXEL);
439
1.95k
        break;
440
441
4.31k
      default:
442
4.31k
        WLog_ERR(TAG, "invalid code 0x%08" PRIx32 ", pbSrcBuffer=%p, pbSrc=%p, pbEnd=%p",
443
4.31k
                 code, pbSrcBuffer, pbSrc, pbEnd);
444
4.31k
        return FALSE;
445
155k
    }
446
155k
  }
447
448
2.77k
  return TRUE;
449
11.4k
}
Unexecuted instantiation: interleaved.c:RleDecompress8to8