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
.long_name =
NULL_IF_CONFIG_SMALL
(
"Binary text"
),
224
.type =
AVMEDIA_TYPE_VIDEO
,
225
.id =
AV_CODEC_ID_BINTEXT
,
226
.priv_data_size =
sizeof
(
XbinContext
),
227
.
init
=
decode_init
,
228
.
close
=
decode_end
,
229
.
decode
=
decode_frame
,
230
.capabilities =
CODEC_CAP_DR1
,
231
};
232
#endif
233
#if CONFIG_XBIN_DECODER
234
AVCodec
ff_xbin_decoder = {
235
.
name
=
"xbin"
,
236
.long_name =
NULL_IF_CONFIG_SMALL
(
"eXtended BINary text"
),
237
.type =
AVMEDIA_TYPE_VIDEO
,
238
.id =
AV_CODEC_ID_XBIN
,
239
.priv_data_size =
sizeof
(
XbinContext
),
240
.
init
=
decode_init
,
241
.
close
=
decode_end
,
242
.
decode
=
decode_frame
,
243
.capabilities =
CODEC_CAP_DR1
,
244
};
245
#endif
246
#if CONFIG_IDF_DECODER
247
AVCodec
ff_idf_decoder = {
248
.
name
=
"idf"
,
249
.long_name =
NULL_IF_CONFIG_SMALL
(
"iCEDraw text"
),
250
.type =
AVMEDIA_TYPE_VIDEO
,
251
.id =
AV_CODEC_ID_IDF
,
252
.priv_data_size =
sizeof
(
XbinContext
),
253
.
init
=
decode_init
,
254
.
close
=
decode_end
,
255
.
decode
=
decode_frame
,
256
.capabilities =
CODEC_CAP_DR1
,
257
};
258
#endif
Generated on Sun Mar 23 2014 23:49:52 for FFmpeg by
1.8.2