OSDN Git Service

lavc: remove the FF_API_AUDIO_OLD cruft.
[coroid/libav_saccubus.git] / 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 "bytestream.h"
26 #define ALT_BITSTREAM_READER_LE
27 #include "get_bits.h"
28 // for av_memcpy_backptr
29 #include "libavutil/lzo.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 } XanContext;
39
40 static av_cold int xan_decode_init(AVCodecContext *avctx)
41 {
42     XanContext *s = avctx->priv_data;
43
44     s->avctx = avctx;
45
46     avctx->pix_fmt = PIX_FMT_YUV420P;
47
48     s->buffer_size = avctx->width * avctx->height;
49     s->y_buffer = av_malloc(s->buffer_size);
50     if (!s->y_buffer)
51         return AVERROR(ENOMEM);
52     s->scratch_buffer = av_malloc(s->buffer_size + 130);
53     if (!s->scratch_buffer) {
54         av_freep(&s->y_buffer);
55         return AVERROR(ENOMEM);
56     }
57
58     return 0;
59 }
60
61 static int xan_unpack_luma(const uint8_t *src, const int src_size,
62                            uint8_t *dst, const int dst_size)
63 {
64    int tree_size, eof;
65    const uint8_t *tree;
66    int bits, mask;
67    int tree_root, node;
68    const uint8_t *dst_end = dst + dst_size;
69    const uint8_t *src_end = src + src_size;
70
71    tree_size = *src++;
72    eof       = *src++;
73    tree      = src - eof * 2 - 2;
74    tree_root = eof + tree_size;
75    src += tree_size * 2;
76
77    node = tree_root;
78    bits = *src++;
79    mask = 0x80;
80    for (;;) {
81        int bit = !!(bits & mask);
82        mask >>= 1;
83        node = tree[node*2 + bit];
84        if (node == eof)
85            break;
86        if (node < eof) {
87            *dst++ = node;
88            if (dst > dst_end)
89                break;
90            node = tree_root;
91        }
92        if (!mask) {
93            bits = *src++;
94            if (src > src_end)
95                break;
96            mask = 0x80;
97        }
98    }
99    return dst != dst_end;
100 }
101
102 /* almost the same as in xan_wc3 decoder */
103 static int xan_unpack(uint8_t *dest, const int dest_len,
104                       const uint8_t *src, const int src_len)
105 {
106     uint8_t opcode;
107     int size;
108     uint8_t *orig_dest = dest;
109     const uint8_t *src_end = src + src_len;
110     const uint8_t *dest_end = dest + dest_len;
111
112     while (dest < dest_end) {
113         opcode = *src++;
114
115         if (opcode < 0xe0) {
116             int size2, back;
117             if ((opcode & 0x80) == 0) {
118                 size  = opcode & 3;
119                 back  = ((opcode & 0x60) << 3) + *src++ + 1;
120                 size2 = ((opcode & 0x1c) >> 2) + 3;
121             } else if ((opcode & 0x40) == 0) {
122                 size  = *src >> 6;
123                 back  = (bytestream_get_be16(&src) & 0x3fff) + 1;
124                 size2 = (opcode & 0x3f) + 4;
125             } else {
126                 size  = opcode & 3;
127                 back  = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1;
128                 size2 = ((opcode & 0x0c) <<  6) + *src++ + 5;
129                 if (size + size2 > dest_end - dest)
130                     break;
131             }
132             if (src + size > src_end || dest + size + size2 > dest_end)
133                 return -1;
134             bytestream_get_buffer(&src, dest, size);
135             dest += size;
136             av_memcpy_backptr(dest, back, size2);
137             dest += size2;
138         } else {
139             int finish = opcode >= 0xfc;
140
141             size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
142             if (src + size > src_end || dest + size > dest_end)
143                 return -1;
144             bytestream_get_buffer(&src, dest, size);
145             dest += size;
146             if (finish)
147                 break;
148         }
149     }
150     return dest - orig_dest;
151 }
152
153 static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt)
154 {
155     const uint8_t *buf = avpkt->data;
156     XanContext *s = avctx->priv_data;
157     uint8_t *U, *V;
158     unsigned chroma_off;
159     int val, uval, vval;
160     int i, j;
161     const uint8_t *src, *src_end;
162     const uint8_t *table;
163     int mode, offset, dec_size;
164
165     chroma_off = AV_RL32(buf + 4);
166     if (!chroma_off)
167         return 0;
168     if (chroma_off + 10 >= avpkt->size) {
169         av_log(avctx, AV_LOG_ERROR, "Invalid chroma block position\n");
170         return -1;
171     }
172     src    = avpkt->data + 4 + chroma_off;
173     table  = src + 2;
174     mode   = bytestream_get_le16(&src);
175     offset = bytestream_get_le16(&src) * 2;
176
177     if (src - avpkt->data >= avpkt->size - offset) {
178         av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
179         return -1;
180     }
181
182     memset(s->scratch_buffer, 0, s->buffer_size);
183     dec_size = xan_unpack(s->scratch_buffer, s->buffer_size, src + offset,
184                           avpkt->size - offset - (src - avpkt->data));
185     if (dec_size < 0) {
186         av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n");
187         return -1;
188     }
189
190     U = s->pic.data[1];
191     V = s->pic.data[2];
192     src     = s->scratch_buffer;
193     src_end = src + dec_size;
194     if (mode) {
195         for (j = 0; j < avctx->height >> 1; j++) {
196             for (i = 0; i < avctx->width >> 1; i++) {
197                 val = *src++;
198                 if (val) {
199                     val  = AV_RL16(table + (val << 1));
200                     uval = (val >> 3) & 0xF8;
201                     vval = (val >> 8) & 0xF8;
202                     U[i] = uval | (uval >> 5);
203                     V[i] = vval | (vval >> 5);
204                 }
205                 if (src == src_end)
206                     return 0;
207             }
208             U += s->pic.linesize[1];
209             V += s->pic.linesize[2];
210         }
211     } else {
212         uint8_t *U2 = U + s->pic.linesize[1];
213         uint8_t *V2 = V + s->pic.linesize[2];
214
215         for (j = 0; j < avctx->height >> 2; j++) {
216             for (i = 0; i < avctx->width >> 1; i += 2) {
217                 val = *src++;
218                 if (val) {
219                     val  = AV_RL16(table + (val << 1));
220                     uval = (val >> 3) & 0xF8;
221                     vval = (val >> 8) & 0xF8;
222                     U[i] = U[i+1] = U2[i] = U2[i+1] = uval | (uval >> 5);
223                     V[i] = V[i+1] = V2[i] = V2[i+1] = vval | (vval >> 5);
224                 }
225             }
226             U  += s->pic.linesize[1] * 2;
227             V  += s->pic.linesize[2] * 2;
228             U2 += s->pic.linesize[1] * 2;
229             V2 += s->pic.linesize[2] * 2;
230         }
231     }
232
233     return 0;
234 }
235
236 static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt)
237 {
238     const uint8_t *buf = avpkt->data;
239     XanContext *s = avctx->priv_data;
240     uint8_t *ybuf, *prev_buf, *src = s->scratch_buffer;
241     unsigned  chroma_off, corr_off;
242     int cur, last, size;
243     int i, j;
244     int ret;
245
246     corr_off   = AV_RL32(buf + 8);
247     chroma_off = AV_RL32(buf + 4);
248
249     if ((ret = xan_decode_chroma(avctx, avpkt)) != 0)
250         return ret;
251
252     size = avpkt->size - 4;
253     if (corr_off >= avpkt->size) {
254         av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n");
255         corr_off = 0;
256     }
257     if (corr_off)
258         size = corr_off;
259     if (chroma_off)
260         size = FFMIN(size, chroma_off);
261     ret = xan_unpack_luma(buf + 12, size, src, s->buffer_size >> 1);
262     if (ret) {
263         av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");
264         return ret;
265     }
266
267     ybuf = s->y_buffer;
268     last = *src++;
269     ybuf[0] = last << 1;
270     for (j = 1; j < avctx->width - 1; j += 2) {
271         cur = (last + *src++) & 0x1F;
272         ybuf[j]   = last + cur;
273         ybuf[j+1] = cur << 1;
274         last = cur;
275     }
276     ybuf[j]  = last << 1;
277     prev_buf = ybuf;
278     ybuf += avctx->width;
279
280     for (i = 1; i < avctx->height; i++) {
281         last = ((prev_buf[0] >> 1) + *src++) & 0x1F;
282         ybuf[0] = last << 1;
283         for (j = 1; j < avctx->width - 1; j += 2) {
284             cur = ((prev_buf[j + 1] >> 1) + *src++) & 0x1F;
285             ybuf[j]   = last + cur;
286             ybuf[j+1] = cur << 1;
287             last = cur;
288         }
289         ybuf[j] = last << 1;
290         prev_buf = ybuf;
291         ybuf += avctx->width;
292     }
293
294     if (corr_off) {
295         int corr_end, dec_size;
296
297         corr_end = avpkt->size;
298         if (chroma_off > corr_off)
299             corr_end = chroma_off;
300         dec_size = xan_unpack(s->scratch_buffer, s->buffer_size,
301                               avpkt->data + 8 + corr_off,
302                               corr_end - corr_off);
303         if (dec_size < 0)
304             dec_size = 0;
305         for (i = 0; i < dec_size; i++)
306             s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F;
307     }
308
309     src  = s->y_buffer;
310     ybuf = s->pic.data[0];
311     for (j = 0; j < avctx->height; j++) {
312         for (i = 0; i < avctx->width; i++)
313             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
314         src  += avctx->width;
315         ybuf += s->pic.linesize[0];
316     }
317
318     return 0;
319 }
320
321 static int xan_decode_frame_type1(AVCodecContext *avctx, AVPacket *avpkt)
322 {
323     const uint8_t *buf = avpkt->data;
324     XanContext *s = avctx->priv_data;
325     uint8_t *ybuf, *src = s->scratch_buffer;
326     int cur, last;
327     int i, j;
328     int ret;
329
330     if ((ret = xan_decode_chroma(avctx, avpkt)) != 0)
331         return ret;
332
333     ret = xan_unpack_luma(buf + 16, avpkt->size - 16, src,
334                           s->buffer_size >> 1);
335     if (ret) {
336         av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");
337         return ret;
338     }
339
340     ybuf = s->y_buffer;
341     for (i = 0; i < avctx->height; i++) {
342         last = (ybuf[0] + (*src++ << 1)) & 0x3F;
343         ybuf[0] = last;
344         for (j = 1; j < avctx->width - 1; j += 2) {
345             cur = (ybuf[j + 1] + (*src++ << 1)) & 0x3F;
346             ybuf[j]   = (last + cur) >> 1;
347             ybuf[j+1] = cur;
348             last = cur;
349         }
350         ybuf[j] = last;
351         ybuf += avctx->width;
352     }
353
354     src = s->y_buffer;
355     ybuf = s->pic.data[0];
356     for (j = 0; j < avctx->height; j++) {
357         for (i = 0; i < avctx->width; i++)
358             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
359         src  += avctx->width;
360         ybuf += s->pic.linesize[0];
361     }
362
363     return 0;
364 }
365
366 static int xan_decode_frame(AVCodecContext *avctx,
367                             void *data, int *data_size,
368                             AVPacket *avpkt)
369 {
370     XanContext *s = avctx->priv_data;
371     int ftype;
372     int ret;
373
374     s->pic.reference = 1;
375     s->pic.buffer_hints = FF_BUFFER_HINTS_VALID |
376                           FF_BUFFER_HINTS_PRESERVE |
377                           FF_BUFFER_HINTS_REUSABLE;
378     if ((ret = avctx->reget_buffer(avctx, &s->pic))) {
379         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
380         return ret;
381     }
382
383     ftype = AV_RL32(avpkt->data);
384     switch (ftype) {
385     case 0:
386         ret = xan_decode_frame_type0(avctx, avpkt);
387         break;
388     case 1:
389         ret = xan_decode_frame_type1(avctx, avpkt);
390         break;
391     default:
392         av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype);
393         return -1;
394     }
395     if (ret)
396         return ret;
397
398     *data_size = sizeof(AVFrame);
399     *(AVFrame*)data = s->pic;
400
401     return avpkt->size;
402 }
403
404 static av_cold int xan_decode_end(AVCodecContext *avctx)
405 {
406     XanContext *s = avctx->priv_data;
407
408     if (s->pic.data[0])
409         avctx->release_buffer(avctx, &s->pic);
410
411     av_freep(&s->y_buffer);
412     av_freep(&s->scratch_buffer);
413
414     return 0;
415 }
416
417 AVCodec ff_xan_wc4_decoder = {
418     "xan_wc4",
419     AVMEDIA_TYPE_VIDEO,
420     CODEC_ID_XAN_WC4,
421     sizeof(XanContext),
422     xan_decode_init,
423     NULL,
424     xan_decode_end,
425     xan_decode_frame,
426     CODEC_CAP_DR1,
427     .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
428 };
429