FFmpeg
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 "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;
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 
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 {
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 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 */
RangeCoder::range
uint32_t range
Definition: mss3.c:66
SCPRContext::cxshift
int cxshift
Definition: scpr.h:60
r
const char * r
Definition: vf_curves.c:127
GetByteContext
Definition: bytestream.h:33
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
SxyModel3
Definition: scpr3.h:63
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:72
SCPRContext::cbits
uint32_t cbits
Definition: scpr.h:59
RangeCoder::code1
uint32_t code1
Definition: scpr.h:33
SCPRContext::nby
uint32_t nby
Definition: scpr.h:56
SCPRContext::get_freq
int(* get_freq)(RangeCoder *rc, uint32_t total_freq, uint32_t *freq)
Definition: scpr.h:71
PixelModel
Definition: scpr.h:36
SCPRContext::rc
RangeCoder rc
Definition: scpr.h:47
SCPRContext::current_frame
AVFrame * current_frame
Definition: scpr.h:45
SCPRContext::nbcount
uint32_t nbcount
Definition: scpr.h:57
g
const char * g
Definition: vf_curves.c:128
SCPRContext::gb
GetByteContext gb
Definition: scpr.h:46
FillModel3
Definition: scpr3.h:42
SCPRContext::fill_model
uint32_t fill_model[6]
Definition: scpr.h:53
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:75
SCPRContext::count_model
uint32_t count_model[257]
Definition: scpr.h:52
SCPRContext::mv_model3
MVModel3 mv_model3[2]
Definition: scpr.h:68
SCPRContext::last_frame
AVFrame * last_frame
Definition: scpr.h:44
SCPRContext::version
int version
Definition: scpr.h:43
run
uint8_t run
Definition: svq3.c:204
SCPRContext::pixel_model
PixelModel pixel_model[3][4096]
Definition: scpr.h:48
scpr3.h
PixelModel::freq
uint32_t freq[256]
Definition: scpr.h:37
SCPRContext::run_model3
RunModel3 run_model3[6]
Definition: scpr.h:63
SCPRContext::mv_model
uint32_t mv_model[2][513]
Definition: scpr.h:55
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
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:217
SCPRContext::blocks
uint32_t * blocks
Definition: scpr.h:58
SCPRContext::range_model3
RunModel3 range_model3
Definition: scpr.h:64
OpModel3
Definition: scpr3.h:49
SCPRContext
Definition: scpr.h:42
PixelModel::total_freq
uint32_t total_freq
Definition: scpr.h:39
SCPRContext::nbx
uint32_t nbx
Definition: scpr.h:56
RangeCoder::code
uint32_t code
Definition: scpr.h:31
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1578
SCPRContext::pixel_model3
PixelModel3 pixel_model3[3][4096]
Definition: scpr.h:62
RunModel3
Definition: scpr3.h:56
SCPRContext::count_model3
RunModel3 count_model3
Definition: scpr.h:65
AVCodecContext::height
int height
Definition: avcodec.h:624
avcodec.h
PixelModel::lookup
uint32_t lookup[16]
Definition: scpr.h:38
SCPRContext::op_model
uint32_t op_model[6][7]
Definition: scpr.h:49
SCPRContext::fill_model3
FillModel3 fill_model3
Definition: scpr.h:66
SCPRContext::sxy_model3
SxyModel3 sxy_model3[4]
Definition: scpr.h:67
AVCodecContext
main external API structure.
Definition: avcodec.h:451
SCPRContext::sxy_model
uint32_t sxy_model[4][17]
Definition: scpr.h:54
SCPRContext::range_model
uint32_t range_model[257]
Definition: scpr.h:51
PixelModel3
Definition: scpr3.h:28
SCPRContext::run_model
uint32_t run_model[6][257]
Definition: scpr.h:50
MVModel3
Definition: scpr3.h:70
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:624
bytestream.h
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
RangeCoder
Definition: mss3.c:63
SCPRContext::op_model3
OpModel3 op_model3[6]
Definition: scpr.h:69