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 "
dsputil.h
"
37
#include "
msrledec.h
"
38
39
typedef
struct
MsrleContext
{
40
AVCodecContext
*
avctx
;
41
AVFrame
frame
;
42
43
GetByteContext
gb
;
44
const
unsigned
char
*
buf
;
45
int
size
;
46
47
uint32_t
pal
[256];
48
}
MsrleContext
;
49
50
static
av_cold
int
msrle_decode_init
(
AVCodecContext
*avctx)
51
{
52
MsrleContext
*s = avctx->
priv_data
;
53
int
i;
54
55
s->
avctx
= avctx;
56
57
switch
(avctx->
bits_per_coded_sample
) {
58
case
1:
59
avctx->
pix_fmt
=
AV_PIX_FMT_MONOWHITE
;
60
break
;
61
case
4:
62
case
8:
63
avctx->
pix_fmt
=
AV_PIX_FMT_PAL8
;
64
break
;
65
case
24:
66
avctx->
pix_fmt
=
AV_PIX_FMT_BGR24
;
67
break
;
68
default
:
69
av_log
(avctx,
AV_LOG_ERROR
,
"unsupported bits per sample\n"
);
70
return
-1;
71
}
72
73
avcodec_get_frame_defaults
(&s->
frame
);
74
s->
frame
.
data
[0] =
NULL
;
75
76
if
(avctx->
extradata_size
>= 4)
77
for
(i = 0; i <
FFMIN
(avctx->
extradata_size
,
AVPALETTE_SIZE
)/4; i++)
78
s->
pal
[i] = 0xFFU<<24 |
AV_RL32
(avctx->
extradata
+4*i);
79
80
return
0;
81
}
82
83
static
int
msrle_decode_frame
(
AVCodecContext
*avctx,
84
void
*
data
,
int
*got_frame,
85
AVPacket
*avpkt)
86
{
87
const
uint8_t
*buf = avpkt->
data
;
88
int
buf_size = avpkt->
size
;
89
MsrleContext
*s = avctx->
priv_data
;
90
int
istride =
FFALIGN
(avctx->
width
*avctx->
bits_per_coded_sample
, 32) / 8;
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
(avctx->
reget_buffer
(avctx, &s->
frame
)) {
98
av_log
(avctx,
AV_LOG_ERROR
,
"reget_buffer() failed\n"
);
99
return
-1;
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 03:58:38 for FFmpeg by
1.8.2