11cd7b624b0d515521d9d24a88c308a31dbf9daf
[ffmpeg.git] / libavcodec / dxtory.c
1 /*
2  * Dxtory decoder
3  *
4  * Copyright (c) 2011 Konstantin Shishkov
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 #define BITSTREAM_READER_LE
24 #include "avcodec.h"
25 #include "bytestream.h"
26 #include "get_bits.h"
27 #include "internal.h"
28 #include "unary.h"
29 #include "libavutil/common.h"
30 #include "libavutil/intreadwrite.h"
31
32 static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
33                                 const uint8_t *src, int src_size,
34                                 int id, int bpp)
35 {
36     int h;
37     uint8_t *dst;
38     int ret;
39
40     if (src_size < avctx->width * avctx->height * bpp) {
41         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
42         return AVERROR_INVALIDDATA;
43     }
44
45     avctx->pix_fmt = id;
46     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
47         return ret;
48
49     dst = pic->data[0];
50     for (h = 0; h < avctx->height; h++) {
51         memcpy(dst, src, avctx->width * bpp);
52         src += avctx->width * bpp;
53         dst += pic->linesize[0];
54     }
55
56     return 0;
57 }
58
59 static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
60                                 const uint8_t *src, int src_size)
61 {
62     int h, w;
63     uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
64     int ret;
65
66     if (src_size < avctx->width * avctx->height * 18 / 16) {
67         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
68         return AVERROR_INVALIDDATA;
69     }
70
71     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
72     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
73         return ret;
74
75     Y1 = pic->data[0];
76     Y2 = pic->data[0] + pic->linesize[0];
77     Y3 = pic->data[0] + pic->linesize[0] * 2;
78     Y4 = pic->data[0] + pic->linesize[0] * 3;
79     U  = pic->data[1];
80     V  = pic->data[2];
81     for (h = 0; h < avctx->height; h += 4) {
82         for (w = 0; w < avctx->width; w += 4) {
83             AV_COPY32(Y1 + w, src);
84             AV_COPY32(Y2 + w, src + 4);
85             AV_COPY32(Y3 + w, src + 8);
86             AV_COPY32(Y4 + w, src + 12);
87             U[w >> 2] = src[16] + 0x80;
88             V[w >> 2] = src[17] + 0x80;
89             src += 18;
90         }
91         Y1 += pic->linesize[0] << 2;
92         Y2 += pic->linesize[0] << 2;
93         Y3 += pic->linesize[0] << 2;
94         Y4 += pic->linesize[0] << 2;
95         U  += pic->linesize[1];
96         V  += pic->linesize[2];
97     }
98
99     return 0;
100 }
101
102 static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
103                                 const uint8_t *src, int src_size)
104 {
105     int h, w;
106     uint8_t *Y1, *Y2, *U, *V;
107     int ret;
108
109     if (src_size < avctx->width * avctx->height * 3 / 2) {
110         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
111         return AVERROR_INVALIDDATA;
112     }
113
114     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
115     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
116         return ret;
117
118     Y1 = pic->data[0];
119     Y2 = pic->data[0] + pic->linesize[0];
120     U  = pic->data[1];
121     V  = pic->data[2];
122     for (h = 0; h < avctx->height; h += 2) {
123         for (w = 0; w < avctx->width; w += 2) {
124             AV_COPY16(Y1 + w, src);
125             AV_COPY16(Y2 + w, src + 2);
126             U[w >> 1] = src[4] + 0x80;
127             V[w >> 1] = src[5] + 0x80;
128             src += 6;
129         }
130         Y1 += pic->linesize[0] << 1;
131         Y2 += pic->linesize[0] << 1;
132         U  += pic->linesize[1];
133         V  += pic->linesize[2];
134     }
135
136     return 0;
137 }
138
139 static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
140                                 const uint8_t *src, int src_size)
141 {
142     int h, w;
143     uint8_t *Y, *U, *V;
144     int ret;
145
146     if (src_size < avctx->width * avctx->height * 3) {
147         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
148         return AVERROR_INVALIDDATA;
149     }
150
151     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
152     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
153         return ret;
154
155     Y = pic->data[0];
156     U = pic->data[1];
157     V = pic->data[2];
158     for (h = 0; h < avctx->height; h++) {
159         for (w = 0; w < avctx->width; w++) {
160             Y[w] = *src++;
161             U[w] = *src++ ^ 0x80;
162             V[w] = *src++ ^ 0x80;
163         }
164         Y += pic->linesize[0];
165         U += pic->linesize[1];
166         V += pic->linesize[2];
167     }
168
169     return 0;
170 }
171
172 const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
173
174 static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
175 {
176     uint8_t c, val;
177
178     c = get_unary(gb, 0, 8);
179     if (!c) {
180         val = get_bits(gb, 8);
181         memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
182     } else {
183         val = lru[c - 1];
184         memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
185     }
186     lru[0] = val;
187
188     return val;
189 }
190
191 static int dx2_decode_slice_rgb(GetBitContext *gb, int width, int height,
192                                 uint8_t *dst, int stride)
193 {
194     int x, y, i;
195     uint8_t lru[3][8];
196
197     for (i = 0; i < 3; i++)
198         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
199
200     for (y = 0; y < height; y++) {
201         for (x = 0; x < width; x++) {
202             dst[x * 3 + 0] = decode_sym(gb, lru[0]);
203             dst[x * 3 + 1] = decode_sym(gb, lru[1]);
204             dst[x * 3 + 2] = decode_sym(gb, lru[2]);
205         }
206
207         dst += stride;
208     }
209
210     return 0;
211 }
212
213 static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
214                                 const uint8_t *src, int src_size)
215 {
216     GetByteContext gb;
217     GetBitContext  gb2;
218     int nslices, slice, slice_height;
219     uint32_t off, slice_size;
220     uint8_t *dst;
221     int ret;
222
223     bytestream2_init(&gb, src, src_size);
224     nslices = bytestream2_get_le16(&gb);
225     off = FFALIGN(nslices * 4 + 2, 16);
226     if (src_size < off) {
227         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
228         return AVERROR_INVALIDDATA;
229     }
230
231     if (!nslices || avctx->height % nslices) {
232         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
233                               avctx->width, avctx->height);
234         return AVERROR_PATCHWELCOME;
235     }
236
237     slice_height = avctx->height / nslices;
238     avctx->pix_fmt = AV_PIX_FMT_BGR24;
239     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
240         return ret;
241
242     dst = pic->data[0];
243     for (slice = 0; slice < nslices; slice++) {
244         slice_size = bytestream2_get_le32(&gb);
245         if (slice_size > src_size - off) {
246             av_log(avctx, AV_LOG_ERROR,
247                    "invalid slice size %d (only %d bytes left)\n",
248                    slice_size, src_size - off);
249             return AVERROR_INVALIDDATA;
250         }
251         if (slice_size <= 16) {
252             av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
253             return AVERROR_INVALIDDATA;
254         }
255
256         if (AV_RL32(src + off) != slice_size - 16) {
257             av_log(avctx, AV_LOG_ERROR,
258                    "Slice sizes mismatch: got %d instead of %d\n",
259                    AV_RL32(src + off), slice_size - 16);
260         }
261         init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
262         dx2_decode_slice_rgb(&gb2, avctx->width, slice_height, dst,
263                              pic->linesize[0]);
264
265         dst += pic->linesize[0] * slice_height;
266         off += slice_size;
267     }
268
269     return 0;
270 }
271
272 static int dx2_decode_slice_410(GetBitContext *gb, int width, int height,
273                                 uint8_t *Y, uint8_t *U, uint8_t *V,
274                                 int ystride, int ustride, int vstride)
275 {
276     int x, y, i, j;
277     uint8_t lru[3][8];
278
279     for (i = 0; i < 3; i++)
280         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
281
282     for (y = 0; y < height; y += 4) {
283         for (x = 0; x < width; x += 4) {
284             for (j = 0; j < 4; j++)
285                 for (i = 0; i < 4; i++)
286                     Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
287             U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
288             V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
289         }
290
291         Y += ystride << 2;
292         U += ustride;
293         V += vstride;
294     }
295
296     return 0;
297 }
298
299 static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
300                                 const uint8_t *src, int src_size)
301 {
302     GetByteContext gb;
303     GetBitContext  gb2;
304     int nslices, slice, slice_height, ref_slice_height;
305     int cur_y, next_y;
306     uint32_t off, slice_size;
307     uint8_t *Y, *U, *V;
308     int ret;
309
310     bytestream2_init(&gb, src, src_size);
311     nslices = bytestream2_get_le16(&gb);
312     off = FFALIGN(nslices * 4 + 2, 16);
313     if (src_size < off) {
314         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
315         return AVERROR_INVALIDDATA;
316     }
317
318     if (!nslices || avctx->height % nslices) {
319         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
320                               avctx->width, avctx->height);
321         return AVERROR_PATCHWELCOME;
322     }
323
324     ref_slice_height = avctx->height / nslices;
325     if ((avctx->width & 3) || (avctx->height & 3)) {
326         avpriv_request_sample(avctx, "Frame dimensions %dx%d",
327                               avctx->width, avctx->height);
328     }
329
330     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
331     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
332         return ret;
333
334     Y = pic->data[0];
335     U = pic->data[1];
336     V = pic->data[2];
337
338     cur_y  = 0;
339     next_y = ref_slice_height;
340     for (slice = 0; slice < nslices; slice++) {
341         slice_size   = bytestream2_get_le32(&gb);
342         slice_height = (next_y & ~3) - (cur_y & ~3);
343         if (slice_size > src_size - off) {
344             av_log(avctx, AV_LOG_ERROR,
345                    "invalid slice size %d (only %d bytes left)\n",
346                    slice_size, src_size - off);
347             return AVERROR_INVALIDDATA;
348         }
349         if (slice_size <= 16) {
350             av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
351             return AVERROR_INVALIDDATA;
352         }
353
354         if (AV_RL32(src + off) != slice_size - 16) {
355             av_log(avctx, AV_LOG_ERROR,
356                    "Slice sizes mismatch: got %d instead of %d\n",
357                    AV_RL32(src + off), slice_size - 16);
358         }
359         init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
360         dx2_decode_slice_410(&gb2, avctx->width, slice_height, Y, U, V,
361                              pic->linesize[0], pic->linesize[1],
362                              pic->linesize[2]);
363
364         Y += pic->linesize[0] *  slice_height;
365         U += pic->linesize[1] * (slice_height >> 2);
366         V += pic->linesize[2] * (slice_height >> 2);
367         off += slice_size;
368         cur_y   = next_y;
369         next_y += ref_slice_height;
370     }
371
372     return 0;
373 }
374
375 static int dx2_decode_slice_420(GetBitContext *gb, int width, int height,
376                                 uint8_t *Y, uint8_t *U, uint8_t *V,
377                                 int ystride, int ustride, int vstride)
378 {
379     int x, y, i;
380     uint8_t lru[3][8];
381
382     for (i = 0; i < 3; i++)
383         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
384
385     for (y = 0; y < height; y+=2) {
386         for (x = 0; x < width; x += 2) {
387             Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
388             Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
389             Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
390             Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
391             U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
392             V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
393         }
394
395         Y += ystride << 1;
396         U += ustride;
397         V += vstride;
398     }
399
400     return 0;
401 }
402
403 static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
404                                 const uint8_t *src, int src_size)
405 {
406     GetByteContext gb;
407     GetBitContext  gb2;
408     int nslices, slice, slice_height, ref_slice_height;
409     int cur_y, next_y;
410     uint32_t off, slice_size;
411     uint8_t *Y, *U, *V;
412     int ret;
413
414     bytestream2_init(&gb, src, src_size);
415     nslices = bytestream2_get_le16(&gb);
416     off = FFALIGN(nslices * 4 + 2, 16);
417     if (src_size < off) {
418         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
419         return AVERROR_INVALIDDATA;
420     }
421
422     if (!nslices || avctx->height % nslices) {
423         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
424                               avctx->width, avctx->height);
425         return AVERROR_PATCHWELCOME;
426     }
427
428     ref_slice_height = avctx->height / nslices;
429     if ((avctx->width & 1) || (avctx->height & 1)) {
430         avpriv_request_sample(avctx, "Frame dimensions %dx%d",
431                               avctx->width, avctx->height);
432     }
433
434     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
435     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
436         return ret;
437
438     Y = pic->data[0];
439     U = pic->data[1];
440     V = pic->data[2];
441
442     cur_y  = 0;
443     next_y = ref_slice_height;
444     for (slice = 0; slice < nslices; slice++) {
445         slice_size   = bytestream2_get_le32(&gb);
446         slice_height = (next_y & ~1) - (cur_y & ~1);
447         if (slice_size > src_size - off) {
448             av_log(avctx, AV_LOG_ERROR,
449                    "invalid slice size %d (only %d bytes left)\n",
450                    slice_size, src_size - off);
451             return AVERROR_INVALIDDATA;
452         }
453         if (slice_size <= 16) {
454             av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
455             return AVERROR_INVALIDDATA;
456         }
457
458         if (AV_RL32(src + off) != slice_size - 16) {
459             av_log(avctx, AV_LOG_ERROR,
460                    "Slice sizes mismatch: got %d instead of %d\n",
461                    AV_RL32(src + off), slice_size - 16);
462         }
463         init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
464         dx2_decode_slice_420(&gb2, avctx->width, slice_height, Y, U, V,
465                              pic->linesize[0], pic->linesize[1],
466                              pic->linesize[2]);
467
468         Y += pic->linesize[0] *  slice_height;
469         U += pic->linesize[1] * (slice_height >> 1);
470         V += pic->linesize[2] * (slice_height >> 1);
471         off += slice_size;
472         cur_y   = next_y;
473         next_y += ref_slice_height;
474     }
475
476     return 0;
477 }
478
479 static int dx2_decode_slice_444(GetBitContext *gb, int width, int height,
480                                 uint8_t *Y, uint8_t *U, uint8_t *V,
481                                 int ystride, int ustride, int vstride)
482 {
483     int x, y, i;
484     uint8_t lru[3][8];
485
486     for (i = 0; i < 3; i++)
487         memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
488
489     for (y = 0; y < height; y++) {
490         for (x = 0; x < width; x++) {
491             Y[x] = decode_sym(gb, lru[0]);
492             U[x] = decode_sym(gb, lru[1]) ^ 0x80;
493             V[x] = decode_sym(gb, lru[2]) ^ 0x80;
494         }
495
496         Y += ystride;
497         U += ustride;
498         V += vstride;
499     }
500
501     return 0;
502 }
503
504 static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
505                                 const uint8_t *src, int src_size)
506 {
507     GetByteContext gb;
508     GetBitContext  gb2;
509     int nslices, slice, slice_height;
510     uint32_t off, slice_size;
511     uint8_t *Y, *U, *V;
512     int ret;
513
514     bytestream2_init(&gb, src, src_size);
515     nslices = bytestream2_get_le16(&gb);
516     off = FFALIGN(nslices * 4 + 2, 16);
517     if (src_size < off) {
518         av_log(avctx, AV_LOG_ERROR, "no slice data\n");
519         return AVERROR_INVALIDDATA;
520     }
521
522     if (!nslices || avctx->height % nslices) {
523         avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
524                               avctx->width, avctx->height);
525         return AVERROR_PATCHWELCOME;
526     }
527
528     slice_height = avctx->height / nslices;
529
530     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
531     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
532         return ret;
533
534     Y = pic->data[0];
535     U = pic->data[1];
536     V = pic->data[2];
537
538     for (slice = 0; slice < nslices; slice++) {
539         slice_size = bytestream2_get_le32(&gb);
540         if (slice_size > src_size - off) {
541             av_log(avctx, AV_LOG_ERROR,
542                    "invalid slice size %d (only %d bytes left)\n",
543                    slice_size, src_size - off);
544             return AVERROR_INVALIDDATA;
545         }
546         if (slice_size <= 16) {
547             av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
548             return AVERROR_INVALIDDATA;
549         }
550
551         if (AV_RL32(src + off) != slice_size - 16) {
552             av_log(avctx, AV_LOG_ERROR,
553                    "Slice sizes mismatch: got %d instead of %d\n",
554                    AV_RL32(src + off), slice_size - 16);
555         }
556         init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
557         dx2_decode_slice_444(&gb2, avctx->width, slice_height, Y, U, V,
558                              pic->linesize[0], pic->linesize[1],
559                              pic->linesize[2]);
560
561         Y += pic->linesize[0] * slice_height;
562         U += pic->linesize[1] * slice_height;
563         V += pic->linesize[2] * slice_height;
564         off += slice_size;
565     }
566
567     return 0;
568 }
569
570 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
571                         AVPacket *avpkt)
572 {
573     AVFrame *pic = data;
574     const uint8_t *src = avpkt->data;
575     int ret;
576
577     if (avpkt->size < 16) {
578         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
579         return AVERROR_INVALIDDATA;
580     }
581
582     switch (AV_RB32(src)) {
583     case 0x01000001:
584         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
585                                    AV_PIX_FMT_BGR24, 3);
586         break;
587     case 0x01000009:
588         ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
589         break;
590     case 0x02000001:
591         ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
592         break;
593     case 0x02000009:
594         ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
595         break;
596     case 0x03000001:
597         ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
598         break;
599     case 0x03000009:
600         ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
601         break;
602     case 0x04000001:
603         ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
604         break;
605     case 0x04000009:
606         ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
607         break;
608     case 0x17000001:
609         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
610                                    AV_PIX_FMT_RGB565LE, 2);
611         break;
612     case 0x18000001:
613     case 0x19000001:
614         ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
615                                    AV_PIX_FMT_RGB555LE, 2);
616         break;
617     default:
618         avpriv_request_sample(avctx, "Frame header %X", AV_RB32(src));
619         return AVERROR_PATCHWELCOME;
620     }
621
622     if (ret)
623         return ret;
624
625     pic->pict_type = AV_PICTURE_TYPE_I;
626     pic->key_frame = 1;
627     *got_frame = 1;
628
629     return avpkt->size;
630 }
631
632 AVCodec ff_dxtory_decoder = {
633     .name           = "dxtory",
634     .long_name      = NULL_IF_CONFIG_SMALL("Dxtory"),
635     .type           = AVMEDIA_TYPE_VIDEO,
636     .id             = AV_CODEC_ID_DXTORY,
637     .decode         = decode_frame,
638     .capabilities   = CODEC_CAP_DR1,
639 };