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,
00039 const unsigned char *src_end,
00040 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, (src_end - src) * 8);
00048 for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) {
00049 if (get_bits_left(&gb) < 4)
00050 return NULL;
00051 code_table[i] = get_sbits(&gb, 4);
00052 sz += FFABS(code_table[i]);
00053 }
00054 src += (get_bits_count(&gb) + 7) / 8;
00055
00056
00057 for (i = 0; i < 64 && dst_size > 0; i++) {
00058 len = code_table[i];
00059 if (len < 0) {
00060 len = -len;
00061 if (src_end - src < 1)
00062 return NULL;
00063 memset(dst, *src++, FFMIN(len, dst_size));
00064 } else {
00065 if (src_end - src < len)
00066 return NULL;
00067 memcpy(dst, src, FFMIN(len, dst_size));
00068 src += len;
00069 }
00070 dst += len;
00071 dst_size -= len;
00072 }
00073 return src;
00074 }
00075
00076 static const unsigned char *seq_decode_op1(SeqVideoContext *seq,
00077 const unsigned char *src,
00078 const unsigned char *src_end,
00079 unsigned char *dst)
00080 {
00081 const unsigned char *color_table;
00082 int b, i, len, bits;
00083 GetBitContext gb;
00084 unsigned char block[8 * 8];
00085
00086 if (src_end - src < 1)
00087 return NULL;
00088 len = *src++;
00089 if (len & 0x80) {
00090 switch (len & 3) {
00091 case 1:
00092 src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
00093 for (b = 0; b < 8; b++) {
00094 memcpy(dst, &block[b * 8], 8);
00095 dst += seq->frame.linesize[0];
00096 }
00097 break;
00098 case 2:
00099 src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
00100 for (i = 0; i < 8; i++) {
00101 for (b = 0; b < 8; b++)
00102 dst[b * seq->frame.linesize[0]] = block[i * 8 + b];
00103 ++dst;
00104 }
00105 break;
00106 }
00107 } else {
00108 if (len <= 0)
00109 return NULL;
00110 bits = ff_log2_tab[len - 1] + 1;
00111 if (src_end - src < len + 8 * bits)
00112 return NULL;
00113 color_table = src;
00114 src += len;
00115 init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8;
00116 for (b = 0; b < 8; b++) {
00117 for (i = 0; i < 8; i++)
00118 dst[i] = color_table[get_bits(&gb, bits)];
00119 dst += seq->frame.linesize[0];
00120 }
00121 }
00122
00123 return src;
00124 }
00125
00126 static const unsigned char *seq_decode_op2(SeqVideoContext *seq,
00127 const unsigned char *src,
00128 const unsigned char *src_end,
00129 unsigned char *dst)
00130 {
00131 int i;
00132
00133 if (src_end - src < 8 * 8)
00134 return NULL;
00135
00136 for (i = 0; i < 8; i++) {
00137 memcpy(dst, src, 8);
00138 src += 8;
00139 dst += seq->frame.linesize[0];
00140 }
00141
00142 return src;
00143 }
00144
00145 static const unsigned char *seq_decode_op3(SeqVideoContext *seq,
00146 const unsigned char *src,
00147 const unsigned char *src_end,
00148 unsigned char *dst)
00149 {
00150 int pos, offset;
00151
00152 do {
00153 if (src_end - src < 2)
00154 return NULL;
00155 pos = *src++;
00156 offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7);
00157 dst[offset] = *src++;
00158 } while (!(pos & 0x80));
00159
00160 return src;
00161 }
00162
00163 static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size)
00164 {
00165 const unsigned char *data_end = data + data_size;
00166 GetBitContext gb;
00167 int flags, i, j, x, y, op;
00168 unsigned char c[3];
00169 unsigned char *dst;
00170 uint32_t *palette;
00171
00172 flags = *data++;
00173
00174 if (flags & 1) {
00175 palette = (uint32_t *)seq->frame.data[1];
00176 if (data_end - data < 256 * 3)
00177 return AVERROR_INVALIDDATA;
00178 for (i = 0; i < 256; i++) {
00179 for (j = 0; j < 3; j++, data++)
00180 c[j] = (*data << 2) | (*data >> 4);
00181 palette[i] = 0xFF << 24 | AV_RB24(c);
00182 }
00183 seq->frame.palette_has_changed = 1;
00184 }
00185
00186 if (flags & 2) {
00187 if (data_end - data < 128)
00188 return AVERROR_INVALIDDATA;
00189 init_get_bits(&gb, data, 128 * 8); data += 128;
00190 for (y = 0; y < 128; y += 8)
00191 for (x = 0; x < 256; x += 8) {
00192 dst = &seq->frame.data[0][y * seq->frame.linesize[0] + x];
00193 op = get_bits(&gb, 2);
00194 switch (op) {
00195 case 1:
00196 data = seq_decode_op1(seq, data, data_end, dst);
00197 break;
00198 case 2:
00199 data = seq_decode_op2(seq, data, data_end, dst);
00200 break;
00201 case 3:
00202 data = seq_decode_op3(seq, data, data_end, dst);
00203 break;
00204 }
00205 if (!data)
00206 return AVERROR_INVALIDDATA;
00207 }
00208 }
00209 return 0;
00210 }
00211
00212 static av_cold int seqvideo_decode_init(AVCodecContext *avctx)
00213 {
00214 SeqVideoContext *seq = avctx->priv_data;
00215
00216 seq->avctx = avctx;
00217 avctx->pix_fmt = PIX_FMT_PAL8;
00218
00219 avcodec_get_frame_defaults(&seq->frame);
00220 seq->frame.data[0] = NULL;
00221
00222 return 0;
00223 }
00224
00225 static int seqvideo_decode_frame(AVCodecContext *avctx,
00226 void *data, int *data_size,
00227 AVPacket *avpkt)
00228 {
00229 const uint8_t *buf = avpkt->data;
00230 int buf_size = avpkt->size;
00231
00232 SeqVideoContext *seq = avctx->priv_data;
00233
00234 seq->frame.reference = 3;
00235 seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00236 if (avctx->reget_buffer(avctx, &seq->frame)) {
00237 av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n");
00238 return -1;
00239 }
00240
00241 if (seqvideo_decode(seq, buf, buf_size))
00242 return AVERROR_INVALIDDATA;
00243
00244 *data_size = sizeof(AVFrame);
00245 *(AVFrame *)data = seq->frame;
00246
00247 return buf_size;
00248 }
00249
00250 static av_cold int seqvideo_decode_end(AVCodecContext *avctx)
00251 {
00252 SeqVideoContext *seq = avctx->priv_data;
00253
00254 if (seq->frame.data[0])
00255 avctx->release_buffer(avctx, &seq->frame);
00256
00257 return 0;
00258 }
00259
00260 AVCodec ff_tiertexseqvideo_decoder = {
00261 .name = "tiertexseqvideo",
00262 .type = AVMEDIA_TYPE_VIDEO,
00263 .id = CODEC_ID_TIERTEXSEQVIDEO,
00264 .priv_data_size = sizeof(SeqVideoContext),
00265 .init = seqvideo_decode_init,
00266 .close = seqvideo_decode_end,
00267 .decode = seqvideo_decode_frame,
00268 .capabilities = CODEC_CAP_DR1,
00269 .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"),
00270 };