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 "get_bits.h"
00030
00031
00032 typedef struct SeqVideoContext {
00033 AVCodecContext *avctx;
00034 AVFrame frame;
00035 } SeqVideoContext;
00036
00037
00038 static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsigned char *dst, int dst_size)
00039 {
00040 int i, len, sz;
00041 GetBitContext gb;
00042 int code_table[64];
00043
00044
00045 init_get_bits(&gb, src, 64 * 8);
00046 for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) {
00047 code_table[i] = get_sbits(&gb, 4);
00048 sz += FFABS(code_table[i]);
00049 }
00050 src += (get_bits_count(&gb) + 7) / 8;
00051
00052
00053 for (i = 0; i < 64 && dst_size > 0; i++) {
00054 len = code_table[i];
00055 if (len < 0) {
00056 len = -len;
00057 memset(dst, *src++, FFMIN(len, dst_size));
00058 } else {
00059 memcpy(dst, src, FFMIN(len, dst_size));
00060 src += len;
00061 }
00062 dst += len;
00063 dst_size -= len;
00064 }
00065 return src;
00066 }
00067
00068 static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
00069 {
00070 const unsigned char *color_table;
00071 int b, i, len, bits;
00072 GetBitContext gb;
00073 unsigned char block[8 * 8];
00074
00075 len = *src++;
00076 if (len & 0x80) {
00077 switch (len & 3) {
00078 case 1:
00079 src = seq_unpack_rle_block(src, block, sizeof(block));
00080 for (b = 0; b < 8; b++) {
00081 memcpy(dst, &block[b * 8], 8);
00082 dst += seq->frame.linesize[0];
00083 }
00084 break;
00085 case 2:
00086 src = seq_unpack_rle_block(src, block, sizeof(block));
00087 for (i = 0; i < 8; i++) {
00088 for (b = 0; b < 8; b++)
00089 dst[b * seq->frame.linesize[0]] = block[i * 8 + b];
00090 ++dst;
00091 }
00092 break;
00093 }
00094 } else {
00095 color_table = src;
00096 src += len;
00097 bits = ff_log2_tab[len - 1] + 1;
00098 init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8;
00099 for (b = 0; b < 8; b++) {
00100 for (i = 0; i < 8; i++)
00101 dst[i] = color_table[get_bits(&gb, bits)];
00102 dst += seq->frame.linesize[0];
00103 }
00104 }
00105
00106 return src;
00107 }
00108
00109 static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
00110 {
00111 int i;
00112
00113 for (i = 0; i < 8; i++) {
00114 memcpy(dst, src, 8);
00115 src += 8;
00116 dst += seq->frame.linesize[0];
00117 }
00118
00119 return src;
00120 }
00121
00122 static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst)
00123 {
00124 int pos, offset;
00125
00126 do {
00127 pos = *src++;
00128 offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7);
00129 dst[offset] = *src++;
00130 } while (!(pos & 0x80));
00131
00132 return src;
00133 }
00134
00135 static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size)
00136 {
00137 GetBitContext gb;
00138 int flags, i, j, x, y, op;
00139 unsigned char c[3];
00140 unsigned char *dst;
00141 uint32_t *palette;
00142
00143 flags = *data++;
00144
00145 if (flags & 1) {
00146 palette = (uint32_t *)seq->frame.data[1];
00147 for (i = 0; i < 256; i++) {
00148 for (j = 0; j < 3; j++, data++)
00149 c[j] = (*data << 2) | (*data >> 4);
00150 palette[i] = AV_RB24(c);
00151 }
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 av_cold 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 AVPacket *avpkt)
00191 {
00192 const uint8_t *buf = avpkt->data;
00193 int buf_size = avpkt->size;
00194
00195 SeqVideoContext *seq = avctx->priv_data;
00196
00197 seq->frame.reference = 1;
00198 seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00199 if (avctx->reget_buffer(avctx, &seq->frame)) {
00200 av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n");
00201 return -1;
00202 }
00203
00204 seqvideo_decode(seq, buf, buf_size);
00205
00206 *data_size = sizeof(AVFrame);
00207 *(AVFrame *)data = seq->frame;
00208
00209 return buf_size;
00210 }
00211
00212 static av_cold int seqvideo_decode_end(AVCodecContext *avctx)
00213 {
00214 SeqVideoContext *seq = avctx->priv_data;
00215
00216 if (seq->frame.data[0])
00217 avctx->release_buffer(avctx, &seq->frame);
00218
00219 return 0;
00220 }
00221
00222 AVCodec tiertexseqvideo_decoder = {
00223 "tiertexseqvideo",
00224 AVMEDIA_TYPE_VIDEO,
00225 CODEC_ID_TIERTEXSEQVIDEO,
00226 sizeof(SeqVideoContext),
00227 seqvideo_decode_init,
00228 NULL,
00229 seqvideo_decode_end,
00230 seqvideo_decode_frame,
00231 CODEC_CAP_DR1,
00232 .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"),
00233 };