FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
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 "
libavutil/intreadwrite.h
"
32
#include "
libavutil/xga_font_data.h
"
33
#include "
avcodec.h
"
34
#include "
cga_data.h
"
35
#include "
bintext.h
"
36
#include "
internal.h
"
37
38
typedef
struct
XbinContext
{
39
AVFrame
*
frame
;
40
int
palette
[16];
41
int
flags
;
42
int
font_height
;
43
const
uint8_t
*
font
;
44
int
x
,
y
;
45
}
XbinContext
;
46
47
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
48
{
49
XbinContext
*
s
= avctx->
priv_data
;
50
uint8_t
*p;
51
int
i;
52
53
avctx->
pix_fmt
=
AV_PIX_FMT_PAL8
;
54
p = avctx->
extradata
;
55
if
(p) {
56
s->
font_height
= p[0];
57
s->
flags
= p[1];
58
p += 2;
59
if
(avctx->
extradata_size
< 2 + (!!(s->
flags
&
BINTEXT_PALETTE
))*3*16
60
+ (!!(s->
flags
&
BINTEXT_FONT
))*s->
font_height
*256) {
61
av_log
(avctx,
AV_LOG_ERROR
,
"not enough extradata\n"
);
62
return
AVERROR_INVALIDDATA
;
63
}
64
}
else
{
65
s->
font_height
= 8;
66
s->
flags
= 0;
67
}
68
69
if
((s->
flags
&
BINTEXT_PALETTE
)) {
70
for
(i = 0; i < 16; i++) {
71
s->
palette
[i] = 0xFF000000 | (
AV_RB24
(p) << 2) | ((
AV_RB24
(p) >> 4) & 0x30303);
72
p += 3;
73
}
74
}
else
{
75
for
(i = 0; i < 16; i++)
76
s->
palette
[i] = 0xFF000000 |
ff_cga_palette
[i];
77
}
78
79
if
((s->
flags
&
BINTEXT_FONT
)) {
80
s->
font
= p;
81
}
else
{
82
switch
(s->
font_height
) {
83
default
:
84
av_log
(avctx,
AV_LOG_WARNING
,
"font height %i not supported\n"
, s->
font_height
);
85
s->
font_height
= 8;
86
case
8:
87
s->
font
=
avpriv_cga_font
;
88
break
;
89
case
16:
90
s->
font
=
avpriv_vga16_font
;
91
break
;
92
}
93
}
94
95
s->
frame
=
av_frame_alloc
();
96
if
(!s->
frame
)
97
return
AVERROR
(ENOMEM);
98
99
return
0;
100
}
101
102
#define DEFAULT_BG_COLOR 0
103
av_unused
static
void
hscroll
(
AVCodecContext
*avctx)
104
{
105
XbinContext
*
s
= avctx->
priv_data
;
106
if
(s->
y
< avctx->
height
- s->
font_height
) {
107
s->
y
+= s->
font_height
;
108
}
else
{
109
memmove(s->
frame
->
data
[0], s->
frame
->
data
[0] + s->
font_height
*s->
frame
->
linesize
[0],
110
(avctx->
height
- s->
font_height
)*s->
frame
->
linesize
[0]);
111
memset(s->
frame
->
data
[0] + (avctx->
height
- s->
font_height
)*s->
frame
->
linesize
[0],
112
DEFAULT_BG_COLOR
, s->
font_height
* s->
frame
->
linesize
[0]);
113
}
114
}
115
116
#define FONT_WIDTH 8
117
118
/**
119
* Draw character to screen
120
*/
121
static
void
draw_char
(
AVCodecContext
*avctx,
int
c
,
int
a
)
122
{
123
XbinContext
*
s
= avctx->
priv_data
;
124
if
(s->
y
> avctx->
height
- s->
font_height
)
125
return
;
126
ff_draw_pc_font
(s->
frame
->
data
[0] + s->
y
* s->
frame
->
linesize
[0] + s->
x
,
127
s->
frame
->
linesize
[0], s->
font
, s->
font_height
, c,
128
a & 0x0F, a >> 4);
129
s->
x
+=
FONT_WIDTH
;
130
if
(s->
x
> avctx->
width
-
FONT_WIDTH
) {
131
s->
x
= 0;
132
s->
y
+= s->
font_height
;
133
}
134
}
135
136
static
int
decode_frame
(
AVCodecContext
*avctx,
137
void
*
data
,
int
*got_frame,
138
AVPacket
*avpkt)
139
{
140
XbinContext
*
s
= avctx->
priv_data
;
141
const
uint8_t
*
buf
= avpkt->
data
;
142
int
buf_size = avpkt->
size
;
143
const
uint8_t
*buf_end = buf+buf_size;
144
int
ret
;
145
146
s->
x
= s->
y
= 0;
147
if
((ret =
ff_reget_buffer
(avctx, s->
frame
)) < 0)
148
return
ret
;
149
s->
frame
->
pict_type
=
AV_PICTURE_TYPE_I
;
150
s->
frame
->
palette_has_changed
= 1;
151
memcpy(s->
frame
->
data
[1], s->
palette
, 16 * 4);
152
153
if
(avctx->
codec_id
==
AV_CODEC_ID_XBIN
) {
154
while
(buf + 2 < buf_end) {
155
int
i,
c
,
a
;
156
int
type
= *buf >> 6;
157
int
count
= (*buf & 0x3F) + 1;
158
buf++;
159
switch
(type) {
160
case
0:
//no compression
161
for
(i = 0; i < count && buf + 1 < buf_end; i++) {
162
draw_char
(avctx, buf[0], buf[1]);
163
buf += 2;
164
}
165
break
;
166
case
1:
//character compression
167
c = *buf++;
168
for
(i = 0; i < count && buf < buf_end; i++)
169
draw_char
(avctx, c, *buf++);
170
break
;
171
case
2:
//attribute compression
172
a = *buf++;
173
for
(i = 0; i < count && buf < buf_end; i++)
174
draw_char
(avctx, *buf++, a);
175
break
;
176
case
3:
//character/attribute compression
177
c = *buf++;
178
a = *buf++;
179
for
(i = 0; i < count && buf < buf_end; i++)
180
draw_char
(avctx, c, a);
181
break
;
182
}
183
}
184
}
else
if
(avctx->
codec_id
==
AV_CODEC_ID_IDF
) {
185
while
(buf + 2 < buf_end) {
186
if
(
AV_RL16
(buf) == 1) {
187
int
i;
188
if
(buf + 6 > buf_end)
189
break
;
190
for
(i = 0; i < buf[2]; i++)
191
draw_char
(avctx, buf[4], buf[5]);
192
buf += 6;
193
}
else
{
194
draw_char
(avctx, buf[0], buf[1]);
195
buf += 2;
196
}
197
}
198
}
else
{
199
while
(buf + 1 < buf_end) {
200
draw_char
(avctx, buf[0], buf[1]);
201
buf += 2;
202
}
203
}
204
205
if
((ret =
av_frame_ref
(data, s->
frame
)) < 0)
206
return
ret
;
207
*got_frame = 1;
208
return
buf_size;
209
}
210
211
static
av_cold
int
decode_end
(
AVCodecContext
*avctx)
212
{
213
XbinContext
*
s
= avctx->
priv_data
;
214
215
av_frame_free
(&s->
frame
);
216
217
return
0;
218
}
219
220
#if CONFIG_BINTEXT_DECODER
221
AVCodec
ff_bintext_decoder = {
222
.
name
=
"bintext"
,
223
.type =
AVMEDIA_TYPE_VIDEO
,
224
.id =
AV_CODEC_ID_BINTEXT
,
225
.priv_data_size =
sizeof
(
XbinContext
),
226
.
init
=
decode_init
,
227
.
close
=
decode_end
,
228
.
decode
=
decode_frame
,
229
.capabilities =
CODEC_CAP_DR1
,
230
.long_name =
NULL_IF_CONFIG_SMALL
(
"Binary text"
),
231
};
232
#endif
233
#if CONFIG_XBIN_DECODER
234
AVCodec
ff_xbin_decoder = {
235
.
name
=
"xbin"
,
236
.type =
AVMEDIA_TYPE_VIDEO
,
237
.id =
AV_CODEC_ID_XBIN
,
238
.priv_data_size =
sizeof
(
XbinContext
),
239
.
init
=
decode_init
,
240
.
close
=
decode_end
,
241
.
decode
=
decode_frame
,
242
.capabilities =
CODEC_CAP_DR1
,
243
.long_name =
NULL_IF_CONFIG_SMALL
(
"eXtended BINary text"
),
244
};
245
#endif
246
#if CONFIG_IDF_DECODER
247
AVCodec
ff_idf_decoder = {
248
.
name
=
"idf"
,
249
.type =
AVMEDIA_TYPE_VIDEO
,
250
.id =
AV_CODEC_ID_IDF
,
251
.priv_data_size =
sizeof
(
XbinContext
),
252
.
init
=
decode_init
,
253
.
close
=
decode_end
,
254
.
decode
=
decode_frame
,
255
.capabilities =
CODEC_CAP_DR1
,
256
.long_name =
NULL_IF_CONFIG_SMALL
(
"iCEDraw text"
),
257
};
258
#endif
Generated on Wed Jul 10 2013 23:47:56 for FFmpeg by
1.8.2