Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavcodec / escape130.c
CommitLineData
2ba45a60
DM
1/*
2 * Escape 130 video decoder
3 * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "libavutil/attributes.h"
23#include "libavutil/mem.h"
24#include "avcodec.h"
25#define BITSTREAM_READER_LE
26#include "get_bits.h"
27#include "internal.h"
28
29typedef struct Escape130Context {
30 uint8_t *old_y_avg;
31
32 uint8_t *new_y, *old_y;
33 uint8_t *new_u, *old_u;
34 uint8_t *new_v, *old_v;
35
36 uint8_t *buf1, *buf2;
37 int linesize[3];
38} Escape130Context;
39
40static const uint8_t offset_table[] = { 2, 4, 10, 20 };
41static const int8_t sign_table[64][4] = {
42 { 0, 0, 0, 0 },
43 { -1, 1, 0, 0 },
44 { 1, -1, 0, 0 },
45 { -1, 0, 1, 0 },
46 { -1, 1, 1, 0 },
47 { 0, -1, 1, 0 },
48 { 1, -1, 1, 0 },
49 { -1, -1, 1, 0 },
50 { 1, 0, -1, 0 },
51 { 0, 1, -1, 0 },
52 { 1, 1, -1, 0 },
53 { -1, 1, -1, 0 },
54 { 1, -1, -1, 0 },
55 { -1, 0, 0, 1 },
56 { -1, 1, 0, 1 },
57 { 0, -1, 0, 1 },
58
59 { 0, 0, 0, 0 },
60 { 1, -1, 0, 1 },
61 { -1, -1, 0, 1 },
62 { -1, 0, 1, 1 },
63 { -1, 1, 1, 1 },
64 { 0, -1, 1, 1 },
65 { 1, -1, 1, 1 },
66 { -1, -1, 1, 1 },
67 { 0, 0, -1, 1 },
68 { 1, 0, -1, 1 },
69 { -1, 0, -1, 1 },
70 { 0, 1, -1, 1 },
71 { 1, 1, -1, 1 },
72 { -1, 1, -1, 1 },
73 { 0, -1, -1, 1 },
74 { 1, -1, -1, 1 },
75
76 { 0, 0, 0, 0 },
77 { -1, -1, -1, 1 },
78 { 1, 0, 0, -1 },
79 { 0, 1, 0, -1 },
80 { 1, 1, 0, -1 },
81 { -1, 1, 0, -1 },
82 { 1, -1, 0, -1 },
83 { 0, 0, 1, -1 },
84 { 1, 0, 1, -1 },
85 { -1, 0, 1, -1 },
86 { 0, 1, 1, -1 },
87 { 1, 1, 1, -1 },
88 { -1, 1, 1, -1 },
89 { 0, -1, 1, -1 },
90 { 1, -1, 1, -1 },
91 { -1, -1, 1, -1 },
92
93 { 0, 0, 0, 0 },
94 { 1, 0, -1, -1 },
95 { 0, 1, -1, -1 },
96 { 1, 1, -1, -1 },
97 { -1, 1, -1, -1 },
98 { 1, -1, -1, -1 }
99};
100
101static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
102
103static const int8_t chroma_adjust[2][8] = {
104 { 1, 1, 0, -1, -1, -1, 0, 1 },
105 { 0, 1, 1, 1, 0, -1, -1, -1 }
106};
107
108static const uint8_t chroma_vals[] = {
109 20, 28, 36, 44, 52, 60, 68, 76,
110 84, 92, 100, 106, 112, 116, 120, 124,
111 128, 132, 136, 140, 144, 150, 156, 164,
112 172, 180, 188, 196, 204, 212, 220, 228
113};
114
115static av_cold int escape130_decode_init(AVCodecContext *avctx)
116{
117 Escape130Context *s = avctx->priv_data;
118 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
119
120 if ((avctx->width & 1) || (avctx->height & 1)) {
121 av_log(avctx, AV_LOG_ERROR,
122 "Dimensions should be a multiple of two.\n");
123 return AVERROR_INVALIDDATA;
124 }
125
126 s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
127 s->buf1 = av_malloc(avctx->width * avctx->height * 3 / 2);
128 s->buf2 = av_malloc(avctx->width * avctx->height * 3 / 2);
129 if (!s->old_y_avg || !s->buf1 || !s->buf2) {
130 av_freep(&s->old_y_avg);
131 av_freep(&s->buf1);
132 av_freep(&s->buf2);
133 av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
134 return AVERROR(ENOMEM);
135 }
136
137 s->linesize[0] = avctx->width;
138 s->linesize[1] =
139 s->linesize[2] = avctx->width / 2;
140
141 s->new_y = s->buf1;
142 s->new_u = s->new_y + avctx->width * avctx->height;
143 s->new_v = s->new_u + avctx->width * avctx->height / 4;
144 s->old_y = s->buf2;
145 s->old_u = s->old_y + avctx->width * avctx->height;
146 s->old_v = s->old_u + avctx->width * avctx->height / 4;
147 memset(s->old_y, 0, avctx->width * avctx->height);
148 memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
149 memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
150
151 return 0;
152}
153
154static av_cold int escape130_decode_close(AVCodecContext *avctx)
155{
156 Escape130Context *s = avctx->priv_data;
157
158 av_freep(&s->old_y_avg);
159 av_freep(&s->buf1);
160 av_freep(&s->buf2);
161
162 return 0;
163}
164
165static int decode_skip_count(GetBitContext* gb)
166{
167 int value;
168
169 if (get_bits_left(gb) < 1+3)
170 return -1;
171
172 value = get_bits1(gb);
173 if (value)
174 return 0;
175
176 value = get_bits(gb, 3);
177 if (value)
178 return value;
179
180 value = get_bits(gb, 8);
181 if (value)
182 return value + 7;
183
184 value = get_bits(gb, 15);
185 if (value)
186 return value + 262;
187
188 return -1;
189}
190
191static int escape130_decode_frame(AVCodecContext *avctx, void *data,
192 int *got_frame, AVPacket *avpkt)
193{
194 int buf_size = avpkt->size;
195 Escape130Context *s = avctx->priv_data;
196 AVFrame *pic = data;
197 GetBitContext gb;
198 int ret;
199
200 uint8_t *old_y, *old_cb, *old_cr,
201 *new_y, *new_cb, *new_cr;
202 uint8_t *dstY, *dstU, *dstV;
203 unsigned old_y_stride, old_cb_stride, old_cr_stride,
204 new_y_stride, new_cb_stride, new_cr_stride;
205 unsigned total_blocks = avctx->width * avctx->height / 4,
206 block_index, block_x = 0;
207 unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
208 int skip = -1, y_avg = 0, i, j;
209 uint8_t *ya = s->old_y_avg;
210
211 // first 16 bytes are header; no useful information in here
212 if (buf_size <= 16) {
213 av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
214 return AVERROR_INVALIDDATA;
215 }
216
217 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
218 return ret;
219
220 if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
221 return ret;
222 skip_bits_long(&gb, 16 * 8);
223
224 new_y = s->new_y;
225 new_cb = s->new_u;
226 new_cr = s->new_v;
227 new_y_stride = s->linesize[0];
228 new_cb_stride = s->linesize[1];
229 new_cr_stride = s->linesize[2];
230 old_y = s->old_y;
231 old_cb = s->old_u;
232 old_cr = s->old_v;
233 old_y_stride = s->linesize[0];
234 old_cb_stride = s->linesize[1];
235 old_cr_stride = s->linesize[2];
236
237 for (block_index = 0; block_index < total_blocks; block_index++) {
238 // Note that this call will make us skip the rest of the blocks
239 // if the frame ends prematurely.
240 if (skip == -1)
241 skip = decode_skip_count(&gb);
242 if (skip == -1) {
243 av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
244 return AVERROR_INVALIDDATA;
245 }
246
247 if (skip) {
248 y[0] = old_y[0];
249 y[1] = old_y[1];
250 y[2] = old_y[old_y_stride];
251 y[3] = old_y[old_y_stride + 1];
252 y_avg = ya[0];
253 cb = old_cb[0];
254 cr = old_cr[0];
255 } else {
256 if (get_bits1(&gb)) {
257 unsigned sign_selector = get_bits(&gb, 6);
258 unsigned difference_selector = get_bits(&gb, 2);
259 y_avg = 2 * get_bits(&gb, 5);
260 for (i = 0; i < 4; i++) {
261 y[i] = av_clip(y_avg + offset_table[difference_selector] *
262 sign_table[sign_selector][i], 0, 63);
263 }
264 } else if (get_bits1(&gb)) {
265 if (get_bits1(&gb)) {
266 y_avg = get_bits(&gb, 6);
267 } else {
268 unsigned adjust_index = get_bits(&gb, 3);
269 y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
270 }
271 for (i = 0; i < 4; i++)
272 y[i] = y_avg;
273 }
274
275 if (get_bits1(&gb)) {
276 if (get_bits1(&gb)) {
277 cb = get_bits(&gb, 5);
278 cr = get_bits(&gb, 5);
279 } else {
280 unsigned adjust_index = get_bits(&gb, 3);
281 cb = (cb + chroma_adjust[0][adjust_index]) & 31;
282 cr = (cr + chroma_adjust[1][adjust_index]) & 31;
283 }
284 }
285 }
286 *ya++ = y_avg;
287
288 new_y[0] = y[0];
289 new_y[1] = y[1];
290 new_y[new_y_stride] = y[2];
291 new_y[new_y_stride + 1] = y[3];
292 *new_cb = cb;
293 *new_cr = cr;
294
295 old_y += 2;
296 old_cb++;
297 old_cr++;
298 new_y += 2;
299 new_cb++;
300 new_cr++;
301 block_x++;
302 if (block_x * 2 == avctx->width) {
303 block_x = 0;
304 old_y += old_y_stride * 2 - avctx->width;
305 old_cb += old_cb_stride - avctx->width / 2;
306 old_cr += old_cr_stride - avctx->width / 2;
307 new_y += new_y_stride * 2 - avctx->width;
308 new_cb += new_cb_stride - avctx->width / 2;
309 new_cr += new_cr_stride - avctx->width / 2;
310 }
311
312 skip--;
313 }
314
315 new_y = s->new_y;
316 new_cb = s->new_u;
317 new_cr = s->new_v;
318 dstY = pic->data[0];
319 dstU = pic->data[1];
320 dstV = pic->data[2];
321 for (j = 0; j < avctx->height; j++) {
322 for (i = 0; i < avctx->width; i++)
323 dstY[i] = new_y[i] << 2;
324 dstY += pic->linesize[0];
325 new_y += new_y_stride;
326 }
327 for (j = 0; j < avctx->height / 2; j++) {
328 for (i = 0; i < avctx->width / 2; i++) {
329 dstU[i] = chroma_vals[new_cb[i]];
330 dstV[i] = chroma_vals[new_cr[i]];
331 }
332 dstU += pic->linesize[1];
333 dstV += pic->linesize[2];
334 new_cb += new_cb_stride;
335 new_cr += new_cr_stride;
336 }
337
338 av_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
339 buf_size, get_bits_count(&gb) >> 3);
340
341 FFSWAP(uint8_t*, s->old_y, s->new_y);
342 FFSWAP(uint8_t*, s->old_u, s->new_u);
343 FFSWAP(uint8_t*, s->old_v, s->new_v);
344
345 *got_frame = 1;
346
347 return buf_size;
348}
349
350AVCodec ff_escape130_decoder = {
351 .name = "escape130",
352 .long_name = NULL_IF_CONFIG_SMALL("Escape 130"),
353 .type = AVMEDIA_TYPE_VIDEO,
354 .id = AV_CODEC_ID_ESCAPE130,
355 .priv_data_size = sizeof(Escape130Context),
356 .init = escape130_decode_init,
357 .close = escape130_decode_close,
358 .decode = escape130_decode_frame,
359 .capabilities = CODEC_CAP_DR1,
360};