[FFmpeg-cvslog] r22977 - trunk/libavformat/iff.c

rbultje subversion
Tue Apr 27 16:03:48 CEST 2010


Author: rbultje
Date: Tue Apr 27 16:03:47 2010
New Revision: 22977

Log:
Make the IFF demuxer a little more standards-compliant, e.g. respect the size
fields of common media header chunks (these can have different sizes depending
on the type of IFF file you read), better handle odd sizes (like RIFF, every
field is padded to word) and handle headerchunks after the BODY chunk.

Patch by Sebastian Vater <cdgs.basty googlemail com>.

Modified:
   trunk/libavformat/iff.c

Modified: trunk/libavformat/iff.c
==============================================================================
--- trunk/libavformat/iff.c	Tue Apr 27 00:39:08 2010	(r22976)
+++ trunk/libavformat/iff.c	Tue Apr 27 16:03:47 2010	(r22977)
@@ -2,6 +2,7 @@
  * IFF (.iff) file demuxer
  * Copyright (c) 2008 Jaikrishnan Menon <realityman at gmx.net>
  * Copyright (c) 2010 Peter Ross <pross at xvid.org>
+ * Copyright (c) 2010 Sebastian Vater <cdgs.basty at googlemail.com>
  *
  * This file is part of FFmpeg.
  *
@@ -72,6 +73,7 @@ typedef enum {
 } bitmap_compression_type;
 
 typedef struct {
+    uint64_t  body_pos;
     uint32_t  body_size;
     uint32_t  sent_bytes;
     uint32_t  audio_frame_count;
@@ -107,7 +109,6 @@ static int iff_read_header(AVFormatConte
     ByteIOContext *pb = s->pb;
     AVStream *st;
     uint32_t chunk_id, data_size;
-    int padding, done = 0;
     int compression = -1;
     char *buf;
 
@@ -120,27 +121,34 @@ static int iff_read_header(AVFormatConte
     // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
     st->codec->codec_tag = get_le32(pb);
 
-    while(!done && !url_feof(pb)) {
+    while(!url_feof(pb)) {
+        uint64_t orig_pos;
         chunk_id = get_le32(pb);
         data_size = get_be32(pb);
-        padding = data_size & 1;
+        orig_pos = url_ftell(pb);
 
         switch(chunk_id) {
         case ID_VHDR:
             st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+
+            if (data_size < 14)
+                return AVERROR_INVALIDDATA;
             url_fskip(pb, 12);
             st->codec->sample_rate = get_be16(pb);
+            if (data_size >= 16) {
             url_fskip(pb, 1);
             compression            = get_byte(pb);
-            url_fskip(pb, 4);
+            }
             break;
 
         case ID_BODY:
+            iff->body_pos = url_ftell(pb);
             iff->body_size = data_size;
-            done = 1;
             break;
 
         case ID_CHAN:
+            if (data_size < 4)
+                return AVERROR_INVALIDDATA;
             st->codec->channels = (get_be32(pb) < 6) ? 1 : 2;
             break;
 
@@ -155,16 +163,21 @@ static int iff_read_header(AVFormatConte
 
         case ID_BMHD:
             st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;
+            if (data_size <= 8)
+                return AVERROR_INVALIDDATA;
             st->codec->width                 = get_be16(pb);
             st->codec->height                = get_be16(pb);
             url_fskip(pb, 4); // x, y offset
             st->codec->bits_per_coded_sample = get_byte(pb);
+            if (data_size >= 11) {
             url_fskip(pb, 1); // masking
             compression                      = get_byte(pb);
+            }
+            if (data_size >= 16) {
             url_fskip(pb, 3); // paddding, transparent
             st->sample_aspect_ratio.num      = get_byte(pb);
             st->sample_aspect_ratio.den      = get_byte(pb);
-            url_fskip(pb, 4); // source page width, height
+            }
             break;
 
         case ID_ANNO:
@@ -175,13 +188,13 @@ static int iff_read_header(AVFormatConte
             buf[data_size] = 0;
             av_metadata_set2(&s->metadata, "comment", buf, AV_METADATA_DONT_STRDUP_VAL);
             break;
-
-        default:
-            url_fseek(pb, data_size + padding, SEEK_CUR);
-            break;
         }
+
+        url_fskip(pb, data_size - (url_ftell(pb) - orig_pos) + (data_size & 1));
     }
 
+    url_fseek(pb, iff->body_pos, SEEK_SET);
+
     switch(st->codec->codec_type) {
     case AVMEDIA_TYPE_AUDIO:
         av_set_pts_info(st, 32, 1, st->codec->sample_rate);



More information about the ffmpeg-cvslog mailing list