dxtory: add more compressed and uncompressed modes
[libav.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 };