]> git.sesse.net Git - ffmpeg/blob - libavcodec/xxan.c
Merge remote-tracking branch 'qatar/master'
[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 "bytestream.h"
26 #define 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 ||
133                 dest + size + size2 > dest_end ||
134                 dest + size - orig_dest < back )
135                 return -1;
136             bytestream_get_buffer(&src, dest, size);
137             dest += size;
138             av_memcpy_backptr(dest, back, size2);
139             dest += size2;
140         } else {
141             int finish = opcode >= 0xfc;
142
143             size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
144             if (src + size > src_end || dest + size > dest_end)
145                 return -1;
146             bytestream_get_buffer(&src, dest, size);
147             dest += size;
148             if (finish)
149                 break;
150         }
151     }
152     return dest - orig_dest;
153 }
154
155 static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt)
156 {
157     const uint8_t *buf = avpkt->data;
158     XanContext *s = avctx->priv_data;
159     uint8_t *U, *V;
160     unsigned chroma_off;
161     int val, uval, vval;
162     int i, j;
163     const uint8_t *src, *src_end;
164     const uint8_t *table;
165     int table_size;
166     int mode, offset, dec_size;
167
168     chroma_off = AV_RL32(buf + 4);
169     if (!chroma_off)
170         return 0;
171     if (chroma_off + 10 >= avpkt->size) {
172         av_log(avctx, AV_LOG_ERROR, "Invalid chroma block position\n");
173         return -1;
174     }
175     src    = avpkt->data + 4 + chroma_off;
176     table  = src + 2;
177     table_size =  avpkt->data + avpkt->size - table;
178     mode   = bytestream_get_le16(&src);
179     offset = bytestream_get_le16(&src) * 2;
180
181     if (src - avpkt->data >= avpkt->size - offset) {
182         av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
183         return -1;
184     }
185
186     memset(s->scratch_buffer, 0, s->buffer_size);
187     dec_size = xan_unpack(s->scratch_buffer, s->buffer_size, src + offset,
188                           avpkt->size - offset - (src - avpkt->data));
189     if (dec_size < 0) {
190         av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n");
191         return -1;
192     }
193
194     U = s->pic.data[1];
195     V = s->pic.data[2];
196     src     = s->scratch_buffer;
197     src_end = src + dec_size;
198     if (mode) {
199         for (j = 0; j < avctx->height >> 1; j++) {
200             for (i = 0; i < avctx->width >> 1; i++) {
201                 if (src_end - src < 1)
202                     return 0;
203                 val = *src++;
204                 if (val) {
205                     if (val << 1 >= table_size)
206                         return AVERROR_INVALIDDATA;
207                     val  = AV_RL16(table + (val << 1));
208                     uval = (val >> 3) & 0xF8;
209                     vval = (val >> 8) & 0xF8;
210                     U[i] = uval | (uval >> 5);
211                     V[i] = vval | (vval >> 5);
212                 }
213             }
214             U += s->pic.linesize[1];
215             V += s->pic.linesize[2];
216         }
217     } else {
218         uint8_t *U2 = U + s->pic.linesize[1];
219         uint8_t *V2 = V + s->pic.linesize[2];
220
221         for (j = 0; j < avctx->height >> 2; j++) {
222             for (i = 0; i < avctx->width >> 1; i += 2) {
223                 if (src_end - src < 1)
224                     return 0;
225                 val = *src++;
226                 if (val) {
227                     if (val << 1 >= table_size)
228                         return AVERROR_INVALIDDATA;
229                     val  = AV_RL16(table + (val << 1));
230                     uval = (val >> 3) & 0xF8;
231                     vval = (val >> 8) & 0xF8;
232                     U[i] = U[i+1] = U2[i] = U2[i+1] = uval | (uval >> 5);
233                     V[i] = V[i+1] = V2[i] = V2[i+1] = vval | (vval >> 5);
234                 }
235             }
236             U  += s->pic.linesize[1] * 2;
237             V  += s->pic.linesize[2] * 2;
238             U2 += s->pic.linesize[1] * 2;
239             V2 += s->pic.linesize[2] * 2;
240         }
241     }
242
243     return 0;
244 }
245
246 static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt)
247 {
248     const uint8_t *buf = avpkt->data;
249     XanContext *s = avctx->priv_data;
250     uint8_t *ybuf, *prev_buf, *src = s->scratch_buffer;
251     unsigned  chroma_off, corr_off;
252     int cur, last, size;
253     int i, j;
254     int ret;
255
256     corr_off   = AV_RL32(buf + 8);
257     chroma_off = AV_RL32(buf + 4);
258
259     if ((ret = xan_decode_chroma(avctx, avpkt)) != 0)
260         return ret;
261
262     size = avpkt->size - 4;
263     if (corr_off >= avpkt->size) {
264         av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n");
265         corr_off = 0;
266     }
267     if (corr_off)
268         size = corr_off;
269     if (chroma_off)
270         size = FFMIN(size, chroma_off);
271     ret = xan_unpack_luma(buf + 12, size, src, s->buffer_size >> 1);
272     if (ret) {
273         av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");
274         return ret;
275     }
276
277     ybuf = s->y_buffer;
278     last = *src++;
279     ybuf[0] = last << 1;
280     for (j = 1; j < avctx->width - 1; j += 2) {
281         cur = (last + *src++) & 0x1F;
282         ybuf[j]   = last + cur;
283         ybuf[j+1] = cur << 1;
284         last = cur;
285     }
286     ybuf[j]  = last << 1;
287     prev_buf = ybuf;
288     ybuf += avctx->width;
289
290     for (i = 1; i < avctx->height; i++) {
291         last = ((prev_buf[0] >> 1) + *src++) & 0x1F;
292         ybuf[0] = last << 1;
293         for (j = 1; j < avctx->width - 1; j += 2) {
294             cur = ((prev_buf[j + 1] >> 1) + *src++) & 0x1F;
295             ybuf[j]   = last + cur;
296             ybuf[j+1] = cur << 1;
297             last = cur;
298         }
299         ybuf[j] = last << 1;
300         prev_buf = ybuf;
301         ybuf += avctx->width;
302     }
303
304     if (corr_off) {
305         int corr_end, dec_size;
306
307         corr_end = avpkt->size;
308         if (chroma_off > corr_off)
309             corr_end = chroma_off;
310         dec_size = xan_unpack(s->scratch_buffer, s->buffer_size,
311                               avpkt->data + 8 + corr_off,
312                               corr_end - corr_off);
313         if (dec_size < 0)
314             dec_size = 0;
315         else
316             dec_size = FFMIN(dec_size, s->buffer_size/2 - 1);
317
318         for (i = 0; i < dec_size; i++)
319             s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F;
320     }
321
322     src  = s->y_buffer;
323     ybuf = s->pic.data[0];
324     for (j = 0; j < avctx->height; j++) {
325         for (i = 0; i < avctx->width; i++)
326             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
327         src  += avctx->width;
328         ybuf += s->pic.linesize[0];
329     }
330
331     return 0;
332 }
333
334 static int xan_decode_frame_type1(AVCodecContext *avctx, AVPacket *avpkt)
335 {
336     const uint8_t *buf = avpkt->data;
337     XanContext *s = avctx->priv_data;
338     uint8_t *ybuf, *src = s->scratch_buffer;
339     int cur, last;
340     int i, j;
341     int ret;
342
343     if ((ret = xan_decode_chroma(avctx, avpkt)) != 0)
344         return ret;
345
346     ret = xan_unpack_luma(buf + 16, avpkt->size - 16, src,
347                           s->buffer_size >> 1);
348     if (ret) {
349         av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");
350         return ret;
351     }
352
353     ybuf = s->y_buffer;
354     for (i = 0; i < avctx->height; i++) {
355         last = (ybuf[0] + (*src++ << 1)) & 0x3F;
356         ybuf[0] = last;
357         for (j = 1; j < avctx->width - 1; j += 2) {
358             cur = (ybuf[j + 1] + (*src++ << 1)) & 0x3F;
359             ybuf[j]   = (last + cur) >> 1;
360             ybuf[j+1] = cur;
361             last = cur;
362         }
363         ybuf[j] = last;
364         ybuf += avctx->width;
365     }
366
367     src = s->y_buffer;
368     ybuf = s->pic.data[0];
369     for (j = 0; j < avctx->height; j++) {
370         for (i = 0; i < avctx->width; i++)
371             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
372         src  += avctx->width;
373         ybuf += s->pic.linesize[0];
374     }
375
376     return 0;
377 }
378
379 static int xan_decode_frame(AVCodecContext *avctx,
380                             void *data, int *data_size,
381                             AVPacket *avpkt)
382 {
383     XanContext *s = avctx->priv_data;
384     int ftype;
385     int ret;
386
387     s->pic.reference = 3;
388     s->pic.buffer_hints = FF_BUFFER_HINTS_VALID |
389                           FF_BUFFER_HINTS_PRESERVE |
390                           FF_BUFFER_HINTS_REUSABLE;
391     if ((ret = avctx->reget_buffer(avctx, &s->pic))) {
392         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
393         return ret;
394     }
395
396     ftype = AV_RL32(avpkt->data);
397     switch (ftype) {
398     case 0:
399         ret = xan_decode_frame_type0(avctx, avpkt);
400         break;
401     case 1:
402         ret = xan_decode_frame_type1(avctx, avpkt);
403         break;
404     default:
405         av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype);
406         return -1;
407     }
408     if (ret)
409         return ret;
410
411     *data_size = sizeof(AVFrame);
412     *(AVFrame*)data = s->pic;
413
414     return avpkt->size;
415 }
416
417 static av_cold int xan_decode_end(AVCodecContext *avctx)
418 {
419     XanContext *s = avctx->priv_data;
420
421     if (s->pic.data[0])
422         avctx->release_buffer(avctx, &s->pic);
423
424     av_freep(&s->y_buffer);
425     av_freep(&s->scratch_buffer);
426
427     return 0;
428 }
429
430 AVCodec ff_xan_wc4_decoder = {
431     .name           = "xan_wc4",
432     .type           = AVMEDIA_TYPE_VIDEO,
433     .id             = CODEC_ID_XAN_WC4,
434     .priv_data_size = sizeof(XanContext),
435     .init           = xan_decode_init,
436     .close          = xan_decode_end,
437     .decode         = xan_decode_frame,
438     .capabilities   = CODEC_CAP_DR1,
439     .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
440 };