From 7b02207537d35bfa1714bf8beafc921f717d100a Mon Sep 17 00:00:00 2001
From: 单军华
Date: Wed, 11 Jul 2018 10:47:42 +0800
Subject: [PATCH] 首次上传

---
 screendisplay/Pods/SDWebImage/SDWebImage/SDWebImageImageIOCoder.m |  507 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 507 insertions(+), 0 deletions(-)

diff --git a/screendisplay/Pods/SDWebImage/SDWebImage/SDWebImageImageIOCoder.m b/screendisplay/Pods/SDWebImage/SDWebImage/SDWebImageImageIOCoder.m
new file mode 100644
index 0000000..0447ed3
--- /dev/null
+++ b/screendisplay/Pods/SDWebImage/SDWebImage/SDWebImageImageIOCoder.m
@@ -0,0 +1,507 @@
+/*
+ * This file is part of the SDWebImage package.
+ * (c) Olivier Poitrey <rs@dailymotion.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+#import "SDWebImageImageIOCoder.h"
+#import "SDWebImageCoderHelper.h"
+#import "NSImage+WebCache.h"
+#import <ImageIO/ImageIO.h>
+#import "NSData+ImageContentType.h"
+
+#if SD_UIKIT || SD_WATCH
+static const size_t kBytesPerPixel = 4;
+static const size_t kBitsPerComponent = 8;
+
+/*
+ * Defines the maximum size in MB of the decoded image when the flag `SDWebImageScaleDownLargeImages` is set
+ * Suggested value for iPad1 and iPhone 3GS: 60.
+ * Suggested value for iPad2 and iPhone 4: 120.
+ * Suggested value for iPhone 3G and iPod 2 and earlier devices: 30.
+ */
+static const CGFloat kDestImageSizeMB = 60.0f;
+
+/*
+ * Defines the maximum size in MB of a tile used to decode image when the flag `SDWebImageScaleDownLargeImages` is set
+ * Suggested value for iPad1 and iPhone 3GS: 20.
+ * Suggested value for iPad2 and iPhone 4: 40.
+ * Suggested value for iPhone 3G and iPod 2 and earlier devices: 10.
+ */
+static const CGFloat kSourceImageTileSizeMB = 20.0f;
+
+static const CGFloat kBytesPerMB = 1024.0f * 1024.0f;
+static const CGFloat kPixelsPerMB = kBytesPerMB / kBytesPerPixel;
+static const CGFloat kDestTotalPixels = kDestImageSizeMB * kPixelsPerMB;
+static const CGFloat kTileTotalPixels = kSourceImageTileSizeMB * kPixelsPerMB;
+
+static const CGFloat kDestSeemOverlap = 2.0f;   // the numbers of pixels to overlap the seems where tiles meet.
+#endif
+
+@implementation SDWebImageImageIOCoder {
+        size_t _width, _height;
+#if SD_UIKIT || SD_WATCH
+        UIImageOrientation _orientation;
+#endif
+        CGImageSourceRef _imageSource;
+}
+
+- (void)dealloc {
+    if (_imageSource) {
+        CFRelease(_imageSource);
+        _imageSource = NULL;
+    }
+}
+
++ (instancetype)sharedCoder {
+    static SDWebImageImageIOCoder *coder;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        coder = [[SDWebImageImageIOCoder alloc] init];
+    });
+    return coder;
+}
+
+#pragma mark - Decode
+- (BOOL)canDecodeFromData:(nullable NSData *)data {
+    switch ([NSData sd_imageFormatForImageData:data]) {
+        case SDImageFormatWebP:
+            // Do not support WebP decoding
+            return NO;
+        case SDImageFormatHEIC:
+            // Check HEIC decoding compatibility
+            return [[self class] canDecodeFromHEICFormat];
+        default:
+            return YES;
+    }
+}
+
+- (BOOL)canIncrementallyDecodeFromData:(NSData *)data {
+    switch ([NSData sd_imageFormatForImageData:data]) {
+        case SDImageFormatWebP:
+            // Do not support WebP progressive decoding
+            return NO;
+        case SDImageFormatHEIC:
+            // Check HEIC decoding compatibility
+            return [[self class] canDecodeFromHEICFormat];
+        default:
+            return YES;
+    }
+}
+
+- (UIImage *)decodedImageWithData:(NSData *)data {
+    if (!data) {
+        return nil;
+    }
+    
+    UIImage *image = [[UIImage alloc] initWithData:data];
+    
+    return image;
+}
+
+- (UIImage *)incrementallyDecodedImageWithData:(NSData *)data finished:(BOOL)finished {
+    if (!_imageSource) {
+        _imageSource = CGImageSourceCreateIncremental(NULL);
+    }
+    UIImage *image;
+    
+    // The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/
+    // Thanks to the author @Nyx0uf
+    
+    // Update the data source, we must pass ALL the data, not just the new bytes
+    CGImageSourceUpdateData(_imageSource, (__bridge CFDataRef)data, finished);
+    
+    if (_width + _height == 0) {
+        CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(_imageSource, 0, NULL);
+        if (properties) {
+            NSInteger orientationValue = 1;
+            CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);
+            if (val) CFNumberGetValue(val, kCFNumberLongType, &_height);
+            val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);
+            if (val) CFNumberGetValue(val, kCFNumberLongType, &_width);
+            val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation);
+            if (val) CFNumberGetValue(val, kCFNumberNSIntegerType, &orientationValue);
+            CFRelease(properties);
+            
+            // When we draw to Core Graphics, we lose orientation information,
+            // which means the image below born of initWithCGIImage will be
+            // oriented incorrectly sometimes. (Unlike the image born of initWithData
+            // in didCompleteWithError.) So save it here and pass it on later.
+#if SD_UIKIT || SD_WATCH
+            _orientation = [SDWebImageCoderHelper imageOrientationFromEXIFOrientation:orientationValue];
+#endif
+        }
+    }
+    
+    if (_width + _height > 0) {
+        // Create the image
+        CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(_imageSource, 0, NULL);
+        
+        if (partialImageRef) {
+#if SD_UIKIT || SD_WATCH
+            image = [[UIImage alloc] initWithCGImage:partialImageRef scale:1 orientation:_orientation];
+#elif SD_MAC
+            image = [[UIImage alloc] initWithCGImage:partialImageRef size:NSZeroSize];
+#endif
+            CGImageRelease(partialImageRef);
+        }
+    }
+    
+    if (finished) {
+        if (_imageSource) {
+            CFRelease(_imageSource);
+            _imageSource = NULL;
+        }
+    }
+    
+    return image;
+}
+
+- (UIImage *)decompressedImageWithImage:(UIImage *)image
+                                   data:(NSData *__autoreleasing  _Nullable *)data
+                                options:(nullable NSDictionary<NSString*, NSObject*>*)optionsDict {
+#if SD_MAC
+    return image;
+#endif
+#if SD_UIKIT || SD_WATCH
+    BOOL shouldScaleDown = NO;
+    if (optionsDict != nil) {
+        NSNumber *scaleDownLargeImagesOption = nil;
+        if ([optionsDict[SDWebImageCoderScaleDownLargeImagesKey] isKindOfClass:[NSNumber class]]) {
+            scaleDownLargeImagesOption = (NSNumber *)optionsDict[SDWebImageCoderScaleDownLargeImagesKey];
+        }
+        if (scaleDownLargeImagesOption != nil) {
+            shouldScaleDown = [scaleDownLargeImagesOption boolValue];
+        }
+    }
+    if (!shouldScaleDown) {
+        return [self sd_decompressedImageWithImage:image];
+    } else {
+        UIImage *scaledDownImage = [self sd_decompressedAndScaledDownImageWithImage:image];
+        if (scaledDownImage && !CGSizeEqualToSize(scaledDownImage.size, image.size)) {
+            // if the image is scaled down, need to modify the data pointer as well
+            SDImageFormat format = [NSData sd_imageFormatForImageData:*data];
+            NSData *imageData = [self encodedDataWithImage:scaledDownImage format:format];
+            if (imageData) {
+                *data = imageData;
+            }
+        }
+        return scaledDownImage;
+    }
+#endif
+}
+
+#if SD_UIKIT || SD_WATCH
+- (nullable UIImage *)sd_decompressedImageWithImage:(nullable UIImage *)image {
+    if (![[self class] shouldDecodeImage:image]) {
+        return image;
+    }
+    
+    // autorelease the bitmap context and all vars to help system to free memory when there are memory warning.
+    // on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory];
+    @autoreleasepool{
+        
+        CGImageRef imageRef = image.CGImage;
+        // device color space
+        CGColorSpaceRef colorspaceRef = SDCGColorSpaceGetDeviceRGB();
+        BOOL hasAlpha = SDCGImageRefContainsAlpha(imageRef);
+        // iOS display alpha info (BRGA8888/BGRX8888)
+        CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;
+        bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
+        
+        size_t width = CGImageGetWidth(imageRef);
+        size_t height = CGImageGetHeight(imageRef);
+        
+        // kCGImageAlphaNone is not supported in CGBitmapContextCreate.
+        // Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
+        // to create bitmap graphics contexts without alpha info.
+        CGContextRef context = CGBitmapContextCreate(NULL,
+                                                     width,
+                                                     height,
+                                                     kBitsPerComponent,
+                                                     0,
+                                                     colorspaceRef,
+                                                     bitmapInfo);
+        if (context == NULL) {
+            return image;
+        }
+        
+        // Draw the image into the context and retrieve the new bitmap image without alpha
+        CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
+        CGImageRef imageRefWithoutAlpha = CGBitmapContextCreateImage(context);
+        UIImage *imageWithoutAlpha = [[UIImage alloc] initWithCGImage:imageRefWithoutAlpha scale:image.scale orientation:image.imageOrientation];
+        CGContextRelease(context);
+        CGImageRelease(imageRefWithoutAlpha);
+        
+        return imageWithoutAlpha;
+    }
+}
+
+- (nullable UIImage *)sd_decompressedAndScaledDownImageWithImage:(nullable UIImage *)image {
+    if (![[self class] shouldDecodeImage:image]) {
+        return image;
+    }
+    
+    if (![[self class] shouldScaleDownImage:image]) {
+        return [self sd_decompressedImageWithImage:image];
+    }
+    
+    CGContextRef destContext;
+    
+    // autorelease the bitmap context and all vars to help system to free memory when there are memory warning.
+    // on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory];
+    @autoreleasepool {
+        CGImageRef sourceImageRef = image.CGImage;
+        
+        CGSize sourceResolution = CGSizeZero;
+        sourceResolution.width = CGImageGetWidth(sourceImageRef);
+        sourceResolution.height = CGImageGetHeight(sourceImageRef);
+        float sourceTotalPixels = sourceResolution.width * sourceResolution.height;
+        // Determine the scale ratio to apply to the input image
+        // that results in an output image of the defined size.
+        // see kDestImageSizeMB, and how it relates to destTotalPixels.
+        float imageScale = kDestTotalPixels / sourceTotalPixels;
+        CGSize destResolution = CGSizeZero;
+        destResolution.width = (int)(sourceResolution.width*imageScale);
+        destResolution.height = (int)(sourceResolution.height*imageScale);
+        
+        // device color space
+        CGColorSpaceRef colorspaceRef = SDCGColorSpaceGetDeviceRGB();
+        BOOL hasAlpha = SDCGImageRefContainsAlpha(sourceImageRef);
+        // iOS display alpha info (BGRA8888/BGRX8888)
+        CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;
+        bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst;
+        
+        // kCGImageAlphaNone is not supported in CGBitmapContextCreate.
+        // Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
+        // to create bitmap graphics contexts without alpha info.
+        destContext = CGBitmapContextCreate(NULL,
+                                            destResolution.width,
+                                            destResolution.height,
+                                            kBitsPerComponent,
+                                            0,
+                                            colorspaceRef,
+                                            bitmapInfo);
+        
+        if (destContext == NULL) {
+            return image;
+        }
+        CGContextSetInterpolationQuality(destContext, kCGInterpolationHigh);
+        
+        // Now define the size of the rectangle to be used for the
+        // incremental blits from the input image to the output image.
+        // we use a source tile width equal to the width of the source
+        // image due to the way that iOS retrieves image data from disk.
+        // iOS must decode an image from disk in full width 'bands', even
+        // if current graphics context is clipped to a subrect within that
+        // band. Therefore we fully utilize all of the pixel data that results
+        // from a decoding opertion by achnoring our tile size to the full
+        // width of the input image.
+        CGRect sourceTile = CGRectZero;
+        sourceTile.size.width = sourceResolution.width;
+        // The source tile height is dynamic. Since we specified the size
+        // of the source tile in MB, see how many rows of pixels high it
+        // can be given the input image width.
+        sourceTile.size.height = (int)(kTileTotalPixels / sourceTile.size.width );
+        sourceTile.origin.x = 0.0f;
+        // The output tile is the same proportions as the input tile, but
+        // scaled to image scale.
+        CGRect destTile;
+        destTile.size.width = destResolution.width;
+        destTile.size.height = sourceTile.size.height * imageScale;
+        destTile.origin.x = 0.0f;
+        // The source seem overlap is proportionate to the destination seem overlap.
+        // this is the amount of pixels to overlap each tile as we assemble the ouput image.
+        float sourceSeemOverlap = (int)((kDestSeemOverlap/destResolution.height)*sourceResolution.height);
+        CGImageRef sourceTileImageRef;
+        // calculate the number of read/write operations required to assemble the
+        // output image.
+        int iterations = (int)( sourceResolution.height / sourceTile.size.height );
+        // If tile height doesn't divide the image height evenly, add another iteration
+        // to account for the remaining pixels.
+        int remainder = (int)sourceResolution.height % (int)sourceTile.size.height;
+        if(remainder) {
+            iterations++;
+        }
+        // Add seem overlaps to the tiles, but save the original tile height for y coordinate calculations.
+        float sourceTileHeightMinusOverlap = sourceTile.size.height;
+        sourceTile.size.height += sourceSeemOverlap;
+        destTile.size.height += kDestSeemOverlap;
+        for( int y = 0; y < iterations; ++y ) {
+            @autoreleasepool {
+                sourceTile.origin.y = y * sourceTileHeightMinusOverlap + sourceSeemOverlap;
+                destTile.origin.y = destResolution.height - (( y + 1 ) * sourceTileHeightMinusOverlap * imageScale + kDestSeemOverlap);
+                sourceTileImageRef = CGImageCreateWithImageInRect( sourceImageRef, sourceTile );
+                if( y == iterations - 1 && remainder ) {
+                    float dify = destTile.size.height;
+                    destTile.size.height = CGImageGetHeight( sourceTileImageRef ) * imageScale;
+                    dify -= destTile.size.height;
+                    destTile.origin.y += dify;
+                }
+                CGContextDrawImage( destContext, destTile, sourceTileImageRef );
+                CGImageRelease( sourceTileImageRef );
+            }
+        }
+        
+        CGImageRef destImageRef = CGBitmapContextCreateImage(destContext);
+        CGContextRelease(destContext);
+        if (destImageRef == NULL) {
+            return image;
+        }
+        UIImage *destImage = [[UIImage alloc] initWithCGImage:destImageRef scale:image.scale orientation:image.imageOrientation];
+        CGImageRelease(destImageRef);
+        if (destImage == nil) {
+            return image;
+        }
+        return destImage;
+    }
+}
+#endif
+
+#pragma mark - Encode
+- (BOOL)canEncodeToFormat:(SDImageFormat)format {
+    switch (format) {
+        case SDImageFormatWebP:
+            // Do not support WebP encoding
+            return NO;
+        case SDImageFormatHEIC:
+            // Check HEIC encoding compatibility
+            return [[self class] canEncodeToHEICFormat];
+        default:
+            return YES;
+    }
+}
+
+- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format {
+    if (!image) {
+        return nil;
+    }
+    
+    if (format == SDImageFormatUndefined) {
+        BOOL hasAlpha = SDCGImageRefContainsAlpha(image.CGImage);
+        if (hasAlpha) {
+            format = SDImageFormatPNG;
+        } else {
+            format = SDImageFormatJPEG;
+        }
+    }
+    
+    NSMutableData *imageData = [NSMutableData data];
+    CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:format];
+    
+    // Create an image destination.
+    CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, 1, NULL);
+    if (!imageDestination) {
+        // Handle failure.
+        return nil;
+    }
+    
+    NSMutableDictionary *properties = [NSMutableDictionary dictionary];
+#if SD_UIKIT || SD_WATCH
+    NSInteger exifOrientation = [SDWebImageCoderHelper exifOrientationFromImageOrientation:image.imageOrientation];
+    [properties setValue:@(exifOrientation) forKey:(__bridge_transfer NSString *)kCGImagePropertyOrientation];
+#endif
+    
+    // Add your image to the destination.
+    CGImageDestinationAddImage(imageDestination, image.CGImage, (__bridge CFDictionaryRef)properties);
+    
+    // Finalize the destination.
+    if (CGImageDestinationFinalize(imageDestination) == NO) {
+        // Handle failure.
+        imageData = nil;
+    }
+    
+    CFRelease(imageDestination);
+    
+    return [imageData copy];
+}
+
+#pragma mark - Helper
++ (BOOL)shouldDecodeImage:(nullable UIImage *)image {
+    // Prevent "CGBitmapContextCreateImage: invalid context 0x0" error
+    if (image == nil) {
+        return NO;
+    }
+    
+    // do not decode animated images
+    if (image.images != nil) {
+        return NO;
+    }
+    
+    return YES;
+}
+
++ (BOOL)canDecodeFromHEICFormat {
+    static BOOL canDecode = NO;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunguarded-availability"
+#if TARGET_OS_SIMULATOR || SD_WATCH
+        canDecode = NO;
+#elif SD_MAC
+        NSProcessInfo *processInfo = [NSProcessInfo processInfo];
+        if ([processInfo respondsToSelector:@selector(operatingSystemVersion)]) {
+            // macOS 10.13+
+            canDecode = processInfo.operatingSystemVersion.minorVersion >= 13;
+        } else {
+            canDecode = NO;
+        }
+#elif SD_UIKIT
+        NSProcessInfo *processInfo = [NSProcessInfo processInfo];
+        if ([processInfo respondsToSelector:@selector(operatingSystemVersion)]) {
+            // iOS 11+ && tvOS 11+
+            canDecode = processInfo.operatingSystemVersion.majorVersion >= 11;
+        } else {
+            canDecode = NO;
+        }
+#endif
+#pragma clang diagnostic pop
+    });
+    return canDecode;
+}
+
++ (BOOL)canEncodeToHEICFormat {
+    static BOOL canEncode = NO;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        NSMutableData *imageData = [NSMutableData data];
+        CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:SDImageFormatHEIC];
+        
+        // Create an image destination.
+        CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, 1, NULL);
+        if (!imageDestination) {
+            // Can't encode to HEIC
+            canEncode = NO;
+        } else {
+            // Can encode to HEIC
+            CFRelease(imageDestination);
+            canEncode = YES;
+        }
+    });
+    return canEncode;
+}
+
+#if SD_UIKIT || SD_WATCH
++ (BOOL)shouldScaleDownImage:(nonnull UIImage *)image {
+    BOOL shouldScaleDown = YES;
+    
+    CGImageRef sourceImageRef = image.CGImage;
+    CGSize sourceResolution = CGSizeZero;
+    sourceResolution.width = CGImageGetWidth(sourceImageRef);
+    sourceResolution.height = CGImageGetHeight(sourceImageRef);
+    float sourceTotalPixels = sourceResolution.width * sourceResolution.height;
+    float imageScale = kDestTotalPixels / sourceTotalPixels;
+    if (imageScale < 1) {
+        shouldScaleDown = YES;
+    } else {
+        shouldScaleDown = NO;
+    }
+    
+    return shouldScaleDown;
+}
+#endif
+
+@end

--
Gitblit v1.8.0