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