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