ImageTargetGWorld::ImageTargetGWorld( ImageSourceRef imageSource ) : ImageTarget(), mGWorld( 0 ), mPixMap( 0 ) { setSize( (size_t)imageSource->getWidth(), (size_t)imageSource->getHeight() ); OSType formatType; // for now all we support is 8 bit RGBA setDataType( ImageIo::UINT8 ); formatType = k32ARGBPixelFormat; setChannelOrder( ImageIo::ARGB ); setColorModel( ImageIo::CM_RGB ); ::Rect boundsRect; boundsRect.left = boundsRect.top = 0; boundsRect.right = (short)imageSource->getWidth(); boundsRect.bottom = (short)imageSource->getHeight(); if( ::QTNewGWorld( &mGWorld, formatType, &boundsRect, NULL, NULL, 0 ) != noErr ) throw ImageIoException(); mPixMap = ::GetGWorldPixMap( mGWorld ); if( ! ::LockPixels( mPixMap ) ) { ::DisposeGWorld( mGWorld ); throw ImageIoException(); } #if defined( CINDER_MSW ) mData = reinterpret_cast<uint8_t*>( (**mPixMap).baseAddr ); mRowBytes = ( (**mPixMap).rowBytes ) & 0x3FFF; #else mData = reinterpret_cast<uint8_t*>( ::GetPixBaseAddr( mPixMap ) ); mRowBytes = ::GetPixRowBytes( mPixMap ); #endif }
void SurfaceT<T>::init( ImageSourceRef imageSource, const SurfaceConstraints &constraints, boost::tribool alpha ) { int32_t width = imageSource->getWidth(); int32_t height = imageSource->getHeight(); bool hasAlpha; if( alpha ) hasAlpha = true; else if( ! alpha ) hasAlpha = false; else hasAlpha = imageSource->hasAlpha(); SurfaceChannelOrder channelOrder = constraints.getChannelOrder( hasAlpha ); int32_t rowBytes = constraints.getRowBytes( width, channelOrder, sizeof(T) ); T *data = new T[height * rowBytes]; mObj = std::shared_ptr<Obj>( new Obj( width, height, channelOrder, data, true, rowBytes ) ); mObj->mIsPremultiplied = imageSource->isPremultiplied(); std::shared_ptr<ImageTargetSurface<T> > target = ImageTargetSurface<T>::createRef( this ); imageSource->load( target ); // if the image doesn't have alpha but we do, set ourselves to be full alpha if( hasAlpha && ( ! imageSource->hasAlpha() ) ) { ip::fill( &getChannelAlpha(), CHANTRAIT<T>::max() ); } }
ImageTargetCvPixelBuffer::ImageTargetCvPixelBuffer( ImageSourceRef imageSource, bool convertToYpCbCr ) : ImageTarget(), mPixelBufferRef( 0 ), mConvertToYpCbCr( convertToYpCbCr ) { setSize( (size_t)imageSource->getWidth(), (size_t)imageSource->getHeight() ); //http://developer.apple.com/mac/library/qa/qa2006/qa1501.html // if we're converting to YCbCr, we'll load all of the data as RGB in terms of ci::ImageIo // but we run color space conversion over it later in the finalize method OSType formatType; if( ! mConvertToYpCbCr ) { switch( imageSource->getDataType() ) { // for now all we support is 8 bit RGB(A) case ImageIo::UINT16: case ImageIo::FLOAT32: case ImageIo::UINT8: setDataType( ImageIo::UINT8 ); if( imageSource->hasAlpha () ) { formatType = k32ARGBPixelFormat; setChannelOrder( ImageIo::ARGB ); } else { formatType = k24RGBPixelFormat; setChannelOrder( ImageIo::RGB ); } setColorModel( ImageIo::CM_RGB ); break; default: throw ImageIoException(); } } else { formatType = 'v408';/*k4444YpCbCrA8PixelFormat;*/ setDataType( ImageIo::UINT8 ); setChannelOrder( ImageIo::RGBA ); setColorModel( ImageIo::CM_RGB ); } if( ::CVPixelBufferCreate( kCFAllocatorDefault, imageSource->getWidth(), imageSource->getHeight(), formatType, NULL, &mPixelBufferRef ) != kCVReturnSuccess ) throw ImageIoException(); if( ::CVPixelBufferLockBaseAddress( mPixelBufferRef, 0 ) != kCVReturnSuccess ) throw ImageIoException(); mData = reinterpret_cast<uint8_t*>( ::CVPixelBufferGetBaseAddress( mPixelBufferRef ) ); mRowBytes = ::CVPixelBufferGetBytesPerRow( mPixelBufferRef ); }
SurfaceImage::SurfaceImage( ImageSourceRef imageSource ) : SurfaceBase( imageSource->getWidth(), imageSource->getHeight() ) { mCairoSurface = cairo_image_surface_create( imageSource->hasAlpha() ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, imageSource->getWidth(), imageSource->getHeight() ); initCinderSurface( imageSource->hasAlpha(), cairo_image_surface_get_data( mCairoSurface ), cairo_image_surface_get_stride( mCairoSurface ) ); writeImage( (ImageTargetRef)mCinderSurface, imageSource ); cairo_surface_mark_dirty( mCairoSurface ); }
ChannelT<T>::ChannelT( const ImageSourceRef &imageSource ) { mWidth = imageSource->getWidth(); mHeight = imageSource->getHeight(); mRowBytes = mWidth * sizeof(T); mIncrement = 1; mDataStore = shared_ptr<T>( new T[mHeight * (mRowBytes/sizeof(T))], std::default_delete<T[]>() ); mData = mDataStore.get(); shared_ptr<ImageTargetChannel<T>> target = ImageTargetChannel<T>::createRef( this ); imageSource->load( target ); }
ChannelT<T>::ChannelT( ImageSourceRef imageSource ) { int32_t width = imageSource->getWidth(); int32_t height = imageSource->getHeight(); int32_t rowBytes = width * sizeof(T); T *data = new T[height * (rowBytes/sizeof(T))]; mObj = shared_ptr<Obj>( new Obj( width, height, rowBytes, 1, true, data ) ); mObj->mOwnsData = true; shared_ptr<ImageTargetChannel<T> > target = ImageTargetChannel<T>::createRef( this ); imageSource->load( target ); }
ImageTargetFileTinyExr::ImageTargetFileTinyExr( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, const std::string & /*extensionData*/ ) { if( ! dataTarget->providesFilePath() ) { throw ImageIoExceptionFailedWrite( "ImageTargetFileTinyExr only supports writing to files." ); } mFilePath = dataTarget->getFilePath(); setSize( imageSource->getWidth(), imageSource->getHeight() ); ImageIo::ColorModel cm = options.isColorModelDefault() ? imageSource->getColorModel() : options.getColorModel(); switch( cm ) { case ImageIo::ColorModel::CM_RGB: mNumComponents = ( imageSource->hasAlpha() ) ? 4 : 3; setColorModel( ImageIo::ColorModel::CM_RGB ); setChannelOrder( ( mNumComponents == 3 ) ? ImageIo::ChannelOrder::BGR : ImageIo::ChannelOrder::ABGR ); if( mNumComponents == 3 ) mChannelNames = { "G", "B", "R" }; else mChannelNames = { "A", "G", "B", "R" }; break; case ImageIo::ColorModel::CM_GRAY: mNumComponents = ( imageSource->hasAlpha() ) ? 2 : 1; setColorModel( ImageIo::ColorModel::CM_GRAY ); setChannelOrder( ( mNumComponents == 2 ) ? ImageIo::ChannelOrder::YA : ImageIo::ChannelOrder::Y ); if( mNumComponents == 2 ) mChannelNames = { "Y", "A" }; else mChannelNames = { "Y" }; break; default: throw ImageIoExceptionIllegalColorModel(); } // TODO: consider supporting half float and uint types as well setDataType( ImageIo::DataType::FLOAT32 ); mData.resize( mHeight * imageSource->getWidth() * mNumComponents ); }
ImageTargetFileStbImage::ImageTargetFileStbImage( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, const std::string &extensionData ) { if( ! dataTarget->providesFilePath() ) { throw ImageIoExceptionFailedWrite( "ImageTargetFileStbImage only supports writing to files." ); } mFilePath = dataTarget->getFilePath(); setSize( imageSource->getWidth(), imageSource->getHeight() ); ImageIo::ColorModel cm = options.isColorModelDefault() ? imageSource->getColorModel() : options.getColorModel(); switch( cm ) { case ImageIo::ColorModel::CM_RGB: mNumComponents = ( imageSource->hasAlpha() ) ? 4 : 3; setColorModel( ImageIo::ColorModel::CM_RGB ); setChannelOrder( ( mNumComponents == 4 ) ? ImageIo::ChannelOrder::RGBA : ImageIo::ChannelOrder::RGB ); break; case ImageIo::ColorModel::CM_GRAY: mNumComponents = ( imageSource->hasAlpha() ) ? 2 : 1; setColorModel( ImageIo::ColorModel::CM_GRAY ); setChannelOrder( ( mNumComponents == 2 ) ? ImageIo::ChannelOrder::YA : ImageIo::ChannelOrder::Y ); break; default: throw ImageIoExceptionIllegalColorModel(); } mExtension = extensionData; if( mExtension == "hdr" ) { // Radiance files are always float* setDataType( ImageIo::DataType::FLOAT32 ); mRowBytes = mNumComponents * imageSource->getWidth() * sizeof(float); } else { setDataType( ImageIo::DataType::UINT8 ); mRowBytes = mNumComponents * imageSource->getWidth() * sizeof(float); } mData = std::unique_ptr<uint8_t[]>( new uint8_t[mWidth * mRowBytes] ); }
void Texture::init( ImageSourceRef imageSource, const Format &format ) { mObj->mDoNotDispose = false; mObj->mTarget = format.mTarget; mObj->mWidth = mObj->mCleanWidth = imageSource->getWidth(); mObj->mHeight = mObj->mCleanHeight = imageSource->getHeight(); #if defined( CINDER_MAC ) bool supportsTextureFloat = gl::isExtensionAvailable( "GL_ARB_texture_float" ); #elif defined( CINDER_MSW ) bool supportsTextureFloat = GLEE_ARB_texture_float != 0; #endif // Set the internal format based on the image's color space if( format.isAutoInternalFormat() ) { switch( imageSource->getColorModel() ) { #if ! defined( CINDER_GLES ) case ImageIo::CM_RGB: if( imageSource->getDataType() == ImageIo::UINT8 ) mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_RGBA8 : GL_RGB8; else if( imageSource->getDataType() == ImageIo::UINT16 ) mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_RGBA16 : GL_RGB16; else if( imageSource->getDataType() == ImageIo::FLOAT32 && supportsTextureFloat ) mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_RGBA32F_ARB : GL_RGB32F_ARB; else mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_RGBA : GL_RGB; break; case ImageIo::CM_GRAY: if( imageSource->getDataType() == ImageIo::UINT8 ) mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE8; else if( imageSource->getDataType() == ImageIo::UINT16 ) mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_LUMINANCE16_ALPHA16 : GL_LUMINANCE16; else if( imageSource->getDataType() == ImageIo::FLOAT32 && supportsTextureFloat ) mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_LUMINANCE_ALPHA32F_ARB : GL_LUMINANCE32F_ARB; else mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_LUMINANCE_ALPHA : GL_LUMINANCE; break; #else case ImageIo::CM_RGB: mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_RGBA : GL_RGB; break; case ImageIo::CM_GRAY: mObj->mInternalFormat = ( imageSource->hasAlpha() ) ? GL_LUMINANCE_ALPHA : GL_LUMINANCE; break; #endif default: throw ImageIoExceptionIllegalColorModel(); break; } } else { mObj->mInternalFormat = format.mInternalFormat; } // setup an appropriate dataFormat/ImageTargetTexture based on the image's color space GLint dataFormat; ImageIo::ChannelOrder channelOrder; bool isGray = false; switch( imageSource->getColorModel() ) { case ImageSource::CM_RGB: dataFormat = ( imageSource->hasAlpha() ) ? GL_RGBA : GL_RGB; channelOrder = ( imageSource->hasAlpha() ) ? ImageIo::RGBA : ImageIo::RGB; break; case ImageSource::CM_GRAY: dataFormat = ( imageSource->hasAlpha() ) ? GL_LUMINANCE_ALPHA : GL_LUMINANCE; channelOrder = ( imageSource->hasAlpha() ) ? ImageIo::YA : ImageIo::Y; isGray = true; break; default: // if this is some other color space, we'll have to punt and go w/ RGB dataFormat = ( imageSource->hasAlpha() ) ? GL_RGBA : GL_RGB; channelOrder = ( imageSource->hasAlpha() ) ? ImageIo::RGBA : ImageIo::RGB; break; } glGenTextures( 1, &mObj->mTextureID ); glBindTexture( mObj->mTarget, mObj->mTextureID ); glTexParameteri( mObj->mTarget, GL_TEXTURE_WRAP_S, format.mWrapS ); glTexParameteri( mObj->mTarget, GL_TEXTURE_WRAP_T, format.mWrapT ); glTexParameteri( mObj->mTarget, GL_TEXTURE_MIN_FILTER, format.mMinFilter ); glTexParameteri( mObj->mTarget, GL_TEXTURE_MAG_FILTER, format.mMagFilter ); if( format.mMipmapping ) glTexParameteri( mObj->mTarget, GL_GENERATE_MIPMAP, GL_TRUE ); if( mObj->mTarget == GL_TEXTURE_2D ) { mObj->mMaxU = mObj->mMaxV = 1.0f; } else { mObj->mMaxU = (float)mObj->mWidth; mObj->mMaxV = (float)mObj->mHeight; } glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); if( imageSource->getDataType() == ImageIo::UINT8 ) { shared_ptr<ImageTargetGLTexture<uint8_t> > target = ImageTargetGLTexture<uint8_t>::createRef( this, channelOrder, isGray, imageSource->hasAlpha() ); imageSource->load( target ); glTexImage2D( mObj->mTarget, 0, mObj->mInternalFormat, mObj->mWidth, mObj->mHeight, 0, dataFormat, GL_UNSIGNED_BYTE, target->getData() ); } else if( imageSource->getDataType() == ImageIo::UINT16 ) { shared_ptr<ImageTargetGLTexture<uint16_t> > target = ImageTargetGLTexture<uint16_t>::createRef( this, channelOrder, isGray, imageSource->hasAlpha() ); imageSource->load( target ); glTexImage2D( mObj->mTarget, 0, mObj->mInternalFormat, mObj->mWidth, mObj->mHeight, 0, dataFormat, GL_UNSIGNED_SHORT, target->getData() ); } else { shared_ptr<ImageTargetGLTexture<float> > target = ImageTargetGLTexture<float>::createRef( this, channelOrder, isGray, imageSource->hasAlpha() ); imageSource->load( target ); glTexImage2D( mObj->mTarget, 0, mObj->mInternalFormat, mObj->mWidth, mObj->mHeight, 0, dataFormat, GL_FLOAT, target->getData() ); } }
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> ); }
ImageTargetFileWic::ImageTargetFileWic( DataTargetRef dataTarget, ImageSourceRef imageSource, ImageTarget::Options options, 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 { ImageIo::ColorModel cm = options.isColorModelDefault() ? imageSource->getColorModel() : options.getColorModel(); if( cm == 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 { // RGB 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 ImageIoExceptionFailedWrite( "Could not create WIC Factory." ); shared_ptr<IWICImagingFactory> IWICFactory = msw::makeComShared( IWICFactoryP ); IWICBitmapEncoder *encoderP = NULL; hr = IWICFactory->CreateEncoder( *mCodecGUID, 0, &encoderP ); if( ! SUCCEEDED( hr ) ) throw ImageIoExceptionFailedWrite( "Could not create WIC Encoder." ); mEncoder = msw::makeComShared( encoderP ); // create the stream IWICStream *pIWICStream = NULL; hr = IWICFactory->CreateStream( &pIWICStream ); if( ! SUCCEEDED(hr) ) throw ImageIoExceptionFailedWrite( "Could not create WIC stream." ); shared_ptr<IWICStream> stream = msw::makeComShared( pIWICStream ); // initialize the stream based on properties of the cinder::DataSouce if( mDataTarget->providesFilePath() ) { #if defined( CINDER_WINRT) std::string s = mDataTarget->getFilePath().string(); std::wstring filePath = std::wstring(s.begin(), s.end()); #else std::wstring filePath = mDataTarget->getFilePath().wstring().c_str(); #endif hr = stream->InitializeFromFilename( filePath.c_str(), GENERIC_WRITE ); if( ! SUCCEEDED(hr) ) throw ImageIoExceptionFailedWrite( "Could not initialize WIC Stream from filename." ); } else { shared_ptr<msw::ComOStream> comOStream = msw::makeComShared( new msw::ComOStream( mDataTarget->getStream() ) ); hr = stream->InitializeFromIStream( comOStream.get() ); if( ! SUCCEEDED(hr) ) throw ImageIoExceptionFailedWrite( "Could not initialize WIC Stream from IStream." ); } hr = mEncoder->Initialize( stream.get(), WICBitmapEncoderNoCache ); if( ! SUCCEEDED( hr ) ) throw ImageIoExceptionFailedWrite( "Could not initialize WIC Encoder." ); // create the frame encoder IPropertyBag2 *pPropertybag = NULL; IWICBitmapFrameEncode *pBitmapFrame = NULL; hr = mEncoder->CreateNewFrame( &pBitmapFrame, &pPropertybag ); if( ! SUCCEEDED( hr ) ) throw ImageIoExceptionFailedWrite( "Could not ceate WIC Frame." ); mBitmapFrame = msw::makeComShared( pBitmapFrame ); // setup the propertyBag to express quality PROPBAG2 option = { 0 }; option.pstrName = L"ImageQuality"; VARIANT varValue; VariantInit(&varValue); varValue.vt = VT_R4; varValue.fltVal = options.getQuality(); hr = pPropertybag->Write( 1, &option, &varValue ); hr = mBitmapFrame->Initialize( pPropertybag ); if( ! SUCCEEDED( hr ) ) throw ImageIoExceptionFailedWrite( "Could not initialize WIC PROPBAG2." ); hr = mBitmapFrame->SetSize( mWidth, mHeight ); if( ! SUCCEEDED( hr ) ) throw ImageIoExceptionFailedWrite( "Could not set WIC Frame size." ); // ask for our ideal pixel format and then process the one we actually get hr = mBitmapFrame->SetPixelFormat( &formatGUID ); if( ! SUCCEEDED( hr ) ) throw ImageIoExceptionFailedWrite( "Could not set WIC Frame pixel format." ); setupPixelFormat( formatGUID ); mData = shared_ptr<uint8_t>( new uint8_t[mHeight * mRowBytes], std::default_delete<uint8_t[]>() ); }