bool CUP_Player::parseNextHeaderTag(Common::SeekableReadStream &dataStream) {
	uint32 tag = dataStream.readUint32BE();
	uint32 size = dataStream.readUint32BE() - 8;

	if (dataStream.eos())
		return false;

	uint32 next = dataStream.pos() + size;
	debug(1, "New header tag %s %d dataSize %d", tag2str(tag), size, _dataSize);
	switch (tag) {
	case MKTAG('H','E','A','D'):
		handleHEAD(dataStream, size);
		break;
	case MKTAG('S','F','X','B'):
		handleSFXB(dataStream, size);
		break;
	case MKTAG('R','G','B','S'):
		handleRGBS(dataStream, size);
		break;
	case MKTAG('D','A','T','A'):
		_dataSize = size;
		return false;
	case MKTAG('G','F','X','B'):
		// this is never triggered
	default:
		warning("Unhandled tag %s", tag2str(tag));
		break;
	}
	dataStream.seek(next);
	return true;
}
Exemple #2
0
byte *ScummEngine_v71he::heFindResource(uint32 tag, byte *searchin) {
	uint32 curpos, totalsize, size;

	debugC(DEBUG_RESOURCE, "heFindResource(%s, %p)", tag2str(tag), (const void *)searchin);

	assert(searchin);
	searchin += 4;
	_resourceLastSearchSize = totalsize = READ_BE_UINT32(searchin);
	curpos = 8;
	searchin += 4;

	while (curpos < totalsize) {
		if (READ_BE_UINT32(searchin) == tag) {
			return searchin;
		}

		size = READ_BE_UINT32(searchin + 4);
		if ((int32)size <= 0) {
			error("(%s) Not found in %d... illegal block len %d", tag2str(tag), 0, size);
			return NULL;
		}

		curpos += size;
		searchin += size;
	}

	return NULL;
}
Exemple #3
0
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) != kStreamTypeAudio)
			error("Invalid audio track tag '%s'", tag2str(nextTag));

		assert(chunk);
		((AVIAudioTrack *)track)->queueSound(chunk);
	} else {
		AVIVideoTrack *videoTrack = (AVIVideoTrack *)track;

		if (getStreamType(nextTag) == kStreamTypePaletteChange) {
			// Palette Change
			videoTrack->loadPaletteFromChunk(chunk);
		} else if (getStreamType(nextTag) == kStreamTypeRawVideo) {
			// 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);
		}
	}
}
Exemple #4
0
void AviDecoder::runHandle(uint32 tag) {
	assert (_fileStream);
	if (_fileStream->eos())
		return;

	debug (3, "Decoding tag %s", tag2str(tag));

	switch (tag) {
		case ID_RIFF:
			/*_filesize = */_fileStream->readUint32LE();
			if (_fileStream->readUint32BE() != ID_AVI)
				error("RIFF file is not an AVI video");
			break;
		case ID_LIST:
			handleList();
			break;
		case ID_AVIH:
			_header.size = _fileStream->readUint32LE();
			_header.microSecondsPerFrame = _fileStream->readUint32LE();
			_header.maxBytesPerSecond = _fileStream->readUint32LE();
			_header.padding = _fileStream->readUint32LE();
			_header.flags = _fileStream->readUint32LE();
			_header.totalFrames = _fileStream->readUint32LE();
			_header.initialFrames = _fileStream->readUint32LE();
			_header.streams = _fileStream->readUint32LE();
			_header.bufferSize = _fileStream->readUint32LE();
			_header.width = _fileStream->readUint32LE();
			_header.height = _fileStream->readUint32LE();
			//Ignore 16 bytes of reserved data
			_fileStream->skip(16);
			break;
		case ID_STRH:
			handleStreamHeader();
			break;
		case ID_STRD: // Extra stream info, safe to ignore
		case ID_VEDT: // Unknown, safe to ignore
		case ID_JUNK: // Alignment bytes, should be ignored
			{
			uint32 junkSize = _fileStream->readUint32LE();
			_fileStream->skip(junkSize + (junkSize & 1)); // Alignment
			} break;
		case ID_IDX1:
			_ixInfo.size = _fileStream->readUint32LE();
			_ixInfo.indices = new AVIOLDINDEX::Index[_ixInfo.size / 16];
			debug (0, "%d Indices", (_ixInfo.size / 16));
			for (uint32 i = 0; i < (_ixInfo.size / 16); i++) {
				_ixInfo.indices[i].id = _fileStream->readUint32BE();
				_ixInfo.indices[i].flags = _fileStream->readUint32LE();
				_ixInfo.indices[i].offset = _fileStream->readUint32LE();
				_ixInfo.indices[i].size = _fileStream->readUint32LE();
				debug (0, "Index %d == Tag \'%s\', Offset = %d, Size = %d", i, tag2str(_ixInfo.indices[i].id), _ixInfo.indices[i].offset, _ixInfo.indices[i].size);
			}
			break;
		default:
			error ("Unknown tag \'%s\' found", tag2str(tag));
	}
}
Exemple #5
0
bool AVIDecoder::parseNextChunk() {
	uint32 tag = _fileStream->readUint32BE();
	uint32 size = _fileStream->readUint32LE();

	if (_fileStream->eos())
		return false;

	debug(3, "Decoding tag %s", tag2str(tag));

	switch (tag) {
	case ID_LIST:
		handleList(size);
		break;
	case ID_AVIH:
		_header.size = size;
		_header.microSecondsPerFrame = _fileStream->readUint32LE();
		_header.maxBytesPerSecond = _fileStream->readUint32LE();
		_header.padding = _fileStream->readUint32LE();
		_header.flags = _fileStream->readUint32LE();
		_header.totalFrames = _fileStream->readUint32LE();
		_header.initialFrames = _fileStream->readUint32LE();
		_header.streams = _fileStream->readUint32LE();
		_header.bufferSize = _fileStream->readUint32LE();
		_header.width = _fileStream->readUint32LE();
		_header.height = _fileStream->readUint32LE();
		// Ignore 16 bytes of reserved data
		_fileStream->skip(16);
		break;
	case ID_STRH:
		handleStreamHeader(size);
		break;
	case ID_STRD: // Extra stream info, safe to ignore
	case ID_VEDT: // Unknown, safe to ignore
	case ID_JUNK: // Alignment bytes, should be ignored
	case ID_ISFT: // Metadata, safe to ignore
	case ID_DISP: // Metadata, should be safe to ignore
		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);
		}
		break;
	default:
		error("Unknown tag \'%s\' found", tag2str(tag));
	}

	return true;
}
Exemple #6
0
Common::String Archive::getName(uint32 tag, uint16 id) const {
	if (!_types.contains(tag))
		error("Archive does not contain '%s' %04x", tag2str(tag), id);

	const ResourceMap &resMap = _types[tag];

	if (!resMap.contains(id))
		error("Archive does not contain '%s' %04x", tag2str(tag), id);

	return resMap[id].name;
}
Exemple #7
0
uint32 Archive::getOffset(uint32 tag, uint16 id) const {
	if (!_types.contains(tag))
		error("Archive does not contain '%s' %04x", tag2str(tag), id);

	const ResourceMap &resMap = _types[tag];

	if (!resMap.contains(id))
		error("Archive does not contain '%s' %04x", tag2str(tag), id);

	return resMap[id].offset;
}
Exemple #8
0
bool AVIDecoder::parseNextChunk() {
	uint32 tag = _fileStream->readUint32BE();
	uint32 size = _fileStream->readUint32LE();

	if (_fileStream->eos())
		return false;

	debug(6, "Decoding tag %s", tag2str(tag));

	switch (tag) {
	case ID_LIST:
		handleList(size);
		break;
	case ID_AVIH:
		_header.size = size;
		_header.microSecondsPerFrame = _fileStream->readUint32LE();
		_header.maxBytesPerSecond = _fileStream->readUint32LE();
		_header.padding = _fileStream->readUint32LE();
		_header.flags = _fileStream->readUint32LE();
		_header.totalFrames = _fileStream->readUint32LE();
		_header.initialFrames = _fileStream->readUint32LE();
		_header.streams = _fileStream->readUint32LE();
		_header.bufferSize = _fileStream->readUint32LE();
		_header.width = _fileStream->readUint32LE();
		_header.height = _fileStream->readUint32LE();
		// Ignore 16 bytes of reserved data
		_fileStream->skip(16);
		break;
	case ID_STRH:
		handleStreamHeader(size);
		break;
	case ID_STRD: // Extra stream info, safe to ignore
	case ID_VEDT: // Unknown, safe to ignore
	case ID_JUNK: // Alignment bytes, should be ignored
	case ID_JUNQ: // Same as JUNK, safe to ignore
	case ID_ISFT: // Metadata, safe to ignore
	case ID_DISP: // Metadata, should be safe to ignore
	case ID_DMLH: // OpenDML extension, contains an extra total frames field, safe to ignore
		skipChunk(size);
		break;
	case ID_STRN: // Metadata, safe to ignore
		readStreamName(size);
		break;
	case ID_IDX1:
		readOldIndex(size);
		break;
	default:
		error("Unknown tag \'%s\' found", tag2str(tag));
	}

	return true;
}
Exemple #9
0
Common::SeekableSubReadStreamEndian *Archive::getResource(uint32 tag, uint16 id) {
	if (!_types.contains(tag))
		error("Archive does not contain '%s' %04x", tag2str(tag), id);

	const ResourceMap &resMap = _types[tag];

	if (!resMap.contains(id))
		error("Archive does not contain '%s' %04x", tag2str(tag), id);

	const Resource &res = resMap[id];

	return new Common::SeekableSubReadStreamEndian(_stream, res.offset, res.offset + res.size, _isBigEndian, DisposeAfterUse::NO);
}
Exemple #10
0
void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, int &numSyncs, int &numMarkers) {
	uint32 tag;
	int32 size = 0;

	do {
		tag = READ_BE_UINT32(ptr); ptr += 4;
		switch (tag) {
		case MKTAG('S','T','O','P'):
		case MKTAG('F','R','M','T'):
		case MKTAG('D','A','T','A'):
			size = READ_BE_UINT32(ptr); ptr += size + 4;
			break;
		case MKTAG('T','E','X','T'):
			if (!scumm_stricmp((const char *)(ptr + 8), "exit"))
				numMarkers++;
			size = READ_BE_UINT32(ptr); ptr += size + 4;
			break;
		case MKTAG('R','E','G','N'):
			numRegions++;
			size = READ_BE_UINT32(ptr); ptr += size + 4;
			break;
		case MKTAG('J','U','M','P'):
			numJumps++;
			size = READ_BE_UINT32(ptr); ptr += size + 4;
			break;
		case MKTAG('S','Y','N','C'):
			numSyncs++;
			size = READ_BE_UINT32(ptr); ptr += size + 4;
			break;
		default:
			error("ImuseDigiSndMgr::countElements() Unknown sfx header '%s'", tag2str(tag));
		}
	} while (tag != MKTAG('D','A','T','A'));
}
Exemple #11
0
Codec *createQuickTimeCodec(uint32 tag, int width, int height, int bitsPerPixel) {
	switch (tag) {
	case MKTAG('c','v','i','d'):
		// Cinepak: As used by most Myst and all Riven videos as well as some Myst ME videos. "The Chief" videos also use this.
		return new CinepakDecoder(bitsPerPixel);
	case MKTAG('r','p','z','a'):
		// Apple Video ("Road Pizza"): Used by some Myst videos.
		return new RPZADecoder(width, height);
	case MKTAG('r','l','e',' '):
		// QuickTime RLE: Used by some Myst ME videos.
		return new QTRLEDecoder(width, height, bitsPerPixel);
	case MKTAG('s','m','c',' '):
		// Apple SMC: Used by some Myst videos.
		return new SMCDecoder(width, height);
	case MKTAG('S','V','Q','1'):
		// Sorenson Video 1: Used by some Myst ME videos.
		return new SVQ1Decoder(width, height);
	case MKTAG('S','V','Q','3'):
		// Sorenson Video 3: Used by some Myst ME videos.
		warning("Sorenson Video 3 not yet supported");
		break;
	case MKTAG('j','p','e','g'):
		// JPEG: Used by some Myst ME 10th Anniversary videos.
		return new JPEGDecoder();
	case MKTAG('Q','k','B','k'):
		// CDToons: Used by most of the Broderbund games.
		return new CDToonsDecoder(width, height);
	default:
		warning("Unsupported QuickTime codec \'%s\'", tag2str(tag));
	}

	return 0;
}
Exemple #12
0
void
reportstats (void)
{
  unsigned int grandcount = 1;
  unsigned int grandreachcount = 1;
  uint32_t grandspace = headspace;
  int k;
  for (k=0; k<MAX_TAG; k++) {
    grandcount += count[k];
    grandreachcount += reachcount[k];
    grandspace += space[k];
  }
  if (rmode) printf("%7s", "% Reach");
  printf("%10s   %-20s%12s%10s\n\n",
    "Number", "Description", "Bytes", "% Space");
  if (rmode) printf("%7.1f", pc(1,1));
  printf("%10u   %-20s%12u%10.1f\n",
    1, "header", headspace, pc(headspace,grandspace));
  for (k=0; k<=ListCons; (k==ExpDoStmt? k=AtomVariable: k++)) {
    if (rmode) printf("%7.1f", pc(reachcount[k], count[k]));
    printf("%10u   %-20s%12u%10.1f\n",
      count[k], tag2str(k), space[k],
      pc(space[k],grandspace));
  }
  { int w;
    putchar('\n');
    if (rmode) for (w=0; w<7; w++) putchar(' ');
    for (w=0; w<55; w++) putchar(w<13 ? ' ' : '-');
    putchar('\n');
  }
  if (rmode) printf("%7.1f", pc(grandreachcount,grandcount));
  printf("%10u   %-20s%12u%10.1f\n",
    grandcount, "whole trace file", grandspace, pc(grandspace,grandspace));
}
bool BundleMgr::loadCompTable(int32 index) {
	_file->seek(_bundleTable[index].offset, SEEK_SET);
	uint32 tag = _file->readUint32BE();
	_numCompItems = _file->readUint32BE();
	assert(_numCompItems > 0);
	_file->seek(8, SEEK_CUR);

	if (tag != MKID_BE('COMP')) {
		error("BundleMgr::loadCompTable() Compressed sound %d invalid (%s)", index, tag2str(tag));
		return false;
	}

	_compTable = (CompTable *)malloc(sizeof(CompTable) * _numCompItems);
	assert(_compTable);
	int32 maxSize = 0;
	for (int i = 0; i < _numCompItems; i++) {
		_compTable[i].offset = _file->readUint32BE();
		_compTable[i].size = _file->readUint32BE();
		_compTable[i].codec = _file->readUint32BE();
		_file->seek(4, SEEK_CUR);
		if (_compTable[i].size > maxSize)
			maxSize = _compTable[i].size;
	}
	// CMI hack: one more byte at the end of input buffer
	_compInput = (byte *)malloc(maxSize + 1);
	assert(_compInput);

	return true;
}
Exemple #14
0
void AVIDecoder::handleList(uint32 listSize) {
	uint32 listType = _fileStream->readUint32BE();
	listSize -= 4; // Subtract away listType's 4 bytes
	uint32 curPos = _fileStream->pos();

	debug(0, "Found LIST of type %s", tag2str(listType));

	switch (listType) {
	case ID_MOVI: // Movie List
		// We found the movie block
		_foundMovieList = true;
		_movieListStart = curPos;
		_fileStream->skip(listSize);
		return;
	case ID_HDRL: // Header List
		// Mark the header as decoded
		_decodedHeader = true;
		break;
	case ID_INFO: // Metadata
	case ID_PRMI: // Unknown metadata, should be safe to ignore
		// Ignore metadata
		_fileStream->skip(listSize);
		return;
	case ID_STRL: // Stream list
	default:      // (Just hope we can parse it!)
		break;
	}

	while ((_fileStream->pos() - curPos) < listSize)
		parseNextChunk();
}
Exemple #15
0
void QuickTimeDecoder::VideoSampleDesc::initCodec(Graphics::Surface &surface) {
	if (_codecTag == MKID_BE('mp4v')) {
		Common::UString videoType;

		// Parse the object type
		switch (_parentTrack->objectTypeMP4) {
		case 0x20:
			videoType = "h.263";

			_videoCodec = new H263Codec(_parentTrack->width, _parentTrack->height);
			if (_parentTrack->extraData)
				_videoCodec->decodeFrame(surface, *_parentTrack->extraData);
			break;

		default:
			videoType = "Unknown";
			break;
		}

		if (!_videoCodec)
			warning("MPEG-4 Video (%s) not yet supported", videoType.c_str());

	} else if (_codecTag == MKID_BE('SVQ3')) {
		// TODO: Sorenson Video 3
		warning("Sorenson Video 3 not yet supported");
	} else {
		warning("Unsupported codec \'%s\'", tag2str(_codecTag));
	}
}
Exemple #16
0
Codec *QuickTimeDecoder::createCodec(uint32 codecTag, byte bitsPerPixel) {
	if (codecTag == MKID_BE('cvid')) {
		// Cinepak: As used by most Myst and all Riven videos as well as some Myst ME videos. "The Chief" videos also use this.
		return new CinepakDecoder(bitsPerPixel);
	} else if (codecTag == MKID_BE('rpza')) {
		// Apple Video ("Road Pizza"): Used by some Myst videos.
		return new RPZADecoder(getWidth(), getHeight());
	} else if (codecTag == MKID_BE('rle ')) {
		// QuickTime RLE: Used by some Myst ME videos.
		return new QTRLEDecoder(getWidth(), getHeight(), bitsPerPixel);
	} else if (codecTag == MKID_BE('smc ')) {
		// Apple SMC: Used by some Myst videos.
		return new SMCDecoder(getWidth(), getHeight());
	} else if (codecTag == MKID_BE('SVQ1')) {
		// Sorenson Video 1: Used by some Myst ME videos.
		warning("Sorenson Video 1 not yet supported");
	} else if (codecTag == MKID_BE('SVQ3')) {
		// Sorenson Video 3: Used by some Myst ME videos.
		warning("Sorenson Video 3 not yet supported");
	} else if (codecTag == MKID_BE('jpeg')) {
		// Motion JPEG: Used by some Myst ME 10th Anniversary videos.
		return new JPEGDecoder();
	} else if (codecTag == MKID_BE('QkBk')) {
		// CDToons: Used by most of the Broderbund games.
		return new CDToonsDecoder(getWidth(), getHeight());
	} else {
		warning("Unsupported codec \'%s\'", tag2str(codecTag));
	}

	return NULL;
}
Exemple #17
0
Common::SeekableReadStream *ComposerEngine::getResource(uint32 tag, uint16 id) {
	for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++)
		if (i->_archive->hasResource(tag, id))
			return i->_archive->getResource(tag, id);

	error("No loaded library contains '%s' %04x", tag2str(tag), id);
}
Exemple #18
0
Codec *AVIDecoder::AVIVideoTrack::createCodec() {
	switch (_vidsHeader.streamHandler) {
	case ID_CRAM:
	case ID_MSVC:
	case ID_WHAM:
		return new MSVideo1Decoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
	case ID_RLE:
		return new MSRLEDecoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
	case ID_CVID:
		return new CinepakDecoder(_bmInfo.bitCount);
	case ID_IV32:
		return new Indeo3Decoder(_bmInfo.width, _bmInfo.height);
#ifdef VIDEO_CODECS_TRUEMOTION1_H
	case ID_DUCK:
		return new TrueMotion1Decoder(_bmInfo.width, _bmInfo.height);
#endif
#ifdef USE_MPEG2
	case ID_MPG2:
		return new MPEGDecoder();
#endif
	default:
		warning("Unknown/Unhandled compression format \'%s\'", tag2str(_vidsHeader.streamHandler));
	}

	return 0;
}
Exemple #19
0
Common::SeekableReadStream *MohawkEngine::getResource(uint32 tag, uint16 id) {
    for (uint32 i = 0; i < _mhk.size(); i++)
        if (_mhk[i]->hasResource(tag, id))
            return _mhk[i]->getResource(tag, id);

    error("Could not find a '%s' resource with ID %04x", tag2str(tag), id);
    return NULL;
}
Exemple #20
0
uint16 MohawkEngine::findResourceID(uint32 tag, const Common::String &resName) {
    for (uint32 i = 0; i < _mhk.size(); i++)
        if (_mhk[i]->hasResource(tag, resName))
            return _mhk[i]->findResourceID(tag, resName);

    error("Could not find a '%s' resource matching name '%s'", tag2str(tag), resName.c_str());
    return 0xFFFF;
}
Exemple #21
0
uint32 MohawkEngine::getResourceOffset(uint32 tag, uint16 id) {
    for (uint32 i = 0; i < _mhk.size(); i++)
        if (_mhk[i]->hasResource(tag, id))
            return _mhk[i]->getOffset(tag, id);

    error("Could not find a '%s' resource with ID %04x", tag2str(tag), id);
    return 0;
}
Exemple #22
0
void
dopointer (int okzero,
           int requiretag, FileOffset requireoffset,
           int contexttag, FileOffset contextoffset,
	   char *edgelabel)
{
  if (vmode && ((okzero==NONZERO && requireoffset <= Interrupted)
               || (okzero==MAYBELAMBDA && requireoffset < Lambda))) {
      fprintf(stderr, "bad %s pointer in %s 0x%x\n"
             ,ref2str(requireoffset), tag2str(contexttag), contextoffset);     
  }
  if (vmode && requireoffset>DoLambda) {
    int t = tagat(requireoffset);
    if (t != requiretag) {
      if ((requiretag==ANYEXP) && (ExpApp<=t) && (t<=ExpDoStmt))
        ;
      else if ((requiretag==ANYATOM) && (AtomVariable<=t) && (t<=AtomAbstract))
        ;
      else fprintf(stderr, "tag at 0x%x is %s, not %s as %s at 0x%x implies\n"
                         , requireoffset, tag2str(t), tag2str(requiretag)
	                 , tag2str(contexttag), contextoffset);
    }
  }
  if (amode) {
    switch(requireoffset) {
      case Root:
      case Unevaluated:
      case Entered:
      case Interrupted:
      case Lambda:
      case DoLambda:
                printf("(%s)",ref2str(requireoffset));
                break;
      default:  printf("(%s 0x%x)", tag2str(requiretag), requireoffset);
                break;
    }
  }
  if (gmode && requireoffset!=0 && *edgelabel != '\0')
    if (strcmp(edgelabel,"p")==0)
      printf("%d -> %d [style=dashed]\n",
        contextoffset, requireoffset);
    else
      printf("%d -> %d [label=\"%s\"]\n",
        contextoffset, requireoffset, edgelabel);
}
Exemple #23
0
Common::String MohawkEngine::getResourceName(uint32 tag, uint16 id) {
    for (uint32 i = 0; i < _mhk.size(); i++)
        if (_mhk[i]->hasResource(tag, id)) {
            return _mhk[i]->getName(tag, id);
        }

    error("Could not find a \'%s\' resource with ID %04x", tag2str(tag), id);
    return 0;
}
Exemple #24
0
bool CUP_Player::parseNextBlockTag(Common::SeekableReadStream &dataStream) {
	uint32 tag = dataStream.readUint32BE();
	uint32 size = dataStream.readUint32BE() - 8;
	uint32 next = dataStream.pos() + size;
	debug(1, "New block tag %s %d dataSize %d", tag2str(tag), size, _dataSize);
	switch (tag) {
	case MKTAG('F','R','A','M'):
		handleFRAM(dataStream, size);
		break;
	case MKTAG('L','Z','S','S'):
		if (handleLZSS(dataStream, size) && _outLzssBufSize != 0) {
			Common::MemoryReadStream memoryStream(_outLzssBufData, _outLzssBufSize);
			parseNextBlockTag(memoryStream);
		}
		break;
	case MKTAG('R','A','T','E'):
		handleRATE(dataStream, size);
		break;
	case MKTAG('R','G','B','S'):
		handleRGBS(dataStream, size);
		break;
	case MKTAG('S','N','D','E'):
		handleSNDE(dataStream, size);
		break;
	case MKTAG('T','O','I','L'):
		handleTOIL(dataStream, size);
		break;
	case MKTAG('S','R','L','E'):
		handleSRLE(dataStream, size);
		break;
	case MKTAG('B','L','O','K'):
		_dataSize -= size + 8;
		return false;
	case MKTAG('W','R','L','E'):
		// this is never triggered
	default:
		warning("Unhandled tag %s", tag2str(tag));
		break;
	}
	dataStream.seek(next);
	return true;
}
Exemple #25
0
void AVIDecoder::readOldIndex(uint32 size) {
	uint32 entryCount = size / 16;

	debug(7, "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(6, "Old index is %s", isAbsolute ? "absolute" : "relative");

	if (!isAbsolute)
		firstEntry.offset += _movieListStart - 4;

	debug(7, "Index 0: Tag '%s', Offset = %d, Size = %d (Flags = %d)", tag2str(firstEntry.id), firstEntry.offset, firstEntry.size, firstEntry.flags);
	_indexEntries.push_back(firstEntry);

	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(7, "Index %d: Tag '%s', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags);
	}
}
Exemple #26
0
int QuickTimeDecoder::readHDLR(MOVatom atom) {
    MOVStreamContext *st = _streams[_numStreams - 1];

    _fd->readByte(); // version
    _fd->readByte();
    _fd->readByte();
    _fd->readByte(); // flags

    // component type
    uint32 ctype = _fd->readUint32LE();
    uint32 type = _fd->readUint32BE(); // component subtype

    debug(0, "ctype= %s (0x%08lx)", tag2str(ctype), (long)ctype);
    debug(0, "stype= %s", tag2str(type));

    if(ctype == MKTAG('m','h','l','r')) // MOV
        debug(0, "MOV detected");
    else if(ctype == 0) {
        warning("MP4 streams are not supported");
        return -1;
    }

    if (type == MKTAG('v','i','d','e'))
        st->codec_type = CODEC_TYPE_VIDEO;
    else if (type == MKTAG('s','o','u','n'))
        st->codec_type = CODEC_TYPE_AUDIO;

    _fd->readUint32BE(); // component manufacture
    _fd->readUint32BE(); // component flags
    _fd->readUint32BE(); // component flags mask

    if (atom.size <= 24)
        return 0; // nothing left to read

    // .mov: PASCAL string
    byte len = _fd->readByte();
    _fd->seek(len, SEEK_CUR);

    _fd->seek(atom.size - (_fd->pos() - atom.offset), SEEK_CUR);

    return 0;
}
Exemple #27
0
int QuickTimeParser::readHDLR(Atom atom) {
	Track *track = _tracks.back();

	_fd->readByte(); // version
	_fd->readByte(); _fd->readByte(); _fd->readByte(); // flags

	// component type
	uint32 ctype = _fd->readUint32BE();
	uint32 type = _fd->readUint32BE(); // component subtype

	debug(0, "ctype= %s (0x%08lx)", tag2str(ctype), (long)ctype);
	debug(0, "stype= %s", tag2str(type));

	if (ctype == MKTAG('m', 'h', 'l', 'r')) // MOV
		debug(0, "MOV detected");
	else if (ctype == 0)
		debug(0, "MPEG-4 detected");

	if (type == MKTAG('v', 'i', 'd', 'e'))
		track->codecType = CODEC_TYPE_VIDEO;
	else if (type == MKTAG('s', 'o', 'u', 'n'))
		track->codecType = CODEC_TYPE_AUDIO;
	else if (type == MKTAG('m', 'u', 's', 'i'))
		track->codecType = CODEC_TYPE_MIDI;

	_fd->readUint32BE(); // component manufacture
	_fd->readUint32BE(); // component flags
	_fd->readUint32BE(); // component flags mask

	if (atom.size <= 24)
		return 0; // nothing left to read

	// .mov: PASCAL string
	byte len = _fd->readByte();
	_fd->seek(len, SEEK_CUR);

	_fd->seek(atom.size - (_fd->pos() - atom.offset), SEEK_CUR);

	return 0;
}
Exemple #28
0
void AviDecoder::handleList() {
	uint32 listSize = _fileStream->readUint32LE() - 4; // Subtract away listType's 4 bytes
	uint32 listType = _fileStream->readUint32BE();
	uint32 curPos = _fileStream->pos();

	debug (0, "Found LIST of type %s", tag2str(listType));

	while ((_fileStream->pos() - curPos) < listSize)
		runHandle(_fileStream->readUint32BE());

	// We now have all the header data
	if (listType == ID_HDRL)
		_decodedHeader = true;
}
Exemple #29
0
Common::QuickTimeParser::SampleDesc *QuickTimeAudioDecoder::readSampleDesc(Track *track, uint32 format) {
	if (track->codecType == CODEC_TYPE_AUDIO) {
		debug(0, "Audio Codec FourCC: \'%s\'", tag2str(format));

		AudioSampleDesc *entry = new AudioSampleDesc(track, format);

		uint16 stsdVersion = _fd->readUint16BE();
		_fd->readUint16BE(); // revision level
		_fd->readUint32BE(); // vendor

		entry->_channels = _fd->readUint16BE();			 // channel count
		entry->_bitsPerSample = _fd->readUint16BE();	  // sample size

		_fd->readUint16BE(); // compression id = 0
		_fd->readUint16BE(); // packet size = 0

		entry->_sampleRate = (_fd->readUint32BE() >> 16);

		debug(0, "stsd version =%d", stsdVersion);
		if (stsdVersion == 0) {
			// Not used, except in special cases. See below.
			entry->_samplesPerFrame = entry->_bytesPerFrame = 0;
		} else if (stsdVersion == 1) {
			// Read QT version 1 fields. In version 0 these dont exist.
			entry->_samplesPerFrame = _fd->readUint32BE();
			debug(0, "stsd samples_per_frame =%d",entry->_samplesPerFrame);
			_fd->readUint32BE(); // bytes per packet
			entry->_bytesPerFrame = _fd->readUint32BE();
			debug(0, "stsd bytes_per_frame =%d", entry->_bytesPerFrame);
			_fd->readUint32BE(); // bytes per sample
		} else {
			warning("Unsupported QuickTime STSD audio version %d", stsdVersion);
			delete entry;
			return 0;
		}

		// Version 0 videos (such as the Riven ones) don't have this set,
		// but we need it later on. Add it in here.
		if (format == MKTAG('i', 'm', 'a', '4')) {
			entry->_samplesPerFrame = 64;
			entry->_bytesPerFrame = 34 * entry->_channels;
		}

		if (entry->_sampleRate == 0 && track->timeScale > 1)
			entry->_sampleRate = track->timeScale;

		return entry;
	}
bool SaudChannel::handleSubTags(int32 &offset) {
	if (_tbufferSize - offset >= 8) {
		uint32 type = READ_BE_UINT32(_tbuffer + offset);
		uint32 size = READ_BE_UINT32(_tbuffer + offset + 4);
		uint32 available_size = _tbufferSize - offset;

		switch (type) {
		case MKID_BE('STRK'):
			_inData = false;
			if (available_size >= (size + 8)) {
				int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4);
				if (subSize != 14 && subSize != 10) {
					error("STRK has an invalid size : %d", subSize);
				}
			} else
				return false;
			break;
		case MKID_BE('SMRK'):
			_inData = false;
			if (available_size >= (size + 8))
				_markReached = true;
			else
				return false;
			break;
		case MKID_BE('SHDR'):
			_inData = false;
			if (available_size >= (size + 8)) {
				int32 subSize = READ_BE_UINT32((byte *)_tbuffer + offset + 4);
				if (subSize != 4)
					error("SHDR has an invalid size : %d", subSize);
			} else
				return false;
			break;
		case MKID_BE('SDAT'):
			_inData = true;
			_dataSize = size;
			offset += 8;
			return false;
		default:
			error("unknown Chunk in SAUD track : %s ", tag2str(type));
		}
		offset += size + 8;
		return true;
	}
	return false;
}