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