summaryrefslogtreecommitdiffstats
path: root/libavcodec/dpx.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/dpx.c')
-rw-r--r--libavcodec/dpx.c108
1 files changed, 71 insertions, 37 deletions
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 18d74fe..71cf439 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -2,20 +2,20 @@
* DPX (.dpx) image decoder
* Copyright (c) 2009 Jimmy Christensen
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -41,14 +41,6 @@ static unsigned int read32(const uint8_t **ptr, int is_big)
return temp;
}
-static inline unsigned make_16bit(unsigned value)
-{
- // mask away invalid bits
- value &= 0xFFC0;
- // correctly expand to 16 bits
- return value + (value >> 10);
-}
-
static int decode_frame(AVCodecContext *avctx,
void *data,
int *data_size,
@@ -60,12 +52,13 @@ static int decode_frame(AVCodecContext *avctx,
DPXContext *const s = avctx->priv_data;
AVFrame *picture = data;
AVFrame *const p = &s->picture;
- uint8_t *ptr;
+ uint8_t *ptr[AV_NUM_DATA_POINTERS];
unsigned int offset;
int magic_num, endian;
- int x, y;
+ int x, y, i;
int w, h, stride, bits_per_color, descriptor, elements, target_packet_size, source_packet_size;
+ int planar;
unsigned int rgbBuffer;
@@ -110,6 +103,12 @@ static int decode_frame(AVCodecContext *avctx,
buf += 825;
avctx->sample_aspect_ratio.num = read32(&buf, endian);
avctx->sample_aspect_ratio.den = read32(&buf, endian);
+ if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
+ av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
+ avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den,
+ 0x10000);
+ else
+ avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
switch (descriptor) {
case 51: // RGBA
@@ -132,21 +131,33 @@ static int decode_frame(AVCodecContext *avctx,
}
source_packet_size = elements;
target_packet_size = elements;
+ planar = 0;
break;
case 10:
- avctx->pix_fmt = PIX_FMT_RGB48;
+ avctx->pix_fmt = PIX_FMT_GBRP10;
target_packet_size = 6;
source_packet_size = 4;
+ planar = 1;
break;
case 12:
- case 16:
if (endian) {
- avctx->pix_fmt = PIX_FMT_RGB48BE;
+ avctx->pix_fmt = elements == 4 ? PIX_FMT_GBRP12BE : PIX_FMT_GBRP12BE;
} else {
- avctx->pix_fmt = PIX_FMT_RGB48LE;
+ avctx->pix_fmt = elements == 4 ? PIX_FMT_GBRP12LE : PIX_FMT_GBRP12LE;
}
target_packet_size = 6;
+ source_packet_size = 6;
+ planar = 1;
+ break;
+ case 16:
+ if (endian) {
+ avctx->pix_fmt = elements == 4 ? PIX_FMT_RGBA64BE : PIX_FMT_RGB48BE;
+ } else {
+ avctx->pix_fmt = elements == 4 ? PIX_FMT_RGBA64LE : PIX_FMT_RGB48LE;
+ }
+ target_packet_size =
source_packet_size = elements * 2;
+ planar = 0;
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported color depth : %d\n", bits_per_color);
@@ -167,7 +178,8 @@ static int decode_frame(AVCodecContext *avctx,
// Move pointer to offset from start of file
buf = avpkt->data + offset;
- ptr = p->data[0];
+ for (i=0; i<AV_NUM_DATA_POINTERS; i++)
+ ptr[i] = p->data[i];
stride = p->linesize[0];
if (source_packet_size*avctx->width*avctx->height > buf_end - buf) {
@@ -177,35 +189,56 @@ static int decode_frame(AVCodecContext *avctx,
switch (bits_per_color) {
case 10:
for (x = 0; x < avctx->height; x++) {
- uint16_t *dst = (uint16_t*)ptr;
+ uint16_t *dst[3] = {(uint16_t*)ptr[0],
+ (uint16_t*)ptr[1],
+ (uint16_t*)ptr[2]};
for (y = 0; y < avctx->width; y++) {
rgbBuffer = read32(&buf, endian);
- // Read out the 10-bit colors and convert to 16-bit
- *dst++ = make_16bit(rgbBuffer >> 16);
- *dst++ = make_16bit(rgbBuffer >> 6);
- *dst++ = make_16bit(rgbBuffer << 4);
+ *dst[0]++ = (rgbBuffer >> 12) & 0x3FF;
+ *dst[1]++ = (rgbBuffer >> 2) & 0x3FF;
+ *dst[2]++ = (rgbBuffer >> 22) & 0x3FF;
}
- ptr += stride;
+ for (i=0; i<3; i++)
+ ptr[i] += p->linesize[i];
}
break;
case 8:
- case 12: // Treat 12-bit as 16-bit
+ case 12:
case 16:
- if (source_packet_size == target_packet_size) {
+ if (planar) {
+ int source_bpc = target_packet_size / elements;
+ int target_bpc = target_packet_size / elements;
for (x = 0; x < avctx->height; x++) {
- memcpy(ptr, buf, target_packet_size*avctx->width);
- ptr += stride;
- buf += source_packet_size*avctx->width;
+ uint8_t *dst[AV_NUM_DATA_POINTERS];
+ for (i=0; i<elements; i++)
+ dst[i] = ptr[i];
+ for (y = 0; y < avctx->width; y++) {
+ for (i=0; i<3; i++) {
+ memcpy(dst[i], buf, FFMIN(source_bpc, target_bpc));
+ dst[i] += target_bpc;
+ buf += source_bpc;
+ }
+ }
+ for (i=0; i<elements; i++)
+ ptr[i] += p->linesize[i];
}
} else {
- for (x = 0; x < avctx->height; x++) {
- uint8_t *dst = ptr;
- for (y = 0; y < avctx->width; y++) {
- memcpy(dst, buf, target_packet_size);
- dst += target_packet_size;
- buf += source_packet_size;
+ if (source_packet_size == target_packet_size) {
+ for (x = 0; x < avctx->height; x++) {
+ memcpy(ptr[0], buf, target_packet_size*avctx->width);
+ ptr[0] += stride;
+ buf += source_packet_size*avctx->width;
+ }
+ } else {
+ for (x = 0; x < avctx->height; x++) {
+ uint8_t *dst = ptr[0];
+ for (y = 0; y < avctx->width; y++) {
+ memcpy(dst, buf, target_packet_size);
+ dst += target_packet_size;
+ buf += source_packet_size;
+ }
+ ptr[0] += stride;
}
- ptr += stride;
}
}
break;
@@ -242,5 +275,6 @@ AVCodec ff_dpx_decoder = {
.init = decode_init,
.close = decode_end,
.decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("DPX image"),
};
OpenPOWER on IntegriCloud