SDImageCodersManager.m 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * This file is part of the SDWebImage package.
  3. * (c) Olivier Poitrey <rs@dailymotion.com>
  4. *
  5. * For the full copyright and license information, please view the LICENSE
  6. * file that was distributed with this source code.
  7. */
  8. #import "SDImageCodersManager.h"
  9. #import "SDImageIOCoder.h"
  10. #import "SDImageGIFCoder.h"
  11. #import "SDImageAPNGCoder.h"
  12. #import "SDInternalMacros.h"
  13. @interface SDImageCodersManager ()
  14. @property (nonatomic, strong, nonnull) dispatch_semaphore_t codersLock;
  15. @end
  16. @implementation SDImageCodersManager
  17. {
  18. NSMutableArray<id<SDImageCoder>> *_imageCoders;
  19. }
  20. + (nonnull instancetype)sharedManager {
  21. static dispatch_once_t once;
  22. static id instance;
  23. dispatch_once(&once, ^{
  24. instance = [self new];
  25. });
  26. return instance;
  27. }
  28. - (instancetype)init {
  29. if (self = [super init]) {
  30. // initialize with default coders
  31. _imageCoders = [NSMutableArray arrayWithArray:@[[SDImageIOCoder sharedCoder], [SDImageGIFCoder sharedCoder], [SDImageAPNGCoder sharedCoder]]];
  32. _codersLock = dispatch_semaphore_create(1);
  33. }
  34. return self;
  35. }
  36. - (NSArray<id<SDImageCoder>> *)coders
  37. {
  38. SD_LOCK(self.codersLock);
  39. NSArray<id<SDImageCoder>> *coders = [_imageCoders copy];
  40. SD_UNLOCK(self.codersLock);
  41. return coders;
  42. }
  43. - (void)setCoders:(NSArray<id<SDImageCoder>> *)coders
  44. {
  45. SD_LOCK(self.codersLock);
  46. [_imageCoders removeAllObjects];
  47. if (coders.count) {
  48. [_imageCoders addObjectsFromArray:coders];
  49. }
  50. SD_UNLOCK(self.codersLock);
  51. }
  52. #pragma mark - Coder IO operations
  53. - (void)addCoder:(nonnull id<SDImageCoder>)coder {
  54. if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {
  55. return;
  56. }
  57. SD_LOCK(self.codersLock);
  58. [_imageCoders addObject:coder];
  59. SD_UNLOCK(self.codersLock);
  60. }
  61. - (void)removeCoder:(nonnull id<SDImageCoder>)coder {
  62. if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {
  63. return;
  64. }
  65. SD_LOCK(self.codersLock);
  66. [_imageCoders removeObject:coder];
  67. SD_UNLOCK(self.codersLock);
  68. }
  69. #pragma mark - SDImageCoder
  70. - (BOOL)canDecodeFromData:(NSData *)data {
  71. NSArray<id<SDImageCoder>> *coders = self.coders;
  72. for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
  73. if ([coder canDecodeFromData:data]) {
  74. return YES;
  75. }
  76. }
  77. return NO;
  78. }
  79. - (BOOL)canEncodeToFormat:(SDImageFormat)format {
  80. NSArray<id<SDImageCoder>> *coders = self.coders;
  81. for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
  82. if ([coder canEncodeToFormat:format]) {
  83. return YES;
  84. }
  85. }
  86. return NO;
  87. }
  88. - (UIImage *)decodedImageWithData:(NSData *)data options:(nullable SDImageCoderOptions *)options {
  89. if (!data) {
  90. return nil;
  91. }
  92. UIImage *image;
  93. NSArray<id<SDImageCoder>> *coders = self.coders;
  94. for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
  95. if ([coder canDecodeFromData:data]) {
  96. image = [coder decodedImageWithData:data options:options];
  97. break;
  98. }
  99. }
  100. return image;
  101. }
  102. - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(nullable SDImageCoderOptions *)options {
  103. if (!image) {
  104. return nil;
  105. }
  106. NSArray<id<SDImageCoder>> *coders = self.coders;
  107. for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
  108. if ([coder canEncodeToFormat:format]) {
  109. return [coder encodedDataWithImage:image format:format options:options];
  110. }
  111. }
  112. return nil;
  113. }
  114. @end