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
msrle.c
Go to the documentation of this file.
1
/*
2
* Microsoft RLE video decoder
3
* Copyright (C) 2003 the ffmpeg project
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
/**
23
* @file
24
* MS RLE video decoder by Mike Melanson (melanson@pcisys.net)
25
* For more information about the MS RLE format, visit:
26
* http://www.pcisys.net/~melanson/codecs/
27
*
28
* The MS RLE decoder outputs PAL8 colorspace data.
29
*/
30
31
#include <stdio.h>
32
#include <stdlib.h>
33
#include <string.h>
34
35
#include "
avcodec.h
"
36
#include "
msrledec.h
"
37
38
typedef
struct
MsrleContext
{
39
AVCodecContext
*
avctx
;
40
AVFrame
frame
;
41
42
GetByteContext
gb
;
43
const
unsigned
char
*
buf
;
44
int
size
;
45
46
uint32_t
pal
[256];
47
}
MsrleContext
;
48
49
static
av_cold
int
msrle_decode_init
(
AVCodecContext
*avctx)
50
{
51
MsrleContext
*s = avctx->
priv_data
;
52
int
i;
53
54
s->
avctx
= avctx;
55
56
switch
(avctx->
bits_per_coded_sample
) {
57
case
1:
58
avctx->
pix_fmt
=
AV_PIX_FMT_MONOWHITE
;
59
break
;
60
case
4:
61
case
8:
62
avctx->
pix_fmt
=
AV_PIX_FMT_PAL8
;
63
break
;
64
case
24:
65
avctx->
pix_fmt
=
AV_PIX_FMT_BGR24
;
66
break
;
67
default
:
68
av_log
(avctx,
AV_LOG_ERROR
,
"unsupported bits per sample\n"
);
69
return
AVERROR_INVALIDDATA
;
70
}
71
72
avcodec_get_frame_defaults
(&s->
frame
);
73
s->
frame
.
data
[0] =
NULL
;
74
75
if
(avctx->
extradata_size
>= 4)
76
for
(i = 0; i <
FFMIN
(avctx->
extradata_size
,
AVPALETTE_SIZE
)/4; i++)
77
s->
pal
[i] = 0xFFU<<24 |
AV_RL32
(avctx->
extradata
+4*i);
78
79
return
0;
80
}
81
82
static
int
msrle_decode_frame
(
AVCodecContext
*avctx,
83
void
*
data
,
int
*got_frame,
84
AVPacket
*avpkt)
85
{
86
const
uint8_t
*buf = avpkt->
data
;
87
int
buf_size = avpkt->
size
;
88
MsrleContext
*s = avctx->
priv_data
;
89
int
istride =
FFALIGN
(avctx->
width
*avctx->
bits_per_coded_sample
, 32) / 8;
90
int
ret;
91
92
s->
buf
= buf;
93
s->
size
= buf_size;
94
95
s->
frame
.
reference
= 3;
96
s->
frame
.
buffer_hints
=
FF_BUFFER_HINTS_VALID
|
FF_BUFFER_HINTS_PRESERVE
|
FF_BUFFER_HINTS_REUSABLE
;
97
if
((ret = avctx->
reget_buffer
(avctx, &s->
frame
)) < 0) {
98
av_log
(avctx,
AV_LOG_ERROR
,
"reget_buffer() failed\n"
);
99
return
ret;
100
}
101
102
if
(avctx->
bits_per_coded_sample
> 1 && avctx->
bits_per_coded_sample
<= 8) {
103
const
uint8_t
*pal =
av_packet_get_side_data
(avpkt,
AV_PKT_DATA_PALETTE
,
NULL
);
104
105
if
(pal) {
106
s->
frame
.
palette_has_changed
= 1;
107
memcpy(s->
pal
, pal,
AVPALETTE_SIZE
);
108
}
109
/* make the palette available */
110
memcpy(s->
frame
.
data
[1], s->
pal
,
AVPALETTE_SIZE
);
111
}
112
113
/* FIXME how to correctly detect RLE ??? */
114
if
(avctx->
height
* istride == avpkt->
size
) {
/* assume uncompressed */
115
int
linesize = (avctx->
width
* avctx->
bits_per_coded_sample
+ 7) / 8;
116
uint8_t
*ptr = s->
frame
.
data
[0];
117
uint8_t
*buf = avpkt->
data
+ (avctx->
height
-1)*istride;
118
int
i, j;
119
120
for
(i = 0; i < avctx->
height
; i++) {
121
if
(avctx->
bits_per_coded_sample
== 4) {
122
for
(j = 0; j < avctx->
width
- 1; j += 2) {
123
ptr[j+0] = buf[j>>1] >> 4;
124
ptr[j+1] = buf[j>>1] & 0xF;
125
}
126
if
(avctx->
width
& 1)
127
ptr[j+0] = buf[j>>1] >> 4;
128
}
else
{
129
memcpy(ptr, buf, linesize);
130
}
131
buf -= istride;
132
ptr += s->
frame
.
linesize
[0];
133
}
134
}
else
{
135
bytestream2_init
(&s->
gb
, buf, buf_size);
136
ff_msrle_decode
(avctx, (
AVPicture
*)&s->
frame
, avctx->
bits_per_coded_sample
, &s->
gb
);
137
}
138
139
*got_frame = 1;
140
*(
AVFrame
*)data = s->
frame
;
141
142
/* report that the buffer was completely consumed */
143
return
buf_size;
144
}
145
146
static
av_cold
int
msrle_decode_end
(
AVCodecContext
*avctx)
147
{
148
MsrleContext
*s = avctx->
priv_data
;
149
150
/* release the last frame */
151
if
(s->
frame
.
data
[0])
152
avctx->
release_buffer
(avctx, &s->
frame
);
153
154
return
0;
155
}
156
157
AVCodec
ff_msrle_decoder
= {
158
.
name
=
"msrle"
,
159
.type =
AVMEDIA_TYPE_VIDEO
,
160
.id =
AV_CODEC_ID_MSRLE
,
161
.priv_data_size =
sizeof
(
MsrleContext
),
162
.
init
=
msrle_decode_init
,
163
.
close
=
msrle_decode_end
,
164
.
decode
=
msrle_decode_frame
,
165
.capabilities =
CODEC_CAP_DR1
,
166
.long_name =
NULL_IF_CONFIG_SMALL
(
"Microsoft RLE"
),
167
};
Generated on Sat May 25 2013 04:01:08 for FFmpeg by
1.8.2