static int tmv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { AVFrame *frame = data; const uint8_t *src = avpkt->data; uint8_t *dst; unsigned char_cols = avctx->width >> 3; unsigned char_rows = avctx->height >> 3; unsigned x, y, fg, bg, c; int ret; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (avpkt->size < 2*char_rows*char_cols) { av_log(avctx, AV_LOG_ERROR, "Input buffer too small, truncated sample?\n"); *got_frame = 0; return AVERROR_INVALIDDATA; } frame->pict_type = AV_PICTURE_TYPE_I; frame->key_frame = 1; dst = frame->data[0]; frame->palette_has_changed = 1; memcpy(frame->data[1], ff_cga_palette, 16 * 4); memset(frame->data[1] + 16 * 4, 0, AVPALETTE_SIZE - 16 * 4); for (y = 0; y < char_rows; y++) { for (x = 0; x < char_cols; x++) { c = *src++; bg = *src >> 4; fg = *src++ & 0xF; ff_draw_pc_font(dst + x * 8, frame->linesize[0], avpriv_cga_font, 8, c, fg, bg); } dst += frame->linesize[0] * 8; } *got_frame = 1; return avpkt->size; }
/** * Draw character to screen */ static void draw_char(AVCodecContext *avctx, int c) { AnsiContext *s = avctx->priv_data; int fg = s->fg; int bg = s->bg; if ((s->attributes & ATTR_BOLD)) fg += 8; if ((s->attributes & ATTR_BLINK)) bg += 8; if ((s->attributes & ATTR_REVERSE)) FFSWAP(int, fg, bg); if ((s->attributes & ATTR_CONCEALED)) fg = bg; ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x, s->frame->linesize[0], s->font, s->font_height, c, fg, bg); s->x += FONT_WIDTH; if (s->x >= avctx->width) { s->x = 0; hscroll(avctx); } }