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