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
if
((ret =
av_image_check_size
(w, h, 0, avctx)) < 0)
115
return
ret
;
116
117
if
(w != avctx->
width
|| h != avctx->
height
)
118
avcodec_set_dimensions
(avctx, w, h);
119
120
// Need to end in 0x320 to read the descriptor
121
buf += 20;
122
descriptor = buf[0];
123
124
// Need to end in 0x323 to read the bits per color
125
buf += 3;
126
avctx->
bits_per_raw_sample
=
127
bits_per_color = buf[0];
128
buf++;
129
packing =
read16
(&buf, endian);
130
encoding =
read16
(&buf, endian);
131
132
if
(packing > 1) {
133
avpriv_report_missing_feature
(avctx,
"Packing %d"
, packing);
134
return
AVERROR_PATCHWELCOME
;
135
}
136
if
(encoding) {
137
avpriv_report_missing_feature
(avctx,
"Encoding %d"
, encoding);
138
return
AVERROR_PATCHWELCOME
;
139
}
140
141
buf += 820;
142
avctx->
sample_aspect_ratio
.
num
=
read32
(&buf, endian);
143
avctx->
sample_aspect_ratio
.
den
=
read32
(&buf, endian);
144
if
(avctx->
sample_aspect_ratio
.
num
> 0 && avctx->
sample_aspect_ratio
.
den
> 0)
145
av_reduce
(&avctx->
sample_aspect_ratio
.
num
, &avctx->
sample_aspect_ratio
.
den
,
146
avctx->
sample_aspect_ratio
.
num
, avctx->
sample_aspect_ratio
.
den
,
147
0x10000);
148
else
149
avctx->
sample_aspect_ratio
= (
AVRational
){ 0, 1 };
150
151
switch
(descriptor) {
152
case
6:
// Y
153
elements = 1;
154
break
;
155
case
52:
// ABGR
156
case
51:
// RGBA
157
elements = 4;
158
break
;
159
case
50:
// RGB
160
elements = 3;
161
break
;
162
default
:
163
avpriv_report_missing_feature
(avctx,
"Descriptor %d"
, descriptor);
164
return
AVERROR_PATCHWELCOME
;
165
}
166
167
switch
(bits_per_color) {
168
case
8:
169
total_size = avctx->
width
* avctx->
height
* elements;
170
break
;
171
case
10:
172
if
(!packing) {
173
av_log
(avctx,
AV_LOG_ERROR
,
"Packing to 32bit required\n"
);
174
return
-1;
175
}
176
total_size = (avctx->
width
* elements + 2) / 3 * 4 * avctx->
height
;
177
break
;
178
case
12:
179
if
(!packing) {
180
av_log
(avctx,
AV_LOG_ERROR
,
"Packing to 16bit required\n"
);
181
return
-1;
182
}
183
total_size = 2 * avctx->
width
* avctx->
height
* elements;
184
break
;
185
case
16:
186
total_size = 2 * avctx->
width
* avctx->
height
* elements;
187
break
;
188
case
1:
189
case
32:
190
case
64:
191
avpriv_report_missing_feature
(avctx,
"Depth %d"
, bits_per_color);
192
return
AVERROR_PATCHWELCOME
;
193
default
:
194
return
AVERROR_INVALIDDATA
;
195
}
196
197
switch
(1000 * descriptor + 10 * bits_per_color + endian) {
198
case
6081:
199
case
6080:
200
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY8
;
201
break
;
202
case
50081:
203
case
50080:
204
avctx->
pix_fmt
=
AV_PIX_FMT_RGB24
;
205
break
;
206
case
52081:
207
case
52080:
208
avctx->
pix_fmt
=
AV_PIX_FMT_ABGR
;
209
break
;
210
case
51081:
211
case
51080:
212
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA
;
213
break
;
214
case
50100:
215
case
51100:
216
case
50101:
217
case
51101:
218
avctx->
pix_fmt
=
AV_PIX_FMT_GBRP10
;
219
break
;
220
case
50120:
221
case
51120:
222
case
50121:
223
case
51121:
224
avctx->
pix_fmt
=
AV_PIX_FMT_GBRP12
;
225
break
;
226
case
6161:
227
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16BE
;
228
break
;
229
case
6160:
230
avctx->
pix_fmt
=
AV_PIX_FMT_GRAY16LE
;
231
break
;
232
case
50161:
233
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48BE
;
234
break
;
235
case
50160:
236
avctx->
pix_fmt
=
AV_PIX_FMT_RGB48LE
;
237
break
;
238
case
51161:
239
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA64BE
;
240
break
;
241
case
51160:
242
avctx->
pix_fmt
=
AV_PIX_FMT_RGBA64LE
;
243
break
;
244
default
:
245
av_log
(avctx,
AV_LOG_ERROR
,
"Unsupported format\n"
);
246
return
AVERROR_PATCHWELCOME
;
247
}
248
249
if
((ret =
ff_get_buffer
(avctx, p, 0)) < 0)
250
return
ret
;
251
252
// Move pointer to offset from start of file
253
buf = avpkt->
data
+
offset
;
254
255
for
(i=0; i<
AV_NUM_DATA_POINTERS
; i++)
256
ptr[i] = p->
data
[i];
257
258
if
(total_size + (int64_t)offset > avpkt->
size
) {
259
av_log
(avctx,
AV_LOG_ERROR
,
"Overread buffer. Invalid header?\n"
);
260
return
AVERROR_INVALIDDATA
;
261
}
262
switch
(bits_per_color) {
263
case
10:
264
for
(x = 0; x < avctx->
height
; x++) {
265
uint16_t *dst[3] = {(uint16_t*)ptr[0],
266
(uint16_t*)ptr[1],
267
(uint16_t*)ptr[2]};
268
for
(y = 0; y < avctx->
width
; y++) {
269
*dst[2]++ =
read10in32
(&buf, &rgbBuffer,
270
&n_datum, endian);
271
*dst[0]++ =
read10in32
(&buf, &rgbBuffer,
272
&n_datum, endian);
273
*dst[1]++ =
read10in32
(&buf, &rgbBuffer,
274
&n_datum, endian);
275
// For 10 bit, ignore alpha
276
if
(elements == 4)
277
read10in32
(&buf, &rgbBuffer,
278
&n_datum, endian);
279
}
280
n_datum = 0;
281
for
(i = 0; i < 3; i++)
282
ptr[i] += p->
linesize
[i];
283
}
284
break
;
285
case
12:
286
for
(x = 0; x < avctx->
height
; x++) {
287
uint16_t *dst[3] = {(uint16_t*)ptr[0],
288
(uint16_t*)ptr[1],
289
(uint16_t*)ptr[2]};
290
for
(y = 0; y < avctx->
width
; y++) {
291
*dst[2] =
read16
(&buf, endian) >> 4;
292
dst[2]++;
293
*dst[0] =
read16
(&buf, endian) >> 4;
294
dst[0]++;
295
*dst[1] =
read16
(&buf, endian) >> 4;
296
dst[1]++;
297
// For 12 bit, ignore alpha
298
if
(elements == 4)
299
buf += 2;
300
}
301
for
(i = 0; i < 3; i++)
302
ptr[i] += p->
linesize
[i];
303
}
304
break
;
305
case
16:
306
elements *= 2;
307
case
8:
308
av_image_copy_plane
(ptr[0], p->
linesize
[0],
309
buf, elements * avctx->
width
,
310
elements * avctx->
width
, avctx->
height
);
311
break
;
312
}
313
314
*got_frame = 1;
315
316
return
buf_size;
317
}
318
319
AVCodec
ff_dpx_decoder
= {
320
.
name
=
"dpx"
,
321
.long_name =
NULL_IF_CONFIG_SMALL
(
"DPX (Digital Picture Exchange) image"
),
322
.type =
AVMEDIA_TYPE_VIDEO
,
323
.id =
AV_CODEC_ID_DPX
,
324
.decode =
decode_frame
,
325
.capabilities =
CODEC_CAP_DR1
,
326
};
Generated on Sat Jan 25 2014 19:51:46 for FFmpeg by
1.8.2