mirror of
https://github.com/OpenVGLab/OmniLottie.git
synced 2026-09-17 07:36:27 +00:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
import os
|
||||
import enum
|
||||
import json
|
||||
import inspect
|
||||
|
||||
from ..parsers.tgs import parse_tgs
|
||||
from ..objects.base import ObjectVisitor
|
||||
from ..objects.animation import Animation
|
||||
from ..objects import layers
|
||||
from ..objects import shapes
|
||||
from ..objects import helpers
|
||||
|
||||
|
||||
class Severity(enum.Enum):
|
||||
Note = enum.auto()
|
||||
Warning = enum.auto()
|
||||
Error = enum.auto()
|
||||
|
||||
|
||||
class TgsError:
|
||||
def __init__(self, message, target, severity=Severity.Warning):
|
||||
self.message = message
|
||||
self.target = target
|
||||
self.severity = severity
|
||||
|
||||
def target_id(self):
|
||||
if isinstance(self.target, str):
|
||||
return self.target
|
||||
if getattr(self.target, "name", ""):
|
||||
return self.target.name
|
||||
return self.target.__class__.__name__
|
||||
|
||||
def __str__(self):
|
||||
return "%s: on %s: %s" % (
|
||||
self.severity.name,
|
||||
self.target_id(),
|
||||
self.message
|
||||
)
|
||||
|
||||
|
||||
class TgsValidator(ObjectVisitor):
|
||||
def __init__(self, severity=Severity.Note):
|
||||
self.errors = []
|
||||
self.severity = severity
|
||||
|
||||
def _check(self, expr, message, target, severity=Severity.Warning):
|
||||
if severity.value >= self.severity.value and not expr:
|
||||
self.errors.append(TgsError(message, target, severity))
|
||||
|
||||
def check_file_size(self, filename):
|
||||
return self.check_size(os.path.getsize(filename))
|
||||
|
||||
def check_size(self, bytes, filename="file"):
|
||||
size_k = bytes / 1024
|
||||
self._check(
|
||||
size_k <= 64,
|
||||
"Invalid size (%.1fk), should be less than 64k" % size_k,
|
||||
filename,
|
||||
Severity.Error
|
||||
)
|
||||
|
||||
def check_file(self, filename):
|
||||
self.check_file_size(filename)
|
||||
try:
|
||||
self(parse_tgs(filename))
|
||||
except json.decoder.JSONDecodeError as e:
|
||||
self._check(
|
||||
False,
|
||||
"Invalid JSON: %s" % e,
|
||||
filename,
|
||||
Severity.Error
|
||||
)
|
||||
|
||||
def visit(self, object):
|
||||
for cls in inspect.getmro(object.__class__):
|
||||
callback = "_visit_%s" % cls.__name__.lower()
|
||||
if hasattr(self, callback):
|
||||
getattr(self, callback)(object)
|
||||
|
||||
def _visit_animation(self, o: Animation):
|
||||
self._check(
|
||||
o.frame_rate in {30, 60},
|
||||
"Invalid framerate %s, should be 30 or 60" % o.frame_rate,
|
||||
o,
|
||||
Severity.Error
|
||||
)
|
||||
self._check(
|
||||
o.width == 512,
|
||||
"Invalid width %s, should be 512" % o.width,
|
||||
o,
|
||||
Severity.Error
|
||||
)
|
||||
self._check(
|
||||
o.height == 512,
|
||||
"Invalid height %s, should be 512" % o.height,
|
||||
o,
|
||||
Severity.Error
|
||||
)
|
||||
self._check(
|
||||
(o.out_point-o.in_point) <= 180,
|
||||
"Too many frames (%s), should be less than 180" % (o.out_point-o.in_point),
|
||||
o,
|
||||
Severity.Error
|
||||
)
|
||||
|
||||
def _visit_layer(self, o: layers.Layer):
|
||||
self._check(
|
||||
not o.has_masks and not o.masks,
|
||||
"Masks are not officially supported",
|
||||
o,
|
||||
Severity.Note
|
||||
)
|
||||
self._check(
|
||||
not o.effects,
|
||||
"Effects are not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
self._check(
|
||||
not o.threedimensional,
|
||||
"3D layers are not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
self._check(
|
||||
not isinstance(o, layers.TextLayer),
|
||||
"Text layers are not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
self._check(
|
||||
not isinstance(o, layers.ImageLayer),
|
||||
"Image layers are not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
self._check(
|
||||
not o.auto_orient,
|
||||
"Auto-orient layers are not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
self._check(
|
||||
o.matte_mode in {None, layers.MatteMode.Normal},
|
||||
"Mattes are not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
|
||||
def _visit_precomplayer(self, o: layers.PreCompLayer):
|
||||
self._check(
|
||||
o.time_remapping is None,
|
||||
"Time remapping is not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
|
||||
def _visit_merge(self, o: shapes.Merge):
|
||||
self._check(
|
||||
False,
|
||||
"Merge paths are not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
|
||||
def _visit_transform(self, o: helpers.Transform):
|
||||
self._check(
|
||||
o.skew is None or (
|
||||
not o.skew.animated and o.skew.value == 0
|
||||
),
|
||||
"Skew transforms are not supported",
|
||||
o,
|
||||
Severity.Warning
|
||||
)
|
||||
|
||||
def _visit_gradientstroke(self, o: shapes.GradientStroke):
|
||||
self._check(
|
||||
False,
|
||||
"Gradient strokes are not officially supported",
|
||||
o,
|
||||
Severity.Note
|
||||
)
|
||||
|
||||
def _visit_star(self, o: shapes.Star):
|
||||
self._check(
|
||||
False,
|
||||
"Star Shapes are not officially supported",
|
||||
o,
|
||||
Severity.Note
|
||||
)
|
||||
|
||||
def _visit_repeater(self, o: shapes.Repeater):
|
||||
self._check(
|
||||
False,
|
||||
"Repeaters are not officially supported",
|
||||
o,
|
||||
Severity.Note
|
||||
)
|
||||
Reference in New Issue
Block a user