1 /*
2 * Dxtory decoder
3 *
4 * Copyright (c) 2011 Konstantin Shishkov
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 <inttypes.h>
24
25 #define BITSTREAM_READER_LE
33
36 int id, int bpp)
37 {
41
42 if (src_size < avctx->
width * avctx->
height * (int64_t)bpp) {
45 }
46
50
52 for (h = 0; h < avctx->
height; h++) {
53 memcpy(dst, src, avctx->
width * bpp);
54 src += avctx->
width * bpp;
56 }
57
58 return 0;
59 }
60
63 {
67
68 if (src_size < avctx->
width * avctx->
height * 9LL / 8) {
71 }
72
76
83 for (h = 0; h < avctx->
height; h += 4) {
84 for (w = 0; w < avctx->
width; w += 4) {
89 U[w >> 2] = src[16] + 0x80;
90 V[w >> 2] = src[17] + 0x80;
91 src += 18;
92 }
99 }
100
101 return 0;
102 }
103
106 {
110
111 if (src_size < avctx->
width * avctx->
height * 3LL / 2) {
114 }
115
119
124 for (h = 0; h < avctx->
height; h += 2) {
125 for (w = 0; w < avctx->
width; w += 2) {
128 U[w >> 1] = src[4] + 0x80;
129 V[w >> 1] = src[5] + 0x80;
130 src += 6;
131 }
136 }
137
138 return 0;
139 }
140
143 {
147
148 if (src_size < avctx->
width * avctx->
height * 3LL) {
151 }
152
156
160 for (h = 0; h < avctx->
height; h++) {
161 for (w = 0; w < avctx->
width; w++) {
162 Y[w] = *src++;
163 U[w] = *src++ ^ 0x80;
164 V[w] = *src++ ^ 0x80;
165 }
169 }
170
171 return 0;
172 }
173
174 static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
177
179 {
181
183 if (!c) {
185 memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
186 } else {
187 val = lru[c - 1];
188 memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
189 }
191
193 }
194
197 {
199
201 if (!c) {
203 memmove(lru + 1, lru, sizeof(*lru) * (6 - 1));
204 } else {
205 val = lru[c - 1];
206 memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
207 }
209
211 }
212
215 {
219
222 memcpy(lru[2], def_lru_555, 8 *
sizeof(*
def_lru));
223
224 for (y = 0; y <
height; y++) {
225 for (x = 0; x <
width; x++) {
229 dst[x * 3 + 0] = (r << 3) | (r >> 2);
230 dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
231 dst[x * 3 + 2] = (b << 3) | (b >> 2);
232 }
233
235 }
236
237 return 0;
238 }
239
242 {
245 int nslices, slice, slice_height;
246 uint32_t off, slice_size;
249
251 nslices = bytestream2_get_le16(&gb);
252 off =
FFALIGN(nslices * 4 + 2, 16);
253 if (src_size < off) {
256 }
257
258 if (!nslices || avctx->
height % nslices) {
262 }
263
264 slice_height = avctx->
height / nslices;
268
270 for (slice = 0; slice < nslices; slice++) {
271 slice_size = bytestream2_get_le32(&gb);
272 if (slice_size > src_size - off) {
274 "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
275 slice_size, src_size - off);
277 }
278 if (slice_size <= 16) {
281 }
282
283 if (
AV_RL32(src + off) != slice_size - 16) {
285 "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
286 AV_RL32(src + off), slice_size - 16);
287 }
288 if ((ret =
init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
292
293 dst += pic->
linesize[0] * slice_height;
294 off += slice_size;
295 }
296
297 return 0;
298 }
299
302 {
305
306 for (i = 0; i < 3; i++)
308
309 for (y = 0; y <
height; y++) {
310 for (x = 0; x <
width; x++) {
314 }
315
317 }
318
319 return 0;
320 }
321
324 {
327 int nslices, slice, slice_height;
328 uint32_t off, slice_size;
331
333 nslices = bytestream2_get_le16(&gb);
334 off =
FFALIGN(nslices * 4 + 2, 16);
335 if (src_size < off) {
338 }
339
340 if (!nslices || avctx->
height % nslices) {
344 }
345
346 slice_height = avctx->
height / nslices;
350
352 for (slice = 0; slice < nslices; slice++) {
353 slice_size = bytestream2_get_le32(&gb);
354 if (slice_size > src_size - off) {
356 "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
357 slice_size, src_size - off);
359 }
360 if (slice_size <= 16) {
362 slice_size);
364 }
365
366 if (
AV_RL32(src + off) != slice_size - 16) {
368 "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
369 AV_RL32(src + off), slice_size - 16);
370 }
371 if ((ret =
init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
375
376 dst += pic->
linesize[0] * slice_height;
377 off += slice_size;
378 }
379
380 return 0;
381 }
382
385 int ystride, int ustride, int vstride)
386 {
389
390 for (i = 0; i < 3; i++)
392
393 for (y = 0; y <
height; y += 4) {
394 for (x = 0; x <
width; x += 4) {
395 for (j = 0; j < 4; j++)
396 for (i = 0; i < 4; i++)
397 Y[x + i + j * ystride] =
decode_sym(gb, lru[0]);
400 }
401
402 Y += ystride << 2;
403 U += ustride;
404 V += vstride;
405 }
406
407 return 0;
408 }
409
412 {
415 int nslices, slice, slice_height;
416 int cur_y, next_y;
417 uint32_t off, slice_size;
420
422 nslices = bytestream2_get_le16(&gb);
423 off =
FFALIGN(nslices * 4 + 2, 16);
424 if (src_size < off) {
427 }
428
429 if (!nslices) {
433 }
434
438 }
439
443
447
448 cur_y = 0;
449 for (slice = 0; slice < nslices; slice++) {
450 slice_size = bytestream2_get_le32(&gb);
451 next_y = ((slice + 1) * avctx->
height) / nslices;
452 slice_height = (next_y & ~3) - (cur_y & ~3);
453 if (slice_size > src_size - off) {
455 "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
456 slice_size, src_size - off);
458 }
459 if (slice_size <= 16) {
462 }
463
464 if (
AV_RL32(src + off) != slice_size - 16) {
466 "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
467 AV_RL32(src + off), slice_size - 16);
468 }
469 if ((ret =
init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
474
475 Y += pic->
linesize[0] * slice_height;
476 U += pic->
linesize[1] * (slice_height >> 2);
477 V += pic->
linesize[2] * (slice_height >> 2);
478 off += slice_size;
479 cur_y = next_y;
480 }
481
482 return 0;
483 }
484
487 int ystride, int ustride, int vstride)
488 {
491
492 for (i = 0; i < 3; i++)
494
495 for (y = 0; y <
height; y+=2) {
496 for (x = 0; x <
width; x += 2) {
497 Y[x + 0 + 0 * ystride] =
decode_sym(gb, lru[0]);
498 Y[x + 1 + 0 * ystride] =
decode_sym(gb, lru[0]);
499 Y[x + 0 + 1 * ystride] =
decode_sym(gb, lru[0]);
500 Y[x + 1 + 1 * ystride] =
decode_sym(gb, lru[0]);
503 }
504
505 Y += ystride << 1;
506 U += ustride;
507 V += vstride;
508 }
509
510 return 0;
511 }
512
515 {
518 int nslices, slice, slice_height;
519 int cur_y, next_y;
520 uint32_t off, slice_size;
523
525 nslices = bytestream2_get_le16(&gb);
526 off =
FFALIGN(nslices * 4 + 2, 16);
527 if (src_size < off) {
530 }
531
532 if (!nslices) {
536 }
537
541 }
542
546
550
551 cur_y = 0;
552 for (slice = 0; slice < nslices; slice++) {
553 slice_size = bytestream2_get_le32(&gb);
554 next_y = ((slice + 1) * avctx->
height) / nslices;
555 slice_height = (next_y & ~1) - (cur_y & ~1);
556 if (slice_size > src_size - off) {
558 "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
559 slice_size, src_size - off);
561 }
562 if (slice_size <= 16) {
565 }
566
567 if (
AV_RL32(src + off) != slice_size - 16) {
569 "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
570 AV_RL32(src + off), slice_size - 16);
571 }
572 if ((ret =
init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
577
578 Y += pic->
linesize[0] * slice_height;
579 U += pic->
linesize[1] * (slice_height >> 1);
580 V += pic->
linesize[2] * (slice_height >> 1);
581 off += slice_size;
582 cur_y = next_y;
583 }
584
585 return 0;
586 }
587
590 int ystride, int ustride, int vstride)
591 {
594
595 for (i = 0; i < 3; i++)
597
598 for (y = 0; y <
height; y++) {
599 for (x = 0; x <
width; x++) {
603 }
604
605 Y += ystride;
606 U += ustride;
607 V += vstride;
608 }
609
610 return 0;
611 }
612
615 {
618 int nslices, slice, slice_height;
619 uint32_t off, slice_size;
622
624 nslices = bytestream2_get_le16(&gb);
625 off =
FFALIGN(nslices * 4 + 2, 16);
626 if (src_size < off) {
629 }
630
631 if (!nslices || avctx->
height % nslices) {
635 }
636
637 slice_height = avctx->
height / nslices;
638
642
646
647 for (slice = 0; slice < nslices; slice++) {
648 slice_size = bytestream2_get_le32(&gb);
649 if (slice_size > src_size - off) {
651 "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
652 slice_size, src_size - off);
654 }
655 if (slice_size <= 16) {
658 }
659
660 if (
AV_RL32(src + off) != slice_size - 16) {
662 "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
663 AV_RL32(src + off), slice_size - 16);
664 }
665 if ((ret =
init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
670
671 Y += pic->
linesize[0] * slice_height;
672 U += pic->
linesize[1] * slice_height;
673 V += pic->
linesize[2] * slice_height;
674 off += slice_size;
675 }
676
677 return 0;
678 }
679
682 {
686
687 if (avpkt->
size < 16) {
690 }
691
693 case 0x01000001:
696 break;
697 case 0x01000009:
699 break;
700 case 0x02000001:
702 break;
703 case 0x02000009:
705 break;
706 case 0x03000001:
708 break;
709 case 0x03000009:
711 break;
712 case 0x04000001:
714 break;
715 case 0x04000009:
717 break;
718 case 0x17000001:
721 break;
722 case 0x17000009:
724 break;
725 case 0x18000001:
726 case 0x19000001:
729 break;
730 case 0x18000009:
731 case 0x19000009:
733 break;
734 default:
737 }
738
739 if (ret)
741
744 *got_frame = 1;
745
747 }
748
756 };
static int dx2_decode_slice_444(GetBitContext *gb, int width, int height, uint8_t *Y, uint8_t *U, uint8_t *V, int ystride, int ustride, int vstride)
static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
const char const char void * val
static int dx2_decode_slice_rgb(GetBitContext *gb, int width, int height, uint8_t *dst, int stride)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
packed RGB 8:8:8, 24bpp, RGBRGB...
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined ...
static const uint8_t def_lru_555[8]
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
bitstream reader API header.
static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
static const uint8_t def_lru[8]
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int dx2_decode_slice_420(GetBitContext *gb, int width, int height, uint8_t *Y, uint8_t *U, uint8_t *V, int ystride, int ustride, int vstride)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
const char * name
Name of the codec implementation.
Libavcodec external API header.
enum AVPictureType pict_type
Picture type of the frame.
int width
picture width / height.
packed RGB 8:8:8, 24bpp, BGRBGR...
static uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
AVCodec ff_dxtory_decoder
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, int is_565)
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
main external API structure.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
BYTE int const BYTE int int int height
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
static int dx2_decode_slice_565(GetBitContext *gb, int width, int height, uint8_t *dst, int stride, int is_565)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static const uint8_t def_lru_565[8]
GLint GLenum GLboolean GLsizei stride
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
common internal api header.
common internal and external API header
static int get_unary(GetBitContext *gb, int stop, int len)
Get unary code of limited length.
int key_frame
1 -> keyframe, 0-> not
static int dx2_decode_slice_410(GetBitContext *gb, int width, int height, uint8_t *Y, uint8_t *U, uint8_t *V, int ystride, int ustride, int vstride)
static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic, const uint8_t *src, int src_size, int id, int bpp)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
This structure stores compressed data.
static uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8], int bits)
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)