@@ -331,11 +331,10 @@ - (void)updateIncrementalData:(NSData *)data finished:(BOOL)finished {
331
331
webpData.size = _imageData.length ;
332
332
WebPDemuxState state;
333
333
_demux = WebPDemuxPartial (&webpData, &state);
334
- SD_UNLOCK (_lock);
335
-
336
334
if (_demux && state != WEBP_DEMUX_PARSE_ERROR) {
337
335
[self scanAndCheckFramesValidWithDemuxer: _demux];
338
336
}
337
+ SD_UNLOCK (_lock);
339
338
}
340
339
341
340
- (UIImage *)incrementalDecodedImageWithOptions : (SDImageCoderOptions *)options {
@@ -986,7 +985,6 @@ - (BOOL)scanAndCheckFramesValidWithDemuxer:(WebPDemuxer *)demuxer {
986
985
_hasAlpha = hasAlpha;
987
986
_canvasWidth = canvasWidth;
988
987
_canvasHeight = canvasHeight;
989
- _frameCount = frameCount;
990
988
_loopCount = loopCount;
991
989
992
990
// If static WebP, does not need to parse the frame blend index
@@ -1032,8 +1030,10 @@ - (BOOL)scanAndCheckFramesValidWithDemuxer:(WebPDemuxer *)demuxer {
1032
1030
WebPDemuxReleaseIterator (&iter);
1033
1031
1034
1032
if (frames.count != frameCount) {
1033
+ // frames not match, do not override current value
1035
1034
return NO ;
1036
1035
}
1036
+ _frameCount = frameCount;
1037
1037
_frames = [frames copy ];
1038
1038
1039
1039
return YES ;
@@ -1052,27 +1052,57 @@ - (NSUInteger)animatedImageFrameCount {
1052
1052
}
1053
1053
1054
1054
- (NSTimeInterval )animatedImageDurationAtIndex : (NSUInteger )index {
1055
- if (index >= _frameCount) {
1056
- return 0 ;
1057
- }
1058
- if (_frameCount <= 1 ) {
1059
- return 0 ;
1055
+ NSTimeInterval duration;
1056
+ // Incremental Animation decoding may update frames when new bytes available
1057
+ // Which should use lock to ensure frame count and frames match, ensure atomic logic
1058
+ if (_idec != NULL ) {
1059
+ SD_LOCK (_lock);
1060
+ if (index >= _frames.count ) {
1061
+ SD_UNLOCK (_lock);
1062
+ return 0 ;
1063
+ }
1064
+ duration = _frames[index].duration ;
1065
+ SD_UNLOCK (_lock);
1066
+ } else {
1067
+ if (index >= _frames.count ) {
1068
+ return 0 ;
1069
+ }
1070
+ duration = _frames[index].duration ;
1060
1071
}
1061
- return _frames[index]. duration ;
1072
+ return duration;
1062
1073
}
1063
1074
1064
1075
- (UIImage *)animatedImageFrameAtIndex : (NSUInteger )index {
1065
1076
UIImage *image;
1066
- if (index >= _frameCount) {
1067
- return nil ;
1068
- }
1069
- SD_LOCK (_lock);
1070
- if (_frameCount <= 1 ) {
1071
- image = [self safeStaticImageFrame ];
1077
+ // Incremental Animation decoding may update frames when new bytes available
1078
+ // Which should use lock to ensure frame count and frames match, ensure atomic logic
1079
+ if (_idec != NULL ) {
1080
+ SD_LOCK (_lock);
1081
+ if (index >= _frames.count ) {
1082
+ SD_UNLOCK (_lock);
1083
+ return nil ;
1084
+ }
1085
+ if (_frames.count <= 1 ) {
1086
+ image = [self safeStaticImageFrame ];
1087
+ } else {
1088
+ image = [self safeAnimatedImageFrameAtIndex: index];
1089
+ }
1090
+ SD_UNLOCK (_lock);
1072
1091
} else {
1073
- image = [self safeAnimatedImageFrameAtIndex: index];
1092
+ // Animation Decoding need a lock on the canvas (which is shared), but the _frames is immutable and no lock needed
1093
+ if (index >= _frames.count ) {
1094
+ return nil ;
1095
+ }
1096
+ if (_frames.count <= 1 ) {
1097
+ SD_LOCK (_lock);
1098
+ image = [self safeStaticImageFrame ];
1099
+ SD_UNLOCK (_lock);
1100
+ } else {
1101
+ SD_LOCK (_lock);
1102
+ image = [self safeAnimatedImageFrameAtIndex: index];
1103
+ SD_UNLOCK (_lock);
1104
+ }
1074
1105
}
1075
- SD_UNLOCK (_lock);
1076
1106
return image;
1077
1107
}
1078
1108
0 commit comments