00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00029 #include <string.h>
00030
00031 #include "avcodec.h"
00032 #include "libavutil/internal.h"
00033
00034 #include "cga_data.h"
00035
00036 typedef struct TMVContext {
00037 AVFrame pic;
00038 } TMVContext;
00039
00040 static int tmv_decode_frame(AVCodecContext *avctx, void *data,
00041 int *data_size, AVPacket *avpkt)
00042 {
00043 TMVContext *tmv = avctx->priv_data;
00044 const uint8_t *src = avpkt->data;
00045 uint8_t *dst;
00046 unsigned char_cols = avctx->width >> 3;
00047 unsigned char_rows = avctx->height >> 3;
00048 unsigned x, y, fg, bg, c;
00049
00050 if (tmv->pic.data[0])
00051 avctx->release_buffer(avctx, &tmv->pic);
00052
00053 if (avctx->get_buffer(avctx, &tmv->pic) < 0) {
00054 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00055 return -1;
00056 }
00057
00058 if (avpkt->size < 2*char_rows*char_cols) {
00059 av_log(avctx, AV_LOG_ERROR,
00060 "Input buffer too small, truncated sample?\n");
00061 *data_size = 0;
00062 return -1;
00063 }
00064
00065 tmv->pic.pict_type = AV_PICTURE_TYPE_I;
00066 tmv->pic.key_frame = 1;
00067 dst = tmv->pic.data[0];
00068
00069 tmv->pic.palette_has_changed = 1;
00070 memcpy(tmv->pic.data[1], ff_cga_palette, 16 * 4);
00071
00072 for (y = 0; y < char_rows; y++) {
00073 for (x = 0; x < char_cols; x++) {
00074 c = *src++;
00075 bg = *src >> 4;
00076 fg = *src++ & 0xF;
00077 ff_draw_pc_font(dst + x * 8, tmv->pic.linesize[0],
00078 ff_cga_font, 8, c, fg, bg);
00079 }
00080 dst += tmv->pic.linesize[0] * 8;
00081 }
00082
00083 *data_size = sizeof(AVFrame);
00084 *(AVFrame *)data = tmv->pic;
00085 return avpkt->size;
00086 }
00087
00088 static av_cold int tmv_decode_init(AVCodecContext *avctx)
00089 {
00090 TMVContext *tmv = avctx->priv_data;
00091 avctx->pix_fmt = PIX_FMT_PAL8;
00092 avcodec_get_frame_defaults(&tmv->pic);
00093 return 0;
00094 }
00095
00096 static av_cold int tmv_decode_close(AVCodecContext *avctx)
00097 {
00098 TMVContext *tmv = avctx->priv_data;
00099
00100 if (tmv->pic.data[0])
00101 avctx->release_buffer(avctx, &tmv->pic);
00102
00103 return 0;
00104 }
00105
00106 AVCodec ff_tmv_decoder = {
00107 .name = "tmv",
00108 .type = AVMEDIA_TYPE_VIDEO,
00109 .id = AV_CODEC_ID_TMV,
00110 .priv_data_size = sizeof(TMVContext),
00111 .init = tmv_decode_init,
00112 .close = tmv_decode_close,
00113 .decode = tmv_decode_frame,
00114 .capabilities = CODEC_CAP_DR1,
00115 .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"),
00116 };