示例#1
0
void ImageTargetFileWic::finalize()
{
	::HRESULT hr = S_OK;
	
	hr = mBitmapFrame->WritePixels( mHeight, mRowBytes, mHeight * mRowBytes, mData.get() );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();

	hr = mBitmapFrame->Commit();
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();

	hr = mEncoder->Commit();
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();		
}
示例#2
0
ImageSourceRef ImageIoRegistrar::Inst::createSource( DataSourceRef dataSource, ImageSource::Options options, string extension )
{
	std::transform( extension.begin(), extension.end(), extension.begin(), static_cast<int(*)(int)>( tolower ) );

	// for non-empty extensions we'll walk everyone who is registered for this extension
	if( ! extension.empty() ) {
		map<string,multimap<int32_t,ImageIoRegistrar::SourceCreationFunc> >::iterator sIt = mSources.find( extension );
		if( sIt != mSources.end() ) {
			for( multimap<int32_t,ImageIoRegistrar::SourceCreationFunc>::const_iterator sourcesIt = sIt->second.begin(); sourcesIt != sIt->second.end(); ++sourcesIt ) {
				try {
					return (*(sourcesIt->second))( dataSource, options );
				}
				catch( ... ) { // we'll ignore exceptions and move to the next handler
				}
			}
		}
	}

	// if there is no extension, or none of the registered types got it, we'll have try the generic loaders	
	for( map<int32_t, ImageIoRegistrar::SourceCreationFunc>::const_iterator genericIt = mGenericSources.begin(); genericIt != mGenericSources.end(); ++genericIt ) {
		try {
			return (*(genericIt->second))( dataSource, options );
		}
		catch( ... ) { // we'll ignore exceptions and move to the next handler
		}
	}
	
	// failure
	throw ImageIoExceptionFailedLoad();
}
示例#3
0
///////////////////////////////////////////////////////////////////////////////
// ImageSourceFileQuartz
ImageSourceFileQuartzRef ImageSourceFileQuartz::createFileQuartzRef( DataSourceRef dataSourceRef, ImageSource::Options options )
{
	std::shared_ptr<CGImageSource> sourceRef;
	std::shared_ptr<CGImage> imageRef;
	
	::CFStringRef keys[1] = { kCGImageSourceShouldAllowFloat };
	::CFBooleanRef values[1] = { kCFBooleanTrue };
	const std::shared_ptr<__CFDictionary> optionsDict( (__CFDictionary*)CFDictionaryCreate( kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 1, NULL, NULL ), cocoa::safeCfRelease );

	if( dataSourceRef->isFilePath() ) {
		::CFStringRef pathString = cocoa::createCfString( dataSourceRef->getFilePath().string() );
		::CFURLRef urlRef = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, pathString, kCFURLPOSIXPathStyle, false );
		sourceRef = std::shared_ptr<CGImageSource>( ::CGImageSourceCreateWithURL( urlRef, optionsDict.get() ), cocoa::safeCfRelease );
		::CFRelease( pathString );
		::CFRelease( urlRef );
	}
	else if( dataSourceRef->isUrl() ) {
		::CFURLRef urlRef = cocoa::createCfUrl( dataSourceRef->getUrl() );
		if( ! urlRef )
			throw ImageIoExceptionFailedLoad();
		sourceRef = std::shared_ptr<CGImageSource>( ::CGImageSourceCreateWithURL( urlRef, optionsDict.get() ), cocoa::safeCfRelease );
		::CFRelease( urlRef );		
	}
	else { // last ditch, we'll use a dataref from the buffer
		::CFDataRef dataRef = cocoa::createCfDataRef( dataSourceRef->getBuffer() );
		if( ! dataRef )
			throw ImageIoExceptionFailedLoad();
		
		sourceRef = std::shared_ptr<CGImageSource>( ::CGImageSourceCreateWithData( dataRef, optionsDict.get() ), cocoa::safeCfRelease );
		::CFRelease( dataRef );
	}
	
	if( sourceRef ) {
		imageRef = std::shared_ptr<CGImage>( ::CGImageSourceCreateImageAtIndex( sourceRef.get(), options.getIndex(), optionsDict.get() ), CGImageRelease );
		if( ! imageRef )
			throw ImageIoExceptionFailedLoad();
	}
	else
		throw ImageIoExceptionFailedLoad();

	const std::shared_ptr<__CFDictionary> imageProperties( (__CFDictionary*)::CGImageSourceCopyProperties( sourceRef.get(), NULL ), ::CFRelease );
	const std::shared_ptr<__CFDictionary> imageIndexProperties( (__CFDictionary*)::CGImageSourceCopyPropertiesAtIndex( sourceRef.get(), options.getIndex(), NULL ), ::CFRelease );

	return ImageSourceFileQuartzRef( new ImageSourceFileQuartz( imageRef.get(), options, imageProperties, imageIndexProperties ) );
}
示例#4
0
///////////////////////////////////////////////////////////////////////////////
// ImageSourceFileQuartz
ImageSourceFileQuartzRef ImageSourceFileQuartz::createFileQuartzRef( DataSourceRef dataSourceRef )
{
	::CGImageSourceRef sourceRef = NULL;
	::CGImageRef imageRef = NULL;
	
	::CFStringRef keys[1] = { kCGImageSourceShouldAllowFloat };
	::CFBooleanRef values[1] = { kCFBooleanTrue };
	::CFDictionaryRef optionsDict = ::CFDictionaryCreate( kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 1, NULL, NULL );

	if( dataSourceRef->isFilePath() ) {
		::CFStringRef pathString = cocoa::createCfString( dataSourceRef->getFilePath() );
		::CFURLRef urlRef = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, pathString, kCFURLPOSIXPathStyle, false );
		sourceRef = ::CGImageSourceCreateWithURL( urlRef, optionsDict );
		::CFRelease( pathString );
		::CFRelease( urlRef );
	}
	else if( dataSourceRef->isUrl() ) {
		::CFURLRef urlRef = cocoa::createCfUrl( dataSourceRef->getUrl() );
		if( ! urlRef )
			throw ImageIoExceptionFailedLoad();
		sourceRef = ::CGImageSourceCreateWithURL( urlRef, optionsDict );
		::CFRelease( urlRef );		
	}
	else { // last ditch, we'll use a dataref from the buffer
		::CFDataRef dataRef = cocoa::createCfDataRef( dataSourceRef->getBuffer() );
		if( ! dataRef )
			throw ImageIoExceptionFailedLoad();
		
		sourceRef = ::CGImageSourceCreateWithData( dataRef, optionsDict );
		::CFRelease( dataRef );
	}
	
	if( sourceRef ) {
		imageRef = ::CGImageSourceCreateImageAtIndex( sourceRef, 0, optionsDict );
		::CFRelease( sourceRef );
		if( ! imageRef )
			throw ImageIoExceptionFailedLoad();
	}
	else
		throw ImageIoExceptionFailedLoad();

	return ImageSourceFileQuartzRef( new ImageSourceFileQuartz( imageRef ) );
}
示例#5
0
ImageTargetFileWic::ImageTargetFileWic( DataTargetRef dataTarget, ImageSourceRef imageSource, const string &extensionData )
	: ImageTarget(), mDataTarget( dataTarget )
{
	mCodecGUID = getExtensionMap()[extensionData];

	setSize( imageSource->getWidth(), imageSource->getHeight() );

	// determine the pixel format we'll request
	WICPixelFormatGUID formatGUID;
	if( imageSource->hasAlpha() ) {
		bool premultAlpha = imageSource->isPremultiplied();
		// WIC doesn't support gray+alpha, so we need to do RGBA regardless
		if( imageSource->getDataType() == ImageIo::UINT8 )
			formatGUID = premultAlpha ? GUID_WICPixelFormat32bppPBGRA : GUID_WICPixelFormat32bppBGRA;
		else if( imageSource->getDataType() == ImageIo::UINT16 )
			formatGUID = premultAlpha ? GUID_WICPixelFormat64bppPRGBA : GUID_WICPixelFormat64bppRGBA;
		else
			formatGUID = premultAlpha ? GUID_WICPixelFormat128bppPRGBAFloat : GUID_WICPixelFormat128bppRGBAFloat;
	}
	else {
		if( imageSource->getColorModel() == ImageIo::CM_GRAY ) {
			if( imageSource->getDataType() == ImageIo::UINT8 )
				formatGUID = GUID_WICPixelFormat8bppGray;
			else if( imageSource->getDataType() == ImageIo::UINT16 )
				formatGUID = GUID_WICPixelFormat16bppGray;
			else
				formatGUID = GUID_WICPixelFormat32bppGrayFloat;
		}
		else {
			if( imageSource->getDataType() == ImageIo::UINT8 )
				formatGUID = GUID_WICPixelFormat24bppBGR;
			else if( imageSource->getDataType() == ImageIo::UINT16 )
				formatGUID = GUID_WICPixelFormat48bppRGB;
			else
				formatGUID = GUID_WICPixelFormat128bppRGBFloat;
		}
	}
	
	::HRESULT hr = S_OK;

	msw::initializeCom();

 // Create WIC factory
    IWICImagingFactory *IWICFactoryP = NULL;
    hr = ::CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&IWICFactoryP) );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();
	shared_ptr<IWICImagingFactory> IWICFactory = msw::makeComShared( IWICFactoryP );

	IWICBitmapEncoder *encoderP = NULL;
	hr = IWICFactory->CreateEncoder( *mCodecGUID, 0, &encoderP );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();
	mEncoder = msw::makeComShared( encoderP );
	
	// create the stream		
	IWICStream *pIWICStream = NULL;
	hr = IWICFactory->CreateStream( &pIWICStream );
	if( ! SUCCEEDED(hr) )
		throw ImageIoExceptionFailedLoad();
	shared_ptr<IWICStream> stream = msw::makeComShared( pIWICStream );
	
	// initialize the stream based on properties of the cinder::DataSouce
	if( mDataTarget->providesFilePath() ) {
		hr = stream->InitializeFromFilename( toUtf16( mDataTarget->getFilePath() ).c_str(), GENERIC_WRITE );
		if( ! SUCCEEDED(hr) )
			throw ImageIoExceptionFailedLoad();
	}
	else {
		shared_ptr<msw::ComOStream> comOStream = msw::makeComShared( new msw::ComOStream( mDataTarget->getStream() ) );
		hr = stream->InitializeFromIStream( comOStream.get() );
		if( ! SUCCEEDED(hr) )
			throw ImageIoExceptionFailedLoad();		
	}
	
	hr = mEncoder->Initialize( stream.get(), WICBitmapEncoderNoCache );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();

	// create the frame encoder
	IPropertyBag2 *pPropertybag = NULL;
	IWICBitmapFrameEncode *pBitmapFrame = NULL;
	hr = mEncoder->CreateNewFrame( &pBitmapFrame, &pPropertybag );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();
	mBitmapFrame = msw::makeComShared( pBitmapFrame );

	hr = mBitmapFrame->Initialize( 0 );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();	
	
	hr = mBitmapFrame->SetSize( mWidth, mHeight );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();
	
	// ask for our ideal pixel format and then process the one we actually get
	hr = mBitmapFrame->SetPixelFormat( &formatGUID );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();
	
	setupPixelFormat( formatGUID );
	
	mData = shared_ptr<uint8_t>( new uint8_t[mHeight * mRowBytes], boost::checked_array_delete<uint8_t> );
}
示例#6
0
void ImageTargetFileWic::setupPixelFormat( const GUID &guid )
{
	if( guid == GUID_WICPixelFormat24bppBGR ) {		
		setChannelOrder( ImageIo::BGR ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat24bppRGB ) {
		setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat32bppBGR ) {
		setChannelOrder( ImageIo::BGRX ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat32bppBGRA ) {
		setChannelOrder( ImageIo::BGRA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat32bppPBGRA ) {
		setChannelOrder( ImageIo::BGRA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT8 );// mIsPremultipliedAlpha = true;
	}
	else if( guid == GUID_WICPixelFormat48bppRGB ) {
		setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 );
	}
	else if( guid == GUID_WICPixelFormat64bppRGBA ) {
		setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 );
	}
	else if( guid == GUID_WICPixelFormat64bppPRGBA ) {
		setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::UINT16 ); // mIsPremultipliedAlpha = true;
	}
	else if( guid == GUID_WICPixelFormat128bppRGBFloat ) {
		setChannelOrder( ImageIo::RGB ); setColorModel( ImageIo::CM_RGB ); setDataType( ImageIo::FLOAT32 );
	}
	else if( guid == GUID_WICPixelFormat8bppGray ) {
		setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::UINT8 );
	}
	else if( guid == GUID_WICPixelFormat16bppGray ) {
		setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::UINT16 );
	}
	else if( guid == GUID_WICPixelFormat32bppGrayFloat ) {
		setChannelOrder( ImageIo::Y ); setColorModel( ImageIo::CM_GRAY ); setDataType( ImageIo::FLOAT32 );
	}
	else
		throw ImageIoExceptionFailedLoad();
	
	int32_t bitsPerComponent;
	bool writingAlpha = hasAlpha();
	bool isFloat = true;
	switch( getDataType() ) {
		case ImageIo::UINT8: bitsPerComponent = 8; isFloat = false; break;
		case ImageIo::UINT16: bitsPerComponent = 16; isFloat = false; break;
		default: bitsPerComponent = 32; isFloat = true;
	}
	uint8_t numChannels;
	switch( getColorModel() ) {
		case ImageIo::CM_GRAY:
			numChannels = ( writingAlpha ) ? 2 : 1; break;
		default:
			numChannels = ( writingAlpha ) ? 4 : 3;
	}
	int32_t bitsPerPixel = numChannels * bitsPerComponent;
	mRowBytes = ( mWidth * ( bitsPerPixel / 8 ) + 3 ) & ~3;

	return;
}
示例#7
0
ImageSourceFileWic::ImageSourceFileWic( DataSourceRef dataSourceRef, ImageSource::Options options )
	: ImageSource()
{
	::HRESULT hr = S_OK;

	// Initialize COM
	msw::initializeCom();
	
    // Create WIC factory
    IWICImagingFactory *IWICFactoryP = NULL;
    hr = ::CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&IWICFactoryP) );
	if( ! SUCCEEDED( hr ) )
		throw ImageIoExceptionFailedLoad();
	std::shared_ptr<IWICImagingFactory> IWICFactory = msw::makeComShared( IWICFactoryP );
	
    // Create a decoder
	IWICBitmapDecoder *decoderP = NULL;
	if( dataSourceRef->isFilePath() ) {
		hr = IWICFactory->CreateDecoderFromFilename(
				toUtf16( dataSourceRef->getFilePath().string() ).c_str(),                      // Image to be decoded
				NULL,                            // Do not prefer a particular vendor
				GENERIC_READ,                    // Desired read access to the file
				WICDecodeMetadataCacheOnDemand,  // Cache metadata when needed
				&decoderP                        // Pointer to the decoder
			);
		if( ! SUCCEEDED(hr) )
			throw ImageIoExceptionFailedLoad();
	}
	else { // have to use a buffer
		IWICStream *pIWICStream = NULL;
		hr = IWICFactory->CreateStream( &pIWICStream );
		if( ! SUCCEEDED(hr) )
			throw ImageIoExceptionFailedLoad();
		std::shared_ptr<IWICStream> stream = msw::makeComShared( pIWICStream );
		
		Buffer buffer = dataSourceRef->getBuffer();
		hr = stream->InitializeFromMemory( reinterpret_cast<BYTE*>( buffer.getData() ), buffer.getDataSize() );
		if( ! SUCCEEDED(hr) )
			throw ImageIoExceptionFailedLoad();
		
		hr = IWICFactory->CreateDecoderFromStream( stream.get(), NULL, WICDecodeMetadataCacheOnDemand, &decoderP );
		if( ! SUCCEEDED(hr) )
			throw ImageIoExceptionFailedLoad();
	}
	std::shared_ptr<IWICBitmapDecoder> decoder = msw::makeComShared( decoderP );

    // Retrieve the 'index' frame of the image from the decoder
	IWICBitmapFrameDecode *frameP = NULL;
	hr = decoder->GetFrame( options.getIndex(), &frameP );
	if( ! SUCCEEDED(hr) )
		throw ImageIoExceptionFailedLoad();
	std::shared_ptr<IWICBitmapFrameDecode> frame = msw::makeComShared( frameP );

	UINT width = 0, height = 0;
	frame->GetSize( &width, &height );
	mWidth = width; mHeight = height;
	
	GUID pixelFormat = { 0 }, convertPixelFormat;
	frame->GetPixelFormat( &pixelFormat );
	
	bool requiresConversion = processFormat( pixelFormat, &convertPixelFormat );
	mRowBytes = mWidth * ImageIo::dataTypeBytes( mDataType ) * channelOrderNumChannels( mChannelOrder );

	mData = std::shared_ptr<uint8_t>( new uint8_t[mRowBytes * mHeight], boost::checked_array_delete<uint8_t> );

	if( requiresConversion ) {
		IWICFormatConverter *pIFormatConverter = NULL;	
		hr = IWICFactory->CreateFormatConverter( &pIFormatConverter );
		if( ! SUCCEEDED( hr ) )
			throw ImageIoExceptionFailedLoad();
		std::shared_ptr<IWICFormatConverter> formatConverter = msw::makeComShared( pIFormatConverter );
		hr = formatConverter->Initialize( frame.get(), convertPixelFormat, WICBitmapDitherTypeNone,
					NULL, 0.f, WICBitmapPaletteTypeCustom );
		if( ! SUCCEEDED( hr ) )
			throw ImageIoExceptionFailedLoad();
		hr = formatConverter->CopyPixels( NULL, (UINT)mRowBytes, mRowBytes * mHeight, mData.get() );
	}
	else
		hr = frame->CopyPixels( NULL, (UINT)mRowBytes, mRowBytes * mHeight, mData.get() );
}