Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

bool Gob::Imd::load ( Common::SeekableReadStream stream  )  [virtual]

Load a video out of a stream.

Implements Gob::CoktelVideo.

Definition at line 41 of file coktelvideo.cpp.

References Gob::CoktelVideo::kFeaturesDataSize, Gob::CoktelVideo::kFeaturesFrameCoords, Gob::CoktelVideo::kFeaturesFramesPos, Gob::CoktelVideo::kFeaturesSound, Gob::CoktelVideo::kFeaturesStdCoords, Gob::CoktelVideo::kFeaturesVideo, Common::ReadStream::read(), Common::ReadStream::readByte(), Common::ReadStream::readSint16LE(), Common::ReadStream::readUint16LE(), Common::ReadStream::readUint32LE(), Common::SeekableReadStream::seek(), and unload().

                                               {
      unload();

      _stream = &stream;

      // Version
      uint16 handle = _stream->readUint16LE();
      _version = _stream->readByte();

      // Version checking
      if ((handle != 0) || (_version < 2)) {
            warning("IMD Version incorrect (%d,%X)", handle, _version);
            unload();
            return false;
      }

      // Rest header
      _features = _stream->readByte();
      _framesCount = _stream->readUint16LE();
      _x = _stream->readSint16LE();
      _y = _stream->readSint16LE();
      _width = _stream->readSint16LE();
      _height = _stream->readSint16LE();
      _flags = _stream->readUint16LE();
      _firstFramePos = _stream->readUint16LE();

      // IMDs always have video
      _features |= kFeaturesVideo;

      // Palette
      _stream->read((byte *) _palette, 768);

      // Standard coordinates
      if (_version >= 3) {
            _stdX = _stream->readUint16LE();
            if (_stdX > 1) {
                  warning("IMD: More than one standard coordinate quad found (%d)", _stdX);
                  unload();
                  return false;
            }
            if (_stdX != 0) {
                  _stdX = _stream->readSint16LE();
                  _stdY = _stream->readSint16LE();
                  _stdWidth = _stream->readSint16LE();
                  _stdHeight = _stream->readSint16LE();
                  _features |= kFeaturesStdCoords;
            } else
                  _stdX = -1;
      } else
            _stdX = -1;

      // Offset to frame positions table
      uint32 framesPosPos = 0;
      if (_version >= 4) {
            framesPosPos = _stream->readUint32LE();
            if (framesPosPos != 0) {
                  _framesPos = new uint32[_framesCount];
                  assert(_framesPos);
                  _features |= kFeaturesFramesPos;
            }
      }

      // Offset to frame coordinates
      uint32 framesCoordsPos = 0;
      if (_features & kFeaturesFrameCoords)
            framesCoordsPos = _stream->readUint32LE();

      // Sound
      if (_features & kFeaturesSound) {
            _soundFreq = _stream->readSint16LE();
            _soundSliceSize = _stream->readSint16LE();
            _soundSlicesCount = _stream->readSint16LE();

            if (_soundFreq < 0)
                  _soundFreq = -_soundFreq;

            if (_soundSlicesCount < 0)
                  _soundSlicesCount = -_soundSlicesCount - 1;

            if (_soundSlicesCount > 40) {
                  warning("IMD: More than 40 sound slices found (%d)", _soundSlicesCount);
                  unload();
                  return false;
            }

            _soundSliceLength = 1000 / (_soundFreq / _soundSliceSize);
            _frameLength = _soundSliceLength;

            _soundStage = 1;
            _hasSound = true;

            _audioStream = Audio::makeAppendableAudioStream(_soundFreq, 0);
      } else
            _frameLength = 1000 / 12; // 12 FPS for a video without sound

      // Sizes of the frame data and extra video buffer
      if (_features & kFeaturesDataSize) {
            _frameDataSize = _stream->readUint16LE();
            if (_frameDataSize == 0) {
                  _frameDataSize = _stream->readUint32LE();
                  _vidBufferSize = _stream->readUint32LE();
            } else
                  _vidBufferSize = _stream->readUint16LE();
      } else {
            _frameDataSize = _width * _height + 500;
            if (!(_flags & 0x100) || (_flags & 0x1000))
                  _vidBufferSize = _frameDataSize;
      }

      // Frame positions table
      if (_framesPos) {
            _stream->seek(framesPosPos, SEEK_SET);
            for (int i = 0; i < _framesCount; i++)
                  _framesPos[i] = _stream->readUint32LE();
      }

      // Frame coordinates table
      if (_features & kFeaturesFrameCoords) {
            _stream->seek(framesCoordsPos, SEEK_SET);
            _frameCoords = new Coord[_framesCount];
            assert(_frameCoords);
            for (int i = 0; i < _framesCount; i++) {
                  _frameCoords[i].left = _stream->readSint16LE();
                  _frameCoords[i].top = _stream->readSint16LE();
                  _frameCoords[i].right = _stream->readSint16LE();
                  _frameCoords[i].bottom = _stream->readSint16LE();
            }
      }

      // Seek to the first frame
      _stream->seek(_firstFramePos, SEEK_SET);

      // Allocating working memory
      _frameData = new byte[_frameDataSize + 500];
      assert(_frameData);
      memset(_frameData, 0, _frameDataSize + 500);
      _vidBuffer = new byte[_vidBufferSize + 500];
      assert(_vidBuffer);
      memset(_vidBuffer, 0, _vidBufferSize + 500);

      return true;
}


Generated by  Doxygen 1.6.0   Back to index