ImageOrientation ImageDecoder::frameOrientationAtIndex(size_t index) const { RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), index, imageSourceOptions().get())); if (!properties) return ImageOrientation(); return orientationFromProperties(properties.get()); }
ImageOrientation ImageSource::orientationAtIndex(size_t index) const { RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions().get())); if (!properties) return DefaultImageOrientation; return orientationFromProperties(properties.get()); }
IntSize ImageSource::frameSizeAtIndex(size_t index, ImageOrientationDescription description) const { RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata))); if (!properties) return IntSize(); int w = 0, h = 0; CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth); if (num) CFNumberGetValue(num, kCFNumberIntType, &w); num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight); if (num) CFNumberGetValue(num, kCFNumberIntType, &h); #if PLATFORM(IOS) if (!m_isProgressive) { CFDictionaryRef jfifProperties = static_cast<CFDictionaryRef>(CFDictionaryGetValue(properties.get(), kCGImagePropertyJFIFDictionary)); if (jfifProperties) { CFBooleanRef isProgCFBool = static_cast<CFBooleanRef>(CFDictionaryGetValue(jfifProperties, kCGImagePropertyJFIFIsProgressive)); if (isProgCFBool) m_isProgressive = CFBooleanGetValue(isProgCFBool); // Workaround for <rdar://problem/5184655> - Hang rendering very large progressive JPEG. Decoding progressive // images hangs for a very long time right now. Until this is fixed, don't sub-sample progressive images. This // will cause them to fail our large image check and they won't be decoded. // FIXME: Remove once underlying issue is fixed (<rdar://problem/5191418>) } } if ((m_baseSubsampling == 0) && !m_isProgressive) { IntSize subsampledSize(w, h); const int cMaximumImageSizeBeforeSubsampling = 5 * 1024 * 1024; while ((m_baseSubsampling < 3) && subsampledSize.width() * subsampledSize.height() > cMaximumImageSizeBeforeSubsampling) { // We know the size, but the actual image is very large and should be sub-sampled. // Increase the base subsampling and ask for the size again. If the image can be subsampled, the size will be // greatly reduced. 4x sub-sampling will make us support up to 320MP (5MP * 4^3) images, which should be plenty. // There's no callback from ImageIO when the size is available, so we do the check when we happen // to check the size and its non - zero. // Note: Some clients of this class don't call isSizeAvailable() so we can't rely on that. ++m_baseSubsampling; subsampledSize = frameSizeAtIndex(index, description.respectImageOrientation()); } w = subsampledSize.width(); h = subsampledSize.height(); } #endif if ((description.respectImageOrientation() == RespectImageOrientation) && orientationFromProperties(properties.get()).usesWidthAsHeight()) return IntSize(h, w); return IntSize(w, h); }
IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const { RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata))); if (!properties) return IntSize(); int w = 0, h = 0; CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth); if (num) CFNumberGetValue(num, kCFNumberIntType, &w); num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight); if (num) CFNumberGetValue(num, kCFNumberIntType, &h); if ((shouldRespectOrientation == RespectImageOrientation) && orientationFromProperties(properties.get()).usesWidthAsHeight()) return IntSize(h, w); return IntSize(w, h); }
IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel, ImageOrientationDescription description) const { RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(subsamplingLevel).get())); if (!properties) return IntSize(); int width = 0; int height = 0; CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth); if (num) CFNumberGetValue(num, kCFNumberIntType, &width); num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight); if (num) CFNumberGetValue(num, kCFNumberIntType, &height); if ((description.respectImageOrientation() == RespectImageOrientation) && orientationFromProperties(properties.get()).usesWidthAsHeight()) return IntSize(height, width); return IntSize(width, height); }
IntSize ImageSource::originalSize(RespectImageOrientationEnum shouldRespectOrientation) const { frameSizeAtIndex(0, shouldRespectOrientation); RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions(SkipMetadata, -1))); if (!properties) return IntSize(); int width = 0; int height = 0; CFNumberRef number = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth); if (number) CFNumberGetValue(number, kCFNumberIntType, &width); number = static_cast<CFNumberRef>(CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight)); if (number) CFNumberGetValue(number, kCFNumberIntType, &height); if ((shouldRespectOrientation == RespectImageOrientation) && orientationFromProperties(properties.get()).usesWidthAsHeight()) return IntSize(height, width); return IntSize(width, height); }