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
sgirledec.c
Go to the documentation of this file.
1
/*
2
* SGI RLE 8-bit decoder
3
* Copyright (c) 2012 Peter Ross
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
* SGI RLE 8-bit decoder
25
*/
26
27
#include "
libavutil/intreadwrite.h
"
28
#include "
avcodec.h
"
29
#include "
bytestream.h
"
30
31
static
av_cold
int
sgirle_decode_init
(
AVCodecContext
*avctx)
32
{
33
avctx->
pix_fmt
=
AV_PIX_FMT_BGR8
;
34
avctx->
coded_frame
=
avcodec_alloc_frame
();
35
if
(!avctx->
coded_frame
)
36
return
AVERROR
(ENOMEM);
37
return
0;
38
}
39
40
/**
41
* Convert SGI RGB332 pixel into PIX_FMT_BGR8
42
* SGI RGB332 is packed RGB 3:3:2, 8bpp, (msb)3R 2B 3G(lsb)
43
*/
44
#define RGB332_TO_BGR8(x) (((x << 3) & 0xC0) | ((x << 3) & 0x38) | ((x >> 5) & 7))
45
46
static
av_always_inline
void
memcpy_rgb332_to_bgr8
(
uint8_t
*
dst
,
const
uint8_t
*src,
int
size
)
47
{
48
int
i;
49
for
(i = 0; i <
size
; i++)
50
dst[i] =
RGB332_TO_BGR8
(src[i]);
51
}
52
53
/**
54
* @param[out] dst Destination buffer
55
* @param[in] src Source buffer
56
* @param src_size Source buffer size (bytes)
57
* @param width Width of destination buffer (pixels)
58
* @param height Height of destination buffer (pixels)
59
* @param linesize Line size of destination buffer (bytes)
60
* @return <0 on error
61
*/
62
static
int
decode_sgirle8
(
AVCodecContext
*avctx,
uint8_t
*
dst
,
const
uint8_t
*src,
int
src_size,
int
width
,
int
height
,
int
linesize)
63
{
64
const
uint8_t
*src_end = src + src_size;
65
int
x = 0,
y
= 0;
66
67
#define INC_XY(n) \
68
x += n; \
69
if (x >= width) { \
70
y++; \
71
if (y >= height) \
72
return 0; \
73
x = 0; \
74
}
75
76
while
(src_end - src >= 2) {
77
uint8_t
v
= *src++;
78
if
(v > 0 && v < 0xC0) {
79
do
{
80
int
length =
FFMIN
(v, width - x);
81
memset(dst +
y
*linesize + x,
RGB332_TO_BGR8
(*src), length);
82
INC_XY
(length);
83
v -= length;
84
}
while
(v > 0);
85
src++;
86
}
else
if
(v >= 0xC1) {
87
v -= 0xC0;
88
do
{
89
int
length =
FFMIN3
(v, width - x, src_end - src);
90
if
(src_end - src < length)
91
break
;
92
memcpy_rgb332_to_bgr8
(dst +
y
*linesize + x, src, length);
93
INC_XY
(length);
94
src += length;
95
v -= length;
96
}
while
(v > 0);
97
}
else
{
98
av_log_ask_for_sample
(avctx,
"unknown opcode\n"
);
99
return
AVERROR_PATCHWELCOME
;
100
}
101
}
102
return
0;
103
}
104
105
static
int
sgirle_decode_frame
(
AVCodecContext
*avctx,
106
void
*
data
,
int
*got_frame,
107
AVPacket
*avpkt)
108
{
109
AVFrame
*
frame
= avctx->
coded_frame
;
110
int
ret;
111
112
frame->
reference
= 3;
113
frame->
buffer_hints
=
FF_BUFFER_HINTS_VALID
|
FF_BUFFER_HINTS_PRESERVE
|
114
FF_BUFFER_HINTS_REUSABLE
|
FF_BUFFER_HINTS_READABLE
;
115
ret = avctx->
reget_buffer
(avctx, frame);
116
if
(ret < 0) {
117
av_log
(avctx,
AV_LOG_ERROR
,
"reget_buffer() failed\n"
);
118
return
ret;
119
}
120
121
ret =
decode_sgirle8
(avctx, frame->
data
[0], avpkt->
data
, avpkt->
size
, avctx->
width
, avctx->
height
, frame->
linesize
[0]);
122
if
(ret < 0)
123
return
ret;
124
125
*got_frame = 1;
126
*(
AVFrame
*)data = *frame;
127
128
return
avpkt->
size
;
129
}
130
131
static
av_cold
int
sgirle_decode_end
(
AVCodecContext
*avctx)
132
{
133
if
(avctx->
coded_frame
->
data
[0])
134
avctx->
release_buffer
(avctx, avctx->
coded_frame
);
135
av_freep
(&avctx->
coded_frame
);
136
return
0;
137
}
138
139
AVCodec
ff_sgirle_decoder
= {
140
.
name
=
"sgirle"
,
141
.type =
AVMEDIA_TYPE_VIDEO
,
142
.id =
AV_CODEC_ID_SGIRLE
,
143
.init =
sgirle_decode_init
,
144
.close =
sgirle_decode_end
,
145
.decode =
sgirle_decode_frame
,
146
.capabilities =
CODEC_CAP_DR1
,
147
.long_name =
NULL_IF_CONFIG_SMALL
(
"SGI RLE 8-bit"
),
148
};
Generated on Sat May 25 2013 04:01:10 for FFmpeg by
1.8.2