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 Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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 typedef struct DPXContext {
30 } DPXContext;
31 
32 
33 static unsigned int read32(const uint8_t **ptr, int is_big)
34 {
35  unsigned int temp;
36  if (is_big) {
37  temp = AV_RB32(*ptr);
38  } else {
39  temp = AV_RL32(*ptr);
40  }
41  *ptr += 4;
42  return temp;
43 }
44 
45 static inline unsigned make_16bit(unsigned value)
46 {
47  // mask away invalid bits
48  value &= 0xFFC0;
49  // correctly expand to 16 bits
50  return value + (value >> 10);
51 }
52 
53 static int decode_frame(AVCodecContext *avctx,
54  void *data,
55  int *got_frame,
56  AVPacket *avpkt)
57 {
58  const uint8_t *buf = avpkt->data;
59  const uint8_t *buf_end = avpkt->data + avpkt->size;
60  int buf_size = avpkt->size;
61  DPXContext *const s = avctx->priv_data;
62  AVFrame *picture = data;
63  AVFrame *const p = &s->picture;
64  uint8_t *ptr;
65 
66  unsigned int offset;
67  int magic_num, endian;
68  int x, y;
69  int w, h, stride, bits_per_color, descriptor, elements, target_packet_size, source_packet_size;
70 
71  unsigned int rgbBuffer;
72 
73  if (avpkt->size <= 1634) {
74  av_log(avctx, AV_LOG_ERROR, "Packet too small for DPX header\n");
75  return AVERROR_INVALIDDATA;
76  }
77 
78  magic_num = AV_RB32(buf);
79  buf += 4;
80 
81  /* Check if the files "magic number" is "SDPX" which means it uses
82  * big-endian or XPDS which is for little-endian files */
83  if (magic_num == AV_RL32("SDPX")) {
84  endian = 0;
85  } else if (magic_num == AV_RB32("SDPX")) {
86  endian = 1;
87  } else {
88  av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
89  return -1;
90  }
91 
92  offset = read32(&buf, endian);
93  if (avpkt->size <= offset) {
94  av_log(avctx, AV_LOG_ERROR, "Invalid data start offset\n");
95  return AVERROR_INVALIDDATA;
96  }
97  // Need to end in 0x304 offset from start of file
98  buf = avpkt->data + 0x304;
99  w = read32(&buf, endian);
100  h = read32(&buf, endian);
101 
102  // Need to end in 0x320 to read the descriptor
103  buf += 20;
104  descriptor = buf[0];
105 
106  // Need to end in 0x323 to read the bits per color
107  buf += 3;
108  avctx->bits_per_raw_sample =
109  bits_per_color = buf[0];
110 
111  buf += 825;
112  avctx->sample_aspect_ratio.num = read32(&buf, endian);
113  avctx->sample_aspect_ratio.den = read32(&buf, endian);
114 
115  switch (descriptor) {
116  case 51: // RGBA
117  elements = 4;
118  break;
119  case 50: // RGB
120  elements = 3;
121  break;
122  default:
123  av_log(avctx, AV_LOG_ERROR, "Unsupported descriptor %d\n", descriptor);
124  return -1;
125  }
126 
127  switch (bits_per_color) {
128  case 8:
129  if (elements == 4) {
130  avctx->pix_fmt = AV_PIX_FMT_RGBA;
131  } else {
132  avctx->pix_fmt = AV_PIX_FMT_RGB24;
133  }
134  source_packet_size = elements;
135  target_packet_size = elements;
136  break;
137  case 10:
138  avctx->pix_fmt = AV_PIX_FMT_RGB48;
139  target_packet_size = 6;
140  source_packet_size = 4;
141  break;
142  case 12:
143  case 16:
144  if (endian) {
145  avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
146  } else {
147  avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
148  }
149  target_packet_size = 6;
150  source_packet_size = elements * 2;
151  break;
152  default:
153  av_log(avctx, AV_LOG_ERROR, "Unsupported color depth : %d\n", bits_per_color);
154  return -1;
155  }
156 
157  if (s->picture.data[0])
158  avctx->release_buffer(avctx, &s->picture);
159  if (av_image_check_size(w, h, 0, avctx))
160  return -1;
161  if (w != avctx->width || h != avctx->height)
162  avcodec_set_dimensions(avctx, w, h);
163  if (ff_get_buffer(avctx, p) < 0) {
164  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
165  return -1;
166  }
167 
168  // Move pointer to offset from start of file
169  buf = avpkt->data + offset;
170 
171  ptr = p->data[0];
172  stride = p->linesize[0];
173 
174  if (source_packet_size*avctx->width*avctx->height > buf_end - buf) {
175  av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
176  return -1;
177  }
178  switch (bits_per_color) {
179  case 10:
180  for (x = 0; x < avctx->height; x++) {
181  uint16_t *dst = (uint16_t*)ptr;
182  for (y = 0; y < avctx->width; y++) {
183  rgbBuffer = read32(&buf, endian);
184  // Read out the 10-bit colors and convert to 16-bit
185  *dst++ = make_16bit(rgbBuffer >> 16);
186  *dst++ = make_16bit(rgbBuffer >> 6);
187  *dst++ = make_16bit(rgbBuffer << 4);
188  }
189  ptr += stride;
190  }
191  break;
192  case 8:
193  case 12: // Treat 12-bit as 16-bit
194  case 16:
195  if (source_packet_size == target_packet_size) {
196  for (x = 0; x < avctx->height; x++) {
197  memcpy(ptr, buf, target_packet_size*avctx->width);
198  ptr += stride;
199  buf += source_packet_size*avctx->width;
200  }
201  } else {
202  for (x = 0; x < avctx->height; x++) {
203  uint8_t *dst = ptr;
204  for (y = 0; y < avctx->width; y++) {
205  memcpy(dst, buf, target_packet_size);
206  dst += target_packet_size;
207  buf += source_packet_size;
208  }
209  ptr += stride;
210  }
211  }
212  break;
213  }
214 
215  *picture = s->picture;
216  *got_frame = 1;
217 
218  return buf_size;
219 }
220 
222 {
223  DPXContext *s = avctx->priv_data;
225  avctx->coded_frame = &s->picture;
226  return 0;
227 }
228 
230 {
231  DPXContext *s = avctx->priv_data;
232  if (s->picture.data[0])
233  avctx->release_buffer(avctx, &s->picture);
234 
235  return 0;
236 }
237 
239  .name = "dpx",
240  .type = AVMEDIA_TYPE_VIDEO,
241  .id = AV_CODEC_ID_DPX,
242  .priv_data_size = sizeof(DPXContext),
243  .init = decode_init,
244  .close = decode_end,
245  .decode = decode_frame,
246  .long_name = NULL_IF_CONFIG_SMALL("DPX image"),
247  .capabilities = CODEC_CAP_DR1,
248 };
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dpx.c:53
This structure describes decoded (raw) audio or video data.
Definition: avcodec.h:989
void(* release_buffer)(struct AVCodecContext *c, AVFrame *pic)
Called to release buffers which were allocated with get_buffer.
Definition: avcodec.h:2259
misc image utilities
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:67
AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:2725
int num
numerator
Definition: rational.h:44
void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
Definition: utils.c:149
int size
Definition: avcodec.h:916
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
Definition: avcodec.h:1724
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1533
static av_cold int decode_end(AVCodecContext *avctx)
Definition: dpx.c:229
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:2711
int stride
Definition: mace.c:144
AVCodec.
Definition: avcodec.h:2960
static int decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)
Definition: mimic.c:228
uint8_t
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as lit...
Definition: pixfmt.h:109
AVCodec ff_dpx_decoder
Definition: dpx.c:238
#define AV_RB32
Definition: intreadwrite.h:130
const char data[16]
Definition: mxf.c:66
uint8_t * data
Definition: avcodec.h:915
static unsigned int read32(const uint8_t **ptr, int is_big)
Definition: dpx.c:33
static int init(AVCodecParserContext *s)
Definition: h264_parser.c:335
Definition: dpx.c:28
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:88
struct DPXContext DPXContext
static unsigned make_16bit(unsigned value)
Definition: dpx.c:45
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:146
const char * name
Name of the codec implementation.
Definition: avcodec.h:2967
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:94
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:220
static AVFrame * picture
int width
picture width / height.
Definition: avcodec.h:1508
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
Get a buffer for a frame.
Definition: utils.c:464
#define AV_RL32
Definition: intreadwrite.h:146
static av_cold int decode_init(AVCodecContext *avctx)
Definition: dpx.c:221
external API header
int linesize[AV_NUM_DATA_POINTERS]
Size, in bytes, of the data for each picture/channel plane.
Definition: avcodec.h:1008
main external API structure.
Definition: avcodec.h:1339
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:326
void avcodec_get_frame_defaults(AVFrame *frame)
Set the fields of the given AVFrame to default values.
Definition: utils.c:602
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: avcodec.h:997
common internal api header.
packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big...
Definition: pixfmt.h:108
int den
denominator
Definition: rational.h:45
void * priv_data
Definition: avcodec.h:1382
AVFrame picture
Definition: dpx.c:29
This structure stores compressed data.
Definition: avcodec.h:898