void SmackerDecoder::readNextPacket() { SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0); if (videoTrack->endOfTrack()) return; videoTrack->increaseCurFrame(); uint i; uint32 chunkSize = 0; uint32 dataSizeUnpacked = 0; uint32 startPos = _fileStream->pos(); // Check if we got a frame with palette data, and // call back the virtual setPalette function to set // the current palette if (_frameTypes[videoTrack->getCurFrame()] & 1) videoTrack->unpackPalette(_fileStream); // Load audio tracks for (i = 0; i < 7; ++i) { if (!(_frameTypes[videoTrack->getCurFrame()] & (2 << i))) continue; chunkSize = _fileStream->readUint32LE(); chunkSize -= 4; // subtract the first 4 bytes (chunk size) if (_header.audioInfo[i].compression == kCompressionNone) { dataSizeUnpacked = chunkSize; } else { dataSizeUnpacked = _fileStream->readUint32LE(); chunkSize -= 4; // subtract the next 4 bytes (unpacked data size) } handleAudioTrack(i, chunkSize, dataSizeUnpacked); } uint32 frameSize = _frameSizes[videoTrack->getCurFrame()] & ~3; // uint32 remainder = _frameSizes[videoTrack->getCurFrame()] & 3; if (_fileStream->pos() - startPos > frameSize) error("Smacker actual frame size exceeds recorded frame size"); uint32 frameDataSize = frameSize - (_fileStream->pos() - startPos); byte *frameData = (byte *)malloc(frameDataSize + 1); // Padding to keep the BigHuffmanTrees from reading past the data end frameData[frameDataSize] = 0x00; _fileStream->read(frameData, frameDataSize); Common::BitStream8LSB bs(new Common::MemoryReadStream(frameData, frameDataSize + 1, DisposeAfterUse::YES), true); videoTrack->decodeFrame(bs); _fileStream->seek(startPos + frameSize); }
void NeverhoodSmackerDecoder::forceSeekToFrame(uint frame) { if (!isVideoLoaded()) return; if (frame >= getFrameCount()) error("Can't force Smacker seek to invalid frame %d", frame); if (_header.audioInfo[0].hasAudio) error("Can't force Smacker frame seek with audio"); if (!rewind()) error("Failed to rewind"); SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0); uint32 offset = 0; for (uint32 i = 0; i < frame; i++) { videoTrack->increaseCurFrame(); offset += _frameSizes[i] & ~3; } _fileStream->seek(offset, SEEK_CUR); }