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