base64 fbx encoding
This commit is contained in:
parent
faa3caa627
commit
3a36501dcd
3 changed files with 29 additions and 19 deletions
18
external/openfbx/ofbx.cpp
vendored
18
external/openfbx/ofbx.cpp
vendored
|
@ -80,6 +80,7 @@ struct Allocator {
|
||||||
|
|
||||||
struct Video
|
struct Video
|
||||||
{
|
{
|
||||||
|
IElementProperty* base64_property = nullptr;
|
||||||
DataView filename;
|
DataView filename;
|
||||||
DataView content;
|
DataView content;
|
||||||
DataView media;
|
DataView media;
|
||||||
|
@ -1957,6 +1958,10 @@ struct Scene : IScene
|
||||||
return m_videos[index].is_base_64;
|
return m_videos[index].is_base_64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const IElementProperty* getEmbeddedBase64Data(int index) const override {
|
||||||
|
return m_videos[index].base64_property;
|
||||||
|
}
|
||||||
|
|
||||||
DataView getEmbeddedFilename(int index) const override {
|
DataView getEmbeddedFilename(int index) const override {
|
||||||
return m_videos[index].filename;
|
return m_videos[index].filename;
|
||||||
}
|
}
|
||||||
|
@ -2256,16 +2261,6 @@ void parseVideo(Scene& scene, const Element& element, Allocator& allocator)
|
||||||
if (!content_element->first_property) return;
|
if (!content_element->first_property) return;
|
||||||
const Property* content_property = content_element->first_property;
|
const Property* content_property = content_element->first_property;
|
||||||
if (content_element->first_property->getType() != IElementProperty::BINARY) {
|
if (content_element->first_property->getType() != IElementProperty::BINARY) {
|
||||||
/*
|
|
||||||
if this happens in text format:
|
|
||||||
Content: ,
|
|
||||||
"iVBORw0KGgoA...
|
|
||||||
this is not a proper solution, but keep doing this until it become an issue
|
|
||||||
*/
|
|
||||||
if (content_element->first_property->getType() != IElementProperty::NONE) return;
|
|
||||||
if (!content_element->first_property->next) return;
|
|
||||||
if (content_element->first_property->next->getType() != IElementProperty::STRING) return;
|
|
||||||
content_property = content_element->first_property->next;
|
|
||||||
is_base64 = true;
|
is_base64 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2276,7 +2271,8 @@ void parseVideo(Scene& scene, const Element& element, Allocator& allocator)
|
||||||
|
|
||||||
Video video;
|
Video video;
|
||||||
video.is_base_64 = is_base64;
|
video.is_base_64 = is_base64;
|
||||||
video.content = content_property->value;
|
video.base64_property = is_base64 ? content_element->first_property->next : nullptr;
|
||||||
|
video.content = is_base64 ? DataView{} : content_element->first_property->value;
|
||||||
video.filename = filename_element->first_property->value;
|
video.filename = filename_element->first_property->value;
|
||||||
video.media = element.first_property->next->value;
|
video.media = element.first_property->next->value;
|
||||||
scene.m_videos.push_back(video);
|
scene.m_videos.push_back(video);
|
||||||
|
|
2
external/openfbx/ofbx.h
vendored
2
external/openfbx/ofbx.h
vendored
|
@ -737,6 +737,8 @@ struct IScene
|
||||||
virtual DataView getEmbeddedData(int index) const = 0;
|
virtual DataView getEmbeddedData(int index) const = 0;
|
||||||
virtual DataView getEmbeddedFilename(int index) const = 0;
|
virtual DataView getEmbeddedFilename(int index) const = 0;
|
||||||
virtual bool isEmbeddedBase64(int index) const = 0;
|
virtual bool isEmbeddedBase64(int index) const = 0;
|
||||||
|
// data are encoded in returned property and all ->next properties
|
||||||
|
virtual const IElementProperty* getEmbeddedBase64Data(int index) const = 0;
|
||||||
|
|
||||||
// Scene Misc
|
// Scene Misc
|
||||||
virtual const TakeInfo* getTakeInfo(const char* name) const = 0;
|
virtual const TakeInfo* getTakeInfo(const char* name) const = 0;
|
||||||
|
|
|
@ -142,14 +142,15 @@ void decodeBase64(const void* data, const u32 len, OutputMemoryStream& str)
|
||||||
unsigned char* p = (unsigned char*)data;
|
unsigned char* p = (unsigned char*)data;
|
||||||
int pad = len > 0 && (len % 4 || p[len - 1] == '=');
|
int pad = len > 0 && (len % 4 || p[len - 1] == '=');
|
||||||
const u32 L = ((len + 3) / 4 - pad) * 4;
|
const u32 L = ((len + 3) / 4 - pad) * 4;
|
||||||
str.resize(L / 4 * 3 + pad);
|
const u32 offset = (u32)str.size();
|
||||||
|
str.resize(L / 4 * 3 + pad + offset);
|
||||||
|
|
||||||
for (u32 i = 0, j = 0; i < L; i += 4)
|
for (u32 i = 0, j = 0; i < L; i += 4)
|
||||||
{
|
{
|
||||||
int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
|
int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
|
||||||
str[j++] = n >> 16;
|
str[offset + j++] = n >> 16;
|
||||||
str[j++] = n >> 8 & 0xFF;
|
str[offset + j++] = n >> 8 & 0xFF;
|
||||||
str[j++] = n & 0xFF;
|
str[offset + j++] = n & 0xFF;
|
||||||
}
|
}
|
||||||
if (pad)
|
if (pad)
|
||||||
{
|
{
|
||||||
|
@ -174,7 +175,7 @@ static void extractEmbedded(const ofbx::IScene& m_scene, StringView src_dir, IAl
|
||||||
const PathInfo pi(filename);
|
const PathInfo pi(filename);
|
||||||
const StaticString<MAX_PATH> fullpath(src_dir, pi.basename, ".", pi.extension);
|
const StaticString<MAX_PATH> fullpath(src_dir, pi.basename, ".", pi.extension);
|
||||||
|
|
||||||
if (os::fileExists(fullpath)) return;
|
if (os::fileExists(fullpath)) continue;
|
||||||
|
|
||||||
os::OutputFile file;
|
os::OutputFile file;
|
||||||
if (!file.open(fullpath)) {
|
if (!file.open(fullpath)) {
|
||||||
|
@ -184,11 +185,22 @@ static void extractEmbedded(const ofbx::IScene& m_scene, StringView src_dir, IAl
|
||||||
|
|
||||||
if (m_scene.isEmbeddedBase64(i)) {
|
if (m_scene.isEmbeddedBase64(i)) {
|
||||||
OutputMemoryStream tmp(allocator);
|
OutputMemoryStream tmp(allocator);
|
||||||
decodeBase64(embedded.begin, u32(embedded.end - embedded.begin), tmp);
|
const ofbx::IElementProperty* prop = m_scene.getEmbeddedBase64Data(i);
|
||||||
|
if (prop) {
|
||||||
|
if (prop->getNext()) {
|
||||||
|
for (const auto* j = prop; j; j = j->getNext()) {
|
||||||
|
decodeBase64(j->getValue().begin, u32(j->getValue().end - j->getValue().begin), tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
decodeBase64(prop->getValue().begin, u32(prop->getValue().end - prop->getValue().begin), tmp);
|
||||||
|
}
|
||||||
if (!file.write(tmp.data(), tmp.size())) {
|
if (!file.write(tmp.data(), tmp.size())) {
|
||||||
logError("Failed to write ", fullpath);
|
logError("Failed to write ", fullpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else logError("Invalid data ", fullpath);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (!file.write(embedded.begin + 4, embedded.end - embedded.begin - 4)) {
|
if (!file.write(embedded.begin + 4, embedded.end - embedded.begin - 4)) {
|
||||||
logError("Failed to write ", fullpath);
|
logError("Failed to write ", fullpath);
|
||||||
|
|
Loading…
Reference in a new issue