bool FliPlayer::decodeFrame() { FrameTypeChunkHeader frameHeader; ChunkHeader cHeader = readChunkHeader(fli_data_); do { switch (cHeader.type) { case 4: setPalette(fli_data_ + 6); g_System.setPalette8b3(palette_); break; case 7: decodeDeltaFLC(fli_data_ + 6); break; case 15: decodeByteRun(fli_data_ + 6); break; case FRAME_TYPE: frameHeader = readFrameTypeChunkHeader(cHeader, fli_data_); fli_info_.numFrames--; //printf("Frames Remaining: %d\n", fli_info_.numFrames); break; default: break; } if (cHeader.type != FRAME_TYPE) fli_data_ += cHeader.size; cHeader = readChunkHeader(fli_data_); } while (isValidChunk(cHeader.type) && cHeader.type != FRAME_TYPE); return isValidChunk(cHeader.type); }
void FlicDecoder::FlicVideoTrack::handleFrame() { uint16 chunkCount = _fileStream->readUint16LE(); // Note: The overridden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword) // the frame delay is the FLIC "speed", in milliseconds. uint16 newFrameDelay = _fileStream->readUint16LE(); // "speed", in milliseconds if (newFrameDelay > 0) _frameDelay = newFrameDelay; _fileStream->readUint16LE(); // reserved, always 0 uint16 newWidth = _fileStream->readUint16LE(); uint16 newHeight = _fileStream->readUint16LE(); if ((newWidth != 0) || (newHeight != 0)) { if (newWidth == 0) newWidth = _surface->w; if (newHeight == 0) newHeight = _surface->h; _surface->free(); delete _surface; _surface = new Graphics::Surface(); _surface->create(newWidth, newHeight, Graphics::PixelFormat::createFormatCLUT8()); } // Read subchunks for (uint32 i = 0; i < chunkCount; ++i) { uint32 frameSize = _fileStream->readUint32LE(); uint16 frameType = _fileStream->readUint16LE(); uint8 *data = new uint8[frameSize - 6]; _fileStream->read(data, frameSize - 6); switch (frameType) { case FLI_SETPAL: unpackPalette(data); _dirtyPalette = true; break; case FLI_SS2: decodeDeltaFLC(data); break; case FLI_BRUN: decodeByteRun(data); break; case FLI_COPY: copyFrame(data); break; case PSTAMP: /* PSTAMP - skip for now */ break; default: error("FlicDecoder::decodeNextFrame(): unknown subchunk type (type = 0x%02X)", frameType); break; } delete[] data; } }
const Graphics::Surface *FlicDecoder::FlicVideoTrack::decodeNextFrame() { // Read chunk uint32 frameSize = _fileStream->readUint32LE(); uint16 frameType = _fileStream->readUint16LE(); uint16 chunkCount = 0; switch (frameType) { case FRAME_TYPE: { chunkCount = _fileStream->readUint16LE(); // Note: The overridden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword) // the frame delay is the FLIC "speed", in milliseconds. uint16 newFrameDelay = _fileStream->readUint16LE(); // "speed", in milliseconds if (newFrameDelay > 0) _frameDelay = newFrameDelay; _fileStream->readUint16LE(); // reserved, always 0 uint16 newWidth = _fileStream->readUint16LE(); uint16 newHeight = _fileStream->readUint16LE(); if ((newWidth != 0) && (newHeight != 0)) { if (newWidth == 0) newWidth = _surface->w; if (newHeight == 0) newHeight = _surface->h; _surface->free(); delete _surface; _surface = new Graphics::Surface(); _surface->create(newWidth, newHeight, Graphics::PixelFormat::createFormatCLUT8()); } } break; default: error("FlicDecoder::decodeFrame(): unknown main chunk type (type = 0x%02X)", frameType); break; } // Read subchunks if (frameType == FRAME_TYPE) { for (uint32 i = 0; i < chunkCount; ++i) { frameSize = _fileStream->readUint32LE(); frameType = _fileStream->readUint16LE(); uint8 *data = new uint8[frameSize - 6]; _fileStream->read(data, frameSize - 6); switch (frameType) { case FLI_SETPAL: unpackPalette(data); _dirtyPalette = true; break; case FLI_SS2: decodeDeltaFLC(data); break; case FLI_BRUN: decodeByteRun(data); break; case FLI_COPY: copyFrame(data); break; case PSTAMP: /* PSTAMP - skip for now */ break; default: error("FlicDecoder::decodeNextFrame(): unknown subchunk type (type = 0x%02X)", frameType); break; } delete[] data; } } _curFrame++; _nextFrameStartTime += _frameDelay; if (_atRingFrame) { // If we decoded the ring frame, seek to the second frame _atRingFrame = false; _fileStream->seek(_offsetFrame2); } return _surface; }