2 * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
3 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 * by Jaikrishnan Menon
27 * for more information on the .iff file format, visit:
28 * http://wiki.multimedia.cx/index.php?title=IFF
33 #include "libavutil/avassert.h"
34 #include "libavutil/channel_layout.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/dict.h"
37 #include "libavcodec/bytestream.h"
42 #define ID_8SVX MKTAG('8','S','V','X')
43 #define ID_16SV MKTAG('1','6','S','V')
44 #define ID_MAUD MKTAG('M','A','U','D')
45 #define ID_MHDR MKTAG('M','H','D','R')
46 #define ID_MDAT MKTAG('M','D','A','T')
47 #define ID_VHDR MKTAG('V','H','D','R')
48 #define ID_ATAK MKTAG('A','T','A','K')
49 #define ID_RLSE MKTAG('R','L','S','E')
50 #define ID_CHAN MKTAG('C','H','A','N')
51 #define ID_PBM MKTAG('P','B','M',' ')
52 #define ID_ILBM MKTAG('I','L','B','M')
53 #define ID_BMHD MKTAG('B','M','H','D')
54 #define ID_DGBL MKTAG('D','G','B','L')
55 #define ID_CAMG MKTAG('C','A','M','G')
56 #define ID_CMAP MKTAG('C','M','A','P')
57 #define ID_ACBM MKTAG('A','C','B','M')
58 #define ID_DEEP MKTAG('D','E','E','P')
59 #define ID_RGB8 MKTAG('R','G','B','8')
60 #define ID_RGBN MKTAG('R','G','B','N')
61 #define ID_DSD MKTAG('D','S','D',' ')
62 #define ID_DST MKTAG('D','S','T',' ')
63 #define ID_DSTC MKTAG('D','S','T','C')
64 #define ID_DSTF MKTAG('D','S','T','F')
65 #define ID_FRTE MKTAG('F','R','T','E')
66 #define ID_ANIM MKTAG('A','N','I','M')
67 #define ID_ANHD MKTAG('A','N','H','D')
68 #define ID_DLTA MKTAG('D','L','T','A')
69 #define ID_DPAN MKTAG('D','P','A','N')
71 #define ID_FORM MKTAG('F','O','R','M')
72 #define ID_FRM8 MKTAG('F','R','M','8')
73 #define ID_ANNO MKTAG('A','N','N','O')
74 #define ID_AUTH MKTAG('A','U','T','H')
75 #define ID_CHRS MKTAG('C','H','R','S')
76 #define ID_COPYRIGHT MKTAG('(','c',')',' ')
77 #define ID_CSET MKTAG('C','S','E','T')
78 #define ID_FVER MKTAG('F','V','E','R')
79 #define ID_NAME MKTAG('N','A','M','E')
80 #define ID_TEXT MKTAG('T','E','X','T')
81 #define ID_ABIT MKTAG('A','B','I','T')
82 #define ID_BODY MKTAG('B','O','D','Y')
83 #define ID_DBOD MKTAG('D','B','O','D')
84 #define ID_DPEL MKTAG('D','P','E','L')
85 #define ID_DLOC MKTAG('D','L','O','C')
86 #define ID_TVDC MKTAG('T','V','D','C')
93 * This number of bytes if added at the beginning of each AVPacket
94 * which contain additional information about video properties
95 * which has to be shared between demuxer and decoder.
96 * This number may change between frames, e.g. the demuxer might
97 * set it to smallest possible size of 2 to indicate that there's
98 * no extradata changing in this frame.
100 #define IFF_EXTRA_VIDEO_SIZE 41
106 } svx8_compression_type
;
108 typedef struct IffDemuxContext
{
109 int is_64bit
; ///< chunk size is 64-bit
113 svx8_compression_type svx8_compression
;
115 unsigned maud_compression
;
116 unsigned bitmap_compression
; ///< delta compression method used
117 unsigned bpp
; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
118 unsigned ham
; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
119 unsigned flags
; ///< 1 for EHB, 0 is no extra half darkening
120 unsigned transparency
; ///< transparency color index in palette
121 unsigned masking
; ///< masking method used
122 uint8_t tvdc
[32]; ///< TVDC lookup table
126 /* Metadata string read */
127 static int get_metadata(AVFormatContext
*s
,
128 const char *const tag
,
129 const unsigned data_size
)
131 uint8_t *buf
= ((data_size
+ 1) == 0) ? NULL
: av_malloc(data_size
+ 1);
134 return AVERROR(ENOMEM
);
136 if (avio_read(s
->pb
, buf
, data_size
) != data_size
) {
141 av_dict_set(&s
->metadata
, tag
, buf
, AV_DICT_DONT_STRDUP_VAL
);
145 static int iff_probe(AVProbeData
*p
)
147 const uint8_t *d
= p
->buf
;
149 if ( (AV_RL32(d
) == ID_FORM
&&
150 (AV_RL32(d
+8) == ID_8SVX
||
151 AV_RL32(d
+8) == ID_16SV
||
152 AV_RL32(d
+8) == ID_MAUD
||
153 AV_RL32(d
+8) == ID_PBM
||
154 AV_RL32(d
+8) == ID_ACBM
||
155 AV_RL32(d
+8) == ID_DEEP
||
156 AV_RL32(d
+8) == ID_ILBM
||
157 AV_RL32(d
+8) == ID_RGB8
||
158 AV_RL32(d
+8) == ID_ANIM
||
159 AV_RL32(d
+8) == ID_RGBN
)) ||
160 (AV_RL32(d
) == ID_FRM8
&& AV_RL32(d
+12) == ID_DSD
))
161 return AVPROBE_SCORE_MAX
;
165 static const AVCodecTag dsd_codec_tags
[] = {
166 { AV_CODEC_ID_DSD_MSBF
, ID_DSD
},
167 { AV_CODEC_ID_DST
, ID_DST
},
168 { AV_CODEC_ID_NONE
, 0 },
172 #define DSD_SLFT MKTAG('S','L','F','T')
173 #define DSD_SRGT MKTAG('S','R','G','T')
174 #define DSD_MLFT MKTAG('M','L','F','T')
175 #define DSD_MRGT MKTAG('M','R','G','T')
176 #define DSD_C MKTAG('C',' ',' ',' ')
177 #define DSD_LS MKTAG('L','S',' ',' ')
178 #define DSD_RS MKTAG('R','S',' ',' ')
179 #define DSD_LFE MKTAG('L','F','E',' ')
181 static const uint32_t dsd_stereo
[] = { DSD_SLFT
, DSD_SRGT
};
182 static const uint32_t dsd_5point0
[] = { DSD_MLFT
, DSD_MRGT
, DSD_C
, DSD_LS
, DSD_RS
};
183 static const uint32_t dsd_5point1
[] = { DSD_MLFT
, DSD_MRGT
, DSD_C
, DSD_LFE
, DSD_LS
, DSD_RS
};
187 const uint32_t * dsd_layout
;
190 static const DSDLayoutDesc dsd_channel_layout
[] = {
191 { AV_CH_LAYOUT_STEREO
, dsd_stereo
},
192 { AV_CH_LAYOUT_5POINT0
, dsd_5point0
},
193 { AV_CH_LAYOUT_5POINT1
, dsd_5point1
},
196 static const uint64_t dsd_loudspeaker_config
[] = {
199 AV_CH_LAYOUT_5POINT0
, AV_CH_LAYOUT_5POINT1
,
202 static const char * dsd_source_comment
[] = {
203 "dsd_source_comment",
204 "analogue_source_comment",
205 "pcm_source_comment",
208 static const char * dsd_history_comment
[] = {
216 static int parse_dsd_diin(AVFormatContext
*s
, AVStream
*st
, uint64_t eof
)
218 AVIOContext
*pb
= s
->pb
;
220 while (avio_tell(pb
) + 12 <= eof
&& !avio_feof(pb
)) {
221 uint32_t tag
= avio_rl32(pb
);
222 uint64_t size
= avio_rb64(pb
);
223 uint64_t orig_pos
= avio_tell(pb
);
224 const char * metadata_tag
= NULL
;
226 if (size
>= INT64_MAX
)
227 return AVERROR_INVALIDDATA
;
230 case MKTAG('D','I','A','R'): metadata_tag
= "artist"; break;
231 case MKTAG('D','I','T','I'): metadata_tag
= "title"; break;
234 if (metadata_tag
&& size
> 4) {
235 unsigned int tag_size
= avio_rb32(pb
);
236 int ret
= get_metadata(s
, metadata_tag
, FFMIN(tag_size
, size
- 4));
238 av_log(s
, AV_LOG_ERROR
, "cannot allocate metadata tag %s!\n", metadata_tag
);
243 avio_skip(pb
, size
- (avio_tell(pb
) - orig_pos
) + (size
& 1));
249 static int parse_dsd_prop(AVFormatContext
*s
, AVStream
*st
, uint64_t eof
)
251 AVIOContext
*pb
= s
->pb
;
253 int hour
, min
, sec
, i
, ret
, config
;
255 ID3v2ExtraMeta
*id3v2_extra_meta
;
257 while (avio_tell(pb
) + 12 <= eof
&& !avio_feof(pb
)) {
258 uint32_t tag
= avio_rl32(pb
);
259 uint64_t size
= avio_rb64(pb
);
260 uint64_t orig_pos
= avio_tell(pb
);
262 if (size
>= INT64_MAX
)
263 return AVERROR_INVALIDDATA
;
266 case MKTAG('A','B','S','S'):
268 return AVERROR_INVALIDDATA
;
269 hour
= avio_rb16(pb
);
272 snprintf(abss
, sizeof(abss
), "%02dh:%02dm:%02ds:%d", hour
, min
, sec
, avio_rb32(pb
));
273 av_dict_set(&st
->metadata
, "absolute_start_time", abss
, 0);
276 case MKTAG('C','H','N','L'):
278 return AVERROR_INVALIDDATA
;
279 st
->codecpar
->channels
= avio_rb16(pb
);
280 if (size
< 2 + st
->codecpar
->channels
* 4)
281 return AVERROR_INVALIDDATA
;
282 st
->codecpar
->channel_layout
= 0;
283 if (st
->codecpar
->channels
> FF_ARRAY_ELEMS(dsd_layout
)) {
284 avpriv_request_sample(s
, "channel layout");
287 for (i
= 0; i
< st
->codecpar
->channels
; i
++)
288 dsd_layout
[i
] = avio_rl32(pb
);
289 for (i
= 0; i
< FF_ARRAY_ELEMS(dsd_channel_layout
); i
++) {
290 const DSDLayoutDesc
* d
= &dsd_channel_layout
[i
];
291 if (av_get_channel_layout_nb_channels(d
->layout
) == st
->codecpar
->channels
&&
292 !memcmp(d
->dsd_layout
, dsd_layout
, st
->codecpar
->channels
* sizeof(uint32_t))) {
293 st
->codecpar
->channel_layout
= d
->layout
;
299 case MKTAG('C','M','P','R'):
301 return AVERROR_INVALIDDATA
;
302 st
->codecpar
->codec_tag
= tag
= avio_rl32(pb
);
303 st
->codecpar
->codec_id
= ff_codec_get_id(dsd_codec_tags
, tag
);
304 if (!st
->codecpar
->codec_id
) {
305 av_log(s
, AV_LOG_ERROR
, "'%c%c%c%c' compression is not supported\n",
306 tag
&0xFF, (tag
>>8)&0xFF, (tag
>>16)&0xFF, (tag
>>24)&0xFF);
307 return AVERROR_PATCHWELCOME
;
311 case MKTAG('F','S',' ',' '):
313 return AVERROR_INVALIDDATA
;
314 st
->codecpar
->sample_rate
= avio_rb32(pb
) / 8;
317 case MKTAG('I','D','3',' '):
318 id3v2_extra_meta
= NULL
;
319 ff_id3v2_read(s
, ID3v2_DEFAULT_MAGIC
, &id3v2_extra_meta
, size
);
320 if (id3v2_extra_meta
) {
321 if ((ret
= ff_id3v2_parse_apic(s
, &id3v2_extra_meta
)) < 0) {
322 ff_id3v2_free_extra_meta(&id3v2_extra_meta
);
325 ff_id3v2_free_extra_meta(&id3v2_extra_meta
);
328 if (size
< avio_tell(pb
) - orig_pos
) {
329 av_log(s
, AV_LOG_ERROR
, "id3 exceeds chunk size\n");
330 return AVERROR_INVALIDDATA
;
334 case MKTAG('L','S','C','O'):
336 return AVERROR_INVALIDDATA
;
337 config
= avio_rb16(pb
);
338 if (config
!= 0xFFFF) {
339 if (config
< FF_ARRAY_ELEMS(dsd_loudspeaker_config
))
340 st
->codecpar
->channel_layout
= dsd_loudspeaker_config
[config
];
341 if (!st
->codecpar
->channel_layout
)
342 avpriv_request_sample(s
, "loudspeaker configuration %d", config
);
347 avio_skip(pb
, size
- (avio_tell(pb
) - orig_pos
) + (size
& 1));
353 static int read_dst_frame(AVFormatContext
*s
, AVPacket
*pkt
)
355 IffDemuxContext
*iff
= s
->priv_data
;
356 AVIOContext
*pb
= s
->pb
;
358 uint64_t chunk_pos
, data_pos
, data_size
;
359 int ret
= AVERROR_EOF
;
361 while (!avio_feof(pb
)) {
362 chunk_pos
= avio_tell(pb
);
363 if (chunk_pos
>= iff
->body_end
)
366 chunk_id
= avio_rl32(pb
);
367 data_size
= iff
->is_64bit
? avio_rb64(pb
) : avio_rb32(pb
);
368 data_pos
= avio_tell(pb
);
370 if (data_size
< 1 || data_size
>= INT64_MAX
)
371 return AVERROR_INVALIDDATA
;
376 iff
->body_pos
= avio_tell(pb
) - (iff
->is_64bit
? 12 : 8);
377 iff
->body_size
= iff
->body_end
- iff
->body_pos
;
380 ret
= av_get_packet(pb
, pkt
, data_size
);
385 pkt
->flags
|= AV_PKT_FLAG_KEY
;
386 pkt
->stream_index
= 0;
387 pkt
->duration
= s
->streams
[0]->codecpar
->sample_rate
/ 75;
388 pkt
->pos
= chunk_pos
;
390 chunk_pos
= avio_tell(pb
);
391 if (chunk_pos
>= iff
->body_end
)
394 avio_seek(pb
, chunk_pos
, SEEK_SET
);
399 return AVERROR_INVALIDDATA
;
400 s
->streams
[0]->duration
= avio_rb32(pb
) * (uint64_t)s
->streams
[0]->codecpar
->sample_rate
/ 75;
405 avio_skip(pb
, data_size
- (avio_tell(pb
) - data_pos
) + (data_size
& 1));
411 static const uint8_t deep_rgb24
[] = {0, 0, 0, 3, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8};
412 static const uint8_t deep_rgba
[] = {0, 0, 0, 4, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8};
413 static const uint8_t deep_bgra
[] = {0, 0, 0, 4, 0, 3, 0, 8, 0, 2, 0, 8, 0, 1, 0, 8};
414 static const uint8_t deep_argb
[] = {0, 0, 0, 4, 0,17, 0, 8, 0, 1, 0, 8, 0, 2, 0, 8};
415 static const uint8_t deep_abgr
[] = {0, 0, 0, 4, 0,17, 0, 8, 0, 3, 0, 8, 0, 2, 0, 8};
417 static int iff_read_header(AVFormatContext
*s
)
419 IffDemuxContext
*iff
= s
->priv_data
;
420 AVIOContext
*pb
= s
->pb
;
425 uint32_t screenmode
= 0, num
, den
;
426 unsigned transparency
= 0;
427 unsigned masking
= 0; // no mask
431 st
= avformat_new_stream(s
, NULL
);
433 return AVERROR(ENOMEM
);
435 st
->codecpar
->channels
= 1;
436 st
->codecpar
->channel_layout
= AV_CH_LAYOUT_MONO
;
437 iff
->is_64bit
= avio_rl32(pb
) == ID_FRM8
;
438 avio_skip(pb
, iff
->is_64bit
? 8 : 4);
439 // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
440 st
->codecpar
->codec_tag
= avio_rl32(pb
);
441 if (st
->codecpar
->codec_tag
== ID_ANIM
) {
444 iff
->bitmap_compression
= -1;
445 iff
->svx8_compression
= -1;
447 iff
->maud_compression
= -1;
449 while(!avio_feof(pb
)) {
452 const char *metadata_tag
= NULL
;
453 int version
, nb_comments
, i
;
454 chunk_id
= avio_rl32(pb
);
455 data_size
= iff
->is_64bit
? avio_rb64(pb
) : avio_rb32(pb
);
456 orig_pos
= avio_tell(pb
);
458 if (data_size
>= INT64_MAX
)
459 return AVERROR_INVALIDDATA
;
463 st
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
466 return AVERROR_INVALIDDATA
;
468 st
->codecpar
->sample_rate
= avio_rb16(pb
);
469 if (data_size
>= 16) {
471 iff
->svx8_compression
= avio_r8(pb
);
476 st
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
479 return AVERROR_INVALIDDATA
;
481 iff
->maud_bits
= avio_rb16(pb
);
486 return AVERROR_INVALIDDATA
;
488 st
->codecpar
->sample_rate
= num
/ den
;
489 st
->codecpar
->channels
= avio_rb16(pb
);
490 iff
->maud_compression
= avio_rb16(pb
);
491 if (st
->codecpar
->channels
== 1)
492 st
->codecpar
->channel_layout
= AV_CH_LAYOUT_MONO
;
493 else if (st
->codecpar
->channels
== 2)
494 st
->codecpar
->channel_layout
= AV_CH_LAYOUT_STEREO
;
503 iff
->body_pos
= avio_tell(pb
);
504 if (iff
->body_pos
< 0 || iff
->body_pos
+ data_size
> INT64_MAX
)
505 return AVERROR_INVALIDDATA
;
507 iff
->body_end
= iff
->body_pos
+ data_size
;
508 iff
->body_size
= data_size
;
509 if (chunk_id
== ID_DST
) {
510 int ret
= read_dst_frame(s
, NULL
);
518 return AVERROR_INVALIDDATA
;
519 if (avio_rb32(pb
) < 6) {
520 st
->codecpar
->channels
= 1;
521 st
->codecpar
->channel_layout
= AV_CH_LAYOUT_MONO
;
523 st
->codecpar
->channels
= 2;
524 st
->codecpar
->channel_layout
= AV_CH_LAYOUT_STEREO
;
530 return AVERROR_INVALIDDATA
;
531 screenmode
= avio_rb32(pb
);
535 if (data_size
< 3 || data_size
> 768 || data_size
% 3) {
536 av_log(s
, AV_LOG_ERROR
, "Invalid CMAP chunk size %"PRIu64
"\n",
538 return AVERROR_INVALIDDATA
;
540 st
->codecpar
->extradata_size
= data_size
+ IFF_EXTRA_VIDEO_SIZE
;
541 st
->codecpar
->extradata
= av_malloc(data_size
+ IFF_EXTRA_VIDEO_SIZE
+ AV_INPUT_BUFFER_PADDING_SIZE
);
542 if (!st
->codecpar
->extradata
)
543 return AVERROR(ENOMEM
);
544 if (avio_read(pb
, st
->codecpar
->extradata
+ IFF_EXTRA_VIDEO_SIZE
, data_size
) < 0)
549 st
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
551 return AVERROR_INVALIDDATA
;
552 st
->codecpar
->width
= avio_rb16(pb
);
553 st
->codecpar
->height
= avio_rb16(pb
);
554 avio_skip(pb
, 4); // x, y offset
555 st
->codecpar
->bits_per_coded_sample
= avio_r8(pb
);
557 masking
= avio_r8(pb
);
559 iff
->bitmap_compression
= avio_r8(pb
);
560 if (data_size
>= 14) {
561 avio_skip(pb
, 1); // padding
562 transparency
= avio_rb16(pb
);
564 if (data_size
>= 16) {
565 st
->sample_aspect_ratio
.num
= avio_r8(pb
);
566 st
->sample_aspect_ratio
.den
= avio_r8(pb
);
575 st
->duration
= avio_rb16(pb
);
579 if (data_size
< 4 || (data_size
& 3))
580 return AVERROR_INVALIDDATA
;
581 if ((fmt_size
= avio_read(pb
, fmt
, sizeof(fmt
))) < 0)
583 if (fmt_size
== sizeof(deep_rgb24
) && !memcmp(fmt
, deep_rgb24
, sizeof(deep_rgb24
)))
584 st
->codecpar
->format
= AV_PIX_FMT_RGB24
;
585 else if (fmt_size
== sizeof(deep_rgba
) && !memcmp(fmt
, deep_rgba
, sizeof(deep_rgba
)))
586 st
->codecpar
->format
= AV_PIX_FMT_RGBA
;
587 else if (fmt_size
== sizeof(deep_bgra
) && !memcmp(fmt
, deep_bgra
, sizeof(deep_bgra
)))
588 st
->codecpar
->format
= AV_PIX_FMT_BGRA
;
589 else if (fmt_size
== sizeof(deep_argb
) && !memcmp(fmt
, deep_argb
, sizeof(deep_argb
)))
590 st
->codecpar
->format
= AV_PIX_FMT_ARGB
;
591 else if (fmt_size
== sizeof(deep_abgr
) && !memcmp(fmt
, deep_abgr
, sizeof(deep_abgr
)))
592 st
->codecpar
->format
= AV_PIX_FMT_ABGR
;
594 avpriv_request_sample(s
, "color format %.16s", fmt
);
595 return AVERROR_PATCHWELCOME
;
600 st
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
602 return AVERROR_INVALIDDATA
;
603 st
->codecpar
->width
= avio_rb16(pb
);
604 st
->codecpar
->height
= avio_rb16(pb
);
605 iff
->bitmap_compression
= avio_rb16(pb
);
606 st
->sample_aspect_ratio
.num
= avio_r8(pb
);
607 st
->sample_aspect_ratio
.den
= avio_r8(pb
);
608 st
->codecpar
->bits_per_coded_sample
= 24;
613 return AVERROR_INVALIDDATA
;
614 st
->codecpar
->width
= avio_rb16(pb
);
615 st
->codecpar
->height
= avio_rb16(pb
);
619 if (data_size
< sizeof(iff
->tvdc
))
620 return AVERROR_INVALIDDATA
;
621 res
= avio_read(pb
, iff
->tvdc
, sizeof(iff
->tvdc
));
627 case ID_TEXT
: metadata_tag
= "comment"; break;
628 case ID_AUTH
: metadata_tag
= "artist"; break;
629 case ID_COPYRIGHT
: metadata_tag
= "copyright"; break;
630 case ID_NAME
: metadata_tag
= "title"; break;
634 case MKTAG('F','V','E','R'):
636 return AVERROR_INVALIDDATA
;
637 version
= avio_rb32(pb
);
638 av_log(s
, AV_LOG_DEBUG
, "DSIFF v%d.%d.%d.%d\n",version
>> 24, (version
>> 16) & 0xFF, (version
>> 8) & 0xFF, version
& 0xFF);
639 st
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
642 case MKTAG('D','I','I','N'):
643 res
= parse_dsd_diin(s
, st
, orig_pos
+ data_size
);
648 case MKTAG('P','R','O','P'):
650 return AVERROR_INVALIDDATA
;
651 if (avio_rl32(pb
) != MKTAG('S','N','D',' ')) {
652 avpriv_request_sample(s
, "unknown property type");
655 res
= parse_dsd_prop(s
, st
, orig_pos
+ data_size
);
660 case MKTAG('C','O','M','T'):
662 return AVERROR_INVALIDDATA
;
663 nb_comments
= avio_rb16(pb
);
664 for (i
= 0; i
< nb_comments
; i
++) {
665 int year
, mon
, day
, hour
, min
, type
, ref
;
670 year
= avio_rb16(pb
);
675 snprintf(tmp
, sizeof(tmp
), "%04d-%02d-%02d %02d:%02d", year
, mon
, day
, hour
, min
);
676 av_dict_set(&st
->metadata
, "comment_time", tmp
, 0);
678 type
= avio_rb16(pb
);
683 tag
= "channel_comment";
685 snprintf(tmp
, sizeof(tmp
), "channel%d_comment", ref
);
690 tag
= ref
< FF_ARRAY_ELEMS(dsd_source_comment
) ? dsd_source_comment
[ref
] : "source_comment";
693 tag
= ref
< FF_ARRAY_ELEMS(dsd_history_comment
) ? dsd_history_comment
[ref
] : "file_history";
699 metadata_size
= avio_rb32(pb
);
700 if ((res
= get_metadata(s
, tag
, metadata_size
)) < 0) {
701 av_log(s
, AV_LOG_ERROR
, "cannot allocate metadata tag %s!\n", tag
);
705 if (metadata_size
& 1)
712 if ((res
= get_metadata(s
, metadata_tag
, data_size
)) < 0) {
713 av_log(s
, AV_LOG_ERROR
, "cannot allocate metadata tag %s!\n", metadata_tag
);
717 avio_skip(pb
, data_size
- (avio_tell(pb
) - orig_pos
) + (data_size
& 1));
720 if (st
->codecpar
->codec_tag
== ID_ANIM
)
721 avio_seek(pb
, 12, SEEK_SET
);
723 avio_seek(pb
, iff
->body_pos
, SEEK_SET
);
725 switch(st
->codecpar
->codec_type
) {
726 case AVMEDIA_TYPE_AUDIO
:
727 avpriv_set_pts_info(st
, 32, 1, st
->codecpar
->sample_rate
);
729 if (st
->codecpar
->codec_tag
== ID_16SV
)
730 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S16BE_PLANAR
;
731 else if (st
->codecpar
->codec_tag
== ID_MAUD
) {
732 if (iff
->maud_bits
== 8 && !iff
->maud_compression
) {
733 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_U8
;
734 } else if (iff
->maud_bits
== 16 && !iff
->maud_compression
) {
735 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S16BE
;
736 } else if (iff
->maud_bits
== 8 && iff
->maud_compression
== 2) {
737 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_ALAW
;
738 } else if (iff
->maud_bits
== 8 && iff
->maud_compression
== 3) {
739 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_MULAW
;
741 avpriv_request_sample(s
, "compression %d and bit depth %d", iff
->maud_compression
, iff
->maud_bits
);
742 return AVERROR_PATCHWELCOME
;
744 } else if (st
->codecpar
->codec_tag
!= ID_DSD
&&
745 st
->codecpar
->codec_tag
!= ID_DST
) {
746 switch (iff
->svx8_compression
) {
748 st
->codecpar
->codec_id
= AV_CODEC_ID_PCM_S8_PLANAR
;
751 st
->codecpar
->codec_id
= AV_CODEC_ID_8SVX_FIB
;
754 st
->codecpar
->codec_id
= AV_CODEC_ID_8SVX_EXP
;
757 av_log(s
, AV_LOG_ERROR
,
758 "Unknown SVX8 compression method '%d'\n", iff
->svx8_compression
);
763 st
->codecpar
->bits_per_coded_sample
= av_get_bits_per_sample(st
->codecpar
->codec_id
);
764 st
->codecpar
->bit_rate
= st
->codecpar
->channels
* st
->codecpar
->sample_rate
* st
->codecpar
->bits_per_coded_sample
;
765 st
->codecpar
->block_align
= st
->codecpar
->channels
* st
->codecpar
->bits_per_coded_sample
;
766 if ((st
->codecpar
->codec_tag
== ID_DSD
|| st
->codecpar
->codec_tag
== ID_MAUD
) && st
->codecpar
->block_align
<= 0)
767 return AVERROR_INVALIDDATA
;
770 case AVMEDIA_TYPE_VIDEO
:
771 iff
->bpp
= st
->codecpar
->bits_per_coded_sample
;
772 if (st
->codecpar
->codec_tag
== ID_ANIM
)
773 avpriv_set_pts_info(st
, 32, 1, 60);
774 if ((screenmode
& 0x800 /* Hold And Modify */) && iff
->bpp
<= 8) {
775 iff
->ham
= iff
->bpp
> 6 ? 6 : 4;
776 st
->codecpar
->bits_per_coded_sample
= 24;
778 iff
->flags
= (screenmode
& 0x80 /* Extra HalfBrite */) && iff
->bpp
<= 8;
779 iff
->masking
= masking
;
780 iff
->transparency
= transparency
;
782 if (!st
->codecpar
->extradata
) {
783 st
->codecpar
->extradata_size
= IFF_EXTRA_VIDEO_SIZE
;
784 st
->codecpar
->extradata
= av_malloc(IFF_EXTRA_VIDEO_SIZE
+ AV_INPUT_BUFFER_PADDING_SIZE
);
785 if (!st
->codecpar
->extradata
)
786 return AVERROR(ENOMEM
);
788 av_assert0(st
->codecpar
->extradata_size
>= IFF_EXTRA_VIDEO_SIZE
);
789 buf
= st
->codecpar
->extradata
;
790 bytestream_put_be16(&buf
, IFF_EXTRA_VIDEO_SIZE
);
791 bytestream_put_byte(&buf
, iff
->bitmap_compression
);
792 bytestream_put_byte(&buf
, iff
->bpp
);
793 bytestream_put_byte(&buf
, iff
->ham
);
794 bytestream_put_byte(&buf
, iff
->flags
);
795 bytestream_put_be16(&buf
, iff
->transparency
);
796 bytestream_put_byte(&buf
, iff
->masking
);
797 bytestream_put_buffer(&buf
, iff
->tvdc
, sizeof(iff
->tvdc
));
798 st
->codecpar
->codec_id
= AV_CODEC_ID_IFF_ILBM
;
807 static unsigned get_anim_duration(uint8_t *buf
, int size
)
811 bytestream2_init(&gb
, buf
, size
);
812 bytestream2_skip(&gb
, 4);
813 while (bytestream2_get_bytes_left(&gb
) > 8) {
814 unsigned chunk
= bytestream2_get_le32(&gb
);
815 unsigned size
= bytestream2_get_be32(&gb
);
817 if (chunk
== ID_ANHD
) {
820 bytestream2_skip(&gb
, 14);
821 return bytestream2_get_be32(&gb
);
823 bytestream2_skip(&gb
, size
+ size
& 1);
829 static int iff_read_packet(AVFormatContext
*s
,
832 IffDemuxContext
*iff
= s
->priv_data
;
833 AVIOContext
*pb
= s
->pb
;
834 AVStream
*st
= s
->streams
[0];
836 int64_t pos
= avio_tell(pb
);
840 if (st
->codecpar
->codec_tag
!= ID_ANIM
&& pos
>= iff
->body_end
)
843 if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
844 if (st
->codecpar
->codec_tag
== ID_DSD
|| st
->codecpar
->codec_tag
== ID_MAUD
) {
845 ret
= av_get_packet(pb
, pkt
, FFMIN(iff
->body_end
- pos
, 1024 * st
->codecpar
->block_align
));
846 } else if (st
->codecpar
->codec_tag
== ID_DST
) {
847 return read_dst_frame(s
, pkt
);
849 if (iff
->body_size
> INT_MAX
|| !iff
->body_size
)
850 return AVERROR_INVALIDDATA
;
851 ret
= av_get_packet(pb
, pkt
, iff
->body_size
);
853 } else if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
&&
854 st
->codecpar
->codec_tag
== ID_ANIM
) {
855 uint64_t data_size
, orig_pos
;
856 uint32_t chunk_id
, chunk_id2
;
858 while (!avio_feof(pb
)) {
862 orig_pos
= avio_tell(pb
);
863 chunk_id
= avio_rl32(pb
);
864 data_size
= avio_rb32(pb
);
865 chunk_id2
= avio_rl32(pb
);
867 if (chunk_id
== ID_FORM
&&
868 chunk_id2
== ID_ILBM
) {
871 } else if (chunk_id
== ID_FORM
&&
872 chunk_id2
== ID_ANIM
) {
875 avio_skip(pb
, data_size
);
878 ret
= av_get_packet(pb
, pkt
, data_size
);
880 pkt
->duration
= get_anim_duration(pkt
->data
, pkt
->size
);
882 pkt
->flags
|= AV_PKT_FLAG_KEY
;
883 } else if (st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
&&
884 st
->codecpar
->codec_tag
!= ID_ANIM
) {
885 if (iff
->body_size
> INT_MAX
|| !iff
->body_size
)
886 return AVERROR_INVALIDDATA
;
887 ret
= av_get_packet(pb
, pkt
, iff
->body_size
);
889 if (pos
== iff
->body_pos
)
890 pkt
->flags
|= AV_PKT_FLAG_KEY
;
897 pkt
->stream_index
= 0;
901 AVInputFormat ff_iff_demuxer
= {
903 .long_name
= NULL_IF_CONFIG_SMALL("IFF (Interchange File Format)"),
904 .priv_data_size
= sizeof(IffDemuxContext
),
905 .read_probe
= iff_probe
,
906 .read_header
= iff_read_header
,
907 .read_packet
= iff_read_packet
,
908 .flags
= AVFMT_GENERIC_INDEX
| AVFMT_NO_BYTE_SEEK
,