FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/scpr.h
Date: 2026-09-28 11:37:26
Exec Total Coverage
Lines: 0 204 0.0%
Functions: 0 2 0.0%
Branches: 0 143 0.0%

Line Branch Exec 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 ✗ av_unused 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 {
80 uint32_t r, g, b;
81 int z;
82 ✗ int x = *px,
83 ✗ y = *py;
84 ✗ uint32_t lx = *plx,
85 ✗ ly = *ply;
86
87 ✗ if (y >= avctx->height)
88 ✗ return AVERROR_INVALIDDATA;
89
90 ✗ switch (ptype) {
91 ✗ case 0:
92 ✗ while (run-- > 0) {
93 ✗ dst[y * linesize + x] = clr;
94 ✗ lx = x;
95 ✗ ly = y;
96 ✗ (x)++;
97 ✗ if (x >= avctx->width) {
98 ✗ x = 0;
99 ✗ (y)++;
100 ✗ if (y >= avctx->height && run)
101 ✗ return AVERROR_INVALIDDATA;
102 }
103 }
104 ✗ break;
105 ✗ case 1:
106 ✗ while (run-- > 0) {
107 ✗ dst[y * linesize + x] = dst[ly * linesize + lx];
108 ✗ lx = x;
109 ✗ ly = y;
110 ✗ (x)++;
111 ✗ if (x >= avctx->width) {
112 ✗ x = 0;
113 ✗ (y)++;
114 ✗ if (y >= avctx->height && run)
115 ✗ return AVERROR_INVALIDDATA;
116 }
117 }
118 ✗ clr = dst[ly * linesize + lx];
119 ✗ break;
120 ✗ case 2:
121 ✗ if (y < 1)
122 ✗ return AVERROR_INVALIDDATA;
123
124 ✗ while (run-- > 0) {
125 ✗ clr = dst[y * linesize + x + off + 1];
126 ✗ dst[y * linesize + x] = clr;
127 ✗ lx = x;
128 ✗ ly = y;
129 ✗ (x)++;
130 ✗ if (x >= avctx->width) {
131 ✗ x = 0;
132 ✗ (y)++;
133 ✗ if (y >= avctx->height && run)
134 ✗ return AVERROR_INVALIDDATA;
135 }
136 }
137 ✗ break;
138 ✗ case 4:
139 ✗ if (y < 1 || (y == 1 && x == 0))
140 ✗ return AVERROR_INVALIDDATA;
141
142 ✗ while (run-- > 0) {
143 ✗ uint8_t *odst = (uint8_t *)dst;
144 ✗ int off1 = (ly * linesize + lx) * 4;
145 ✗ int off2 = ((y * linesize + x) + off) * 4;
146
147 ✗ if (x == 0) {
148 ✗ z = backstep * 4;
149 } else {
150 ✗ z = 0;
151 }
152
153 ✗ r = odst[off1] +
154 ✗ odst[off2 + 4] -
155 ✗ odst[off2 - z ];
156 ✗ g = odst[off1 + 1] +
157 ✗ odst[off2 + 5] -
158 ✗ odst[off2 - z + 1];
159 ✗ b = odst[off1 + 2] +
160 ✗ odst[off2 + 6] -
161 ✗ odst[off2 - z + 2];
162 ✗ clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
163 ✗ dst[y * linesize + x] = clr;
164 ✗ lx = x;
165 ✗ ly = y;
166 ✗ (x)++;
167 ✗ if (x >= avctx->width) {
168 ✗ x = 0;
169 ✗ (y)++;
170 ✗ if (y >= avctx->height && run)
171 ✗ return AVERROR_INVALIDDATA;
172 }
173 }
174 ✗ break;
175 ✗ case 5:
176 ✗ if (y < 1 || (y == 1 && x == 0))
177 ✗ return AVERROR_INVALIDDATA;
178
179 ✗ while (run-- > 0) {
180 ✗ if (x == 0) {
181 ✗ z = backstep;
182 } else {
183 ✗ z = 0;
184 }
185
186 ✗ clr = dst[y * linesize + x + off - z];
187 ✗ dst[y * linesize + x] = clr;
188 ✗ lx = x;
189 ✗ ly = y;
190 ✗ (x)++;
191 ✗ if (x >= avctx->width) {
192 ✗ x = 0;
193 ✗ (y)++;
194 ✗ if (y >= avctx->height && run)
195 ✗ return AVERROR_INVALIDDATA;
196 }
197 }
198 ✗ break;
199 }
200
201 ✗ *px = x;
202 ✗ *py = y;
203 ✗ *plx= lx;
204 ✗ *ply= ly;
205
206 ✗ if (avctx->bits_per_coded_sample == 16) {
207 ✗ *cx1 = (clr & 0x3F00) >> 2;
208 ✗ *cx = (clr & 0x3FFFFF) >> 16;
209 } else {
210 ✗ *cx1 = (clr & 0xFC00) >> 4;
211 ✗ *cx = (clr & 0xFFFFFF) >> 18;
212 }
213
214 ✗ return 0;
215 }
216
217 ✗ av_unused 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 {
225 uint32_t r, g, b;
226 int z;
227
228 ✗ switch (ptype) {
229 ✗ case 0:
230 ✗ while (run-- > 0) {
231 ✗ if (*by >= avctx->height)
232 ✗ return AVERROR_INVALIDDATA;
233
234 ✗ dst[*by * linesize + *bx] = clr;
235 ✗ (*bx)++;
236 ✗ if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
237 ✗ *bx = x * 16 + sx1;
238 ✗ (*by)++;
239 }
240 }
241 ✗ break;
242 ✗ case 1:
243 ✗ while (run-- > 0) {
244 ✗ if (*bx == 0) {
245 ✗ if (*by < 1)
246 ✗ return AVERROR_INVALIDDATA;
247 ✗ z = backstep;
248 } else {
249 ✗ z = 0;
250 }
251
252 ✗ if (*by >= avctx->height)
253 ✗ return AVERROR_INVALIDDATA;
254
255 ✗ clr = dst[*by * linesize + *bx - 1 - z];
256 ✗ dst[*by * linesize + *bx] = clr;
257 ✗ (*bx)++;
258 ✗ if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
259 ✗ *bx = x * 16 + sx1;
260 ✗ (*by)++;
261 }
262 }
263 ✗ break;
264 ✗ case 2:
265 ✗ while (run-- > 0) {
266 ✗ if (*by < 1 || *by >= avctx->height)
267 ✗ return AVERROR_INVALIDDATA;
268
269 ✗ clr = dst[(*by - 1) * linesize + *bx];
270 ✗ dst[*by * linesize + *bx] = clr;
271 ✗ (*bx)++;
272 ✗ if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
273 ✗ *bx = x * 16 + sx1;
274 ✗ (*by)++;
275 }
276 }
277 ✗ break;
278 ✗ case 3:
279 ✗ while (run-- > 0) {
280 ✗ if (*by >= avctx->height)
281 ✗ return AVERROR_INVALIDDATA;
282
283 ✗ clr = prev[*by * plinesize + *bx];
284 ✗ dst[*by * linesize + *bx] = clr;
285 ✗ (*bx)++;
286 ✗ if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
287 ✗ *bx = x * 16 + sx1;
288 ✗ (*by)++;
289 }
290 }
291 ✗ break;
292 ✗ case 4:
293 ✗ while (run-- > 0) {
294 ✗ uint8_t *odst = (uint8_t *)dst;
295
296 ✗ if (*by < 1 || *by >= avctx->height)
297 ✗ return AVERROR_INVALIDDATA;
298
299 ✗ if (*bx == 0) {
300 ✗ if (*by < 2)
301 ✗ return AVERROR_INVALIDDATA;
302 ✗ z = backstep;
303 } else {
304 ✗ z = 0;
305 }
306
307 ✗ r = odst[((*by - 1) * linesize + *bx) * 4] +
308 ✗ odst[(*by * linesize + *bx - 1 - z) * 4] -
309 ✗ odst[((*by - 1) * linesize + *bx - 1 - z) * 4];
310 ✗ g = odst[((*by - 1) * linesize + *bx) * 4 + 1] +
311 ✗ odst[(*by * linesize + *bx - 1 - z) * 4 + 1] -
312 ✗ odst[((*by - 1) * linesize + *bx - 1 - z) * 4 + 1];
313 ✗ b = odst[((*by - 1) * linesize + *bx) * 4 + 2] +
314 ✗ odst[(*by * linesize + *bx - 1 - z) * 4 + 2] -
315 ✗ odst[((*by - 1) * linesize + *bx - 1 - z) * 4 + 2];
316 ✗ clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
317 ✗ dst[*by * linesize + *bx] = clr;
318 ✗ (*bx)++;
319 ✗ if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
320 ✗ *bx = x * 16 + sx1;
321 ✗ (*by)++;
322 }
323 }
324 ✗ break;
325 ✗ case 5:
326 ✗ while (run-- > 0) {
327 ✗ if (*by < 1 || *by >= avctx->height)
328 ✗ return AVERROR_INVALIDDATA;
329
330 ✗ if (*bx == 0) {
331 ✗ if (*by < 2)
332 ✗ return AVERROR_INVALIDDATA;
333 ✗ z = backstep;
334 } else {
335 ✗ z = 0;
336 }
337
338 ✗ clr = dst[(*by - 1) * linesize + *bx - 1 - z];
339 ✗ dst[*by * linesize + *bx] = clr;
340 ✗ (*bx)++;
341 ✗ if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
342 ✗ *bx = x * 16 + sx1;
343 ✗ (*by)++;
344 }
345 }
346 ✗ break;
347 }
348
349 ✗ if (avctx->bits_per_coded_sample == 16) {
350 ✗ *cx1 = (clr & 0x3F00) >> 2;
351 ✗ *cx = (clr & 0x3FFFFF) >> 16;
352 } else {
353 ✗ *cx1 = (clr & 0xFC00) >> 4;
354 ✗ *cx = (clr & 0xFFFFFF) >> 18;
355 }
356
357 ✗ return 0;
358 }
359
360 #endif /* AVCODEC_SCPR_H */
361