From d82174cc79a50da7ccc330fadd78b7e439315d29 Mon Sep 17 00:00:00 2001 From: ibireme Date: Sat, 27 Feb 2016 17:55:14 +0800 Subject: [PATCH] swift api compatibility --- Demo/YYTextDemo/YYImage/YYAnimatedImageView.h | 12 +- Demo/YYTextDemo/YYImage/YYAnimatedImageView.m | 23 ++-- Demo/YYTextDemo/YYImage/YYFrameImage.h | 20 +++- Demo/YYTextDemo/YYImage/YYImage.h | 16 +-- Demo/YYTextDemo/YYImage/YYImageCoder.h | 103 +++++++++--------- Demo/YYTextDemo/YYImage/YYImageCoder.m | 59 ++++++---- Demo/YYTextDemo/YYImage/YYSpriteSheetImage.h | 16 ++- 7 files changed, 148 insertions(+), 101 deletions(-) diff --git a/Demo/YYTextDemo/YYImage/YYAnimatedImageView.h b/Demo/YYTextDemo/YYImage/YYAnimatedImageView.h index 7448a3a6..e70a6543 100644 --- a/Demo/YYTextDemo/YYImage/YYAnimatedImageView.h +++ b/Demo/YYTextDemo/YYImage/YYAnimatedImageView.h @@ -11,6 +11,8 @@ #import +NS_ASSUME_NONNULL_BEGIN + /** An image view for displaying animated image. @@ -38,7 +40,7 @@ The default value is `YES`. */ -@property (nonatomic, assign) BOOL autoPlayAnimatedImage; +@property (nonatomic) BOOL autoPlayAnimatedImage; /** Index of the currently displayed frame (index from 0). @@ -48,7 +50,7 @@ You can add an observer to this property to observe the playing status. */ -@property (nonatomic, assign) NSUInteger currentAnimatedImageIndex; +@property (nonatomic) NSUInteger currentAnimatedImageIndex; /** Whether the image view is playing animation currently. @@ -76,7 +78,7 @@ When receive memory warning or app enter background, the buffer will be released immediately, and may grow back at the right time. */ -@property (nonatomic, assign) NSUInteger maxBufferSize; +@property (nonatomic) NSUInteger maxBufferSize; @end @@ -107,7 +109,7 @@ /// Returns the frame image from a specified index. /// This method may be called on background thread. /// @param index Frame index (zero based). -- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index; +- (nullable UIImage *)animatedImageFrameAtIndex:(NSUInteger)index; /// Returns the frames's duration from a specified index. /// @param index Frame index (zero based). @@ -119,3 +121,5 @@ /// It may used to display sprite animation with a single image (sprite sheet). - (CGRect)animatedImageContentsRectAtIndex:(NSUInteger)index; @end + +NS_ASSUME_NONNULL_END diff --git a/Demo/YYTextDemo/YYImage/YYAnimatedImageView.m b/Demo/YYTextDemo/YYImage/YYAnimatedImageView.m index 99e42c2e..8c50ef7c 100644 --- a/Demo/YYTextDemo/YYImage/YYAnimatedImageView.m +++ b/Demo/YYTextDemo/YYImage/YYAnimatedImageView.m @@ -135,7 +135,7 @@ @interface YYAnimatedImageView() { NSUInteger _curIndex; ///< current frame index (from 0) NSUInteger _totalFrameCount; ///< total frame count - BOOL _loopEnd; ///< weather the loop is end. + BOOL _loopEnd; ///< whether the loop is end. NSUInteger _curLoop; ///< current loop count (from 0) NSUInteger _totalLoop; ///< total loop count, 0 means infinity @@ -165,22 +165,28 @@ - (void)main { if ([self isCancelled]) return; view->_incrBufferCount++; if (view->_incrBufferCount == 0) [view calcMaxBufferCount]; - if ((int)view->_incrBufferCount > (int)view->_maxBufferCount) { + if (view->_incrBufferCount > (NSInteger)view->_maxBufferCount) { view->_incrBufferCount = view->_maxBufferCount; } NSUInteger idx = _nextIndex; NSUInteger max = view->_incrBufferCount < 1 ? 1 : view->_incrBufferCount; NSUInteger total = view->_totalFrameCount; + view = nil; + for (int i = 0; i < max; i++, idx++) { @autoreleasepool { if (idx >= total) idx = 0; if ([self isCancelled]) break; + __strong YYAnimatedImageView *view = _view; + if (!view) break; LOCK_VIEW(BOOL miss = (view->_buffer[@(idx)] == nil)); + if (miss) { UIImage *img = [_curImage animatedImageFrameAtIndex:idx]; - img = [img yy_imageByDecoded]; + img = img.yy_imageByDecoded; if ([self isCancelled]) break; LOCK_VIEW(view->_buffer[@(idx)] = img ? img : [NSNull null]); + view = nil; } } } @@ -373,16 +379,18 @@ - (void)imageChanged { // dynamically adjust buffer size for current memory. - (void)calcMaxBufferCount { - NSUInteger bytes = _curAnimatedImage.animatedImageBytesPerFrame; - if (bytes == 0) bytes = 1; + int64_t bytes = (int64_t)_curAnimatedImage.animatedImageBytesPerFrame; + if (bytes == 0) bytes = 1024; int64_t total = _YYDeviceMemoryTotal(); int64_t free = _YYDeviceMemoryFree(); int64_t max = MIN(total * 0.2, free * 0.6); max = MAX(max, BUFFER_SIZE); if (_maxBufferSize) max = max > _maxBufferSize ? _maxBufferSize : max; - _maxBufferCount = (float)max / (float)bytes; - if (_maxBufferCount == 0) _maxBufferCount = 1; + double maxBufferCount = (double)max / (double)bytes; + if (maxBufferCount < 1) maxBufferCount = 1; + else if (maxBufferCount > 512) maxBufferCount = 512; + _maxBufferCount = maxBufferCount; } - (void)dealloc { @@ -398,6 +406,7 @@ - (BOOL)isAnimating { - (void)stopAnimating { [super stopAnimating]; + [_requestQueue cancelAllOperations]; _link.paused = YES; self.currentIsPlayingAnimation = NO; } diff --git a/Demo/YYTextDemo/YYImage/YYFrameImage.h b/Demo/YYTextDemo/YYImage/YYFrameImage.h index 182a2eec..5795cc51 100644 --- a/Demo/YYTextDemo/YYImage/YYFrameImage.h +++ b/Demo/YYTextDemo/YYImage/YYFrameImage.h @@ -19,6 +19,8 @@ #import "YYAnimatedImageView.h" #endif +NS_ASSUME_NONNULL_BEGIN + /** An image to display frame-based animation. @@ -49,7 +51,9 @@ @return An initialized YYFrameImage object, or nil when an error occurs. */ -- (instancetype)initWithImagePaths:(NSArray *)paths oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount; +- (nullable instancetype)initWithImagePaths:(NSArray *)paths + oneFrameDuration:(NSTimeInterval)oneFrameDuration + loopCount:(NSUInteger)loopCount; /** Create a frame animated image from files. @@ -65,7 +69,9 @@ @return An initialized YYFrameImage object, or nil when an error occurs. */ -- (instancetype)initWithImagePaths:(NSArray *)paths frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount; +- (nullable instancetype)initWithImagePaths:(NSArray *)paths + frameDurations:(NSArray *)frameDurations + loopCount:(NSUInteger)loopCount; /** Create a frame animated image from an array of data. @@ -78,7 +84,9 @@ @return An initialized YYFrameImage object, or nil when an error occurs. */ -- (instancetype)initWithImageDataArray:(NSArray *)dataArray oneFrameDuration:(NSTimeInterval)oneFrameDuration loopCount:(NSUInteger)loopCount; +- (nullable instancetype)initWithImageDataArray:(NSArray *)dataArray + oneFrameDuration:(NSTimeInterval)oneFrameDuration + loopCount:(NSUInteger)loopCount; /** Create a frame animated image from an array of data. @@ -92,6 +100,10 @@ @return An initialized YYFrameImage object, or nil when an error occurs. */ -- (instancetype)initWithImageDataArray:(NSArray *)dataArray frameDurations:(NSArray *)frameDurations loopCount:(NSUInteger)loopCount; +- (nullable instancetype)initWithImageDataArray:(NSArray *)dataArray + frameDurations:(NSArray *)frameDurations + loopCount:(NSUInteger)loopCount; @end + +NS_ASSUME_NONNULL_END diff --git a/Demo/YYTextDemo/YYImage/YYImage.h b/Demo/YYTextDemo/YYImage/YYImage.h index 41bfb157..03610260 100644 --- a/Demo/YYTextDemo/YYImage/YYImage.h +++ b/Demo/YYTextDemo/YYImage/YYImage.h @@ -30,7 +30,7 @@ FOUNDATION_EXPORT const unsigned char YYImageVersionString[]; #import "YYAnimatedImageView.h" #endif - +NS_ASSUME_NONNULL_BEGIN /** @@ -53,10 +53,10 @@ FOUNDATION_EXPORT const unsigned char YYImageVersionString[]; */ @interface YYImage : UIImage -+ (YYImage *)imageNamed:(NSString *)name; // no cache! -+ (YYImage *)imageWithContentsOfFile:(NSString *)path; -+ (YYImage *)imageWithData:(NSData *)data; -+ (YYImage *)imageWithData:(NSData *)data scale:(CGFloat)scale; ++ (nullable YYImage *)imageNamed:(NSString *)name; // no cache! ++ (nullable YYImage *)imageWithContentsOfFile:(NSString *)path; ++ (nullable YYImage *)imageWithData:(NSData *)data; ++ (nullable YYImage *)imageWithData:(NSData *)data scale:(CGFloat)scale; /** If the image is created from data or file, then the value indicates the data type. @@ -67,7 +67,7 @@ FOUNDATION_EXPORT const unsigned char YYImageVersionString[]; If the image is created from animated image data (multi-frame GIF/APNG/WebP), this property stores the original image data. */ -@property (nonatomic, readonly) NSData *animatedImageData; +@property (nullable, nonatomic, readonly) NSData *animatedImageData; /** The total memory usage (in bytes) if all frame images was loaded into memory. @@ -85,6 +85,8 @@ FOUNDATION_EXPORT const unsigned char YYImageVersionString[]; See `animatedImageMemorySize` for memory cost. */ -@property (nonatomic, assign) BOOL preloadAllAnimatedImageFrames; +@property (nonatomic) BOOL preloadAllAnimatedImageFrames; @end + +NS_ASSUME_NONNULL_END diff --git a/Demo/YYTextDemo/YYImage/YYImageCoder.h b/Demo/YYTextDemo/YYImage/YYImageCoder.h index 6330b1ec..61a931c4 100644 --- a/Demo/YYTextDemo/YYImage/YYImageCoder.h +++ b/Demo/YYTextDemo/YYImage/YYImageCoder.h @@ -11,6 +11,8 @@ #import +NS_ASSUME_NONNULL_BEGIN + /** Image file type. */ @@ -76,15 +78,15 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { An image frame object. */ @interface YYImageFrame : NSObject -@property (nonatomic, assign) NSUInteger index; ///< Frame index (zero based) -@property (nonatomic, assign) NSUInteger width; ///< Frame width -@property (nonatomic, assign) NSUInteger height; ///< Frame height -@property (nonatomic, assign) NSUInteger offsetX; ///< Frame origin.x in canvas (left-bottom based) -@property (nonatomic, assign) NSUInteger offsetY; ///< Frame origin.y in canvas (left-bottom based) -@property (nonatomic, assign) NSTimeInterval duration; ///< Frame duration in seconds -@property (nonatomic, assign) YYImageDisposeMethod dispose; ///< Frame dispose method. -@property (nonatomic, assign) YYImageBlendOperation blend; ///< Frame blend operation. -@property (nonatomic, strong) UIImage *image; ///< The image. +@property (nonatomic) NSUInteger index; ///< Frame index (zero based) +@property (nonatomic) NSUInteger width; ///< Frame width +@property (nonatomic) NSUInteger height; ///< Frame height +@property (nonatomic) NSUInteger offsetX; ///< Frame origin.x in canvas (left-bottom based) +@property (nonatomic) NSUInteger offsetY; ///< Frame origin.y in canvas (left-bottom based) +@property (nonatomic) NSTimeInterval duration; ///< Frame duration in seconds +@property (nonatomic) YYImageDisposeMethod dispose; ///< Frame dispose method. +@property (nonatomic) YYImageBlendOperation blend; ///< Frame blend operation. +@property (nullable, nonatomic, strong) UIImage *image; ///< The image. + (instancetype)frameWithImage:(UIImage *)image; @end @@ -124,9 +126,9 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { */ @interface YYImageDecoder : NSObject -@property (nonatomic, readonly) NSData *data; ///< Image data. -@property (nonatomic, readonly) YYImageType type; ///< Image data type. -@property (nonatomic, readonly) CGFloat scale; ///< Image scale. +@property (nullable, nonatomic, readonly) NSData *data; ///< Image data. +@property (nonatomic, readonly) YYImageType type; ///< Image data type. +@property (nonatomic, readonly) CGFloat scale; ///< Image scale. @property (nonatomic, readonly) NSUInteger frameCount; ///< Image frame count. @property (nonatomic, readonly) NSUInteger loopCount; ///< Image loop count, 0 means infinite. @property (nonatomic, readonly) NSUInteger width; ///< Image canvas width. @@ -158,7 +160,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { @return Whether succeed. */ -- (BOOL)updateData:(NSData *)data final:(BOOL)final; +- (BOOL)updateData:(nullable NSData *)data final:(BOOL)final; /** Convenience method to create a decoder with specified data. @@ -166,7 +168,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { @param scale Image's scale. @return A new decoder, or nil if an error occurs. */ -+ (instancetype)decoderWithData:(NSData *)data scale:(CGFloat)scale; ++ (nullable instancetype)decoderWithData:(NSData *)data scale:(CGFloat)scale; /** Decodes and returns a frame from a specified index. @@ -175,7 +177,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { If NO, it will try to returns the original frame data without blend. @return A new frame with image, or nil if an error occurs. */ -- (YYImageFrame *)frameAtIndex:(NSUInteger)index decodeForDisplay:(BOOL)decodeForDisplay; +- (nullable YYImageFrame *)frameAtIndex:(NSUInteger)index decodeForDisplay:(BOOL)decodeForDisplay; /** Returns the frame duration from a specified index. @@ -191,13 +193,13 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { @param index Frame image index (zero-based). @return The ImageIO frame property. */ -- (NSDictionary *)framePropertiesAtIndex:(NSUInteger)index; +- (nullable NSDictionary *)framePropertiesAtIndex:(NSUInteger)index; /** Returns the image's properties. See "CGImageProperties.h" in ImageIO.framework for more information. */ -- (NSDictionary *)imageProperties; +- (nullable NSDictionary *)imageProperties; @end @@ -231,10 +233,10 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { */ @interface YYImageEncoder : NSObject -@property (nonatomic, readonly) YYImageType type; ///< Image type. -@property (nonatomic, assign) NSUInteger loopCount; ///< Loop count, 0 means infinit, only available for GIF/APNG/WebP. -@property (nonatomic, assign) BOOL lossless; ///< Lossless, only available for WebP. -@property (nonatomic, assign) CGFloat quality; ///< Compress quality, 0.0~1.0, only available for JPG/JP2/WebP. +@property (nonatomic, readonly) YYImageType type; ///< Image type. +@property (nonatomic) NSUInteger loopCount; ///< Loop count, 0 means infinit, only available for GIF/APNG/WebP. +@property (nonatomic) BOOL lossless; ///< Lossless, only available for WebP. +@property (nonatomic) CGFloat quality; ///< Compress quality, 0.0~1.0, only available for JPG/JP2/WebP. - (instancetype)init UNAVAILABLE_ATTRIBUTE; + (instancetype)new UNAVAILABLE_ATTRIBUTE; @@ -244,7 +246,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { @param type Image type. @return A new encoder, or nil if an error occurs. */ -- (instancetype)initWithType:(YYImageType)type NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithType:(YYImageType)type NS_DESIGNATED_INITIALIZER; /** Add an image to encoder. @@ -271,7 +273,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { Encodes the image and returns the image data. @return The image data, or nil if an error occurs. */ -- (NSData *)encode; +- (nullable NSData *)encode; /** Encodes the image to a file. @@ -287,7 +289,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { @param quality Image quality, 0.0~1.0. @return The image data, or nil if an error occurs. */ -+ (NSData *)encodeImage:(UIImage *)image type:(YYImageType)type quality:(CGFloat)quality; ++ (nullable NSData *)encodeImage:(UIImage *)image type:(YYImageType)type quality:(CGFloat)quality; /** Convenience method to encode image from a decoder. @@ -296,7 +298,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { @param quality Image quality, 0.0~1.0. @return The image data, or nil if an error occurs. */ -+ (NSData *)encodeImageWithDecoder:(YYImageDecoder *)decoder type:(YYImageType)type quality:(CGFloat)quality; ++ (nullable NSData *)encodeImageWithDecoder:(YYImageDecoder *)decoder type:(YYImageType)type quality:(CGFloat)quality; @end @@ -319,7 +321,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { Wherher the image can be display on screen without additional decoding. @warning It just a hint for your code, change it has no other effect. */ -@property (nonatomic, assign) BOOL yy_isDecodedForDisplay; +@property (nonatomic) BOOL yy_isDecodedForDisplay; /** Saves this image to iOS Photos Album. @@ -332,7 +334,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { assetURL: An URL that identifies the saved image file. If the image is not saved, assetURL is nil. error: If the image is not saved, an error object that describes the reason for failure, otherwise nil. */ -- (void)yy_saveToAlbumWithCompletionBlock:(void(^)(NSURL *assetURL, NSError *error))completionBlock; +- (void)yy_saveToAlbumWithCompletionBlock:(nullable void(^)(NSURL * _Nullable assetURL, NSError * _Nullable error))completionBlock; /** Return a 'best' data representation for this image. @@ -343,7 +345,7 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { @return Image data, or nil if an error occurs. */ -- (NSData *)yy_imageDataRepresentation; +- (nullable NSData *)yy_imageDataRepresentation; @end @@ -355,13 +357,13 @@ typedef NS_ENUM(NSUInteger, YYImageBlendOperation) { CG_EXTERN YYImageType YYImageDetectType(CFDataRef data); /// Convert YYImageType to UTI (such as kUTTypeJPEG). -CG_EXTERN CFStringRef YYImageTypeToUTType(YYImageType type); +CG_EXTERN CFStringRef _Nullable YYImageTypeToUTType(YYImageType type); /// Convert UTI (such as kUTTypeJPEG) to YYImageType. CG_EXTERN YYImageType YYImageTypeFromUTType(CFStringRef uti); /// Get image type's file extension (such as @"jpg"). -CG_EXTERN NSString *YYImageTypeGetExtension(YYImageType type); +CG_EXTERN NSString *_Nullable YYImageTypeGetExtension(YYImageType type); @@ -402,7 +404,7 @@ CG_EXTERN NSInteger YYUIImageOrientationToEXIFValue(UIImageOrientation orientati @return A decoded image, or NULL if an error occurs. */ -CG_EXTERN CGImageRef YYCGImageCreateDecodedCopy(CGImageRef imageRef, BOOL decodeForDisplay); +CG_EXTERN CGImageRef _Nullable YYCGImageCreateDecodedCopy(CGImageRef imageRef, BOOL decodeForDisplay); /** Create an image copy with an orientation. @@ -412,9 +414,9 @@ CG_EXTERN CGImageRef YYCGImageCreateDecodedCopy(CGImageRef imageRef, BOOL decode @param destBitmapInfo Destimation image bitmap, only support 32bit format (such as ARGB8888). @return A new image, or NULL if an error occurs. */ -CG_EXTERN CGImageRef YYCGImageCreateCopyWithOrientation(CGImageRef imageRef, - UIImageOrientation orientation, - CGBitmapInfo destBitmapInfo); +CG_EXTERN CGImageRef _Nullable YYCGImageCreateCopyWithOrientation(CGImageRef imageRef, + UIImageOrientation orientation, + CGBitmapInfo destBitmapInfo); /** Create an image copy with CGAffineTransform. @@ -425,10 +427,10 @@ CG_EXTERN CGImageRef YYCGImageCreateCopyWithOrientation(CGImageRef imageRef, @param destBitmapInfo Destimation image bitmap, only support 32bit format (such as ARGB8888). @return A new image, or NULL if an error occurs. */ -CG_EXTERN CGImageRef YYCGImageCreateAffineTransformCopy(CGImageRef imageRef, - CGAffineTransform transform, - CGSize destSize, - CGBitmapInfo destBitmapInfo); +CG_EXTERN CGImageRef _Nullable YYCGImageCreateAffineTransformCopy(CGImageRef imageRef, + CGAffineTransform transform, + CGSize destSize, + CGBitmapInfo destBitmapInfo); /** Encode an image to data with CGImageDestination. @@ -438,7 +440,7 @@ CG_EXTERN CGImageRef YYCGImageCreateAffineTransformCopy(CGImageRef imageRef, @param quality The quality (0.0~1.0) @return A new image data, or nil if an error occurs. */ -CG_EXTERN CFDataRef YYCGImageCreateEncodedData(CGImageRef imageRef, YYImageType type, CGFloat quality); +CG_EXTERN CFDataRef _Nullable YYCGImageCreateEncodedData(CGImageRef imageRef, YYImageType type, CGFloat quality); /** @@ -468,12 +470,11 @@ CG_EXTERN NSUInteger YYImageGetWebPFrameCount(CFDataRef webpData); (speed down, and may lose some details). @return The decoded image, or NULL if an error occurs. */ -CG_EXTERN CGImageRef YYCGImageCreateWithWebPData(CFDataRef webpData, - BOOL decodeForDisplay, - BOOL useThreads, - BOOL bypassFiltering, - BOOL noFancyUpsampling); - +CG_EXTERN CGImageRef _Nullable YYCGImageCreateWithWebPData(CFDataRef webpData, + BOOL decodeForDisplay, + BOOL useThreads, + BOOL bypassFiltering, + BOOL noFancyUpsampling); typedef NS_ENUM(NSUInteger, YYImagePreset) { YYImagePresetDefault = 0, ///< default preset. @@ -495,8 +496,10 @@ typedef NS_ENUM(NSUInteger, YYImagePreset) { @param preset Preset for different image type, default is YYImagePresetDefault. @return WebP data, or nil if an error occurs. */ -CG_EXTERN CFDataRef YYCGImageCreateEncodedWebPData(CGImageRef imageRef, - BOOL lossless, - CGFloat quality, - int compressLevel, - YYImagePreset preset); +CG_EXTERN CFDataRef _Nullable YYCGImageCreateEncodedWebPData(CGImageRef imageRef, + BOOL lossless, + CGFloat quality, + int compressLevel, + YYImagePreset preset); + +NS_ASSUME_NONNULL_END diff --git a/Demo/YYTextDemo/YYImage/YYImageCoder.m b/Demo/YYTextDemo/YYImage/YYImageCoder.m index 46698b2f..feedd439 100644 --- a/Demo/YYTextDemo/YYImage/YYImageCoder.m +++ b/Demo/YYTextDemo/YYImage/YYImageCoder.m @@ -1399,7 +1399,8 @@ Call WebPDecode() on a multi-frame webp data will get an error (VP8_STATUS_UNSUP config.output.u.RGBA.stride = (int)bytesPerRow; config.output.u.RGBA.size = destLength; - if (WebPDecode(payload, payloadSize, &config) != VP8_STATUS_OK) goto fail; + VP8StatusCode result = WebPDecode(payload, payloadSize, &config); + if ((result != VP8_STATUS_OK) && (result != VP8_STATUS_NOT_ENOUGH_DATA)) goto fail; if (iter.x_offset != 0 || iter.y_offset != 0) { void *tmp = calloc(1, destLength); @@ -2150,7 +2151,8 @@ - (CGImageRef)_newUnblendedImageAtIndex:(NSUInteger)index config.output.u.RGBA.rgba = pixels; config.output.u.RGBA.stride = (int)bytesPerRow; config.output.u.RGBA.size = length; - if (WebPDecode(payload, payloadSize, &config) != VP8_STATUS_OK) { // decode + VP8StatusCode result = WebPDecode(payload, payloadSize, &config); // decode + if ((result != VP8_STATUS_OK) && (result != VP8_STATUS_NOT_ENOUGH_DATA)) { WebPDemuxReleaseIterator(&iter); free(pixels); return NULL; @@ -2415,27 +2417,38 @@ - (void)_encodeImageWithDestination:(CGImageDestinationRef)destination imageCoun } for (int i = 0; i < count; i++) { - id imageSrc = _images[i]; - NSDictionary *frameProperty = NULL; - if (_type == YYImageTypeGIF && count > 1) { - frameProperty = @{(NSString *)kCGImagePropertyGIFDictionary : @{(NSString *) kCGImagePropertyGIFDelayTime:_durations[i]}}; - } else { - frameProperty = @{(id)kCGImageDestinationLossyCompressionQuality : @(_quality)}; - } - - if ([imageSrc isKindOfClass:[UIImage class]]) { - CGImageDestinationAddImage(destination, ((UIImage *)imageSrc).CGImage, (CFDictionaryRef)frameProperty); - } else if ([imageSrc isKindOfClass:[NSURL class]]) { - CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)imageSrc, NULL); - if (source) { - CGImageDestinationAddImageFromSource(destination, source, i, (CFDictionaryRef)frameProperty); - CFRelease(source); + @autoreleasepool { + id imageSrc = _images[i]; + NSDictionary *frameProperty = NULL; + if (_type == YYImageTypeGIF && count > 1) { + frameProperty = @{(NSString *)kCGImagePropertyGIFDictionary : @{(NSString *) kCGImagePropertyGIFDelayTime:_durations[i]}}; + } else { + frameProperty = @{(id)kCGImageDestinationLossyCompressionQuality : @(_quality)}; } - } else if ([imageSrc isKindOfClass:[NSData class]]) { - CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imageSrc, NULL); - if (source) { - CGImageDestinationAddImageFromSource(destination, source, i, (CFDictionaryRef)frameProperty); - CFRelease(source); + + if ([imageSrc isKindOfClass:[UIImage class]]) { + UIImage *image = imageSrc; + if (image.imageOrientation != UIImageOrientationUp && image.CGImage) { + CGBitmapInfo info = CGImageGetBitmapInfo(image.CGImage) | CGImageGetAlphaInfo(image.CGImage); + CGImageRef rotated = YYCGImageCreateCopyWithOrientation(image.CGImage, image.imageOrientation, info); + if (rotated) { + image = [UIImage imageWithCGImage:rotated]; + CFRelease(rotated); + } + } + if (image.CGImage) CGImageDestinationAddImage(destination, ((UIImage *)imageSrc).CGImage, (CFDictionaryRef)frameProperty); + } else if ([imageSrc isKindOfClass:[NSURL class]]) { + CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)imageSrc, NULL); + if (source) { + CGImageDestinationAddImageFromSource(destination, source, i, (CFDictionaryRef)frameProperty); + CFRelease(source); + } + } else if ([imageSrc isKindOfClass:[NSData class]]) { + CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imageSrc, NULL); + if (source) { + CGImageDestinationAddImageFromSource(destination, source, i, (CFDictionaryRef)frameProperty); + CFRelease(source); + } } } } @@ -2724,7 +2737,7 @@ + (NSData *)encodeImage:(UIImage *)image type:(YYImageType)type quality:(CGFloat } + (NSData *)encodeImageWithDecoder:(YYImageDecoder *)decoder type:(YYImageType)type quality:(CGFloat)quality { - if (!decoder || !decoder.frameCount == 0) return nil; + if (!decoder || decoder.frameCount == 0) return nil; YYImageEncoder *encoder = [[YYImageEncoder alloc] initWithType:type]; encoder.quality = quality; for (int i = 0; i < decoder.frameCount; i++) { diff --git a/Demo/YYTextDemo/YYImage/YYSpriteSheetImage.h b/Demo/YYTextDemo/YYImage/YYSpriteSheetImage.h index 403168ca..403bbf57 100644 --- a/Demo/YYTextDemo/YYImage/YYSpriteSheetImage.h +++ b/Demo/YYTextDemo/YYImage/YYSpriteSheetImage.h @@ -19,6 +19,8 @@ #import "YYAnimatedImageView.h" #endif +NS_ASSUME_NONNULL_BEGIN + /** An image to display sprite sheet animation. @@ -79,13 +81,13 @@ @return An image object, or nil if an error occurs. */ -- (instancetype)initWithSpriteSheetImage:(UIImage *)image - contentRects:(NSArray *)contentRects - frameDurations:(NSArray *)frameDurations - loopCount:(NSUInteger)loopCount; +- (nullable instancetype)initWithSpriteSheetImage:(UIImage *)image + contentRects:(NSArray *)contentRects + frameDurations:(NSArray *)frameDurations + loopCount:(NSUInteger)loopCount; -@property (nonatomic, readonly) NSArray *contentRects; -@property (nonatomic, readonly) NSArray *frameDurations; +@property (nonatomic, readonly) NSArray *contentRects; +@property (nonatomic, readonly) NSArray *frameDurations; @property (nonatomic, readonly) NSUInteger loopCount; /** @@ -98,3 +100,5 @@ - (CGRect)contentsRectForCALayerAtIndex:(NSUInteger)index; @end + +NS_ASSUME_NONNULL_END