4 * Copyright (c) 2011 Konstantin Shishkov
6 * This file is part of Libav.
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.
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.
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
25 #include "libavutil/common.h"
26 #include "libavutil/intreadwrite.h"
28 #define BITSTREAM_READER_LE
30 #include "bitstream.h"
31 #include "bytestream.h"
35 static int dxtory_decode_v1_rgb(AVCodecContext
*avctx
, AVFrame
*pic
,
36 const uint8_t *src
, int src_size
,
43 if (src_size
< avctx
->width
* avctx
->height
* bpp
) {
44 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
45 return AVERROR_INVALIDDATA
;
49 if ((ret
= ff_get_buffer(avctx
, pic
, 0)) < 0)
53 for (h
= 0; h
< avctx
->height
; h
++) {
54 memcpy(dst
, src
, avctx
->width
* bpp
);
55 src
+= avctx
->width
* bpp
;
56 dst
+= pic
->linesize
[0];
62 static int dxtory_decode_v1_410(AVCodecContext
*avctx
, AVFrame
*pic
,
63 const uint8_t *src
, int src_size
)
66 uint8_t *Y1
, *Y2
, *Y3
, *Y4
, *U
, *V
;
69 if (src_size
< avctx
->width
* avctx
->height
* 18 / 16) {
70 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
71 return AVERROR_INVALIDDATA
;
74 avctx
->pix_fmt
= AV_PIX_FMT_YUV410P
;
75 if ((ret
= ff_get_buffer(avctx
, pic
, 0)) < 0)
79 Y2
= pic
->data
[0] + pic
->linesize
[0];
80 Y3
= pic
->data
[0] + pic
->linesize
[0] * 2;
81 Y4
= pic
->data
[0] + pic
->linesize
[0] * 3;
84 for (h
= 0; h
< avctx
->height
; h
+= 4) {
85 for (w
= 0; w
< avctx
->width
; w
+= 4) {
86 AV_COPY32(Y1
+ w
, src
);
87 AV_COPY32(Y2
+ w
, src
+ 4);
88 AV_COPY32(Y3
+ w
, src
+ 8);
89 AV_COPY32(Y4
+ w
, src
+ 12);
90 U
[w
>> 2] = src
[16] + 0x80;
91 V
[w
>> 2] = src
[17] + 0x80;
94 Y1
+= pic
->linesize
[0] << 2;
95 Y2
+= pic
->linesize
[0] << 2;
96 Y3
+= pic
->linesize
[0] << 2;
97 Y4
+= pic
->linesize
[0] << 2;
98 U
+= pic
->linesize
[1];
99 V
+= pic
->linesize
[2];
105 static int dxtory_decode_v1_420(AVCodecContext
*avctx
, AVFrame
*pic
,
106 const uint8_t *src
, int src_size
)
109 uint8_t *Y1
, *Y2
, *U
, *V
;
112 if (src_size
< avctx
->width
* avctx
->height
* 3 / 2) {
113 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
114 return AVERROR_INVALIDDATA
;
117 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
118 if ((ret
= ff_get_buffer(avctx
, pic
, 0)) < 0)
122 Y2
= pic
->data
[0] + pic
->linesize
[0];
125 for (h
= 0; h
< avctx
->height
; h
+= 2) {
126 for (w
= 0; w
< avctx
->width
; w
+= 2) {
127 AV_COPY16(Y1
+ w
, src
);
128 AV_COPY16(Y2
+ w
, src
+ 2);
129 U
[w
>> 1] = src
[4] + 0x80;
130 V
[w
>> 1] = src
[5] + 0x80;
133 Y1
+= pic
->linesize
[0] << 1;
134 Y2
+= pic
->linesize
[0] << 1;
135 U
+= pic
->linesize
[1];
136 V
+= pic
->linesize
[2];
142 static int dxtory_decode_v1_444(AVCodecContext
*avctx
, AVFrame
*pic
,
143 const uint8_t *src
, int src_size
)
149 if (src_size
< avctx
->width
* avctx
->height
* 3) {
150 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
151 return AVERROR_INVALIDDATA
;
154 avctx
->pix_fmt
= AV_PIX_FMT_YUV444P
;
155 if ((ret
= ff_get_buffer(avctx
, pic
, 0)) < 0)
161 for (h
= 0; h
< avctx
->height
; h
++) {
162 for (w
= 0; w
< avctx
->width
; w
++) {
164 U
[w
] = *src
++ ^ 0x80;
165 V
[w
] = *src
++ ^ 0x80;
167 Y
+= pic
->linesize
[0];
168 U
+= pic
->linesize
[1];
169 V
+= pic
->linesize
[2];
175 static const uint8_t def_lru
[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
176 static const uint8_t def_lru_555
[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
177 static const uint8_t def_lru_565
[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
179 static inline uint8_t decode_sym(BitstreamContext
*bc
, uint8_t lru
[8])
183 c
= get_unary(bc
, 0, 8);
185 val
= bitstream_read(bc
, 8);
186 memmove(lru
+ 1, lru
, sizeof(*lru
) * (8 - 1));
189 memmove(lru
+ 1, lru
, sizeof(*lru
) * (c
- 1));
196 static int check_slice_size(AVCodecContext
*avctx
,
197 const uint8_t *src
, int src_size
,
198 int slice_size
, int off
)
202 if (slice_size
> src_size
- off
) {
203 av_log(avctx
, AV_LOG_ERROR
,
204 "invalid slice size %d (only %d bytes left)\n",
205 slice_size
, src_size
- off
);
206 return AVERROR_INVALIDDATA
;
208 if (slice_size
<= 16) {
209 av_log(avctx
, AV_LOG_ERROR
, "invalid slice size %d\n",
211 return AVERROR_INVALIDDATA
;
214 cur_slice_size
= AV_RL32(src
+ off
);
215 if (cur_slice_size
!= slice_size
- 16) {
216 av_log(avctx
, AV_LOG_ERROR
,
217 "Slice sizes mismatch: got %d instead of %d\n",
218 cur_slice_size
, slice_size
- 16);
224 static int load_buffer(AVCodecContext
*avctx
,
225 const uint8_t *src
, int src_size
,
227 int *nslices
, int *off
)
229 bytestream2_init(gb
, src
, src_size
);
230 *nslices
= bytestream2_get_le16(gb
);
231 *off
= FFALIGN(*nslices
* 4 + 2, 16);
232 if (src_size
< *off
) {
233 av_log(avctx
, AV_LOG_ERROR
, "no slice data\n");
234 return AVERROR_INVALIDDATA
;
238 avpriv_request_sample(avctx
, "%d slices for %dx%d", *nslices
,
239 avctx
->width
, avctx
->height
);
240 return AVERROR_PATCHWELCOME
;
246 static inline uint8_t decode_sym_565(BitstreamContext
*bc
, uint8_t lru
[8],
251 c
= get_unary(bc
, 0, bits
);
253 val
= bitstream_read(bc
, bits
);
254 memmove(lru
+ 1, lru
, sizeof(*lru
) * (6 - 1));
257 memmove(lru
+ 1, lru
, sizeof(*lru
) * (c
- 1));
264 typedef int (*decode_slice_func
)(BitstreamContext
*bc
, AVFrame
*frame
,
265 int line
, int height
, uint8_t lru
[3][8]);
267 typedef void (*setup_lru_func
)(uint8_t lru
[3][8]);
269 static int dxtory_decode_v2(AVCodecContext
*avctx
, AVFrame
*pic
,
270 const uint8_t *src
, int src_size
,
271 decode_slice_func decode_slice
,
272 setup_lru_func setup_lru
,
273 enum AVPixelFormat fmt
)
277 int nslices
, slice
, line
= 0;
278 uint32_t off
, slice_size
;
282 ret
= load_buffer(avctx
, src
, src_size
, &gb
, &nslices
, &off
);
286 avctx
->pix_fmt
= fmt
;
287 if ((ret
= ff_get_buffer(avctx
, pic
, 0)) < 0)
290 for (slice
= 0; slice
< nslices
; slice
++) {
291 slice_size
= bytestream2_get_le32(&gb
);
295 ret
= check_slice_size(avctx
, src
, src_size
, slice_size
, off
);
299 bitstream_init8(&bc
, src
+ off
+ 16, slice_size
- 16);
301 line
+= decode_slice(&bc
, pic
, line
, avctx
->height
- line
, lru
);
306 if (avctx
->height
- line
) {
307 av_log(avctx
, AV_LOG_VERBOSE
,
308 "Not enough slice data available, "
309 "cropping the frame by %d pixels\n",
310 avctx
->height
- line
);
311 avctx
->height
= line
;
318 static int dx2_decode_slice_5x5(BitstreamContext
*bc
, AVFrame
*frame
,
319 int line
, int left
, uint8_t lru
[3][8],
324 int width
= frame
->width
;
325 int stride
= frame
->linesize
[0];
326 uint8_t *dst
= frame
->data
[0] + stride
* line
;
328 for (y
= 0; y
< left
&& bitstream_bits_left(bc
) > 16; y
++) {
329 for (x
= 0; x
< width
; x
++) {
330 b
= decode_sym_565(bc
, lru
[0], 5);
331 g
= decode_sym_565(bc
, lru
[1], is_565
? 6 : 5);
332 r
= decode_sym_565(bc
, lru
[2], 5);
333 dst
[x
* 3 + 0] = (r
<< 3) | (r
>> 2);
334 dst
[x
* 3 + 1] = is_565
? (g
<< 2) | (g
>> 4) : (g
<< 3) | (g
>> 2);
335 dst
[x
* 3 + 2] = (b
<< 3) | (b
>> 2);
344 static void setup_lru_555(uint8_t lru
[3][8])
346 memcpy(lru
[0], def_lru_555
, 8 * sizeof(*def_lru
));
347 memcpy(lru
[1], def_lru_555
, 8 * sizeof(*def_lru
));
348 memcpy(lru
[2], def_lru_555
, 8 * sizeof(*def_lru
));
351 static void setup_lru_565(uint8_t lru
[3][8])
353 memcpy(lru
[0], def_lru_555
, 8 * sizeof(*def_lru
));
354 memcpy(lru
[1], def_lru_565
, 8 * sizeof(*def_lru
));
355 memcpy(lru
[2], def_lru_555
, 8 * sizeof(*def_lru
));
358 static int dx2_decode_slice_555(BitstreamContext
*bc
, AVFrame
*frame
,
359 int line
, int left
, uint8_t lru
[3][8])
361 return dx2_decode_slice_5x5(bc
, frame
, line
, left
, lru
, 0);
364 static int dx2_decode_slice_565(BitstreamContext
*bc
, AVFrame
*frame
,
365 int line
, int left
, uint8_t lru
[3][8])
367 return dx2_decode_slice_5x5(bc
, frame
, line
, left
, lru
, 1);
370 static int dxtory_decode_v2_565(AVCodecContext
*avctx
, AVFrame
*pic
,
371 const uint8_t *src
, int src_size
, int is_565
)
373 enum AVPixelFormat fmt
= AV_PIX_FMT_RGB24
;
375 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
376 dx2_decode_slice_565
,
380 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
381 dx2_decode_slice_555
,
386 static int dx2_decode_slice_rgb(BitstreamContext
*bc
, AVFrame
*frame
,
387 int line
, int left
, uint8_t lru
[3][8])
390 int width
= frame
->width
;
391 int stride
= frame
->linesize
[0];
392 uint8_t *dst
= frame
->data
[0] + stride
* line
;
394 for (y
= 0; y
< left
&& bitstream_bits_left(bc
) > 16; y
++) {
395 for (x
= 0; x
< width
; x
++) {
396 dst
[x
* 3 + 0] = decode_sym(bc
, lru
[0]);
397 dst
[x
* 3 + 1] = decode_sym(bc
, lru
[1]);
398 dst
[x
* 3 + 2] = decode_sym(bc
, lru
[2]);
407 static void default_setup_lru(uint8_t lru
[3][8])
411 for (i
= 0; i
< 3; i
++)
412 memcpy(lru
[i
], def_lru
, 8 * sizeof(*def_lru
));
415 static int dxtory_decode_v2_rgb(AVCodecContext
*avctx
, AVFrame
*pic
,
416 const uint8_t *src
, int src_size
)
418 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
419 dx2_decode_slice_rgb
,
424 static int dx2_decode_slice_410(BitstreamContext
*bc
, AVFrame
*frame
,
429 int width
= frame
->width
;
431 int ystride
= frame
->linesize
[0];
432 int ustride
= frame
->linesize
[1];
433 int vstride
= frame
->linesize
[2];
435 uint8_t *Y
= frame
->data
[0] + ystride
* line
;
436 uint8_t *U
= frame
->data
[1] + (ustride
>> 2) * line
;
437 uint8_t *V
= frame
->data
[2] + (vstride
>> 2) * line
;
439 for (y
= 0; y
< left
- 3 && bitstream_bits_left(bc
) > 16; y
+= 4) {
440 for (x
= 0; x
< width
; x
+= 4) {
441 for (j
= 0; j
< 4; j
++)
442 for (i
= 0; i
< 4; i
++)
443 Y
[x
+ i
+ j
* ystride
] = decode_sym(bc
, lru
[0]);
444 U
[x
>> 2] = decode_sym(bc
, lru
[1]) ^ 0x80;
445 V
[x
>> 2] = decode_sym(bc
, lru
[2]) ^ 0x80;
457 static int dxtory_decode_v2_410(AVCodecContext
*avctx
, AVFrame
*pic
,
458 const uint8_t *src
, int src_size
)
460 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
461 dx2_decode_slice_410
,
466 static int dx2_decode_slice_420(BitstreamContext
*bc
, AVFrame
*frame
,
472 int width
= frame
->width
;
474 int ystride
= frame
->linesize
[0];
475 int ustride
= frame
->linesize
[1];
476 int vstride
= frame
->linesize
[2];
478 uint8_t *Y
= frame
->data
[0] + ystride
* line
;
479 uint8_t *U
= frame
->data
[1] + (ustride
>> 1) * line
;
480 uint8_t *V
= frame
->data
[2] + (vstride
>> 1) * line
;
483 for (y
= 0; y
< left
- 1 && bitstream_bits_left(bc
) > 16; y
+= 2) {
484 for (x
= 0; x
< width
; x
+= 2) {
485 Y
[x
+ 0 + 0 * ystride
] = decode_sym(bc
, lru
[0]);
486 Y
[x
+ 1 + 0 * ystride
] = decode_sym(bc
, lru
[0]);
487 Y
[x
+ 0 + 1 * ystride
] = decode_sym(bc
, lru
[0]);
488 Y
[x
+ 1 + 1 * ystride
] = decode_sym(bc
, lru
[0]);
489 U
[x
>> 1] = decode_sym(bc
, lru
[1]) ^ 0x80;
490 V
[x
>> 1] = decode_sym(bc
, lru
[2]) ^ 0x80;
501 static int dxtory_decode_v2_420(AVCodecContext
*avctx
, AVFrame
*pic
,
502 const uint8_t *src
, int src_size
)
504 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
505 dx2_decode_slice_420
,
510 static int dx2_decode_slice_444(BitstreamContext
*bc
, AVFrame
*frame
,
516 int width
= frame
->width
;
518 int ystride
= frame
->linesize
[0];
519 int ustride
= frame
->linesize
[1];
520 int vstride
= frame
->linesize
[2];
522 uint8_t *Y
= frame
->data
[0] + ystride
* line
;
523 uint8_t *U
= frame
->data
[1] + ustride
* line
;
524 uint8_t *V
= frame
->data
[2] + vstride
* line
;
526 for (y
= 0; y
< left
&& bitstream_bits_left(bc
) > 16; y
++) {
527 for (x
= 0; x
< width
; x
++) {
528 Y
[x
] = decode_sym(bc
, lru
[0]);
529 U
[x
] = decode_sym(bc
, lru
[1]) ^ 0x80;
530 V
[x
] = decode_sym(bc
, lru
[2]) ^ 0x80;
541 static int dxtory_decode_v2_444(AVCodecContext
*avctx
, AVFrame
*pic
,
542 const uint8_t *src
, int src_size
)
544 return dxtory_decode_v2(avctx
, pic
, src
, src_size
,
545 dx2_decode_slice_444
,
550 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
554 const uint8_t *src
= avpkt
->data
;
557 if (avpkt
->size
< 16) {
558 av_log(avctx
, AV_LOG_ERROR
, "packet too small\n");
559 return AVERROR_INVALIDDATA
;
562 switch (AV_RB32(src
)) {
564 ret
= dxtory_decode_v1_rgb(avctx
, pic
, src
+ 16, avpkt
->size
- 16,
565 AV_PIX_FMT_BGR24
, 3);
568 ret
= dxtory_decode_v2_rgb(avctx
, pic
, src
+ 16, avpkt
->size
- 16);
571 ret
= dxtory_decode_v1_420(avctx
, pic
, src
+ 16, avpkt
->size
- 16);
574 ret
= dxtory_decode_v2_420(avctx
, pic
, src
+ 16, avpkt
->size
- 16);
577 ret
= dxtory_decode_v1_410(avctx
, pic
, src
+ 16, avpkt
->size
- 16);
580 ret
= dxtory_decode_v2_410(avctx
, pic
, src
+ 16, avpkt
->size
- 16);
583 ret
= dxtory_decode_v1_444(avctx
, pic
, src
+ 16, avpkt
->size
- 16);
586 ret
= dxtory_decode_v2_444(avctx
, pic
, src
+ 16, avpkt
->size
- 16);
589 ret
= dxtory_decode_v1_rgb(avctx
, pic
, src
+ 16, avpkt
->size
- 16,
590 AV_PIX_FMT_RGB565LE
, 2);
593 ret
= dxtory_decode_v2_565(avctx
, pic
, src
+ 16, avpkt
->size
- 16, 1);
597 ret
= dxtory_decode_v1_rgb(avctx
, pic
, src
+ 16, avpkt
->size
- 16,
598 AV_PIX_FMT_RGB555LE
, 2);
602 ret
= dxtory_decode_v2_565(avctx
, pic
, src
+ 16, avpkt
->size
- 16, 0);
605 avpriv_request_sample(avctx
, "Frame header %"PRIX32
, AV_RB32(src
));
606 return AVERROR_PATCHWELCOME
;
612 pic
->pict_type
= AV_PICTURE_TYPE_I
;
619 AVCodec ff_dxtory_decoder
= {
621 .long_name
= NULL_IF_CONFIG_SMALL("Dxtory"),
622 .type
= AVMEDIA_TYPE_VIDEO
,
623 .id
= AV_CODEC_ID_DXTORY
,
624 .decode
= decode_frame
,
625 .capabilities
= AV_CODEC_CAP_DR1
,