////////////////////////////////////////////////////////////////////////// ImageSourceFileQuartz
| 84 | /////////////////////////////////////////////////////////////////////////////// |
| 85 | // ImageSourceFileQuartz |
| 86 | ImageSourceFileQuartzRef ImageSourceFileQuartz::createFileQuartzRef( DataSourceRef dataSourceRef, ImageSource::Options options ) |
| 87 | { |
| 88 | std::shared_ptr<CGImageSource> sourceRef; |
| 89 | std::shared_ptr<CGImage> imageRef; |
| 90 | |
| 91 | ::CFStringRef keys[1] = { kCGImageSourceShouldAllowFloat }; |
| 92 | ::CFBooleanRef values[1] = { kCFBooleanTrue }; |
| 93 | const std::shared_ptr<__CFDictionary> optionsDict( (__CFDictionary*)CFDictionaryCreate( kCFAllocatorDefault, (const void **)&keys, (const void **)&values, 1, NULL, NULL ), cocoa::safeCfRelease ); |
| 94 | |
| 95 | if( dataSourceRef->isFilePath() ) { |
| 96 | ::CFStringRef pathString = cocoa::createCfString( dataSourceRef->getFilePath().string() ); |
| 97 | ::CFURLRef urlRef = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, pathString, kCFURLPOSIXPathStyle, false ); |
| 98 | sourceRef = std::shared_ptr<CGImageSource>( ::CGImageSourceCreateWithURL( urlRef, optionsDict.get() ), cocoa::safeCfRelease ); |
| 99 | ::CFRelease( pathString ); |
| 100 | ::CFRelease( urlRef ); |
| 101 | } |
| 102 | else if( dataSourceRef->isUrl() ) { |
| 103 | ::CFURLRef urlRef = cocoa::createCfUrl( dataSourceRef->getUrl() ); |
| 104 | if( ! urlRef ) |
| 105 | throw ImageIoException( "Could not create CFURLRef from data source." ); |
| 106 | sourceRef = std::shared_ptr<CGImageSource>( ::CGImageSourceCreateWithURL( urlRef, optionsDict.get() ), cocoa::safeCfRelease ); |
| 107 | ::CFRelease( urlRef ); |
| 108 | } |
| 109 | else { // last ditch, we'll use a dataref from the buffer |
| 110 | ::CFDataRef dataRef = cocoa::createCfDataRef( *dataSourceRef->getBuffer() ); |
| 111 | if( ! dataRef ) |
| 112 | throw ImageIoExceptionFailedLoad( "Could not create CFDataRef from data source." ); |
| 113 | |
| 114 | sourceRef = std::shared_ptr<CGImageSource>( ::CGImageSourceCreateWithData( dataRef, optionsDict.get() ), cocoa::safeCfRelease ); |
| 115 | ::CFRelease( dataRef ); |
| 116 | } |
| 117 | |
| 118 | if( sourceRef ) { |
| 119 | imageRef = std::shared_ptr<CGImage>( ::CGImageSourceCreateImageAtIndex( sourceRef.get(), options.getIndex(), optionsDict.get() ), CGImageRelease ); |
| 120 | if( ! imageRef ) |
| 121 | throw ImageIoExceptionFailedLoad( "Core Graphics could not create image data." ); |
| 122 | } |
| 123 | else |
| 124 | throw ImageIoExceptionFailedLoad( "Failed to load CGImageSource." ); |
| 125 | |
| 126 | const std::shared_ptr<__CFDictionary> imageProperties( (__CFDictionary*)::CGImageSourceCopyProperties( sourceRef.get(), NULL ), ::CFRelease ); |
| 127 | const std::shared_ptr<__CFDictionary> imageIndexProperties( (__CFDictionary*)::CGImageSourceCopyPropertiesAtIndex( sourceRef.get(), options.getIndex(), NULL ), ::CFRelease ); |
| 128 | const int32_t numFrames = (int32_t)::CGImageSourceGetCount( sourceRef.get() ); |
| 129 | |
| 130 | return ImageSourceFileQuartzRef( new ImageSourceFileQuartz( imageRef.get(), options, imageProperties, imageIndexProperties, numFrames ) ); |
| 131 | } |
| 132 | |
| 133 | ImageSourceFileQuartz::ImageSourceFileQuartz( CGImageRef imageRef, ImageSource::Options options, std::shared_ptr<const struct __CFDictionary> imageProperties, std::shared_ptr<const struct __CFDictionary> imageIndexProps, int32_t numFrames ) |
| 134 | : ImageSourceCgImage( imageRef, options ), mImageProperties( imageProperties ), mImageIndexProperties( imageIndexProps ) |