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