2 * Tiertex Limited SEQ Video Decoder
3 * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * @file libavcodec/tiertexseqv.c
24 * Tiertex Limited SEQ video decoder
28 #define ALT_BITSTREAM_READER_LE
32 typedef struct SeqVideoContext
{
33 AVCodecContext
*avctx
;
38 static const unsigned char *seq_unpack_rle_block(const unsigned char *src
, unsigned char *dst
, int dst_size
)
44 /* get the rle codes (at most 64 bytes) */
45 init_get_bits(&gb
, src
, 64 * 8);
46 for (i
= 0, sz
= 0; i
< 64 && sz
< dst_size
; i
++) {
47 code_table
[i
] = get_sbits(&gb
, 4);
48 sz
+= FFABS(code_table
[i
]);
50 src
+= (get_bits_count(&gb
) + 7) / 8;
52 /* do the rle unpacking */
53 for (i
= 0; i
< 64 && dst_size
> 0; i
++) {
57 memset(dst
, *src
++, FFMIN(len
, dst_size
));
59 memcpy(dst
, src
, FFMIN(len
, dst_size
));
68 static const unsigned char *seq_decode_op1(SeqVideoContext
*seq
, const unsigned char *src
, unsigned char *dst
)
70 const unsigned char *color_table
;
73 unsigned char block
[8 * 8];
79 src
= seq_unpack_rle_block(src
, block
, sizeof(block
));
80 for (b
= 0; b
< 8; b
++) {
81 memcpy(dst
, &block
[b
* 8], 8);
82 dst
+= seq
->frame
.linesize
[0];
86 src
= seq_unpack_rle_block(src
, block
, sizeof(block
));
87 for (i
= 0; i
< 8; i
++) {
88 for (b
= 0; b
< 8; b
++)
89 dst
[b
* seq
->frame
.linesize
[0]] = block
[i
* 8 + b
];
97 bits
= ff_log2_tab
[len
- 1] + 1;
98 init_get_bits(&gb
, src
, bits
* 8 * 8); src
+= bits
* 8;
99 for (b
= 0; b
< 8; b
++) {
100 for (i
= 0; i
< 8; i
++)
101 dst
[i
] = color_table
[get_bits(&gb
, bits
)];
102 dst
+= seq
->frame
.linesize
[0];
109 static const unsigned char *seq_decode_op2(SeqVideoContext
*seq
, const unsigned char *src
, unsigned char *dst
)
113 for (i
= 0; i
< 8; i
++) {
116 dst
+= seq
->frame
.linesize
[0];
122 static const unsigned char *seq_decode_op3(SeqVideoContext
*seq
, const unsigned char *src
, unsigned char *dst
)
128 offset
= ((pos
>> 3) & 7) * seq
->frame
.linesize
[0] + (pos
& 7);
129 dst
[offset
] = *src
++;
130 } while (!(pos
& 0x80));
135 static void seqvideo_decode(SeqVideoContext
*seq
, const unsigned char *data
, int data_size
)
138 int flags
, i
, j
, x
, y
, op
;
146 palette
= (uint32_t *)seq
->frame
.data
[1];
147 for (i
= 0; i
< 256; i
++) {
148 for (j
= 0; j
< 3; j
++, data
++)
149 c
[j
] = (*data
<< 2) | (*data
>> 4);
150 palette
[i
] = AV_RB24(c
);
152 seq
->frame
.palette_has_changed
= 1;
156 init_get_bits(&gb
, data
, 128 * 8); data
+= 128;
157 for (y
= 0; y
< 128; y
+= 8)
158 for (x
= 0; x
< 256; x
+= 8) {
159 dst
= &seq
->frame
.data
[0][y
* seq
->frame
.linesize
[0] + x
];
160 op
= get_bits(&gb
, 2);
163 data
= seq_decode_op1(seq
, data
, dst
);
166 data
= seq_decode_op2(seq
, data
, dst
);
169 data
= seq_decode_op3(seq
, data
, dst
);
176 static av_cold
int seqvideo_decode_init(AVCodecContext
*avctx
)
178 SeqVideoContext
*seq
= avctx
->priv_data
;
181 avctx
->pix_fmt
= PIX_FMT_PAL8
;
183 seq
->frame
.data
[0] = NULL
;
188 static int seqvideo_decode_frame(AVCodecContext
*avctx
,
189 void *data
, int *data_size
,
192 const uint8_t *buf
= avpkt
->data
;
193 int buf_size
= avpkt
->size
;
195 SeqVideoContext
*seq
= avctx
->priv_data
;
197 seq
->frame
.reference
= 1;
198 seq
->frame
.buffer_hints
= FF_BUFFER_HINTS_VALID
| FF_BUFFER_HINTS_PRESERVE
| FF_BUFFER_HINTS_REUSABLE
;
199 if (avctx
->reget_buffer(avctx
, &seq
->frame
)) {
200 av_log(seq
->avctx
, AV_LOG_ERROR
, "tiertexseqvideo: reget_buffer() failed\n");
204 seqvideo_decode(seq
, buf
, buf_size
);
206 *data_size
= sizeof(AVFrame
);
207 *(AVFrame
*)data
= seq
->frame
;
212 static av_cold
int seqvideo_decode_end(AVCodecContext
*avctx
)
214 SeqVideoContext
*seq
= avctx
->priv_data
;
216 if (seq
->frame
.data
[0])
217 avctx
->release_buffer(avctx
, &seq
->frame
);
222 AVCodec tiertexseqvideo_decoder
= {
225 CODEC_ID_TIERTEXSEQVIDEO
,
226 sizeof(SeqVideoContext
),
227 seqvideo_decode_init
,
230 seqvideo_decode_frame
,
232 .long_name
= NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"),