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