123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /*
- * 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 "SDImageCodersManager.h"
- #import "SDImageIOCoder.h"
- #import "SDImageGIFCoder.h"
- #import "SDImageAPNGCoder.h"
- #import "SDImageHEICCoder.h"
- #import "SDInternalMacros.h"
- @interface SDImageCodersManager ()
- @property (nonatomic, strong, nonnull) NSMutableArray<id<SDImageCoder>> *imageCoders;
- @end
- @implementation SDImageCodersManager {
- SD_LOCK_DECLARE(_codersLock);
- }
- + (nonnull instancetype)sharedManager {
- static dispatch_once_t once;
- static id instance;
- dispatch_once(&once, ^{
- instance = [self new];
- });
- return instance;
- }
- - (instancetype)init {
- if (self = [super init]) {
- // initialize with default coders
- _imageCoders = [NSMutableArray arrayWithArray:@[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]]];
- SD_LOCK_INIT(_codersLock);
- }
- return self;
- }
- - (NSArray<id<SDImageCoder>> *)coders {
- SD_LOCK(_codersLock);
- NSArray<id<SDImageCoder>> *coders = [_imageCoders copy];
- SD_UNLOCK(_codersLock);
- return coders;
- }
- - (void)setCoders:(NSArray<id<SDImageCoder>> *)coders {
- SD_LOCK(_codersLock);
- [_imageCoders removeAllObjects];
- if (coders.count) {
- [_imageCoders addObjectsFromArray:coders];
- }
- SD_UNLOCK(_codersLock);
- }
- #pragma mark - Coder IO operations
- - (void)addCoder:(nonnull id<SDImageCoder>)coder {
- if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {
- return;
- }
- SD_LOCK(_codersLock);
- [_imageCoders addObject:coder];
- SD_UNLOCK(_codersLock);
- }
- - (void)removeCoder:(nonnull id<SDImageCoder>)coder {
- if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {
- return;
- }
- SD_LOCK(_codersLock);
- [_imageCoders removeObject:coder];
- SD_UNLOCK(_codersLock);
- }
- #pragma mark - SDImageCoder
- - (BOOL)canDecodeFromData:(NSData *)data {
- NSArray<id<SDImageCoder>> *coders = self.coders;
- for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
- if ([coder canDecodeFromData:data]) {
- return YES;
- }
- }
- return NO;
- }
- - (BOOL)canEncodeToFormat:(SDImageFormat)format {
- NSArray<id<SDImageCoder>> *coders = self.coders;
- for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
- if ([coder canEncodeToFormat:format]) {
- return YES;
- }
- }
- return NO;
- }
- - (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options {
- if (!data) {
- return nil;
- }
- UIImage *image;
- NSArray<id<SDImageCoder>> *coders = self.coders;
- for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
- if ([coder canDecodeFromData:data]) {
- image = [coder decodedImageWithData:data options:options];
- break;
- }
- }
-
- return image;
- }
- - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(nullable SDImageCoderOptions *)options {
- if (!image) {
- return nil;
- }
- NSArray<id<SDImageCoder>> *coders = self.coders;
- for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
- if ([coder canEncodeToFormat:format]) {
- return [coder encodedDataWithImage:image format:format options:options];
- }
- }
- return nil;
- }
- - (NSData *)encodedDataWithFrames:(NSArray<SDImageFrame *> *)frames loopCount:(NSUInteger)loopCount format:(SDImageFormat)format options:(SDImageCoderOptions *)options {
- if (!frames || frames.count < 1) {
- return nil;
- }
- NSArray<id<SDImageCoder>> *coders = self.coders;
- for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
- if ([coder canEncodeToFormat:format]) {
- if ([coder respondsToSelector:@selector(encodedDataWithFrames:loopCount:format:options:)]) {
- return [coder encodedDataWithFrames:frames loopCount:loopCount format:format options:options];
- }
- }
- }
- return nil;
- }
- @end
|