bool PEResources::loadFromEXE(File *stream) { clear(); if (!stream) return false; if (stream->readUint16BE() != MKTAG16('M', 'Z')) return false; stream->skip(58); uint32 peOffset = stream->readUint32LE(); if (!peOffset || peOffset >= (uint32)stream->size()) return false; stream->seek(peOffset); if (stream->readUint32BE() != MKTAG('P','E',0,0)) return false; stream->skip(2); uint16 sectionCount = stream->readUint16LE(); stream->skip(12); uint16 optionalHeaderSize = stream->readUint16LE(); stream->skip(optionalHeaderSize + 2); // Read in all the sections for (uint16 i = 0; i < sectionCount; i++) { char sectionName[9]; stream->read(sectionName, 8); sectionName[8] = 0; Section section; stream->skip(4); section.virtualAddress = stream->readUint32LE(); section.size = stream->readUint32LE(); section.offset = stream->readUint32LE(); stream->skip(16); _sections[sectionName] = section; } // Currently, we require loading a resource section if (!_sections.contains(".rsrc")) { clear(); return false; } _exe = stream; Section &resSection = _sections[".rsrc"]; parseResourceLevel(resSection, resSection.offset, 0); return true; }
void AVIDecoder::readNextPacket() { uint32 nextTag = _fileStream->readUint32BE(); uint32 size = _fileStream->readUint32LE(); if (_fileStream->eos()) return; if (nextTag == ID_LIST) { // A list of audio/video chunks int32 startPos = _fileStream->pos(); if (_fileStream->readUint32BE() != ID_REC) error("Expected 'rec ' LIST"); size -= 4; // subtract list type // Decode chunks in the list while (_fileStream->pos() < startPos + (int32)size) readNextPacket(); return; } else if (nextTag == ID_JUNK || nextTag == ID_IDX1) { skipChunk(size); return; } Track *track = getTrack(getStreamIndex(nextTag)); if (!track) error("Cannot get track from tag '%s'", tag2str(nextTag)); Common::SeekableReadStream *chunk = 0; if (size != 0) { chunk = _fileStream->readStream(size); _fileStream->skip(size & 1); } if (track->getTrackType() == Track::kTrackTypeAudio) { if (getStreamType(nextTag) != MKTAG16('w', 'b')) error("Invalid audio track tag '%s'", tag2str(nextTag)); assert(chunk); ((AVIAudioTrack *)track)->queueSound(chunk); } else { AVIVideoTrack *videoTrack = (AVIVideoTrack *)track; if (getStreamType(nextTag) == MKTAG16('p', 'c')) { // Palette Change assert(chunk); byte firstEntry = chunk->readByte(); uint16 numEntries = chunk->readByte(); chunk->readUint16LE(); // Reserved // 0 entries means all colors are going to be changed if (numEntries == 0) numEntries = 256; byte *palette = const_cast<byte *>(videoTrack->getPalette()); for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) { palette[i * 3] = chunk->readByte(); palette[i * 3 + 1] = chunk->readByte(); palette[i * 3 + 2] = chunk->readByte(); chunk->readByte(); // Flags that don't serve us any purpose } delete chunk; videoTrack->markPaletteDirty(); } else if (getStreamType(nextTag) == MKTAG16('d', 'b')) { // TODO: Check if this really is uncompressed. Many videos // falsely put compressed data in here. error("Uncompressed AVI frame found"); } else { // Otherwise, assume it's a compressed frame videoTrack->decodeFrame(chunk); } } }