4 * Copyright (c) 2011 Konstantin Shishkov
6 * This file is part of FFmpeg.
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.
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.
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
25 #include "libavutil/common.h"
26 #include "libavutil/intreadwrite.h"
28 #define BITSTREAM_READER_LE
30 #include "bytestream.h"
35 static int64_t get_raw_size(enum AVPixelFormat fmt, int width, int height)
38 case AV_PIX_FMT_RGB555LE:
39 case AV_PIX_FMT_RGB565LE:
40 return width * height * 2LL;
41 case AV_PIX_FMT_RGB24:
42 case AV_PIX_FMT_BGR24:
43 case AV_PIX_FMT_YUV444P:
44 return width * height * 3LL;
45 case AV_PIX_FMT_YUV420P:
46 return (int64_t)(width * height) + AV_CEIL_RSHIFT(width, 1) * AV_CEIL_RSHIFT(height, 1);
47 case AV_PIX_FMT_YUV410P:
48 return (int64_t)(width * height) + AV_CEIL_RSHIFT(width, 2) * AV_CEIL_RSHIFT(height, 2);
54 static void do_vflip(AVCodecContext *avctx, AVFrame *pic, int vflip)
59 switch (pic->format) {
60 case AV_PIX_FMT_YUV444P:
61 pic->data[1] += (avctx->height - 1) * pic->linesize[1];
62 pic->linesize[1] = -pic->linesize[1];
63 pic->data[2] += (avctx->height - 1) * pic->linesize[2];
64 pic->linesize[2] = -pic->linesize[2];
65 case AV_PIX_FMT_RGB555LE:
66 case AV_PIX_FMT_RGB565LE:
67 case AV_PIX_FMT_BGR24:
68 case AV_PIX_FMT_RGB24:
69 pic->data[0] += (avctx->height - 1) * pic->linesize[0];
70 pic->linesize[0] = -pic->linesize[0];
72 case AV_PIX_FMT_YUV410P:
73 pic->data[0] += (avctx->height - 1) * pic->linesize[0];
74 pic->linesize[0] = -pic->linesize[0];
75 pic->data[1] += (AV_CEIL_RSHIFT(avctx->height, 2) - 1) * pic->linesize[1];
76 pic->linesize[1] = -pic->linesize[1];
77 pic->data[2] += (AV_CEIL_RSHIFT(avctx->height, 2) - 1) * pic->linesize[2];
78 pic->linesize[2] = -pic->linesize[2];
80 case AV_PIX_FMT_YUV420P:
81 pic->data[0] += (avctx->height - 1) * pic->linesize[0];
82 pic->linesize[0] = -pic->linesize[0];
83 pic->data[1] += (AV_CEIL_RSHIFT(avctx->height, 1) - 1) * pic->linesize[1];
84 pic->linesize[1] = -pic->linesize[1];
85 pic->data[2] += (AV_CEIL_RSHIFT(avctx->height, 1) - 1) * pic->linesize[2];
86 pic->linesize[2] = -pic->linesize[2];
91 static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
92 const uint8_t *src, int src_size,
93 int id, int bpp, uint32_t vflipped)
99 if (src_size < get_raw_size(id, avctx->width, avctx->height)) {
100 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
101 return AVERROR_INVALIDDATA;
105 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
108 do_vflip(avctx, pic, vflipped);
111 for (h = 0; h < avctx->height; h++) {
112 memcpy(dst, src, avctx->width * bpp);
113 src += avctx->width * bpp;
114 dst += pic->linesize[0];
117 do_vflip(avctx, pic, vflipped);
122 static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
123 const uint8_t *src, int src_size,
127 uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
128 int height, width, hmargin, vmargin;
132 if (src_size < get_raw_size(AV_PIX_FMT_YUV410P, avctx->width, avctx->height)) {
133 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
134 return AVERROR_INVALIDDATA;
137 avctx->pix_fmt = AV_PIX_FMT_YUV410P;
138 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
141 do_vflip(avctx, pic, vflipped);
143 height = avctx->height & ~3;
144 width = avctx->width & ~3;
145 hmargin = avctx->width - width;
146 vmargin = avctx->height - height;
147 huvborder = AV_CEIL_RSHIFT(avctx->width, 2) - 1;
150 Y2 = pic->data[0] + pic->linesize[0];
151 Y3 = pic->data[0] + pic->linesize[0] * 2;
152 Y4 = pic->data[0] + pic->linesize[0] * 3;
155 for (h = 0; h < height; h += 4) {
156 for (w = 0; w < width; w += 4) {
157 AV_COPY32U(Y1 + w, src);
158 AV_COPY32U(Y2 + w, src + 4);
159 AV_COPY32U(Y3 + w, src + 8);
160 AV_COPY32U(Y4 + w, src + 12);
161 U[w >> 2] = src[16] + 0x80;
162 V[w >> 2] = src[17] + 0x80;
166 for (w = 0; w < hmargin; w++) {
167 Y1[width + w] = src[w];
168 Y2[width + w] = src[w + hmargin * 1];
169 Y3[width + w] = src[w + hmargin * 2];
170 Y4[width + w] = src[w + hmargin * 3];
173 U[huvborder] = src[0] + 0x80;
174 V[huvborder] = src[1] + 0x80;
177 Y1 += pic->linesize[0] << 2;
178 Y2 += pic->linesize[0] << 2;
179 Y3 += pic->linesize[0] << 2;
180 Y4 += pic->linesize[0] << 2;
181 U += pic->linesize[1];
182 V += pic->linesize[2];
186 for (w = 0; w < width; w += 4) {
187 AV_COPY32U(Y1 + w, src);
189 AV_COPY32U(Y2 + w, src + 4);
191 AV_COPY32U(Y3 + w, src + 8);
193 U[w >> 2] = src[0] + 0x80;
194 V[w >> 2] = src[1] + 0x80;
198 for (w = 0; w < hmargin; w++) {
199 AV_COPY32U(Y1 + w, src);
201 AV_COPY32U(Y2 + w, src + 4);
203 AV_COPY32U(Y3 + w, src + 8);
206 U[huvborder] = src[0] + 0x80;
207 V[huvborder] = src[1] + 0x80;
212 do_vflip(avctx, pic, vflipped);
217 static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
218 const uint8_t *src, int src_size,
222 uint8_t *Y1, *Y2, *U, *V;
223 int height, width, hmargin, vmargin;
227 if (src_size < get_raw_size(AV_PIX_FMT_YUV420P, avctx->width, avctx->height)) {
228 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
229 return AVERROR_INVALIDDATA;
232 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
233 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
236 do_vflip(avctx, pic, vflipped);
238 height = avctx->height & ~1;
239 width = avctx->width & ~1;
240 hmargin = avctx->width - width;
241 vmargin = avctx->height - height;
242 huvborder = AV_CEIL_RSHIFT(avctx->width, 1) - 1;
245 Y2 = pic->data[0] + pic->linesize[0];
248 for (h = 0; h < height; h += 2) {
249 for (w = 0; w < width; w += 2) {
250 AV_COPY16(Y1 + w, src);
251 AV_COPY16(Y2 + w, src + 2);
252 U[w >> 1] = src[4] + 0x80;
253 V[w >> 1] = src[5] + 0x80;
257 Y1[width + 1] = src[0];
258 Y2[width + 1] = src[1];
259 U[huvborder] = src[2] + 0x80;
260 V[huvborder] = src[3] + 0x80;
263 Y1 += pic->linesize[0] << 1;
264 Y2 += pic->linesize[0] << 1;
265 U += pic->linesize[1];
266 V += pic->linesize[2];
270 for (w = 0; w < width; w += 2) {
271 AV_COPY16U(Y1 + w, src);
272 U[w >> 1] = src[0] + 0x80;
273 V[w >> 1] = src[1] + 0x80;
278 U[huvborder] = src[1] + 0x80;
279 V[huvborder] = src[2] + 0x80;
284 do_vflip(avctx, pic, vflipped);
289 static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
290 const uint8_t *src, int src_size,
297 if (src_size < get_raw_size(AV_PIX_FMT_YUV444P, avctx->width, avctx->height)) {
298 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
299 return AVERROR_INVALIDDATA;
302 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
303 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
306 do_vflip(avctx, pic, vflipped);
311 for (h = 0; h < avctx->height; h++) {
312 for (w = 0; w < avctx->width; w++) {
314 U[w] = *src++ ^ 0x80;
315 V[w] = *src++ ^ 0x80;
317 Y += pic->linesize[0];
318 U += pic->linesize[1];
319 V += pic->linesize[2];
322 do_vflip(avctx, pic, vflipped);
327 static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
328 static const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
329 static const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
331 static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
335 c = get_unary(gb, 0, 8);
337 val = get_bits(gb, 8);
338 memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
341 memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
348 static int check_slice_size(AVCodecContext *avctx,
349 const uint8_t *src, int src_size,
350 int slice_size, int off)
354 if (slice_size > src_size - off) {
355 av_log(avctx, AV_LOG_ERROR,
356 "invalid slice size %d (only %d bytes left)\n",
357 slice_size, src_size - off);
358 return AVERROR_INVALIDDATA;
360 if (slice_size <= 16) {
361 av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n",
363 return AVERROR_INVALIDDATA;
366 cur_slice_size = AV_RL32(src + off);
367 if (cur_slice_size != slice_size - 16) {
368 av_log(avctx, AV_LOG_ERROR,
369 "Slice sizes mismatch: got %d instead of %d\n",
370 cur_slice_size, slice_size - 16);
376 static int load_buffer(AVCodecContext *avctx,
377 const uint8_t *src, int src_size,
379 int *nslices, int *off)
381 bytestream2_init(gb, src, src_size);
382 *nslices = bytestream2_get_le16(gb);
383 *off = FFALIGN(*nslices * 4 + 2, 16);
384 if (src_size < *off) {
385 av_log(avctx, AV_LOG_ERROR, "no slice data\n");
386 return AVERROR_INVALIDDATA;
390 avpriv_request_sample(avctx, "%d slices for %dx%d", *nslices,
391 avctx->width, avctx->height);
392 return AVERROR_PATCHWELCOME;
398 static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8],
403 c = get_unary(gb, 0, bits);
405 val = get_bits(gb, bits);
406 memmove(lru + 1, lru, sizeof(*lru) * (6 - 1));
409 memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
416 typedef int (*decode_slice_func)(GetBitContext *gb, AVFrame *frame,
417 int line, int height, uint8_t lru[3][8]);
419 typedef void (*setup_lru_func)(uint8_t lru[3][8]);
421 static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
422 const uint8_t *src, int src_size,
423 decode_slice_func decode_slice,
424 setup_lru_func setup_lru,
425 enum AVPixelFormat fmt,
428 GetByteContext gb, gb_check;
430 int nslices, slice, line = 0;
431 uint32_t off, slice_size;
436 ret = load_buffer(avctx, src, src_size, &gb, &nslices, &off);
442 for (slice = 0; slice < nslices; slice++) {
443 slice_size = bytestream2_get_le32(&gb_check);
445 if (slice_size <= 16 + (avctx->height * avctx->width / (8 * nslices)))
446 return AVERROR_INVALIDDATA;
447 off_check += slice_size;
450 if (off_check - avctx->discard_damaged_percentage*off_check/100 > src_size)
451 return AVERROR_INVALIDDATA;
453 avctx->pix_fmt = fmt;
454 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
457 do_vflip(avctx, pic, vflipped);
459 for (slice = 0; slice < nslices; slice++) {
460 slice_size = bytestream2_get_le32(&gb);
464 ret = check_slice_size(avctx, src, src_size, slice_size, off);
468 if ((ret = init_get_bits8(&gb2, src + off + 16, slice_size - 16)) < 0)
471 line += decode_slice(&gb2, pic, line, avctx->height - line, lru);
476 if (avctx->height - line) {
477 avpriv_request_sample(avctx, "Not enough slice data available");
480 do_vflip(avctx, pic, vflipped);
486 static int dx2_decode_slice_5x5(GetBitContext *gb, AVFrame *frame,
487 int line, int left, uint8_t lru[3][8],
492 int width = frame->width;
493 int stride = frame->linesize[0];
494 uint8_t *dst = frame->data[0] + stride * line;
496 for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) {
497 for (x = 0; x < width; x++) {
498 b = decode_sym_565(gb, lru[0], 5);
499 g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5);
500 r = decode_sym_565(gb, lru[2], 5);
501 dst[x * 3 + 0] = (r << 3) | (r >> 2);
502 dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
503 dst[x * 3 + 2] = (b << 3) | (b >> 2);
512 static void setup_lru_555(uint8_t lru[3][8])
514 memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
515 memcpy(lru[1], def_lru_555, 8 * sizeof(*def_lru));
516 memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
519 static void setup_lru_565(uint8_t lru[3][8])
521 memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
522 memcpy(lru[1], def_lru_565, 8 * sizeof(*def_lru));
523 memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
526 static int dx2_decode_slice_555(GetBitContext *gb, AVFrame *frame,
527 int line, int left, uint8_t lru[3][8])
529 return dx2_decode_slice_5x5(gb, frame, line, left, lru, 0);
532 static int dx2_decode_slice_565(GetBitContext *gb, AVFrame *frame,
533 int line, int left, uint8_t lru[3][8])
535 return dx2_decode_slice_5x5(gb, frame, line, left, lru, 1);
538 static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
539 const uint8_t *src, int src_size, int is_565,
542 enum AVPixelFormat fmt = AV_PIX_FMT_RGB24;
544 return dxtory_decode_v2(avctx, pic, src, src_size,
545 dx2_decode_slice_565,
549 return dxtory_decode_v2(avctx, pic, src, src_size,
550 dx2_decode_slice_555,
555 static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame,
556 int line, int left, uint8_t lru[3][8])
559 int width = frame->width;
560 int stride = frame->linesize[0];
561 uint8_t *dst = frame->data[0] + stride * line;
563 for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) {
564 for (x = 0; x < width; x++) {
565 dst[x * 3 + 0] = decode_sym(gb, lru[0]);
566 dst[x * 3 + 1] = decode_sym(gb, lru[1]);
567 dst[x * 3 + 2] = decode_sym(gb, lru[2]);
576 static void default_setup_lru(uint8_t lru[3][8])
580 for (i = 0; i < 3; i++)
581 memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
584 static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
585 const uint8_t *src, int src_size,
588 return dxtory_decode_v2(avctx, pic, src, src_size,
589 dx2_decode_slice_rgb,
591 AV_PIX_FMT_BGR24, vflipped);
594 static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,
599 int width = frame->width;
601 int ystride = frame->linesize[0];
602 int ustride = frame->linesize[1];
603 int vstride = frame->linesize[2];
605 uint8_t *Y = frame->data[0] + ystride * line;
606 uint8_t *U = frame->data[1] + (ustride >> 2) * line;
607 uint8_t *V = frame->data[2] + (vstride >> 2) * line;
609 int h, w, hmargin, vmargin;
612 h = frame->height & ~3;
613 w = frame->width & ~3;
614 hmargin = frame->width - w;
615 vmargin = frame->height - h;
616 huvborder = AV_CEIL_RSHIFT(frame->width, 2) - 1;
618 for (y = 0; y < left - 3 && get_bits_left(gb) >= 18 * w / 4 + hmargin * 4 + (!!hmargin * 2); y += 4) {
619 for (x = 0; x < w; x += 4) {
620 for (j = 0; j < 4; j++)
621 for (i = 0; i < 4; i++)
622 Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
623 U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
624 V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
627 for (j = 0; j < 4; j++)
628 for (i = 0; i < hmargin; i++)
629 Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
630 U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80;
631 V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80;
639 if (vmargin && y + vmargin == left) {
640 for (x = 0; x < width; x += 4) {
641 for (j = 0; j < vmargin; j++)
642 for (i = 0; i < 4; i++)
643 Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
644 U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
645 V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
648 for (j = 0; j < vmargin; j++) {
649 for (i = 0; i < hmargin; i++)
650 Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
652 U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80;
653 V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80;
663 static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
664 const uint8_t *src, int src_size,
667 return dxtory_decode_v2(avctx, pic, src, src_size,
668 dx2_decode_slice_410,
670 AV_PIX_FMT_YUV410P, vflipped);
673 static int dx2_decode_slice_420(GetBitContext *gb, AVFrame *frame,
679 int width = frame->width;
681 int ystride = frame->linesize[0];
682 int ustride = frame->linesize[1];
683 int vstride = frame->linesize[2];
685 uint8_t *Y = frame->data[0] + ystride * line;
686 uint8_t *U = frame->data[1] + (ustride >> 1) * line;
687 uint8_t *V = frame->data[2] + (vstride >> 1) * line;
689 int h, w, hmargin, vmargin;
692 h = frame->height & ~1;
693 w = frame->width & ~1;
694 hmargin = frame->width - w;
695 vmargin = frame->height - h;
696 huvborder = AV_CEIL_RSHIFT(frame->width, 1) - 1;
698 for (y = 0; y < left - 1 && get_bits_left(gb) >= 3 * w + hmargin * 4; y += 2) {
699 for (x = 0; x < w; x += 2) {
700 Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
701 Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
702 Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
703 Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
704 U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
705 V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
708 Y[x + 0 * ystride] = decode_sym(gb, lru[0]);
709 Y[x + 1 * ystride] = decode_sym(gb, lru[0]);
710 U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80;
711 V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80;
720 for (x = 0; x < width; x += 2) {
721 Y[x + 0] = decode_sym(gb, lru[0]);
722 U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
723 V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
726 Y[x] = decode_sym(gb, lru[0]);
727 U[huvborder] = decode_sym(gb, lru[1]) ^ 0x80;
728 V[huvborder] = decode_sym(gb, lru[2]) ^ 0x80;
735 static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
736 const uint8_t *src, int src_size,
739 return dxtory_decode_v2(avctx, pic, src, src_size,
740 dx2_decode_slice_420,
742 AV_PIX_FMT_YUV420P, vflipped);
745 static int dx2_decode_slice_444(GetBitContext *gb, AVFrame *frame,
751 int width = frame->width;
753 int ystride = frame->linesize[0];
754 int ustride = frame->linesize[1];
755 int vstride = frame->linesize[2];
757 uint8_t *Y = frame->data[0] + ystride * line;
758 uint8_t *U = frame->data[1] + ustride * line;
759 uint8_t *V = frame->data[2] + vstride * line;
761 for (y = 0; y < left && get_bits_left(gb) >= 3 * width; y++) {
762 for (x = 0; x < width; x++) {
763 Y[x] = decode_sym(gb, lru[0]);
764 U[x] = decode_sym(gb, lru[1]) ^ 0x80;
765 V[x] = decode_sym(gb, lru[2]) ^ 0x80;
776 static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
777 const uint8_t *src, int src_size,
780 return dxtory_decode_v2(avctx, pic, src, src_size,
781 dx2_decode_slice_444,
783 AV_PIX_FMT_YUV444P, vflipped);
786 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
790 const uint8_t *src = avpkt->data;
794 if (avpkt->size < 16) {
795 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
796 return AVERROR_INVALIDDATA;
800 vflipped = !!(type & 0x20);
805 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
806 AV_PIX_FMT_BGR24, 3, vflipped);
810 ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16, vflipped);
814 ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16, vflipped);
818 ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16, vflipped);
822 ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16, vflipped);
826 ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16, vflipped);
830 ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16, vflipped);
834 ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16, vflipped);
838 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
839 AV_PIX_FMT_RGB565LE, 2, vflipped);
843 ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1, vflipped);
849 ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
850 AV_PIX_FMT_RGB555LE, 2, vflipped);
856 ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0, vflipped);
859 avpriv_request_sample(avctx, "Frame header %"PRIX32, type);
860 return AVERROR_PATCHWELCOME;
866 pic->pict_type = AV_PICTURE_TYPE_I;
873 AVCodec ff_dxtory_decoder = {
875 .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
876 .type = AVMEDIA_TYPE_VIDEO,
877 .id = AV_CODEC_ID_DXTORY,
878 .decode = decode_frame,
879 .capabilities = AV_CODEC_CAP_DR1,