From 66cfc23f1c16359899650f5d49687b0a2e95dc1d Mon Sep 17 00:00:00 2001 From: Antti Kortetmaa Date: Thu, 10 Dec 2020 14:31:08 +0200 Subject: [PATCH 1/8] Added new encoding options to WebP encoding --- SDWebImageWebPCoder.xcodeproj/project.pbxproj | 20 +++ .../Classes/SDImageWebPCoder.m | 108 +++++++++++++- .../Classes/SDWebImageWebPCoderDefine.h | 134 ++++++++++++++++++ .../Classes/SDWebImageWebPCoderDefine.m | 28 ++++ .../Module/SDWebImageWebPCoder.h | 1 + 5 files changed, 284 insertions(+), 7 deletions(-) create mode 100644 SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h create mode 100644 SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.m diff --git a/SDWebImageWebPCoder.xcodeproj/project.pbxproj b/SDWebImageWebPCoder.xcodeproj/project.pbxproj index d4a8813..6023d9e 100644 --- a/SDWebImageWebPCoder.xcodeproj/project.pbxproj +++ b/SDWebImageWebPCoder.xcodeproj/project.pbxproj @@ -7,6 +7,14 @@ objects = { /* Begin PBXBuildFile section */ + 220A6239257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; + 220A623A257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; + 220A623B257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; + 220A623C257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; + 220A623D257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; + 220A623E257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; + 220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; + 220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; 806E77B32136A2E900A316D2 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 806E77AA2136A2E900A316D2 /* UIImage+WebP.m */; }; 806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AB2136A2E900A316D2 /* SDImageWebPCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 806E77B62136A2E900A316D2 /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AD2136A2E900A316D2 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -38,6 +46,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageWebPCoderDefine.m; sourceTree = ""; }; + 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageWebPCoderDefine.h; sourceTree = ""; }; 28D8AA3D3015E075692FD3E3 /* Pods-SDWebImageWebPCoderTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageWebPCoderTests.debug.xcconfig"; path = "Tests/Pods/Target Support Files/Pods-SDWebImageWebPCoderTests/Pods-SDWebImageWebPCoderTests.debug.xcconfig"; sourceTree = ""; }; 3217BE7B220547EB003D0310 /* SDWebImageWebPCoder.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = SDWebImageWebPCoder.modulemap; sourceTree = ""; }; 46F21AD7D1692EBAC4D0FF33 /* Pods_SDWebImageWebPCoderTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageWebPCoderTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -146,6 +156,8 @@ 806E77A92136A2E900A316D2 /* Classes */ = { isa = PBXGroup; children = ( + 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */, + 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */, 806E77AB2136A2E900A316D2 /* SDImageWebPCoder.h */, 806E77AE2136A2E900A316D2 /* SDImageWebPCoder.m */, 806E77AD2136A2E900A316D2 /* UIImage+WebP.h */, @@ -228,6 +240,7 @@ files = ( 806E77C72136A7AD00A316D2 /* SDWebImageWebPCoder.h in Headers */, 806E77B62136A2E900A316D2 /* UIImage+WebP.h in Headers */, + 220A623D257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */, 806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -238,6 +251,7 @@ files = ( 80BFF2502136BC1500B95470 /* UIImage+WebP.h in Headers */, 80BFF24D2136BC0600B95470 /* SDWebImageWebPCoder.h in Headers */, + 220A623E257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */, 80BFF24E2136BC1000B95470 /* SDImageWebPCoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -248,6 +262,7 @@ files = ( 80BFF2632136BE2200B95470 /* SDWebImageWebPCoder.h in Headers */, 80BFF2612136BE1C00B95470 /* UIImage+WebP.h in Headers */, + 220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */, 80BFF25F2136BE1700B95470 /* SDImageWebPCoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -258,6 +273,7 @@ files = ( 80BFF27F2136BEF200B95470 /* SDWebImageWebPCoder.h in Headers */, 80BFF27D2136BEED00B95470 /* UIImage+WebP.h in Headers */, + 220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */, 80BFF27B2136BEE700B95470 /* SDImageWebPCoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -416,6 +432,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 220A6239257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */, 806E77B72136A2E900A316D2 /* SDImageWebPCoder.m in Sources */, 806E77B32136A2E900A316D2 /* UIImage+WebP.m in Sources */, ); @@ -425,6 +442,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 220A623A257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */, 80BFF24F2136BC1300B95470 /* SDImageWebPCoder.m in Sources */, 80BFF2512136BC1800B95470 /* UIImage+WebP.m in Sources */, ); @@ -434,6 +452,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 220A623B257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */, 80BFF2602136BE1A00B95470 /* SDImageWebPCoder.m in Sources */, 80BFF2622136BE1F00B95470 /* UIImage+WebP.m in Sources */, ); @@ -443,6 +462,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 220A623C257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */, 80BFF27C2136BEEB00B95470 /* SDImageWebPCoder.m in Sources */, 80BFF27E2136BEF000B95470 /* UIImage+WebP.m in Sources */, ); diff --git a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m index 9aaa45a..1759fd3 100644 --- a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m +++ b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m @@ -23,6 +23,7 @@ #endif #import +#import "SDWebImageWebPCoderDefine.h" /// Calculate the actual thumnail pixel size static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio, CGSize thumbnailSize) { @@ -617,7 +618,11 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio BOOL encodeFirstFrame = [options[SDImageCoderEncodeFirstFrameOnly] boolValue]; if (encodeFirstFrame || frames.count == 0) { // for static single webp image - data = [self sd_encodedWebpDataWithImage:image.CGImage quality:compressionQuality maxPixelSize:maxPixelSize maxFileSize:maxFileSize]; + data = [self sd_encodedWebpDataWithImage:image.CGImage + quality:compressionQuality + maxPixelSize:maxPixelSize + maxFileSize:maxFileSize + options:options]; } else { // for animated webp image WebPMux *mux = WebPMuxNew(); @@ -626,7 +631,11 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio } for (size_t i = 0; i < frames.count; i++) { SDImageFrame *currentFrame = frames[i]; - NSData *webpData = [self sd_encodedWebpDataWithImage:currentFrame.image.CGImage quality:compressionQuality maxPixelSize:maxPixelSize maxFileSize:maxFileSize]; + NSData *webpData = [self sd_encodedWebpDataWithImage:currentFrame.image.CGImage + quality:compressionQuality + maxPixelSize:maxPixelSize + maxFileSize:maxFileSize + options:options]; int duration = currentFrame.duration * 1000; WebPMuxFrameInfo frame = { .bitstream.bytes = webpData.bytes, .bitstream.size = webpData.length, @@ -663,7 +672,12 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio return data; } -- (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef quality:(double)quality maxPixelSize:(CGSize)maxPixelSize maxFileSize:(NSUInteger)maxFileSize { +- (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef + quality:(double)quality + maxPixelSize:(CGSize)maxPixelSize + maxFileSize:(NSUInteger)maxFileSize + options:(nullable SDImageCoderOptions *)options +{ NSData *webpData; if (!imageRef) { return nil; @@ -779,10 +793,7 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio return nil; } - config.target_size = (int)maxFileSize; // Max filesize for output, 0 means use quality instead - config.pass = maxFileSize > 0 ? 6 : 1; // Use 6 passes for file size limited encoding, which is the default value of `cwebp` command line - config.thread_level = 1; // Thread encoding for fast - config.lossless = 0; // Disable lossless encoding (If we need, can add new Encoding Options in future version) + [self updateWebPOptionsToConfig:&config maxFileSize:maxFileSize options:options]; picture.use_argb = 0; // Lossy encoding use YUV for internel bitstream picture.width = (int)width; picture.height = (int)height; @@ -830,6 +841,89 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio return webpData; } +- (void) updateWebPOptionsToConfig:(WebPConfig*)config + maxFileSize:(NSUInteger)maxFileSize + options:(nullable SDImageCoderOptions *)options { + + config->target_size = (int)maxFileSize; // Max filesize for output, 0 means use quality instead + config->pass = maxFileSize > 0 ? 6 : 1; // Use 6 passes for file size limited encoding, which is the default value of `cwebp` command line + config->lossless = 0; // Disable lossless encoding (If we need, can add new Encoding Options in future version) + + if ([options[SDImageCoderEncodeWebPMethod] intValue]) { + config->method = [options[SDImageCoderEncodeWebPMethod] intValue]; + } + if ([options[SDImageCoderEncodeWebPPass] intValue]) { + config->pass = [options[SDImageCoderEncodeWebPPass] intValue]; + } + if ([options[SDImageCoderEncodeWebPPreprocessing] intValue]) { + config->preprocessing = [options[SDImageCoderEncodeWebPPreprocessing] intValue]; + } + if ([options[SDImageCoderEncodeWebPThreadLevel] intValue]) { + config->thread_level = [options[SDImageCoderEncodeWebPThreadLevel] intValue]; + } else { + config->thread_level = 1; + } + if ([options[SDImageCoderEncodeWebPLowMemory] intValue]) { + config->low_memory = [options[SDImageCoderEncodeWebPLowMemory] intValue]; + } + + if ([options[SDImageCoderEncodeWebPTargetPSNR] floatValue]) { + config->target_PSNR = [options[SDImageCoderEncodeWebPTargetPSNR] floatValue]; + } + + if ([options[SDImageCoderEncodeWebPSegments] intValue]) { + config->segments = [options[SDImageCoderEncodeWebPSegments] intValue]; + } + + if ([options[SDImageCoderEncodeWebPSnsStrength] intValue]) { + config->sns_strength = [options[SDImageCoderEncodeWebPSnsStrength] intValue]; + } + + if ([options[SDImageCoderEncodeWebPFilterStrength] intValue]) { + config->filter_strength = [options[SDImageCoderEncodeWebPFilterStrength] intValue]; + } + + if ([options[SDImageCoderEncodeWebPFilterSharpness] intValue]) { + config->filter_sharpness = [options[SDImageCoderEncodeWebPFilterSharpness] intValue]; + } + + if ([options[SDImageCoderEncodeWebPFilterType] intValue]) { + config->filter_type = [options[SDImageCoderEncodeWebPFilterType] intValue]; + } + + if ([options[SDImageCoderEncodeWebPAutofilter] intValue]) { + config->autofilter = [options[SDImageCoderEncodeWebPAutofilter] intValue]; + } + + if ([options[SDImageCoderEncodeWebPAlphaCompression] intValue]) { + config->alpha_compression = [options[SDImageCoderEncodeWebPAlphaCompression] intValue]; + } + + if ([options[SDImageCoderEncodeWebPAlphaFiltering] intValue]) { + config->alpha_filtering = [options[SDImageCoderEncodeWebPAlphaFiltering] intValue]; + } + + if ([options[SDImageCoderEncodeWebPAlphaQuality] intValue]) { + config->alpha_quality = [options[SDImageCoderEncodeWebPAlphaQuality] intValue]; + } + + if ([options[SDImageCoderEncodeWebPShowCompressed] intValue]) { + config->show_compressed = [options[SDImageCoderEncodeWebPShowCompressed] intValue]; + } + + if ([options[SDImageCoderEncodeWebPPartitions] intValue]) { + config->partitions = [options[SDImageCoderEncodeWebPPartitions] intValue]; + } + + if ([options[SDImageCoderEncodeWebPPartitionLimit] intValue]) { + config->partition_limit = [options[SDImageCoderEncodeWebPPartitionLimit] intValue]; + } + + if ([options[SDImageCoderEncodeWebPUseSharpYuv] intValue]) { + config->use_sharp_yuv = [options[SDImageCoderEncodeWebPUseSharpYuv] intValue]; + } +} + static void FreeImageData(void *info, const void *data, size_t size) { free((void *)data); } diff --git a/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h b/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h new file mode 100644 index 0000000..e04a536 --- /dev/null +++ b/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h @@ -0,0 +1,134 @@ +// +// SDWebImageWebPCoderDefine.h +// SDWebImageWebPCoderDefine +// +// Created by Antti Kortetmaa on 2020/12/06. +// + +#if __has_include() +#import +#else +@import SDWebImage; +#endif + +NS_ASSUME_NONNULL_BEGIN + +/** +Integer value +Quality/speed trade-off (0=fast, 6=slower-better) + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPMethod; + +/** +Integer value +Number of entropy-analysis passes (in [1..10]) + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPass; + +/** + Integer value + Preprocessing filter (0=none, 1=segment-smooth) + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPreprocessing; + +/** + Float value + if non-zero, specifies the minimal distortion to try to achieve. Takes precedence over target_size. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPTargetPSNR; + +/** + Integer value + If non-zero, try and use multi-threaded encoding. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPThreadLevel; + +/** + Integer value + If set, reduce memory usage (but increase CPU use). + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPLowMemory; + +/** + Integer value + if non-zero, specifies the minimal distortion to try to achieve. Takes precedence over target_size. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPSegments; + +/** + Integer value + Spatial Noise Shaping. 0=off, 100=maximum. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPSnsStrength; + +/** + Integer value + Range: [0 = off .. 100 = strongest] + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterStrength; + +/** + Integer value + range: [0 = off .. 7 = least sharp] + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterSharpness; + +/** + Integer value + Filtering type: 0 = simple, 1 = strong (only used If filter_strength > 0 or autofilter > 0) + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterType; + +/** + Integer value + Auto adjust filter's strength [0 = off, 1 = on] + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAutofilter; + +/** + Integer value + Algorithm for encoding the alpha plane (0 = none, 1 = compressed with WebP lossless). Default is 1. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaCompression; + +/** + Integer value + Predictive filtering method for alpha plane. 0: none, 1: fast, 2: best. Default if 1. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaFiltering; + +/** + Integer value + Between 0 (smallest size) and 100 (lossless). + Default is 100. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaQuality; + +/** + Integer value + If true, export the compressed picture back. + In-loop filtering is not applied. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPShowCompressed; + +/** + Integer + Log2(number of token partitions) in [0..3] + Default is set to 0 for easier progressive decoding. + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPartitions; + +/** + Integer value + Quality degradation allowed to fit the 512k limit on + Prediction modes coding (0: no degradation, 100: maximum possible degradation). + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPartitionLimit; + +/** + Integer value + if needed, use sharp (and slow) RGB->YUV conversion + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPUseSharpYuv; + +NS_ASSUME_NONNULL_END diff --git a/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.m b/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.m new file mode 100644 index 0000000..ff333de --- /dev/null +++ b/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.m @@ -0,0 +1,28 @@ +// +// SDWebImageWebPCoderDefine.m +// SDWebImageWebPCoder +// +// Created by Antti Kortetmaa on 2020/12/06. +// + +#import "SDWebImageWebPCoderDefine.h" + +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPMethod = @"webPMethod"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPass = @"webPPass"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPreprocessing = @"webPPreprocessing"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPThreadLevel = @"webPThreadLevel"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPLowMemory = @"webPLowMemory"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPTargetPSNR = @"webPTargetPSNR"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPSegments = @"webPSegments"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPSnsStrength = @"webPSnsStrength"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterStrength = @"webPFilterStrength"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterSharpness = @"webPFilterSharpness"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterType = @"webPFilterType"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAutofilter = @"webPAutofilter"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaCompression = @"webPAlphaCompression"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaFiltering = @"webPAlphaFiltering"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaQuality = @"webPAlphaQuality"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPShowCompressed = @"webPShowCompressed"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPartitions = @"webPPartitions"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPartitionLimit = @"webPPartitionLimit"; +SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPUseSharpYuv = @"webPUseSharpYuv"; diff --git a/SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h b/SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h index d0c0797..69e8947 100644 --- a/SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h +++ b/SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h @@ -12,4 +12,5 @@ FOUNDATION_EXPORT double SDWebImageWebPCoderVersionNumber; FOUNDATION_EXPORT const unsigned char SDWebImageWebPCoderVersionString[]; #import +#import #import From e330f22573720b70b658c80319012619185896d2 Mon Sep 17 00:00:00 2001 From: Antti Kortetmaa Date: Thu, 10 Dec 2020 21:07:37 +0200 Subject: [PATCH 2/8] Added unit tests for WebP settings. --- SDWebImageWebPCoder.xcodeproj/project.pbxproj | 4 +- .../Classes/SDImageWebPCoder.h | 18 +++++++ .../Classes/SDImageWebPCoder.m | 6 +-- Tests/SDWebImageWebPCoderTests.m | 49 +++++++++++++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/SDWebImageWebPCoder.xcodeproj/project.pbxproj b/SDWebImageWebPCoder.xcodeproj/project.pbxproj index 6023d9e..86d8a32 100644 --- a/SDWebImageWebPCoder.xcodeproj/project.pbxproj +++ b/SDWebImageWebPCoder.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 220A6239257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; 220A623A257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; 220A623B257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; 220A623C257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; @@ -15,6 +14,7 @@ 220A623E257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; 220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; 220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; + 228EA36125825A52005903D9 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; 806E77B32136A2E900A316D2 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 806E77AA2136A2E900A316D2 /* UIImage+WebP.m */; }; 806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AB2136A2E900A316D2 /* SDImageWebPCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 806E77B62136A2E900A316D2 /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AD2136A2E900A316D2 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -432,7 +432,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 220A6239257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */, + 228EA36125825A52005903D9 /* SDWebImageWebPCoderDefine.m in Sources */, 806E77B72136A2E900A316D2 /* SDImageWebPCoder.m in Sources */, 806E77B32136A2E900A316D2 /* UIImage+WebP.m in Sources */, ); diff --git a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h index 7629ded..849259f 100644 --- a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h +++ b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h @@ -12,6 +12,20 @@ @import SDWebImage; #endif +#if __has_include("webp/decode.h") && __has_include("webp/encode.h") && __has_include("webp/demux.h") && __has_include("webp/mux.h") +#import "webp/decode.h" +#import "webp/encode.h" +#import "webp/demux.h" +#import "webp/mux.h" +#elif __has_include() && __has_include() && __has_include() && __has_include() +#import +#import +#import +#import +#else +@import libwebp; +#endif + /** Built in coder that supports WebP and animated WebP */ @@ -19,4 +33,8 @@ @property (nonatomic, class, readonly, nonnull) SDImageWebPCoder *sharedCoder; +- (void) updateWebPOptionsToConfig:(WebPConfig * _Nonnull)config + maxFileSize:(NSUInteger)maxFileSize + options:(nullable SDImageCoderOptions *)options; + @end diff --git a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m index 1759fd3..612ed91 100644 --- a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m +++ b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m @@ -841,9 +841,9 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio return webpData; } -- (void) updateWebPOptionsToConfig:(WebPConfig*)config - maxFileSize:(NSUInteger)maxFileSize - options:(nullable SDImageCoderOptions *)options { +- (void) updateWebPOptionsToConfig:(WebPConfig * _Nonnull)config + maxFileSize:(NSUInteger)maxFileSize + options:(nullable SDImageCoderOptions *)options { config->target_size = (int)maxFileSize; // Max filesize for output, 0 means use quality instead config->pass = maxFileSize > 0 ? 6 : 1; // Use 6 passes for file size limited encoding, which is the default value of `cwebp` command line diff --git a/Tests/SDWebImageWebPCoderTests.m b/Tests/SDWebImageWebPCoderTests.m index f2deee5..7583d13 100644 --- a/Tests/SDWebImageWebPCoderTests.m +++ b/Tests/SDWebImageWebPCoderTests.m @@ -10,6 +10,7 @@ @import XCTest; #import #import +#import #import #import @@ -196,6 +197,54 @@ const int64_t kAsyncTestTimeout = 5; XCTAssertLessThanOrEqual(dataWithLimit.length, maxFileSize); } +- (void)testEncodingSettings { + WebPConfig config; + WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, 0.2); + + SDImageCoderOptions *options = @{ SDImageCoderEncodeWebPMethod: @1, + SDImageCoderEncodeWebPPass: @2, + SDImageCoderEncodeWebPPreprocessing: @3, + SDImageCoderEncodeWebPThreadLevel: @4, + SDImageCoderEncodeWebPLowMemory: @5, + SDImageCoderEncodeWebPTargetPSNR: @6, + SDImageCoderEncodeWebPSegments: @7, + SDImageCoderEncodeWebPSnsStrength: @8, + SDImageCoderEncodeWebPFilterStrength: @9, + SDImageCoderEncodeWebPFilterSharpness: @10, + SDImageCoderEncodeWebPFilterType: @11, + SDImageCoderEncodeWebPAutofilter: @12, + SDImageCoderEncodeWebPAlphaCompression: @13, + SDImageCoderEncodeWebPAlphaFiltering: @14, + SDImageCoderEncodeWebPAlphaQuality: @15, + SDImageCoderEncodeWebPShowCompressed: @16, + SDImageCoderEncodeWebPPartitions: @17, + SDImageCoderEncodeWebPPartitionLimit: @18, + SDImageCoderEncodeWebPUseSharpYuv: @19 }; + + [SDImageWebPCoder.sharedCoder updateWebPOptionsToConfig:&config maxFileSize:1200 options:options]; + + expect(config.method).to.equal(1); + expect(config.pass).to.equal(2); + expect(config.preprocessing).to.equal(3); + expect(config.thread_level).to.equal(4); + expect(config.low_memory).to.equal(5); + expect(config.target_PSNR).to.equal(6); + expect(config.segments).to.equal(7); + expect(config.sns_strength).to.equal(8); + expect(config.filter_strength).to.equal(9); + expect(config.filter_sharpness).to.equal(10); + expect(config.filter_type).to.equal(11); + expect(config.autofilter).to.equal(12); + expect(config.alpha_compression).to.equal(13); + expect(config.alpha_filtering).to.equal(14); + expect(config.alpha_quality).to.equal(15); + expect(config.show_compressed).to.equal(16); + expect(config.partitions).to.equal(17); + expect(config.partition_limit).to.equal(18); + expect(config.use_sharp_yuv).to.equal(19); + +} + @end @implementation SDWebImageWebPCoderTests (Helpers) From de7ba8d08e2ba9b76b5c9707113f9be0f1046c58 Mon Sep 17 00:00:00 2001 From: Antti Kortetmaa Date: Fri, 11 Dec 2020 12:09:26 +0200 Subject: [PATCH 3/8] Removed updateWebPOptionsToConfig from the public API of SDImageWebPCoder --- .../Classes/SDImageWebPCoder.h | 18 ------------------ Tests/SDWebImageWebPCoderTests.m | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h index 849259f..7629ded 100644 --- a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h +++ b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h @@ -12,20 +12,6 @@ @import SDWebImage; #endif -#if __has_include("webp/decode.h") && __has_include("webp/encode.h") && __has_include("webp/demux.h") && __has_include("webp/mux.h") -#import "webp/decode.h" -#import "webp/encode.h" -#import "webp/demux.h" -#import "webp/mux.h" -#elif __has_include() && __has_include() && __has_include() && __has_include() -#import -#import -#import -#import -#else -@import libwebp; -#endif - /** Built in coder that supports WebP and animated WebP */ @@ -33,8 +19,4 @@ @property (nonatomic, class, readonly, nonnull) SDImageWebPCoder *sharedCoder; -- (void) updateWebPOptionsToConfig:(WebPConfig * _Nonnull)config - maxFileSize:(NSUInteger)maxFileSize - options:(nullable SDImageCoderOptions *)options; - @end diff --git a/Tests/SDWebImageWebPCoderTests.m b/Tests/SDWebImageWebPCoderTests.m index 7583d13..43ee412 100644 --- a/Tests/SDWebImageWebPCoderTests.m +++ b/Tests/SDWebImageWebPCoderTests.m @@ -13,6 +13,19 @@ #import #import #import +#if __has_include("webp/decode.h") && __has_include("webp/encode.h") && __has_include("webp/demux.h") && __has_include("webp/mux.h") +#import "webp/decode.h" +#import "webp/encode.h" +#import "webp/demux.h" +#import "webp/mux.h" +#elif __has_include() && __has_include() && __has_include() && __has_include() +#import +#import +#import +#import +#else +@import libwebp; +#endif const int64_t kAsyncTestTimeout = 5; @@ -31,6 +44,12 @@ const int64_t kAsyncTestTimeout = 5; @property (nonatomic, assign) NSUInteger blendFromIndex; // The nearest previous frame index which blend mode is WEBP_MUX_BLEND @end +@interface SDImageWebPCoder () +- (void) updateWebPOptionsToConfig:(WebPConfig * _Nonnull)config + maxFileSize:(NSUInteger)maxFileSize + options:(nullable SDImageCoderOptions *)options; +@end + @implementation SDWebImageWebPCoderTests + (void)setUp { From 19b7465deaf2241036e6b6f8111c39a58f470bc5 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Mon, 14 Dec 2020 11:38:10 +0800 Subject: [PATCH 4/8] Update the Xcode Project of WebP encode options --- SDWebImageWebPCoder.xcodeproj/project.pbxproj | 20 ++++--------------- .../Classes/SDWebImageWebPCoderDefine.h | 13 ++++++------ Tests/SDWebImageWebPCoderTests.m | 1 - 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/SDWebImageWebPCoder.xcodeproj/project.pbxproj b/SDWebImageWebPCoder.xcodeproj/project.pbxproj index 86d8a32..b375c0e 100644 --- a/SDWebImageWebPCoder.xcodeproj/project.pbxproj +++ b/SDWebImageWebPCoder.xcodeproj/project.pbxproj @@ -10,10 +10,10 @@ 220A623A257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; 220A623B257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; 220A623C257EAFB300262720 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; - 220A623D257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; - 220A623E257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; - 220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; - 220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; }; + 220A623D257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 220A623E257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Public, ); }; }; 228EA36125825A52005903D9 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; 806E77B32136A2E900A316D2 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 806E77AA2136A2E900A316D2 /* UIImage+WebP.m */; }; 806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AB2136A2E900A316D2 /* SDImageWebPCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -48,7 +48,6 @@ /* Begin PBXFileReference section */ 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageWebPCoderDefine.m; sourceTree = ""; }; 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageWebPCoderDefine.h; sourceTree = ""; }; - 28D8AA3D3015E075692FD3E3 /* Pods-SDWebImageWebPCoderTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageWebPCoderTests.debug.xcconfig"; path = "Tests/Pods/Target Support Files/Pods-SDWebImageWebPCoderTests/Pods-SDWebImageWebPCoderTests.debug.xcconfig"; sourceTree = ""; }; 3217BE7B220547EB003D0310 /* SDWebImageWebPCoder.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = SDWebImageWebPCoder.modulemap; sourceTree = ""; }; 46F21AD7D1692EBAC4D0FF33 /* Pods_SDWebImageWebPCoderTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageWebPCoderTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 806E779D2136A1C000A316D2 /* SDWebImageWebPCoder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImageWebPCoder.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -69,7 +68,6 @@ 80BFF26E2136BE7900B95470 /* SDWebImageWebPCoder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImageWebPCoder.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 80BFF2772136BEE000B95470 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/watchOS/SDWebImage.framework; sourceTree = ""; }; 80BFF2782136BEE000B95470 /* libwebp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libwebp.framework; path = Carthage/Build/watchOS/libwebp.framework; sourceTree = ""; }; - D92E6791BF088D1A101E670E /* Pods-SDWebImageWebPCoderTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageWebPCoderTests.release.xcconfig"; path = "Tests/Pods/Target Support Files/Pods-SDWebImageWebPCoderTests/Pods-SDWebImageWebPCoderTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -112,22 +110,12 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 52FB3B532EE8775B69517E2E /* Pods */ = { - isa = PBXGroup; - children = ( - 28D8AA3D3015E075692FD3E3 /* Pods-SDWebImageWebPCoderTests.debug.xcconfig */, - D92E6791BF088D1A101E670E /* Pods-SDWebImageWebPCoderTests.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; 806E77932136A1C000A316D2 = { isa = PBXGroup; children = ( 806E77A82136A2E900A316D2 /* SDImageWebPCoder */, 806E779E2136A1C000A316D2 /* Products */, 80BFF2312136AA7D00B95470 /* Frameworks */, - 52FB3B532EE8775B69517E2E /* Pods */, ); sourceTree = ""; }; diff --git a/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h b/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h index e04a536..dd972fe 100644 --- a/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h +++ b/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h @@ -1,9 +1,10 @@ -// -// SDWebImageWebPCoderDefine.h -// SDWebImageWebPCoderDefine -// -// Created by Antti Kortetmaa on 2020/12/06. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #if __has_include() #import diff --git a/Tests/SDWebImageWebPCoderTests.m b/Tests/SDWebImageWebPCoderTests.m index 43ee412..97ce68e 100644 --- a/Tests/SDWebImageWebPCoderTests.m +++ b/Tests/SDWebImageWebPCoderTests.m @@ -10,7 +10,6 @@ @import XCTest; #import #import -#import #import #import #if __has_include("webp/decode.h") && __has_include("webp/encode.h") && __has_include("webp/demux.h") && __has_include("webp/mux.h") From ba51befd7c8ab9cde085bfe1a02b222b46eb002a Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Mon, 14 Dec 2020 11:53:45 +0800 Subject: [PATCH 5/8] Replace the dispatch semaphore into os_unfair_lock, copied from SDWebImage Core --- .../Classes/SDImageWebPCoder.m | 53 +++++++++++++++++-- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m index 612ed91..207aa1c 100644 --- a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m +++ b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m @@ -7,6 +7,10 @@ */ #import "SDImageWebPCoder.h" +#import "SDWebImageWebPCoderDefine.h" +#import +#import +#import #if __has_include("webp/decode.h") && __has_include("webp/encode.h") && __has_include("webp/demux.h") && __has_include("webp/mux.h") #import "webp/decode.h" @@ -22,8 +26,47 @@ @import libwebp; #endif -#import -#import "SDWebImageWebPCoderDefine.h" +#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\ + (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\ + (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\ + (__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\ + (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) + +#ifndef SD_LOCK_DECLARE +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK_DECLARE(lock) os_unfair_lock lock +#else +#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \ +OSSpinLock lock##_deprecated; +#endif +#endif + +#ifndef SD_LOCK_INIT +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT +#else +#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \ +else lock##_deprecated = OS_SPINLOCK_INIT; +#endif +#endif + +#ifndef SD_LOCK +#if SD_USE_OS_UNFAIR_LOCK +#define SD_LOCK(lock) os_unfair_lock_lock(&lock) +#else +#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \ +else OSSpinLockLock(&lock##_deprecated); +#endif +#endif + +#ifndef SD_UNLOCK +#if SD_USE_OS_UNFAIR_LOCK +#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock) +#else +#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \ +else OSSpinLockUnlock(&lock##_deprecated); +#endif +#endif /// Calculate the actual thumnail pixel size static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio, CGSize thumbnailSize) { @@ -99,7 +142,7 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio BOOL _finished; CGFloat _canvasWidth; CGFloat _canvasHeight; - dispatch_semaphore_t _lock; + SD_LOCK_DECLARE(_lock); NSUInteger _currentBlendIndex; BOOL _preserveAspectRatio; CGSize _thumbnailSize; @@ -292,7 +335,7 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio } _preserveAspectRatio = preserveAspectRatio; _currentBlendIndex = NSNotFound; - _lock = dispatch_semaphore_create(1); + SD_LOCK_INIT(_lock); } return self; } @@ -975,7 +1018,7 @@ static void FreeImageData(void *info, const void *data, size_t size) { _demux = demuxer; _imageData = data; _currentBlendIndex = NSNotFound; - _lock = dispatch_semaphore_create(1); + SD_LOCK_INIT(_lock); } return self; } From 9158e2429fe18df079b67b71957704ad025b25c5 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Mon, 14 Dec 2020 15:01:11 +0800 Subject: [PATCH 6/8] Update the readme about new libwebp codec options --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index de2a781..31b8441 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,30 @@ let thumbnailWebpData = SDImageWebPCoder.shared.encodedData(with: image, format: See more documentation in [SDWebImage Wiki - Coders](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-coder-420) +### Advanced WebP codec options (0.8+) + +The WebP codec [libwebp](https://developers.google.com/speed/webp/docs/api) we use, supports some advanced control options for encoding/decoding. You can pass them to libwebp by using the wrapper top level API: + +```objective-c +UIImage *image; +SDImageCoderOptions *options = @{SDImageCoderEncodeWebPMethod: @(0), SDImageCoderEncodeWebPAlphaCompression: @(100)}; +NSData *data = [SDImageWebPCoder.sharedCoder encodedDataWithImage:image format:SDImageFormatWebP options:options]; +// Will translate into: +// config->method = 0; +// config->alpha_quality = 100; +``` + ++ Swift + +```swift +let image: UIImage +let options = [.encodeWebPMethod: 0, .encodeWebPAlphaCompression: 100] +let data = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: options) +// Will translate into: +// config->method = 0; +// config->alpha_quality = 100; +``` + ## Example To run the example project, clone the repo, and run `pod install` from the root directory first. Then open `SDWebImageWebPCoder.xcworkspace`. From 8df7931f95af2d8be07a9146c664c442688713c4 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Mon, 14 Dec 2020 15:03:39 +0800 Subject: [PATCH 7/8] Bumped version to 0.8.0 --- SDWebImageWebPCoder.podspec | 2 +- SDWebImageWebPCoder/Module/Info.plist | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SDWebImageWebPCoder.podspec b/SDWebImageWebPCoder.podspec index c5d68b4..2baea59 100644 --- a/SDWebImageWebPCoder.podspec +++ b/SDWebImageWebPCoder.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'SDWebImageWebPCoder' - s.version = '0.7.0' + s.version = '0.8.0' s.summary = 'WebP decoder/encoder for SDWebImage coder plugin.' s.description = <<-DESC diff --git a/SDWebImageWebPCoder/Module/Info.plist b/SDWebImageWebPCoder/Module/Info.plist index 44f8cb0..bdaef62 100644 --- a/SDWebImageWebPCoder/Module/Info.plist +++ b/SDWebImageWebPCoder/Module/Info.plist @@ -15,9 +15,9 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.7.0 + 0.8.0 CFBundleVersion - 0.7.0 + 0.8.0 NSPrincipalClass From 864a71e8f3cd6e39e883691001070c1377e0f004 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Mon, 14 Dec 2020 15:11:35 +0800 Subject: [PATCH 8/8] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 31b8441..70ae978 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,8 @@ See more documentation in [SDWebImage Wiki - Coders](https://github.com/SDWebIma The WebP codec [libwebp](https://developers.google.com/speed/webp/docs/api) we use, supports some advanced control options for encoding/decoding. You can pass them to libwebp by using the wrapper top level API: ++ Objective-C + ```objective-c UIImage *image; SDImageCoderOptions *options = @{SDImageCoderEncodeWebPMethod: @(0), SDImageCoderEncodeWebPAlphaCompression: @(100)};