Esempio n. 1
0
Image* PVRTCDecoder::Decode(DataStream* ds) {
    PVRTexHeader header;
    if (!ds) return 0;
    if ( ds->Read((Byte*)&header, sizeof(header))!=sizeof(header) )
        return 0;
    if ( header.pvrTag[0] != gPVRTexIdentifier[0] ||
            header.pvrTag[1] != gPVRTexIdentifier[1] ||
            header.pvrTag[2] != gPVRTexIdentifier[2] ||
            header.pvrTag[3] != gPVRTexIdentifier[3] )
        return 0;
    /// @todo swap bytes ordering
    UInt32 formatFlags = SwapLittleToHost(header.flags) & PVR_TEXTURE_FLAG_TYPE_MASK;
    if ( formatFlags != kPVRTextureFlagTypePVRTC_2 &&
            formatFlags != kPVRTextureFlagTypePVRTC_4 ) {
        return 0;
    }
    //bool haveAlpha = SwapLittleToHost(header.bitmaskAlpha);
    UInt32 width = SwapLittleToHost(header.width);
    UInt32 height = SwapLittleToHost(header.height);
    UInt32 dataLength = SwapLittleToHost(header.dataLength);

    UInt32 blockSize = 0;
    UInt32 widthBlocks = 0;
    UInt32 heightBlocks = 0;
    UInt32 bpp = 0;
    ImageFormat format;
    if (formatFlags == kPVRTextureFlagTypePVRTC_4)
    {
        blockSize = 4 * 4; // Pixel by pixel block size for 4bpp
        widthBlocks = width / 4;
        heightBlocks = height / 4;
        bpp = 4;
        format = IMAGE_FORMAT_PVRTC_4;
    }
    else
    {
        blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
        widthBlocks = width / 8;
        heightBlocks = height / 4;
        bpp = 2;
        format = IMAGE_FORMAT_PVRTC_2;
    }

    // Clamp to minimum number of blocks
    if (widthBlocks < 2)
        widthBlocks = 2;
    if (heightBlocks < 2)
        heightBlocks = 2;

    UInt32 dataSize = widthBlocks * heightBlocks * ((blockSize  * bpp) / 8);
    if ( dataSize < dataLength ) return 0;
    DataImpl* buffer = new DataImpl( dataSize );
    if ( ds->Read(buffer->GetDataPtr(), dataSize )!=dataSize ) {
        buffer->Release();
        return 0;
    }
    return new ImageImpl(width,height,format,buffer);
}
Esempio n. 2
0
int32_t VMMemory::getScalar(RXEFile::dstocType type, const void *memoryLocation) const throw(std::invalid_argument)
{
	switch (type)
	{
			// Default
		case RXEFile::TC_UBYTE: return int32_t(SwapLittleToHost(reinterpret_cast<const uint8_t *>(memoryLocation)[0]));
		case RXEFile::TC_SBYTE: return int32_t(SwapLittleToHost(reinterpret_cast<const int8_t *>(memoryLocation)[0]));
		case RXEFile::TC_UWORD: return int32_t(SwapLittleToHost(reinterpret_cast<const uint16_t *>(memoryLocation)[0]));
		case RXEFile::TC_SWORD: return int32_t(SwapLittleToHost(reinterpret_cast<const int16_t *>(memoryLocation)[0]));
		case RXEFile::TC_ULONG: return int32_t(SwapLittleToHost(reinterpret_cast<const uint32_t *>(memoryLocation)[0]));
		case RXEFile::TC_SLONG: return int32_t(SwapLittleToHost(reinterpret_cast<const int32_t *>(memoryLocation)[0]));
			// Special cases
			
			// The field for an array contains an uint16_t which is the number of the dope vector.
		case RXEFile::TC_ARRAY: return int32_t(SwapLittleToHost(reinterpret_cast<const uint16_t *> (memoryLocation)[0]));
			
			// A mutex is a 32-bit value. What it contains is not fully clear.
		case RXEFile::TC_MUTEX: return int32_t(SwapLittleToHost(reinterpret_cast<const uint32_t *> (memoryLocation)[0]));
			
			// Extremely sketchy support for floats.
		case RXEFile::TC_FLOAT: return int32_t(SwapLittleToHost(reinterpret_cast<const float *> (memoryLocation)[0]));
			
			// We do NOT like clusters and voids
		default: throw std::invalid_argument("Invalid DSTOC type used for get");
	}
}
Esempio n. 3
0
SoundBuffer::SoundBuffer(const char *filename) throw(std::runtime_error)
{
	std::ifstream file(filename, std::ios::binary);
	if (!file) throw std::runtime_error("Could not open sound file!");
		
	char actualGroupID[4];
	file.read(actualGroupID, 4);
	if (memcmp(actualGroupID, "RIFF", 4) != 0) throw std::runtime_error("Not a WAV file.");
	
	// File length minus eight. Ignored here.
	uint32_t fileLength;
	file.read(reinterpret_cast<char *> (&fileLength), 4);
    fileLength = SwapLittleToHost(fileLength);
	
	char actualRiffType[4];
	file.read(actualRiffType, 4);
	if (memcmp(actualRiffType, "WAVE", 4) != 0) throw std::runtime_error("Not a WAV file.");
	
	// Information about the file
	bool haveFmt = false;
	bool haveData = false;
	
	uint32_t dataLength;
	uint16_t numChannels;
	uint32_t samplesPerSecond;
	uint16_t bitsPerSample;
	char *data = NULL;
	
	// Scan chunks
	while (file.good() && !(haveFmt && haveData))
	{
		char chunkType[4];
		file.read(chunkType, 4);
		
		if (memcmp(chunkType, "fmt ", 4) == 0)
		{
			// Read Format header
			if (haveFmt) throw std::runtime_error("Format data specified more than once.");
			haveFmt = true;
			
			uint32_t chunkLength;
			file.read(reinterpret_cast<char *> (&chunkLength), 4);
            chunkLength = SwapLittleToHost(chunkLength);
			if (chunkLength != 16) throw std::runtime_error("Sound file format not supported.");
			
			uint16_t format;
			file.read(reinterpret_cast<char *> (&format), 2);
            format = SwapLittleToHost(format);
			if (format != 0x0001) throw std::runtime_error("Format is not PCM.");
			
			file.read(reinterpret_cast<char *> (&numChannels), 2);
            numChannels = SwapLittleToHost(numChannels);
			if (numChannels > 2) throw std::runtime_error("More than two channels.");
			
			file.read(reinterpret_cast<char *> (&samplesPerSecond), 4);
            samplesPerSecond = SwapLittleToHost(samplesPerSecond);
			
			// Bytes per second and block align.
			file.seekg(6, std::ios::cur);
			
			file.read(reinterpret_cast<char *> (&bitsPerSample), 2);
            bitsPerSample = SwapLittleToHost(bitsPerSample);
			if (bitsPerSample != 8 && bitsPerSample != 16) throw std::runtime_error("Bits per sample has unusual value.");
		}
		else if (memcmp(chunkType, "data", 4) == 0)
		{
			// Read actual data
			if (haveData) throw std::runtime_error("Sound data specified more than once.");
			haveData = true;
			
			file.read(reinterpret_cast<char *> (&dataLength), 4);
            dataLength = SwapLittleToHost(dataLength);
			data = new char [dataLength];
			file.read(data, dataLength);
		}
		else
		{
			// Skip unknown chunk
			uint32_t chunkLength;
			file.read(reinterpret_cast<char *> (&chunkLength), 4);
			chunkLength += chunkLength % 2; // RIFF-Files are word aligned
			file.seekg(chunkLength, std::ios::cur);
		}
	}
    
    if (bitsPerSample == 16)
        SwapU16LittleToHost(reinterpret_cast<uint16_t *>(data), dataLength/sizeof(uint16_t));
	
	initWithData(data, dataLength, samplesPerSecond, bitsPerSample == 16, numChannels == 2);
	
	delete [] data;
}