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_ANIM MKTAG('A','N','I','M')
64 #define ID_FORM MKTAG('F','O','R','M')
65 #define ID_FRM8 MKTAG('F','R','M','8')
66 #define ID_ANNO MKTAG('A','N','N','O')
67 #define ID_AUTH MKTAG('A','U','T','H')
68 #define ID_CHRS MKTAG('C','H','R','S')
69 #define ID_COPYRIGHT MKTAG('(','c',')',' ')
70 #define ID_CSET MKTAG('C','S','E','T')
71 #define ID_FVER MKTAG('F','V','E','R')
72 #define ID_NAME MKTAG('N','A','M','E')
73 #define ID_TEXT MKTAG('T','E','X','T')
74 #define ID_ABIT MKTAG('A','B','I','T')
75 #define ID_BODY MKTAG('B','O','D','Y')
76 #define ID_DBOD MKTAG('D','B','O','D')
77 #define ID_DPEL MKTAG('D','P','E','L')
78 #define ID_DLOC MKTAG('D','L','O','C')
79 #define ID_TVDC MKTAG('T','V','D','C')
86 * This number of bytes if added at the beginning of each AVPacket
87 * which contain additional information about video properties
88 * which has to be shared between demuxer and decoder.
89 * This number may change between frames, e.g. the demuxer might
90 * set it to smallest possible size of 2 to indicate that there's
91 * no extradata changing in this frame.
93 #define IFF_EXTRA_VIDEO_SIZE 41
99 } svx8_compression_type
;
102 int is_64bit
; ///< chunk size is 64-bit
106 svx8_compression_type svx8_compression
;
108 unsigned maud_compression
;
109 unsigned bitmap_compression
; ///< delta compression method used
110 unsigned bpp
; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
111 unsigned ham
; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
112 unsigned flags
; ///< 1 for EHB, 0 is no extra half darkening
113 unsigned transparency
; ///< transparency color index in palette
114 unsigned masking
; ///< masking method used
115 uint8_t tvdc
[32]; ///< TVDC lookup table
118 /* Metadata string read */
119 static int get_metadata(AVFormatContext
*s
,
120 const char *const tag
,
121 const unsigned data_size
)
123 uint8_t *buf
= ((data_size
+ 1) == 0) ? NULL
: av_malloc(data_size
+ 1);
126 return AVERROR(ENOMEM
);
128 if (avio_read(s
->pb
, buf
, data_size
) != data_size
) {
133 av_dict_set(&s
->metadata
, tag
, buf
, AV_DICT_DONT_STRDUP_VAL
);
137 static int iff_probe(AVProbeData
*p
)
139 const uint8_t *d
= p
->buf
;
141 if ( (AV_RL32(d
) == ID_FORM
&&
142 (AV_RL32(d
+8) == ID_8SVX
||
143 AV_RL32(d
+8) == ID_16SV
||
144 AV_RL32(d
+8) == ID_MAUD
||
145 AV_RL32(d
+8) == ID_PBM
||
146 AV_RL32(d
+8) == ID_ACBM
||
147 AV_RL32(d
+8) == ID_DEEP
||
148 AV_RL32(d
+8) == ID_ILBM
||
149 AV_RL32(d
+8) == ID_RGB8
||
150 AV_RL32(d
+8) == ID_RGB8
||
151 AV_RL32(d
+8) == ID_ANIM
||
152 AV_RL32(d
+8) == ID_RGBN
)) ||
153 (AV_RL32(d
) == ID_FRM8
&& AV_RL32(d
+12) == ID_DSD
))
154 return AVPROBE_SCORE_MAX
;
158 static const AVCodecTag dsd_codec_tags
[] = {
159 { AV_CODEC_ID_DSD_MSBF
, ID_DSD
},
160 { AV_CODEC_ID_NONE
, 0 },
164 #define DSD_SLFT MKTAG('S','L','F','T')
165 #define DSD_SRGT MKTAG('S','R','G','T')
166 #define DSD_MLFT MKTAG('M','L','F','T')
167 #define DSD_MRGT MKTAG('M','R','G','T')
168 #define DSD_C MKTAG('C',' ',' ',' ')
169 #define DSD_LS MKTAG('L','S',' ',' ')
170 #define DSD_RS MKTAG('R','S',' ',' ')
171 #define DSD_LFE MKTAG('L','F','E',' ')
173 static const uint32_t dsd_stereo
[] = { DSD_SLFT
, DSD_SRGT
};
174 static const uint32_t dsd_5point0
[] = { DSD_MLFT
, DSD_MRGT
, DSD_C
, DSD_LS
, DSD_RS
};
175 static const uint32_t dsd_5point1
[] = { DSD_MLFT
, DSD_MRGT
, DSD_C
, DSD_LFE
, DSD_LS
, DSD_RS
};
179 const uint32_t * dsd_layout
;
182 static const DSDLayoutDesc dsd_channel_layout
[] = {
183 { AV_CH_LAYOUT_STEREO
, dsd_stereo
},
184 { AV_CH_LAYOUT_5POINT0
, dsd_5point0
},
185 { AV_CH_LAYOUT_5POINT1
, dsd_5point1
},
188 static const uint64_t dsd_loudspeaker_config
[] = {
191 AV_CH_LAYOUT_5POINT0
, AV_CH_LAYOUT_5POINT1
,
194 static const char * dsd_source_comment
[] = {
195 "dsd_source_comment",
196 "analogue_source_comment",
197 "pcm_source_comment",
200 static const char * dsd_history_comment
[] = {
208 static int parse_dsd_diin(AVFormatContext
*s
, AVStream
*st
, uint64_t eof
)
210 AVIOContext
*pb
= s
->pb
;
212 while (avio_tell(pb
) + 12 <= eof
) {
213 uint32_t tag
= avio_rl32(pb
);
214 uint64_t size
= avio_rb64(pb
);
215 uint64_t orig_pos
= avio_tell(pb
);
216 const char * metadata_tag
= NULL
;
219 case MKTAG('D','I','A','R'): metadata_tag
= "artist"; break;
220 case MKTAG('D','I','T','I'): metadata_tag
= "title"; break;
223 if (metadata_tag
&& size
> 4) {
224 unsigned int tag_size
= avio_rb32(pb
);
225 int ret
= get_metadata(s
, metadata_tag
, FFMIN(tag_size
, size
- 4));
227 av_log(s
, AV_LOG_ERROR
, "cannot allocate metadata tag %s!\n", metadata_tag
);
232 avio_skip(pb
, size
- (avio_tell(pb
) - orig_pos
) + (size
& 1));
238 static int parse_dsd_prop(AVFormatContext
*s
, AVStream
*st
, uint64_t eof
)
240 AVIOContext
*pb
= s
->pb
;
242 int hour
, min
, sec
, i
, ret
, config
;
244 ID3v2ExtraMeta
*id3v2_extra_meta
;
246 while (avio_tell(pb
) + 12 <= eof
) {
247 uint32_t tag
= avio_rl32(pb
);
248 uint64_t size
= avio_rb64(pb
);
249 uint64_t orig_pos
= avio_tell(pb
);
252 case MKTAG('A','B','S','S'):
254 return AVERROR_INVALIDDATA
;
255 hour
= avio_rb16(pb
);
258 snprintf(abss
, sizeof(abss
), "%02dh:%02dm:%02ds:%d", hour
, min
, sec
, avio_rb32(pb
));
259 av_dict_set(&st
->metadata
, "absolute_start_time", abss
, 0);
262 case MKTAG('C','H','N','L'):
264 return AVERROR_INVALIDDATA
;
265 st
->codec
->channels
= avio_rb16(pb
);
266 if (size
< 2 + st
->codec
->channels
* 4)
267 return AVERROR_INVALIDDATA
;
268 st
->codec
->channel_layout
= 0;
269 if (st
->codec
->channels
> FF_ARRAY_ELEMS(dsd_layout
)) {
270 avpriv_request_sample(s
, "channel layout");
273 for (i
= 0; i
< st
->codec
->channels
; i
++)
274 dsd_layout
[i
] = avio_rl32(pb
);
275 for (i
= 0; i
< FF_ARRAY_ELEMS(dsd_channel_layout
); i
++) {
276 const DSDLayoutDesc
* d
= &dsd_channel_layout
[i
];
277 if (av_get_channel_layout_nb_channels(d
->layout
) == st
->codec
->channels
&&
278 !memcmp(d
->dsd_layout
, dsd_layout
, st
->codec
->channels
* sizeof(uint32_t))) {
279 st
->codec
->channel_layout
= d
->layout
;
285 case MKTAG('C','M','P','R'):
287 return AVERROR_INVALIDDATA
;
289 st
->codec
->codec_id
= ff_codec_get_id(dsd_codec_tags
, tag
);
290 if (!st
->codec
->codec_id
) {
291 av_log(s
, AV_LOG_ERROR
, "'%c%c%c%c' compression is not supported\n",
292 tag
&0xFF, (tag
>>8)&0xFF, (tag
>>16)&0xFF, (tag
>>24)&0xFF);
293 return AVERROR_PATCHWELCOME
;
297 case MKTAG('F','S',' ',' '):
299 return AVERROR_INVALIDDATA
;
300 st
->codec
->sample_rate
= avio_rb32(pb
) / 8;
303 case MKTAG('I','D','3',' '):
304 id3v2_extra_meta
= NULL
;
305 ff_id3v2_read(s
, ID3v2_DEFAULT_MAGIC
, &id3v2_extra_meta
, size
);
306 if (id3v2_extra_meta
) {
307 if ((ret
= ff_id3v2_parse_apic(s
, &id3v2_extra_meta
)) < 0) {
308 ff_id3v2_free_extra_meta(&id3v2_extra_meta
);
311 ff_id3v2_free_extra_meta(&id3v2_extra_meta
);
314 if (size
< avio_tell(pb
) - orig_pos
) {
315 av_log(s
, AV_LOG_ERROR
, "id3 exceeds chunk size\n");
316 return AVERROR_INVALIDDATA
;
320 case MKTAG('L','S','C','O'):
322 return AVERROR_INVALIDDATA
;
323 config
= avio_rb16(pb
);
324 if (config
!= 0xFFFF) {
325 if (config
< FF_ARRAY_ELEMS(dsd_loudspeaker_config
))
326 st
->codec
->channel_layout
= dsd_loudspeaker_config
[config
];
327 if (!st
->codec
->channel_layout
)
328 avpriv_request_sample(s
, "loudspeaker configuration %d", config
);
333 avio_skip(pb
, size
- (avio_tell(pb
) - orig_pos
) + (size
& 1));
339 static const uint8_t deep_rgb24
[] = {0, 0, 0, 3, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8};
340 static const uint8_t deep_rgba
[] = {0, 0, 0, 4, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8};
341 static const uint8_t deep_bgra
[] = {0, 0, 0, 4, 0, 3, 0, 8, 0, 2, 0, 8, 0, 1, 0, 8};
342 static const uint8_t deep_argb
[] = {0, 0, 0, 4, 0,17, 0, 8, 0, 1, 0, 8, 0, 2, 0, 8};
343 static const uint8_t deep_abgr
[] = {0, 0, 0, 4, 0,17, 0, 8, 0, 3, 0, 8, 0, 2, 0, 8};
345 static int iff_read_header(AVFormatContext
*s
)
347 IffDemuxContext
*iff
= s
->priv_data
;
348 AVIOContext
*pb
= s
->pb
;
353 uint32_t screenmode
= 0, num
, den
;
354 unsigned transparency
= 0;
355 unsigned masking
= 0; // no mask
359 st
= avformat_new_stream(s
, NULL
);
361 return AVERROR(ENOMEM
);
363 st
->codec
->channels
= 1;
364 st
->codec
->channel_layout
= AV_CH_LAYOUT_MONO
;
365 iff
->is_64bit
= avio_rl32(pb
) == ID_FRM8
;
366 avio_skip(pb
, iff
->is_64bit
? 8 : 4);
367 // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
368 st
->codec
->codec_tag
= avio_rl32(pb
);
369 if (st
->codec
->codec_tag
== ID_ANIM
) {
371 st
->codec
->codec_tag
= avio_rl32(pb
);
373 iff
->bitmap_compression
= -1;
374 iff
->svx8_compression
= -1;
376 iff
->maud_compression
= -1;
378 while(!avio_feof(pb
)) {
381 const char *metadata_tag
= NULL
;
382 int version
, nb_comments
, i
;
383 chunk_id
= avio_rl32(pb
);
384 data_size
= iff
->is_64bit
? avio_rb64(pb
) : avio_rb32(pb
);
385 orig_pos
= avio_tell(pb
);
389 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
392 return AVERROR_INVALIDDATA
;
394 st
->codec
->sample_rate
= avio_rb16(pb
);
395 if (data_size
>= 16) {
397 iff
->svx8_compression
= avio_r8(pb
);
402 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
405 return AVERROR_INVALIDDATA
;
407 iff
->maud_bits
= avio_rb16(pb
);
412 return AVERROR_INVALIDDATA
;
414 st
->codec
->sample_rate
= num
/ den
;
415 st
->codec
->channels
= avio_rb16(pb
);
416 iff
->maud_compression
= avio_rb16(pb
);
417 if (st
->codec
->channels
== 1)
418 st
->codec
->channel_layout
= AV_CH_LAYOUT_MONO
;
419 else if (st
->codec
->channels
== 2)
420 st
->codec
->channel_layout
= AV_CH_LAYOUT_STEREO
;
428 iff
->body_pos
= avio_tell(pb
);
429 iff
->body_end
= iff
->body_pos
+ data_size
;
430 iff
->body_size
= data_size
;
435 return AVERROR_INVALIDDATA
;
436 if (avio_rb32(pb
) < 6) {
437 st
->codec
->channels
= 1;
438 st
->codec
->channel_layout
= AV_CH_LAYOUT_MONO
;
440 st
->codec
->channels
= 2;
441 st
->codec
->channel_layout
= AV_CH_LAYOUT_STEREO
;
447 return AVERROR_INVALIDDATA
;
448 screenmode
= avio_rb32(pb
);
452 if (data_size
< 3 || data_size
> 768 || data_size
% 3) {
453 av_log(s
, AV_LOG_ERROR
, "Invalid CMAP chunk size %"PRIu64
"\n",
455 return AVERROR_INVALIDDATA
;
457 st
->codec
->extradata_size
= data_size
+ IFF_EXTRA_VIDEO_SIZE
;
458 st
->codec
->extradata
= av_malloc(data_size
+ IFF_EXTRA_VIDEO_SIZE
+ FF_INPUT_BUFFER_PADDING_SIZE
);
459 if (!st
->codec
->extradata
)
460 return AVERROR(ENOMEM
);
461 if (avio_read(pb
, st
->codec
->extradata
+ IFF_EXTRA_VIDEO_SIZE
, data_size
) < 0)
466 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
468 return AVERROR_INVALIDDATA
;
469 st
->codec
->width
= avio_rb16(pb
);
470 st
->codec
->height
= avio_rb16(pb
);
471 avio_skip(pb
, 4); // x, y offset
472 st
->codec
->bits_per_coded_sample
= avio_r8(pb
);
474 masking
= avio_r8(pb
);
476 iff
->bitmap_compression
= avio_r8(pb
);
477 if (data_size
>= 14) {
478 avio_skip(pb
, 1); // padding
479 transparency
= avio_rb16(pb
);
481 if (data_size
>= 16) {
482 st
->sample_aspect_ratio
.num
= avio_r8(pb
);
483 st
->sample_aspect_ratio
.den
= avio_r8(pb
);
488 if (data_size
< 4 || (data_size
& 3))
489 return AVERROR_INVALIDDATA
;
490 if ((fmt_size
= avio_read(pb
, fmt
, sizeof(fmt
))) < 0)
492 if (fmt_size
== sizeof(deep_rgb24
) && !memcmp(fmt
, deep_rgb24
, sizeof(deep_rgb24
)))
493 st
->codec
->pix_fmt
= AV_PIX_FMT_RGB24
;
494 else if (fmt_size
== sizeof(deep_rgba
) && !memcmp(fmt
, deep_rgba
, sizeof(deep_rgba
)))
495 st
->codec
->pix_fmt
= AV_PIX_FMT_RGBA
;
496 else if (fmt_size
== sizeof(deep_bgra
) && !memcmp(fmt
, deep_bgra
, sizeof(deep_bgra
)))
497 st
->codec
->pix_fmt
= AV_PIX_FMT_BGRA
;
498 else if (fmt_size
== sizeof(deep_argb
) && !memcmp(fmt
, deep_argb
, sizeof(deep_argb
)))
499 st
->codec
->pix_fmt
= AV_PIX_FMT_ARGB
;
500 else if (fmt_size
== sizeof(deep_abgr
) && !memcmp(fmt
, deep_abgr
, sizeof(deep_abgr
)))
501 st
->codec
->pix_fmt
= AV_PIX_FMT_ABGR
;
503 avpriv_request_sample(s
, "color format %.16s", fmt
);
504 return AVERROR_PATCHWELCOME
;
509 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
511 return AVERROR_INVALIDDATA
;
512 st
->codec
->width
= avio_rb16(pb
);
513 st
->codec
->height
= avio_rb16(pb
);
514 iff
->bitmap_compression
= avio_rb16(pb
);
515 st
->sample_aspect_ratio
.num
= avio_r8(pb
);
516 st
->sample_aspect_ratio
.den
= avio_r8(pb
);
517 st
->codec
->bits_per_coded_sample
= 24;
522 return AVERROR_INVALIDDATA
;
523 st
->codec
->width
= avio_rb16(pb
);
524 st
->codec
->height
= avio_rb16(pb
);
528 if (data_size
< sizeof(iff
->tvdc
))
529 return AVERROR_INVALIDDATA
;
530 res
= avio_read(pb
, iff
->tvdc
, sizeof(iff
->tvdc
));
536 case ID_TEXT
: metadata_tag
= "comment"; break;
537 case ID_AUTH
: metadata_tag
= "artist"; break;
538 case ID_COPYRIGHT
: metadata_tag
= "copyright"; break;
539 case ID_NAME
: metadata_tag
= "title"; break;
543 case MKTAG('F','V','E','R'):
545 return AVERROR_INVALIDDATA
;
546 version
= avio_rb32(pb
);
547 av_log(s
, AV_LOG_DEBUG
, "DSIFF v%d.%d.%d.%d\n",version
>> 24, (version
>> 16) & 0xFF, (version
>> 8) & 0xFF, version
& 0xFF);
548 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
551 case MKTAG('D','I','I','N'):
552 res
= parse_dsd_diin(s
, st
, orig_pos
+ data_size
);
557 case MKTAG('P','R','O','P'):
559 return AVERROR_INVALIDDATA
;
560 if (avio_rl32(pb
) != MKTAG('S','N','D',' ')) {
561 avpriv_request_sample(s
, "unknown property type");
564 res
= parse_dsd_prop(s
, st
, orig_pos
+ data_size
);
569 case MKTAG('C','O','M','T'):
571 return AVERROR_INVALIDDATA
;
572 nb_comments
= avio_rb16(pb
);
573 for (i
= 0; i
< nb_comments
; i
++) {
574 int year
, mon
, day
, hour
, min
, type
, ref
;
579 year
= avio_rb16(pb
);
584 snprintf(tmp
, sizeof(tmp
), "%04d-%02d-%02d %02d:%02d", year
, mon
, day
, hour
, min
);
585 av_dict_set(&st
->metadata
, "comment_time", tmp
, 0);
587 type
= avio_rb16(pb
);
592 tag
= "channel_comment";
594 snprintf(tmp
, sizeof(tmp
), "channel%d_comment", ref
);
599 tag
= ref
< FF_ARRAY_ELEMS(dsd_source_comment
) ? dsd_source_comment
[ref
] : "source_comment";
602 tag
= ref
< FF_ARRAY_ELEMS(dsd_history_comment
) ? dsd_history_comment
[ref
] : "file_history";
608 metadata_size
= avio_rb32(pb
);
609 if ((res
= get_metadata(s
, tag
, metadata_size
)) < 0) {
610 av_log(s
, AV_LOG_ERROR
, "cannot allocate metadata tag %s!\n", tag
);
614 if (metadata_size
& 1)
621 if ((res
= get_metadata(s
, metadata_tag
, data_size
)) < 0) {
622 av_log(s
, AV_LOG_ERROR
, "cannot allocate metadata tag %s!\n", metadata_tag
);
626 avio_skip(pb
, data_size
- (avio_tell(pb
) - orig_pos
) + (data_size
& 1));
629 avio_seek(pb
, iff
->body_pos
, SEEK_SET
);
631 switch(st
->codec
->codec_type
) {
632 case AVMEDIA_TYPE_AUDIO
:
633 avpriv_set_pts_info(st
, 32, 1, st
->codec
->sample_rate
);
635 if (st
->codec
->codec_tag
== ID_16SV
)
636 st
->codec
->codec_id
= AV_CODEC_ID_PCM_S16BE_PLANAR
;
637 else if (st
->codec
->codec_tag
== ID_MAUD
) {
638 if (iff
->maud_bits
== 8 && !iff
->maud_compression
) {
639 st
->codec
->codec_id
= AV_CODEC_ID_PCM_U8
;
640 } else if (iff
->maud_bits
== 16 && !iff
->maud_compression
) {
641 st
->codec
->codec_id
= AV_CODEC_ID_PCM_S16BE
;
642 } else if (iff
->maud_bits
== 8 && iff
->maud_compression
== 2) {
643 st
->codec
->codec_id
= AV_CODEC_ID_PCM_ALAW
;
644 } else if (iff
->maud_bits
== 8 && iff
->maud_compression
== 3) {
645 st
->codec
->codec_id
= AV_CODEC_ID_PCM_MULAW
;
647 avpriv_request_sample(s
, "compression %d and bit depth %d", iff
->maud_compression
, iff
->maud_bits
);
648 return AVERROR_PATCHWELCOME
;
650 } else if (st
->codec
->codec_tag
!= ID_DSD
) {
651 switch (iff
->svx8_compression
) {
653 st
->codec
->codec_id
= AV_CODEC_ID_PCM_S8_PLANAR
;
656 st
->codec
->codec_id
= AV_CODEC_ID_8SVX_FIB
;
659 st
->codec
->codec_id
= AV_CODEC_ID_8SVX_EXP
;
662 av_log(s
, AV_LOG_ERROR
,
663 "Unknown SVX8 compression method '%d'\n", iff
->svx8_compression
);
668 st
->codec
->bits_per_coded_sample
= av_get_bits_per_sample(st
->codec
->codec_id
);
669 st
->codec
->bit_rate
= st
->codec
->channels
* st
->codec
->sample_rate
* st
->codec
->bits_per_coded_sample
;
670 st
->codec
->block_align
= st
->codec
->channels
* st
->codec
->bits_per_coded_sample
;
673 case AVMEDIA_TYPE_VIDEO
:
674 iff
->bpp
= st
->codec
->bits_per_coded_sample
;
675 if ((screenmode
& 0x800 /* Hold And Modify */) && iff
->bpp
<= 8) {
676 iff
->ham
= iff
->bpp
> 6 ? 6 : 4;
677 st
->codec
->bits_per_coded_sample
= 24;
679 iff
->flags
= (screenmode
& 0x80 /* Extra HalfBrite */) && iff
->bpp
<= 8;
680 iff
->masking
= masking
;
681 iff
->transparency
= transparency
;
683 if (!st
->codec
->extradata
) {
684 st
->codec
->extradata_size
= IFF_EXTRA_VIDEO_SIZE
;
685 st
->codec
->extradata
= av_malloc(IFF_EXTRA_VIDEO_SIZE
+ FF_INPUT_BUFFER_PADDING_SIZE
);
686 if (!st
->codec
->extradata
)
687 return AVERROR(ENOMEM
);
689 av_assert0(st
->codec
->extradata_size
>= IFF_EXTRA_VIDEO_SIZE
);
690 buf
= st
->codec
->extradata
;
691 bytestream_put_be16(&buf
, IFF_EXTRA_VIDEO_SIZE
);
692 bytestream_put_byte(&buf
, iff
->bitmap_compression
);
693 bytestream_put_byte(&buf
, iff
->bpp
);
694 bytestream_put_byte(&buf
, iff
->ham
);
695 bytestream_put_byte(&buf
, iff
->flags
);
696 bytestream_put_be16(&buf
, iff
->transparency
);
697 bytestream_put_byte(&buf
, iff
->masking
);
698 bytestream_put_buffer(&buf
, iff
->tvdc
, sizeof(iff
->tvdc
));
699 st
->codec
->codec_id
= AV_CODEC_ID_IFF_ILBM
;
708 static int iff_read_packet(AVFormatContext
*s
,
711 IffDemuxContext
*iff
= s
->priv_data
;
712 AVIOContext
*pb
= s
->pb
;
713 AVStream
*st
= s
->streams
[0];
715 int64_t pos
= avio_tell(pb
);
717 if (pos
>= iff
->body_end
)
720 if (st
->codec
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
721 if (st
->codec
->codec_tag
== ID_DSD
|| st
->codec
->codec_tag
== ID_MAUD
) {
722 ret
= av_get_packet(pb
, pkt
, FFMIN(iff
->body_end
- pos
, 1024 * st
->codec
->block_align
));
724 ret
= av_get_packet(pb
, pkt
, iff
->body_size
);
726 } else if (st
->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
729 if (av_new_packet(pkt
, iff
->body_size
+ 2) < 0) {
730 return AVERROR(ENOMEM
);
734 bytestream_put_be16(&buf
, 2);
735 ret
= avio_read(pb
, buf
, iff
->body_size
);
738 } else if (ret
< iff
->body_size
)
739 av_shrink_packet(pkt
, ret
+ 2);
744 if (pos
== iff
->body_pos
)
745 pkt
->flags
|= AV_PKT_FLAG_KEY
;
748 pkt
->stream_index
= 0;
752 AVInputFormat ff_iff_demuxer
= {
754 .long_name
= NULL_IF_CONFIG_SMALL("IFF (Interchange File Format)"),
755 .priv_data_size
= sizeof(IffDemuxContext
),
756 .read_probe
= iff_probe
,
757 .read_header
= iff_read_header
,
758 .read_packet
= iff_read_packet
,
759 .flags
= AVFMT_GENERIC_INDEX
| AVFMT_NO_BYTE_SEEK
,