From 7b02207537d35bfa1714bf8beafc921f717d100a Mon Sep 17 00:00:00 2001 From: 单军华 Date: Wed, 11 Jul 2018 10:47:42 +0800 Subject: [PATCH] 首次上传 --- screendisplay/Pods/YYImage/YYImage/YYImage.m | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 254 insertions(+), 0 deletions(-) diff --git a/screendisplay/Pods/YYImage/YYImage/YYImage.m b/screendisplay/Pods/YYImage/YYImage/YYImage.m new file mode 100755 index 0000000..aaea939 --- /dev/null +++ b/screendisplay/Pods/YYImage/YYImage/YYImage.m @@ -0,0 +1,254 @@ +// +// YYImage.m +// YYImage <https://github.com/ibireme/YYImage> +// +// Created by ibireme on 14/10/20. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "YYImage.h" + +/** + An array of NSNumber objects, shows the best order for path scale search. + e.g. iPhone3GS:@[@1,@2,@3] iPhone5:@[@2,@3,@1] iPhone6 Plus:@[@3,@2,@1] + */ +static NSArray *_NSBundlePreferredScales() { + static NSArray *scales; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + CGFloat screenScale = [UIScreen mainScreen].scale; + if (screenScale <= 1) { + scales = @[@1,@2,@3]; + } else if (screenScale <= 2) { + scales = @[@2,@3,@1]; + } else { + scales = @[@3,@2,@1]; + } + }); + return scales; +} + +/** + Add scale modifier to the file name (without path extension), + From @"name" to @"name@2x". + + e.g. + <table> + <tr><th>Before </th><th>After(scale:2)</th></tr> + <tr><td>"icon" </td><td>"icon@2x" </td></tr> + <tr><td>"icon " </td><td>"icon @2x" </td></tr> + <tr><td>"icon.top" </td><td>"icon.top@2x" </td></tr> + <tr><td>"/p/name" </td><td>"/p/name@2x" </td></tr> + <tr><td>"/path/" </td><td>"/path/" </td></tr> + </table> + + @param scale Resource scale. + @return String by add scale modifier, or just return if it's not end with file name. + */ +static NSString *_NSStringByAppendingNameScale(NSString *string, CGFloat scale) { + if (!string) return nil; + if (fabs(scale - 1) <= __FLT_EPSILON__ || string.length == 0 || [string hasSuffix:@"/"]) return string.copy; + return [string stringByAppendingFormat:@"@%@x", @(scale)]; +} + +/** + Return the path scale. + + e.g. + <table> + <tr><th>Path </th><th>Scale </th></tr> + <tr><td>"icon.png" </td><td>1 </td></tr> + <tr><td>"icon@2x.png" </td><td>2 </td></tr> + <tr><td>"icon@2.5x.png" </td><td>2.5 </td></tr> + <tr><td>"icon@2x" </td><td>1 </td></tr> + <tr><td>"icon@2x..png" </td><td>1 </td></tr> + <tr><td>"icon@2x.png/" </td><td>1 </td></tr> + </table> + */ +static CGFloat _NSStringPathScale(NSString *string) { + if (string.length == 0 || [string hasSuffix:@"/"]) return 1; + NSString *name = string.stringByDeletingPathExtension; + __block CGFloat scale = 1; + + NSRegularExpression *pattern = [NSRegularExpression regularExpressionWithPattern:@"@[0-9]+\\.?[0-9]*x$" options:NSRegularExpressionAnchorsMatchLines error:nil]; + [pattern enumerateMatchesInString:name options:kNilOptions range:NSMakeRange(0, name.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { + if (result.range.location >= 3) { + scale = [string substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)].doubleValue; + } + }]; + + return scale; +} + + +@implementation YYImage { + YYImageDecoder *_decoder; + NSArray *_preloadedFrames; + dispatch_semaphore_t _preloadedLock; + NSUInteger _bytesPerFrame; +} + ++ (YYImage *)imageNamed:(NSString *)name { + if (name.length == 0) return nil; + if ([name hasSuffix:@"/"]) return nil; + + NSString *res = name.stringByDeletingPathExtension; + NSString *ext = name.pathExtension; + NSString *path = nil; + CGFloat scale = 1; + + // If no extension, guess by system supported (same as UIImage). + NSArray *exts = ext.length > 0 ? @[ext] : @[@"", @"png", @"jpeg", @"jpg", @"gif", @"webp", @"apng"]; + NSArray *scales = _NSBundlePreferredScales(); + for (int s = 0; s < scales.count; s++) { + scale = ((NSNumber *)scales[s]).floatValue; + NSString *scaledName = _NSStringByAppendingNameScale(res, scale); + for (NSString *e in exts) { + path = [[NSBundle mainBundle] pathForResource:scaledName ofType:e]; + if (path) break; + } + if (path) break; + } + if (path.length == 0) return nil; + + NSData *data = [NSData dataWithContentsOfFile:path]; + if (data.length == 0) return nil; + + return [[self alloc] initWithData:data scale:scale]; +} + ++ (YYImage *)imageWithContentsOfFile:(NSString *)path { + return [[self alloc] initWithContentsOfFile:path]; +} + ++ (YYImage *)imageWithData:(NSData *)data { + return [[self alloc] initWithData:data]; +} + ++ (YYImage *)imageWithData:(NSData *)data scale:(CGFloat)scale { + return [[self alloc] initWithData:data scale:scale]; +} + +- (instancetype)initWithContentsOfFile:(NSString *)path { + NSData *data = [NSData dataWithContentsOfFile:path]; + return [self initWithData:data scale:_NSStringPathScale(path)]; +} + +- (instancetype)initWithData:(NSData *)data { + return [self initWithData:data scale:1]; +} + +- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale { + if (data.length == 0) return nil; + if (scale <= 0) scale = [UIScreen mainScreen].scale; + _preloadedLock = dispatch_semaphore_create(1); + @autoreleasepool { + YYImageDecoder *decoder = [YYImageDecoder decoderWithData:data scale:scale]; + YYImageFrame *frame = [decoder frameAtIndex:0 decodeForDisplay:YES]; + UIImage *image = frame.image; + if (!image) return nil; + self = [self initWithCGImage:image.CGImage scale:decoder.scale orientation:image.imageOrientation]; + if (!self) return nil; + _animatedImageType = decoder.type; + if (decoder.frameCount > 1) { + _decoder = decoder; + _bytesPerFrame = CGImageGetBytesPerRow(image.CGImage) * CGImageGetHeight(image.CGImage); + _animatedImageMemorySize = _bytesPerFrame * decoder.frameCount; + } + self.yy_isDecodedForDisplay = YES; + } + return self; +} + +- (NSData *)animatedImageData { + return _decoder.data; +} + +- (void)setPreloadAllAnimatedImageFrames:(BOOL)preloadAllAnimatedImageFrames { + if (_preloadAllAnimatedImageFrames != preloadAllAnimatedImageFrames) { + if (preloadAllAnimatedImageFrames && _decoder.frameCount > 0) { + NSMutableArray *frames = [NSMutableArray new]; + for (NSUInteger i = 0, max = _decoder.frameCount; i < max; i++) { + UIImage *img = [self animatedImageFrameAtIndex:i]; + if (img) { + [frames addObject:img]; + } else { + [frames addObject:[NSNull null]]; + } + } + dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER); + _preloadedFrames = frames; + dispatch_semaphore_signal(_preloadedLock); + } else { + dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER); + _preloadedFrames = nil; + dispatch_semaphore_signal(_preloadedLock); + } + } +} + +#pragma mark - protocol NSCoding + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + NSNumber *scale = [aDecoder decodeObjectForKey:@"YYImageScale"]; + NSData *data = [aDecoder decodeObjectForKey:@"YYImageData"]; + if (data.length) { + self = [self initWithData:data scale:scale.doubleValue]; + } else { + self = [super initWithCoder:aDecoder]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + if (_decoder.data.length) { + [aCoder encodeObject:@(self.scale) forKey:@"YYImageScale"]; + [aCoder encodeObject:_decoder.data forKey:@"YYImageData"]; + } else { + [super encodeWithCoder:aCoder]; // Apple use UIImagePNGRepresentation() to encode UIImage. + } +} + +#pragma mark - protocol YYAnimatedImage + +- (NSUInteger)animatedImageFrameCount { + return _decoder.frameCount; +} + +- (NSUInteger)animatedImageLoopCount { + return _decoder.loopCount; +} + +- (NSUInteger)animatedImageBytesPerFrame { + return _bytesPerFrame; +} + +- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index { + if (index >= _decoder.frameCount) return nil; + dispatch_semaphore_wait(_preloadedLock, DISPATCH_TIME_FOREVER); + UIImage *image = _preloadedFrames[index]; + dispatch_semaphore_signal(_preloadedLock); + if (image) return image == (id)[NSNull null] ? nil : image; + return [_decoder frameAtIndex:index decodeForDisplay:YES].image; +} + +- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index { + NSTimeInterval duration = [_decoder frameDurationAtIndex:index]; + + /* + http://opensource.apple.com/source/WebCore/WebCore-7600.1.25/platform/graphics/cg/ImageSourceCG.cpp + Many annoying ads specify a 0 duration to make an image flash as quickly as + possible. We follow Safari and Firefox's behavior and use a duration of 100 ms + for any frames that specify a duration of <= 10 ms. + See <rdar://problem/7689300> and <http://webkit.org/b/36082> for more information. + + See also: http://nullsleep.tumblr.com/post/16524517190/animated-gif-minimum-frame-delay-browser. + */ + if (duration < 0.011f) return 0.100f; + return duration; +} + +@end -- Gitblit v1.8.0