]> git.sesse.net Git - ffmpeg/blob - libavcodec/xxan.c
lavc: AV-prefix all codec capabilities
[ffmpeg] / libavcodec / xxan.c
1 /*
2  * Wing Commander/Xan Video Decoder
3  * Copyright (C) 2011 Konstantin Shishkov
4  * based on work by Mike Melanson
5  *
6  * This file is part of Libav.
7  *
8  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "avcodec.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/mem.h"
26 #include "bytestream.h"
27 #define BITSTREAM_READER_LE
28 #include "get_bits.h"
29 #include "internal.h"
30
31 typedef struct XanContext {
32     AVCodecContext *avctx;
33     AVFrame *pic;
34
35     uint8_t *y_buffer;
36     uint8_t *scratch_buffer;
37     int     buffer_size;
38     GetByteContext gb;
39 } XanContext;
40
41 static av_cold int xan_decode_end(AVCodecContext *avctx)
42 {
43     XanContext *s = avctx->priv_data;
44
45     av_frame_free(&s->pic);
46
47     av_freep(&s->y_buffer);
48     av_freep(&s->scratch_buffer);
49
50     return 0;
51 }
52
53 static av_cold int xan_decode_init(AVCodecContext *avctx)
54 {
55     XanContext *s = avctx->priv_data;
56
57     s->avctx = avctx;
58
59     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
60
61     if (avctx->height < 8) {
62         av_log(avctx, AV_LOG_ERROR, "Invalid frame height: %d.\n", avctx->height);
63         return AVERROR(EINVAL);
64     }
65     if (avctx->width & 1) {
66         av_log(avctx, AV_LOG_ERROR, "Invalid frame width: %d.\n", avctx->width);
67         return AVERROR(EINVAL);
68     }
69
70     s->buffer_size = avctx->width * avctx->height;
71     s->y_buffer = av_malloc(s->buffer_size);
72     if (!s->y_buffer)
73         return AVERROR(ENOMEM);
74     s->scratch_buffer = av_malloc(s->buffer_size + 130);
75     if (!s->scratch_buffer) {
76         av_freep(&s->y_buffer);
77         return AVERROR(ENOMEM);
78     }
79
80     s->pic = av_frame_alloc();
81     if (!s->pic) {
82         xan_decode_end(avctx);
83         return AVERROR(ENOMEM);
84     }
85
86     return 0;
87 }
88
89 static int xan_unpack_luma(XanContext *s,
90                            uint8_t *dst, const int dst_size)
91 {
92     int tree_size, eof;
93     int bits, mask;
94     int tree_root, node;
95     const uint8_t *dst_end = dst + dst_size;
96     GetByteContext tree = s->gb;
97     int start_off = bytestream2_tell(&tree);
98
99     tree_size = bytestream2_get_byte(&s->gb);
100     eof       = bytestream2_get_byte(&s->gb);
101     tree_root = eof + tree_size;
102     bytestream2_skip(&s->gb, tree_size * 2);
103
104     node = tree_root;
105     bits = bytestream2_get_byte(&s->gb);
106     mask = 0x80;
107     for (;;) {
108         int bit = !!(bits & mask);
109         mask >>= 1;
110         bytestream2_seek(&tree, start_off + node*2 + bit - eof * 2, SEEK_SET);
111         node = bytestream2_get_byte(&tree);
112         if (node == eof)
113             break;
114         if (node < eof) {
115             *dst++ = node;
116             if (dst > dst_end)
117                 break;
118             node = tree_root;
119         }
120         if (!mask) {
121             if (bytestream2_get_bytes_left(&s->gb) <= 0)
122                 break;
123             bits = bytestream2_get_byteu(&s->gb);
124             mask = 0x80;
125         }
126     }
127     return dst != dst_end ? AVERROR_INVALIDDATA : 0;
128 }
129
130 /* almost the same as in xan_wc3 decoder */
131 static int xan_unpack(XanContext *s,
132                       uint8_t *dest, const int dest_len)
133 {
134     uint8_t opcode;
135     int size;
136     uint8_t *orig_dest = dest;
137     const uint8_t *dest_end = dest + dest_len;
138
139     while (dest < dest_end) {
140         if (bytestream2_get_bytes_left(&s->gb) <= 0)
141             return AVERROR_INVALIDDATA;
142
143         opcode = bytestream2_get_byteu(&s->gb);
144
145         if (opcode < 0xe0) {
146             int size2, back;
147             if ((opcode & 0x80) == 0) {
148                 size  = opcode & 3;
149                 back  = ((opcode & 0x60) << 3) + bytestream2_get_byte(&s->gb) + 1;
150                 size2 = ((opcode & 0x1c) >> 2) + 3;
151             } else if ((opcode & 0x40) == 0) {
152                 size  = bytestream2_peek_byte(&s->gb) >> 6;
153                 back  = (bytestream2_get_be16(&s->gb) & 0x3fff) + 1;
154                 size2 = (opcode & 0x3f) + 4;
155             } else {
156                 size  = opcode & 3;
157                 back  = ((opcode & 0x10) << 12) + bytestream2_get_be16(&s->gb) + 1;
158                 size2 = ((opcode & 0x0c) <<  6) + bytestream2_get_byte(&s->gb) + 5;
159                 if (size + size2 > dest_end - dest)
160                     break;
161             }
162             if (dest + size + size2 > dest_end ||
163                 dest - orig_dest + size < back)
164                 return AVERROR_INVALIDDATA;
165             bytestream2_get_buffer(&s->gb, dest, size);
166             dest += size;
167             av_memcpy_backptr(dest, back, size2);
168             dest += size2;
169         } else {
170             int finish = opcode >= 0xfc;
171
172             size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
173             if (dest_end - dest < size)
174                 return AVERROR_INVALIDDATA;
175             bytestream2_get_buffer(&s->gb, dest, size);
176             dest += size;
177             if (finish)
178                 break;
179         }
180     }
181     return dest - orig_dest;
182 }
183
184 static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
185 {
186     XanContext *s = avctx->priv_data;
187     uint8_t *U, *V;
188     int val, uval, vval;
189     int i, j;
190     const uint8_t *src, *src_end;
191     const uint8_t *table;
192     int mode, offset, dec_size, table_size;
193
194     if (!chroma_off)
195         return 0;
196     if (chroma_off + 4 >= bytestream2_get_bytes_left(&s->gb)) {
197         av_log(avctx, AV_LOG_ERROR, "Invalid chroma block position\n");
198         return AVERROR_INVALIDDATA;
199     }
200     bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET);
201     mode        = bytestream2_get_le16(&s->gb);
202     table       = s->gb.buffer;
203     table_size  = bytestream2_get_le16(&s->gb);
204     offset      = table_size * 2;
205     table_size += 1;
206
207     if (offset >= bytestream2_get_bytes_left(&s->gb)) {
208         av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
209         return AVERROR_INVALIDDATA;
210     }
211
212     bytestream2_skip(&s->gb, offset);
213     memset(s->scratch_buffer, 0, s->buffer_size);
214     dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
215     if (dec_size < 0) {
216         av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n");
217         return dec_size;
218     }
219
220     U = s->pic->data[1];
221     V = s->pic->data[2];
222     src     = s->scratch_buffer;
223     src_end = src + dec_size;
224     if (mode) {
225         for (j = 0; j < avctx->height >> 1; j++) {
226             for (i = 0; i < avctx->width >> 1; i++) {
227                 val = *src++;
228                 if (val && val < table_size) {
229                     val  = AV_RL16(table + (val << 1));
230                     uval = (val >> 3) & 0xF8;
231                     vval = (val >> 8) & 0xF8;
232                     U[i] = uval | (uval >> 5);
233                     V[i] = vval | (vval >> 5);
234                 }
235                 if (src == src_end)
236                     return 0;
237             }
238             U += s->pic->linesize[1];
239             V += s->pic->linesize[2];
240         }
241         if (avctx->height & 1) {
242             memcpy(U, U - s->pic->linesize[1], avctx->width >> 1);
243             memcpy(V, V - s->pic->linesize[2], avctx->width >> 1);
244         }
245     } else {
246         uint8_t *U2 = U + s->pic->linesize[1];
247         uint8_t *V2 = V + s->pic->linesize[2];
248
249         for (j = 0; j < avctx->height >> 2; j++) {
250             for (i = 0; i < avctx->width >> 1; i += 2) {
251                 val = *src++;
252                 if (val && val < table_size) {
253                     val  = AV_RL16(table + (val << 1));
254                     uval = (val >> 3) & 0xF8;
255                     vval = (val >> 8) & 0xF8;
256                     U[i] = U[i+1] = U2[i] = U2[i+1] = uval | (uval >> 5);
257                     V[i] = V[i+1] = V2[i] = V2[i+1] = vval | (vval >> 5);
258                 }
259             }
260             U  += s->pic->linesize[1] * 2;
261             V  += s->pic->linesize[2] * 2;
262             U2 += s->pic->linesize[1] * 2;
263             V2 += s->pic->linesize[2] * 2;
264         }
265         if (avctx->height & 3) {
266             int lines = ((avctx->height + 1) >> 1) - (avctx->height >> 2) * 2;
267
268             memcpy(U, U - lines * s->pic->linesize[1], lines * s->pic->linesize[1]);
269             memcpy(V, V - lines * s->pic->linesize[2], lines * s->pic->linesize[2]);
270         }
271     }
272
273     return 0;
274 }
275
276 static int xan_decode_frame_type0(AVCodecContext *avctx)
277 {
278     XanContext *s = avctx->priv_data;
279     uint8_t *ybuf, *prev_buf, *src = s->scratch_buffer;
280     unsigned  chroma_off, corr_off;
281     int cur, last;
282     int i, j;
283     int ret;
284
285     chroma_off = bytestream2_get_le32(&s->gb);
286     corr_off   = bytestream2_get_le32(&s->gb);
287
288     if ((ret = xan_decode_chroma(avctx, chroma_off)) != 0)
289         return ret;
290
291     if (corr_off >= (s->gb.buffer_end - s->gb.buffer_start)) {
292         av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n");
293         corr_off = 0;
294     }
295     bytestream2_seek(&s->gb, 12, SEEK_SET);
296     ret = xan_unpack_luma(s, src, s->buffer_size >> 1);
297     if (ret) {
298         av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");
299         return ret;
300     }
301
302     ybuf = s->y_buffer;
303     last = *src++;
304     ybuf[0] = last << 1;
305     for (j = 1; j < avctx->width - 1; j += 2) {
306         cur = (last + *src++) & 0x1F;
307         ybuf[j]   = last + cur;
308         ybuf[j+1] = cur << 1;
309         last = cur;
310     }
311     ybuf[j]  = last << 1;
312     prev_buf = ybuf;
313     ybuf += avctx->width;
314
315     for (i = 1; i < avctx->height; i++) {
316         last = ((prev_buf[0] >> 1) + *src++) & 0x1F;
317         ybuf[0] = last << 1;
318         for (j = 1; j < avctx->width - 1; j += 2) {
319             cur = ((prev_buf[j + 1] >> 1) + *src++) & 0x1F;
320             ybuf[j]   = last + cur;
321             ybuf[j+1] = cur << 1;
322             last = cur;
323         }
324         ybuf[j] = last << 1;
325         prev_buf = ybuf;
326         ybuf += avctx->width;
327     }
328
329     if (corr_off) {
330         int dec_size;
331
332         bytestream2_seek(&s->gb, 8 + corr_off, SEEK_SET);
333         dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size / 2);
334         if (dec_size < 0)
335             dec_size = 0;
336         for (i = 0; i < dec_size; i++)
337             s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F;
338     }
339
340     src  = s->y_buffer;
341     ybuf = s->pic->data[0];
342     for (j = 0; j < avctx->height; j++) {
343         for (i = 0; i < avctx->width; i++)
344             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
345         src  += avctx->width;
346         ybuf += s->pic->linesize[0];
347     }
348
349     return 0;
350 }
351
352 static int xan_decode_frame_type1(AVCodecContext *avctx)
353 {
354     XanContext *s = avctx->priv_data;
355     uint8_t *ybuf, *src = s->scratch_buffer;
356     int cur, last;
357     int i, j;
358     int ret;
359
360     if ((ret = xan_decode_chroma(avctx, bytestream2_get_le32(&s->gb))) != 0)
361         return ret;
362
363     bytestream2_seek(&s->gb, 16, SEEK_SET);
364     ret = xan_unpack_luma(s, src,
365                           s->buffer_size >> 1);
366     if (ret) {
367         av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");
368         return ret;
369     }
370
371     ybuf = s->y_buffer;
372     for (i = 0; i < avctx->height; i++) {
373         last = (ybuf[0] + (*src++ << 1)) & 0x3F;
374         ybuf[0] = last;
375         for (j = 1; j < avctx->width - 1; j += 2) {
376             cur = (ybuf[j + 1] + (*src++ << 1)) & 0x3F;
377             ybuf[j]   = (last + cur) >> 1;
378             ybuf[j+1] = cur;
379             last = cur;
380         }
381         ybuf[j] = last;
382         ybuf += avctx->width;
383     }
384
385     src = s->y_buffer;
386     ybuf = s->pic->data[0];
387     for (j = 0; j < avctx->height; j++) {
388         for (i = 0; i < avctx->width; i++)
389             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
390         src  += avctx->width;
391         ybuf += s->pic->linesize[0];
392     }
393
394     return 0;
395 }
396
397 static int xan_decode_frame(AVCodecContext *avctx,
398                             void *data, int *got_frame,
399                             AVPacket *avpkt)
400 {
401     XanContext *s = avctx->priv_data;
402     int ftype;
403     int ret;
404
405     if ((ret = ff_reget_buffer(avctx, s->pic))) {
406         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
407         return ret;
408     }
409
410     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
411     ftype = bytestream2_get_le32(&s->gb);
412     switch (ftype) {
413     case 0:
414         ret = xan_decode_frame_type0(avctx);
415         break;
416     case 1:
417         ret = xan_decode_frame_type1(avctx);
418         break;
419     default:
420         av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype);
421         return AVERROR_INVALIDDATA;
422     }
423     if (ret)
424         return ret;
425
426     if ((ret = av_frame_ref(data, s->pic)) < 0)
427         return ret;
428
429     *got_frame = 1;
430
431     return avpkt->size;
432 }
433
434 AVCodec ff_xan_wc4_decoder = {
435     .name           = "xan_wc4",
436     .long_name      = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
437     .type           = AVMEDIA_TYPE_VIDEO,
438     .id             = AV_CODEC_ID_XAN_WC4,
439     .priv_data_size = sizeof(XanContext),
440     .init           = xan_decode_init,
441     .close          = xan_decode_end,
442     .decode         = xan_decode_frame,
443     .capabilities   = AV_CODEC_CAP_DR1,
444 };