Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
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 Libav.
6
*
7
* Libav 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
* Libav 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 Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
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
54
s->
avctx
= avctx;
55
56
switch
(avctx->
bits_per_coded_sample
) {
57
case
4:
58
case
8:
59
avctx->
pix_fmt
=
PIX_FMT_PAL8
;
60
break
;
61
case
24:
62
avctx->
pix_fmt
=
PIX_FMT_BGR24
;
63
break
;
64
default
:
65
av_log
(avctx,
AV_LOG_ERROR
,
"unsupported bits per sample\n"
);
66
return
-1;
67
}
68
69
s->
frame
.
data
[0] =
NULL
;
70
71
return
0;
72
}
73
74
static
int
msrle_decode_frame
(
AVCodecContext
*avctx,
75
void
*
data
,
int
*data_size,
76
AVPacket
*avpkt)
77
{
78
const
uint8_t *buf = avpkt->
data
;
79
int
buf_size = avpkt->
size
;
80
MsrleContext
*s = avctx->
priv_data
;
81
int
istride =
FFALIGN
(avctx->
width
*avctx->
bits_per_coded_sample
, 32) / 8;
82
83
s->
buf
= buf;
84
s->
size
= buf_size;
85
86
s->
frame
.
reference
= 1;
87
s->
frame
.
buffer_hints
=
FF_BUFFER_HINTS_VALID
|
FF_BUFFER_HINTS_PRESERVE
|
FF_BUFFER_HINTS_REUSABLE
;
88
if
(avctx->
reget_buffer
(avctx, &s->
frame
)) {
89
av_log
(avctx,
AV_LOG_ERROR
,
"reget_buffer() failed\n"
);
90
return
-1;
91
}
92
93
if
(avctx->
bits_per_coded_sample
<= 8) {
94
const
uint8_t *pal =
av_packet_get_side_data
(avpkt,
AV_PKT_DATA_PALETTE
,
NULL
);
95
96
if
(pal) {
97
s->
frame
.
palette_has_changed
= 1;
98
memcpy(s->
pal
, pal,
AVPALETTE_SIZE
);
99
}
100
101
/* make the palette available */
102
memcpy(s->
frame
.
data
[1], s->
pal
,
AVPALETTE_SIZE
);
103
}
104
105
/* FIXME how to correctly detect RLE ??? */
106
if
(avctx->
height
* istride == avpkt->
size
) {
/* assume uncompressed */
107
int
linesize = avctx->
width
* avctx->
bits_per_coded_sample
/ 8;
108
uint8_t *ptr = s->
frame
.
data
[0];
109
uint8_t *buf = avpkt->
data
+ (avctx->
height
-1)*istride;
110
int
i, j;
111
112
for
(i = 0; i < avctx->
height
; i++) {
113
if
(avctx->
bits_per_coded_sample
== 4) {
114
for
(j = 0; j < avctx->
width
- 1; j += 2) {
115
ptr[j+0] = buf[j>>1] >> 4;
116
ptr[j+1] = buf[j>>1] & 0xF;
117
}
118
if
(avctx->
width
& 1)
119
ptr[j+0] = buf[j>>1] >> 4;
120
}
else
{
121
memcpy(ptr, buf, linesize);
122
}
123
buf -= istride;
124
ptr += s->
frame
.
linesize
[0];
125
}
126
}
else
{
127
bytestream2_init
(&s->
gb
, buf, buf_size);
128
ff_msrle_decode
(avctx, (
AVPicture
*)&s->
frame
, avctx->
bits_per_coded_sample
, &s->
gb
);
129
}
130
131
*data_size =
sizeof
(
AVFrame
);
132
*(
AVFrame
*)data = s->
frame
;
133
134
/* report that the buffer was completely consumed */
135
return
buf_size;
136
}
137
138
static
av_cold
int
msrle_decode_end
(
AVCodecContext
*avctx)
139
{
140
MsrleContext
*s = avctx->
priv_data
;
141
142
/* release the last frame */
143
if
(s->
frame
.
data
[0])
144
avctx->
release_buffer
(avctx, &s->
frame
);
145
146
return
0;
147
}
148
149
AVCodec
ff_msrle_decoder
= {
150
.
name
=
"msrle"
,
151
.type =
AVMEDIA_TYPE_VIDEO
,
152
.id =
CODEC_ID_MSRLE
,
153
.priv_data_size =
sizeof
(
MsrleContext
),
154
.
init
=
msrle_decode_init
,
155
.
close
=
msrle_decode_end
,
156
.
decode
=
msrle_decode_frame
,
157
.capabilities =
CODEC_CAP_DR1
,
158
.long_name=
NULL_IF_CONFIG_SMALL
(
"Microsoft RLE"
),
159
};