FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
dpx.c
Go to the documentation of this file.
1
/*
2
* DPX (.dpx) image decoder
3
* Copyright (c) 2009 Jimmy Christensen
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
#include "
libavutil/intreadwrite.h
"
23
#include "
libavutil/imgutils.h
"
24
#include "
bytestream.h
"
25
#include "
avcodec.h
"
26
#include "
internal.h
"
27
28
static
unsigned
int
read16
(
const
uint8_t
**ptr,
int
is_big)
29
{
30
unsigned
int
temp
;
31
if
(is_big) {
32
temp =
AV_RB16
(*ptr);
33
}
else
{
34
temp =
AV_RL16
(*ptr);
35
}
36
*ptr += 2;
37
return
temp
;
38
}
39
40
static
unsigned
int
read32
(
const
uint8_t
**ptr,
int
is_big)
41
{
42
unsigned
int
temp
;
43
if
(is_big) {
44
temp =
AV_RB32
(*ptr);
45
}
else
{
46
temp =
AV_RL32
(*ptr);
47
}
48
*ptr += 4;
49
return
temp
;
50
}
51
52
static
uint16_t
read10in32
(
const
uint8_t
**ptr, uint32_t * lbuf,
53
int
* n_datum,
int
is_big)
54
{
55
if
(*n_datum)
56
(*n_datum)--;
57
else
{
58
*lbuf =
read32
(ptr, is_big);
59
*n_datum = 2;
60
}
61
62
*lbuf = (*lbuf << 10) | (*lbuf >> 22);
63
64
return
*lbuf & 0x3FF;
65
}
66
67
static
int
decode_frame
(
AVCodecContext
*avctx,
68
void
*
data
,
69
int
*got_frame,
70
AVPacket
*avpkt)
71
{
72
const
uint8_t
*
buf
= avpkt->
data
;
73
int
buf_size = avpkt->
size
;
74
AVFrame
*
const
p =
data
;
75
uint8_t
*ptr[
AV_NUM_DATA_POINTERS
];
76
77
unsigned
int
offset
;
78
int
magic_num, endian;
79
int
x,
y
, i,
ret
;
80
int
w, h, bits_per_color, descriptor, elements, packing, total_size;
81
int
encoding;
82
83
unsigned
int
rgbBuffer = 0;
84
int
n_datum = 0;
85
86
if
(avpkt->
size
<= 1634) {
87
av_log
(avctx,
AV_LOG_ERROR
,
"Packet too small for DPX header\n"
);
88
return
AVERROR_INVALIDDATA
;
89
}
90
91
magic_num =
AV_RB32
(buf);
92
buf += 4;
93
94
/* Check if the files "magic number" is "SDPX" which means it uses
95
* big-endian or XPDS which is for little-endian files */
96
if
(magic_num ==
AV_RL32
(
"SDPX"
)) {
97
endian = 0;
98
}
else
if
(magic_num ==
AV_RB32
(
"SDPX"
)) {
99
endian = 1;
100
}
else
{
101
av_log
(avctx,
AV_LOG_ERROR
,
"DPX marker not found\n"
);
102
return
AVERROR_INVALIDDATA
;
103
}
104
105
offset =
read32
(&buf, endian);
106
if
(avpkt->
size
<= offset) {
107
av_log
(avctx,
AV_LOG_ERROR
,
"Invalid data start offset\n"
);
108
return
AVERROR_INVALIDDATA
;
109
}
110
// Need to end in 0x304 offset from start of file
111
buf = avpkt->
data
+ 0x304;
112
w =
read32
(&buf, endian);
113
h =
read32
(&buf, endian);
114
115
if
((ret =
ff_set_dimensions
(avctx, w, h)) < 0)
116
return
ret
;
117
118
// Need to end in 0x320 to read the descriptor
119
buf += 20;
120
descriptor = buf[0];
121
122
// Need to end in 0x323 to read the bits per color
123
buf += 3;
124
avctx->
bits_per_raw_sample
=
125
bits_per_color = buf[0];
126
buf++;
127
packing =
read16
(&buf, endian);
128
encoding =
read16
(&buf, endian);
129
130
if
(packing > 1) {
131
avpriv_report_missing_feature
(avctx,
"Packing %d"
, packing);
132
return
AVERROR_PATCHWELCOME
;
133
}
134
if
(encoding) {
135
avpriv_report_missing_feature
(avctx,
"Encoding %d"
, encoding);
136
return
AVERROR_PATCHWELCOME
;
137
}
138
139
buf += 820;
140
avctx->
sample_aspect_ratio
.
num
=
read32
(&buf, endian);
141
avctx->
sample_aspect_ratio
.
den
=
read32
(&buf, endian);
142
if
(avctx->
sample_aspect_ratio
.
num
> 0 && avctx->
sample_aspect_ratio
.
den
> 0)
143
av_reduce
(&avctx->
sample_aspect_ratio
.
num
, &avctx->
sample_aspect_ratio
.
den
,
144
avctx->
sample_aspect_ratio
.
num
, avctx->
sample_aspect_ratio
.
den
,
145
0x10000);
146
else
147
avctx->
sample_aspect_ratio
= (
AVRational
){ 0, 1 };
148
149
switch
(descriptor) {
150
case
6:
// Y
151
elements = 1;
152
break
;
153
case
52:
// ABGR
154
case
51:
// RGBA
155
elements = 4;
156
break
;
157
case
50:
// RGB
158
elements = 3;
159
break
;
160
default
:
161
avpriv_report_missing_feature
(avctx,
"Descriptor %d"
, descriptor);
162
return
AVERROR_PATCHWELCOME
;
163
}
164
165
switch
(bits_per_color) {
166
case
8:
167
total_size = avctx->
width
* avctx->
height
* elements;
168
break
;
169
case
10:
170
if
(!packing) {
171
av_log
(avctx,
AV_LOG_ERROR
,
"Packing to 32bit required\n"
);
172
return
-1;
173
}
174
total_size = (avctx->
width
* elements + 2) / 3 * 4 * avctx->
height
;
175
break
;
176
case
12:
177
if
(!packing) {
178
av_log
(avctx,
AV_LOG_ERROR
,
"Packing to 16bit required\n"
);
179
return
-1;
180
}
181
total_size = 2 * avctx->
width
* avctx->
height
* elements;
182
break
;
183
case
16:
184
total_size = 2 * avctx->
width
* avctx->
height
* elements;
185
break
;
186
case
1:
187
case
32:
188
case
64:
189
avpriv_report_missing_feature
(avctx,
"Depth %d"
, bits_per_color);
190
return
AVERROR_PATCHWELCOME
;
191
default
:
192
return
AVERROR_INVALIDDATA
;
193
}
194
195
switch
(1000 * descriptor + 10 * bits_per_color + endian) {
196
case
6081:
197
case
6080:
198
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY8
;
199
break
;
200
case
50081:
201
case
50080:
202
avctx->
pix_fmt
=
AV_PIX_FMT_RGB24
;
203
break
;
204
case
52081:
205
case
52080:
206
avctx->
pix_fmt
=
AV_PIX_FMT_ABGR
;
207
break
;
208
case
51081:
209
case
51080:
210
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA
;
211
break
;
212
case
50100:
213
case
51100:
214
case
50101:
215
case
51101:
216
avctx->
pix_fmt
=
AV_PIX_FMT_GBRP10
;
217
break
;
218
case
50120:
219
case
51120:
220
case
50121:
221
case
51121:
222
avctx->
pix_fmt
=
AV_PIX_FMT_GBRP12
;
223
break
;
224
case
6161:
225
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16BE
;
226
break
;
227
case
6160:
228
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16LE
;
229
break
;
230
case
50161:
231
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48BE
;
232
break
;
233
case
50160:
234
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48LE
;
235
break
;
236
case
51161:
237
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA64BE
;
238
break
;
239
case
51160:
240
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA64LE
;
241
break
;
242
default
:
243
av_log
(avctx,
AV_LOG_ERROR
,
"Unsupported format\n"
);
244
return
AVERROR_PATCHWELCOME
;
245
}
246
247
if
((ret =
ff_get_buffer
(avctx, p, 0)) < 0)
248
return
ret
;
249
250
// Move pointer to offset from start of file
251
buf = avpkt->
data
+
offset
;
252
253
for
(i=0; i<
AV_NUM_DATA_POINTERS
; i++)
254
ptr[i] = p->
data
[i];
255
256
if
(total_size + (int64_t)offset > avpkt->
size
) {
257
av_log
(avctx,
AV_LOG_ERROR
,
"Overread buffer. Invalid header?\n"
);
258
return
AVERROR_INVALIDDATA
;
259
}
260
switch
(bits_per_color) {
261
case
10:
262
for
(x = 0; x < avctx->
height
; x++) {
263
uint16_t *dst[3] = {(uint16_t*)ptr[0],
264
(uint16_t*)ptr[1],
265
(uint16_t*)ptr[2]};
266
for
(y = 0; y < avctx->
width
; y++) {
267
*dst[2]++ =
read10in32
(&buf, &rgbBuffer,
268
&n_datum, endian);
269
*dst[0]++ =
read10in32
(&buf, &rgbBuffer,
270
&n_datum, endian);
271
*dst[1]++ =
read10in32
(&buf, &rgbBuffer,
272
&n_datum, endian);
273
// For 10 bit, ignore alpha
274
if
(elements == 4)
275
read10in32
(&buf, &rgbBuffer,
276
&n_datum, endian);
277
}
278
n_datum = 0;
279
for
(i = 0; i < 3; i++)
280
ptr[i] += p->
linesize
[i];
281
}
282
break
;
283
case
12:
284
for
(x = 0; x < avctx->
height
; x++) {
285
uint16_t *dst[3] = {(uint16_t*)ptr[0],
286
(uint16_t*)ptr[1],
287
(uint16_t*)ptr[2]};
288
for
(y = 0; y < avctx->
width
; y++) {
289
*dst[2] =
read16
(&buf, endian) >> 4;
290
dst[2]++;
291
*dst[0] =
read16
(&buf, endian) >> 4;
292
dst[0]++;
293
*dst[1] =
read16
(&buf, endian) >> 4;
294
dst[1]++;
295
// For 12 bit, ignore alpha
296
if
(elements == 4)
297
buf += 2;
298
}
299
for
(i = 0; i < 3; i++)
300
ptr[i] += p->
linesize
[i];
301
}
302
break
;
303
case
16:
304
elements *= 2;
305
case
8:
306
av_image_copy_plane
(ptr[0], p->
linesize
[0],
307
buf, elements * avctx->
width
,
308
elements * avctx->
width
, avctx->
height
);
309
break
;
310
}
311
312
*got_frame = 1;
313
314
return
buf_size;
315
}
316
317
AVCodec
ff_dpx_decoder
= {
318
.
name
=
"dpx"
,
319
.long_name =
NULL_IF_CONFIG_SMALL
(
"DPX (Digital Picture Exchange) image"
),
320
.type =
AVMEDIA_TYPE_VIDEO
,
321
.id =
AV_CODEC_ID_DPX
,
322
.decode =
decode_frame
,
323
.capabilities =
CODEC_CAP_DR1
,
324
};
Generated on Sun Mar 23 2014 23:49:53 for FFmpeg by
1.8.2