diff --git a/Telegram-iOS.xcworkspace/contents.xcworkspacedata b/Telegram-iOS.xcworkspace/contents.xcworkspacedata index 8b5bceb4c8..cad6be2ce4 100644 --- a/Telegram-iOS.xcworkspace/contents.xcworkspacedata +++ b/Telegram-iOS.xcworkspace/contents.xcworkspacedata @@ -1,6 +1,9 @@ + + diff --git a/submodules/Display/Display/GridNode.swift b/submodules/Display/Display/GridNode.swift index 72727165aa..e0f8c2e475 100644 --- a/submodules/Display/Display/GridNode.swift +++ b/submodules/Display/Display/GridNode.swift @@ -217,6 +217,8 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { private var sectionNodes: [WrappedGridSection: ASDisplayNode] = [:] private var itemLayout = GridNodeItemLayout(contentSize: CGSize(), items: [], sections: []) + public var setupNode: ((GridItemNode) -> Void)? + private var applyingContentOffset = false public var visibleItemsUpdated: ((GridNodeVisibleItems) -> Void)? @@ -845,6 +847,7 @@ open class GridNode: GridNodeScroller, UIScrollViewDelegate { self.addItemNode(index: item.index, itemNode: itemNode, lowestSectionNode: lowestSectionNode) addedNodes = true itemNode.updateLayout(item: self.items[item.index], size: item.frame.size, isVisible: bounds.intersects(item.frame), synchronousLoads: synchronousLoads) + self.setupNode?(itemNode) } } diff --git a/submodules/RLottie/Info.plist b/submodules/RLottie/Info.plist new file mode 100644 index 0000000000..e1fe4cfb7b --- /dev/null +++ b/submodules/RLottie/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/submodules/RLottie/RLottie_Xcode.xcodeproj/project.pbxproj b/submodules/RLottie/RLottie_Xcode.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..099862aed2 --- /dev/null +++ b/submodules/RLottie/RLottie_Xcode.xcodeproj/project.pbxproj @@ -0,0 +1,875 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + D010DF4122C225E4009324D4 /* RLottie.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF3F22C225E4009324D4 /* RLottie.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D010E07022C237CE009324D4 /* rlottiecommon.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF4D22C237CE009324D4 /* rlottiecommon.h */; }; + D010E07222C237CE009324D4 /* rlottie.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF4F22C237CE009324D4 /* rlottie.h */; }; + D010E07322C237CE009324D4 /* rlottie_capi.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF5022C237CE009324D4 /* rlottie_capi.h */; }; + D010E10422C237CE009324D4 /* lottieanimation_capi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DFEC22C237CE009324D4 /* lottieanimation_capi.cpp */; }; + D010E10722C237CE009324D4 /* lottiemodel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DFF022C237CE009324D4 /* lottiemodel.cpp */; }; + D010E10822C237CE009324D4 /* lottieitem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DFF122C237CE009324D4 /* lottieitem.cpp */; }; + D010E10A22C237CE009324D4 /* lottieanimation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DFF322C237CE009324D4 /* lottieanimation.cpp */; }; + D010E10B22C237CE009324D4 /* lottiekeypath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DFF422C237CE009324D4 /* lottiekeypath.cpp */; }; + D010E10C22C237CE009324D4 /* lottieparser.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DFF522C237CE009324D4 /* lottieparser.h */; }; + D010E10D22C237CE009324D4 /* lottieparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DFF622C237CE009324D4 /* lottieparser.cpp */; }; + D010E10E22C237CE009324D4 /* lottieloader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DFF722C237CE009324D4 /* lottieloader.cpp */; }; + D010E10F22C237CE009324D4 /* lottieitem.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DFF822C237CE009324D4 /* lottieitem.h */; }; + D010E11022C237CE009324D4 /* lottiekeypath.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DFF922C237CE009324D4 /* lottiekeypath.h */; }; + D010E11222C237CE009324D4 /* lottieproxymodel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DFFB22C237CE009324D4 /* lottieproxymodel.cpp */; }; + D010E11322C237CE009324D4 /* fwd.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DFFD22C237CE009324D4 /* fwd.h */; }; + D010E11422C237CE009324D4 /* memorystream.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DFFE22C237CE009324D4 /* memorystream.h */; }; + D010E11522C237CE009324D4 /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DFFF22C237CE009324D4 /* reader.h */; }; + D010E11622C237CE009324D4 /* prettywriter.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00022C237CE009324D4 /* prettywriter.h */; }; + D010E11722C237CE009324D4 /* ostreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00122C237CE009324D4 /* ostreamwrapper.h */; }; + D010E11822C237CE009324D4 /* encodedstream.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00222C237CE009324D4 /* encodedstream.h */; }; + D010E11922C237CE009324D4 /* filereadstream.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00322C237CE009324D4 /* filereadstream.h */; }; + D010E11A22C237CE009324D4 /* cursorstreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00422C237CE009324D4 /* cursorstreamwrapper.h */; }; + D010E11B22C237CE009324D4 /* istreamwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00522C237CE009324D4 /* istreamwrapper.h */; }; + D010E11C22C237CE009324D4 /* stringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00622C237CE009324D4 /* stringbuffer.h */; }; + D010E11D22C237CE009324D4 /* ieee754.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00822C237CE009324D4 /* ieee754.h */; }; + D010E11E22C237CE009324D4 /* strtod.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00922C237CE009324D4 /* strtod.h */; }; + D010E11F22C237CE009324D4 /* swap.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00A22C237CE009324D4 /* swap.h */; }; + D010E12022C237CE009324D4 /* regex.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00B22C237CE009324D4 /* regex.h */; }; + D010E12122C237CE009324D4 /* diyfp.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00C22C237CE009324D4 /* diyfp.h */; }; + D010E12222C237CE009324D4 /* biginteger.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00D22C237CE009324D4 /* biginteger.h */; }; + D010E12322C237CE009324D4 /* strfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00E22C237CE009324D4 /* strfunc.h */; }; + D010E12422C237CE009324D4 /* itoa.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E00F22C237CE009324D4 /* itoa.h */; }; + D010E12522C237CE009324D4 /* stack.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01022C237CE009324D4 /* stack.h */; }; + D010E12622C237CE009324D4 /* dtoa.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01122C237CE009324D4 /* dtoa.h */; }; + D010E12722C237CE009324D4 /* meta.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01222C237CE009324D4 /* meta.h */; }; + D010E12822C237CE009324D4 /* pow10.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01322C237CE009324D4 /* pow10.h */; }; + D010E12922C237CE009324D4 /* encodings.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01422C237CE009324D4 /* encodings.h */; }; + D010E12A22C237CE009324D4 /* schema.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01522C237CE009324D4 /* schema.h */; }; + D010E12B22C237CE009324D4 /* stream.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01622C237CE009324D4 /* stream.h */; }; + D010E12C22C237CE009324D4 /* filewritestream.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01722C237CE009324D4 /* filewritestream.h */; }; + D010E12D22C237CE009324D4 /* rapidjson.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01822C237CE009324D4 /* rapidjson.h */; }; + D010E12E22C237CE009324D4 /* document.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01922C237CE009324D4 /* document.h */; }; + D010E12F22C237CE009324D4 /* allocators.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01A22C237CE009324D4 /* allocators.h */; }; + D010E13022C237CE009324D4 /* writer.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01B22C237CE009324D4 /* writer.h */; }; + D010E13122C237CE009324D4 /* error.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01D22C237CE009324D4 /* error.h */; }; + D010E13222C237CE009324D4 /* en.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01E22C237CE009324D4 /* en.h */; }; + D010E13322C237CE009324D4 /* memorybuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E01F22C237CE009324D4 /* memorybuffer.h */; }; + D010E13422C237CE009324D4 /* pointer.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E02022C237CE009324D4 /* pointer.h */; }; + D010E13722C237CE009324D4 /* lottieproxymodel.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E02422C237CE009324D4 /* lottieproxymodel.h */; }; + D010E13822C237CE009324D4 /* lottiemodel.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E02522C237CE009324D4 /* lottiemodel.h */; }; + D010E13922C237CE009324D4 /* lottieloader.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E02622C237CE009324D4 /* lottieloader.h */; }; + D010E13A22C237CE009324D4 /* vdasher.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E02822C237CE009324D4 /* vdasher.h */; }; + D010E13B22C237CE009324D4 /* vrle.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E02922C237CE009324D4 /* vrle.h */; }; + D010E13C22C237CE009324D4 /* velapsedtimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E02A22C237CE009324D4 /* velapsedtimer.cpp */; }; + D010E13E22C237CE009324D4 /* velapsedtimer.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E02C22C237CE009324D4 /* velapsedtimer.h */; }; + D010E14022C237CE009324D4 /* vrect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E02E22C237CE009324D4 /* vrect.cpp */; }; + D010E14122C237CF009324D4 /* vdasher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E02F22C237CE009324D4 /* vdasher.cpp */; }; + D010E14222C237CF009324D4 /* vbezier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E03022C237CE009324D4 /* vbezier.cpp */; }; + D010E14422C237CF009324D4 /* pixman-arm-neon-asm.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E03322C237CE009324D4 /* pixman-arm-neon-asm.h */; }; + D010E14522C237CF009324D4 /* vregion.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E03422C237CE009324D4 /* vregion.h */; }; + D010E14822C237CF009324D4 /* vregion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E03722C237CE009324D4 /* vregion.cpp */; }; + D010E14922C237CF009324D4 /* vpath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E03822C237CE009324D4 /* vpath.cpp */; }; + D010E14A22C237CF009324D4 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E03922C237CE009324D4 /* config.h */; }; + D010E14C22C237CF009324D4 /* v_ft_types.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E03C22C237CE009324D4 /* v_ft_types.h */; }; + D010E14D22C237CF009324D4 /* v_ft_raster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E03D22C237CE009324D4 /* v_ft_raster.cpp */; }; + D010E14F22C237CF009324D4 /* v_ft_stroker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E03F22C237CE009324D4 /* v_ft_stroker.cpp */; }; + D010E15022C237CF009324D4 /* v_ft_math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E04022C237CE009324D4 /* v_ft_math.cpp */; }; + D010E15122C237CF009324D4 /* v_ft_stroker.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04122C237CE009324D4 /* v_ft_stroker.h */; }; + D010E15222C237CF009324D4 /* v_ft_math.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04222C237CE009324D4 /* v_ft_math.h */; }; + D010E15322C237CF009324D4 /* v_ft_raster.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04322C237CE009324D4 /* v_ft_raster.h */; }; + D010E15422C237CF009324D4 /* vcompositionfunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E04422C237CE009324D4 /* vcompositionfunctions.cpp */; }; + D010E15522C237CF009324D4 /* vdrawhelper.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04522C237CE009324D4 /* vdrawhelper.h */; }; + D010E15622C237CF009324D4 /* vbitmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E04622C237CE009324D4 /* vbitmap.cpp */; }; + D010E15722C237CF009324D4 /* vdrawable.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04722C237CE009324D4 /* vdrawable.h */; }; + D010E15822C237CF009324D4 /* vbitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04822C237CE009324D4 /* vbitmap.h */; }; + D010E15922C237CF009324D4 /* vpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04922C237CE009324D4 /* vpoint.h */; }; + D010E15A22C237CF009324D4 /* vpathmesure.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04A22C237CE009324D4 /* vpathmesure.h */; }; + D010E15B22C237CF009324D4 /* vdebug.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04B22C237CE009324D4 /* vdebug.h */; }; + D010E15C22C237CF009324D4 /* vpath.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E04C22C237CE009324D4 /* vpath.h */; }; + D010E15F22C237CF009324D4 /* stb_image.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E05022C237CE009324D4 /* stb_image.h */; }; + D010E16022C237CF009324D4 /* stb_image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E05122C237CE009324D4 /* stb_image.cpp */; }; + D010E16222C237CF009324D4 /* vtaskqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E05322C237CE009324D4 /* vtaskqueue.h */; }; + D010E16322C237CF009324D4 /* vline.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E05422C237CE009324D4 /* vline.h */; }; + D010E16422C237CF009324D4 /* vdrawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E05522C237CE009324D4 /* vdrawable.cpp */; }; + D010E16522C237CF009324D4 /* vpathmesure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E05622C237CE009324D4 /* vpathmesure.cpp */; }; + D010E16622C237CF009324D4 /* vbrush.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E05722C237CE009324D4 /* vbrush.h */; }; + D010E16722C237CF009324D4 /* vpainter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E05822C237CE009324D4 /* vpainter.cpp */; }; + D010E16822C237CF009324D4 /* vdebug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E05922C237CE009324D4 /* vdebug.cpp */; }; + D010E16922C237CF009324D4 /* vimageloader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E05A22C237CE009324D4 /* vimageloader.cpp */; }; + D010E16A22C237CF009324D4 /* vglobal.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E05B22C237CE009324D4 /* vglobal.h */; }; + D010E16B22C237CF009324D4 /* vraster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E05C22C237CE009324D4 /* vraster.cpp */; }; + D010E16C22C237CF009324D4 /* vpainter.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E05D22C237CE009324D4 /* vpainter.h */; }; + D010E16D22C237CF009324D4 /* vmatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E05E22C237CE009324D4 /* vmatrix.cpp */; }; + D010E16E22C237CF009324D4 /* vrect.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E05F22C237CE009324D4 /* vrect.h */; }; + D010E16F22C237CF009324D4 /* vinterpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E06022C237CE009324D4 /* vinterpolator.h */; }; + D010E17022C237CF009324D4 /* vbezier.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E06122C237CE009324D4 /* vbezier.h */; }; + D010E17122C237CF009324D4 /* vdrawhelper_sse2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E06222C237CE009324D4 /* vdrawhelper_sse2.cpp */; }; + D010E17222C237CF009324D4 /* vinterpolator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E06322C237CE009324D4 /* vinterpolator.cpp */; }; + D010E17322C237CF009324D4 /* vdrawhelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E06422C237CE009324D4 /* vdrawhelper.cpp */; }; + D010E17422C237CF009324D4 /* vstackallocator.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E06522C237CE009324D4 /* vstackallocator.h */; }; + D010E17522C237CF009324D4 /* vimageloader.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E06622C237CE009324D4 /* vimageloader.h */; }; + D010E17622C237CF009324D4 /* vraster.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E06722C237CE009324D4 /* vraster.h */; }; + D010E17722C237CF009324D4 /* vmatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E06822C237CE009324D4 /* vmatrix.h */; }; + D010E17822C237CF009324D4 /* vrle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E06922C237CE009324D4 /* vrle.cpp */; }; + D010E17922C237CF009324D4 /* vcowptr.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E06A22C237CE009324D4 /* vcowptr.h */; }; + D010E17A22C237CF009324D4 /* vbrush.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010E06B22C237CE009324D4 /* vbrush.cpp */; }; + D010E17F22C23C42009324D4 /* LottieInstance.mm in Sources */ = {isa = PBXBuildFile; fileRef = D010E17E22C23C42009324D4 /* LottieInstance.mm */; }; + D010E18122C23D57009324D4 /* LottieInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = D010E18022C23D57009324D4 /* LottieInstance.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + D010DF3C22C225E4009324D4 /* RLottie.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RLottie.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D010DF3F22C225E4009324D4 /* RLottie.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RLottie.h; sourceTree = ""; }; + D010DF4022C225E4009324D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D010DF4D22C237CE009324D4 /* rlottiecommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rlottiecommon.h; sourceTree = ""; }; + D010DF4F22C237CE009324D4 /* rlottie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rlottie.h; sourceTree = ""; }; + D010DF5022C237CE009324D4 /* rlottie_capi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rlottie_capi.h; sourceTree = ""; }; + D010DFEC22C237CE009324D4 /* lottieanimation_capi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lottieanimation_capi.cpp; sourceTree = ""; }; + D010DFF022C237CE009324D4 /* lottiemodel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lottiemodel.cpp; sourceTree = ""; }; + D010DFF122C237CE009324D4 /* lottieitem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lottieitem.cpp; sourceTree = ""; }; + D010DFF322C237CE009324D4 /* lottieanimation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lottieanimation.cpp; sourceTree = ""; }; + D010DFF422C237CE009324D4 /* lottiekeypath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lottiekeypath.cpp; sourceTree = ""; }; + D010DFF522C237CE009324D4 /* lottieparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lottieparser.h; sourceTree = ""; }; + D010DFF622C237CE009324D4 /* lottieparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lottieparser.cpp; sourceTree = ""; }; + D010DFF722C237CE009324D4 /* lottieloader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lottieloader.cpp; sourceTree = ""; }; + D010DFF822C237CE009324D4 /* lottieitem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lottieitem.h; sourceTree = ""; }; + D010DFF922C237CE009324D4 /* lottiekeypath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lottiekeypath.h; sourceTree = ""; }; + D010DFFB22C237CE009324D4 /* lottieproxymodel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lottieproxymodel.cpp; sourceTree = ""; }; + D010DFFD22C237CE009324D4 /* fwd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fwd.h; sourceTree = ""; }; + D010DFFE22C237CE009324D4 /* memorystream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memorystream.h; sourceTree = ""; }; + D010DFFF22C237CE009324D4 /* reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = ""; }; + D010E00022C237CE009324D4 /* prettywriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prettywriter.h; sourceTree = ""; }; + D010E00122C237CE009324D4 /* ostreamwrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ostreamwrapper.h; sourceTree = ""; }; + D010E00222C237CE009324D4 /* encodedstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encodedstream.h; sourceTree = ""; }; + D010E00322C237CE009324D4 /* filereadstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filereadstream.h; sourceTree = ""; }; + D010E00422C237CE009324D4 /* cursorstreamwrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursorstreamwrapper.h; sourceTree = ""; }; + D010E00522C237CE009324D4 /* istreamwrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = istreamwrapper.h; sourceTree = ""; }; + D010E00622C237CE009324D4 /* stringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringbuffer.h; sourceTree = ""; }; + D010E00822C237CE009324D4 /* ieee754.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ieee754.h; sourceTree = ""; }; + D010E00922C237CE009324D4 /* strtod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strtod.h; sourceTree = ""; }; + D010E00A22C237CE009324D4 /* swap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = swap.h; sourceTree = ""; }; + D010E00B22C237CE009324D4 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = ""; }; + D010E00C22C237CE009324D4 /* diyfp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = diyfp.h; sourceTree = ""; }; + D010E00D22C237CE009324D4 /* biginteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = biginteger.h; sourceTree = ""; }; + D010E00E22C237CE009324D4 /* strfunc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strfunc.h; sourceTree = ""; }; + D010E00F22C237CE009324D4 /* itoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = itoa.h; sourceTree = ""; }; + D010E01022C237CE009324D4 /* stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack.h; sourceTree = ""; }; + D010E01122C237CE009324D4 /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = ""; }; + D010E01222C237CE009324D4 /* meta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = meta.h; sourceTree = ""; }; + D010E01322C237CE009324D4 /* pow10.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pow10.h; sourceTree = ""; }; + D010E01422C237CE009324D4 /* encodings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encodings.h; sourceTree = ""; }; + D010E01522C237CE009324D4 /* schema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = schema.h; sourceTree = ""; }; + D010E01622C237CE009324D4 /* stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stream.h; sourceTree = ""; }; + D010E01722C237CE009324D4 /* filewritestream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filewritestream.h; sourceTree = ""; }; + D010E01822C237CE009324D4 /* rapidjson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rapidjson.h; sourceTree = ""; }; + D010E01922C237CE009324D4 /* document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = document.h; sourceTree = ""; }; + D010E01A22C237CE009324D4 /* allocators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = allocators.h; sourceTree = ""; }; + D010E01B22C237CE009324D4 /* writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = writer.h; sourceTree = ""; }; + D010E01D22C237CE009324D4 /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = ""; }; + D010E01E22C237CE009324D4 /* en.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = en.h; sourceTree = ""; }; + D010E01F22C237CE009324D4 /* memorybuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memorybuffer.h; sourceTree = ""; }; + D010E02022C237CE009324D4 /* pointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pointer.h; sourceTree = ""; }; + D010E02422C237CE009324D4 /* lottieproxymodel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lottieproxymodel.h; sourceTree = ""; }; + D010E02522C237CE009324D4 /* lottiemodel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lottiemodel.h; sourceTree = ""; }; + D010E02622C237CE009324D4 /* lottieloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lottieloader.h; sourceTree = ""; }; + D010E02822C237CE009324D4 /* vdasher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vdasher.h; sourceTree = ""; }; + D010E02922C237CE009324D4 /* vrle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vrle.h; sourceTree = ""; }; + D010E02A22C237CE009324D4 /* velapsedtimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = velapsedtimer.cpp; sourceTree = ""; }; + D010E02B22C237CE009324D4 /* vdrawhelper_neon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdrawhelper_neon.cpp; sourceTree = ""; }; + D010E02C22C237CE009324D4 /* velapsedtimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = velapsedtimer.h; sourceTree = ""; }; + D010E02E22C237CE009324D4 /* vrect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vrect.cpp; sourceTree = ""; }; + D010E02F22C237CE009324D4 /* vdasher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdasher.cpp; sourceTree = ""; }; + D010E03022C237CE009324D4 /* vbezier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vbezier.cpp; sourceTree = ""; }; + D010E03322C237CE009324D4 /* pixman-arm-neon-asm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "pixman-arm-neon-asm.h"; sourceTree = ""; }; + D010E03422C237CE009324D4 /* vregion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vregion.h; sourceTree = ""; }; + D010E03522C237CE009324D4 /* pixman-arm-neon-asm.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = "pixman-arm-neon-asm.S"; sourceTree = ""; }; + D010E03722C237CE009324D4 /* vregion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vregion.cpp; sourceTree = ""; }; + D010E03822C237CE009324D4 /* vpath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vpath.cpp; sourceTree = ""; }; + D010E03922C237CE009324D4 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; + D010E03C22C237CE009324D4 /* v_ft_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v_ft_types.h; sourceTree = ""; }; + D010E03D22C237CE009324D4 /* v_ft_raster.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = v_ft_raster.cpp; sourceTree = ""; }; + D010E03F22C237CE009324D4 /* v_ft_stroker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = v_ft_stroker.cpp; sourceTree = ""; }; + D010E04022C237CE009324D4 /* v_ft_math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = v_ft_math.cpp; sourceTree = ""; }; + D010E04122C237CE009324D4 /* v_ft_stroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v_ft_stroker.h; sourceTree = ""; }; + D010E04222C237CE009324D4 /* v_ft_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v_ft_math.h; sourceTree = ""; }; + D010E04322C237CE009324D4 /* v_ft_raster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v_ft_raster.h; sourceTree = ""; }; + D010E04422C237CE009324D4 /* vcompositionfunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vcompositionfunctions.cpp; sourceTree = ""; }; + D010E04522C237CE009324D4 /* vdrawhelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vdrawhelper.h; sourceTree = ""; }; + D010E04622C237CE009324D4 /* vbitmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vbitmap.cpp; sourceTree = ""; }; + D010E04722C237CE009324D4 /* vdrawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vdrawable.h; sourceTree = ""; }; + D010E04822C237CE009324D4 /* vbitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vbitmap.h; sourceTree = ""; }; + D010E04922C237CE009324D4 /* vpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vpoint.h; sourceTree = ""; }; + D010E04A22C237CE009324D4 /* vpathmesure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vpathmesure.h; sourceTree = ""; }; + D010E04B22C237CE009324D4 /* vdebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vdebug.h; sourceTree = ""; }; + D010E04C22C237CE009324D4 /* vpath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vpath.h; sourceTree = ""; }; + D010E05022C237CE009324D4 /* stb_image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_image.h; sourceTree = ""; }; + D010E05122C237CE009324D4 /* stb_image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stb_image.cpp; sourceTree = ""; }; + D010E05322C237CE009324D4 /* vtaskqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vtaskqueue.h; sourceTree = ""; }; + D010E05422C237CE009324D4 /* vline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vline.h; sourceTree = ""; }; + D010E05522C237CE009324D4 /* vdrawable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdrawable.cpp; sourceTree = ""; }; + D010E05622C237CE009324D4 /* vpathmesure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vpathmesure.cpp; sourceTree = ""; }; + D010E05722C237CE009324D4 /* vbrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vbrush.h; sourceTree = ""; }; + D010E05822C237CE009324D4 /* vpainter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vpainter.cpp; sourceTree = ""; }; + D010E05922C237CE009324D4 /* vdebug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdebug.cpp; sourceTree = ""; }; + D010E05A22C237CE009324D4 /* vimageloader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vimageloader.cpp; sourceTree = ""; }; + D010E05B22C237CE009324D4 /* vglobal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vglobal.h; sourceTree = ""; }; + D010E05C22C237CE009324D4 /* vraster.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vraster.cpp; sourceTree = ""; }; + D010E05D22C237CE009324D4 /* vpainter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vpainter.h; sourceTree = ""; }; + D010E05E22C237CE009324D4 /* vmatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vmatrix.cpp; sourceTree = ""; }; + D010E05F22C237CE009324D4 /* vrect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vrect.h; sourceTree = ""; }; + D010E06022C237CE009324D4 /* vinterpolator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vinterpolator.h; sourceTree = ""; }; + D010E06122C237CE009324D4 /* vbezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vbezier.h; sourceTree = ""; }; + D010E06222C237CE009324D4 /* vdrawhelper_sse2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdrawhelper_sse2.cpp; sourceTree = ""; }; + D010E06322C237CE009324D4 /* vinterpolator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vinterpolator.cpp; sourceTree = ""; }; + D010E06422C237CE009324D4 /* vdrawhelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdrawhelper.cpp; sourceTree = ""; }; + D010E06522C237CE009324D4 /* vstackallocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstackallocator.h; sourceTree = ""; }; + D010E06622C237CE009324D4 /* vimageloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vimageloader.h; sourceTree = ""; }; + D010E06722C237CE009324D4 /* vraster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vraster.h; sourceTree = ""; }; + D010E06822C237CE009324D4 /* vmatrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vmatrix.h; sourceTree = ""; }; + D010E06922C237CE009324D4 /* vrle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vrle.cpp; sourceTree = ""; }; + D010E06A22C237CE009324D4 /* vcowptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vcowptr.h; sourceTree = ""; }; + D010E06B22C237CE009324D4 /* vbrush.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vbrush.cpp; sourceTree = ""; }; + D010E17E22C23C42009324D4 /* LottieInstance.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LottieInstance.mm; sourceTree = ""; }; + D010E18022C23D57009324D4 /* LottieInstance.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LottieInstance.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + D010DF3922C225E4009324D4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + D010DF3222C225E4009324D4 = { + isa = PBXGroup; + children = ( + D010DF4022C225E4009324D4 /* Info.plist */, + D010DF3E22C225E4009324D4 /* Sources */, + D010DF3D22C225E4009324D4 /* Products */, + ); + sourceTree = ""; + }; + D010DF3D22C225E4009324D4 /* Products */ = { + isa = PBXGroup; + children = ( + D010DF3C22C225E4009324D4 /* RLottie.framework */, + ); + name = Products; + sourceTree = ""; + }; + D010DF3E22C225E4009324D4 /* Sources */ = { + isa = PBXGroup; + children = ( + D010DF4722C237CE009324D4 /* rlottie */, + D010DF3F22C225E4009324D4 /* RLottie.h */, + D010E18022C23D57009324D4 /* LottieInstance.h */, + D010E17E22C23C42009324D4 /* LottieInstance.mm */, + ); + path = Sources; + sourceTree = ""; + }; + D010DF4722C237CE009324D4 /* rlottie */ = { + isa = PBXGroup; + children = ( + D010DF4B22C237CE009324D4 /* inc */, + D010DFE422C237CE009324D4 /* src */, + ); + path = rlottie; + sourceTree = ""; + }; + D010DF4B22C237CE009324D4 /* inc */ = { + isa = PBXGroup; + children = ( + D010DF4D22C237CE009324D4 /* rlottiecommon.h */, + D010DF4F22C237CE009324D4 /* rlottie.h */, + D010DF5022C237CE009324D4 /* rlottie_capi.h */, + ); + path = inc; + sourceTree = ""; + }; + D010DFE422C237CE009324D4 /* src */ = { + isa = PBXGroup; + children = ( + D010DFE622C237CE009324D4 /* binding */, + D010DFEF22C237CE009324D4 /* lottie */, + D010E02722C237CE009324D4 /* vector */, + ); + path = src; + sourceTree = ""; + }; + D010DFE622C237CE009324D4 /* binding */ = { + isa = PBXGroup; + children = ( + D010DFEA22C237CE009324D4 /* c */, + ); + path = binding; + sourceTree = ""; + }; + D010DFEA22C237CE009324D4 /* c */ = { + isa = PBXGroup; + children = ( + D010DFEC22C237CE009324D4 /* lottieanimation_capi.cpp */, + ); + path = c; + sourceTree = ""; + }; + D010DFEF22C237CE009324D4 /* lottie */ = { + isa = PBXGroup; + children = ( + D010DFF022C237CE009324D4 /* lottiemodel.cpp */, + D010DFF122C237CE009324D4 /* lottieitem.cpp */, + D010DFF322C237CE009324D4 /* lottieanimation.cpp */, + D010DFF422C237CE009324D4 /* lottiekeypath.cpp */, + D010DFF522C237CE009324D4 /* lottieparser.h */, + D010DFF622C237CE009324D4 /* lottieparser.cpp */, + D010DFF722C237CE009324D4 /* lottieloader.cpp */, + D010DFF822C237CE009324D4 /* lottieitem.h */, + D010DFF922C237CE009324D4 /* lottiekeypath.h */, + D010DFFB22C237CE009324D4 /* lottieproxymodel.cpp */, + D010DFFC22C237CE009324D4 /* rapidjson */, + D010E02422C237CE009324D4 /* lottieproxymodel.h */, + D010E02522C237CE009324D4 /* lottiemodel.h */, + D010E02622C237CE009324D4 /* lottieloader.h */, + ); + path = lottie; + sourceTree = ""; + }; + D010DFFC22C237CE009324D4 /* rapidjson */ = { + isa = PBXGroup; + children = ( + D010DFFD22C237CE009324D4 /* fwd.h */, + D010DFFE22C237CE009324D4 /* memorystream.h */, + D010DFFF22C237CE009324D4 /* reader.h */, + D010E00022C237CE009324D4 /* prettywriter.h */, + D010E00122C237CE009324D4 /* ostreamwrapper.h */, + D010E00222C237CE009324D4 /* encodedstream.h */, + D010E00322C237CE009324D4 /* filereadstream.h */, + D010E00422C237CE009324D4 /* cursorstreamwrapper.h */, + D010E00522C237CE009324D4 /* istreamwrapper.h */, + D010E00622C237CE009324D4 /* stringbuffer.h */, + D010E00722C237CE009324D4 /* internal */, + D010E01422C237CE009324D4 /* encodings.h */, + D010E01522C237CE009324D4 /* schema.h */, + D010E01622C237CE009324D4 /* stream.h */, + D010E01722C237CE009324D4 /* filewritestream.h */, + D010E01822C237CE009324D4 /* rapidjson.h */, + D010E01922C237CE009324D4 /* document.h */, + D010E01A22C237CE009324D4 /* allocators.h */, + D010E01B22C237CE009324D4 /* writer.h */, + D010E01C22C237CE009324D4 /* error */, + D010E01F22C237CE009324D4 /* memorybuffer.h */, + D010E02022C237CE009324D4 /* pointer.h */, + ); + path = rapidjson; + sourceTree = ""; + }; + D010E00722C237CE009324D4 /* internal */ = { + isa = PBXGroup; + children = ( + D010E00822C237CE009324D4 /* ieee754.h */, + D010E00922C237CE009324D4 /* strtod.h */, + D010E00A22C237CE009324D4 /* swap.h */, + D010E00B22C237CE009324D4 /* regex.h */, + D010E00C22C237CE009324D4 /* diyfp.h */, + D010E00D22C237CE009324D4 /* biginteger.h */, + D010E00E22C237CE009324D4 /* strfunc.h */, + D010E00F22C237CE009324D4 /* itoa.h */, + D010E01022C237CE009324D4 /* stack.h */, + D010E01122C237CE009324D4 /* dtoa.h */, + D010E01222C237CE009324D4 /* meta.h */, + D010E01322C237CE009324D4 /* pow10.h */, + ); + path = internal; + sourceTree = ""; + }; + D010E01C22C237CE009324D4 /* error */ = { + isa = PBXGroup; + children = ( + D010E01D22C237CE009324D4 /* error.h */, + D010E01E22C237CE009324D4 /* en.h */, + ); + path = error; + sourceTree = ""; + }; + D010E02722C237CE009324D4 /* vector */ = { + isa = PBXGroup; + children = ( + D010E02822C237CE009324D4 /* vdasher.h */, + D010E02922C237CE009324D4 /* vrle.h */, + D010E02A22C237CE009324D4 /* velapsedtimer.cpp */, + D010E02B22C237CE009324D4 /* vdrawhelper_neon.cpp */, + D010E02C22C237CE009324D4 /* velapsedtimer.h */, + D010E02E22C237CE009324D4 /* vrect.cpp */, + D010E02F22C237CE009324D4 /* vdasher.cpp */, + D010E03022C237CE009324D4 /* vbezier.cpp */, + D010E03122C237CE009324D4 /* pixman */, + D010E03822C237CE009324D4 /* vpath.cpp */, + D010E03922C237CE009324D4 /* config.h */, + D010E03A22C237CE009324D4 /* freetype */, + D010E04422C237CE009324D4 /* vcompositionfunctions.cpp */, + D010E04522C237CE009324D4 /* vdrawhelper.h */, + D010E04622C237CE009324D4 /* vbitmap.cpp */, + D010E04722C237CE009324D4 /* vdrawable.h */, + D010E04822C237CE009324D4 /* vbitmap.h */, + D010E04922C237CE009324D4 /* vpoint.h */, + D010E04A22C237CE009324D4 /* vpathmesure.h */, + D010E04B22C237CE009324D4 /* vdebug.h */, + D010E04C22C237CE009324D4 /* vpath.h */, + D010E04D22C237CE009324D4 /* stb */, + D010E05322C237CE009324D4 /* vtaskqueue.h */, + D010E05422C237CE009324D4 /* vline.h */, + D010E05522C237CE009324D4 /* vdrawable.cpp */, + D010E05622C237CE009324D4 /* vpathmesure.cpp */, + D010E05722C237CE009324D4 /* vbrush.h */, + D010E05822C237CE009324D4 /* vpainter.cpp */, + D010E05922C237CE009324D4 /* vdebug.cpp */, + D010E05A22C237CE009324D4 /* vimageloader.cpp */, + D010E05B22C237CE009324D4 /* vglobal.h */, + D010E05C22C237CE009324D4 /* vraster.cpp */, + D010E05D22C237CE009324D4 /* vpainter.h */, + D010E05E22C237CE009324D4 /* vmatrix.cpp */, + D010E05F22C237CE009324D4 /* vrect.h */, + D010E06022C237CE009324D4 /* vinterpolator.h */, + D010E06122C237CE009324D4 /* vbezier.h */, + D010E06222C237CE009324D4 /* vdrawhelper_sse2.cpp */, + D010E06322C237CE009324D4 /* vinterpolator.cpp */, + D010E06422C237CE009324D4 /* vdrawhelper.cpp */, + D010E06522C237CE009324D4 /* vstackallocator.h */, + D010E06622C237CE009324D4 /* vimageloader.h */, + D010E06722C237CE009324D4 /* vraster.h */, + D010E06822C237CE009324D4 /* vmatrix.h */, + D010E06922C237CE009324D4 /* vrle.cpp */, + D010E06A22C237CE009324D4 /* vcowptr.h */, + D010E06B22C237CE009324D4 /* vbrush.cpp */, + ); + path = vector; + sourceTree = ""; + }; + D010E03122C237CE009324D4 /* pixman */ = { + isa = PBXGroup; + children = ( + D010E03322C237CE009324D4 /* pixman-arm-neon-asm.h */, + D010E03422C237CE009324D4 /* vregion.h */, + D010E03522C237CE009324D4 /* pixman-arm-neon-asm.S */, + D010E03722C237CE009324D4 /* vregion.cpp */, + ); + path = pixman; + sourceTree = ""; + }; + D010E03A22C237CE009324D4 /* freetype */ = { + isa = PBXGroup; + children = ( + D010E03C22C237CE009324D4 /* v_ft_types.h */, + D010E03D22C237CE009324D4 /* v_ft_raster.cpp */, + D010E03F22C237CE009324D4 /* v_ft_stroker.cpp */, + D010E04022C237CE009324D4 /* v_ft_math.cpp */, + D010E04122C237CE009324D4 /* v_ft_stroker.h */, + D010E04222C237CE009324D4 /* v_ft_math.h */, + D010E04322C237CE009324D4 /* v_ft_raster.h */, + ); + path = freetype; + sourceTree = ""; + }; + D010E04D22C237CE009324D4 /* stb */ = { + isa = PBXGroup; + children = ( + D010E05022C237CE009324D4 /* stb_image.h */, + D010E05122C237CE009324D4 /* stb_image.cpp */, + ); + path = stb; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D010DF3722C225E4009324D4 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D010E17622C237CF009324D4 /* vraster.h in Headers */, + D010E12622C237CE009324D4 /* dtoa.h in Headers */, + D010E14422C237CF009324D4 /* pixman-arm-neon-asm.h in Headers */, + D010E16E22C237CF009324D4 /* vrect.h in Headers */, + D010E17922C237CF009324D4 /* vcowptr.h in Headers */, + D010E12022C237CE009324D4 /* regex.h in Headers */, + D010E12422C237CE009324D4 /* itoa.h in Headers */, + D010E13022C237CE009324D4 /* writer.h in Headers */, + D010E11322C237CE009324D4 /* fwd.h in Headers */, + D010E13822C237CE009324D4 /* lottiemodel.h in Headers */, + D010E13E22C237CE009324D4 /* velapsedtimer.h in Headers */, + D010E11422C237CE009324D4 /* memorystream.h in Headers */, + D010E12E22C237CE009324D4 /* document.h in Headers */, + D010E12522C237CE009324D4 /* stack.h in Headers */, + D010E12C22C237CE009324D4 /* filewritestream.h in Headers */, + D010E17022C237CF009324D4 /* vbezier.h in Headers */, + D010E07222C237CE009324D4 /* rlottie.h in Headers */, + D010E11822C237CE009324D4 /* encodedstream.h in Headers */, + D010E11722C237CE009324D4 /* ostreamwrapper.h in Headers */, + D010E15222C237CF009324D4 /* v_ft_math.h in Headers */, + D010E14522C237CF009324D4 /* vregion.h in Headers */, + D010E16C22C237CF009324D4 /* vpainter.h in Headers */, + D010DF4122C225E4009324D4 /* RLottie.h in Headers */, + D010E17722C237CF009324D4 /* vmatrix.h in Headers */, + D010E12D22C237CE009324D4 /* rapidjson.h in Headers */, + D010E11E22C237CE009324D4 /* strtod.h in Headers */, + D010E14A22C237CF009324D4 /* config.h in Headers */, + D010E17422C237CF009324D4 /* vstackallocator.h in Headers */, + D010E10C22C237CE009324D4 /* lottieparser.h in Headers */, + D010E15A22C237CF009324D4 /* vpathmesure.h in Headers */, + D010E13922C237CE009324D4 /* lottieloader.h in Headers */, + D010E12F22C237CE009324D4 /* allocators.h in Headers */, + D010E16322C237CF009324D4 /* vline.h in Headers */, + D010E11C22C237CE009324D4 /* stringbuffer.h in Headers */, + D010E13422C237CE009324D4 /* pointer.h in Headers */, + D010E12222C237CE009324D4 /* biginteger.h in Headers */, + D010E11D22C237CE009324D4 /* ieee754.h in Headers */, + D010E11A22C237CE009324D4 /* cursorstreamwrapper.h in Headers */, + D010E15722C237CF009324D4 /* vdrawable.h in Headers */, + D010E07022C237CE009324D4 /* rlottiecommon.h in Headers */, + D010E16A22C237CF009324D4 /* vglobal.h in Headers */, + D010E12822C237CE009324D4 /* pow10.h in Headers */, + D010E11B22C237CE009324D4 /* istreamwrapper.h in Headers */, + D010E11922C237CE009324D4 /* filereadstream.h in Headers */, + D010E12922C237CE009324D4 /* encodings.h in Headers */, + D010E13722C237CE009324D4 /* lottieproxymodel.h in Headers */, + D010E14C22C237CF009324D4 /* v_ft_types.h in Headers */, + D010E16622C237CF009324D4 /* vbrush.h in Headers */, + D010E12322C237CE009324D4 /* strfunc.h in Headers */, + D010E07322C237CE009324D4 /* rlottie_capi.h in Headers */, + D010E15F22C237CF009324D4 /* stb_image.h in Headers */, + D010E12122C237CE009324D4 /* diyfp.h in Headers */, + D010E13122C237CE009324D4 /* error.h in Headers */, + D010E15822C237CF009324D4 /* vbitmap.h in Headers */, + D010E15922C237CF009324D4 /* vpoint.h in Headers */, + D010E18122C23D57009324D4 /* LottieInstance.h in Headers */, + D010E12A22C237CE009324D4 /* schema.h in Headers */, + D010E12722C237CE009324D4 /* meta.h in Headers */, + D010E13322C237CE009324D4 /* memorybuffer.h in Headers */, + D010E13A22C237CE009324D4 /* vdasher.h in Headers */, + D010E15B22C237CF009324D4 /* vdebug.h in Headers */, + D010E15522C237CF009324D4 /* vdrawhelper.h in Headers */, + D010E13222C237CE009324D4 /* en.h in Headers */, + D010E17522C237CF009324D4 /* vimageloader.h in Headers */, + D010E15122C237CF009324D4 /* v_ft_stroker.h in Headers */, + D010E16222C237CF009324D4 /* vtaskqueue.h in Headers */, + D010E11F22C237CE009324D4 /* swap.h in Headers */, + D010E15322C237CF009324D4 /* v_ft_raster.h in Headers */, + D010E11522C237CE009324D4 /* reader.h in Headers */, + D010E11622C237CE009324D4 /* prettywriter.h in Headers */, + D010E11022C237CE009324D4 /* lottiekeypath.h in Headers */, + D010E15C22C237CF009324D4 /* vpath.h in Headers */, + D010E10F22C237CE009324D4 /* lottieitem.h in Headers */, + D010E12B22C237CE009324D4 /* stream.h in Headers */, + D010E13B22C237CE009324D4 /* vrle.h in Headers */, + D010E16F22C237CF009324D4 /* vinterpolator.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + D010DF3B22C225E4009324D4 /* RLottie */ = { + isa = PBXNativeTarget; + buildConfigurationList = D010DF4422C225E4009324D4 /* Build configuration list for PBXNativeTarget "RLottie" */; + buildPhases = ( + D010DF3722C225E4009324D4 /* Headers */, + D010DF3822C225E4009324D4 /* Sources */, + D010DF3922C225E4009324D4 /* Frameworks */, + D010DF3A22C225E4009324D4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RLottie; + productName = RLottie; + productReference = D010DF3C22C225E4009324D4 /* RLottie.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D010DF3322C225E4009324D4 /* Project object */ = { + isa = PBXProject; + attributes = { + DefaultBuildSystemTypeForWorkspace = Latest; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Telegram LLP"; + TargetAttributes = { + D010DF3B22C225E4009324D4 = { + CreatedOnToolsVersion = 10.1; + }; + }; + }; + buildConfigurationList = D010DF3622C225E4009324D4 /* Build configuration list for PBXProject "RLottie_Xcode" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = D010DF3222C225E4009324D4; + productRefGroup = D010DF3D22C225E4009324D4 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D010DF3B22C225E4009324D4 /* RLottie */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + D010DF3A22C225E4009324D4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + D010DF3822C225E4009324D4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D010E14922C237CF009324D4 /* vpath.cpp in Sources */, + D010E16022C237CF009324D4 /* stb_image.cpp in Sources */, + D010E17822C237CF009324D4 /* vrle.cpp in Sources */, + D010E16422C237CF009324D4 /* vdrawable.cpp in Sources */, + D010E10E22C237CE009324D4 /* lottieloader.cpp in Sources */, + D010E16522C237CF009324D4 /* vpathmesure.cpp in Sources */, + D010E16722C237CF009324D4 /* vpainter.cpp in Sources */, + D010E16D22C237CF009324D4 /* vmatrix.cpp in Sources */, + D010E17122C237CF009324D4 /* vdrawhelper_sse2.cpp in Sources */, + D010E10B22C237CE009324D4 /* lottiekeypath.cpp in Sources */, + D010E10A22C237CE009324D4 /* lottieanimation.cpp in Sources */, + D010E14822C237CF009324D4 /* vregion.cpp in Sources */, + D010E17322C237CF009324D4 /* vdrawhelper.cpp in Sources */, + D010E15422C237CF009324D4 /* vcompositionfunctions.cpp in Sources */, + D010E16B22C237CF009324D4 /* vraster.cpp in Sources */, + D010E10822C237CE009324D4 /* lottieitem.cpp in Sources */, + D010E11222C237CE009324D4 /* lottieproxymodel.cpp in Sources */, + D010E10722C237CE009324D4 /* lottiemodel.cpp in Sources */, + D010E14022C237CE009324D4 /* vrect.cpp in Sources */, + D010E10422C237CE009324D4 /* lottieanimation_capi.cpp in Sources */, + D010E17A22C237CF009324D4 /* vbrush.cpp in Sources */, + D010E14F22C237CF009324D4 /* v_ft_stroker.cpp in Sources */, + D010E14222C237CF009324D4 /* vbezier.cpp in Sources */, + D010E14122C237CF009324D4 /* vdasher.cpp in Sources */, + D010E15022C237CF009324D4 /* v_ft_math.cpp in Sources */, + D010E16822C237CF009324D4 /* vdebug.cpp in Sources */, + D010E10D22C237CE009324D4 /* lottieparser.cpp in Sources */, + D010E17222C237CF009324D4 /* vinterpolator.cpp in Sources */, + D010E15622C237CF009324D4 /* vbitmap.cpp in Sources */, + D010E17F22C23C42009324D4 /* LottieInstance.mm in Sources */, + D010E13C22C237CE009324D4 /* velapsedtimer.cpp in Sources */, + D010E14D22C237CF009324D4 /* v_ft_raster.cpp in Sources */, + D010E16922C237CF009324D4 /* vimageloader.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + D010DF4222C225E4009324D4 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = DebugHockeyapp; + }; + D010DF4322C225E4009324D4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + D010DF4522C225E4009324D4 /* DebugHockeyapp */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_OPTIMIZATION_LEVEL = s; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.RLottie; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = DebugHockeyapp; + }; + D010DF4622C225E4009324D4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Manual; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = org.telegram.RLottie; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + D010DF3622C225E4009324D4 /* Build configuration list for PBXProject "RLottie_Xcode" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D010DF4222C225E4009324D4 /* DebugHockeyapp */, + D010DF4322C225E4009324D4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D010DF4422C225E4009324D4 /* Build configuration list for PBXNativeTarget "RLottie" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D010DF4522C225E4009324D4 /* DebugHockeyapp */, + D010DF4622C225E4009324D4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D010DF3322C225E4009324D4 /* Project object */; +} diff --git a/submodules/RLottie/Sources/LottieInstance.h b/submodules/RLottie/Sources/LottieInstance.h new file mode 100644 index 0000000000..42c949e81c --- /dev/null +++ b/submodules/RLottie/Sources/LottieInstance.h @@ -0,0 +1,16 @@ +#ifndef Lottie_h +#define Lottie_h + +#import + +@interface LottieInstance : NSObject + +@property (nonatomic, readonly) int32_t frameCount; +@property (nonatomic, readonly) int32_t frameRate; + +- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data cacheKey:(NSString * _Nonnull)cacheKey; +- (void)renderFrameWithIndex:(int32_t)index into:(uint8_t * _Nonnull)buffer width:(int32_t)width height:(int32_t)height; + +@end + +#endif /* Lottie_h */ diff --git a/submodules/RLottie/Sources/LottieInstance.mm b/submodules/RLottie/Sources/LottieInstance.mm new file mode 100644 index 0000000000..849339297b --- /dev/null +++ b/submodules/RLottie/Sources/LottieInstance.mm @@ -0,0 +1,32 @@ +#import "LottieInstance.h" + +#include + +@interface LottieInstance () { + std::unique_ptr _animation; +} + +@end + +@implementation LottieInstance + +- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data 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])); + if (_animation == nullptr) { + return nil; + } + + _frameCount = (int32_t)_animation->totalFrame(); + _frameRate = (int32_t)_animation->frameRate(); + } + return self; +} + +- (void)renderFrameWithIndex:(int32_t)index into:(uint8_t * _Nonnull)buffer width:(int32_t)width height:(int32_t)height { + rlottie::Surface surface((uint32_t *)buffer, width, height, width * 4); + _animation->renderSync(index, surface); +} + +@end diff --git a/submodules/RLottie/Sources/RLottie.h b/submodules/RLottie/Sources/RLottie.h new file mode 100644 index 0000000000..6f9e94b224 --- /dev/null +++ b/submodules/RLottie/Sources/RLottie.h @@ -0,0 +1,19 @@ +// +// RLottie.h +// RLottie +// +// Created by Peter on 6/25/19. +// Copyright © 2019 Telegram LLP. All rights reserved. +// + +#import + +//! Project version number for RLottie. +FOUNDATION_EXPORT double RLottieVersionNumber; + +//! Project version string for RLottie. +FOUNDATION_EXPORT const unsigned char RLottieVersionString[]; + +#import + + diff --git a/submodules/TelegramCore/TelegramCore/TelegramMediaFile.swift b/submodules/TelegramCore/TelegramCore/TelegramMediaFile.swift index d7170bd462..7e318c1419 100644 --- a/submodules/TelegramCore/TelegramCore/TelegramMediaFile.swift +++ b/submodules/TelegramCore/TelegramCore/TelegramMediaFile.swift @@ -363,6 +363,14 @@ public final class TelegramMediaFile: Media, Equatable { return false } + public var isAnimatedSticker: Bool { + if let fileName = self.fileName, fileName.hasSuffix(".tgs"), self.mimeType == "application/x-tgsticker" { + return true + } else { + return false + } + } + public var isMusic: Bool { for attribute in self.attributes { if case .Audio(false, _, _, _, _) = attribute { @@ -382,7 +390,13 @@ public final class TelegramMediaFile: Media, Equatable { } public var dimensions: CGSize? { - return dimensionsForFileAttributes(self.attributes) + if let value = dimensionsForFileAttributes(self.attributes) { + return value + } else if self.isAnimatedSticker { + return CGSize(width: 512.0, height: 512.0) + } else { + return nil + } } public var duration: Int32? { diff --git a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift index ce3fbd0638..60b52b783e 100644 --- a/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift +++ b/submodules/TelegramUI/TelegramUI/AnimatedStickerUtils.swift @@ -8,6 +8,7 @@ import Lottie import TelegramUIPrivateModule import Compression import GZip +import RLottie private func validateAnimationItems(_ items: [Any]?, shapes: Bool = true) -> Bool { if let items = items { @@ -81,7 +82,7 @@ func validateAnimationComposition(json: [AnyHashable: Any]) -> Bool { } @available(iOS 9.0, *) -func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: CGSize) -> Signal { +func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: CGSize, cacheKey: String) -> Signal { return Signal({ subscriber in let queue = Queue() @@ -91,170 +92,97 @@ func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: CGSize) var appendingTime: Double = 0 let decompressedData = TGGUnzipData(data) - if let decompressedData = decompressedData, let json = (try? JSONSerialization.jsonObject(with: decompressedData, options: [])) as? [AnyHashable: Any] { - if validateAnimationComposition(json: json) { - let model = LOTComposition(json: json) - if let startFrame = model.startFrame?.int32Value, let endFrame = model.endFrame?.int32Value { - print("read at \(CACurrentMediaTime() - startTime)") - - var randomId: Int64 = 0 - arc4random_buf(&randomId, 8) - let path = NSTemporaryDirectory() + "\(randomId).lz4v" - guard let fileContext = ManagedFile(queue: queue, path: path, mode: .readwrite) else { - return - } - - let videoSize = CGSize(width: size.width, height: size.height * 2.0) - let scale = size.width / 512.0 - - var currentFrame: Int32 = 0 - - let container = LOTAnimationLayerContainer(model: model, size: size) - - let singleContext = DrawingContext(size: size, scale: 1.0, clear: true) - - var fps: Int32 = model.framerate?.int32Value ?? 30 - let _ = fileContext.write(&fps, count: 4) - - if true { - let frameLength = singleContext.length - assert(frameLength % 16 == 0) - - let previousFrameData = malloc(frameLength)! - memset(previousFrameData, 0, frameLength) - - let bc1FrameData = malloc(frameLength)! - memset(bc1FrameData, 0, frameLength) - - defer { - free(previousFrameData) - free(bc1FrameData) - } - - var compressedFrameData = Data(count: frameLength) - let compressedFrameDataLength = compressedFrameData.count - - let scratchData = malloc(compression_encode_scratch_buffer_size(COMPRESSION_LZ4))! - defer { - free(scratchData) - } - - while startFrame + currentFrame < endFrame { - let drawStartTime = CACurrentMediaTime() - singleContext.withContext { context in - context.clear(CGRect(origin: CGPoint(), size: size)) - context.saveGState() - context.scaleBy(x: scale, y: scale) - container?.renderFrame(startFrame + currentFrame, in: context) - context.restoreGState() - } - - var lhs = previousFrameData.assumingMemoryBound(to: UInt64.self) - var rhs = singleContext.bytes.assumingMemoryBound(to: UInt64.self) - for _ in 0 ..< frameLength / 8 { - lhs.pointee = rhs.pointee ^ lhs.pointee - lhs = lhs.advanced(by: 1) - rhs = rhs.advanced(by: 1) - } - - drawingTime += CACurrentMediaTime() - drawStartTime - - compressedFrameData.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in - let length = compression_encode_buffer(bytes, compressedFrameDataLength, previousFrameData.assumingMemoryBound(to: UInt8.self), frameLength, scratchData, COMPRESSION_LZ4) - var frameLengthValue: Int32 = Int32(length) - let _ = fileContext.write(&frameLengthValue, count: 4) - let _ = fileContext.write(bytes, count: length) - } - - memcpy(previousFrameData, singleContext.bytes, frameLength) - - let appendStartTime = CACurrentMediaTime() - - compressRGBAToBC1(previousFrameData.assumingMemoryBound(to: UInt8.self), Int32(size.width), Int32(size.height), bc1FrameData.assumingMemoryBound(to: UInt8.self)) - - appendingTime += CACurrentMediaTime() - appendStartTime - currentFrame += 1 - } - - if startFrame + currentFrame >= endFrame { - subscriber.putNext(path) - subscriber.putCompletion() - print("animation render time \(CACurrentMediaTime() - startTime)") - print("of which drawing time \(drawingTime)") - print("of which appending time \(appendingTime)") - } - } else { - let bgrg422Length = Int(size.width) * 2 * Int(size.height) - let aLength = Int(size.width) * Int(size.height) - let frameLength = bgrg422Length + aLength - - assert(frameLength % 16 == 0) - - let currentFrameData = malloc(frameLength)! - let previousFrameData = malloc(frameLength)! - memset(previousFrameData, 0, frameLength) - - defer { - free(currentFrameData) - free(previousFrameData) - } - - let fps: Int32 = model.framerate?.int32Value ?? 30 - - var compressedFrameData = Data(count: bgrg422Length + aLength) - let compressedFrameDataLength = compressedFrameData.count - - let scratchData = malloc(compression_encode_scratch_buffer_size(COMPRESSION_LZ4))! - defer { - free(scratchData) - } - - while startFrame + currentFrame < endFrame { - let drawStartTime = CACurrentMediaTime() - singleContext.withContext { context in - context.clear(CGRect(origin: CGPoint(), size: size)) - context.saveGState() - context.scaleBy(x: scale, y: scale) - container?.renderFrame(startFrame + currentFrame, in: context) - context.restoreGState() - } - - encodeRGBAToBRGR422A(currentFrameData.assumingMemoryBound(to: UInt8.self).advanced(by: 0), currentFrameData.assumingMemoryBound(to: UInt8.self).advanced(by: bgrg422Length), singleContext.bytes.assumingMemoryBound(to: UInt8.self), Int32(size.width), Int32(size.height)) - - var lhs = previousFrameData.assumingMemoryBound(to: UInt64.self) - var rhs = currentFrameData.assumingMemoryBound(to: UInt64.self) - for _ in 0 ..< frameLength / 8 { - lhs.pointee = rhs.pointee ^ lhs.pointee - lhs = lhs.advanced(by: 1) - rhs = rhs.advanced(by: 1) - } - - drawingTime += CACurrentMediaTime() - drawStartTime - - let appendStartTime = CACurrentMediaTime() - compressedFrameData.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in - let length = compression_encode_buffer(bytes, compressedFrameDataLength, previousFrameData.assumingMemoryBound(to: UInt8.self), frameLength, scratchData, COMPRESSION_LZ4) - var frameLengthValue: Int32 = Int32(length) - let _ = fileContext.write(&frameLengthValue, count: 4) - let _ = fileContext.write(bytes, count: length) - } - - memcpy(previousFrameData, currentFrameData, frameLength) - - appendingTime += CACurrentMediaTime() - appendStartTime - currentFrame += 1 - } - - if startFrame + currentFrame >= endFrame { - subscriber.putNext(path) - subscriber.putCompletion() - print("animation render time \(CACurrentMediaTime() - startTime)") - print("of which drawing time \(drawingTime)") - print("of which appending time \(appendingTime)") - } - } - } + if let decompressedData = decompressedData, let player = LottieInstance(data: decompressedData, cacheKey: cacheKey) { + let endFrame = Int(player.frameCount) + print("read at \(CACurrentMediaTime() - startTime)") + + var randomId: Int64 = 0 + arc4random_buf(&randomId, 8) + let path = NSTemporaryDirectory() + "\(randomId).lz4v" + guard let fileContext = ManagedFile(queue: queue, path: path, mode: .readwrite) else { + return } + + let scale = size.width / 512.0 + + var currentFrame: Int32 = 0 + + var fps: Int32 = player.frameRate + let _ = fileContext.write(&fps, count: 4) + var widthValue: Int32 = Int32(size.width) + var heightValue: Int32 = Int32(size.height) + let _ = fileContext.write(&widthValue, count: 4) + let _ = fileContext.write(&heightValue, count: 4) + + let frameLength = Int(size.width) * Int(size.height) * 4 + assert(frameLength % 16 == 0) + + let currentFrameData = malloc(frameLength)! + memset(currentFrameData, 0, frameLength) + + let yuvaLength = Int(size.width) * Int(size.height) * 2 + Int(size.width) * Int(size.height) / 2 + assert(yuvaLength % 8 == 0) + var yuvaFrameData = malloc(yuvaLength)! + memset(yuvaFrameData, 0, yuvaLength) + + var previousYuvaFrameData = malloc(yuvaLength)! + memset(previousYuvaFrameData, 0, yuvaLength) + + defer { + free(currentFrameData) + free(previousYuvaFrameData) + free(yuvaFrameData) + } + + var compressedFrameData = Data(count: frameLength) + let compressedFrameDataLength = compressedFrameData.count + + let scratchData = malloc(compression_encode_scratch_buffer_size(COMPRESSION_LZ4))! + defer { + free(scratchData) + } + + while currentFrame < endFrame { + let drawStartTime = CACurrentMediaTime() + memset(currentFrameData, 0, frameLength) + player.renderFrame(with: Int32(currentFrame), into: currentFrameData.assumingMemoryBound(to: UInt8.self), width: Int32(size.width), height: Int32(size.height)) + + let appendStartTime = CACurrentMediaTime() + + encodeRGBAToYUVA(yuvaFrameData.assumingMemoryBound(to: UInt8.self), currentFrameData.assumingMemoryBound(to: UInt8.self), Int32(size.width), Int32(size.height)) + //decodeYUVAToRGBA(yuvaFrameData.assumingMemoryBound(to: UInt8.self), singleContext.bytes.assumingMemoryBound(to: UInt8.self), Int32(size.width), Int32(size.height)) + + appendingTime += CACurrentMediaTime() - appendStartTime + + var lhs = previousYuvaFrameData.assumingMemoryBound(to: UInt64.self) + var rhs = yuvaFrameData.assumingMemoryBound(to: UInt64.self) + for _ in 0 ..< yuvaLength / 8 { + lhs.pointee = rhs.pointee ^ lhs.pointee + lhs = lhs.advanced(by: 1) + rhs = rhs.advanced(by: 1) + } + + drawingTime += CACurrentMediaTime() - drawStartTime + + compressedFrameData.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in + let length = compression_encode_buffer(bytes, compressedFrameDataLength, previousYuvaFrameData.assumingMemoryBound(to: UInt8.self), yuvaLength, scratchData, COMPRESSION_LZ4) + var frameLengthValue: Int32 = Int32(length) + let _ = fileContext.write(&frameLengthValue, count: 4) + let _ = fileContext.write(bytes, count: length) + } + + let tmp = previousYuvaFrameData + previousYuvaFrameData = yuvaFrameData + yuvaFrameData = tmp + + currentFrame += 1 + } + + subscriber.putNext(path) + subscriber.putCompletion() + print("animation render time \(CACurrentMediaTime() - startTime)") + print("of which drawing time \(drawingTime)") + print("of which appending time \(appendingTime)") } } return EmptyDisposable @@ -364,7 +292,7 @@ func convertCompressedLottieToCombinedMp4(data: Data, size: CGSize) -> Signal= endFrame { assetWriterInput.markAsFinished() assetWriter.finishWriting { subscriber.putNext(path) diff --git a/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift b/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift index 513de44094..20bd11248e 100644 --- a/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift +++ b/submodules/TelegramUI/TelegramUI/CachedResourceRepresentations.swift @@ -216,8 +216,16 @@ final class CachedEmojiRepresentation: CachedMediaResourceRepresentation { } final class CachedAnimatedStickerRepresentation: CachedMediaResourceRepresentation { + let width: Int32 + let height: Int32 + var uniqueId: String { - return "animated-sticker-v3" + return "animated-sticker-\(self.width)x\(self.height)-v3" + } + + init(width: Int32, height: Int32) { + self.width = width + self.height = height } func isEqual(to: CachedMediaResourceRepresentation) -> Bool { diff --git a/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift index e5aed30622..f898ec9ab0 100644 --- a/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatControllerNode.swift @@ -268,7 +268,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { self.historyNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) - self.textInputPanelNode = ChatTextInputPanelNode(theme: chatPresentationInterfaceState.theme, presentController: { [weak self] controller in + self.textInputPanelNode = ChatTextInputPanelNode(presentationInterfaceState: chatPresentationInterfaceState, presentController: { [weak self] controller in self?.interfaceInteraction?.presentController(controller, nil) }) self.textInputPanelNode?.storedInputLanguage = chatPresentationInterfaceState.interfaceState.inputLanguage diff --git a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift index defa532eaf..d3de4c634a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift +++ b/submodules/TelegramUI/TelegramUI/ChatInterfaceStateInputPanels.swift @@ -219,7 +219,7 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState textInputPanelNode.context = context return textInputPanelNode } else { - let panel = ChatTextInputPanelNode(theme: chatPresentationInterfaceState.theme, presentController: { [weak interfaceInteraction] controller in + let panel = ChatTextInputPanelNode(presentationInterfaceState: chatPresentationInterfaceState, presentController: { [weak interfaceInteraction] controller in interfaceInteraction?.presentController(controller, nil) }) panel.interfaceInteraction = interfaceInteraction diff --git a/submodules/TelegramUI/TelegramUI/ChatMediaInputNode.swift b/submodules/TelegramUI/TelegramUI/ChatMediaInputNode.swift index d5958bb212..85f712d9a0 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMediaInputNode.swift @@ -1321,7 +1321,7 @@ final class ChatMediaInputNode: ChatInputNode { self.gifPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible, transition: transition) - self.stickerPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible, transition: transition) + self.stickerPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible && visiblePanes.contains(where: { $0.0 == .stickers }), transition: transition) self.trendingPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible, transition: transition) if self.gifPane.supernode != nil { diff --git a/submodules/TelegramUI/TelegramUI/ChatMediaInputStickerGridItem.swift b/submodules/TelegramUI/TelegramUI/ChatMediaInputStickerGridItem.swift index b20e3336ca..9fd8b27fbb 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMediaInputStickerGridItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMediaInputStickerGridItem.swift @@ -166,11 +166,21 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode { private var currentState: (Account, StickerPackItem, CGSize)? private var currentSize: CGSize? private let imageNode: TransformImageNode + private var animationNode: StickerAnimationNode? private let stickerFetchedDisposable = MetaDisposable() var currentIsPreviewing = false + override var isVisibleInGrid: Bool { + didSet { + self.updateVisibility() + } + } + + private var isPanelVisible = false + private var isPlaying = false + var interfaceInteraction: ChatControllerInteraction? var inputNodeInteraction: ChatMediaInputNodeInteraction? var selected: (() -> Void)? @@ -208,7 +218,22 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode { } if self.currentState == nil || self.currentState!.0 !== item.account || self.currentState!.1 != item.stickerItem { if let dimensions = item.stickerItem.file.dimensions { - self.imageNode.setSignal(chatMessageSticker(account: item.account, file: item.stickerItem.file, small: true, synchronousLoad: synchronousLoads && isVisible)) + if item.stickerItem.file.isAnimatedSticker { + if self.animationNode == nil { + let animationNode = StickerAnimationNode() + self.animationNode = animationNode + self.addSubnode(animationNode) + } + self.animationNode?.setup(account: item.account, fileReference: FileMediaReference.standalone(media: item.stickerItem.file), width: 140, height: 140) + self.animationNode?.visibility = self.isVisibleInGrid + } else { + if let animationNode = self.animationNode { + animationNode.visibility = false + self.animationNode = nil + animationNode.removeFromSupernode() + } + self.imageNode.setSignal(chatMessageSticker(account: item.account, file: item.stickerItem.file, small: true, synchronousLoad: synchronousLoads && isVisible)) + } self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: item.account, fileReference: stickerPackFileReference(item.stickerItem.file), resource: chatMessageStickerResource(file: item.stickerItem.file, small: true)).start()) self.currentState = (item.account, item.stickerItem, dimensions) @@ -226,6 +251,10 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode { let imageSize = mediaDimensions.aspectFitted(boundingSize) self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))() self.imageNode.frame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: (size.height - imageSize.height) / 2.0), size: imageSize) + if let animationNode = self.animationNode { + animationNode.frame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: (size.height - imageSize.height) / 2.0), size: imageSize) + animationNode.updateLayout(size: imageSize) + } } } } @@ -244,6 +273,21 @@ final class ChatMediaInputStickerGridItemNode: GridItemNode { return self.imageNode } + func updateIsPanelVisible(_ isPanelVisible: Bool) { + if self.isPanelVisible != isPanelVisible { + self.isPanelVisible = isPanelVisible + self.updateVisibility() + } + } + + func updateVisibility() { + let isPlaying = self.isPanelVisible && self.isVisibleInGrid + if self.isPlaying != isPlaying { + self.isPlaying = isPlaying + self.animationNode?.visibility = isPlaying + } + } + func updatePreviewing(animated: Bool) { var isPreviewing = false if let (_, item, _) = self.currentState, let interaction = self.inputNodeInteraction { diff --git a/submodules/TelegramUI/TelegramUI/ChatMediaInputStickerPane.swift b/submodules/TelegramUI/TelegramUI/ChatMediaInputStickerPane.swift index 6da49891d7..d2caf0a433 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMediaInputStickerPane.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMediaInputStickerPane.swift @@ -103,6 +103,14 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane { fixGridScrolling(strongSelf.gridNode) } } + self.gridNode.setupNode = { [weak self] itemNode in + guard let strongSelf = self else { + return + } + if let itemNode = itemNode as? ChatMediaInputStickerGridItemNode { + itemNode.updateIsPanelVisible(strongSelf.isPaneVisible) + } + } self.gridNode.scrollView.alwaysBounceVertical = true } @@ -152,10 +160,9 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane { if self.isPaneVisible != isVisible { self.isPaneVisible = isVisible - if isVisible { - self.gridNode.forEachItemNode { itemNode in - if let _ = itemNode as? ChatMediaInputStickerGridItemNode { - } + self.gridNode.forEachItemNode { itemNode in + if let itemNode = itemNode as? ChatMediaInputStickerGridItemNode { + itemNode.updateIsPanelVisible(isVisible) } } } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift index 0710b2bf90..ac14e6d0d9 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageAnimatedStickerItemNode.swift @@ -27,11 +27,17 @@ private final class AnimationFrameCache { } func set(index: Int, bytes: UnsafeRawPointer, length: Int) { - self.cache[index] = NSPurgeableData(bytes: bytes, length: length) + let data = NSPurgeableData(bytes: bytes, length: length) + data.endContentAccess() + self.cache[index] = data + } + + func removeAll() { + self.cache.removeAll() } } -private final class StickerAnimationNode: ASDisplayNode { +final class StickerAnimationNode: ASDisplayNode { private var account: Account? private var fileReference: FileMediaReference? private let disposable = MetaDisposable() @@ -80,8 +86,8 @@ private final class StickerAnimationNode: ASDisplayNode { self.addSubnode(self.renderer!) } - func setup(account: Account, fileReference: FileMediaReference) { - self.disposable.set(chatMessageAnimationData(postbox: account.postbox, fileReference: fileReference, synchronousLoad: false).start(next: { [weak self] data in + func setup(account: Account, fileReference: FileMediaReference, width: Int, height: Int) { + self.disposable.set(chatMessageAnimationData(postbox: account.postbox, fileReference: fileReference, width: width, height: height, synchronousLoad: false).start(next: { [weak self] data in if let strongSelf = self, data.complete { strongSelf.data = try? Data(contentsOf: URL(fileURLWithPath: data.path), options: [.mappedRead]) if strongSelf.visibility { @@ -106,160 +112,104 @@ private final class StickerAnimationNode: ASDisplayNode { self.timer?.invalidate() var scratchBuffer = Data(count: compression_decode_scratch_buffer_size(COMPRESSION_LZ4)) - let width = 320 - let height = 320 - var offset = 0 + var width = 0 + var height = 0 var fps: Int32 = 0 data.withUnsafeBytes { (bytes: UnsafePointer) -> Void in - memcpy(&fps, bytes, 4) + memcpy(&fps, bytes.advanced(by: offset), 4) offset += 4 + var widthValue: Int32 = 0 + var heightValue: Int32 = 0 + memcpy(&widthValue, bytes.advanced(by: offset), 4) + offset += 4 + memcpy(&heightValue, bytes.advanced(by: offset), 4) + offset += 4 + width = Int(widthValue) + height = Int(heightValue) } - if true { - var decodeBuffer = Data(count: width * 4 * height) - var frameBuffer = Data(count: width * 4 * height) - let decodeBufferLength = decodeBuffer.count - frameBuffer.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in - memset(bytes, 0, decodeBufferLength) - } - - var frameIndex = 0 - let timer = SwiftSignalKit.Timer(timeout: 1.0 / Double(fps), repeat: true, completion: { [weak self] in - guard let strongSelf = self else { - return - } - data.withUnsafeBytes { (bytes: UnsafePointer) -> Void in - var frameLength: Int32 = 0 - memcpy(&frameLength, bytes.advanced(by: offset), 4) - - var usedCache = false - strongSelf.frameCache.get(index: frameIndex, { data in - if let data = data { - usedCache = true - - strongSelf.renderer?.render(width: 320, height: 320, bytes: data.bytes, length: data.length) - - if !strongSelf.reportedStarted { - strongSelf.reportedStarted = true - strongSelf.started() - } - } - }) - - if !usedCache { - scratchBuffer.withUnsafeMutableBytes { (scratchBytes: UnsafeMutablePointer) -> Void in - decodeBuffer.withUnsafeMutableBytes { (decodeBytes: UnsafeMutablePointer) -> Void in - frameBuffer.withUnsafeMutableBytes { (frameBytes: UnsafeMutablePointer) -> Void in - compression_decode_buffer(decodeBytes, decodeBufferLength, bytes.advanced(by: offset + 4), Int(frameLength), UnsafeMutableRawPointer(scratchBytes), COMPRESSION_LZ4) - - var lhs = UnsafeMutableRawPointer(frameBytes).assumingMemoryBound(to: UInt64.self) - var rhs = UnsafeRawPointer(decodeBytes).assumingMemoryBound(to: UInt64.self) - for _ in 0 ..< decodeBufferLength / 8 { - lhs.pointee = lhs.pointee ^ rhs.pointee - lhs = lhs.advanced(by: 1) - rhs = rhs.advanced(by: 1) - } - - strongSelf.renderer?.render(width: 320, height: 320, bytes: frameBytes, length: decodeBufferLength) - - strongSelf.frameCache.set(index: frameIndex, bytes: frameBytes, length: decodeBufferLength) - } - } - } - - if !strongSelf.reportedStarted { - strongSelf.reportedStarted = true - strongSelf.started() - } - } - - offset += 4 + Int(frameLength) - frameIndex += 1 - if offset == dataCount { - offset = 4 - frameIndex = 0 - } - } - }, queue: Queue.mainQueue()) - self.timer = timer - timer.start() - } else { - var decodeBuffer = Data(count: width * 2 * height + width * height) - var frameBuffer = Data(count: width * 2 * height + width * height) - let decodeBufferLength = decodeBuffer.count - frameBuffer.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in - memset(bytes, 0, decodeBufferLength) - } - - var frameIndex = 0 - let timer = SwiftSignalKit.Timer(timeout: 1.0 / Double(offset), repeat: true, completion: { [weak self] in - guard let strongSelf = self else { - return - } - data.withUnsafeBytes { (bytes: UnsafePointer) -> Void in - var frameLength: Int32 = 0 - memcpy(&frameLength, bytes.advanced(by: offset), 4) - - var usedCache = false - strongSelf.frameCache.get(index: frameIndex, { data in - if let data = data { - usedCache = true - - strongSelf.renderer?.render(width: 320, height: 320, bytes: data.bytes, length: data.length) - - if !strongSelf.reportedStarted { - strongSelf.reportedStarted = true - strongSelf.started() - } - } - }) - - if !usedCache { - scratchBuffer.withUnsafeMutableBytes { (scratchBytes: UnsafeMutablePointer) -> Void in - decodeBuffer.withUnsafeMutableBytes { (decodeBytes: UnsafeMutablePointer) -> Void in - frameBuffer.withUnsafeMutableBytes { (frameBytes: UnsafeMutablePointer) -> Void in - compression_decode_buffer(decodeBytes, decodeBufferLength, bytes.advanced(by: offset + 4), Int(frameLength), UnsafeMutableRawPointer(scratchBytes), COMPRESSION_LZ4) - - var lhs = UnsafeMutableRawPointer(frameBytes).assumingMemoryBound(to: UInt64.self) - var rhs = UnsafeRawPointer(decodeBytes).assumingMemoryBound(to: UInt64.self) - for _ in 0 ..< Int(decodeBufferLength) / 8 { - lhs.pointee = lhs.pointee ^ rhs.pointee - lhs = lhs.advanced(by: 1) - rhs = rhs.advanced(by: 1) - } - - strongSelf.renderer?.render(width: 320, height: 320, bytes: frameBytes, length: decodeBufferLength) - - strongSelf.frameCache.set(index: frameIndex, bytes: frameBytes, length: decodeBufferLength) - } - } - } - - if !strongSelf.reportedStarted { - strongSelf.reportedStarted = true - strongSelf.started() - } - } - - offset += 4 + Int(frameLength) - frameIndex += 1 - if offset == dataCount { - offset = 0 - frameIndex = 0 - } - } - }, queue: Queue.mainQueue()) - self.timer = timer - timer.start() + let initialOffset = offset + + var decodeBuffer = Data(count: width * 4 * height) + var frameBuffer = Data(count: width * 4 * height) + let decodeBufferLength = decodeBuffer.count + frameBuffer.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in + memset(bytes, 0, decodeBufferLength) } + + var frameIndex = 0 + let timer = SwiftSignalKit.Timer(timeout: 1.0 / Double(fps), repeat: true, completion: { [weak self] in + guard let strongSelf = self else { + return + } + data.withUnsafeBytes { (bytes: UnsafePointer) -> Void in + var frameLength: Int32 = 0 + memcpy(&frameLength, bytes.advanced(by: offset), 4) + + var usedCache = false + strongSelf.frameCache.get(index: frameIndex, { data in + if let data = data { + usedCache = true + + strongSelf.renderer?.render(width: width, height: height, bytes: data.bytes, length: data.length) + + if !strongSelf.reportedStarted { + strongSelf.reportedStarted = true + strongSelf.started() + } + } + }) + + if !usedCache { + scratchBuffer.withUnsafeMutableBytes { (scratchBytes: UnsafeMutablePointer) -> Void in + decodeBuffer.withUnsafeMutableBytes { (decodeBytes: UnsafeMutablePointer) -> Void in + frameBuffer.withUnsafeMutableBytes { (frameBytes: UnsafeMutablePointer) -> Void in + compression_decode_buffer(decodeBytes, decodeBufferLength, bytes.advanced(by: offset + 4), Int(frameLength), UnsafeMutableRawPointer(scratchBytes), COMPRESSION_LZ4) + + var lhs = UnsafeMutableRawPointer(frameBytes).assumingMemoryBound(to: UInt64.self) + var rhs = UnsafeRawPointer(decodeBytes).assumingMemoryBound(to: UInt64.self) + for _ in 0 ..< decodeBufferLength / 8 { + lhs.pointee = lhs.pointee ^ rhs.pointee + lhs = lhs.advanced(by: 1) + rhs = rhs.advanced(by: 1) + } + + strongSelf.renderer?.render(width: width, height: height, bytes: frameBytes, length: decodeBufferLength) + + //strongSelf.frameCache.set(index: frameIndex, bytes: frameBytes, length: decodeBufferLength) + } + } + } + + if !strongSelf.reportedStarted { + strongSelf.reportedStarted = true + strongSelf.started() + } + } + + offset += 4 + Int(frameLength) + frameIndex += 1 + if offset == dataCount { + offset = initialOffset + frameIndex = 0 + frameBuffer.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in + memset(bytes, 0, decodeBufferLength) + } + } + } + }, queue: Queue.mainQueue()) + self.timer = timer + timer.start() } } func stop() { self.timer?.invalidate() self.timer = nil + self.reportedStarted = false + self.frameCache.removeAll() } func updateLayout(size: CGSize) { @@ -366,7 +316,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { if self.telegramFile?.id != telegramFile.id { self.telegramFile = telegramFile self.imageNode.setSignal(chatMessageSticker(account: item.context.account, file: telegramFile, small: false, thumbnail: true)) - self.animationNode.setup(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: telegramFile)) + self.animationNode.setup(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: telegramFile), width: 360, height: 360) } break } @@ -374,7 +324,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } override func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, Bool) -> Void) { - let displaySize = CGSize(width: 162.0, height: 162.0) + let displaySize = CGSize(width: 184.0, height: 184.0) let telegramFile = self.telegramFile let layoutConstants = self.layoutConstants let imageLayout = self.imageNode.asyncLayout() @@ -387,14 +337,14 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { return { item, params, mergedTop, mergedBottom, dateHeaderAtBottom in let incoming = item.message.effectivelyIncoming(item.context.account.peerId) - var imageSize: CGSize = CGSize(width: 160.0, height: 160.0) - /*if let telegramFile = telegramFile { + var imageSize: CGSize = CGSize(width: 200.0, height: 200.0) + if let telegramFile = telegramFile { if let dimensions = telegramFile.dimensions { imageSize = dimensions.aspectFitted(displaySize) } else if let thumbnailSize = telegramFile.previewRepresentations.first?.dimensions { imageSize = thumbnailSize.aspectFitted(displaySize) } - }*/ + } let avatarInset: CGFloat var hasAvatar = false diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift index e5262ec77a..fd9bd147e3 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageItem.swift @@ -353,7 +353,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { loop: for media in self.message.media { if let telegramFile = media as? TelegramMediaFile { - if let fileName = telegramFile.fileName, fileName.hasSuffix(".tgs") && telegramFile.mimeType == "application/x-tgsticker", let size = telegramFile.size, size > 0 && size <= 64 * 1024, !telegramFile.previewRepresentations.isEmpty { + if telegramFile.isAnimatedSticker, let size = telegramFile.size, size > 0 && size <= 64 * 1024, !telegramFile.previewRepresentations.isEmpty { viewClassName = ChatMessageAnimatedStickerItemNode.self break loop } diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift index f1ff78b432..3debf63e5f 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageStickerItemNode.swift @@ -117,7 +117,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } override func asyncLayout() -> (_ item: ChatMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: ChatMessageMerge, _ mergedBottom: ChatMessageMerge, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation, Bool) -> Void) { - let displaySize = CGSize(width: 162.0, height: 162.0) + let displaySize = CGSize(width: 184.0, height: 184.0) let telegramFile = self.telegramFile let layoutConstants = self.layoutConstants let imageLayout = self.imageNode.asyncLayout() diff --git a/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift index ae04d17996..c39d0610f9 100644 --- a/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatTextInputPanelNode.swift @@ -317,10 +317,12 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { private let accessoryButtonSpacing: CGFloat = 0.0 private let accessoryButtonInset: CGFloat = 2.0 - init(theme: PresentationTheme, presentController: @escaping (ViewController) -> Void) { + init(presentationInterfaceState: ChatPresentationInterfaceState, presentController: @escaping (ViewController) -> Void) { + self.presentationInterfaceState = presentationInterfaceState + self.textInputContainer = ASDisplayNode() self.textInputContainer.clipsToBounds = true - self.textInputContainer.backgroundColor = theme.chat.inputPanel.inputBackgroundColor + self.textInputContainer.backgroundColor = presentationInterfaceState.theme.chat.inputPanel.inputBackgroundColor self.textInputBackgroundNode = ASImageNode() self.textInputBackgroundNode.displaysAsynchronously = false @@ -335,7 +337,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.searchLayoutProgressView = UIImageView(image: searchLayoutProgressImage) self.searchLayoutProgressView.isHidden = true - self.actionButtons = ChatTextInputActionButtonsNode(theme: theme, presentController: presentController) + self.actionButtons = ChatTextInputActionButtonsNode(theme: presentationInterfaceState.theme, presentController: presentController) super.init() diff --git a/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift b/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift index 95a094b3b5..5162de2352 100644 --- a/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift +++ b/submodules/TelegramUI/TelegramUI/FetchCachedRepresentations.swift @@ -889,7 +889,7 @@ private func fetchAnimatedStickerRepresentation(account: Account, resource: Medi return Signal({ subscriber in if let data = try? Data(contentsOf: URL(fileURLWithPath: resourceData.path), options: [.mappedIfSafe]) { if #available(iOS 9.0, *) { - return experimentalConvertCompressedLottieToCombinedMp4(data: data, size: CGSize(width: 320.0, height: 320.0)).start(next: { path in + return experimentalConvertCompressedLottieToCombinedMp4(data: data, size: CGSize(width: CGFloat(representation.width), height: CGFloat(representation.height)), cacheKey: "\(resource.id.uniqueId)-\(representation.uniqueId)").start(next: { path in subscriber.putNext(CachedMediaResourceRepresentationResult(temporaryPath: path)) subscriber.putCompletion() }) @@ -899,5 +899,6 @@ private func fetchAnimatedStickerRepresentation(account: Account, resource: Medi } else { return EmptyDisposable } - }) |> runOn(Queue.concurrentDefaultQueue()) + }) + |> runOn(Queue.concurrentDefaultQueue()) } diff --git a/submodules/TelegramUI/TelegramUI/MetalAnimationRenderer.swift b/submodules/TelegramUI/TelegramUI/MetalAnimationRenderer.swift index 7251e4eb19..c88c2c8d65 100644 --- a/submodules/TelegramUI/TelegramUI/MetalAnimationRenderer.swift +++ b/submodules/TelegramUI/TelegramUI/MetalAnimationRenderer.swift @@ -55,12 +55,12 @@ vertex VertexOut basic_vertex( fragment float4 basic_fragment( VertexOut interpolated [[stage_in]], texture2d texColor [[ texture(0) ]], - sampler samplerColor [[ sampler(0) ]], - texture2d texA [[ texture(1) ]], - sampler samplerA [[ sampler(1) ]] + sampler samplerColor [[ sampler(0) ]]//, + //texture2d texA [[ texture(1) ]], + //sampler samplerA [[ sampler(1) ]] ) { float4 color = texColor.sample(samplerColor, interpolated.texCoord); - float4 alpha = texA.sample(samplerA, interpolated.texCoord); + float4 alpha = 1.0;//texA.sample(samplerA, interpolated.texCoord); return float4(color.r * alpha.a, color.g * alpha.a, color.b * alpha.a, alpha.a); } """, options: nil) @@ -89,7 +89,7 @@ fragment float4 basic_fragment( let dataSize = vertexData.count * MemoryLayout.size(ofValue: vertexData[0]) self.vertexBuffer = device.makeBuffer(bytes: vertexData, length: dataSize, options: [])! - let colorTextureDesc: MTLTextureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgrg422, width: 320, height: 320, mipmapped: false) + let colorTextureDesc: MTLTextureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .pvrtc_rgb_4bpp, width: 512, height: 512, mipmapped: false) colorTextureDesc.sampleCount = 1 if #available(iOS 9.0, *) { colorTextureDesc.storageMode = .private @@ -146,10 +146,10 @@ fragment float4 basic_fragment( } let bgrgLength = width * 2 * height - let alphaLength = width * height + //let alphaLength = width * height - self.colorTexture.replace(region: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0, withBytes: bytes.assumingMemoryBound(to: UInt8.self), bytesPerRow: width * 2) - self.alphaTexture.replace(region: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0, withBytes: bytes.assumingMemoryBound(to: UInt8.self).advanced(by: bgrgLength), bytesPerRow: width) + self.colorTexture.replace(region: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0, withBytes: bytes.assumingMemoryBound(to: UInt8.self), bytesPerRow: width / 2) + //self.alphaTexture.replace(region: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0, withBytes: bytes.assumingMemoryBound(to: UInt8.self).advanced(by: bgrgLength), bytesPerRow: width) let renderPassDescriptor = MTLRenderPassDescriptor() let drawable = self.metalLayer.nextDrawable()! diff --git a/submodules/TelegramUI/TelegramUI/SoftwareAnimationRenderer.swift b/submodules/TelegramUI/TelegramUI/SoftwareAnimationRenderer.swift index 31104db17e..c0a8a295c7 100644 --- a/submodules/TelegramUI/TelegramUI/SoftwareAnimationRenderer.swift +++ b/submodules/TelegramUI/TelegramUI/SoftwareAnimationRenderer.swift @@ -7,11 +7,7 @@ import TelegramUIPrivateModule final class SoftwareAnimationRenderer: ASDisplayNode, AnimationRenderer { func render(width: Int, height: Int, bytes: UnsafeRawPointer, length: Int) { let image = generateImagePixel(CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, pixelGenerator: { _, pixelData in - if true { - memcpy(pixelData, bytes, length) - } else { - encodeBRGR422AToRGBA(bytes.assumingMemoryBound(to: UInt8.self), bytes.assumingMemoryBound(to: UInt8.self).advanced(by: width * 2 * height), pixelData, Int32(width), Int32(height)) - } + decodeYUVAToRGBA(bytes.assumingMemoryBound(to: UInt8.self), pixelData, Int32(width), Int32(height)) }) self.contents = image?.cgImage diff --git a/submodules/TelegramUI/TelegramUI/StickerPackPreviewGridItem.swift b/submodules/TelegramUI/TelegramUI/StickerPackPreviewGridItem.swift index 075fd8ae4e..51feb375f6 100644 --- a/submodules/TelegramUI/TelegramUI/StickerPackPreviewGridItem.swift +++ b/submodules/TelegramUI/TelegramUI/StickerPackPreviewGridItem.swift @@ -49,6 +49,14 @@ private let textFont = Font.regular(20.0) final class StickerPackPreviewGridItemNode: GridItemNode { private var currentState: (Account, StickerPackItem, CGSize)? private let imageNode: TransformImageNode + private var animationNode: StickerAnimationNode? + + override var isVisibleInGrid: Bool { + didSet { + self.animationNode?.visibility = self.isVisibleInGrid + } + } + private let textNode: ASTextNode private var currentIsPreviewing = false @@ -101,7 +109,22 @@ final class StickerPackPreviewGridItemNode: GridItemNode { } self.textNode.attributedText = NSAttributedString(string: text, font: textFont, textColor: .black, paragraphAlignment: .right) if let dimensions = stickerItem.file.dimensions { - self.imageNode.setSignal(chatMessageSticker(account: account, file: stickerItem.file, small: true)) + if stickerItem.file.isAnimatedSticker { + if self.animationNode == nil { + let animationNode = StickerAnimationNode() + self.animationNode = animationNode + self.addSubnode(animationNode) + } + self.animationNode?.setup(account: account, fileReference: FileMediaReference.standalone(media: stickerItem.file), width: 140, height: 140) + self.animationNode?.visibility = self.isVisibleInGrid + } else { + if let animationNode = self.animationNode { + animationNode.visibility = false + self.animationNode = nil + animationNode.removeFromSupernode() + } + self.imageNode.setSignal(chatMessageSticker(account: account, file: stickerItem.file, small: true)) + } self.stickerFetchedDisposable.set(freeMediaFileResourceInteractiveFetched(account: account, fileReference: stickerPackFileReference(stickerItem.file), resource: chatMessageStickerResource(file: stickerItem.file, small: true)).start()) @@ -125,6 +148,10 @@ final class StickerPackPreviewGridItemNode: GridItemNode { let imageSize = mediaDimensions.aspectFitted(boundingSize) self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))() self.imageNode.frame = CGRect(origin: CGPoint(x: floor((bounds.size.width - imageSize.width) / 2.0), y: (bounds.size.height - imageSize.height) / 2.0), size: imageSize) + if let animationNode = self.animationNode { + animationNode.frame = CGRect(origin: CGPoint(x: floor((bounds.size.width - imageSize.width) / 2.0), y: (bounds.size.height - imageSize.height) / 2.0), size: imageSize) + animationNode.updateLayout(size: imageSize) + } let boundingFrame = CGRect(origin: CGPoint(x: floor((bounds.size.width - boundingSize.width) / 2.0), y: (bounds.size.height - boundingSize.height) / 2.0), size: boundingSize) let textSize = CGSize(width: 32.0, height: 24.0) self.textNode.frame = CGRect(origin: CGPoint(x: boundingFrame.maxX - 1.0 - textSize.width, y: boundingFrame.height + 10.0 - textSize.height), size: textSize) diff --git a/submodules/TelegramUI/TelegramUI/StickerPreviewPeekContent.swift b/submodules/TelegramUI/TelegramUI/StickerPreviewPeekContent.swift index c9cce2f335..8d2e6cd5f1 100644 --- a/submodules/TelegramUI/TelegramUI/StickerPreviewPeekContent.swift +++ b/submodules/TelegramUI/TelegramUI/StickerPreviewPeekContent.swift @@ -66,6 +66,8 @@ private final class StickerPreviewPeekContentNode: ASDisplayNode, PeekController private var textNode: ASTextNode private var imageNode: TransformImageNode + private var animationNode: StickerAnimationNode? + private var containerLayout: (ContainerViewLayout, CGFloat)? init(account: Account, item: StickerPreviewPeekItem) { @@ -80,13 +82,28 @@ private final class StickerPreviewPeekContentNode: ASDisplayNode, PeekController self.textNode.attributedText = NSAttributedString(string: text, font: Font.regular(32.0), textColor: .black) break } + + if item.file.isAnimatedSticker { + let animationNode = StickerAnimationNode() + self.animationNode = animationNode + + self.animationNode?.setup(account: account, fileReference: FileMediaReference.standalone(media: item.file), width: 320, height: 320) + self.animationNode?.visibility = true + } else { + self.animationNode = nil + } + self.imageNode.setSignal(chatMessageSticker(account: account, file: item.file, small: false, fetched: true)) super.init() self.isUserInteractionEnabled = false - self.addSubnode(self.imageNode) + if let animationNode = self.animationNode { + self.addSubnode(animationNode) + } else { + self.addSubnode(self.imageNode) + } } func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) -> CGSize { @@ -100,6 +117,10 @@ private final class StickerPreviewPeekContentNode: ASDisplayNode, PeekController self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets()))() let imageFrame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: textSize.height + textSpacing), size: imageSize) self.imageNode.frame = imageFrame + if let animationNode = self.animationNode { + animationNode.frame = imageFrame + animationNode.updateLayout(size: imageSize) + } self.textNode.frame = CGRect(origin: CGPoint(x: floor((imageFrame.size.width - textSize.width) / 2.0), y: -textSize.height - textSpacing), size: textSize) diff --git a/submodules/TelegramUI/TelegramUI/StickerResources.swift b/submodules/TelegramUI/TelegramUI/StickerResources.swift index ae10100c7c..33c43fcd3c 100644 --- a/submodules/TelegramUI/TelegramUI/StickerResources.swift +++ b/submodules/TelegramUI/TelegramUI/StickerResources.swift @@ -168,8 +168,8 @@ private func chatMessageStickerPackThumbnailData(postbox: Postbox, representatio } } -func chatMessageAnimationData(postbox: Postbox, fileReference: FileMediaReference, synchronousLoad: Bool) -> Signal { - let maybeFetched = postbox.mediaBox.cachedResourceRepresentation(fileReference.media.resource, representation: CachedAnimatedStickerRepresentation(), pathExtension: "mp4", complete: false, fetch: false, attemptSynchronously: synchronousLoad) +func chatMessageAnimationData(postbox: Postbox, fileReference: FileMediaReference, width: Int, height: Int, synchronousLoad: Bool) -> Signal { + let maybeFetched = postbox.mediaBox.cachedResourceRepresentation(fileReference.media.resource, representation: CachedAnimatedStickerRepresentation(width: Int32(width), height: Int32(height)), pathExtension: "mp4", complete: false, fetch: false, attemptSynchronously: synchronousLoad) return maybeFetched |> take(1) @@ -177,7 +177,7 @@ func chatMessageAnimationData(postbox: Postbox, fileReference: FileMediaReferenc if maybeData.complete { return .single(maybeData) } else { - return postbox.mediaBox.cachedResourceRepresentation(fileReference.media.resource, representation: CachedAnimatedStickerRepresentation(), pathExtension: "mp4", complete: false) + return postbox.mediaBox.cachedResourceRepresentation(fileReference.media.resource, representation: CachedAnimatedStickerRepresentation(width: Int32(width), height: Int32(height)), pathExtension: "mp4", complete: false) } } } diff --git a/submodules/TelegramUI/TelegramUI/YUV.h b/submodules/TelegramUI/TelegramUI/YUV.h index a13fe86332..9208d75f39 100644 --- a/submodules/TelegramUI/TelegramUI/YUV.h +++ b/submodules/TelegramUI/TelegramUI/YUV.h @@ -1,7 +1,4 @@ #import -void encodeRGBAToBRGR422A(uint8_t * _Nonnull bgrg422, uint8_t * _Nonnull a, uint8_t const * _Nonnull argb, int width, int height); -void encodeBRGR422AToRGBA(uint8_t const * _Nonnull bgrg422, uint8_t const * _Nonnull a, uint8_t * _Nonnull argb, int width, int height); - -NSData * _Nonnull encodeSparseBuffer(uint8_t const * _Nonnull bytes, int length); -void decodeSparseeBuffer(uint8_t * _Nonnull bytes, uint8_t const * _Nonnull buffer); +void encodeRGBAToYUVA(uint8_t *yuva, uint8_t const *argb, int width, int height); +void decodeYUVAToRGBA(uint8_t const *yuva, uint8_t *argb, int width, int height); diff --git a/submodules/TelegramUI/TelegramUI/YUV.m b/submodules/TelegramUI/TelegramUI/YUV.m index 43277cabd0..14de0384e6 100644 --- a/submodules/TelegramUI/TelegramUI/YUV.m +++ b/submodules/TelegramUI/TelegramUI/YUV.m @@ -1,67 +1,96 @@ #import "YUV.h" +#import -void encodeRGBAToBRGR422A(uint8_t *bgrg422, uint8_t *a, uint8_t const *argb, int width, int height) { - int i, j; - int lineWidth = width * 2; - for (j = 0; j < height; j++) { - for (i = 0; i < width; i += 2) { - int A1 = argb[(j * width + i) * 4 + 0]; - int R1 = argb[(j * width + i) * 4 + 3]; - int G1 = argb[(j * width + i) * 4 + 2]; - int B1 = argb[(j * width + i) * 4 + 1]; - - int A2 = argb[(j * width + i) * 4 + 4]; - int R2 = argb[(j * width + i) * 4 + 7]; - int G2 = argb[(j * width + i) * 4 + 6]; - int B2 = argb[(j * width + i) * 4 + 5]; - - bgrg422[j * lineWidth + (i / 2) * 4 + 0] = (uint8_t)((B1 + B2) >> 1); - bgrg422[j * lineWidth + (i / 2) * 4 + 1] = G1; - bgrg422[j * lineWidth + (i / 2) * 4 + 2] = (uint8_t)((R1 + R2) >> 1); - bgrg422[j * lineWidth + (i / 2) * 4 + 3] = G2; - - a[j * width + i + 0] = A1; - a[j * width + i + 1] = A2; - } - } -} - -void encodeBRGR422AToRGBA(uint8_t const * _Nonnull bgrg422, uint8_t const * _Nonnull const a, uint8_t * _Nonnull argb, int width, int height) { - int i, j; - int lineWidth = width * 2; - for (j = 0; j < height; j++) { - for (i = 0; i < width; i += 2) { - argb[(j * width + i) * 4 + 0] = a[j * width + i + 0]; - argb[(j * width + i) * 4 + 3] = bgrg422[j * lineWidth + (i / 2) * 4 + 2]; - argb[(j * width + i) * 4 + 2] = bgrg422[j * lineWidth + (i / 2) * 4 + 1]; - argb[(j * width + i) * 4 + 1] = bgrg422[j * lineWidth + (i / 2) * 4 + 0]; - - argb[(j * width + i) * 4 + 4] = a[j * width + i + 1]; - argb[(j * width + i) * 4 + 7] = bgrg422[j * lineWidth + (i / 2) * 4 + 2]; - argb[(j * width + i) * 4 + 6] = bgrg422[j * lineWidth + (i / 2) * 4 + 3]; - argb[(j * width + i) * 4 + 5] = bgrg422[j * lineWidth + (i / 2) * 4 + 0]; - } - } -} - -NSData * _Nonnull encodeSparseBuffer(uint8_t const * _Nonnull bytes, int length) { - NSMutableData *result = [[NSMutableData alloc] init]; - int offset = 0; - int currentStart = 0; - int currentType = 0; - while (offset != length) { - if (bytes[offset] == 0) { - if (currentType != 0) { - - } - } else { - - } - offset += 1; - } - return result; -} - -void decodeSparseeBuffer(uint8_t * _Nonnull bytes, uint8_t const * _Nonnull buffer) { +void encodeRGBAToYUVA(uint8_t *yuva, uint8_t const *argb, int width, int height) { + vImage_YpCbCrPixelRange pixelRange = (vImage_YpCbCrPixelRange){ 0, 128, 255, 255, 255, 0, 255, 0 }; + vImage_ARGBToYpCbCr info; + vImage_Error error; + error = vImageConvert_ARGBToYpCbCr_GenerateConversion(kvImage_ARGBToYpCbCrMatrix_ITU_R_601_4, &pixelRange, &info, kvImageARGB8888, kvImage420Yp8_Cb8_Cr8, 0); + if (error != kvImageNoError) { + return; + } + + vImage_Buffer src; + src.data = (void *)argb; + src.width = width; + src.height = height; + src.rowBytes = width * 4; + + uint8_t permuteMap[4] = {3, 2, 1, 0}; + error = vImagePermuteChannels_ARGB8888(&src, &src, permuteMap, kvImageDoNotTile); + + error = vImageUnpremultiplyData_ARGB8888(&src, &src, kvImageDoNotTile); + + uint8_t *buf = (uint8_t *)argb; + uint8_t *alpha = yuva + (width * height * 1 + width * height * 1); + for (int i = 0; i < width * height; i += 2) { + uint8_t a0 = (buf[i * 4 + 0] >> 4) << 4; + uint8_t a1 = (buf[(i + 1) * 4 + 0] >> 4) << 4; + alpha[i / 2] = (a0 & (0xf0U)) | ((a1 & (0xf0U)) >> 4); + } + + vImage_Buffer destYp; + destYp.data = (void *)(yuva + 0); + destYp.width = width; + destYp.height = height; + destYp.rowBytes = width; + + vImage_Buffer destCbCr; + destCbCr.data = (void *)(yuva + width * height * 1); + destCbCr.width = width; + destCbCr.height = height; + destCbCr.rowBytes = width; + + error = vImageConvert_ARGB8888To420Yp8_CbCr8(&src, &destYp, &destCbCr, &info, NULL, kvImageDoNotTile); + if (error != kvImageNoError) { + return; + } +} + +void decodeYUVAToRGBA(uint8_t const *yuva, uint8_t *argb, int width, int height) { + vImage_YpCbCrPixelRange pixelRange = (vImage_YpCbCrPixelRange){ 0, 128, 255, 255, 255, 0, 255, 0 }; + vImage_YpCbCrToARGB info; + + vImage_Error error; + error = vImageConvert_YpCbCrToARGB_GenerateConversion(kvImage_YpCbCrToARGBMatrix_ITU_R_601_4, &pixelRange, &info, kvImage420Yp8_Cb8_Cr8, kvImageARGB8888, 0); + if (error != kvImageNoError) { + return; + } + + vImage_Buffer srcYp; + srcYp.data = (void *)(yuva + 0); + srcYp.width = width; + srcYp.height = height; + srcYp.rowBytes = width * 1; + + vImage_Buffer srcCbCr; + srcCbCr.data = (void *)(yuva + width * height * 1); + srcCbCr.width = width; + srcCbCr.height = height; + srcCbCr.rowBytes = width * 1; + + vImage_Buffer dest; + dest.data = (void *)argb; + dest.width = width; + dest.height = height; + dest.rowBytes = width * 4; + + error = vImageConvert_420Yp8_CbCr8ToARGB8888(&srcYp, &srcCbCr, &dest, &info, NULL, 0xff, kvImageDoNotTile); + + uint8_t const *alpha = yuva + (width * height * 1 + width * height * 1); + for (int i = 0; i < width * height; i += 2) { + uint8_t a = alpha[i / 2]; + argb[i * 4 + 0] = (a & (0xf0U)); + argb[(i + 1) * 4 + 0] = (a & (0x0fU)) << 4; + } + + error = vImagePremultiplyData_ARGB8888(&dest, &dest, kvImageDoNotTile); + + uint8_t permuteMap[4] = {3, 2, 1, 0}; + error = vImagePermuteChannels_ARGB8888(&dest, &dest, permuteMap, kvImageDoNotTile); + + if (error != kvImageNoError) { + return; + } } diff --git a/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj b/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj index 9d214e3b27..5bb26b24a5 100644 --- a/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj +++ b/submodules/TelegramUI/TelegramUI_Xcode.xcodeproj/project.pbxproj @@ -255,6 +255,26 @@ D0104F2A1F471DA6004E4881 /* InstantImageGalleryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0104F291F471DA6004E4881 /* InstantImageGalleryItem.swift */; }; D0104F2C1F471EEB004E4881 /* InstantPageGalleryFooterContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0104F2B1F471EEB004E4881 /* InstantPageGalleryFooterContentNode.swift */; }; D0105D682182680E007C04A7 /* IsMediaStreamable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0105D672182680E007C04A7 /* IsMediaStreamable.swift */; }; + D010DF1F22C18769009324D4 /* PvrTcEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DF0C22C18767009324D4 /* PvrTcEncoder.cpp */; }; + D010DF2022C18769009324D4 /* PvrTcPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF0D22C18767009324D4 /* PvrTcPacket.h */; }; + D010DF2122C18769009324D4 /* MortonTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DF0E22C18767009324D4 /* MortonTable.cpp */; }; + D010DF2222C18769009324D4 /* BitScale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DF0F22C18767009324D4 /* BitScale.cpp */; }; + D010DF2322C18769009324D4 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DF1022C18767009324D4 /* main.cpp */; }; + D010DF2422C18769009324D4 /* AlphaBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1122C18767009324D4 /* AlphaBitmap.h */; }; + D010DF2522C18769009324D4 /* Interval.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1222C18767009324D4 /* Interval.h */; }; + D010DF2622C18769009324D4 /* PvrTcEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1322C18767009324D4 /* PvrTcEncoder.h */; }; + D010DF2722C18769009324D4 /* Bitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1422C18767009324D4 /* Bitmap.h */; }; + D010DF2822C18769009324D4 /* PvrTcDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DF1522C18768009324D4 /* PvrTcDecoder.cpp */; }; + D010DF2922C18769009324D4 /* BitScale.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1622C18768009324D4 /* BitScale.h */; }; + D010DF2A22C18769009324D4 /* PvrTcPacket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D010DF1722C18768009324D4 /* PvrTcPacket.cpp */; }; + D010DF2B22C18769009324D4 /* BitUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1822C18768009324D4 /* BitUtility.h */; }; + D010DF2C22C18769009324D4 /* MortonTable.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1922C18768009324D4 /* MortonTable.h */; }; + D010DF2D22C18769009324D4 /* Point2.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1A22C18768009324D4 /* Point2.h */; }; + D010DF2E22C18769009324D4 /* PvrTcDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1B22C18768009324D4 /* PvrTcDecoder.h */; }; + D010DF2F22C18769009324D4 /* RgbaBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1C22C18769009324D4 /* RgbaBitmap.h */; }; + D010DF3022C18769009324D4 /* RgbBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1D22C18769009324D4 /* RgbBitmap.h */; }; + D010DF3122C18769009324D4 /* ColorRgba.h in Headers */ = {isa = PBXBuildFile; fileRef = D010DF1E22C18769009324D4 /* ColorRgba.h */; }; + D010E17D22C238BC009324D4 /* RLottie.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D010E17C22C238BC009324D4 /* RLottie.framework */; }; D0119CD020CAE75F00895300 /* LegacySecureIdAttachmentMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0119CCF20CAE75F00895300 /* LegacySecureIdAttachmentMenu.swift */; }; D013630C208FA62400EB3653 /* SecureIdDocumentGalleryFooterContentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D013630B208FA62400EB3653 /* SecureIdDocumentGalleryFooterContentNode.swift */; }; D0147BA7206E8B4F00E40378 /* SecureIdAuthAcceptNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0147BA6206E8B4F00E40378 /* SecureIdAuthAcceptNode.swift */; }; @@ -1467,6 +1487,26 @@ D0104F2B1F471EEB004E4881 /* InstantPageGalleryFooterContentNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstantPageGalleryFooterContentNode.swift; sourceTree = ""; }; D0105D591D80B957008755D8 /* ChatChannelSubscriberInputPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatChannelSubscriberInputPanelNode.swift; sourceTree = ""; }; D0105D672182680E007C04A7 /* IsMediaStreamable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IsMediaStreamable.swift; sourceTree = ""; }; + D010DF0C22C18767009324D4 /* PvrTcEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PvrTcEncoder.cpp; path = "third-party/etc2/PvrTcEncoder.cpp"; sourceTree = SOURCE_ROOT; }; + D010DF0D22C18767009324D4 /* PvrTcPacket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PvrTcPacket.h; path = "third-party/etc2/PvrTcPacket.h"; sourceTree = SOURCE_ROOT; }; + D010DF0E22C18767009324D4 /* MortonTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MortonTable.cpp; path = "third-party/etc2/MortonTable.cpp"; sourceTree = SOURCE_ROOT; }; + D010DF0F22C18767009324D4 /* BitScale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BitScale.cpp; path = "third-party/etc2/BitScale.cpp"; sourceTree = SOURCE_ROOT; }; + D010DF1022C18767009324D4 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = "third-party/etc2/main.cpp"; sourceTree = SOURCE_ROOT; }; + D010DF1122C18767009324D4 /* AlphaBitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AlphaBitmap.h; path = "third-party/etc2/AlphaBitmap.h"; sourceTree = SOURCE_ROOT; }; + D010DF1222C18767009324D4 /* Interval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Interval.h; path = "third-party/etc2/Interval.h"; sourceTree = SOURCE_ROOT; }; + D010DF1322C18767009324D4 /* PvrTcEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PvrTcEncoder.h; path = "third-party/etc2/PvrTcEncoder.h"; sourceTree = SOURCE_ROOT; }; + D010DF1422C18767009324D4 /* Bitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Bitmap.h; path = "third-party/etc2/Bitmap.h"; sourceTree = SOURCE_ROOT; }; + D010DF1522C18768009324D4 /* PvrTcDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PvrTcDecoder.cpp; path = "third-party/etc2/PvrTcDecoder.cpp"; sourceTree = SOURCE_ROOT; }; + D010DF1622C18768009324D4 /* BitScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BitScale.h; path = "third-party/etc2/BitScale.h"; sourceTree = SOURCE_ROOT; }; + D010DF1722C18768009324D4 /* PvrTcPacket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PvrTcPacket.cpp; path = "third-party/etc2/PvrTcPacket.cpp"; sourceTree = SOURCE_ROOT; }; + D010DF1822C18768009324D4 /* BitUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BitUtility.h; path = "third-party/etc2/BitUtility.h"; sourceTree = SOURCE_ROOT; }; + D010DF1922C18768009324D4 /* MortonTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MortonTable.h; path = "third-party/etc2/MortonTable.h"; sourceTree = SOURCE_ROOT; }; + D010DF1A22C18768009324D4 /* Point2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Point2.h; path = "third-party/etc2/Point2.h"; sourceTree = SOURCE_ROOT; }; + D010DF1B22C18768009324D4 /* PvrTcDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PvrTcDecoder.h; path = "third-party/etc2/PvrTcDecoder.h"; sourceTree = SOURCE_ROOT; }; + D010DF1C22C18769009324D4 /* RgbaBitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RgbaBitmap.h; path = "third-party/etc2/RgbaBitmap.h"; sourceTree = SOURCE_ROOT; }; + D010DF1D22C18769009324D4 /* RgbBitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RgbBitmap.h; path = "third-party/etc2/RgbBitmap.h"; sourceTree = SOURCE_ROOT; }; + D010DF1E22C18769009324D4 /* ColorRgba.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ColorRgba.h; path = "third-party/etc2/ColorRgba.h"; sourceTree = SOURCE_ROOT; }; + D010E17C22C238BC009324D4 /* RLottie.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RLottie.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0119CCF20CAE75F00895300 /* LegacySecureIdAttachmentMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacySecureIdAttachmentMenu.swift; sourceTree = ""; }; D0127A0C1E6424AC003BFF2E /* ChatPinnedMessageTitlePanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatPinnedMessageTitlePanelNode.swift; sourceTree = ""; }; D013630B208FA62400EB3653 /* SecureIdDocumentGalleryFooterContentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureIdDocumentGalleryFooterContentNode.swift; sourceTree = ""; }; @@ -2417,6 +2457,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D010E17D22C238BC009324D4 /* RLottie.framework in Frameworks */, D03AE67522B945D30078411C /* BuildConfig.framework in Frameworks */, D03AE67322B9459C0078411C /* HockeySDK.framework in Frameworks */, D02D634A22B85B94006BE519 /* PushKit.framework in Frameworks */, @@ -2825,6 +2866,25 @@ D01590A922BD46690017C33E /* Animation */ = { isa = PBXGroup; children = ( + D010DF1122C18767009324D4 /* AlphaBitmap.h */, + D010DF1422C18767009324D4 /* Bitmap.h */, + D010DF0F22C18767009324D4 /* BitScale.cpp */, + D010DF1622C18768009324D4 /* BitScale.h */, + D010DF1822C18768009324D4 /* BitUtility.h */, + D010DF1E22C18769009324D4 /* ColorRgba.h */, + D010DF1222C18767009324D4 /* Interval.h */, + D010DF1022C18767009324D4 /* main.cpp */, + D010DF0E22C18767009324D4 /* MortonTable.cpp */, + D010DF1922C18768009324D4 /* MortonTable.h */, + D010DF1A22C18768009324D4 /* Point2.h */, + D010DF1522C18768009324D4 /* PvrTcDecoder.cpp */, + D010DF1B22C18768009324D4 /* PvrTcDecoder.h */, + D010DF0C22C18767009324D4 /* PvrTcEncoder.cpp */, + D010DF1322C18767009324D4 /* PvrTcEncoder.h */, + D010DF1722C18768009324D4 /* PvrTcPacket.cpp */, + D010DF0D22C18767009324D4 /* PvrTcPacket.h */, + D010DF1C22C18769009324D4 /* RgbaBitmap.h */, + D010DF1D22C18769009324D4 /* RgbBitmap.h */, D01590B622BDAEBC0017C33E /* BC1Compression.cpp */, D01590B122BDAEBB0017C33E /* BC1Compression.h */, D01590B922BDAEBC0017C33E /* BMPImage.cpp */, @@ -3539,6 +3599,7 @@ D08D45281D5E340200A7428A /* Frameworks */ = { isa = PBXGroup; children = ( + D010E17C22C238BC009324D4 /* RLottie.framework */, D03AE67422B945D30078411C /* BuildConfig.framework */, D03AE67222B9459C0078411C /* HockeySDK.framework */, D02D634922B85B94006BE519 /* PushKit.framework */, @@ -4904,20 +4965,26 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + D010DF2B22C18769009324D4 /* BitUtility.h in Headers */, D0E9BA221F05577700F079A4 /* STPCard.h in Headers */, + D010DF3122C18769009324D4 /* ColorRgba.h in Headers */, D0E9BA591F055A2200F079A4 /* STPWeakStrongMacros.h in Headers */, D0E9BADE1F0574D800F079A4 /* STPBackendAPIAdapter.h in Headers */, + D010DF2922C18769009324D4 /* BitScale.h in Headers */, D0E9BAD11F0573C000F079A4 /* STPToken.h in Headers */, + D010DF2C22C18769009324D4 /* MortonTable.h in Headers */, D01590C222BDAEBC0017C33E /* TypeDefinitions.h in Headers */, D0AE303622B1D3620058D3BC /* TGBridgeAudioDecoder.h in Headers */, D0E9BAE71F0574FF00F079A4 /* STPCustomer.h in Headers */, D0208AD51FA33D14001F0D5F /* RaiseToListenActivator.h in Headers */, D00817DA22B47A14008A895F /* TGPresentationAutoNightPreferences.h in Headers */, D0E9BAE31F0574D800F079A4 /* STPBankAccountParams.h in Headers */, + D010DF3022C18769009324D4 /* RgbBitmap.h in Headers */, D0E9BA361F05585000F079A4 /* STPPhoneNumberValidator.h in Headers */, D0E9BA511F0559DA00F079A4 /* STPImageLibrary.h in Headers */, D0E9BA4C1F0559C700F079A4 /* NSString+Stripe_CardBrands.h in Headers */, D00817E022B47A14008A895F /* UIImage+ImageEffects.h in Headers */, + D010DF2E22C18769009324D4 /* PvrTcDecoder.h in Headers */, D01590BA22BDAEBC0017C33E /* ColorVec.h in Headers */, D0E9BAE11F0574D800F079A4 /* STPBankAccount.h in Headers */, D0E9BACE1F0573AF00F079A4 /* STPBlocks.h in Headers */, @@ -4931,6 +4998,7 @@ D01590AE22BD58AD0017C33E /* YUV.h in Headers */, D008177B22B46B7E008A895F /* TGContactModel.h in Headers */, D0E9BA291F0557A600F079A4 /* STPFormEncodable.h in Headers */, + D010DF2F22C18769009324D4 /* RgbaBitmap.h in Headers */, D0E9BA141F05574500F079A4 /* STPCardValidationState.h in Headers */, D00701A12029F6D0006B9E34 /* TGMimeTypeMap.h in Headers */, D0E9BA461F0559A500F079A4 /* NSDictionary+Stripe.h in Headers */, @@ -4942,13 +5010,18 @@ D0E9BADF1F0574D800F079A4 /* STPDispatchFunctions.h in Headers */, D00817CD22B47A14008A895F /* TGAutoDownloadPreferences.h in Headers */, D0E9BACB1F05738600F079A4 /* STPAPIPostRequest.h in Headers */, + D010DF2722C18769009324D4 /* Bitmap.h in Headers */, + D010DF2422C18769009324D4 /* AlphaBitmap.h in Headers */, D0E9BA561F055A0B00F079A4 /* STPFormTextField.h in Headers */, D01590C122BDAEBC0017C33E /* DDSImage.h in Headers */, D008177C22B46B7E008A895F /* TGItemProviderSignals.h in Headers */, + D010DF2522C18769009324D4 /* Interval.h in Headers */, + D010DF2622C18769009324D4 /* PvrTcEncoder.h in Headers */, D0E9BABE1F05735F00F079A4 /* STPPaymentConfiguration+Private.h in Headers */, D01590BB22BDAEBC0017C33E /* BC1Compression.h in Headers */, D0E9BACA1F05738600F079A4 /* STPAPIClient+Private.h in Headers */, D01590BC22BDAEBC0017C33E /* BMPImage.h in Headers */, + D010DF2D22C18769009324D4 /* Point2.h in Headers */, D0E9BA251F05578900F079A4 /* STPCardBrand.h in Headers */, D0E9BAC81F05738600F079A4 /* STPAPIClient+ApplePay.h in Headers */, D0E9BA451F0559A500F079A4 /* STPAPIResponseDecodable.h in Headers */, @@ -4960,6 +5033,7 @@ D01590C922BE62C40017C33E /* TextureCompression.h in Headers */, D0E9BA191F05574500F079A4 /* STPPaymentCardTextField.h in Headers */, D0E9BA3F1F0558FE00F079A4 /* STPSource.h in Headers */, + D010DF2022C18769009324D4 /* PvrTcPacket.h in Headers */, D008177A22B46B7E008A895F /* TGShareLocationSignals.h in Headers */, D0E9BABC1F05735F00F079A4 /* STPPaymentConfiguration.h in Headers */, D01590BF22BDAEBC0017C33E /* Image.h in Headers */, @@ -5203,6 +5277,7 @@ D093D7DD2062D09A00BC3599 /* SecureIdAuthFormFieldNode.swift in Sources */, 092F36902157AB46001A9F49 /* ItemListCallListItem.swift in Sources */, D0EC6CC61EB9F58800EBF1C3 /* PresenceStrings.swift in Sources */, + D010DF1F22C18769009324D4 /* PvrTcEncoder.cpp in Sources */, D00817D522B47A14008A895F /* ApplicationShortcutItem.swift in Sources */, D077C5C122B59A800097D617 /* ApplicationContext.swift in Sources */, D0EC6CC71EB9F58800EBF1C3 /* PeerNotificationSoundStrings.swift in Sources */, @@ -5344,6 +5419,7 @@ 09CE95042236C6B300A7D2C3 /* CachedInstantPages.swift in Sources */, D0AB269E21D56A12008F6685 /* ChannelPermissionsController.swift in Sources */, D0B69C3920EBB397003632C7 /* ChatMessageInteractiveInstantVideoNode.swift in Sources */, + D010DF2822C18769009324D4 /* PvrTcDecoder.cpp in Sources */, 09F79A0D21C88E8900820234 /* LegacyWebSearchEditor.swift in Sources */, 09F21565225C83E100AEDF6D /* ChatListStatusNode.swift in Sources */, D056CD701FF147B000880D28 /* IconButtonNode.swift in Sources */, @@ -5644,6 +5720,7 @@ 09D304152173C0E900C00567 /* WatchManager.swift in Sources */, 9F06830921A404AB001D8EDB /* NotificationExceptionControllerNode.swift in Sources */, D039FB1921711B5D00BD1BAD /* PlatformVideoContent.swift in Sources */, + D010DF2122C18769009324D4 /* MortonTable.cpp in Sources */, D0CAD8FD20AE467D00ACD96E /* PeerChannelMemberCategoriesContextsManager.swift in Sources */, D035734B22B5CCCA00F0920D /* LegacyBuffer.swift in Sources */, D0430B001FF4570500A35ADD /* WebController.swift in Sources */, @@ -5689,6 +5766,7 @@ D0EC6DA91EB9F58900EBF1C3 /* ChatPresentationInterfaceState.swift in Sources */, D0EC6DAA1EB9F58900EBF1C3 /* ChatPanelInterfaceInteraction.swift in Sources */, D00FF2091F4E2414006FA332 /* InstantPageSettingsNode.swift in Sources */, + D010DF2A22C18769009324D4 /* PvrTcPacket.cpp in Sources */, D0BE3037206139F500FBE6D8 /* ImageCompression.swift in Sources */, 09AE3823214C110900850BFD /* LegacySecureIdScanController.swift in Sources */, D0EC6DAB1EB9F58900EBF1C3 /* ChatInterfaceStateAccessoryPanels.swift in Sources */, @@ -5785,6 +5863,7 @@ D0EC6DD81EB9F58900EBF1C3 /* VerticalListContextResultsChatInputPanelButtonItem.swift in Sources */, D04281F4200E5AB0009DDE36 /* ChatRecentActionsController.swift in Sources */, 09FE756D2153F5F900A3120F /* CallRouteActionSheetItem.swift in Sources */, + D010DF2222C18769009324D4 /* BitScale.cpp in Sources */, D0BFAE4E20AB1D7B00793CF2 /* DisabledContextResultsChatInputContextPanelNode.swift in Sources */, D064EF871F69A06F00AC0398 /* MessageContentKind.swift in Sources */, D020A9DA1FEAE675008C66F7 /* OverlayPlayerController.swift in Sources */, @@ -6047,6 +6126,7 @@ D00BDA1F1EE5B69200C64C5E /* ChannelAdminController.swift in Sources */, D0EC6E501EB9F58900EBF1C3 /* ChannelAdminsController.swift in Sources */, D0EC6E511EB9F58900EBF1C3 /* ChannelBlacklistController.swift in Sources */, + D010DF2322C18769009324D4 /* main.cpp in Sources */, D0EC6E521EB9F58900EBF1C3 /* ChannelInfoController.swift in Sources */, D0EC6E531EB9F58900EBF1C3 /* ChannelMembersController.swift in Sources */, D02B676320800A00001A864A /* PaneSearchBarPlaceholderItem.swift in Sources */, @@ -6894,7 +6974,7 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_INSTALL_OBJC_HEADER = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 4.0; USER_HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/third-party/FFmpeg-iOS/include"; }; diff --git a/submodules/TelegramUI/third-party/bc1/BC1Compression.cpp b/submodules/TelegramUI/third-party/bc1/BC1Compression.cpp index 5f59ed8c54..1b71328b29 100644 --- a/submodules/TelegramUI/third-party/bc1/BC1Compression.cpp +++ b/submodules/TelegramUI/third-party/bc1/BC1Compression.cpp @@ -52,7 +52,7 @@ namespace DTX1CompressorDecompressor { unsigned int index = (height - 1 - row) * width + col; // image is reversed in rows (upside down), so row = 0 is the bottom of the image std::memcpy(&pixelData[index].bgra, dtaPtr, 3); - dtaPtr += 3; + dtaPtr += 4; } } @@ -106,7 +106,8 @@ namespace DTX1CompressorDecompressor } // copy pixel data to the actual bmp image - unsigned char* bmpImgData = new unsigned char[3 * width * height]; + unsigned char* bmpImgData = new unsigned char[4 * width * height]; + memset(bmpImgData, 0xff, 4 * width * height); unsigned char* bmpDataPtr = bmpImgData; for (unsigned int row = 0; row < height; ++row) @@ -115,7 +116,7 @@ namespace DTX1CompressorDecompressor { unsigned int index = (height - 1 - row) * width + col; // image is reversed in rows (upside down), so row = 0 is the bottom of the image std::memcpy(bmpDataPtr, &pixelData[index].bgra, 3); - bmpDataPtr += 3; + bmpDataPtr += 4; } } diff --git a/submodules/TelegramUI/third-party/bc1/TextureCompression.cpp b/submodules/TelegramUI/third-party/bc1/TextureCompression.cpp index 452ba3f0af..f118086bbf 100644 --- a/submodules/TelegramUI/third-party/bc1/TextureCompression.cpp +++ b/submodules/TelegramUI/third-party/bc1/TextureCompression.cpp @@ -1,13 +1,36 @@ #import "TextureCompression.h" #import "BC1Compression.h" +#import "PvrTcEncoder.h" +#import "PvrTcDecoder.h" +#import "RgbaBitmap.h" void compressRGBAToBC1(uint8_t const * _Nonnull argb, int width, int height, uint8_t * _Nonnull bc1) { - DTX1CompressorDecompressor::BC1Compression compression; - DTX1CompressorDecompressor::BMPImage image; - image.InitWithData((unsigned char *)argb, width, height); - image.m_ownData = false; - DTX1CompressorDecompressor::BC1DDSImage ddsImage; - compression.Compress(image, ddsImage); - int numBlocks = width * height / (4 * 4); - memcpy(bc1, ddsImage.GetData(), numBlocks * 8); + Javelin::RgbaBitmap bitmap(width, height); + uint8_t *data = (uint8_t *)bitmap.GetData(); + for (int i = 0; i < width * height; i++) { + data[i * 4 + 0] = argb[i * 4 + 0]; + data[i * 4 + 1] = argb[i * 4 + 1]; + data[i * 4 + 2] = argb[i * 4 + 2]; + data[i * 4 + 3] = argb[i * 4 + 3]; + } + Javelin::PvrTcEncoder::EncodeRgb4Bpp(bc1, bitmap); +} + +void decompressBC1ToRGBA(uint8_t const * _Nonnull bc1, int width, int height, uint8_t * _Nonnull argb) { + uint8_t *data = (uint8_t *)malloc(width * height * 3); + Javelin::PvrTcDecoder::DecodeRgb4Bpp((Javelin::ColorRgba *)data, Javelin::Point2(width, height), bc1); + for (int i = 0; i < width * height; i++) { + uint8_t r = data[i * 3 + 0]; + uint8_t g = data[i * 3 + 1]; + uint8_t b = data[i * 3 + 2]; + argb[i * 4 + 3] = 255; + argb[i * 4 + 2] = b; + argb[i * 4 + 1] = g; + argb[i * 4 + 0] = r; + } + free(data); +} + +void compressRGBAToETC2(uint8_t const * _Nonnull argb, int width, int height, uint8_t * _Nonnull etc2) { + } diff --git a/submodules/TelegramUI/third-party/bc1/TextureCompression.h b/submodules/TelegramUI/third-party/bc1/TextureCompression.h index 29b5c6f932..b013ac17d2 100644 --- a/submodules/TelegramUI/third-party/bc1/TextureCompression.h +++ b/submodules/TelegramUI/third-party/bc1/TextureCompression.h @@ -5,6 +5,8 @@ extern "C" { #endif void compressRGBAToBC1(uint8_t const * _Nonnull argb, int width, int height, uint8_t * _Nonnull bc1); +void decompressBC1ToRGBA(uint8_t const * _Nonnull bc1, int width, int height, uint8_t * _Nonnull argb); +void compressRGBAToETC2(uint8_t const * _Nonnull argb, int width, int height, uint8_t * _Nonnull etc2); #ifdef __cplusplus }