From af55a9d80a6f50a806a40ca1641de1372d64ee99 Mon Sep 17 00:00:00 2001 From: Piotr Bandurski Date: Thu, 8 Mar 2012 23:34:36 +0100 Subject: [PATCH] iff: add support for IFF DEEP Fixes trac #1045. Thanks to Peter Ross for his help with this patch. Reviewed-by: Paul B Mahol Signed-off-by: Michael Niedermayer --- libavcodec/iff.c | 10 +++++++++- libavformat/iff.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/libavcodec/iff.c b/libavcodec/iff.c index 2185946649..9b0960447e 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -316,7 +316,8 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) || (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8; } else if (avctx->bits_per_coded_sample <= 32) { - avctx->pix_fmt = PIX_FMT_BGR32; + if (avctx->codec_tag != MKTAG('D','E','E','P')) + avctx->pix_fmt = PIX_FMT_BGR32; } else { return AVERROR_INVALIDDATA; } @@ -503,6 +504,13 @@ static int decode_frame_ilbm(AVCodecContext *avctx, decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); } } + } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { + int raw_width = avctx->width * (av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]) >> 3); + for(y = 0; y < avctx->height && buf < buf_end; y++ ) { + uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]]; + memcpy(row, buf, FFMIN(raw_width, buf_end - buf)); + buf += raw_width; + } } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { for(y = 0; y < avctx->height; y++ ) { diff --git a/libavformat/iff.c b/libavformat/iff.c index 6566a15ddb..7473c182b0 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -42,9 +42,11 @@ #define ID_PBM MKTAG('P','B','M',' ') #define ID_ILBM MKTAG('I','L','B','M') #define ID_BMHD MKTAG('B','M','H','D') +#define ID_DGBL MKTAG('D','G','B','L') #define ID_CAMG MKTAG('C','A','M','G') #define ID_CMAP MKTAG('C','M','A','P') #define ID_ACBM MKTAG('A','C','B','M') +#define ID_DEEP MKTAG('D','E','E','P') #define ID_FORM MKTAG('F','O','R','M') #define ID_ANNO MKTAG('A','N','N','O') @@ -57,7 +59,9 @@ #define ID_TEXT MKTAG('T','E','X','T') #define ID_ABIT MKTAG('A','B','I','T') #define ID_BODY MKTAG('B','O','D','Y') +#define ID_DBOD MKTAG('D','B','O','D') #define ID_ANNO MKTAG('A','N','N','O') +#define ID_DPEL MKTAG('D','P','E','L') #define LEFT 2 #define RIGHT 4 @@ -121,11 +125,14 @@ static int iff_probe(AVProbeData *p) const uint8_t *d = p->buf; if ( AV_RL32(d) == ID_FORM && - (AV_RL32(d+8) == ID_8SVX || AV_RL32(d+8) == ID_PBM || AV_RL32(d+8) == ID_ILBM || AV_RL32(d+8) == ID_ACBM) ) + (AV_RL32(d+8) == ID_8SVX || AV_RL32(d+8) == ID_PBM || AV_RL32(d+8) == ID_ACBM || AV_RL32(d+8) == ID_DEEP || AV_RL32(d+8) == ID_ILBM) ) return AVPROBE_SCORE_MAX; return 0; } +static const uint8_t deep_rgb24[] = {0, 0, 0, 3, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8}; +static const uint8_t deep_rgba[] = {0, 0, 0, 4, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8}; + static int iff_read_header(AVFormatContext *s) { IffDemuxContext *iff = s->priv_data; @@ -136,6 +143,8 @@ static int iff_read_header(AVFormatContext *s) uint32_t screenmode = 0; unsigned transparency = 0; unsigned masking = 0; // no mask + uint8_t fmt[16]; + int fmt_size; st = avformat_new_stream(s, NULL); if (!st) @@ -170,6 +179,7 @@ static int iff_read_header(AVFormatContext *s) case ID_ABIT: case ID_BODY: + case ID_DBOD: iff->body_pos = avio_tell(pb); iff->body_size = data_size; break; @@ -218,6 +228,38 @@ static int iff_read_header(AVFormatContext *s) } break; + case ID_DPEL: + if (data_size < 4 || (data_size & 3)) + return AVERROR_INVALIDDATA; + if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0) + return fmt_size; + if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24))) + st->codec->pix_fmt = PIX_FMT_RGB24; + else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba))) + st->codec->pix_fmt = PIX_FMT_RGBA; + else { + av_log_ask_for_sample(NULL, "unsupported color format\n"); + return AVERROR_PATCHWELCOME; + } + break; + + case ID_DGBL: + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + if (data_size < 8) + return AVERROR_INVALIDDATA; + st->codec->width = avio_rb16(pb); + st->codec->height = avio_rb16(pb); + iff->bitmap_compression = avio_rb16(pb); + if (iff->bitmap_compression != 0) { + av_log(s, AV_LOG_ERROR, + "compression %i not supported\n", iff->bitmap_compression); + return AVERROR_PATCHWELCOME; + } + st->sample_aspect_ratio.num = avio_r8(pb); + st->sample_aspect_ratio.den = avio_r8(pb); + st->codec->bits_per_coded_sample = 24; + break; + case ID_ANNO: case ID_TEXT: metadata_tag = "comment"; break; case ID_AUTH: metadata_tag = "artist"; break;