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"
31 #include "codec_internal.h"
36 static int64_t get_raw_size(enum AVPixelFormat fmt
, int width
, int height
)
39 case AV_PIX_FMT_RGB555LE
:
40 case AV_PIX_FMT_RGB565LE
:
41 return width
* height
* 2LL;
42 case AV_PIX_FMT_RGB24
:
43 case AV_PIX_FMT_BGR24
:
44 case AV_PIX_FMT_YUV444P
:
45 return width
* height
* 3LL;
46 case AV_PIX_FMT_YUV420P
:
47 return (int64_t)(width
* height
) + 2 * AV_CEIL_RSHIFT(width
, 1) * AV_CEIL_RSHIFT(height
, 1);
48 case AV_PIX_FMT_YUV410P
:
49 return (int64_t)(width
* height
) + 2 * AV_CEIL_RSHIFT(width
, 2) * AV_CEIL_RSHIFT(height
, 2);
55 static void do_vflip(AVCodecContext
*avctx
, AVFrame
*pic
, int vflip
)
60 switch (pic
->format
) {
61 case AV_PIX_FMT_YUV444P
:
62 pic
->data
[1] += (avctx
->height
- 1) * pic
->linesize
[1];
63 pic
->linesize
[1] = -pic
->linesize
[1];
64 pic
->data
[2] += (avctx
->height
- 1) * pic
->linesize
[2];
65 pic
->linesize
[2] = -pic
->linesize
[2];
66 case AV_PIX_FMT_RGB555LE
:
67 case AV_PIX_FMT_RGB565LE
:
68 case AV_PIX_FMT_BGR24
:
69 case AV_PIX_FMT_RGB24
:
70 pic
->data
[0] += (avctx
->height
- 1) * pic
->linesize
[0];
71 pic
->linesize
[0] = -pic
->linesize
[0];
73 case AV_PIX_FMT_YUV410P
:
74 pic
->data
[0] += (avctx
->height
- 1) * pic
->linesize
[0];
75 pic
->linesize
[0] = -pic
->linesize
[0];
76 pic
->data
[1] += (AV_CEIL_RSHIFT(avctx
->height
, 2) - 1) * pic
->linesize
[1];
77 pic
->linesize
[1] = -pic
->linesize
[1];
78 pic
->data
[2] += (AV_CEIL_RSHIFT(avctx
->height
, 2) - 1) * pic
->linesize
[2];
79 pic
->linesize
[2] = -pic
->linesize
[2];
81 case AV_PIX_FMT_YUV420P
:
82 pic
->data
[0] += (avctx
->height
- 1) * pic
->linesize
[0];
83 pic
->linesize
[0] = -pic
->linesize
[0];
84 pic
->data
[1] += (AV_CEIL_RSHIFT(avctx
->height
, 1) - 1) * pic
->linesize
[1];
85 pic
->linesize
[1] = -pic
->linesize
[1];
86 pic
->data
[2] += (AV_CEIL_RSHIFT(avctx
->height
, 1) - 1) * pic
->linesize
[2];
87 pic
->linesize
[2] = -pic
->linesize
[2];
92 static int dxtory_decode_v1_rgb(AVCodecContext
*avctx
, AVFrame
*pic
,
93 const uint8_t *src
, int src_size
,
94 int id
, int bpp
, uint32_t vflipped
)
100 if (src_size
< get_raw_size(id
, avctx
->width
, avctx
->height
)) {
101 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
102 return AVERROR_INVALIDDATA
;
106 if ((ret
= ff_thread_get_buffer(avctx
, pic
, 0)) < 0)
109 do_vflip(avctx
, pic
, vflipped
);
112 for (h
= 0; h
< avctx
->height
; h
++) {
113 memcpy(dst
, src
, avctx
->width
* bpp
);
114 src
+= avctx
->width
* bpp
;
115 dst
+= pic
->linesize
[0];
118 do_vflip(avctx
, pic
, vflipped
);
123 static int dxtory_decode_v1_410(AVCodecContext
*avctx
, AVFrame
*pic
,
124 const uint8_t *src
, int src_size
,
128 uint8_t *Y1
, *Y2
, *Y3
, *Y4
, *U
, *V
;
129 int height
, width
, hmargin
, vmargin
;
133 if (src_size
< get_raw_size(AV_PIX_FMT_YUV410P
, avctx
->width
, avctx
->height
)) {
134 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
135 return AVERROR_INVALIDDATA
;
138 avctx
->pix_fmt
= AV_PIX_FMT_YUV410P
;
139 if ((ret
= ff_thread_get_buffer(avctx
, pic
, 0)) < 0)
142 do_vflip(avctx
, pic
, vflipped
);
144 height
= avctx
->height
& ~3;
145 width
= avctx
->width
& ~3;
146 hmargin
= avctx
->width
- width
;
147 vmargin
= avctx
->height
- height
;
148 huvborder
= AV_CEIL_RSHIFT(avctx
->width
, 2) - 1;
151 Y2
= pic
->data
[0] + pic
->linesize
[0];
152 Y3
= pic
->data
[0] + pic
->linesize
[0] * 2;
153 Y4
= pic
->data
[0] + pic
->linesize
[0] * 3;
156 for (h
= 0; h
< height
; h
+= 4) {
157 for (w
= 0; w
< width
; w
+= 4) {
158 AV_COPY32U(Y1
+ w
, src
);
159 AV_COPY32U(Y2
+ w
, src
+ 4);
160 AV_COPY32U(Y3
+ w
, src
+ 8);
161 AV_COPY32U(Y4
+ w
, src
+ 12);
162 U
[w
>> 2] = src
[16] + 0x80;
163 V
[w
>> 2] = src
[17] + 0x80;
167 for (w
= 0; w
< hmargin
; w
++) {
168 Y1
[width
+ w
] = src
[w
];
169 Y2
[width
+ w
] = src
[w
+ hmargin
* 1];
170 Y3
[width
+ w
] = src
[w
+ hmargin
* 2];
171 Y4
[width
+ w
] = src
[w
+ hmargin
* 3];
174 U
[huvborder
] = src
[0] + 0x80;
175 V
[huvborder
] = src
[1] + 0x80;
178 Y1
+= pic
->linesize
[0] * 4;
179 Y2
+= pic
->linesize
[0] * 4;
180 Y3
+= pic
->linesize
[0] * 4;
181 Y4
+= pic
->linesize
[0] * 4;
182 U
+= pic
->linesize
[1];
183 V
+= pic
->linesize
[2];
187 for (w
= 0; w
< width
; w
+= 4) {
188 AV_COPY32U(Y1
+ w
, src
);
190 AV_COPY32U(Y2
+ w
, src
+ 4);
192 AV_COPY32U(Y3
+ w
, src
+ 8);
194 U
[w
>> 2] = src
[0] + 0x80;
195 V
[w
>> 2] = src
[1] + 0x80;
199 for (w
= 0; w
< hmargin
; w
++) {
200 AV_COPY32U(Y1
+ w
, src
);
202 AV_COPY32U(Y2
+ w
, src
+ 4);
204 AV_COPY32U(Y3
+ w
, src
+ 8);
207 U
[huvborder
] = src
[0] + 0x80;
208 V
[huvborder
] = src
[1] + 0x80;
213 do_vflip(avctx
, pic
, vflipped
);
218 static int dxtory_decode_v1_420(AVCodecContext
*avctx
, AVFrame
*pic
,
219 const uint8_t *src
, int src_size
,
223 uint8_t *Y1
, *Y2
, *U
, *V
;
224 int height
, width
, hmargin
, vmargin
;
228 if (src_size
< get_raw_size(AV_PIX_FMT_YUV420P
, avctx
->width
, avctx
->height
)) {
229 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
230 return AVERROR_INVALIDDATA
;
233 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
234 if ((ret
= ff_thread_get_buffer(avctx
, pic
, 0)) < 0)
237 do_vflip(avctx
, pic
, vflipped
);
239 height
= avctx
->height
& ~1;
240 width
= avctx
->width
& ~1;
241 hmargin
= avctx
->width
- width
;
242 vmargin
= avctx
->height
- height
;
243 huvborder
= AV_CEIL_RSHIFT(avctx
->width
, 1) - 1;
246 Y2
= pic
->data
[0] + pic
->linesize
[0];
249 for (h
= 0; h
< height
; h
+= 2) {
250 for (w
= 0; w
< width
; w
+= 2) {
251 AV_COPY16(Y1
+ w
, src
);
252 AV_COPY16(Y2
+ w
, src
+ 2);
253 U
[w
>> 1] = src
[4] + 0x80;
254 V
[w
>> 1] = src
[5] + 0x80;
258 Y1
[width
+ 1] = src
[0];
259 Y2
[width
+ 1] = src
[1];
260 U
[huvborder
] = src
[2] + 0x80;
261 V
[huvborder
] = src
[3] + 0x80;
264 Y1
+= pic
->linesize
[0] * 2;
265 Y2
+= pic
->linesize
[0] * 2;
266 U
+= pic
->linesize
[1];
267 V
+= pic
->linesize
[2];
271 for (w
= 0; w
< width
; w
+= 2) {
272 AV_COPY16U(Y1
+ w
, src
);
273 U
[w
>> 1] = src
[0] + 0x80;
274 V
[w
>> 1] = src
[1] + 0x80;
279 U
[huvborder
] = src
[1] + 0x80;
280 V
[huvborder
] = src
[2] + 0x80;
285 do_vflip(avctx
, pic
, vflipped
);
290 static int dxtory_decode_v1_444(AVCodecContext
*avctx
, AVFrame
*pic
,
291 const uint8_t *src
, int src_size
,
298 if (src_size
< get_raw_size(AV_PIX_FMT_YUV444P
, avctx
->width
, avctx
->height
)) {
299 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
300 return AVERROR_INVALIDDATA
;
303 avctx
->pix_fmt
= AV_PIX_FMT_YUV444P
;
304 if ((ret
= ff_thread_get_buffer(avctx
, pic
, 0)) < 0)
307 do_vflip(avctx
, pic
, vflipped
);
312 for (h
= 0; h
< avctx
->height
; h
++) {
313 for (w
= 0; w
< avctx
->width
; w
++) {
315 U
[w
] = *src
++ ^ 0x80;
316 V
[w
] = *src
++ ^ 0x80;
318 Y
+= pic
->linesize
[0];
319 U
+= pic
->linesize
[1];
320 V
+= pic
->linesize
[2];
323 do_vflip(avctx
, pic
, vflipped
);
328 static const uint8_t def_lru
[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
329 static const uint8_t def_lru_555
[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
330 static const uint8_t def_lru_565
[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
332 static inline uint8_t decode_sym(GetBitContext
*gb
, uint8_t lru
[8])
336 c
= get_unary(gb
, 0, 8);
338 val
= get_bits(gb
, 8);
339 memmove(lru
+ 1, lru
, sizeof(*lru
) * (8 - 1));
342 memmove(lru
+ 1, lru
, sizeof(*lru
) * (c
- 1));
349 static int check_slice_size(AVCodecContext
*avctx
,
350 const uint8_t *src
, int src_size
,
351 int slice_size
, int off
)
355 if (slice_size
> src_size
- off
) {
356 av_log(avctx
, AV_LOG_ERROR
,
357 "invalid slice size %d (only %d bytes left)\n",
358 slice_size
, src_size
- off
);
359 return AVERROR_INVALIDDATA
;
361 if (slice_size
<= 16) {
362 av_log(avctx
, AV_LOG_ERROR
, "invalid slice size %d\n",
364 return AVERROR_INVALIDDATA
;
367 cur_slice_size
= AV_RL32(src
+ off
);
368 if (cur_slice_size
!= slice_size
- 16) {
369 av_log(avctx
, AV_LOG_ERROR
,
370 "Slice sizes mismatch: got %d instead of %d\n",
371 cur_slice_size
, slice_size
- 16);
377 static int load_buffer(AVCodecContext
*avctx
,
378 const uint8_t *src
, int src_size
,
380 int *nslices
, int *off
)
382 bytestream2_init(gb
, src
, src_size
);
383 *nslices
= bytestream2_get_le16(gb
);
384 *off
= FFALIGN(*nslices
* 4 + 2, 16);
385 if (src_size
< *off
) {
386 av_log(avctx
, AV_LOG_ERROR
, "no slice data\n");
387 return AVERROR_INVALIDDATA
;
391 avpriv_request_sample(avctx
, "%d slices for %dx%d", *nslices
,
392 avctx
->width
, avctx
->height
);
393 return AVERROR_PATCHWELCOME
;
399 static inline uint8_t decode_sym_565(GetBitContext
*gb
, uint8_t lru
[8],
404 c
= get_unary(gb
, 0, bits
);
406 val
= get_bits(gb
, bits
);
407 memmove(lru
+ 1, lru
, sizeof(*lru
) * (6 - 1));
410 memmove(lru
+ 1, lru
, sizeof(*lru
) * (c
- 1));
417 typedef int (*decode_slice_func
)(GetBitContext
*gb
, AVFrame
*frame
,
418 int line
, int height
, uint8_t lru
[3][8]);
420 typedef void (*setup_lru_func
)(uint8_t lru
[3][8]);
422 static int dxtory_decode_v2(AVCodecContext
*avctx
, AVFrame
*pic
,
423 const uint8_t *src
, int src_size
,
424 decode_slice_func decode_slice
,
425 setup_lru_func setup_lru
,
426 enum AVPixelFormat fmt
,
429 GetByteContext gb
, gb_check
;
431 int nslices
, slice
, line
= 0;
432 uint32_t off
, slice_size
;
437 ret
= load_buffer(avctx
, src
, src_size
, &gb
, &nslices
, &off
);
443 for (slice
= 0; slice
< nslices
; slice
++) {
444 slice_size
= bytestream2_get_le32(&gb_check
);
446 if (slice_size
<= 16 + (avctx
->height
* avctx
->width
/ (8 * nslices
)))
447 return AVERROR_INVALIDDATA
;
448 off_check
+= slice_size
;
451 if (off_check
- avctx
->discard_damaged_percentage
*off_check
/100 > src_size
)
452 return AVERROR_INVALIDDATA
;
454 avctx
->pix_fmt
= fmt
;
455 if ((ret
= ff_thread_get_buffer(avctx
, pic
, 0)) < 0)
458 do_vflip(avctx
, pic
, vflipped
);
460 for (slice
= 0; slice
< nslices
; slice
++) {
461 slice_size
= bytestream2_get_le32(&gb
);
465 ret
= check_slice_size(avctx
, src
, src_size
, slice_size
, off
);
469 if ((ret
= init_get_bits8(&gb2
, src
+ off
+ 16, slice_size
- 16)) < 0)
472 line
+= decode_slice(&gb2
, pic
, line
, avctx
->height
- line
, lru
);
477 if (avctx
->height
- line
) {
478 avpriv_request_sample(avctx
, "Not enough slice data available");
481 do_vflip(avctx
, pic
, vflipped
);
487 static int dx2_decode_slice_5x5(GetBitContext
*gb
, AVFrame
*frame
,
488 int line
, int left
, uint8_t lru
[3][8],
493 int width
= frame
->width
;
494 int stride
= frame
->linesize
[0];
495 uint8_t *dst
= frame
->data
[0] + stride
* line
;
497 for (y
= 0; y
< left
&& get_bits_left(gb
) >= 3 * width
; y
++) {
498 for (x
= 0; x
< width
; x
++) {
499 b
= decode_sym_565(gb
, lru
[0], 5);
500 g
= decode_sym_565(gb
, lru
[1], is_565
? 6 : 5);
501 r
= decode_sym_565(gb
, lru
[2], 5);
502 dst
[x
* 3 + 0] = (r
<< 3) | (r
>> 2);
503 dst
[x
* 3 + 1] = is_565
? (g
<< 2) | (g
>> 4) : (g
<< 3) | (g
>> 2);
504 dst
[x
* 3 + 2] = (b
<< 3) | (b
>> 2);
513 static void setup_lru_555(uint8_t lru
[3][8])
515 memcpy(lru
[0], def_lru_555
, 8 * sizeof(*def_lru
));
516 memcpy(lru
[1], def_lru_555
, 8 * sizeof(*def_lru
));
517 memcpy(lru
[2], def_lru_555
, 8 * sizeof(*def_lru
));
520 static void setup_lru_565(uint8_t lru
[3][8])
522 memcpy(lru
[0], def_lru_555
, 8 * sizeof(*def_lru
));
523 memcpy(lru
[1], def_lru_565
, 8 * sizeof(*def_lru
));
524 memcpy(lru
[2], def_lru_555
, 8 * sizeof(*def_lru
));
527 static int dx2_decode_slice_555(GetBitContext
*gb
, AVFrame
*frame
,
528 int line
, int left
, uint8_t lru
[3][8])
530 return dx2_decode_slice_5x5(gb
, frame
, line
, left
, lru
, 0);
533 static int dx2_decode_slice_565(GetBitContext
*gb
, AVFrame
*frame
,
534 int line
, int left
, uint8_t lru
[3][8])
536 return dx2_decode_slice_5x5(gb
, frame
, line
, left
, lru
, 1);
539 static int dxtory_decode_v2_565(AVCodecContext
*avctx
, AVFrame
*pic
,
540 const uint8_t *src
, int src_size
, int is_565
,
543 enum AVPixelFormat fmt
= AV_PIX_FMT_RGB24
;
545 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
546 dx2_decode_slice_565
,
550 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
551 dx2_decode_slice_555
,
556 static int dx2_decode_slice_rgb(GetBitContext
*gb
, AVFrame
*frame
,
557 int line
, int left
, uint8_t lru
[3][8])
560 int width
= frame
->width
;
561 int stride
= frame
->linesize
[0];
562 uint8_t *dst
= frame
->data
[0] + stride
* line
;
564 for (y
= 0; y
< left
&& get_bits_left(gb
) >= 3 * width
; y
++) {
565 for (x
= 0; x
< width
; x
++) {
566 dst
[x
* 3 + 0] = decode_sym(gb
, lru
[0]);
567 dst
[x
* 3 + 1] = decode_sym(gb
, lru
[1]);
568 dst
[x
* 3 + 2] = decode_sym(gb
, lru
[2]);
577 static void default_setup_lru(uint8_t lru
[3][8])
581 for (i
= 0; i
< 3; i
++)
582 memcpy(lru
[i
], def_lru
, 8 * sizeof(*def_lru
));
585 static int dxtory_decode_v2_rgb(AVCodecContext
*avctx
, AVFrame
*pic
,
586 const uint8_t *src
, int src_size
,
589 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
590 dx2_decode_slice_rgb
,
592 AV_PIX_FMT_BGR24
, vflipped
);
595 static int dx2_decode_slice_410(GetBitContext
*gb
, AVFrame
*frame
,
600 int width
= frame
->width
;
602 int ystride
= frame
->linesize
[0];
603 int ustride
= frame
->linesize
[1];
604 int vstride
= frame
->linesize
[2];
606 uint8_t *Y
= frame
->data
[0] + ystride
* line
;
607 uint8_t *U
= frame
->data
[1] + (ustride
>> 2) * line
;
608 uint8_t *V
= frame
->data
[2] + (vstride
>> 2) * line
;
610 int h
, w
, hmargin
, vmargin
;
613 h
= frame
->height
& ~3;
614 w
= frame
->width
& ~3;
615 hmargin
= frame
->width
- w
;
616 vmargin
= frame
->height
- h
;
617 huvborder
= AV_CEIL_RSHIFT(frame
->width
, 2) - 1;
619 for (y
= 0; y
< left
- 3 && get_bits_left(gb
) >= 18 * w
/ 4 + hmargin
* 4 + (!!hmargin
* 2); y
+= 4) {
620 for (x
= 0; x
< w
; x
+= 4) {
621 for (j
= 0; j
< 4; j
++)
622 for (i
= 0; i
< 4; i
++)
623 Y
[x
+ i
+ j
* ystride
] = decode_sym(gb
, lru
[0]);
624 U
[x
>> 2] = decode_sym(gb
, lru
[1]) ^ 0x80;
625 V
[x
>> 2] = decode_sym(gb
, lru
[2]) ^ 0x80;
628 for (j
= 0; j
< 4; j
++)
629 for (i
= 0; i
< hmargin
; i
++)
630 Y
[x
+ i
+ j
* ystride
] = decode_sym(gb
, lru
[0]);
631 U
[huvborder
] = decode_sym(gb
, lru
[1]) ^ 0x80;
632 V
[huvborder
] = decode_sym(gb
, lru
[2]) ^ 0x80;
640 if (vmargin
&& y
+ vmargin
== left
) {
641 for (x
= 0; x
< width
; x
+= 4) {
642 for (j
= 0; j
< vmargin
; j
++)
643 for (i
= 0; i
< 4; i
++)
644 Y
[x
+ i
+ j
* ystride
] = decode_sym(gb
, lru
[0]);
645 U
[x
>> 2] = decode_sym(gb
, lru
[1]) ^ 0x80;
646 V
[x
>> 2] = decode_sym(gb
, lru
[2]) ^ 0x80;
649 for (j
= 0; j
< vmargin
; j
++) {
650 for (i
= 0; i
< hmargin
; i
++)
651 Y
[x
+ i
+ j
* ystride
] = decode_sym(gb
, lru
[0]);
653 U
[huvborder
] = decode_sym(gb
, lru
[1]) ^ 0x80;
654 V
[huvborder
] = decode_sym(gb
, lru
[2]) ^ 0x80;
664 static int dxtory_decode_v2_410(AVCodecContext
*avctx
, AVFrame
*pic
,
665 const uint8_t *src
, int src_size
,
668 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
669 dx2_decode_slice_410
,
671 AV_PIX_FMT_YUV410P
, vflipped
);
674 static int dx2_decode_slice_420(GetBitContext
*gb
, AVFrame
*frame
,
680 int width
= frame
->width
;
682 int ystride
= frame
->linesize
[0];
683 int ustride
= frame
->linesize
[1];
684 int vstride
= frame
->linesize
[2];
686 uint8_t *Y
= frame
->data
[0] + ystride
* line
;
687 uint8_t *U
= frame
->data
[1] + (ustride
>> 1) * line
;
688 uint8_t *V
= frame
->data
[2] + (vstride
>> 1) * line
;
690 int h
, w
, hmargin
, vmargin
;
693 h
= frame
->height
& ~1;
694 w
= frame
->width
& ~1;
695 hmargin
= frame
->width
- w
;
696 vmargin
= frame
->height
- h
;
697 huvborder
= AV_CEIL_RSHIFT(frame
->width
, 1) - 1;
699 for (y
= 0; y
< left
- 1 && get_bits_left(gb
) >= 3 * w
+ hmargin
* 4; y
+= 2) {
700 for (x
= 0; x
< w
; x
+= 2) {
701 Y
[x
+ 0 + 0 * ystride
] = decode_sym(gb
, lru
[0]);
702 Y
[x
+ 1 + 0 * ystride
] = decode_sym(gb
, lru
[0]);
703 Y
[x
+ 0 + 1 * ystride
] = decode_sym(gb
, lru
[0]);
704 Y
[x
+ 1 + 1 * ystride
] = decode_sym(gb
, lru
[0]);
705 U
[x
>> 1] = decode_sym(gb
, lru
[1]) ^ 0x80;
706 V
[x
>> 1] = decode_sym(gb
, lru
[2]) ^ 0x80;
709 Y
[x
+ 0 * ystride
] = decode_sym(gb
, lru
[0]);
710 Y
[x
+ 1 * ystride
] = decode_sym(gb
, lru
[0]);
711 U
[huvborder
] = decode_sym(gb
, lru
[1]) ^ 0x80;
712 V
[huvborder
] = decode_sym(gb
, lru
[2]) ^ 0x80;
721 for (x
= 0; x
< width
; x
+= 2) {
722 Y
[x
+ 0] = decode_sym(gb
, lru
[0]);
723 U
[x
>> 1] = decode_sym(gb
, lru
[1]) ^ 0x80;
724 V
[x
>> 1] = decode_sym(gb
, lru
[2]) ^ 0x80;
727 Y
[x
] = decode_sym(gb
, lru
[0]);
728 U
[huvborder
] = decode_sym(gb
, lru
[1]) ^ 0x80;
729 V
[huvborder
] = decode_sym(gb
, lru
[2]) ^ 0x80;
736 static int dxtory_decode_v2_420(AVCodecContext
*avctx
, AVFrame
*pic
,
737 const uint8_t *src
, int src_size
,
740 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
741 dx2_decode_slice_420
,
743 AV_PIX_FMT_YUV420P
, vflipped
);
746 static int dx2_decode_slice_444(GetBitContext
*gb
, AVFrame
*frame
,
752 int width
= frame
->width
;
754 int ystride
= frame
->linesize
[0];
755 int ustride
= frame
->linesize
[1];
756 int vstride
= frame
->linesize
[2];
758 uint8_t *Y
= frame
->data
[0] + ystride
* line
;
759 uint8_t *U
= frame
->data
[1] + ustride
* line
;
760 uint8_t *V
= frame
->data
[2] + vstride
* line
;
762 for (y
= 0; y
< left
&& get_bits_left(gb
) >= 3 * width
; y
++) {
763 for (x
= 0; x
< width
; x
++) {
764 Y
[x
] = decode_sym(gb
, lru
[0]);
765 U
[x
] = decode_sym(gb
, lru
[1]) ^ 0x80;
766 V
[x
] = decode_sym(gb
, lru
[2]) ^ 0x80;
777 static int dxtory_decode_v2_444(AVCodecContext
*avctx
, AVFrame
*pic
,
778 const uint8_t *src
, int src_size
,
781 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
782 dx2_decode_slice_444
,
784 AV_PIX_FMT_YUV444P
, vflipped
);
787 static int decode_frame(AVCodecContext
*avctx
, AVFrame
*pic
,
788 int *got_frame
, AVPacket
*avpkt
)
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
;
871 const FFCodec ff_dxtory_decoder
= {
873 CODEC_LONG_NAME("Dxtory"),
874 .p
.type
= AVMEDIA_TYPE_VIDEO
,
875 .p
.id
= AV_CODEC_ID_DXTORY
,
876 FF_CODEC_DECODE_CB(decode_frame
),
877 .p
.capabilities
= AV_CODEC_CAP_DR1
| AV_CODEC_CAP_FRAME_THREADS
,