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