@@ -736,6 +736,9 @@ - (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef
736
736
}
737
737
738
738
size_t bytesPerRow = CGImageGetBytesPerRow (imageRef);
739
+ size_t bitsPerComponent = CGImageGetBitsPerComponent (imageRef);
740
+ size_t bitsPerPixel = CGImageGetBitsPerPixel (imageRef);
741
+ size_t components = bitsPerPixel / bitsPerComponent;
739
742
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo (imageRef);
740
743
CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask ;
741
744
CGBitmapInfo byteOrderInfo = bitmapInfo & kCGBitmapByteOrderMask ;
@@ -763,10 +766,15 @@ - (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef
763
766
if (!dataRef) {
764
767
return nil ;
765
768
}
769
+ // Check colorSpace is RGB/RGBA
770
+ CGColorSpaceRef colorSpace = CGImageGetColorSpace (imageRef);
771
+ BOOL isRGB = CGColorSpaceGetModel (colorSpace) == kCGColorSpaceModelRGB ;
766
772
767
773
uint8_t *rgba = NULL ; // RGBA Buffer managed by CFData, don't call `free` on it, instead call `CFRelease` on `dataRef`
768
774
// We could not assume that input CGImage's color mode is always RGB888/RGBA8888. Convert all other cases to target color mode using vImage
769
- if (byteOrderNormal && ((alphaInfo == kCGImageAlphaNone ) || (alphaInfo == kCGImageAlphaLast ))) {
775
+ BOOL isRGB888 = isRGB && byteOrderNormal && alphaInfo == kCGImageAlphaNone && components == 3 ;
776
+ BOOL isRGBA8888 = isRGB && byteOrderNormal && alphaInfo == kCGImageAlphaLast && components == 4 ;
777
+ if (isRGB888 || isRGBA8888) {
770
778
// If the input CGImage is already RGB888/RGBA8888
771
779
rgba = (uint8_t *)CFDataGetBytePtr (dataRef);
772
780
} else {
@@ -775,10 +783,11 @@ - (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef
775
783
vImage_Error error = kvImageNoError;
776
784
777
785
vImage_CGImageFormat srcFormat = {
778
- .bitsPerComponent = (uint32_t )CGImageGetBitsPerComponent (imageRef),
779
- .bitsPerPixel = (uint32_t )CGImageGetBitsPerPixel (imageRef),
780
- .colorSpace = CGImageGetColorSpace (imageRef),
781
- .bitmapInfo = bitmapInfo
786
+ .bitsPerComponent = (uint32_t )bitsPerComponent,
787
+ .bitsPerPixel = (uint32_t )bitsPerPixel,
788
+ .colorSpace = colorSpace,
789
+ .bitmapInfo = bitmapInfo,
790
+ .renderingIntent = CGImageGetRenderingIntent (imageRef)
782
791
};
783
792
vImage_CGImageFormat destFormat = {
784
793
.bitsPerComponent = 8 ,
@@ -793,14 +802,15 @@ - (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef
793
802
return nil ;
794
803
}
795
804
796
- vImage_Buffer src = {
797
- . data = ( uint8_t *) CFDataGetBytePtr (dataRef),
798
- . width = width,
799
- . height = height,
800
- . rowBytes = bytesPerRow
801
- } ;
802
- vImage_Buffer dest;
805
+ vImage_Buffer src;
806
+ error = vImageBuffer_InitWithCGImage (&src, &srcFormat, nil , imageRef, kvImageNoFlags);
807
+ if (error != kvImageNoError) {
808
+ vImageConverter_Release (convertor);
809
+ CFRelease (dataRef);
810
+ return nil ;
811
+ }
803
812
813
+ vImage_Buffer dest;
804
814
error = vImageBuffer_Init (&dest, height, width, destFormat.bitsPerPixel , kvImageNoFlags);
805
815
if (error != kvImageNoError) {
806
816
vImageConverter_Release (convertor);
0 commit comments