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; } }
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(); } }
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 ); }