]> git.sesse.net Git - ffmpeg/blob - libavcodec/xxan.c
Merge commit '67bb3a4e285a5871770cbaa2d78bf9024961dd0f'
[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 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 #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         xan_decode_end(avctx);
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                 if (src_end - src < 1)
228                     return 0;
229                 val = *src++;
230                 if (val) {
231                     if (val >= table_size)
232                         return AVERROR_INVALIDDATA;
233                     val  = AV_RL16(table + (val << 1));
234                     uval = (val >> 3) & 0xF8;
235                     vval = (val >> 8) & 0xF8;
236                     U[i] = uval | (uval >> 5);
237                     V[i] = vval | (vval >> 5);
238                 }
239             }
240             U += s->pic->linesize[1];
241             V += s->pic->linesize[2];
242         }
243         if (avctx->height & 1) {
244             memcpy(U, U - s->pic->linesize[1], avctx->width >> 1);
245             memcpy(V, V - s->pic->linesize[2], avctx->width >> 1);
246         }
247     } else {
248         uint8_t *U2 = U + s->pic->linesize[1];
249         uint8_t *V2 = V + s->pic->linesize[2];
250
251         for (j = 0; j < avctx->height >> 2; j++) {
252             for (i = 0; i < avctx->width >> 1; i += 2) {
253                 if (src_end - src < 1)
254                     return 0;
255                 val = *src++;
256                 if (val) {
257                     if (val >= table_size)
258                         return AVERROR_INVALIDDATA;
259                     val  = AV_RL16(table + (val << 1));
260                     uval = (val >> 3) & 0xF8;
261                     vval = (val >> 8) & 0xF8;
262                     U[i] = U[i+1] = U2[i] = U2[i+1] = uval | (uval >> 5);
263                     V[i] = V[i+1] = V2[i] = V2[i+1] = vval | (vval >> 5);
264                 }
265             }
266             U  += s->pic->linesize[1] * 2;
267             V  += s->pic->linesize[2] * 2;
268             U2 += s->pic->linesize[1] * 2;
269             V2 += s->pic->linesize[2] * 2;
270         }
271         if (avctx->height & 3) {
272             int lines = ((avctx->height + 1) >> 1) - (avctx->height >> 2) * 2;
273
274             memcpy(U, U - lines * s->pic->linesize[1], lines * s->pic->linesize[1]);
275             memcpy(V, V - lines * s->pic->linesize[2], lines * s->pic->linesize[2]);
276         }
277     }
278
279     return 0;
280 }
281
282 static int xan_decode_frame_type0(AVCodecContext *avctx)
283 {
284     XanContext *s = avctx->priv_data;
285     uint8_t *ybuf, *prev_buf, *src = s->scratch_buffer;
286     unsigned  chroma_off, corr_off;
287     int cur, last;
288     int i, j;
289     int ret;
290
291     chroma_off = bytestream2_get_le32(&s->gb);
292     corr_off   = bytestream2_get_le32(&s->gb);
293
294     if ((ret = xan_decode_chroma(avctx, chroma_off)) != 0)
295         return ret;
296
297     if (corr_off >= bytestream2_size(&s->gb)) {
298         av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n");
299         corr_off = 0;
300     }
301     bytestream2_seek(&s->gb, 12, SEEK_SET);
302     ret = xan_unpack_luma(s, src, s->buffer_size >> 1);
303     if (ret) {
304         av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");
305         return ret;
306     }
307
308     ybuf = s->y_buffer;
309     last = *src++;
310     ybuf[0] = last << 1;
311     for (j = 1; j < avctx->width - 1; j += 2) {
312         cur = (last + *src++) & 0x1F;
313         ybuf[j]   = last + cur;
314         ybuf[j+1] = cur << 1;
315         last = cur;
316     }
317     ybuf[j]  = last << 1;
318     prev_buf = ybuf;
319     ybuf += avctx->width;
320
321     for (i = 1; i < avctx->height; i++) {
322         last = ((prev_buf[0] >> 1) + *src++) & 0x1F;
323         ybuf[0] = last << 1;
324         for (j = 1; j < avctx->width - 1; j += 2) {
325             cur = ((prev_buf[j + 1] >> 1) + *src++) & 0x1F;
326             ybuf[j]   = last + cur;
327             ybuf[j+1] = cur << 1;
328             last = cur;
329         }
330         ybuf[j] = last << 1;
331         prev_buf = ybuf;
332         ybuf += avctx->width;
333     }
334
335     if (corr_off) {
336         int dec_size;
337
338         bytestream2_seek(&s->gb, 8 + corr_off, SEEK_SET);
339         dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size / 2);
340         if (dec_size < 0)
341             dec_size = 0;
342         else
343             dec_size = FFMIN(dec_size, s->buffer_size/2 - 1);
344
345         for (i = 0; i < dec_size; i++)
346             s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F;
347     }
348
349     src  = s->y_buffer;
350     ybuf = s->pic->data[0];
351     for (j = 0; j < avctx->height; j++) {
352         for (i = 0; i < avctx->width; i++)
353             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
354         src  += avctx->width;
355         ybuf += s->pic->linesize[0];
356     }
357
358     return 0;
359 }
360
361 static int xan_decode_frame_type1(AVCodecContext *avctx)
362 {
363     XanContext *s = avctx->priv_data;
364     uint8_t *ybuf, *src = s->scratch_buffer;
365     int cur, last;
366     int i, j;
367     int ret;
368
369     if ((ret = xan_decode_chroma(avctx, bytestream2_get_le32(&s->gb))) != 0)
370         return ret;
371
372     bytestream2_seek(&s->gb, 16, SEEK_SET);
373     ret = xan_unpack_luma(s, src,
374                           s->buffer_size >> 1);
375     if (ret) {
376         av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");
377         return ret;
378     }
379
380     ybuf = s->y_buffer;
381     for (i = 0; i < avctx->height; i++) {
382         last = (ybuf[0] + (*src++ << 1)) & 0x3F;
383         ybuf[0] = last;
384         for (j = 1; j < avctx->width - 1; j += 2) {
385             cur = (ybuf[j + 1] + (*src++ << 1)) & 0x3F;
386             ybuf[j]   = (last + cur) >> 1;
387             ybuf[j+1] = cur;
388             last = cur;
389         }
390         ybuf[j] = last;
391         ybuf += avctx->width;
392     }
393
394     src = s->y_buffer;
395     ybuf = s->pic->data[0];
396     for (j = 0; j < avctx->height; j++) {
397         for (i = 0; i < avctx->width; i++)
398             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
399         src  += avctx->width;
400         ybuf += s->pic->linesize[0];
401     }
402
403     return 0;
404 }
405
406 static int xan_decode_frame(AVCodecContext *avctx,
407                             void *data, int *got_frame,
408                             AVPacket *avpkt)
409 {
410     XanContext *s = avctx->priv_data;
411     int ftype;
412     int ret;
413
414     if ((ret = ff_reget_buffer(avctx, s->pic)) < 0)
415         return ret;
416
417     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
418     ftype = bytestream2_get_le32(&s->gb);
419     switch (ftype) {
420     case 0:
421         ret = xan_decode_frame_type0(avctx);
422         break;
423     case 1:
424         ret = xan_decode_frame_type1(avctx);
425         break;
426     default:
427         av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype);
428         return AVERROR_INVALIDDATA;
429     }
430     if (ret)
431         return ret;
432
433     if ((ret = av_frame_ref(data, s->pic)) < 0)
434         return ret;
435
436     *got_frame = 1;
437
438     return avpkt->size;
439 }
440
441 AVCodec ff_xan_wc4_decoder = {
442     .name           = "xan_wc4",
443     .long_name      = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
444     .type           = AVMEDIA_TYPE_VIDEO,
445     .id             = AV_CODEC_ID_XAN_WC4,
446     .priv_data_size = sizeof(XanContext),
447     .init           = xan_decode_init,
448     .close          = xan_decode_end,
449     .decode         = xan_decode_frame,
450     .capabilities   = CODEC_CAP_DR1,
451 };