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 <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;
53  PixelModel pixel_model[3][4096];
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 
67  PixelModel3 pixel_model3[3][4096];
68  RunModel3 run_model3[6];
72  SxyModel3 sxy_model3[4];
73  MVModel3 mv_model3[2];
74  OpModel3 op_model3[6];
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 */
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
AVFrame * last_frame
Definition: scpr.h:49
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
const char * g
Definition: vf_curves.c:115
uint32_t code1
Definition: scpr.h:38
uint32_t range
Definition: mss3.c:64
uint8_t run
Definition: svq3.c:206
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
int version
Definition: scpr.h:48
uint8_t
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
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2789
uint32_t nby
Definition: scpr.h:61
AVFrame * current_frame
Definition: scpr.h:50
RangeCoder rc
Definition: scpr.h:52
const char * r
Definition: vf_curves.c:114
int cxshift
Definition: scpr.h:65
#define b
Definition: input.c:41
uint32_t nbcount
Definition: scpr.h:62
int width
picture width / height.
Definition: avcodec.h:1738
FillModel3 fill_model3
Definition: scpr.h:71
Definition: scpr3.h:54
Libavcodec external API header.
main external API structure.
Definition: avcodec.h:1565
uint32_t * blocks
Definition: scpr.h:63
uint32_t code
Definition: scpr.h:36
uint32_t cbits
Definition: scpr.h:64
uint32_t total_freq
Definition: scpr.h:44
static int get_freq(RangeCoder *rc, uint32_t total_freq, uint32_t *freq)
Definition: scpr.c:116
GetByteContext gb
Definition: scpr.h:51
int
common internal api header.
Definition: scpr3.h:75
int lookup
RunModel3 range_model3
Definition: scpr.h:69
RunModel3 count_model3
Definition: scpr.h:70