Fix the thread safe issue for accessing array with index, which may happend during incremental decoding
This commit is contained in:
parent
8a0c5e1ae0
commit
3775b895fb
|
@ -331,11 +331,10 @@ else OSSpinLockUnlock(&lock##_deprecated);
|
||||||
webpData.size = _imageData.length;
|
webpData.size = _imageData.length;
|
||||||
WebPDemuxState state;
|
WebPDemuxState state;
|
||||||
_demux = WebPDemuxPartial(&webpData, &state);
|
_demux = WebPDemuxPartial(&webpData, &state);
|
||||||
SD_UNLOCK(_lock);
|
|
||||||
|
|
||||||
if (_demux && state != WEBP_DEMUX_PARSE_ERROR) {
|
if (_demux && state != WEBP_DEMUX_PARSE_ERROR) {
|
||||||
[self scanAndCheckFramesValidWithDemuxer:_demux];
|
[self scanAndCheckFramesValidWithDemuxer:_demux];
|
||||||
}
|
}
|
||||||
|
SD_UNLOCK(_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIImage *)incrementalDecodedImageWithOptions:(SDImageCoderOptions *)options {
|
- (UIImage *)incrementalDecodedImageWithOptions:(SDImageCoderOptions *)options {
|
||||||
|
@ -986,7 +985,6 @@ static float GetFloatValueForKey(NSDictionary * _Nonnull dictionary, NSString *
|
||||||
_hasAlpha = hasAlpha;
|
_hasAlpha = hasAlpha;
|
||||||
_canvasWidth = canvasWidth;
|
_canvasWidth = canvasWidth;
|
||||||
_canvasHeight = canvasHeight;
|
_canvasHeight = canvasHeight;
|
||||||
_frameCount = frameCount;
|
|
||||||
_loopCount = loopCount;
|
_loopCount = loopCount;
|
||||||
|
|
||||||
// If static WebP, does not need to parse the frame blend index
|
// If static WebP, does not need to parse the frame blend index
|
||||||
|
@ -1032,8 +1030,10 @@ static float GetFloatValueForKey(NSDictionary * _Nonnull dictionary, NSString *
|
||||||
WebPDemuxReleaseIterator(&iter);
|
WebPDemuxReleaseIterator(&iter);
|
||||||
|
|
||||||
if (frames.count != frameCount) {
|
if (frames.count != frameCount) {
|
||||||
|
// frames not match, do not override current value
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
_frameCount = frameCount;
|
||||||
_frames = [frames copy];
|
_frames = [frames copy];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
|
@ -1052,27 +1052,57 @@ static float GetFloatValueForKey(NSDictionary * _Nonnull dictionary, NSString *
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
|
- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
|
||||||
if (index >= _frameCount) {
|
NSTimeInterval duration;
|
||||||
return 0;
|
// Incremental Animation decoding may update frames when new bytes available
|
||||||
|
// Which should use lock to ensure frame count and frames match, ensure atomic logic
|
||||||
|
if (_idec != NULL) {
|
||||||
|
SD_LOCK(_lock);
|
||||||
|
if (index >= _frames.count) {
|
||||||
|
SD_UNLOCK(_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
duration = _frames[index].duration;
|
||||||
|
SD_UNLOCK(_lock);
|
||||||
|
} else {
|
||||||
|
if (index >= _frames.count) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
duration = _frames[index].duration;
|
||||||
}
|
}
|
||||||
if (_frameCount <= 1) {
|
return duration;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return _frames[index].duration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
|
- (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
|
||||||
UIImage *image;
|
UIImage *image;
|
||||||
if (index >= _frameCount) {
|
// Incremental Animation decoding may update frames when new bytes available
|
||||||
return nil;
|
// Which should use lock to ensure frame count and frames match, ensure atomic logic
|
||||||
}
|
if (_idec != NULL) {
|
||||||
SD_LOCK(_lock);
|
SD_LOCK(_lock);
|
||||||
if (_frameCount <= 1) {
|
if (index >= _frames.count) {
|
||||||
image = [self safeStaticImageFrame];
|
SD_UNLOCK(_lock);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if (_frames.count <= 1) {
|
||||||
|
image = [self safeStaticImageFrame];
|
||||||
|
} else {
|
||||||
|
image = [self safeAnimatedImageFrameAtIndex:index];
|
||||||
|
}
|
||||||
|
SD_UNLOCK(_lock);
|
||||||
} else {
|
} else {
|
||||||
image = [self safeAnimatedImageFrameAtIndex:index];
|
// Animation Decoding need a lock on the canvas (which is shared), but the _frames is immutable and no lock needed
|
||||||
|
if (index >= _frames.count) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if (_frames.count <= 1) {
|
||||||
|
SD_LOCK(_lock);
|
||||||
|
image = [self safeStaticImageFrame];
|
||||||
|
SD_UNLOCK(_lock);
|
||||||
|
} else {
|
||||||
|
SD_LOCK(_lock);
|
||||||
|
image = [self safeAnimatedImageFrameAtIndex:index];
|
||||||
|
SD_UNLOCK(_lock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SD_UNLOCK(_lock);
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue