loader/lottie: ++safety

- add an execeptional hanlding at parsing the assets.
- The precomp layer failed to prepare its instance in the parsing stage. This corrects the mistake.
This commit is contained in:
Hermet Park 2023-08-09 12:09:54 +09:00 committed by Hermet Park
parent 9db9e003ba
commit 6f8504d3b9
4 changed files with 15 additions and 23 deletions

View file

@ -31,7 +31,6 @@
struct Animation::Impl struct Animation::Impl
{ {
//TODO: Memory Safety
Picture picture; Picture picture;
}; };
@ -41,7 +40,7 @@ struct Animation::Impl
Animation::~Animation() Animation::~Animation()
{ {
//FIXME: free pImpl
} }

View file

@ -370,15 +370,15 @@ static void _buildReference(LottieComposition* comp, LottieLayer* layer)
{ {
for (auto asset = comp->assets.data; asset < comp->assets.end(); ++asset) { for (auto asset = comp->assets.data; asset < comp->assets.end(); ++asset) {
if (strcmp(layer->refId, (*asset)->name)) continue; if (strcmp(layer->refId, (*asset)->name)) continue;
auto assetLayer = static_cast<LottieLayer*>(*asset);
if (layer->type == LottieLayer::Precomp) { if (layer->type == LottieLayer::Precomp) {
auto assetLayer = static_cast<LottieLayer*>(*asset);
if (_buildPrecomp(comp, assetLayer)) { if (_buildPrecomp(comp, assetLayer)) {
layer->children = assetLayer->children; layer->children = assetLayer->children;
} }
} else if (layer->type == LottieLayer::Image) { } else if (layer->type == LottieLayer::Image) {
layer->children.push(*asset); layer->children.push(*asset);
} }
layer->statical &= assetLayer->statical; layer->statical &= (*asset)->statical;
break; break;
} }
} }

View file

@ -349,12 +349,6 @@ struct LottieLayer : LottieGroup
{ {
enum Type : uint8_t {Precomp = 0, Solid, Image, Null, Shape, Text}; enum Type : uint8_t {Precomp = 0, Solid, Image, Null, Shape, Text};
LottieLayer()
{
autoOrient = false;
mask = false;
}
~LottieLayer() ~LottieLayer()
{ {
if (refId) { if (refId) {
@ -418,9 +412,8 @@ struct LottieLayer : LottieGroup
} cache; } cache;
Type type = Null; Type type = Null;
bool autoOrient = false;
bool autoOrient : 1; bool mask = false;
bool mask : 1;
}; };

View file

@ -806,9 +806,6 @@ void LottieParser::parseObject(LottieGroup* parent)
LottieImage* LottieParser::parseImage(const char* key) LottieImage* LottieParser::parseImage(const char* key)
{ {
auto image = new LottieImage;
if (!image) return nullptr;
//Used for Image Asset //Used for Image Asset
const char* data = nullptr; const char* data = nullptr;
const char* subPath = nullptr; const char* subPath = nullptr;
@ -821,15 +818,14 @@ LottieImage* LottieParser::parseImage(const char* key)
data = getString(); data = getString();
} else if (!strcmp(key, "e")) { } else if (!strcmp(key, "e")) {
embedded = getInt(); embedded = getInt();
#if 0
} else if (!strcmp(key, "w")) {
auto w = getInt();
} else if (!strcmp(key, "h")) {
auto h = getInt();
#endif
} else skip(key); } else skip(key);
} while ((key = nextObjectKey())); } while ((key = nextObjectKey()));
if (!data) return nullptr;
auto image = new LottieImage;
if (!image) return nullptr;
//embeded image resource. should start with "data:" //embeded image resource. should start with "data:"
//header look like "data:image/png;base64," so need to skip till ','. //header look like "data:image/png;base64," so need to skip till ','.
if (embedded && !strncmp(data, "data:", 5)) { if (embedded && !strncmp(data, "data:", 5)) {
@ -877,13 +873,15 @@ LottieObject* LottieParser::parseAsset()
//Precomposition asset //Precomposition asset
} else if (!strcmp(key, "layers")) { } else if (!strcmp(key, "layers")) {
obj = parseLayers(); obj = parseLayers();
} else if (!strcmp(key, "w") || !strcmp(key, "h") || !strcmp(key, "nm") || !strcmp(key, "fr")) {
skip(key);
//Image asset //Image asset
} else { } else {
obj = parseImage(key); obj = parseImage(key);
break; break;
} }
} }
obj->name = id; if (obj) obj->name = id;
return obj; return obj;
} }
@ -1007,6 +1005,8 @@ LottieLayer* LottieParser::parseLayers()
root->children.push(layer); root->children.push(layer);
} }
} }
root->prepare();
return root; return root;
} }