2 * DPX (.dpx) image encoder
3 * Copyright (c) 2011 Peter Ross <pross@xvid.org>
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "libavutil/common.h"
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/imgutils.h"
28 typedef struct DPXContext
{
30 int bits_per_component
;
36 static av_cold
int encode_init(AVCodecContext
*avctx
)
38 DPXContext
*s
= avctx
->priv_data
;
39 const AVPixFmtDescriptor
*desc
= av_pix_fmt_desc_get(avctx
->pix_fmt
);
41 s
->big_endian
= !!(desc
->flags
& AV_PIX_FMT_FLAG_BE
);
42 s
->bits_per_component
= desc
->comp
[0].depth_minus1
+ 1;
43 s
->num_components
= desc
->nb_components
;
44 s
->descriptor
= (desc
->flags
& AV_PIX_FMT_FLAG_ALPHA
) ? 51 : 50;
45 s
->planar
= !!(desc
->flags
& AV_PIX_FMT_FLAG_PLANAR
);
47 switch (avctx
->pix_fmt
) {
51 case AV_PIX_FMT_GRAY16BE
:
52 case AV_PIX_FMT_GRAY16LE
:
53 case AV_PIX_FMT_GRAY8
:
56 case AV_PIX_FMT_GBRP10BE
:
57 case AV_PIX_FMT_GBRP10LE
:
58 case AV_PIX_FMT_GBRP12BE
:
59 case AV_PIX_FMT_GBRP12LE
:
60 case AV_PIX_FMT_RGB24
:
61 case AV_PIX_FMT_RGBA64BE
:
62 case AV_PIX_FMT_RGBA64LE
:
65 case AV_PIX_FMT_RGB48LE
:
66 case AV_PIX_FMT_RGB48BE
:
67 if (avctx
->bits_per_raw_sample
)
68 s
->bits_per_component
= avctx
->bits_per_raw_sample
;
71 av_log(avctx
, AV_LOG_INFO
, "unsupported pixel format\n");
78 #define write16(p, value) \
80 if (s->big_endian) AV_WB16(p, value); \
81 else AV_WL16(p, value); \
84 #define write32(p, value) \
86 if (s->big_endian) AV_WB32(p, value); \
87 else AV_WL32(p, value); \
90 static void encode_rgb48_10bit(AVCodecContext
*avctx
, const AVPicture
*pic
, uint8_t *dst
)
92 DPXContext
*s
= avctx
->priv_data
;
93 const uint8_t *src
= pic
->data
[0];
96 for (y
= 0; y
< avctx
->height
; y
++) {
97 for (x
= 0; x
< avctx
->width
; x
++) {
100 value
= ((AV_RB16(src
+ 6*x
+ 4) & 0xFFC0U
) >> 4)
101 | ((AV_RB16(src
+ 6*x
+ 2) & 0xFFC0U
) << 6)
102 | ((AV_RB16(src
+ 6*x
+ 0) & 0xFFC0U
) << 16);
104 value
= ((AV_RL16(src
+ 6*x
+ 4) & 0xFFC0U
) >> 4)
105 | ((AV_RL16(src
+ 6*x
+ 2) & 0xFFC0U
) << 6)
106 | ((AV_RL16(src
+ 6*x
+ 0) & 0xFFC0U
) << 16);
111 src
+= pic
->linesize
[0];
115 static void encode_gbrp10(AVCodecContext
*avctx
, const AVPicture
*pic
, uint8_t *dst
)
117 DPXContext
*s
= avctx
->priv_data
;
118 const uint8_t *src
[3] = {pic
->data
[0], pic
->data
[1], pic
->data
[2]};
121 for (y
= 0; y
< avctx
->height
; y
++) {
122 for (x
= 0; x
< avctx
->width
; x
++) {
125 value
= (AV_RB16(src
[0] + 2*x
) << 12)
126 | (AV_RB16(src
[1] + 2*x
) << 2)
127 | ((unsigned)AV_RB16(src
[2] + 2*x
) << 22);
129 value
= (AV_RL16(src
[0] + 2*x
) << 12)
130 | (AV_RL16(src
[1] + 2*x
) << 2)
131 | ((unsigned)AV_RL16(src
[2] + 2*x
) << 22);
136 for (i
= 0; i
< 3; i
++)
137 src
[i
] += pic
->linesize
[i
];
141 static void encode_gbrp12(AVCodecContext
*avctx
, const AVPicture
*pic
, uint16_t *dst
)
143 DPXContext
*s
= avctx
->priv_data
;
144 const uint16_t *src
[3] = {(uint16_t*)pic
->data
[0],
145 (uint16_t*)pic
->data
[1],
146 (uint16_t*)pic
->data
[2]};
148 pad
= avctx
->width
*6;
149 pad
= (FFALIGN(pad
, 4) - pad
) >> 1;
150 for (y
= 0; y
< avctx
->height
; y
++) {
151 for (x
= 0; x
< avctx
->width
; x
++) {
154 value
[1] = AV_RB16(src
[0] + x
) << 4;
155 value
[2] = AV_RB16(src
[1] + x
) << 4;
156 value
[0] = AV_RB16(src
[2] + x
) << 4;
158 value
[1] = AV_RL16(src
[0] + x
) << 4;
159 value
[2] = AV_RL16(src
[1] + x
) << 4;
160 value
[0] = AV_RL16(src
[2] + x
) << 4;
162 for (i
= 0; i
< 3; i
++)
163 write16(dst
++, value
[i
]);
165 for (i
= 0; i
< pad
; i
++)
167 for (i
= 0; i
< 3; i
++)
168 src
[i
] += pic
->linesize
[i
]/2;
172 static int encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
173 const AVFrame
*frame
, int *got_packet
)
175 DPXContext
*s
= avctx
->priv_data
;
176 int size
, ret
, need_align
, len
;
179 #define HEADER_SIZE 1664 /* DPX Generic header */
180 if (s
->bits_per_component
== 10)
181 size
= avctx
->height
* avctx
->width
* 4;
182 else if (s
->bits_per_component
== 12) {
183 // 3 components, 12 bits put on 16 bits
184 len
= avctx
->width
*6;
185 size
= FFALIGN(len
, 4);
186 need_align
= size
- len
;
187 size
*= avctx
->height
;
189 // N components, M bits
190 len
= avctx
->width
* s
->num_components
* s
->bits_per_component
>> 3;
191 size
= FFALIGN(len
, 4);
192 need_align
= size
- len
;
193 size
*= avctx
->height
;
195 if ((ret
= ff_alloc_packet2(avctx
, pkt
, size
+ HEADER_SIZE
)) < 0)
199 memset(buf
, 0, HEADER_SIZE
);
201 /* File information header */
202 write32(buf
, MKBETAG('S','D','P','X'));
203 write32(buf
+ 4, HEADER_SIZE
);
204 memcpy (buf
+ 8, "V1.0", 4);
205 write32(buf
+ 20, 1); /* new image */
206 write32(buf
+ 24, HEADER_SIZE
);
207 if (!(avctx
->flags
& CODEC_FLAG_BITEXACT
))
208 memcpy (buf
+ 160, LIBAVCODEC_IDENT
, FFMIN(sizeof(LIBAVCODEC_IDENT
), 100));
209 write32(buf
+ 660, 0xFFFFFFFF); /* unencrypted */
211 /* Image information header */
212 write16(buf
+ 768, 0); /* orientation; left to right, top to bottom */
213 write16(buf
+ 770, 1); /* number of elements */
214 write32(buf
+ 772, avctx
->width
);
215 write32(buf
+ 776, avctx
->height
);
216 buf
[800] = s
->descriptor
;
217 buf
[801] = 2; /* linear transfer */
218 buf
[802] = 2; /* linear colorimetric */
219 buf
[803] = s
->bits_per_component
;
220 write16(buf
+ 804, (s
->bits_per_component
== 10 || s
->bits_per_component
== 12) ?
221 1 : 0); /* packing method */
222 write32(buf
+ 808, HEADER_SIZE
); /* data offset */
224 /* Image source information header */
225 write32(buf
+ 1628, avctx
->sample_aspect_ratio
.num
);
226 write32(buf
+ 1632, avctx
->sample_aspect_ratio
.den
);
228 switch(s
->bits_per_component
) {
233 const uint8_t *src
= frame
->data
[0];
234 uint8_t *dst
= pkt
->data
+ HEADER_SIZE
;
235 size
= (len
+ need_align
) * avctx
->height
;
236 for (j
=0; j
<avctx
->height
; j
++) {
237 memcpy(dst
, src
, len
);
238 memset(dst
+ len
, 0, need_align
);
239 dst
+= len
+ need_align
;
240 src
+= frame
->linesize
[0];
243 size
= avpicture_layout((const AVPicture
*)frame
, avctx
->pix_fmt
,
244 avctx
->width
, avctx
->height
,
245 buf
+ HEADER_SIZE
, pkt
->size
- HEADER_SIZE
);
252 encode_gbrp10(avctx
, (const AVPicture
*)frame
, buf
+ HEADER_SIZE
);
254 encode_rgb48_10bit(avctx
, (const AVPicture
*)frame
, buf
+ HEADER_SIZE
);
257 encode_gbrp12(avctx
, (const AVPicture
*)frame
, (uint16_t*)(buf
+ HEADER_SIZE
));
260 av_log(avctx
, AV_LOG_ERROR
, "Unsupported bit depth: %d\n", s
->bits_per_component
);
266 write32(buf
+ 16, size
); /* file size */
268 pkt
->flags
|= AV_PKT_FLAG_KEY
;
274 AVCodec ff_dpx_encoder
= {
276 .long_name
= NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
277 .type
= AVMEDIA_TYPE_VIDEO
,
278 .id
= AV_CODEC_ID_DPX
,
279 .priv_data_size
= sizeof(DPXContext
),
281 .encode2
= encode_frame
,
282 .pix_fmts
= (const enum AVPixelFormat
[]){
284 AV_PIX_FMT_RGB24
, AV_PIX_FMT_RGBA
, AV_PIX_FMT_ABGR
,
285 AV_PIX_FMT_GRAY16LE
, AV_PIX_FMT_GRAY16BE
,
286 AV_PIX_FMT_RGB48LE
, AV_PIX_FMT_RGB48BE
,
287 AV_PIX_FMT_RGBA64LE
, AV_PIX_FMT_RGBA64BE
,
288 AV_PIX_FMT_GBRP10LE
, AV_PIX_FMT_GBRP10BE
,
289 AV_PIX_FMT_GBRP12LE
, AV_PIX_FMT_GBRP12BE
,