FFmpeg
Loading...
Searching...
No Matches
bintext.c
Go to the documentation of this file.
1/*
2 * Binary text decoder
3 * eXtended BINary text (XBIN) decoder
4 * iCEDraw File decoder
5 * Copyright (c) 2010 Peter Ross (pross@xvid.org)
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24/**
25 * @file
26 * Binary text decoder
27 * eXtended BINary text (XBIN) decoder
28 * iCEDraw File decoder
29 */
30
31#include "config_components.h"
32
36#include "avcodec.h"
37#include "cga_data.h"
38#include "bintext.h"
39#include "codec_internal.h"
40#include "decode.h"
41
42#define FONT_WIDTH 8
43
44typedef struct XbinContext {
46 int palette[16];
47 int flags;
49 const uint8_t *font;
50 int x, y;
52
54{
55 XbinContext *s = avctx->priv_data;
56 uint8_t *p;
57 int i;
58
59 avctx->pix_fmt = AV_PIX_FMT_PAL8;
60 p = avctx->extradata;
61 if (p) {
62 s->font_height = p[0];
63 s->flags = p[1];
64 p += 2;
65 if(avctx->extradata_size < 2 + (!!(s->flags & BINTEXT_PALETTE))*3*16
66 + (!!(s->flags & BINTEXT_FONT))*s->font_height*256) {
67 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
69 }
70 if (!s->font_height) {
71 av_log(avctx, AV_LOG_ERROR, "invalid font height\n");
73 }
74 } else {
75 s->font_height = 8;
76 s->flags = 0;
77 }
78
79 if ((s->flags & BINTEXT_PALETTE)) {
80 for (i = 0; i < 16; i++) {
81 s->palette[i] = 0xFF000000 | (AV_RB24(p) << 2) | ((AV_RB24(p) >> 4) & 0x30303);
82 p += 3;
83 }
84 } else {
85 for (i = 0; i < 16; i++)
86 s->palette[i] = 0xFF000000 | ff_cga_palette[i];
87 }
88
89 if ((s->flags & BINTEXT_FONT)) {
90 s->font = p;
91 } else {
92 switch(s->font_height) {
93 default:
94 av_log(avctx, AV_LOG_WARNING, "font height %i not supported\n", s->font_height);
95 s->font_height = 8;
97 case 8:
98 s->font = avpriv_cga_font_get();
99 break;
100 case 16:
101 s->font = avpriv_vga16_font_get();
102 break;
103 }
104 }
105 if (avctx->width < FONT_WIDTH || avctx->height < s->font_height) {
106 av_log(avctx, AV_LOG_ERROR, "Resolution too small for font.\n");
107 return AVERROR_INVALIDDATA;
108 }
109
110 return 0;
111}
112
113#define DEFAULT_BG_COLOR 0
115{
116 XbinContext *s = avctx->priv_data;
117 if (s->y < avctx->height - s->font_height) {
118 s->y += s->font_height;
119 } else {
120 memmove(s->frame->data[0], s->frame->data[0] + s->font_height*s->frame->linesize[0],
121 (avctx->height - s->font_height)*s->frame->linesize[0]);
122 memset(s->frame->data[0] + (avctx->height - s->font_height)*s->frame->linesize[0],
123 DEFAULT_BG_COLOR, s->font_height * s->frame->linesize[0]);
124 }
125}
126
127/**
128 * Draw character to screen
129 */
130static void draw_char(AVCodecContext *avctx, int c, int a)
131{
132 XbinContext *s = avctx->priv_data;
133 if (s->y > avctx->height - s->font_height)
134 return;
135 ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x,
136 s->frame->linesize[0], s->font, s->font_height, c,
137 a & 0x0F, a >> 4);
138 s->x += FONT_WIDTH;
139 if (s->x > avctx->width - FONT_WIDTH) {
140 s->x = 0;
141 s->y += s->font_height;
142 }
143}
144
146 int *got_frame, AVPacket *avpkt)
147{
148 XbinContext *s = avctx->priv_data;
149 const uint8_t *buf = avpkt->data;
150 int buf_size = avpkt->size;
151 const uint8_t *buf_end = buf+buf_size;
152 int ret;
153
154 if ((avctx->width / FONT_WIDTH) * (avctx->height / s->font_height) / 256 > buf_size)
155 return AVERROR_INVALIDDATA;
156
157 s->frame = frame;
158 s->x = s->y = 0;
159 if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
160 return ret;
161 s->frame->pict_type = AV_PICTURE_TYPE_I;
162 memcpy(s->frame->data[1], s->palette, 16 * 4);
163
164 if (avctx->codec_id == AV_CODEC_ID_XBIN) {
165 while (buf + 2 < buf_end) {
166 int i,c,a;
167 int type = *buf >> 6;
168 int count = (*buf & 0x3F) + 1;
169 buf++;
170 switch (type) {
171 case 0: //no compression
172 for (i = 0; i < count && buf + 1 < buf_end; i++) {
173 draw_char(avctx, buf[0], buf[1]);
174 buf += 2;
175 }
176 break;
177 case 1: //character compression
178 c = *buf++;
179 for (i = 0; i < count && buf < buf_end; i++)
180 draw_char(avctx, c, *buf++);
181 break;
182 case 2: //attribute compression
183 a = *buf++;
184 for (i = 0; i < count && buf < buf_end; i++)
185 draw_char(avctx, *buf++, a);
186 break;
187 case 3: //character/attribute compression
188 c = *buf++;
189 a = *buf++;
190 for (i = 0; i < count && buf < buf_end; i++)
191 draw_char(avctx, c, a);
192 break;
193 }
194 }
195 } else if (avctx->codec_id == AV_CODEC_ID_IDF) {
196 while (buf + 2 < buf_end) {
197 if (AV_RL16(buf) == 1) {
198 int i;
199 if (buf + 6 > buf_end)
200 break;
201 for (i = 0; i < buf[2]; i++)
202 draw_char(avctx, buf[4], buf[5]);
203 buf += 6;
204 } else {
205 draw_char(avctx, buf[0], buf[1]);
206 buf += 2;
207 }
208 }
209 } else {
210 while (buf + 1 < buf_end) {
211 draw_char(avctx, buf[0], buf[1]);
212 buf += 2;
213 }
214 }
215
216 *got_frame = 1;
217 return buf_size;
218}
219
220#if CONFIG_BINTEXT_DECODER
222 .p.name = "bintext",
223 CODEC_LONG_NAME("Binary text"),
224 .p.type = AVMEDIA_TYPE_VIDEO,
225 .p.id = AV_CODEC_ID_BINTEXT,
226 .priv_data_size = sizeof(XbinContext),
227 .init = decode_init,
229 .p.capabilities = AV_CODEC_CAP_DR1,
230};
231#endif
232#if CONFIG_XBIN_DECODER
233const FFCodec ff_xbin_decoder = {
234 .p.name = "xbin",
235 CODEC_LONG_NAME("eXtended BINary text"),
236 .p.type = AVMEDIA_TYPE_VIDEO,
237 .p.id = AV_CODEC_ID_XBIN,
238 .priv_data_size = sizeof(XbinContext),
239 .init = decode_init,
241 .p.capabilities = AV_CODEC_CAP_DR1,
242};
243#endif
244#if CONFIG_IDF_DECODER
245const FFCodec ff_idf_decoder = {
246 .p.name = "idf",
247 CODEC_LONG_NAME("iCEDraw text"),
248 .p.type = AVMEDIA_TYPE_VIDEO,
249 .p.id = AV_CODEC_ID_IDF,
250 .priv_data_size = sizeof(XbinContext),
251 .init = decode_init,
253 .p.capabilities = AV_CODEC_CAP_DR1,
254};
255#endif
const FFCodec ff_idf_decoder
const FFCodec ff_xbin_decoder
const FFCodec ff_bintext_decoder
#define DEFAULT_BG_COLOR
Definition ansi.c:45
#define FONT_WIDTH
Font width.
Definition ansi.c:48
Libavcodec external API header.
Binary text decoder.
#define BINTEXT_FONT
Definition bintext.h:35
#define BINTEXT_PALETTE
Definition bintext.h:34
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
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
const uint32_t ff_cga_palette[16]
Definition cga_data.c:30
CGA/EGA/VGA ROM data.
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_IDF
Definition codec_id.h:602
@ AV_CODEC_ID_XBIN
Definition codec_id.h:601
@ AV_CODEC_ID_BINTEXT
Definition codec_id.h:600
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AV_PICTURE_TYPE_I
Intra.
Definition avutil.h:278
int a
cl_device_type type
#define AV_RL16(p)
#define AV_RB24(x)
static av_cold int decode_init(AVCodecContext *avctx)
Definition 4xm.c:998
static int decode_frame(AVCodecContext *avctx, AVFrame *picture, int *got_frame, AVPacket *avpkt)
Definition 4xm.c:837
static av_unused void hscroll(AVCodecContext *avctx)
Definition bintext.c:114
static int decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition bintext.c:145
static av_cold int decode_init(AVCodecContext *avctx)
Definition bintext.c:53
static void draw_char(AVCodecContext *avctx, int c, int a)
Draw character to screen.
Definition bintext.c:130
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define av_unused
Definition attributes.h:164
#define av_cold
Definition attributes.h:117
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition pixfmt.h:84
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
enum AVCodecID codec_id
Definition avcodec.h:453
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
int flags
Definition bintext.c:47
int font_height
Definition bintext.c:48
int palette[16]
Definition bintext.c:46
const uint8_t * font
Definition bintext.c:49
AVFrame * frame
Definition bintext.c:45
#define av_log(a,...)
static double c[64]
const uint8_t * avpriv_vga16_font_get(void)
const uint8_t * avpriv_cga_font_get(void)
CGA/EGA/VGA ROM font data.