diff --git a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift index 9d058ef231..4d32cb9b3c 100644 --- a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift +++ b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift @@ -8,6 +8,23 @@ import GZip import YuvConversion import MediaResources +public extension EmojiFitzModifier { + var lottieFitzModifier: LottieFitzModifier { + switch self { + case .type12: + return .type12 + case .type3: + return .type3 + case .type4: + return .type4 + case .type5: + return .type5 + case .type6: + return .type6 + } + } +} + private let sharedQueue = Queue() private let sharedStoreQueue = Queue.concurrentDefaultQueue() @@ -666,7 +683,7 @@ private final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource let rawData = TGGUnzipData(data, 8 * 1024 * 1024) ?? data let decompressedData = transformedWithFitzModifier(data: rawData, fitzModifier: fitzModifier) - guard let animation = LottieInstance(data: decompressedData, cacheKey: "") else { + guard let animation = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, cacheKey: "") else { return nil } self.animation = animation diff --git a/submodules/AnimatedStickerNode/Sources/FitzModifier.swift b/submodules/AnimatedStickerNode/Sources/FitzModifier.swift index 45efaf876f..40dd1a0141 100644 --- a/submodules/AnimatedStickerNode/Sources/FitzModifier.swift +++ b/submodules/AnimatedStickerNode/Sources/FitzModifier.swift @@ -5,72 +5,73 @@ import MediaResources let colorKeyRegex = try? NSRegularExpression(pattern: "\"k\":\\[[\\d\\.]+\\,[\\d\\.]+\\,[\\d\\.]+\\,[\\d\\.]+\\]") public func transformedWithFitzModifier(data: Data, fitzModifier: EmojiFitzModifier?) -> Data { - if let fitzModifier = fitzModifier, var string = String(data: data, encoding: .utf8) { - let colors: [UIColor] = [0xf77e41, 0xffb139, 0xffd140, 0xffdf79].map { UIColor(rgb: $0) } - let replacementColors: [UIColor] - switch fitzModifier { - case .type12: - replacementColors = [0xcb7b55, 0xf6b689, 0xffcda7, 0xffdfc5].map { UIColor(rgb: $0) } - case .type3: - replacementColors = [0xa45a38, 0xdf986b, 0xedb183, 0xf4c3a0].map { UIColor(rgb: $0) } - case .type4: - replacementColors = [0x703a17, 0xab673d, 0xc37f4e, 0xd89667].map { UIColor(rgb: $0) } - case .type5: - replacementColors = [0x4a2409, 0x7d3e0e, 0x965529, 0xa96337].map { UIColor(rgb: $0) } - case .type6: - replacementColors = [0x200f0a, 0x412924, 0x593d37, 0x63453f].map { UIColor(rgb: $0) } - } - - func colorToString(_ color: UIColor) -> String { - var r: CGFloat = 0.0 - var g: CGFloat = 0.0 - var b: CGFloat = 0.0 - if color.getRed(&r, green: &g, blue: &b, alpha: nil) { - return "\"k\":[\(r),\(g),\(b),1]" - } - return "" - } - - func match(_ a: Double, _ b: Double, eps: Double) -> Bool { - return abs(a - b) < eps - } - - var replacements: [(NSTextCheckingResult, String)] = [] - - if let colorKeyRegex = colorKeyRegex { - let results = colorKeyRegex.matches(in: string, range: NSRange(string.startIndex..., in: string)) - for result in results.reversed() { - if let range = Range(result.range, in: string) { - let substring = String(string[range]) - let color = substring[substring.index(string.startIndex, offsetBy: "\"k\":[".count) ..< substring.index(before: substring.endIndex)] - let components = color.split(separator: ",") - if components.count == 4, let r = Double(components[0]), let g = Double(components[1]), let b = Double(components[2]), let a = Double(components[3]) { - if match(a, 1.0, eps: 0.01) { - for i in 0 ..< colors.count { - let color = colors[i] - var cr: CGFloat = 0.0 - var cg: CGFloat = 0.0 - var cb: CGFloat = 0.0 - if color.getRed(&cr, green: &cg, blue: &cb, alpha: nil) { - if match(r, Double(cr), eps: 0.01) && match(g, Double(cg), eps: 0.01) && match(b, Double(cb), eps: 0.01) { - replacements.append((result, colorToString(replacementColors[i]))) - } - } - } - } - } - } - } - } - - for (result, text) in replacements { - if let range = Range(result.range, in: string) { - string = string.replacingCharacters(in: range, with: text) - } - } - - return string.data(using: .utf8) ?? data - } else { - return data - } + return data +// if let fitzModifier = fitzModifier, var string = String(data: data, encoding: .utf8) { +// let colors: [UIColor] = [0xf77e41, 0xffb139, 0xffd140, 0xffdf79].map { UIColor(rgb: $0) } +// let replacementColors: [UIColor] +// switch fitzModifier { +// case .type12: +// replacementColors = [0xcb7b55, 0xf6b689, 0xffcda7, 0xffdfc5].map { UIColor(rgb: $0) } +// case .type3: +// replacementColors = [0xa45a38, 0xdf986b, 0xedb183, 0xf4c3a0].map { UIColor(rgb: $0) } +// case .type4: +// replacementColors = [0x703a17, 0xab673d, 0xc37f4e, 0xd89667].map { UIColor(rgb: $0) } +// case .type5: +// replacementColors = [0x4a2409, 0x7d3e0e, 0x965529, 0xa96337].map { UIColor(rgb: $0) } +// case .type6: +// replacementColors = [0x200f0a, 0x412924, 0x593d37, 0x63453f].map { UIColor(rgb: $0) } +// } +// +// func colorToString(_ color: UIColor) -> String { +// var r: CGFloat = 0.0 +// var g: CGFloat = 0.0 +// var b: CGFloat = 0.0 +// if color.getRed(&r, green: &g, blue: &b, alpha: nil) { +// return "\"k\":[\(r),\(g),\(b),1]" +// } +// return "" +// } +// +// func match(_ a: Double, _ b: Double, eps: Double) -> Bool { +// return abs(a - b) < eps +// } +// +// var replacements: [(NSTextCheckingResult, String)] = [] +// +// if let colorKeyRegex = colorKeyRegex { +// let results = colorKeyRegex.matches(in: string, range: NSRange(string.startIndex..., in: string)) +// for result in results.reversed() { +// if let range = Range(result.range, in: string) { +// let substring = String(string[range]) +// let color = substring[substring.index(string.startIndex, offsetBy: "\"k\":[".count) ..< substring.index(before: substring.endIndex)] +// let components = color.split(separator: ",") +// if components.count == 4, let r = Double(components[0]), let g = Double(components[1]), let b = Double(components[2]), let a = Double(components[3]) { +// if match(a, 1.0, eps: 0.01) { +// for i in 0 ..< colors.count { +// let color = colors[i] +// var cr: CGFloat = 0.0 +// var cg: CGFloat = 0.0 +// var cb: CGFloat = 0.0 +// if color.getRed(&cr, green: &cg, blue: &cb, alpha: nil) { +// if match(r, Double(cr), eps: 0.01) && match(g, Double(cg), eps: 0.01) && match(b, Double(cb), eps: 0.01) { +// replacements.append((result, colorToString(replacementColors[i]))) +// } +// } +// } +// } +// } +// } +// } +// } +// +// for (result, text) in replacements { +// if let range = Range(result.range, in: string) { +// string = string.replacingCharacters(in: range, with: text) +// } +// } +// +// return string.data(using: .utf8) ?? data +// } else { +// return data +// } } diff --git a/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift b/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift index e5a7c6acbe..8e0607511a 100644 --- a/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift +++ b/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift @@ -44,7 +44,7 @@ public final class ManagedAnimationState { guard let unpackedData = TGGUnzipData(data, 5 * 1024 * 1024) else { return nil } - guard let instance = LottieInstance(data: unpackedData, cacheKey: item.source.cacheKey) else { + guard let instance = LottieInstance(data: unpackedData, fitzModifier: .none, cacheKey: item.source.cacheKey) else { return nil } resolvedInstance = instance diff --git a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift index 3599fc09f5..557946930a 100644 --- a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift +++ b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift @@ -27,7 +27,7 @@ public func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, fitzM let decompressedData = TGGUnzipData(data, 8 * 1024 * 1024) if let decompressedData = decompressedData { let decompressedData = transformedWithFitzModifier(data: decompressedData, fitzModifier: fitzModifier) - if let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) { + if let player = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, cacheKey: cacheKey) { if cancelled.with({ $0 }) { return } @@ -126,7 +126,7 @@ public func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: C let decompressedData = TGGUnzipData(data, 8 * 1024 * 1024) if let decompressedData = decompressedData { let decompressedData = transformedWithFitzModifier(data: decompressedData, fitzModifier: fitzModifier) - if let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) { + if let player = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, cacheKey: cacheKey) { let endFrame = Int(player.frameCount) if cancelled.with({ $0 }) { diff --git a/submodules/rlottie/LottieInstance.mm b/submodules/rlottie/LottieInstance.mm index be7f9598f5..654979c2df 100755 --- a/submodules/rlottie/LottieInstance.mm +++ b/submodules/rlottie/LottieInstance.mm @@ -10,10 +10,32 @@ @implementation LottieInstance -- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data cacheKey:(NSString * _Nonnull)cacheKey { +- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data fitzModifier:(LottieFitzModifier)fitzModifier cacheKey:(NSString * _Nonnull)cacheKey { self = [super init]; if (self != nil) { - _animation = rlottie::Animation::loadFromData(std::string(reinterpret_cast(data.bytes), data.length), std::string([cacheKey UTF8String])); + rlottie::FitzModifier modifier; + switch(fitzModifier) { + case LottieFitzModifierNone: + modifier = rlottie::FitzModifier::None; + break; + case LottieFitzModifierType12: + modifier = rlottie::FitzModifier::Type12; + break; + case LottieFitzModifierType3: + modifier = rlottie::FitzModifier::Type3; + break; + case LottieFitzModifierType4: + modifier = rlottie::FitzModifier::Type4; + break; + case LottieFitzModifierType5: + modifier = rlottie::FitzModifier::Type5; + break; + case LottieFitzModifierType6: + modifier = rlottie::FitzModifier::Type6; + break; + } + + _animation = rlottie::Animation::loadFromData(std::string(reinterpret_cast(data.bytes), data.length), std::string([cacheKey UTF8String]), "", true, {}, modifier); if (_animation == nullptr) { return nil; } diff --git a/submodules/rlottie/PublicHeaders/RLottieBinding/LottieInstance.h b/submodules/rlottie/PublicHeaders/RLottieBinding/LottieInstance.h index dd57dcddbe..f926fe08dd 100755 --- a/submodules/rlottie/PublicHeaders/RLottieBinding/LottieInstance.h +++ b/submodules/rlottie/PublicHeaders/RLottieBinding/LottieInstance.h @@ -4,13 +4,22 @@ #import #import +typedef NS_ENUM(int32_t, LottieFitzModifier) { + LottieFitzModifierNone, + LottieFitzModifierType12, + LottieFitzModifierType3, + LottieFitzModifierType4, + LottieFitzModifierType5, + LottieFitzModifierType6 +}; + @interface LottieInstance : NSObject @property (nonatomic, readonly) int32_t frameCount; @property (nonatomic, readonly) int32_t frameRate; @property (nonatomic, readonly) CGSize dimensions; -- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data cacheKey:(NSString * _Nonnull)cacheKey; +- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data fitzModifier:(LottieFitzModifier)fitzModifier cacheKey:(NSString * _Nonnull)cacheKey; - (void)renderFrameWithIndex:(int32_t)index into:(uint8_t * _Nonnull)buffer width:(int32_t)width height:(int32_t)height bytesPerRow:(int32_t)bytesPerRow; @end diff --git a/submodules/rlottie/rlottie b/submodules/rlottie/rlottie index 7fdc010d9e..67f103bc8b 160000 --- a/submodules/rlottie/rlottie +++ b/submodules/rlottie/rlottie @@ -1 +1 @@ -Subproject commit 7fdc010d9e71a0c39d3f63d421d1bef762b6a034 +Subproject commit 67f103bc8b625f2a4a9e94f1d8c7bd84c5a08d1d