renderer/loader: enhance picture format compatibility

Attempt to load a given file/data using candidate formats
when the desired loader fails. This approach will enhance
the compatibility with various file formats in unexpected scenarios.

Previously, we had removed this feature, but have since
recognized its necessity due to the impact on file data
in specific corner cases.
This commit is contained in:
Hermet Park 2024-02-07 17:23:16 +09:00 committed by Hermet Park
parent 42a5366735
commit 20fcb5b1c2
2 changed files with 45 additions and 32 deletions

View file

@ -63,7 +63,7 @@ using namespace tvg;
#define TVG_CLASS_ID_RADIAL 5 #define TVG_CLASS_ID_RADIAL 5
#define TVG_CLASS_ID_TEXT 6 #define TVG_CLASS_ID_TEXT 6
enum class FileType { Tvg = 0, Svg, Ttf, Lottie, Raw, Png, Jpg, Webp, Gif, Unknown }; enum class FileType { Png = 0, Jpg, Webp, Tvg, Svg, Lottie, Ttf, Raw, Gif, Unknown };
using Size = Point; using Size = Point;

View file

@ -73,6 +73,24 @@ static Inlist<LoadModule> _activeLoaders;
static LoadModule* _find(FileType type) static LoadModule* _find(FileType type)
{ {
switch(type) { switch(type) {
case FileType::Png: {
#ifdef THORVG_PNG_LOADER_SUPPORT
return new PngLoader;
#endif
break;
}
case FileType::Jpg: {
#ifdef THORVG_JPG_LOADER_SUPPORT
return new JpgLoader;
#endif
break;
}
case FileType::Webp: {
#ifdef THORVG_WEBP_LOADER_SUPPORT
return new WebpLoader;
#endif
break;
}
case FileType::Tvg: { case FileType::Tvg: {
#ifdef THORVG_TVG_LOADER_SUPPORT #ifdef THORVG_TVG_LOADER_SUPPORT
return new TvgLoader; return new TvgLoader;
@ -101,24 +119,6 @@ static LoadModule* _find(FileType type)
return new RawLoader; return new RawLoader;
break; break;
} }
case FileType::Png: {
#ifdef THORVG_PNG_LOADER_SUPPORT
return new PngLoader;
#endif
break;
}
case FileType::Jpg: {
#ifdef THORVG_JPG_LOADER_SUPPORT
return new JpgLoader;
#endif
break;
}
case FileType::Webp: {
#ifdef THORVG_WEBP_LOADER_SUPPORT
return new WebpLoader;
#endif
break;
}
default: { default: {
break; break;
} }
@ -305,8 +305,22 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
return loader; return loader;
} }
delete(loader); delete(loader);
*invalid = true;
} }
//Unkown MimeType. Try with the candidates in the order
for (int i = 0; i < static_cast<int>(FileType::Raw); i++) {
if (auto loader = _find(static_cast<FileType>(i))) {
if (loader->open(path)) {
loader->hashpath = strdup(path.c_str());
{
ScopedLock lock(key);
_activeLoaders.back(loader);
}
return loader;
}
delete(loader);
}
}
*invalid = true;
return nullptr; return nullptr;
} }
@ -349,21 +363,20 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
delete(loader); delete(loader);
} }
} }
}
//Unkown MimeType. Try with the candidates in the order //Unkown MimeType. Try with the candidates in the order
} else { for (int i = 0; i < static_cast<int>(FileType::Raw); i++) {
for (int i = 0; i < static_cast<int>(FileType::Unknown); i++) { auto loader = _find(static_cast<FileType>(i));
auto loader = _find(static_cast<FileType>(i)); if (loader) {
if (loader) { if (loader->open(data, size, rpath, copy)) {
if (loader->open(data, size, rpath, copy)) { loader->hashkey = HASH_KEY(data, size);
loader->hashkey = HASH_KEY(data, size); {
{ ScopedLock lock(key);
ScopedLock lock(key); _activeLoaders.back(loader);
_activeLoaders.back(loader);
}
return loader;
} }
delete(loader); return loader;
} }
delete(loader);
} }
} }
return nullptr; return nullptr;