BU_SDImageCoder.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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 <Foundation/Foundation.h>
  9. #import "BU_SDWebImageCompat.h"
  10. #import "NSData+BUImageContentType.h"
  11. typedef NSString * SDImageCoderOption NS_STRING_ENUM;
  12. typedef NSDictionary<SDImageCoderOption, id> SDImageCoderOptions;
  13. typedef NSMutableDictionary<SDImageCoderOption, id> SDImageCoderMutableOptions;
  14. #pragma mark - Coder Options
  15. // These options are for image decoding
  16. /**
  17. A Boolean value indicating whether to decode the first frame only for animated image during decoding. (NSNumber). If not provide, decode animated image if need.
  18. @note works for `SDImageCoder`.
  19. */
  20. FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderDecodeFirstFrameOnly;
  21. /**
  22. A CGFloat value which is greater than or equal to 1.0. This value specify the image scale factor for decoding. If not provide, use 1.0. (NSNumber)
  23. @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `<BU_SDAnimatedImageCoder>`.
  24. */
  25. FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderDecodeScaleFactor;
  26. // These options are for image encoding
  27. /**
  28. A Boolean value indicating whether to encode the first frame only for animated image during encoding. (NSNumber). If not provide, encode animated image if need.
  29. @note works for `SDImageCoder`.
  30. */
  31. FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderEncodeFirstFrameOnly;
  32. /**
  33. A double value between 0.0-1.0 indicating the encode compression quality to produce the image data. 1.0 resulting in no compression and 0.0 resulting in the maximum compression possible. If not provide, use 1.0. (NSNumber)
  34. @note works for `SDImageCoder`
  35. */
  36. FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderEncodeCompressionQuality;
  37. /**
  38. A SDWebImageContext object which hold the original context options from top-level API. (SDWebImageContext)
  39. This option is ignored for all built-in coders and take no effect.
  40. But this may be useful for some custom coders, because some business logic may dependent on things other than image or image data inforamtion only.
  41. See `SDWebImageContext` for more detailed information.
  42. */
  43. FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderWebImageContext;
  44. /**
  45. A Boolean value indicating whether to keep the original aspect ratio when generating thumbnail images (or bitmap images from vector format).
  46. Defaults to YES.
  47. @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `<BU_SDAnimatedImageCoder>`.
  48. */
  49. FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderDecodePreserveAspectRatio;
  50. /**
  51. A CGSize value indicating whether or not to generate the thumbnail images (or bitmap images from vector format). When this value is provided, the decoder will generate a thumbnail image which pixel size is smaller than or equal to (depends the `.preserveAspectRatio`) the value size.
  52. Defaults to CGSizeZero, which means no thumbnail generation at all.
  53. @note Supports for animated image as well.
  54. @note When you pass `.preserveAspectRatio == NO`, the thumbnail image is stretched to match each dimension. When `.preserveAspectRatio == YES`, the thumbnail image's width is limited to pixel size's width, the thumbnail image's height is limited to pixel size's height. For common cases, you can just pass a square size to limit both.
  55. @note works for `SDImageCoder`, `SDProgressiveImageCoder`, `<BU_SDAnimatedImageCoder>`.
  56. */
  57. FOUNDATION_EXPORT SDImageCoderOption _Nonnull const BU_SDImageCoderDecodeThumbnailPixelSize;
  58. #pragma mark - Coder
  59. /**
  60. This is the image coder protocol to provide custom image decoding/encoding.
  61. These methods are all required to implement.
  62. @note Pay attention that these methods are not called from main queue.
  63. */
  64. @protocol BU_SDImageCoder <NSObject>
  65. @required
  66. #pragma mark - Decoding
  67. /**
  68. Returns YES if this coder can decode some data. Otherwise, the data should be passed to another coder.
  69. @param data The image data so we can look at it
  70. @return YES if this coder can decode the data, NO otherwise
  71. */
  72. - (BOOL)canDecodeFromData:(nullable NSData *)data;
  73. /**
  74. Decode the image data to image.
  75. @note This protocol may supports decode animated image frames. You can use `+[SDImageCoderHelper animatedImageWithFrames:]` to produce an animated image with frames.
  76. @param data The image data to be decoded
  77. @param options A dictionary containing any decoding options. Pass @{BU_SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for image. Pass @{BU_SDImageCoderDecodeFirstFrameOnly: @(YES)} to decode the first frame only.
  78. @return The decoded image from data
  79. */
  80. - (nullable UIImage *)decodedImageWithData:(nullable NSData *)data
  81. options:(nullable SDImageCoderOptions *)options;
  82. #pragma mark - Encoding
  83. /**
  84. Returns YES if this coder can encode some image. Otherwise, it should be passed to another coder.
  85. For custom coder which introduce new image format, you'd better define a new `BU_SDImageFormat` using like this. If you're creating public coder plugin for new image format, also update `https://github.com/rs/SDWebImage/wiki/Coder-Plugin-List` to avoid same value been defined twice.
  86. * @code
  87. static const BU_SDImageFormat BU_SDImageFormatHEIF = 10;
  88. * @endcode
  89. @param format The image format
  90. @return YES if this coder can encode the image, NO otherwise
  91. */
  92. - (BOOL)canEncodeToFormat:(BU_SDImageFormat)format NS_SWIFT_NAME(canEncode(to:));
  93. /**
  94. Encode the image to image data.
  95. @note This protocol may supports encode animated image frames. You can use `+[SDImageCoderHelper framesFromAnimatedImage:]` to assemble an animated image with frames.
  96. @param image The image to be encoded
  97. @param format The image format to encode, you should note `BU_SDImageFormatUndefined` format is also possible
  98. @param options A dictionary containing any encoding options. Pass @{BU_SDImageCoderEncodeCompressionQuality: @(1)} to specify compression quality.
  99. @return The encoded image data
  100. */
  101. - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image
  102. format:(BU_SDImageFormat)format
  103. options:(nullable SDImageCoderOptions *)options;
  104. @end
  105. #pragma mark - Progressive Coder
  106. /**
  107. This is the image coder protocol to provide custom progressive image decoding.
  108. These methods are all required to implement.
  109. @note Pay attention that these methods are not called from main queue.
  110. */
  111. @protocol BU_SDProgressiveImageCoder <BU_SDImageCoder>
  112. @required
  113. /**
  114. Returns YES if this coder can incremental decode some data. Otherwise, it should be passed to another coder.
  115. @param data The image data so we can look at it
  116. @return YES if this coder can decode the data, NO otherwise
  117. */
  118. - (BOOL)canIncrementalDecodeFromData:(nullable NSData *)data;
  119. /**
  120. Because incremental decoding need to keep the decoded context, we will alloc a new instance with the same class for each download operation to avoid conflicts
  121. This init method should not return nil
  122. @param options A dictionary containing any progressive decoding options (instance-level). Pass @{BU_SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for progressive animated image (each frames should use the same scale).
  123. @return A new instance to do incremental decoding for the specify image format
  124. */
  125. - (nonnull instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)options;
  126. /**
  127. Update the incremental decoding when new image data available
  128. @param data The image data has been downloaded so far
  129. @param finished Whether the download has finished
  130. */
  131. - (void)updateIncrementalData:(nullable NSData *)data finished:(BOOL)finished;
  132. /**
  133. Incremental decode the current image data to image.
  134. @note Due to the performance issue for progressive decoding and the integration for image view. This method may only return the first frame image even if the image data is animated image. If you want progressive animated image decoding, conform to `<BU_SDAnimatedImageCoder>` protocol as well and use `animatedImageFrameAtIndex:` instead.
  135. @param options A dictionary containing any progressive decoding options. Pass @{BU_SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for progressive image
  136. @return The decoded image from current data
  137. */
  138. - (nullable UIImage *)incrementalDecodedImageWithOptions:(nullable SDImageCoderOptions *)options;
  139. @end
  140. #pragma mark - Animated Image Provider
  141. /**
  142. This is the animated image protocol to provide the basic function for animated image rendering. It's adopted by `BU_SDAnimatedImage` and `<BU_SDAnimatedImageCoder>`
  143. */
  144. @protocol BU_SDAnimatedImageProvider <NSObject>
  145. @required
  146. /**
  147. The original animated image data for current image. If current image is not an animated format, return nil.
  148. We may use this method to grab back the original image data if need, such as NSCoding or compare.
  149. @return The animated image data
  150. */
  151. @property (nonatomic, copy, readonly, nullable) NSData *animatedImageData;
  152. /**
  153. Total animated frame count.
  154. If the frame count is less than 1, then the methods below will be ignored.
  155. @return Total animated frame count.
  156. */
  157. @property (nonatomic, assign, readonly) NSUInteger animatedImageFrameCount;
  158. /**
  159. Animation loop count, 0 means infinite looping.
  160. @return Animation loop count
  161. */
  162. @property (nonatomic, assign, readonly) NSUInteger animatedImageLoopCount;
  163. /**
  164. Returns the frame image from a specified index.
  165. @note The index maybe randomly if one image was set to different imageViews, keep it re-entrant. (It's not recommend to store the images into array because it's memory consuming)
  166. @param index Frame index (zero based).
  167. @return Frame's image
  168. */
  169. - (nullable UIImage *)animatedImageFrameAtIndex:(NSUInteger)index;
  170. /**
  171. Returns the frames's duration from a specified index.
  172. @note The index maybe randomly if one image was set to different imageViews, keep it re-entrant. (It's recommend to store the durations into array because it's not memory-consuming)
  173. @param index Frame index (zero based).
  174. @return Frame's duration
  175. */
  176. - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index;
  177. @end
  178. #pragma mark - Animated Coder
  179. /**
  180. This is the animated image coder protocol for custom animated image class like `BU_SDAnimatedImage`. Through it inherit from `SDImageCoder`. We currentlly only use the method `canDecodeFromData:` to detect the proper coder for specify animated image format.
  181. */
  182. @protocol BU_SDAnimatedImageCoder <BU_SDImageCoder, BU_SDAnimatedImageProvider>
  183. @required
  184. /**
  185. Because animated image coder should keep the original data, we will alloc a new instance with the same class for the specify animated image data
  186. The init method should return nil if it can't decode the specify animated image data to produce any frame.
  187. After the instance created, we may call methods in `BU_SDAnimatedImageProvider` to produce animated image frame.
  188. @param data The animated image data to be decode
  189. @param options A dictionary containing any animated decoding options (instance-level). Pass @{BU_SDImageCoderDecodeScaleFactor: @(1.0)} to specify scale factor for animated image (each frames should use the same scale).
  190. @return A new instance to do animated decoding for specify image data
  191. */
  192. - (nullable instancetype)initWithAnimatedImageData:(nullable NSData *)data options:(nullable SDImageCoderOptions *)options;
  193. @end