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