mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
3b67bfab1e
Summary: The goal of this PR is to improve the pipeline currently used for displaying GIFs / animated images on iOS. It is achieved by not holding all of the decoded frames in memory at the same time, as well as happily releasing existing memory whenever possible. This code is a simplified version of what you would find in SDWebImage (it is nearly 1:1, with unsupported or uneeded things removed). By adopting this API, it also allows classes conforming to RCTImageURLLoader or RCTImageDataDecoder to return any decodable UIImages conforming to RCTAnimatedImage and have improvements to memory consumption. Because RCTAnimatedImage is just a subset of the SDAnimatedImage protocol, it also means that you can use SDWebImage easier with Image directly. A nice to have would be progressive image loading, but is beyond scope for this PR. It would, however, touch most of these same parts. ## Changelog [iOS] [Fixed] - Substantially lower chances of crashes from abundant GIF use Pull Request resolved: https://github.com/facebook/react-native/pull/24822 Test Plan: TBD. (but i am running a version of this in my own app currently) Reviewed By: shergin Differential Revision: D15853479 Pulled By: sammy-SC fbshipit-source-id: 969e0d458da9fa49453aee1dcdf51783c2a45067
46 lines
1.2 KiB
Objective-C
46 lines
1.2 KiB
Objective-C
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#import "RCTGIFImageDecoder.h"
|
|
|
|
#import <ImageIO/ImageIO.h>
|
|
#import <QuartzCore/QuartzCore.h>
|
|
|
|
#import <React/RCTUtils.h>
|
|
#import "RCTAnimatedImage.h"
|
|
|
|
@implementation RCTGIFImageDecoder
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
- (BOOL)canDecodeImageData:(NSData *)imageData
|
|
{
|
|
char header[7] = {};
|
|
[imageData getBytes:header length:6];
|
|
|
|
return !strcmp(header, "GIF87a") || !strcmp(header, "GIF89a");
|
|
}
|
|
|
|
- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)imageData
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
|
|
{
|
|
RCTAnimatedImage *image = [[RCTAnimatedImage alloc] initWithData:imageData scale:scale];
|
|
|
|
if (!image) {
|
|
completionHandler(nil, nil);
|
|
return ^{};
|
|
}
|
|
|
|
completionHandler(nil, image);
|
|
return ^{};
|
|
}
|
|
|
|
@end
|