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
24 * Tiertex Limited SEQ video decoder
29 #define ALT_BITSTREAM_READER_LE
30 #include "bitstream.h"
33 typedef struct SeqVideoContext {
34 AVCodecContext *avctx;
36 unsigned int palette[256];
37 unsigned char block[8 * 8];
41 static unsigned char *seq_unpack_rle_block(unsigned char *src, unsigned char *dst, int dst_size)
47 /* get the rle codes (at most 64 bytes) */
48 init_get_bits(&gb, src, 64 * 8);
49 for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) {
50 code_table[i] = get_sbits(&gb, 4);
51 sz += FFABS(code_table[i]);
53 src += (get_bits_count(&gb) + 7) / 8;
55 /* do the rle unpacking */
56 for (i = 0; i < 64 && dst_size > 0; i++) {
60 memset(dst, *src++, FFMIN(len, dst_size));
62 memcpy(dst, src, FFMIN(len, dst_size));
71 static unsigned char *seq_decode_op1(SeqVideoContext *seq, unsigned char *src, unsigned char *dst)
73 unsigned char *color_table;
81 src = seq_unpack_rle_block(src, seq->block, sizeof(seq->block));
82 for (b = 0; b < 8; b++) {
83 memcpy(dst, &seq->block[b * 8], 8);
84 dst += seq->frame.linesize[0];
88 src = seq_unpack_rle_block(src, seq->block, sizeof(seq->block));
89 for (i = 0; i < 8; i++) {
90 for (b = 0; b < 8; b++)
91 dst[b * seq->frame.linesize[0]] = seq->block[i * 8 + b];
99 bits = ff_log2_tab[len - 1] + 1;
100 init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8;
101 for (b = 0; b < 8; b++) {
102 for (i = 0; i < 8; i++)
103 dst[i] = color_table[get_bits(&gb, bits)];
104 dst += seq->frame.linesize[0];
111 static unsigned char *seq_decode_op2(SeqVideoContext *seq, unsigned char *src, unsigned char *dst)
115 for (i = 0; i < 8; i++) {
118 dst += seq->frame.linesize[0];
124 static unsigned char *seq_decode_op3(SeqVideoContext *seq, unsigned char *src, unsigned char *dst)
130 offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7);
131 dst[offset] = *src++;
132 } while (!(pos & 0x80));
137 static void seqvideo_decode(SeqVideoContext *seq, unsigned char *data, int data_size)
140 int flags, i, j, x, y, op;
147 for (i = 0; i < 256; i++) {
148 for (j = 0; j < 3; j++, data++)
149 c[j] = (*data << 2) | (*data >> 4);
150 seq->palette[i] = (c[0] << 16) | (c[1] << 8) | c[2];
152 memcpy(seq->frame.data[1], seq->palette, sizeof(seq->palette));
153 seq->frame.palette_has_changed = 1;
157 init_get_bits(&gb, data, 128 * 8); data += 128;
158 for (y = 0; y < 128; y += 8)
159 for (x = 0; x < 256; x += 8) {
160 dst = &seq->frame.data[0][y * seq->frame.linesize[0] + x];
161 op = get_bits(&gb, 2);
164 data = seq_decode_op1(seq, data, dst);
167 data = seq_decode_op2(seq, data, dst);
170 data = seq_decode_op3(seq, data, dst);
177 static int seqvideo_decode_init(AVCodecContext *avctx)
179 SeqVideoContext *seq = (SeqVideoContext *)avctx->priv_data;
182 avctx->pix_fmt = PIX_FMT_PAL8;
183 avctx->has_b_frames = 0;
185 seq->frame.data[0] = NULL;
190 static int seqvideo_decode_frame(AVCodecContext *avctx,
191 void *data, int *data_size,
192 uint8_t *buf, int buf_size)
195 SeqVideoContext *seq = (SeqVideoContext *)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 int seqvideo_decode_end(AVCodecContext *avctx)
214 SeqVideoContext *seq = (SeqVideoContext *)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,