00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #define ALT_BITSTREAM_READER_LE
00029 #include "bitstream.h"
00030
00031
00032 typedef struct SeqVideoContext {
00033 AVCodecContext *avctx;
00034 AVFrame frame;
00035 unsigned int palette[256];
00036 unsigned char block[8 * 8];
00037 } SeqVideoContext;
00038
00039
00040 static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsigned char *dst, int dst_size)
00041 {
00042 int i, len, sz;
00043 GetBitContext gb;
00044 int code_table[64];
00045
00046
00047 init_get_bits(&gb, src, 64 * 8);
00048 for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) {
00049 code_table[i] = get_sbits(&gb, 4);
00050 sz += FFABS(code_table[i]);
00051 }
00052 src += (get_bits_count(&gb) + 7) / 8;
00053
00054
00055 for (i = 0; i < 64 && dst_size > 0; i++) {
00056 len = code_table[i];
00057 if (len < 0) {
00058 len = -len;
00059 memset(dst, *src++, FFMIN(len, dst_size));
00060 } else {
00061 memcpy(dst, src, FFMIN(len, dst_size));
00062 src += len;
00063 }
00064 dst += len;
00065 dst_size -= len;
00066 }
00067 return src;
00068 }
00069
00070 static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
00071 {
00072 const unsigned char *color_table;
00073 int b, i, len, bits;
00074 GetBitContext gb;
00075
00076 len = *src++;
00077 if (len & 0x80) {
00078 switch (len & 3) {
00079 case 1:
00080 src = seq_unpack_rle_block(src, seq->block, sizeof(seq->block));
00081 for (b = 0; b < 8; b++) {
00082 memcpy(dst, &seq->block[b * 8], 8);
00083 dst += seq->frame.linesize[0];
00084 }
00085 break;
00086 case 2:
00087 src = seq_unpack_rle_block(src, seq->block, sizeof(seq->block));
00088 for (i = 0; i < 8; i++) {
00089 for (b = 0; b < 8; b++)
00090 dst[b * seq->frame.linesize[0]] = seq->block[i * 8 + b];
00091 ++dst;
00092 }
00093 break;
00094 }
00095 } else {
00096 color_table = src;
00097 src += len;
00098 bits = ff_log2_tab[len - 1] + 1;
00099 init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8;
00100 for (b = 0; b < 8; b++) {
00101 for (i = 0; i < 8; i++)
00102 dst[i] = color_table[get_bits(&gb, bits)];
00103 dst += seq->frame.linesize[0];
00104 }
00105 }
00106
00107 return src;
00108 }
00109
00110 static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
00111 {
00112 int i;
00113
00114 for (i = 0; i < 8; i++) {
00115 memcpy(dst, src, 8);
00116 src += 8;
00117 dst += seq->frame.linesize[0];
00118 }
00119
00120 return src;
00121 }
00122
00123 static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
00124 {
00125 int pos, offset;
00126
00127 do {
00128 pos = *src++;
00129 offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7);
00130 dst[offset] = *src++;
00131 } while (!(pos & 0x80));
00132
00133 return src;
00134 }
00135
00136 static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size)
00137 {
00138 GetBitContext gb;
00139 int flags, i, j, x, y, op;
00140 unsigned char c[3];
00141 unsigned char *dst;
00142
00143 flags = *data++;
00144
00145 if (flags & 1) {
00146 for (i = 0; i < 256; i++) {
00147 for (j = 0; j < 3; j++, data++)
00148 c[j] = (*data << 2) | (*data >> 4);
00149 seq->palette[i] = AV_RB24(c);
00150 }
00151 memcpy(seq->frame.data[1], seq->palette, sizeof(seq->palette));
00152 seq->frame.palette_has_changed = 1;
00153 }
00154
00155 if (flags & 2) {
00156 init_get_bits(&gb, data, 128 * 8); data += 128;
00157 for (y = 0; y < 128; y += 8)
00158 for (x = 0; x < 256; x += 8) {
00159 dst = &seq->frame.data[0][y * seq->frame.linesize[0] + x];
00160 op = get_bits(&gb, 2);
00161 switch (op) {
00162 case 1:
00163 data = seq_decode_op1(seq, data, dst);
00164 break;
00165 case 2:
00166 data = seq_decode_op2(seq, data, dst);
00167 break;
00168 case 3:
00169 data = seq_decode_op3(seq, data, dst);
00170 break;
00171 }
00172 }
00173 }
00174 }
00175
00176 static int seqvideo_decode_init(AVCodecContext *avctx)
00177 {
00178 SeqVideoContext *seq = avctx->priv_data;
00179
00180 seq->avctx = avctx;
00181 avctx->pix_fmt = PIX_FMT_PAL8;
00182
00183 seq->frame.data[0] = NULL;
00184
00185 return 0;
00186 }
00187
00188 static int seqvideo_decode_frame(AVCodecContext *avctx,
00189 void *data, int *data_size,
00190 const uint8_t *buf, int buf_size)
00191 {
00192
00193 SeqVideoContext *seq = avctx->priv_data;
00194
00195 seq->frame.reference = 1;
00196 seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00197 if (avctx->reget_buffer(avctx, &seq->frame)) {
00198 av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n");
00199 return -1;
00200 }
00201
00202 seqvideo_decode(seq, buf, buf_size);
00203
00204 *data_size = sizeof(AVFrame);
00205 *(AVFrame *)data = seq->frame;
00206
00207 return buf_size;
00208 }
00209
00210 static int seqvideo_decode_end(AVCodecContext *avctx)
00211 {
00212 SeqVideoContext *seq = avctx->priv_data;
00213
00214 if (seq->frame.data[0])
00215 avctx->release_buffer(avctx, &seq->frame);
00216
00217 return 0;
00218 }
00219
00220 AVCodec tiertexseqvideo_decoder = {
00221 "tiertexseqvideo",
00222 CODEC_TYPE_VIDEO,
00223 CODEC_ID_TIERTEXSEQVIDEO,
00224 sizeof(SeqVideoContext),
00225 seqvideo_decode_init,
00226 NULL,
00227 seqvideo_decode_end,
00228 seqvideo_decode_frame,
00229 CODEC_CAP_DR1,
00230 };