VIDEO: Fix AVI indexes with absolute offsets

This commit is contained in:
Matthew Hoops 2013-11-23 10:58:01 -05:00
parent c7a7ab178d
commit 55791d5fc1
2 changed files with 44 additions and 11 deletions

View file

@ -158,16 +158,7 @@ bool AVIDecoder::parseNextChunk() {
skipChunk(size);
break;
case ID_IDX1:
debug(0, "%d Indices", size / 16);
for (uint32 i = 0; i < size / 16; i++) {
OldIndex indexEntry;
indexEntry.id = _fileStream->readUint32BE();
indexEntry.flags = _fileStream->readUint32LE();
indexEntry.offset = _fileStream->readUint32LE() + _movieListStart - 4; // Adjust to absolute
indexEntry.size = _fileStream->readUint32LE();
_indexEntries.push_back(indexEntry);
debug(0, "Index %d == Tag \'%s\', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags);
}
readOldIndex(size);
break;
default:
error("Unknown tag \'%s\' found", tag2str(tag));
@ -621,6 +612,46 @@ byte AVIDecoder::getStreamIndex(uint32 tag) const {
return strtol(string, 0, 16);
}
void AVIDecoder::readOldIndex(uint32 size) {
uint32 entryCount = size / 16;
debug(0, "Old Index: %d entries", entryCount);
if (entryCount == 0)
return;
// Read the first index separately
OldIndex firstEntry;
firstEntry.id = _fileStream->readUint32BE();
firstEntry.flags = _fileStream->readUint32LE();
firstEntry.offset = _fileStream->readUint32LE();
firstEntry.size = _fileStream->readUint32LE();
// Check if the offset is already absolute
// If it's absolute, the offset will equal the start of the movie list
bool isAbsolute = firstEntry.offset == _movieListStart;
debug(1, "Old index is %s", isAbsolute ? "absolute" : "relative");
if (!isAbsolute)
firstEntry.offset += _movieListStart - 4;
for (uint32 i = 1; i < entryCount; i++) {
OldIndex indexEntry;
indexEntry.id = _fileStream->readUint32BE();
indexEntry.flags = _fileStream->readUint32LE();
indexEntry.offset = _fileStream->readUint32LE();
indexEntry.size = _fileStream->readUint32LE();
// Adjust to absolute, if necessary
if (!isAbsolute)
indexEntry.offset += _movieListStart - 4;
_indexEntries.push_back(indexEntry);
debug(0, "Index %d: Tag '%s', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags);
}
}
AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette)
: _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader), _initialPalette(initialPalette) {
_videoCodec = createCodec();

View file

@ -230,9 +230,11 @@ protected:
Audio::QueuingAudioStream *createAudioStream();
};
Common::Array<OldIndex> _indexEntries;
AVIHeader _header;
void readOldIndex(uint32 size);
Common::Array<OldIndex> _indexEntries;
Common::SeekableReadStream *_fileStream;
bool _decodedHeader;
bool _foundMovieList;