FFmpeg  4.3
scpr.h
Go to the documentation of this file.
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 <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "avcodec.h"
31 #include "bytestream.h"
32 #include "internal.h"
33 #include "scpr3.h"
34 
35 typedef struct RangeCoder {
36  uint32_t code;
37  uint32_t range;
38  uint32_t code1;
39 } RangeCoder;
40 
41 typedef struct PixelModel {
42  uint32_t freq[256];
43  uint32_t lookup[16];
44  uint32_t total_freq;
45 } PixelModel;
46 
47 typedef struct SCPRContext {
48  int version;
54  uint32_t op_model[6][7];
55  uint32_t run_model[6][257];
56  uint32_t range_model[257];
57  uint32_t count_model[257];
58  uint32_t fill_model[6];
59  uint32_t sxy_model[4][17];
60  uint32_t mv_model[2][513];
61  uint32_t nbx, nby;
62  uint32_t nbcount;
63  uint32_t *blocks;
64  uint32_t cbits;
65  int cxshift;
66 
75 
76  int (*get_freq)(RangeCoder *rc, uint32_t total_freq, uint32_t *freq);
77  int (*decode)(GetByteContext *gb, RangeCoder *rc, uint32_t cumFreq, uint32_t freq, uint32_t total_freq);
78 } SCPRContext;
79 
80 static int decode_run_i(AVCodecContext *avctx, uint32_t ptype, int run,
81  int *px, int *py, uint32_t clr, uint32_t *dst,
82  int linesize, uint32_t *plx, uint32_t *ply,
83  uint32_t backstep, int off, int *cx, int *cx1)
84 {
85  uint32_t r, g, b;
86  int z;
87  int x = *px,
88  y = *py;
89  uint32_t lx = *plx,
90  ly = *ply;
91 
92  if (y >= avctx->height)
93  return AVERROR_INVALIDDATA;
94 
95  switch (ptype) {
96  case 0:
97  while (run-- > 0) {
98  dst[y * linesize + x] = clr;
99  lx = x;
100  ly = y;
101  (x)++;
102  if (x >= avctx->width) {
103  x = 0;
104  (y)++;
105  if (y >= avctx->height && run)
106  return AVERROR_INVALIDDATA;
107  }
108  }
109  break;
110  case 1:
111  while (run-- > 0) {
112  dst[y * linesize + x] = dst[ly * linesize + lx];
113  lx = x;
114  ly = y;
115  (x)++;
116  if (x >= avctx->width) {
117  x = 0;
118  (y)++;
119  if (y >= avctx->height && run)
120  return AVERROR_INVALIDDATA;
121  }
122  }
123  clr = dst[ly * linesize + lx];
124  break;
125  case 2:
126  if (y < 1)
127  return AVERROR_INVALIDDATA;
128 
129  while (run-- > 0) {
130  clr = dst[y * linesize + x + off + 1];
131  dst[y * linesize + x] = clr;
132  lx = x;
133  ly = y;
134  (x)++;
135  if (x >= avctx->width) {
136  x = 0;
137  (y)++;
138  if (y >= avctx->height && run)
139  return AVERROR_INVALIDDATA;
140  }
141  }
142  break;
143  case 4:
144  if (y < 1 || (y == 1 && x == 0))
145  return AVERROR_INVALIDDATA;
146 
147  while (run-- > 0) {
148  uint8_t *odst = (uint8_t *)dst;
149  int off1 = (ly * linesize + lx) * 4;
150  int off2 = ((y * linesize + x) + off) * 4;
151 
152  if (x == 0) {
153  z = backstep * 4;
154  } else {
155  z = 0;
156  }
157 
158  r = odst[off1] +
159  odst[off2 + 4] -
160  odst[off2 - z ];
161  g = odst[off1 + 1] +
162  odst[off2 + 5] -
163  odst[off2 - z + 1];
164  b = odst[off1 + 2] +
165  odst[off2 + 6] -
166  odst[off2 - z + 2];
167  clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
168  dst[y * linesize + x] = clr;
169  lx = x;
170  ly = y;
171  (x)++;
172  if (x >= avctx->width) {
173  x = 0;
174  (y)++;
175  if (y >= avctx->height && run)
176  return AVERROR_INVALIDDATA;
177  }
178  }
179  break;
180  case 5:
181  if (y < 1 || (y == 1 && x == 0))
182  return AVERROR_INVALIDDATA;
183 
184  while (run-- > 0) {
185  if (x == 0) {
186  z = backstep;
187  } else {
188  z = 0;
189  }
190 
191  clr = dst[y * linesize + x + off - z];
192  dst[y * linesize + x] = clr;
193  lx = x;
194  ly = y;
195  (x)++;
196  if (x >= avctx->width) {
197  x = 0;
198  (y)++;
199  if (y >= avctx->height && run)
200  return AVERROR_INVALIDDATA;
201  }
202  }
203  break;
204  }
205 
206  *px = x;
207  *py = y;
208  *plx= lx;
209  *ply= ly;
210 
211  if (avctx->bits_per_coded_sample == 16) {
212  *cx1 = (clr & 0x3F00) >> 2;
213  *cx = (clr & 0x3FFFFF) >> 16;
214  } else {
215  *cx1 = (clr & 0xFC00) >> 4;
216  *cx = (clr & 0xFFFFFF) >> 18;
217  }
218 
219  return 0;
220 }
221 
222 static int decode_run_p(AVCodecContext *avctx, uint32_t ptype, int run,
223  int x, int y, uint32_t clr,
224  uint32_t *dst, uint32_t *prev,
225  int linesize, int plinesize,
226  uint32_t *bx, uint32_t *by,
227  uint32_t backstep, int sx1, int sx2,
228  int *cx, int *cx1)
229 {
230  uint32_t r, g, b;
231  int z;
232 
233  switch (ptype) {
234  case 0:
235  while (run-- > 0) {
236  if (*by >= avctx->height)
237  return AVERROR_INVALIDDATA;
238 
239  dst[*by * linesize + *bx] = clr;
240  (*bx)++;
241  if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
242  *bx = x * 16 + sx1;
243  (*by)++;
244  }
245  }
246  break;
247  case 1:
248  while (run-- > 0) {
249  if (*bx == 0) {
250  if (*by < 1)
251  return AVERROR_INVALIDDATA;
252  z = backstep;
253  } else {
254  z = 0;
255  }
256 
257  if (*by >= avctx->height)
258  return AVERROR_INVALIDDATA;
259 
260  clr = dst[*by * linesize + *bx - 1 - z];
261  dst[*by * linesize + *bx] = clr;
262  (*bx)++;
263  if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
264  *bx = x * 16 + sx1;
265  (*by)++;
266  }
267  }
268  break;
269  case 2:
270  while (run-- > 0) {
271  if (*by < 1 || *by >= avctx->height)
272  return AVERROR_INVALIDDATA;
273 
274  clr = dst[(*by - 1) * linesize + *bx];
275  dst[*by * linesize + *bx] = clr;
276  (*bx)++;
277  if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
278  *bx = x * 16 + sx1;
279  (*by)++;
280  }
281  }
282  break;
283  case 3:
284  while (run-- > 0) {
285  if (*by >= avctx->height)
286  return AVERROR_INVALIDDATA;
287 
288  clr = prev[*by * plinesize + *bx];
289  dst[*by * linesize + *bx] = clr;
290  (*bx)++;
291  if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
292  *bx = x * 16 + sx1;
293  (*by)++;
294  }
295  }
296  break;
297  case 4:
298  while (run-- > 0) {
299  uint8_t *odst = (uint8_t *)dst;
300 
301  if (*by < 1 || *by >= avctx->height)
302  return AVERROR_INVALIDDATA;
303 
304  if (*bx == 0) {
305  if (*by < 2)
306  return AVERROR_INVALIDDATA;
307  z = backstep;
308  } else {
309  z = 0;
310  }
311 
312  r = odst[((*by - 1) * linesize + *bx) * 4] +
313  odst[(*by * linesize + *bx - 1 - z) * 4] -
314  odst[((*by - 1) * linesize + *bx - 1 - z) * 4];
315  g = odst[((*by - 1) * linesize + *bx) * 4 + 1] +
316  odst[(*by * linesize + *bx - 1 - z) * 4 + 1] -
317  odst[((*by - 1) * linesize + *bx - 1 - z) * 4 + 1];
318  b = odst[((*by - 1) * linesize + *bx) * 4 + 2] +
319  odst[(*by * linesize + *bx - 1 - z) * 4 + 2] -
320  odst[((*by - 1) * linesize + *bx - 1 - z) * 4 + 2];
321  clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
322  dst[*by * linesize + *bx] = clr;
323  (*bx)++;
324  if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
325  *bx = x * 16 + sx1;
326  (*by)++;
327  }
328  }
329  break;
330  case 5:
331  while (run-- > 0) {
332  if (*by < 1 || *by >= avctx->height)
333  return AVERROR_INVALIDDATA;
334 
335  if (*bx == 0) {
336  if (*by < 2)
337  return AVERROR_INVALIDDATA;
338  z = backstep;
339  } else {
340  z = 0;
341  }
342 
343  clr = dst[(*by - 1) * linesize + *bx - 1 - z];
344  dst[*by * linesize + *bx] = clr;
345  (*bx)++;
346  if (*bx >= x * 16 + sx2 || *bx >= avctx->width) {
347  *bx = x * 16 + sx1;
348  (*by)++;
349  }
350  }
351  break;
352  }
353 
354  if (avctx->bits_per_coded_sample == 16) {
355  *cx1 = (clr & 0x3F00) >> 2;
356  *cx = (clr & 0x3FFFFF) >> 16;
357  } else {
358  *cx1 = (clr & 0xFC00) >> 4;
359  *cx = (clr & 0xFFFFFF) >> 18;
360  }
361 
362  return 0;
363 }
364 
365 #endif /* AVCODEC_SCPR_H */
RangeCoder::range
uint32_t range
Definition: mss3.c:64
SCPRContext::cxshift
int cxshift
Definition: scpr.h:65
GetByteContext
Definition: bytestream.h:33
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
SxyModel3
Definition: scpr3.h:68
internal.h
b
#define b
Definition: input.c:41
SCPRContext::decode
int(* decode)(GetByteContext *gb, RangeCoder *rc, uint32_t cumFreq, uint32_t freq, uint32_t total_freq)
Definition: scpr.h:77
SCPRContext::cbits
uint32_t cbits
Definition: scpr.h:64
RangeCoder::code1
uint32_t code1
Definition: scpr.h:38
SCPRContext::nby
uint32_t nby
Definition: scpr.h:61
SCPRContext::get_freq
int(* get_freq)(RangeCoder *rc, uint32_t total_freq, uint32_t *freq)
Definition: scpr.h:76
x
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo x
Definition: fate.txt:150
PixelModel
Definition: scpr.h:41
SCPRContext::rc
RangeCoder rc
Definition: scpr.h:52
SCPRContext::current_frame
AVFrame * current_frame
Definition: scpr.h:50
SCPRContext::nbcount
uint32_t nbcount
Definition: scpr.h:62
g
const char * g
Definition: vf_curves.c:115
SCPRContext::gb
GetByteContext gb
Definition: scpr.h:51
FillModel3
Definition: scpr3.h:47
SCPRContext::fill_model
uint32_t fill_model[6]
Definition: scpr.h:58
decode_run_i
static int decode_run_i(AVCodecContext *avctx, uint32_t ptype, int run, int *px, int *py, uint32_t clr, uint32_t *dst, int linesize, uint32_t *plx, uint32_t *ply, uint32_t backstep, int off, int *cx, int *cx1)
Definition: scpr.h:80
SCPRContext::count_model
uint32_t count_model[257]
Definition: scpr.h:57
SCPRContext::mv_model3
MVModel3 mv_model3[2]
Definition: scpr.h:73
SCPRContext::last_frame
AVFrame * last_frame
Definition: scpr.h:49
SCPRContext::version
int version
Definition: scpr.h:48
run
uint8_t run
Definition: svq3.c:208
SCPRContext::pixel_model
PixelModel pixel_model[3][4096]
Definition: scpr.h:53
scpr3.h
PixelModel::freq
uint32_t freq[256]
Definition: scpr.h:42
SCPRContext::run_model3
RunModel3 run_model3[6]
Definition: scpr.h:68
SCPRContext::mv_model
uint32_t mv_model[2][513]
Definition: scpr.h:60
decode_run_p
static int decode_run_p(AVCodecContext *avctx, uint32_t ptype, int run, int x, int y, uint32_t clr, uint32_t *dst, uint32_t *prev, int linesize, int plinesize, uint32_t *bx, uint32_t *by, uint32_t backstep, int sx1, int sx2, int *cx, int *cx1)
Definition: scpr.h:222
SCPRContext::blocks
uint32_t * blocks
Definition: scpr.h:63
SCPRContext::range_model3
RunModel3 range_model3
Definition: scpr.h:69
OpModel3
Definition: scpr3.h:54
SCPRContext
Definition: scpr.h:47
PixelModel::total_freq
uint32_t total_freq
Definition: scpr.h:44
r
#define r
Definition: input.c:40
SCPRContext::nbx
uint32_t nbx
Definition: scpr.h:61
RangeCoder::code
uint32_t code
Definition: scpr.h:36
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1750
SCPRContext::pixel_model3
PixelModel3 pixel_model3[3][4096]
Definition: scpr.h:67
RunModel3
Definition: scpr3.h:61
uint8_t
uint8_t
Definition: audio_convert.c:194
SCPRContext::count_model3
RunModel3 count_model3
Definition: scpr.h:70
AVCodecContext::height
int height
Definition: avcodec.h:699
avcodec.h
PixelModel::lookup
uint32_t lookup[16]
Definition: scpr.h:43
SCPRContext::op_model
uint32_t op_model[6][7]
Definition: scpr.h:54
SCPRContext::fill_model3
FillModel3 fill_model3
Definition: scpr.h:71
SCPRContext::sxy_model3
SxyModel3 sxy_model3[4]
Definition: scpr.h:72
AVCodecContext
main external API structure.
Definition: avcodec.h:526
SCPRContext::sxy_model
uint32_t sxy_model[4][17]
Definition: scpr.h:59
SCPRContext::range_model
uint32_t range_model[257]
Definition: scpr.h:56
PixelModel3
Definition: scpr3.h:33
SCPRContext::run_model
uint32_t run_model[6][257]
Definition: scpr.h:55
MVModel3
Definition: scpr3.h:75
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:699
bytestream.h
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
RangeCoder
Definition: mss3.c:61
int
int
Definition: ffmpeg_filter.c:192
SCPRContext::op_model3
OpModel3 op_model3[6]
Definition: scpr.h:74