Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
ptx.c
Go to the documentation of this file.
1
/*
2
* V.Flash PTX (.ptx) image decoder
3
* Copyright (c) 2007 Ivo van Poorten
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
22
#include "
libavutil/intreadwrite.h
"
23
#include "
libavutil/imgutils.h
"
24
#include "
avcodec.h
"
25
26
typedef
struct
PTXContext
{
27
AVFrame
picture
;
28
}
PTXContext
;
29
30
static
av_cold
int
ptx_init
(
AVCodecContext
*avctx) {
31
PTXContext
*s = avctx->
priv_data
;
32
33
avcodec_get_frame_defaults
(&s->
picture
);
34
avctx->
coded_frame
= &s->
picture
;
35
36
return
0;
37
}
38
39
static
int
ptx_decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
int
*data_size,
40
AVPacket
*avpkt) {
41
const
uint8_t *buf = avpkt->
data
;
42
const
uint8_t *buf_end = avpkt->
data
+ avpkt->
size
;
43
PTXContext
*
const
s = avctx->
priv_data
;
44
AVFrame
*
picture
=
data
;
45
AVFrame
*
const
p = &s->
picture
;
46
unsigned
int
offset, w, h, y,
stride
, bytes_per_pixel;
47
uint8_t *ptr;
48
49
if
(buf_end - buf < 14)
50
return
AVERROR_INVALIDDATA
;
51
offset =
AV_RL16
(buf);
52
w =
AV_RL16
(buf+8);
53
h =
AV_RL16
(buf+10);
54
bytes_per_pixel =
AV_RL16
(buf+12) >> 3;
55
56
if
(bytes_per_pixel != 2) {
57
av_log_ask_for_sample
(avctx,
"Image format is not RGB15.\n"
);
58
return
-1;
59
}
60
61
avctx->
pix_fmt
=
PIX_FMT_RGB555
;
62
63
if
(buf_end - buf < offset)
64
return
AVERROR_INVALIDDATA
;
65
if
(offset != 0x2c)
66
av_log_ask_for_sample
(avctx,
"offset != 0x2c\n"
);
67
68
buf += offset;
69
70
if
(p->
data
[0])
71
avctx->
release_buffer
(avctx, p);
72
73
if
(
av_image_check_size
(w, h, 0, avctx))
74
return
-1;
75
if
(w != avctx->
width
|| h != avctx->
height
)
76
avcodec_set_dimensions
(avctx, w, h);
77
if
(avctx->
get_buffer
(avctx, p) < 0) {
78
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
79
return
-1;
80
}
81
82
p->
pict_type
=
AV_PICTURE_TYPE_I
;
83
84
ptr = p->
data
[0];
85
stride = p->
linesize
[0];
86
87
for
(y = 0; y < h && buf_end - buf >= w * bytes_per_pixel; y++) {
88
#if HAVE_BIGENDIAN
89
unsigned
int
x;
90
for
(x=0; x<w*bytes_per_pixel; x+=bytes_per_pixel)
91
AV_WN16
(ptr+x,
AV_RL16
(buf+x));
92
#else
93
memcpy(ptr, buf, w*bytes_per_pixel);
94
#endif
95
ptr +=
stride
;
96
buf += w*bytes_per_pixel;
97
}
98
99
*picture = s->
picture
;
100
*data_size =
sizeof
(
AVPicture
);
101
102
if
(y < h) {
103
av_log
(avctx,
AV_LOG_WARNING
,
"incomplete packet\n"
);
104
return
avpkt->
size
;
105
}
106
107
return
offset + w*h*bytes_per_pixel;
108
}
109
110
static
av_cold
int
ptx_end
(
AVCodecContext
*avctx) {
111
PTXContext
*s = avctx->
priv_data
;
112
113
if
(s->
picture
.
data
[0])
114
avctx->
release_buffer
(avctx, &s->
picture
);
115
116
return
0;
117
}
118
119
AVCodec
ff_ptx_decoder
= {
120
.
name
=
"ptx"
,
121
.type =
AVMEDIA_TYPE_VIDEO
,
122
.id =
CODEC_ID_PTX
,
123
.priv_data_size =
sizeof
(
PTXContext
),
124
.
init
=
ptx_init
,
125
.
close
=
ptx_end
,
126
.
decode
=
ptx_decode_frame
,
127
.capabilities =
CODEC_CAP_DR1
,
128
.long_name =
NULL_IF_CONFIG_SMALL
(
"V.Flash PTX image"
),
129
};