lottie/parser: added support for image asset parsing. 37/197637/3
authorsubhransu mohanty <sub.mohanty@samsung.com>
Tue, 15 Jan 2019 00:52:31 +0000 (09:52 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Tue, 15 Jan 2019 06:24:10 +0000 (06:24 +0000)
Change-Id: Ib7a4ec1b7d6d7f5c9357e451c3908d88c671bc37

src/lottie/lottieloader.cpp
src/lottie/lottiemodel.h
src/lottie/lottieparser.cpp
src/lottie/lottieparser.h

index ac2da78..6b540f8 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <fstream>
 #include <unordered_map>
-
+#include <cstring>
 using namespace std;
 
 class LottieFileCache {
@@ -56,6 +56,13 @@ void LottieFileCache::add(const std::string &key, std::shared_ptr<LOTModel> valu
     mHash[key] = std::move(value);
 }
 
+static std::string dirname(const std::string &path)
+{
+    const char *ptr = strrchr(path.c_str(), '/');
+    int len = int(ptr + 1 - path.c_str()); // +1 to include '/'
+    return std::string(path, 0, len);
+}
+
 bool LottieLoader::load(const std::string &path)
 {
     LottieFileCache &fileCache = LottieFileCache::get();
@@ -73,7 +80,7 @@ bool LottieLoader::load(const std::string &path)
         std::stringstream buf;
         buf << f.rdbuf();
 
-        LottieParser parser(const_cast<char *>(buf.str().data()));
+        LottieParser parser(const_cast<char *>(buf.str().data()), dirname(path).c_str());
         mModel = parser.model();
         fileCache.add(path, mModel);
 
index 16a75d5..08f254e 100644 (file)
@@ -339,9 +339,19 @@ public:
 class LOTLayerData;
 struct LOTAsset
 {
-    int                                          mAssetType; //lottie asset type  (precomp/char/image)
-    std::string                                  mRefId; // ref id
-    std::vector<std::shared_ptr<LOTData>>   mLayers;
+    enum class Type {
+        Precomp,
+        Image,
+        Char
+    };
+
+    Type                                      mAssetType{Type::Precomp};
+    std::string                               mRefId; // ref id
+    std::vector<std::shared_ptr<LOTData>>     mLayers;
+    // image asset data
+    int                                       mWidth{0};
+    int                                       mHeight{0};
+    std::string                               mImagePath;
 };
 
 class LOTLayerData : public LOTGroupData
@@ -393,6 +403,7 @@ public:
     bool                 mAutoOrient{false};
     std::vector<std::shared_ptr<LOTMaskData>>  mMasks;
     LOTCompositionData   *mCompRef{nullptr};
+    std::shared_ptr<LOTAsset> mAsset;
 };
 
 class LOTCompositionData : public LOTData
index 16e9232..643c3cb 100644 (file)
@@ -173,7 +173,9 @@ protected:
 
 class LottieParserImpl : protected LookaheadParserHandler {
 public:
-    LottieParserImpl(char *str) : LookaheadParserHandler(str) {}
+    LottieParserImpl(char *str, const char *dir_path)
+        :LookaheadParserHandler(str),
+         mDirPath(dir_path){}
 
 public:
     bool        EnterObject();
@@ -270,6 +272,7 @@ protected:
     LOTCompositionData *                       compRef{nullptr};
     LOTLayerData *                             curLayerRef{nullptr};
     std::vector<std::shared_ptr<LOTLayerData>> mLayersToUpdate;
+    std::string                                mDirPath;
     void                                       SkipOut(int depth);
 };
 
@@ -557,7 +560,11 @@ void LottieParserImpl::resolveLayerRefs()
         LOTLayerData *layer = i.get();
         auto          search = compRef->mAssets.find(layer->mPreCompRefId);
         if (search != compRef->mAssets.end()) {
-            layer->mChildren = search->second.get()->mLayers;
+            if (layer->mLayerType == LayerType::Image) {
+                layer->mAsset = search->second;
+            } else if (layer->mLayerType == LayerType::Precomp) {
+                layer->mChildren = search->second.get()->mLayers;
+            }
         }
     }
 }
@@ -628,11 +635,23 @@ std::shared_ptr<LOTAsset> LottieParserImpl::parseAsset()
     RAPIDJSON_ASSERT(PeekType() == kObjectType);
     std::shared_ptr<LOTAsset> sharedAsset = std::make_shared<LOTAsset>();
     LOTAsset *                asset = sharedAsset.get();
+    std::string    filename;
+    std::string    relativePath;
     EnterObject();
     while (const char *key = NextObjectKey()) {
-        if (0 == strcmp(key, "ty")) { /* Type of layer: Shape. Value 4.*/
+        if (0 == strcmp(key, "w")) {
             RAPIDJSON_ASSERT(PeekType() == kNumberType);
-            asset->mAssetType = GetInt();
+            asset->mWidth = GetInt();
+        } else if (0 == strcmp(key, "h")) {
+            RAPIDJSON_ASSERT(PeekType() == kNumberType);
+            asset->mHeight = GetInt();
+        } else if (0 == strcmp(key, "p")) { /* image name */
+            asset->mAssetType = LOTAsset::Type::Image;
+            RAPIDJSON_ASSERT(PeekType() == kStringType);
+            filename = std::string(GetString());
+        } else if (0 == strcmp(key, "u")) { /* relative image path */
+            RAPIDJSON_ASSERT(PeekType() == kStringType);
+            relativePath = std::string(GetString());
         } else if (0 == strcmp(key, "id")) { /* reference id*/
             if (PeekType() == kStringType) {
                 asset->mRefId = std::string(GetString());
@@ -641,6 +660,7 @@ std::shared_ptr<LOTAsset> LottieParserImpl::parseAsset()
                 asset->mRefId = std::to_string(GetInt());
             }
         } else if (0 == strcmp(key, "layers")) {
+            asset->mAssetType = LOTAsset::Type::Precomp;
             RAPIDJSON_ASSERT(PeekType() == kArrayType);
             EnterArray();
             while (NextArrayValue()) {
@@ -654,6 +674,10 @@ std::shared_ptr<LOTAsset> LottieParserImpl::parseAsset()
             Skip(key);
         }
     }
+    // its an image asset
+    if (!filename.empty()) {
+        asset->mImagePath = mDirPath + relativePath + filename;
+    }
     return sharedAsset;
 }
 
@@ -1978,8 +2002,20 @@ public:
                << ", ao:" << obj->autoOrient()
                << ", ddd:" << obj->mTransform->ddd()
                << ", W:" << obj->layerSize().width()
-               << ", H:" << obj->layerSize().height()
-               << "\n";
+               << ", H:" << obj->layerSize().height();
+
+        if (obj->mLayerType == LayerType::Image)
+            vDebug << level
+                   << "\t{ "
+                   << "ImageInfo:"
+                   << " W :" << obj->mAsset->mWidth
+                   << ", H :" << obj->mAsset->mHeight
+                   << ", Path :"<<obj->mAsset->mImagePath
+                   <<" }"
+                   << "\n";
+        else {
+            vDebug<< level;
+        }
         visitChildren(static_cast<LOTGroupData *>(obj), level);
         vDebug << level
                << "} "
@@ -2121,7 +2157,7 @@ LottieParser::~LottieParser()
     delete d;
 }
 
-LottieParser::LottieParser(char *str) : d(new LottieParserImpl(str))
+LottieParser::LottieParser(char *str, const char *dir_path) : d(new LottieParserImpl(str, dir_path))
 {
     d->parseComposition();
 }
index 3c63f65..d892c24 100644 (file)
@@ -25,7 +25,7 @@ class LottieParserImpl;
 class LottieParser {
 public:
     ~LottieParser();
-    LottieParser(char* str);
+    LottieParser(char* str, const char *dir_path="");
     std::shared_ptr<LOTModel> model();
 private:
    LottieParserImpl   *d;