Coverage Report

Created: 2025-12-31 07:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/scpr.h
Line
Count
Source
1
/*
2
 * ScreenPressor decoder
3
 *
4
 * Copyright (c) 2017 Paul B Mahol
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#ifndef AVCODEC_SCPR_H
24
#define AVCODEC_SCPR_H
25
26
#include "avcodec.h"
27
#include "bytestream.h"
28
#include "scpr3.h"
29
30
typedef struct RangeCoder {
31
    uint32_t   code;
32
    uint32_t   range;
33
    uint32_t   code1;
34
} RangeCoder;
35
36
typedef struct PixelModel {
37
    uint32_t    freq[256];
38
    uint32_t    lookup[16];
39
    uint32_t    total_freq;
40
} PixelModel;
41
42
typedef struct SCPRContext {
43
    int             version;
44
    AVFrame        *last_frame;
45
    AVFrame        *current_frame;
46
    GetByteContext  gb;
47
    RangeCoder      rc;
48
    PixelModel      pixel_model[3][4096];
49
    uint32_t        op_model[6][7];
50
    uint32_t        run_model[6][257];
51
    uint32_t        range_model[257];
52
    uint32_t        count_model[257];
53
    uint32_t        fill_model[6];
54
    uint32_t        sxy_model[4][17];
55
    uint32_t        mv_model[2][513];
56
    uint32_t        nbx, nby;
57
    uint32_t        nbcount;
58
    uint32_t       *blocks;
59
    uint32_t        cbits;
60
    int             cxshift;
61
62
    PixelModel3     pixel_model3[3][4096];
63
    RunModel3       run_model3[6];
64
    RunModel3       range_model3;
65
    RunModel3       count_model3;
66
    FillModel3      fill_model3;
67
    SxyModel3       sxy_model3[4];
68
    MVModel3        mv_model3[2];
69
    OpModel3        op_model3[6];
70
71
    int           (*get_freq)(RangeCoder *rc, uint32_t total_freq, uint32_t *freq);
72
    int           (*decode)(GetByteContext *gb, RangeCoder *rc, uint32_t cumFreq, uint32_t freq, uint32_t total_freq);
73
} SCPRContext;
74
75
static int decode_run_i(AVCodecContext *avctx, uint32_t ptype, int run,
76
                        int *px, int *py, uint32_t clr, uint32_t *dst,
77
                        int linesize, uint32_t *plx, uint32_t *ply,
78
                        uint32_t backstep, int off, int *cx, int *cx1)
79
1.10M
{
80
1.10M
    uint32_t r, g, b;
81
1.10M
    int z;
82
1.10M
    int x = *px,
83
1.10M
        y = *py;
84
1.10M
    uint32_t lx = *plx,
85
1.10M
             ly = *ply;
86
87
1.10M
    if (y >= avctx->height)
88
0
        return AVERROR_INVALIDDATA;
89
90
1.10M
    switch (ptype) {
91
68.4k
    case 0:
92
7.81M
        while (run-- > 0) {
93
7.74M
            dst[y * linesize + x] = clr;
94
7.74M
            lx = x;
95
7.74M
            ly = y;
96
7.74M
            (x)++;
97
7.74M
            if (x >= avctx->width) {
98
434k
                x = 0;
99
434k
                (y)++;
100
434k
                if (y >= avctx->height && run)
101
357
                    return AVERROR_INVALIDDATA;
102
434k
            }
103
7.74M
        }
104
68.1k
        break;
105
126k
    case 1:
106
16.9M
        while (run-- > 0) {
107
16.7M
            dst[y * linesize + x] = dst[ly * linesize + lx];
108
16.7M
            lx = x;
109
16.7M
            ly = y;
110
16.7M
            (x)++;
111
16.7M
            if (x >= avctx->width) {
112
437k
                x = 0;
113
437k
                (y)++;
114
437k
                if (y >= avctx->height && run)
115
515
                    return AVERROR_INVALIDDATA;
116
437k
            }
117
16.7M
        }
118
125k
        clr = dst[ly * linesize + lx];
119
125k
        break;
120
103k
    case 2:
121
103k
        if (y < 1)
122
0
            return AVERROR_INVALIDDATA;
123
124
12.6M
        while (run-- > 0) {
125
12.5M
            clr = dst[y * linesize + x + off + 1];
126
12.5M
            dst[y * linesize + x] = clr;
127
12.5M
            lx = x;
128
12.5M
            ly = y;
129
12.5M
            (x)++;
130
12.5M
            if (x >= avctx->width) {
131
841k
                x = 0;
132
841k
                (y)++;
133
841k
                if (y >= avctx->height && run)
134
457
                    return AVERROR_INVALIDDATA;
135
841k
            }
136
12.5M
        }
137
102k
        break;
138
112k
    case 4:
139
112k
        if (y < 1 || (y == 1 && x == 0))
140
0
            return AVERROR_INVALIDDATA;
141
142
11.0M
        while (run-- > 0) {
143
10.8M
            uint8_t *odst = (uint8_t *)dst;
144
10.8M
            int off1 = (ly * linesize + lx) * 4;
145
10.8M
            int off2 = ((y * linesize + x) + off) * 4;
146
147
10.8M
            if (x == 0) {
148
1.35M
                z = backstep * 4;
149
9.53M
            } else {
150
9.53M
                z = 0;
151
9.53M
            }
152
153
10.8M
            r = odst[off1] +
154
10.8M
                odst[off2 + 4] -
155
10.8M
                odst[off2 - z ];
156
10.8M
            g = odst[off1 + 1] +
157
10.8M
                odst[off2 + 5] -
158
10.8M
                odst[off2 - z  + 1];
159
10.8M
            b = odst[off1 + 2] +
160
10.8M
                odst[off2 + 6] -
161
10.8M
                odst[off2 - z  + 2];
162
10.8M
            clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
163
10.8M
            dst[y * linesize + x] = clr;
164
10.8M
            lx = x;
165
10.8M
            ly = y;
166
10.8M
            (x)++;
167
10.8M
            if (x >= avctx->width) {
168
1.35M
                x = 0;
169
1.35M
                (y)++;
170
1.35M
                if (y >= avctx->height && run)
171
308
                    return AVERROR_INVALIDDATA;
172
1.35M
            }
173
10.8M
        }
174
112k
        break;
175
494k
    case 5:
176
494k
        if (y < 1 || (y == 1 && x == 0))
177
0
            return AVERROR_INVALIDDATA;
178
179
105M
        while (run-- > 0) {
180
105M
            if (x == 0) {
181
3.95M
                z = backstep;
182
101M
            } else {
183
101M
                z = 0;
184
101M
            }
185
186
105M
            clr = dst[y * linesize + x + off - z];
187
105M
            dst[y * linesize + x] = clr;
188
105M
            lx = x;
189
105M
            ly = y;
190
105M
            (x)++;
191
105M
            if (x >= avctx->width) {
192
3.96M
                x = 0;
193
3.96M
                (y)++;
194
3.96M
                if (y >= avctx->height && run)
195
534
                    return AVERROR_INVALIDDATA;
196
3.96M
            }
197
105M
        }
198
494k
        break;
199
1.10M
    }
200
201
1.10M
    *px = x;
202
1.10M
    *py = y;
203
1.10M
    *plx= lx;
204
1.10M
    *ply= ly;
205
206
1.10M
    if (avctx->bits_per_coded_sample == 16) {
207
570k
        *cx1 = (clr & 0x3F00) >> 2;
208
570k
        *cx = (clr & 0x3FFFFF) >> 16;
209
570k
    } else {
210
530k
        *cx1 = (clr & 0xFC00) >> 4;
211
530k
        *cx = (clr & 0xFFFFFF) >> 18;
212
530k
    }
213
214
1.10M
    return 0;
215
1.10M
}
216
217
static int decode_run_p(AVCodecContext *avctx, uint32_t ptype, int run,
218
                        int x, int y, uint32_t clr,
219
                        uint32_t *dst, uint32_t *prev,
220
                        int linesize, int plinesize,
221
                        uint32_t *bx, uint32_t *by,
222
                        uint32_t backstep, int sx1, int sx2,
223
                        int *cx, int *cx1)
224
951k
{
225
951k
    uint32_t r, g, b;
226
951k
    int z;
227
228
951k
    switch (ptype) {
229
249k
    case 0:
230
20.0M
        while (run-- > 0) {
231
19.8M
            if (*by >= avctx->height)
232
1.83k
                return AVERROR_INVALIDDATA;
233
234
19.8M
            dst[*by * linesize + *bx] = clr;
235
19.8M
            (*bx)++;
236
19.8M
            if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
237
5.17M
                *bx = x * 16 + sx1;
238
5.17M
                (*by)++;
239
5.17M
            }
240
19.8M
        }
241
248k
        break;
242
248k
    case 1:
243
11.5M
        while (run-- > 0) {
244
11.4M
            if (*bx == 0) {
245
68.8k
                if (*by < 1)
246
545
                    return AVERROR_INVALIDDATA;
247
68.3k
                z = backstep;
248
11.3M
            } else {
249
11.3M
                z = 0;
250
11.3M
            }
251
252
11.4M
            if (*by >= avctx->height)
253
1.21k
                return AVERROR_INVALIDDATA;
254
255
11.4M
            clr = dst[*by * linesize + *bx - 1 - z];
256
11.4M
            dst[*by * linesize + *bx] = clr;
257
11.4M
            (*bx)++;
258
11.4M
            if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
259
2.90M
                *bx = x * 16 + sx1;
260
2.90M
                (*by)++;
261
2.90M
            }
262
11.4M
        }
263
86.8k
        break;
264
205k
    case 2:
265
18.5M
        while (run-- > 0) {
266
18.3M
            if (*by < 1 || *by >= avctx->height)
267
1.61k
                return AVERROR_INVALIDDATA;
268
269
18.3M
            clr = dst[(*by - 1) * linesize + *bx];
270
18.3M
            dst[*by * linesize + *bx] = clr;
271
18.3M
            (*bx)++;
272
18.3M
            if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
273
3.76M
                *bx = x * 16 + sx1;
274
3.76M
                (*by)++;
275
3.76M
            }
276
18.3M
        }
277
203k
        break;
278
251k
    case 3:
279
22.7M
        while (run-- > 0) {
280
22.5M
            if (*by >= avctx->height)
281
1.43k
                return AVERROR_INVALIDDATA;
282
283
22.5M
            clr = prev[*by * plinesize + *bx];
284
22.5M
            dst[*by * linesize + *bx] = clr;
285
22.5M
            (*bx)++;
286
22.5M
            if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
287
4.86M
                *bx = x * 16 + sx1;
288
4.86M
                (*by)++;
289
4.86M
            }
290
22.5M
        }
291
250k
        break;
292
250k
    case 4:
293
7.21M
        while (run-- > 0) {
294
7.15M
            uint8_t *odst = (uint8_t *)dst;
295
296
7.15M
            if (*by < 1 || *by >= avctx->height)
297
2.40k
                return AVERROR_INVALIDDATA;
298
299
7.15M
            if (*bx == 0) {
300
44.1k
                if (*by < 2)
301
196
                    return AVERROR_INVALIDDATA;
302
43.9k
                z = backstep;
303
7.11M
            } else {
304
7.11M
                z = 0;
305
7.11M
            }
306
307
7.15M
            r = odst[((*by - 1) * linesize + *bx) * 4] +
308
7.15M
                odst[(*by * linesize + *bx - 1 - z) * 4] -
309
7.15M
                odst[((*by - 1) * linesize + *bx - 1 - z) * 4];
310
7.15M
            g = odst[((*by - 1) * linesize + *bx) * 4 + 1] +
311
7.15M
                odst[(*by * linesize + *bx - 1 - z) * 4 + 1] -
312
7.15M
                odst[((*by - 1) * linesize + *bx - 1 - z) * 4 + 1];
313
7.15M
            b = odst[((*by - 1) * linesize + *bx) * 4 + 2] +
314
7.15M
                odst[(*by * linesize + *bx - 1 - z) * 4 + 2] -
315
7.15M
                odst[((*by - 1) * linesize + *bx - 1 - z) * 4 + 2];
316
7.15M
            clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
317
7.15M
            dst[*by * linesize + *bx] = clr;
318
7.15M
            (*bx)++;
319
7.15M
            if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
320
2.56M
                *bx = x * 16 + sx1;
321
2.56M
                (*by)++;
322
2.56M
            }
323
7.15M
        }
324
53.9k
        break;
325
98.8k
    case 5:
326
12.7M
        while (run-- > 0) {
327
12.6M
            if (*by < 1 || *by >= avctx->height)
328
3.55k
                return AVERROR_INVALIDDATA;
329
330
12.6M
            if (*bx == 0) {
331
497k
                if (*by < 2)
332
196
                    return AVERROR_INVALIDDATA;
333
496k
                z = backstep;
334
12.1M
            } else {
335
12.1M
                z = 0;
336
12.1M
            }
337
338
12.6M
            clr = dst[(*by - 1) * linesize + *bx - 1 - z];
339
12.6M
            dst[*by * linesize + *bx] = clr;
340
12.6M
            (*bx)++;
341
12.6M
            if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
342
4.55M
                *bx = x * 16 + sx1;
343
4.55M
                (*by)++;
344
4.55M
            }
345
12.6M
        }
346
95.1k
        break;
347
951k
    }
348
349
938k
    if (avctx->bits_per_coded_sample == 16) {
350
498k
        *cx1 = (clr & 0x3F00) >> 2;
351
498k
        *cx = (clr & 0x3FFFFF) >> 16;
352
498k
    } else {
353
439k
        *cx1 = (clr & 0xFC00) >> 4;
354
439k
        *cx = (clr & 0xFFFFFF) >> 18;
355
439k
    }
356
357
938k
    return 0;
358
951k
}
359
360
#endif /* AVCODEC_SCPR_H */