FFmpeg
ansi.c
Go to the documentation of this file.
1 /*
2  * ASCII/ANSI art decoder
3  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * ASCII/ANSI art decoder
25  */
26 
27 #include "libavutil/common.h"
28 #include "libavutil/frame.h"
30 #include "avcodec.h"
31 #include "cga_data.h"
32 #include "codec_internal.h"
33 #include "decode.h"
34 
35 #define ATTR_BOLD 0x01 /**< Bold/Bright-foreground (mode 1) */
36 #define ATTR_FAINT 0x02 /**< Faint (mode 2) */
37 #define ATTR_ITALICS 0x04 /**< Italics (mode 3) */
38 #define ATTR_UNDERLINE 0x08 /**< Underline (mode 4) */
39 #define ATTR_BLINK 0x10 /**< Blink/Bright-background (mode 5) */
40 #define ATTR_REVERSE 0x40 /**< Reverse (mode 7) */
41 #define ATTR_CONCEALED 0x80 /**< Concealed (mode 8) */
42 
43 #define DEFAULT_FG_COLOR 7 /**< CGA color index */
44 #define DEFAULT_BG_COLOR 0
45 #define DEFAULT_SCREEN_MODE 3 /**< 80x25 */
46 
47 #define FONT_WIDTH 8 /**< Font width */
48 
49 /** map ansi color index to cga palette index */
50 static const uint8_t ansi_to_cga[16] = {
51  0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15
52 };
53 
54 typedef struct AnsiContext {
56  int x; /**< x cursor position (pixels) */
57  int y; /**< y cursor position (pixels) */
58  int sx; /**< saved x cursor position (pixels) */
59  int sy; /**< saved y cursor position (pixels) */
60  const uint8_t* font; /**< font */
61  int font_height; /**< font height */
62  int attributes; /**< attribute flags */
63  int fg; /**< foreground color */
64  int bg; /**< background color */
66 
67  /* ansi parser state machine */
68  enum {
73  } state;
74 #define MAX_NB_ARGS 4
76  int nb_args; /**< number of arguments (may exceed MAX_NB_ARGS) */
77 } AnsiContext;
78 
80 {
81  AnsiContext *s = avctx->priv_data;
82  avctx->pix_fmt = AV_PIX_FMT_PAL8;
83 
84  /* defaults */
85  s->font = avpriv_vga16_font;
86  s->font_height = 16;
87  s->fg = DEFAULT_FG_COLOR;
88  s->bg = DEFAULT_BG_COLOR;
89 
90  if (!avctx->width || !avctx->height) {
91  int ret = ff_set_dimensions(avctx, 80 << 3, 25 << 4);
92  if (ret < 0)
93  return ret;
94  } else if (avctx->width % FONT_WIDTH || avctx->height % s->font_height) {
95  av_log(avctx, AV_LOG_ERROR, "Invalid dimensions %d %d\n", avctx->width, avctx->height);
96  return AVERROR(EINVAL);
97  }
98 
99  s->frame = av_frame_alloc();
100  if (!s->frame)
101  return AVERROR(ENOMEM);
102 
103  return 0;
104 }
105 
106 static void set_palette(uint32_t *pal)
107 {
108  int r, g, b;
109  memcpy(pal, ff_cga_palette, 16 * 4);
110  pal += 16;
111 #define COLOR(x) ((x) * 40 + 55)
112  for (r = 0; r < 6; r++)
113  for (g = 0; g < 6; g++)
114  for (b = 0; b < 6; b++)
115  *pal++ = 0xFF000000 | (COLOR(r) << 16) | (COLOR(g) << 8) | COLOR(b);
116 #define GRAY(x) ((x) * 10 + 8)
117  for (g = 0; g < 24; g++)
118  *pal++ = 0xFF000000 | (GRAY(g) << 16) | (GRAY(g) << 8) | GRAY(g);
119 }
120 
121 static void hscroll(AVCodecContext *avctx)
122 {
123  AnsiContext *s = avctx->priv_data;
124  int i;
125 
126  if (s->y <= avctx->height - 2*s->font_height) {
127  s->y += s->font_height;
128  return;
129  }
130 
131  i = 0;
132  for (; i < avctx->height - s->font_height; i++)
133  memcpy(s->frame->data[0] + i * s->frame->linesize[0],
134  s->frame->data[0] + (i + s->font_height) * s->frame->linesize[0],
135  avctx->width);
136  for (; i < avctx->height; i++)
137  memset(s->frame->data[0] + i * s->frame->linesize[0],
138  DEFAULT_BG_COLOR, avctx->width);
139 }
140 
141 static void erase_line(AVCodecContext * avctx, int xoffset, int xlength)
142 {
143  AnsiContext *s = avctx->priv_data;
144  int i;
145  for (i = 0; i < s->font_height; i++)
146  memset(s->frame->data[0] + (s->y + i)*s->frame->linesize[0] + xoffset,
147  DEFAULT_BG_COLOR, xlength);
148 }
149 
150 static void erase_screen(AVCodecContext *avctx)
151 {
152  AnsiContext *s = avctx->priv_data;
153  int i;
154  for (i = 0; i < avctx->height; i++)
155  memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width);
156  s->x = s->y = 0;
157 }
158 
159 /**
160  * Draw character to screen
161  */
162 static void draw_char(AVCodecContext *avctx, int c)
163 {
164  AnsiContext *s = avctx->priv_data;
165  int fg = s->fg;
166  int bg = s->bg;
167 
168  if ((s->attributes & ATTR_BOLD))
169  fg += 8;
170  if ((s->attributes & ATTR_BLINK))
171  bg += 8;
172  if ((s->attributes & ATTR_REVERSE))
173  FFSWAP(int, fg, bg);
174  if ((s->attributes & ATTR_CONCEALED))
175  fg = bg;
176  ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x,
177  s->frame->linesize[0], s->font, s->font_height, c, fg, bg);
178  s->x += FONT_WIDTH;
179  if (s->x > avctx->width - FONT_WIDTH) {
180  s->x = 0;
181  hscroll(avctx);
182  }
183 }
184 
185 /**
186  * Execute ANSI escape code
187  * @return 0 on success, negative on error
188  */
189 static int execute_code(AVCodecContext * avctx, int c)
190 {
191  AnsiContext *s = avctx->priv_data;
192  int ret, i;
193  int width = avctx->width;
194  int height = avctx->height;
195 
196  switch(c) {
197  case 'A': //Cursor Up
198  s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0);
199  break;
200  case 'B': //Cursor Down
201  s->y = FFMIN(s->y + (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), avctx->height - s->font_height);
202  break;
203  case 'C': //Cursor Right
204  s->x = FFMIN(s->x + (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), avctx->width - FONT_WIDTH);
205  break;
206  case 'D': //Cursor Left
207  s->x = FFMAX(s->x - (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), 0);
208  break;
209  case 'H': //Cursor Position
210  case 'f': //Horizontal and Vertical Position
211  s->y = s->nb_args > 0 ? av_clip((s->args[0] - 1)*s->font_height, 0, avctx->height - s->font_height) : 0;
212  s->x = s->nb_args > 1 ? av_clip((s->args[1] - 1)*FONT_WIDTH, 0, avctx->width - FONT_WIDTH) : 0;
213  break;
214  case 'h': //set screen mode
215  case 'l': //reset screen mode
216  if (s->nb_args < 2)
217  s->args[0] = DEFAULT_SCREEN_MODE;
218  switch(s->args[0]) {
219  case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows)
220  s->font = avpriv_cga_font;
221  s->font_height = 8;
222  width = 40<<3;
223  height = 25<<3;
224  break;
225  case 2: case 3: //640x400 (25 rows)
226  s->font = avpriv_vga16_font;
227  s->font_height = 16;
228  width = 80<<3;
229  height = 25<<4;
230  break;
231  case 6: case 14: //640x200 (25 rows)
232  s->font = avpriv_cga_font;
233  s->font_height = 8;
234  width = 80<<3;
235  height = 25<<3;
236  break;
237  case 7: //set line wrapping
238  break;
239  case 15: case 16: //640x350 (43 rows)
240  s->font = avpriv_cga_font;
241  s->font_height = 8;
242  width = 80<<3;
243  height = 43<<3;
244  break;
245  case 17: case 18: //640x480 (60 rows)
246  s->font = avpriv_cga_font;
247  s->font_height = 8;
248  width = 80<<3;
249  height = 60<<4;
250  break;
251  default:
252  avpriv_request_sample(avctx, "Unsupported screen mode");
253  }
254  s->x = av_clip(s->x, 0, width - FONT_WIDTH);
255  s->y = av_clip(s->y, 0, height - s->font_height);
256  if (width != avctx->width || height != avctx->height) {
257  av_frame_unref(s->frame);
258  ret = ff_set_dimensions(avctx, width, height);
259  if (ret < 0)
260  return ret;
261  if ((ret = ff_get_buffer(avctx, s->frame,
263  return ret;
264  s->frame->pict_type = AV_PICTURE_TYPE_I;
265 #if FF_API_PALETTE_HAS_CHANGED
267  s->frame->palette_has_changed = 1;
269 #endif
270  set_palette((uint32_t *)s->frame->data[1]);
271  erase_screen(avctx);
272  } else if (c == 'l') {
273  erase_screen(avctx);
274  }
275  break;
276  case 'J': //Erase in Page
277  switch (s->args[0]) {
278  case 0:
279  erase_line(avctx, s->x, avctx->width - s->x);
280  if (s->y < avctx->height - s->font_height)
281  memset(s->frame->data[0] + (s->y + s->font_height)*s->frame->linesize[0],
282  DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame->linesize[0]);
283  break;
284  case 1:
285  erase_line(avctx, 0, s->x);
286  if (s->y > 0)
287  memset(s->frame->data[0], DEFAULT_BG_COLOR, s->y * s->frame->linesize[0]);
288  break;
289  case 2:
290  erase_screen(avctx);
291  }
292  break;
293  case 'K': //Erase in Line
294  switch(s->args[0]) {
295  case 0:
296  erase_line(avctx, s->x, avctx->width - s->x);
297  break;
298  case 1:
299  erase_line(avctx, 0, s->x);
300  break;
301  case 2:
302  erase_line(avctx, 0, avctx->width);
303  }
304  break;
305  case 'm': //Select Graphics Rendition
306  if (s->nb_args == 0) {
307  s->nb_args = 1;
308  s->args[0] = 0;
309  }
310  for (i = 0; i < FFMIN(s->nb_args, MAX_NB_ARGS); i++) {
311  int m = s->args[i];
312  if (m == 0) {
313  s->attributes = 0;
314  s->fg = DEFAULT_FG_COLOR;
315  s->bg = DEFAULT_BG_COLOR;
316  } else if (m == 1 || m == 2 || m == 3 || m == 4 || m == 5 || m == 7 || m == 8) {
317  s->attributes |= 1 << (m - 1);
318  } else if (m >= 30 && m <= 37) {
319  s->fg = ansi_to_cga[m - 30];
320  } else if (m == 38 && i + 2 < FFMIN(s->nb_args, MAX_NB_ARGS) && s->args[i + 1] == 5 && s->args[i + 2] < 256) {
321  int index = s->args[i + 2];
322  s->fg = index < 16 ? ansi_to_cga[index] : index;
323  i += 2;
324  } else if (m == 39) {
326  } else if (m >= 40 && m <= 47) {
327  s->bg = ansi_to_cga[m - 40];
328  } else if (m == 48 && i + 2 < FFMIN(s->nb_args, MAX_NB_ARGS) && s->args[i + 1] == 5 && s->args[i + 2] < 256) {
329  int index = s->args[i + 2];
330  s->bg = index < 16 ? ansi_to_cga[index] : index;
331  i += 2;
332  } else if (m == 49) {
334  } else {
335  avpriv_request_sample(avctx, "Unsupported rendition parameter");
336  }
337  }
338  break;
339  case 'n': //Device Status Report
340  case 'R': //report current line and column
341  /* ignore */
342  break;
343  case 's': //Save Cursor Position
344  s->sx = s->x;
345  s->sy = s->y;
346  break;
347  case 'u': //Restore Cursor Position
348  s->x = av_clip(s->sx, 0, avctx->width - FONT_WIDTH);
349  s->y = av_clip(s->sy, 0, avctx->height - s->font_height);
350  break;
351  default:
352  avpriv_request_sample(avctx, "Unknown escape code");
353  break;
354  }
355  s->x = av_clip(s->x, 0, avctx->width - FONT_WIDTH);
356  s->y = av_clip(s->y, 0, avctx->height - s->font_height);
357  return 0;
358 }
359 
360 static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
361  int *got_frame, AVPacket *avpkt)
362 {
363  AnsiContext *s = avctx->priv_data;
364  const uint8_t *buf = avpkt->data;
365  int buf_size = avpkt->size;
366  const uint8_t *buf_end = buf+buf_size;
367  int ret, i, count;
368 
369  if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
370  return ret;
371  if (!avctx->frame_num) {
372  for (i=0; i<avctx->height; i++)
373  memset(s->frame->data[0]+ i*s->frame->linesize[0], 0, avctx->width);
374  memset(s->frame->data[1], 0, AVPALETTE_SIZE);
375  }
376 
377  s->frame->pict_type = AV_PICTURE_TYPE_I;
378 #if FF_API_PALETTE_HAS_CHANGED
380  s->frame->palette_has_changed = 1;
382 #endif
383  set_palette((uint32_t *)s->frame->data[1]);
384  if (!s->first_frame) {
385  erase_screen(avctx);
386  s->first_frame = 1;
387  }
388 
389  while(buf < buf_end) {
390  switch(s->state) {
391  case STATE_NORMAL:
392  switch (buf[0]) {
393  case 0x00: //NUL
394  case 0x07: //BEL
395  case 0x1A: //SUB
396  /* ignore */
397  break;
398  case 0x08: //BS
399  s->x = FFMAX(s->x - 1, 0);
400  break;
401  case 0x09: //HT
402  i = s->x / FONT_WIDTH;
403  count = ((i + 8) & ~7) - i;
404  for (i = 0; i < count; i++)
405  draw_char(avctx, ' ');
406  break;
407  case 0x0A: //LF
408  hscroll(avctx);
409  case 0x0D: //CR
410  s->x = 0;
411  break;
412  case 0x0C: //FF
413  erase_screen(avctx);
414  break;
415  case 0x1B: //ESC
416  s->state = STATE_ESCAPE;
417  break;
418  default:
419  draw_char(avctx, buf[0]);
420  }
421  break;
422  case STATE_ESCAPE:
423  if (buf[0] == '[') {
424  s->state = STATE_CODE;
425  s->nb_args = 0;
426  s->args[0] = -1;
427  } else {
428  s->state = STATE_NORMAL;
429  draw_char(avctx, 0x1B);
430  continue;
431  }
432  break;
433  case STATE_CODE:
434  switch(buf[0]) {
435  case '0': case '1': case '2': case '3': case '4':
436  case '5': case '6': case '7': case '8': case '9':
437  if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] < 6553)
438  s->args[s->nb_args] = FFMAX(s->args[s->nb_args], 0) * 10 + buf[0] - '0';
439  break;
440  case ';':
441  if (s->nb_args < MAX_NB_ARGS)
442  s->nb_args++;
443  if (s->nb_args < MAX_NB_ARGS)
444  s->args[s->nb_args] = 0;
445  break;
446  case 'M':
447  s->state = STATE_MUSIC_PREAMBLE;
448  break;
449  case '=': case '?':
450  /* ignore */
451  break;
452  default:
453  if (s->nb_args > MAX_NB_ARGS)
454  av_log(avctx, AV_LOG_WARNING, "args overflow (%i)\n", s->nb_args);
455  if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] >= 0)
456  s->nb_args++;
457  if ((ret = execute_code(avctx, buf[0])) < 0)
458  return ret;
459  s->state = STATE_NORMAL;
460  }
461  break;
462  case STATE_MUSIC_PREAMBLE:
463  if (buf[0] == 0x0E || buf[0] == 0x1B)
464  s->state = STATE_NORMAL;
465  /* ignore music data */
466  break;
467  }
468  buf++;
469  }
470 
471  *got_frame = 1;
472  if ((ret = av_frame_ref(rframe, s->frame)) < 0)
473  return ret;
474  return buf_size;
475 }
476 
478 {
479  AnsiContext *s = avctx->priv_data;
480 
481  av_frame_free(&s->frame);
482  return 0;
483 }
484 
485 static const FFCodecDefault ansi_defaults[] = {
486  { "max_pixels", "640*480" },
487  { NULL },
488 };
489 
491  .p.name = "ansi",
492  CODEC_LONG_NAME("ASCII/ANSI art"),
493  .p.type = AVMEDIA_TYPE_VIDEO,
494  .p.id = AV_CODEC_ID_ANSI,
495  .priv_data_size = sizeof(AnsiContext),
496  .init = decode_init,
497  .close = decode_close,
499  .p.capabilities = AV_CODEC_CAP_DR1,
500  .defaults = ansi_defaults,
501 };
AV_CODEC_ID_ANSI
@ AV_CODEC_ID_ANSI
Definition: codec_id.h:194
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
decode_close
static av_cold int decode_close(AVCodecContext *avctx)
Definition: ansi.c:477
av_clip
#define av_clip
Definition: common.h:96
AnsiContext::state
enum AnsiContext::@17 state
r
const char * r
Definition: vf_curves.c:126
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
ff_cga_palette
const uint32_t ff_cga_palette[16]
Definition: cga_data.c:30
COLOR
#define COLOR(x)
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:100
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
AVPacket::data
uint8_t * data
Definition: packet.h:491
execute_code
static int execute_code(AVCodecContext *avctx, int c)
Execute ANSI escape code.
Definition: ansi.c:189
b
#define b
Definition: input.c:41
AnsiContext::STATE_ESCAPE
@ STATE_ESCAPE
Definition: ansi.c:70
FFCodec
Definition: codec_internal.h:127
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AnsiContext
Definition: ansi.c:54
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:94
AnsiContext::font
const uint8_t * font
font
Definition: ansi.c:60
AnsiContext::sy
int sy
saved y cursor position (pixels)
Definition: ansi.c:59
FFCodecDefault
Definition: codec_internal.h:97
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AnsiContext::first_frame
int first_frame
Definition: ansi.c:65
AnsiContext::nb_args
int nb_args
number of arguments (may exceed MAX_NB_ARGS)
Definition: ansi.c:76
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:88
ff_draw_pc_font
void ff_draw_pc_font(uint8_t *dst, int linesize, const uint8_t *font, int font_height, int ch, int fg, int bg)
Draw CGA/EGA/VGA font to 8-bit pixel buffer.
Definition: cga_data.c:46
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
width
#define width
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:306
AnsiContext::y
int y
y cursor position (pixels)
Definition: ansi.c:57
s
#define s(width, name)
Definition: cbs_vp9.c:198
g
const char * g
Definition: vf_curves.c:127
AV_GET_BUFFER_FLAG_REF
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Definition: avcodec.h:421
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
decode.h
draw_char
static void draw_char(AVCodecContext *avctx, int c)
Draw character to screen.
Definition: ansi.c:162
ATTR_BLINK
#define ATTR_BLINK
Blink/Bright-background (mode 5)
Definition: ansi.c:39
ATTR_CONCEALED
#define ATTR_CONCEALED
Concealed (mode 8)
Definition: ansi.c:41
ATTR_BOLD
#define ATTR_BOLD
Bold/Bright-foreground (mode 1)
Definition: ansi.c:35
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
GRAY
#define GRAY(x)
NULL
#define NULL
Definition: coverity.c:32
DEFAULT_SCREEN_MODE
#define DEFAULT_SCREEN_MODE
80x25
Definition: ansi.c:45
ansi_defaults
static const FFCodecDefault ansi_defaults[]
Definition: ansi.c:485
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
index
int index
Definition: gxfenc.c:89
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AnsiContext::sx
int sx
saved x cursor position (pixels)
Definition: ansi.c:58
AnsiContext::attributes
int attributes
attribute flags
Definition: ansi.c:62
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1617
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:492
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:361
codec_internal.h
MAX_NB_ARGS
#define MAX_NB_ARGS
Definition: ansi.c:74
hscroll
static void hscroll(AVCodecContext *avctx)
Definition: ansi.c:121
AnsiContext::STATE_NORMAL
@ STATE_NORMAL
Definition: ansi.c:69
frame.h
cga_data.h
erase_line
static void erase_line(AVCodecContext *avctx, int xoffset, int xlength)
Definition: ansi.c:141
height
#define height
DEFAULT_FG_COLOR
#define DEFAULT_FG_COLOR
CGA color index.
Definition: ansi.c:43
xga_font_data.h
AnsiContext::frame
AVFrame * frame
Definition: ansi.c:55
avpriv_vga16_font
const uint8_t avpriv_vga16_font[4096]
Definition: xga_font_data.c:160
set_palette
static void set_palette(uint32_t *pal)
Definition: ansi.c:106
ATTR_REVERSE
#define ATTR_REVERSE
Reverse (mode 7)
Definition: ansi.c:40
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
DEFAULT_BG_COLOR
#define DEFAULT_BG_COLOR
Definition: ansi.c:44
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:622
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
decode_frame
static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
Definition: ansi.c:360
AVCodecContext::height
int height
Definition: avcodec.h:621
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:658
AnsiContext::bg
int bg
background color
Definition: ansi.c:64
avcodec.h
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
AVCodecContext::frame_num
int64_t frame_num
Frame counter, set by libavcodec.
Definition: avcodec.h:2118
ff_reget_buffer
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition: decode.c:1735
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
FONT_WIDTH
#define FONT_WIDTH
Font width.
Definition: ansi.c:47
AnsiContext::fg
int fg
foreground color
Definition: ansi.c:63
AVCodecContext
main external API structure.
Definition: avcodec.h:441
AnsiContext::STATE_MUSIC_PREAMBLE
@ STATE_MUSIC_PREAMBLE
Definition: ansi.c:72
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
ff_ansi_decoder
const FFCodec ff_ansi_decoder
Definition: ansi.c:490
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
avpriv_cga_font
const uint8_t avpriv_cga_font[2048]
Definition: xga_font_data.c:29
AVPacket
This structure stores compressed data.
Definition: packet.h:468
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:468
AnsiContext::args
int args[MAX_NB_ARGS]
Definition: ansi.c:75
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:621
AnsiContext::x
int x
x cursor position (pixels)
Definition: ansi.c:56
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AnsiContext::font_height
int font_height
font height
Definition: ansi.c:61
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: ansi.c:79
AnsiContext::STATE_CODE
@ STATE_CODE
Definition: ansi.c:71
erase_screen
static void erase_screen(AVCodecContext *avctx)
Definition: ansi.c:150
ansi_to_cga
static const uint8_t ansi_to_cga[16]
map ansi color index to cga palette index
Definition: ansi.c:50