예제 #1
0
BufferRef loadStreamBuffer( IStreamRef is )
{
	// prevent crash if stream is not valid
	if( ! is )
		throw StreamExc();

	off_t fileSize = is->size();
	if( fileSize > std::numeric_limits<off_t>::max() )
		throw StreamExcOutOfMemory();
	
	if( fileSize ) { // sometimes fileSize will be zero for a stream that doesn't know how big it is
		auto result = std::make_shared<Buffer>( fileSize );
		is->readDataAvailable( result->getData(), fileSize );

		return result;
	}
	else {
		const size_t bufferSize = 4096;
		size_t offset = 0;
		auto result = std::make_shared<Buffer>( bufferSize );

		while( ! is->isEof() ) {
			if( offset + bufferSize > result->getAllocatedSize() )
				result->resize( std::max( (size_t)( result->getAllocatedSize() * 1.5f ), offset + bufferSize ) );

			size_t bytesRead = is->readDataAvailable( reinterpret_cast<uint8_t*>( result->getData() ) + offset, bufferSize );
			offset += bytesRead;
			result->setSize( offset );
		}

		return result;
	}
}
예제 #2
0
void readStreamWithEndianess( IStreamRef aIStream, T* param, bool isBigEndian )
{
	if( isBigEndian ) {
		aIStream->readBig( param );
		return;
	}
	aIStream->readLittle( param );
}
void ImageSourceFileRadiance::loadStream( IStreamRef stream )
{
	setDataType( ImageIo::FLOAT32 );
	setColorModel( ImageIo::CM_RGB );
	setChannelOrder( ImageIo::RGB );

	char str[200];
	stream->readData( str, 10 );
	if( memcmp( str, "#?RADIANCE", 10 ) )
		throw ImageSourceFileRadianceException( "Invalid header" );

	stream->seekRelative( 1 );

	char cmd[200];
	int i = 0;
	char c = 0, oldc;
	while( true ) {
		oldc = c;
		stream->read( &c );
		if( c == 0xa && oldc == 0xa )
			break;
		cmd[i++] = c;
	}

	char resolution[200];
	i = 0;
	while( true ) {
		stream->read( &c );
		resolution[i++] = c;
		if( c == 0xa )
			break;
	}

	int width, height;
#if defined( CINDER_WINRT )
	if( ! sscanf_s( resolution, "-Y %d +X %d", &height, &width ) )
#else
	if( ! sscanf( resolution, "-Y %d +X %d", &height, &width ) )
#endif
		throw ImageSourceFileRadianceException( "Unable to parse size" );
	setSize( width, height );

	mRgbData = std::unique_ptr<float[]>( new float[width * height * 3] );
	std::unique_ptr<RgbePixel[]> scanline( new RgbePixel[width] );

	// convert image
	float *cols = mRgbData.get();
	for( int y = height - 1; y >= 0; y-- ) {
		if( ! decrunchScanline( scanline.get(), width, stream.get() ) )
			break;
		workOnRgbeScanline( scanline.get(), width, cols );
		cols += width * 3;
	}
}
예제 #4
0
void loadStreamMemory( IStreamRef is, std::shared_ptr<uint8_t> *resultData, size_t *resultDataSize )
{
	// prevent crash if stream is not valid
	if( ! is )
		throw StreamExc();

	off_t fileSize = is->size();
	if( fileSize > std::numeric_limits<off_t>::max() )
		throw StreamExcOutOfMemory();
	
	*resultData = std::shared_ptr<uint8_t>( (uint8_t*)malloc( fileSize ), free );
	if( ! (*resultData ) )
		throw StreamExcOutOfMemory();

	*resultDataSize = static_cast<size_t>( fileSize );
	is->readDataAvailable( resultData->get(), fileSize );
}
예제 #5
0
void TriMesh::read( DataSourceRef dataSource )
{
	IStreamRef in = dataSource->createStream();
	clear();

	uint8_t versionNumber;
	in->read( &versionNumber );
	
	uint32_t numVertices, numNormals, numTexCoords, numIndices;
	in->readLittle( &numVertices );
	in->readLittle( &numNormals );
	in->readLittle( &numTexCoords );
	in->readLittle( &numIndices );
	
	for( size_t idx = 0; idx < numVertices; ++idx ) {
		Vec3f v;
		in->readLittle( &v.x ); in->readLittle( &v.y ); in->readLittle( &v.z );
		mVertices.push_back( v );
	}

	for( size_t idx = 0; idx < numNormals; ++idx ) {
		Vec3f v;
		in->readLittle( &v.x ); in->readLittle( &v.y ); in->readLittle( &v.z );
		mNormals.push_back( v );
	}

	for( size_t idx = 0; idx < numTexCoords; ++idx ) {
		Vec2f v;
		in->readLittle( &v.x ); in->readLittle( &v.y );
		mTexCoords.push_back( v );
	}

	for( size_t idx = 0; idx < numIndices; ++idx ) {
		uint32_t v;
		in->readLittle( &v );
		mIndices.push_back( v );
	}
}
예제 #6
0
Texture Texture::loadDds( IStreamRef ddsStream, Format format )
{
	typedef struct { // DDCOLORKEY
		uint32_t dw1;
		uint32_t dw2;
	} ddColorKey;

	typedef struct  { // DDSCAPS2
		uint32_t dwCaps1;
		uint32_t dwCaps2;
		uint32_t Reserved[2];
	} ddCaps2;

	typedef struct _DDPIXELFORMAT { // DDPIXELFORMAT
		uint32_t  dwSize;
		uint32_t  dwFlags;
		uint32_t  dwFourCC;
		union {
			uint32_t  dwRGBBitCount;
			uint32_t  dwYUVBitCount;
			uint32_t  dwZBufferBitDepth;
			uint32_t  dwAlphaBitDepth;
			uint32_t  dwLuminanceBitCount;
			uint32_t  dwBumpBitCount;
			uint32_t  dwPrivateFormatBitCount;
		} ;
		union {
			uint32_t  dwRBitMask;
			uint32_t  dwYBitMask;
			uint32_t  dwStencilBitDepth;
			uint32_t  dwLuminanceBitMask;
			uint32_t  dwBumpDuBitMask;
			uint32_t  dwOperations;
		} ;
		union {
			uint32_t  dwGBitMask;
			uint32_t  dwUBitMask;
			uint32_t  dwZBitMask;
			uint32_t  dwBumpDvBitMask;
			struct {
				int32_t wFlipMSTypes;
				int32_t wBltMSTypes;
			} MultiSampleCaps;
		};
		union {
			uint32_t  dwBBitMask;
			uint32_t  dwVBitMask;
			uint32_t  dwStencilBitMask;
			uint32_t  dwBumpLuminanceBitMask;
		};
		union {
			uint32_t  dwRGBAlphaBitMask;
			uint32_t  dwYUVAlphaBitMask;
			uint32_t  dwLuminanceAlphaBitMask;
			uint32_t  dwRGBZBitMask;
			uint32_t  dwYUVZBitMask;
		} ;
	} ddPixelFormat;

	typedef struct ddSurface // this is lifted and adapted from DDSURFACEDESC2
	{
		uint32_t               dwSize;                 // size of the DDSURFACEDESC structure
		uint32_t               dwFlags;                // determines what fields are valid
		uint32_t               dwHeight;               // height of surface to be created
		uint32_t               dwWidth;                // width of input surface
		union
		{
			int32_t            lPitch;                 // distance to start of next line (return value only)
			uint32_t           dwLinearSize;           // Formless late-allocated optimized surface size
		};
		union
		{
			uint32_t           dwBackBufferCount;      // number of back buffers requested
			uint32_t           dwDepth;                // the depth if this is a volume texture 
		};
		union
		{
			uint32_t			dwMipMapCount;          // number of mip-map levels requestde
													// dwZBufferBitDepth removed, use ddpfPixelFormat one instead
			uint32_t			dwRefreshRate;          // refresh rate (used when display mode is described)
			uint32_t			dwSrcVBHandle;          // The source used in VB::Optimize
		};
		uint32_t				dwAlphaBitDepth;        // depth of alpha buffer requested
		uint32_t				dwReserved;             // reserved
		uint32_t				lpSurface;              // pointer to the associated surface memory
		union
		{
			ddColorKey			ddckCKDestOverlay;      // color key for destination overlay use
			uint32_t			dwEmptyFaceColor;       // Physical color for empty cubemap faces
		};
		ddColorKey          ddckCKDestBlt;          // color key for destination blt use
		ddColorKey          ddckCKSrcOverlay;       // color key for source overlay use
		ddColorKey          ddckCKSrcBlt;           // color key for source blt use
		union
		{
			ddPixelFormat		ddpfPixelFormat;        // pixel format description of the surface
			uint32_t			dwFVF;                  // vertex format description of vertex buffers
		};
		ddCaps2			ddsCaps;                // direct draw surface capabilities
		uint32_t		dwTextureStage;         // stage in multitexture cascade
	} ddSurface;
	
	enum { FOURCC_DXT1 = 0x31545844, FOURCC_DXT3 = 0x33545844, FOURCC_DXT5 = 0x35545844 };

	try {
		ddSurface ddsd;
		char filecode[4];
		ddsStream->readData( filecode, 4 );
		if( strncmp( filecode, "DDS ", 4 ) != 0 ) { 
			return Texture();
		}

		ddsStream->readData( &ddsd, 124/*sizeof(ddsd)*/ );

		// how big is it going to be including all mipmaps?
		uint32_t bufSize = ( ddsd.dwMipMapCount > 1 ) ? ( ddsd.dwLinearSize * 2 ) : ( ddsd.dwLinearSize ); 
		shared_ptr<uint8_t> pixels( new uint8_t[bufSize+1], checked_array_deleter<uint8_t>() );
		ddsStream->readData( pixels.get(), bufSize ); 

		uint32_t width = ddsd.dwWidth; 
		uint32_t height = ddsd.dwHeight; 
		//int numComponents  = (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1) ? 3 : 4; 
		int numMipMaps = ddsd.dwMipMapCount;
		int dataFormat;
		switch( ddsd.ddpfPixelFormat.dwFourCC ) { 
			case FOURCC_DXT1: 
				dataFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; 
			break; 
			case FOURCC_DXT3: 
				dataFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; 
			break; 
			case FOURCC_DXT5: 
				dataFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 
			break; 
			default: 
				return Texture();
			break;
		} 

		off_t offset   = 0; 
		uint32_t blockSize = ( dataFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16; 

		// Create the texture
		GLenum target = format.mTarget;
		GLuint texID;
		glGenTextures( 1, &texID );
		
		Texture result( target, texID, width, height, false );
		result.mObj->mWidth = width;
		result.mObj->mHeight = height;
		result.mObj->mInternalFormat = dataFormat;

		glBindTexture( result.mObj->mTarget, result.mObj->mTextureID );
		glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

		// load the mipmaps
		for( int i = 0; i <= numMipMaps && (width || height); ++i ) { 
			if( width == 0 ) 
				width = 1;
			if( height == 0 ) 
				height = 1; 

			int size = ( (width+3) / 4 ) * ( (height+3) / 4 ) * blockSize; 
			glCompressedTexImage2D( result.mObj->mTarget, i, dataFormat, width, height, 0, size, pixels.get() + offset );
			 
			offset += size; 
			width  >>= 1; 
			height >>= 1; 
		}

		if( numMipMaps > 1 ) {
			glTexParameteri( result.mObj->mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );	
			glTexParameteri( result.mObj->mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );			
		}
		else {
			glTexParameteri( result.mObj->mTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR );	
			glTexParameteri( result.mObj->mTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR );	
		}
		
		return result;
	}
	catch( ... ) {
		return Texture();
	}
}
예제 #7
0
SourceFileWav::SourceFileWav( DataSourceRef dataSourceRef )
	: Source(), mDataSource( dataSourceRef )
{
	mDataType = DATA_UNKNOWN;
	mSampleRate = 0;
	mChannelCount = 0;
	mBitsPerSample = 0;
	mBlockAlign = 0;
	mIsPcm = FALSE;
	mIsBigEndian = FALSE;
	mIsInterleaved = FALSE;
	
	IStreamRef stream = mDataSource->createStream();

	uint32_t fileSize = 0;
	
	uint32_t chunkName = 0;
	uint32_t chunkSize = 0;
	
	uint32_t riffType = 0;
	
	stream->readData( &chunkName, 4 );
	if( chunkName == gRiffMarker ) {
		mIsBigEndian = false;
	} else if( chunkName == gRifxMarker ) {
		mIsBigEndian = true;
	} else {
		throw IoExceptionFailedLoad();
	}
	
	readStreamWithEndianess( stream, &fileSize, mIsBigEndian );
	fileSize = fileSize + 4 + sizeof( int );
	
	stream->readData( &riffType, 4 );
	if( riffType != gWaveMarker ) {
		throw IoExceptionFailedLoad();
	}
	
	
	uint32_t chunkEnd = 0;
	uint32_t chunks = 0;
	static const uint8_t hasFormat = 1;
	static const uint8_t hasData = 1 << 1;
	
	while( stream->tell() < fileSize) {
		stream->readData( &chunkName, 4 );
		readStreamWithEndianess( stream, &chunkSize, mIsBigEndian );
		chunkEnd = stream->tell() + chunkSize;
		
		if( chunkName == gFmtMarker ) {
			readFormatChunk( stream );
			chunks |= hasFormat;
		} else if( chunkName == gDataMarker ) {
			mDataLength = chunkSize;
			mDataStart = stream->tell();
			chunks |= hasData;
		}
		stream->seekAbsolute( chunkEnd );
	}
	
	if( chunks != ( hasFormat | hasData ) ) {
		throw IoExceptionFailedLoad();
	}

	mSampleCount = mDataLength / mBlockAlign;
	
	//Pull all of the data
	//mData = (int16_t *)calloc( 1, mDataLength );
	//stream->seekSet( mDataStart );
	//stream->readData( mData, mDataLength );


}